diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e96ad27 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +max_line_length = 120 +tab_width = 2 +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false + +[*.{yml,yaml}] +max_line_length = off + +[COMMIT_EDITMSG] +max_line_length = off diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 42ceb9a..0000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -dist/ -lib/ -node_modules/ -jest.config.js diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index bca4a7a..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "plugins": ["jest", "@typescript-eslint", "prettier", "unicorn"], - "extends": ["plugin:unicorn/recommended", "plugin:github/recommended", "plugin:prettier/recommended"], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 2020, - "sourceType": "module", - "extraFileExtensions": [".mjs"], - "ecmaFeatures": { - "impliedStrict": true - }, - "project": "./tsconfig.json" - }, - "env": { - "node": true, - "es6": true, - "jest/globals": true, - "es2020": true - }, - "rules": { - // Error out for code formatting errors - "prettier/prettier": "error", - // Namespaces or sometimes needed - "import/no-namespace": "off", - // Properly format comments - "spaced-comment": ["error", "always"], - "lines-around-comment": [ - "error", - { - "beforeBlockComment": true, - "beforeLineComment": true, - "allowBlockStart": true, - "allowObjectStart": true, - "allowArrayStart": true, - "allowClassStart": true, - "ignorePattern": "pragma|ts-ignore" - } - ], - // Mandatory spacing - "padding-line-between-statements": [ - "error", - { - "blankLine": "always", - "prev": "*", - "next": "return" - }, - { - "blankLine": "always", - "prev": "directive", - "next": "*" - }, - { - "blankLine": "any", - "prev": "directive", - "next": "directive" - } - ], - // Enforce camelCase - "camelcase": "error", - // Allow forOfStatements - "no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "WithStatement"], - // Continue is viable in forOf loops in generators - "no-continue": "off", - // From experience, named exports are almost always desired. I got tired of this rule - "import/prefer-default-export": "off", - // Unused vars are useful to keep method signatures consistent and documented - "@typescript-eslint/no-unused-vars": "off", - // For this project only use kebab-case - "unicorn/filename-case": [ - "error", - { - "cases": { - "kebabCase": true - } - } - ], - // Allow Array.from(set) mitigate TS2569 which would require '--downlevelIteration' - "unicorn/prefer-spread": "off", - // Temp disable to prevent mixing changes with other PRs - "i18n-text/no-en": "off" - }, - "overrides": [ - { - "files": ["jest.setup.js"], - "rules": { - "import/no-commonjs": "off" - } - } - ] -} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..761f9dc --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +[attr]generated-code-file text eol=lf -diff linguist-generated=true +[attr]generated-binary-file -text -diff linguist-generated=true + +dist/index* generated-code-file +dist/licenses* generated-code-file +dist/sourcemap* generated-code-file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..ff2884e --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: game-ci +patreon: # Replace with a single Patreon username +open_collective: # replace with a single OpenCollective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..d996e86 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,23 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' +--- + +**Bug description** + + + +**How to reproduce** + + + +- **Expected behavior** + + + +**Additional details** + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..d22e650 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Discuss on Discord + url: https://game.ci/discord + about: Join our Discord community diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..228014b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: Feature request +about: Suggest an improvement, or a new feature +title: '' +labels: enhancement +assignees: '' +--- + +**Context** + + + +**Suggested solution** + + + +**Considered alternatives** + + + +**Additional details** + + diff --git a/.github/ISSUE_TEMPLATE/other.md b/.github/ISSUE_TEMPLATE/other.md new file mode 100644 index 0000000..a2350bb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/other.md @@ -0,0 +1,7 @@ +--- +name: Other +about: Everything else +title: '' +labels: '' +assignees: '' +--- diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..b00128c --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,29 @@ +#### Changes + +- ... + +#### Related Issues + +- ... + +#### Related PRs + +- ... + +#### Successful Workflow Run Link + +PRs don't have access to secrets so you will need to provide a link to a successful run of the workflows from your own +repo. + +- ... + +#### Checklist + + + +- [x] Read the contribution [guide](https://github.com/game-ci/unity-builder/blob/main/CONTRIBUTING.md) and accept the + [code](https://github.com/game-ci/unity-builder/blob/main/CODE_OF_CONDUCT.md) of conduct +- [ ] Docs (If new inputs or outputs have been added or changes to behavior that should be documented. Please make a PR + in the [documentation repo](https://github.com/game-ci/documentation)) +- [ ] Readme (updated or not needed) +- [ ] Tests (added, updated or not needed) diff --git a/.github/workflows/activation.yml b/.github/workflows/activation.yml new file mode 100644 index 0000000..080ef25 --- /dev/null +++ b/.github/workflows/activation.yml @@ -0,0 +1,20 @@ +name: Acquire activation file + +on: + workflow_dispatch: + +jobs: + activation: + name: Request manual activation file 🔑 + runs-on: ubuntu-latest + steps: + # Request manual activation file + - name: Unity - Request Activation File + id: requestActivationFile + uses: game-ci/unity-request-activation-file@v2.0-alpha-1 + - name: Upload activation file + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.requestActivationFile.outputs.filePath }} + path: ${{ steps.requestActivationFile.outputs.filePath }} + retention-days: 3 diff --git a/.github/workflows/build-tests-mac.yml b/.github/workflows/build-tests-mac.yml new file mode 100644 index 0000000..e0d110a --- /dev/null +++ b/.github/workflows/build-tests-mac.yml @@ -0,0 +1,87 @@ +name: Builds - MacOS + +on: + workflow_dispatch: + push: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + buildForAllPlatformsMacOS: + name: ${{ matrix.targetPlatform }} on ${{ matrix.unityVersion }} + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + projectPath: + - test-project + unityVersion: + - 2021.3.45f2 + - 2022.3.62f3 + - 2023.2.22f1 + targetPlatform: + - StandaloneOSX # Build a MacOS executable + - iOS # Build an iOS executable + include: + # Additionally test enableGpu build for a standalone windows target + - unityVersion: 6000.0.36f1 + targetPlatform: StandaloneOSX + - unityVersion: 6000.0.36f1 + targetPlatform: StandaloneOSX + buildProfile: 'Assets/Settings/Build Profiles/Sample macOS Build Profile.asset' + + steps: + ########################### + # Checkout # + ########################### + - uses: actions/checkout@v4 + with: + lfs: true + + ########################### + # Cache # + ########################### + - uses: actions/cache@v4 + with: + path: ${{ matrix.projectPath }}/Library + key: Library-${{ matrix.projectPath }}-macos-${{ matrix.targetPlatform }} + restore-keys: | + Library-${{ matrix.projectPath }}-macos- + Library- + + ########################### + # Set Scripting Backend # + ########################### + - name: Set Scripting Backend To il2cpp + run: | + mv -f "./test-project/ProjectSettings/ProjectSettingsIl2cpp.asset" "./test-project/ProjectSettings/ProjectSettings.asset" + + ########################### + # Build # + ########################### + - uses: ./ + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} + with: + buildName: 'GameCI Test Build' + projectPath: ${{ matrix.projectPath }} + unityVersion: ${{ matrix.unityVersion }} + targetPlatform: ${{ matrix.targetPlatform }} + buildProfile: ${{ matrix.buildProfile }} + customParameters: -profile SomeProfile -someBoolean -someValue exampleValue + # We use dirty build because we are replacing the default project settings file above + allowDirtyBuild: true + + ########################### + # Upload # + ########################### + - uses: actions/upload-artifact@v4 + with: + name: Build ${{ matrix.targetPlatform }} on MacOS (${{ matrix.unityVersion }})${{ matrix.buildProfile && ' With Build Profile' || '' }} + path: build + retention-days: 14 diff --git a/.github/workflows/build-tests-ubuntu.yml b/.github/workflows/build-tests-ubuntu.yml new file mode 100644 index 0000000..18e7cd5 --- /dev/null +++ b/.github/workflows/build-tests-ubuntu.yml @@ -0,0 +1,203 @@ +name: Builds - Ubuntu + +on: + workflow_dispatch: + push: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + UNITY_LICENSE: "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \nm0Db8UK+ktnOLJBtHybkfetpcKo=o/pUbSQAukz7+ZYAWhnA0AJbIlyyCPL7bKVEM2lVqbrXt7cyey+umkCXamuOgsWPVUKBMkXtMH8L\n5etLmD0getWIhTGhzOnDCk+gtIPfL4jMo9tkEuOCROQAXCci23VFscKcrkB+3X6h4wEOtA2APhOY\nB+wvC794o8/82ffjP79aVAi57rp3Wmzx+9pe9yMwoJuljAy2sc2tIMgdQGWVmOGBpQm3JqsidyzI\nJWG2kjnc7pDXK9pwYzXoKiqUqqrut90d+kQqRyv7MSZXR50HFqD/LI69h68b7P8Bjo3bPXOhNXGR\n9YCoemH6EkfCJxp2gIjzjWW+l2Hj2EsFQi8YXw==" + +jobs: + buildForAllPlatformsUbuntu: + name: "${{ matrix.targetPlatform }} on ${{ matrix.unityVersion}}${{startsWith(matrix.buildProfile, 'Assets') && ' (via Build Profile)' || '' }}" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + providerStrategy: + # - local-docker + - local + projectPath: + - test-project + unityVersion: + - 2021.3.45f2 + - 2022.3.62f3 + - 2023.2.22f1 + targetPlatform: + - StandaloneOSX # Build a macOS standalone (Intel 64-bit) with mono backend. + - StandaloneWindows64 # Build a Windows 64-bit standalone with mono backend. + - StandaloneLinux64 # Build a Linux 64-bit standalone with mono/il2cpp backend. + - iOS # Build an iOS project. + - Android # Build an Android .apk. + - WebGL # WebGL. + buildWithIl2cpp: + - false + - true + additionalParameters: + - -param value + - -standaloneBuildSubtarget Server + # Skipping configurations that are not supported + exclude: + # No il2cpp support on Linux Host + - targetPlatform: StandaloneOSX + buildWithIl2cpp: true + - targetPlatform: StandaloneWindows64 + buildWithIl2cpp: true + # Only builds with Il2cpp + - targetPlatform: iOS + buildWithIl2cpp: false + - targetPlatform: Android + buildWithIl2cpp: false + - targetPlatform: WebGL + buildWithIl2cpp: false + # No dedicated server support + - targetPlatform: WebGL + additionalParameters: -standaloneBuildSubtarget Server + - targetPlatform: Android + additionalParameters: -standaloneBuildSubtarget Server + - targetPlatform: iOS + additionalParameters: -standaloneBuildSubtarget Server + # No dedicated server support on Linux Host + - targetPlatform: StandaloneOSX + additionalParameters: -standaloneBuildSubtarget Server + # No il2cpp dedicated server support on Linux Host + - targetPlatform: StandaloneWindows64 + additionalParameters: -standaloneBuildSubtarget Server + buildWithIl2cpp: true + include: + - unityVersion: 6000.0.36f1 + targetPlatform: WebGL + - unityVersion: 6000.0.36f1 + targetPlatform: WebGL + buildProfile: 'Assets/Settings/Build Profiles/Sample WebGL Build Profile.asset' + + steps: + - name: Clear Space for Android Build + if: matrix.targetPlatform == 'Android' + uses: jlumbroso/free-disk-space@v1.3.1 + + ########################### + # Checkout # + ########################### + - uses: actions/checkout@v4 + with: + lfs: true + + ########################### + # Cache # + ########################### + - uses: actions/cache@v4 + with: + path: ${{ matrix.projectPath }}/Library + key: Library-${{ matrix.projectPath }}-ubuntu-${{ matrix.targetPlatform }} + restore-keys: | + Library-${{ matrix.projectPath }}-ubuntu- + Library- + + ########################### + # Set Scripting Backend # + ########################### + - name: Set Scripting Backend To il2cpp + if: matrix.buildWithIl2cpp == true + run: | + mv -f "./test-project/ProjectSettings/ProjectSettingsIl2cpp.asset" "./test-project/ProjectSettings/ProjectSettings.asset" + + ########################### + # Build # + ########################### + - name: Build + uses: ./ + id: build-1 + continue-on-error: true + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + with: + buildName: 'GameCI Test Build' + projectPath: ${{ matrix.projectPath }} + buildProfile: ${{ matrix.buildProfile }} + unityVersion: ${{ matrix.unityVersion }} + targetPlatform: ${{ matrix.targetPlatform }} + customParameters: -profile SomeProfile -someBoolean -someValue exampleValue ${{ matrix.additionalParameters }} + providerStrategy: ${{ matrix.providerStrategy }} + allowDirtyBuild: true + + - name: Sleep for Retry + if: ${{ steps.build-1.outcome == 'failure' }} + run: | + sleep 60 + + - name: Build (Retry 1) + uses: ./ + id: build-2 + if: ${{ steps.build-1.outcome == 'failure' }} + continue-on-error: true + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + with: + buildName: 'GameCI Test Build' + projectPath: ${{ matrix.projectPath }} + buildProfile: ${{ matrix.buildProfile }} + unityVersion: ${{ matrix.unityVersion }} + targetPlatform: ${{ matrix.targetPlatform }} + customParameters: -profile SomeProfile -someBoolean -someValue exampleValue ${{ matrix.additionalParameters }} + providerStrategy: ${{ matrix.providerStrategy }} + allowDirtyBuild: true + + - name: Sleep for Retry + if: ${{ steps.build-2.outcome == 'failure' }} + run: | + sleep 240 + + - name: Build (Retry 2) + uses: ./ + id: build-3 + if: ${{ steps.build-2.outcome == 'failure' }} + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + with: + buildName: 'GameCI Test Build' + projectPath: ${{ matrix.projectPath }} + buildProfile: ${{ matrix.buildProfile }} + unityVersion: ${{ matrix.unityVersion }} + targetPlatform: ${{ matrix.targetPlatform }} + customParameters: -profile SomeProfile -someBoolean -someValue exampleValue ${{ matrix.additionalParameters }} + providerStrategy: ${{ matrix.providerStrategy }} + allowDirtyBuild: true + + ########################### + # Upload # + ########################### + - uses: actions/upload-artifact@v4 + with: + name: "Build ${{ matrix.targetPlatform }}${{ startsWith(matrix.buildProfile, 'Assets') && ' (via Build Profile)' || '' }} on Ubuntu (${{ matrix.unityVersion }}_il2cpp_${{ matrix.buildWithIl2cpp }}_params_${{ matrix.additionalParameters }})" + path: build + retention-days: 14 diff --git a/.github/workflows/build-tests-windows.yml b/.github/workflows/build-tests-windows.yml new file mode 100644 index 0000000..e052386 --- /dev/null +++ b/.github/workflows/build-tests-windows.yml @@ -0,0 +1,181 @@ +name: Builds - Windows + +on: + workflow_dispatch: + push: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + buildForAllPlatformsWindows: + name: ${{ matrix.targetPlatform }} on ${{ matrix.unityVersion }} + runs-on: windows-2022 + strategy: + fail-fast: false + matrix: + projectPath: + - test-project + unityVersion: + - 2021.3.45f2 + - 2022.3.62f3 + - 2023.2.22f1 + targetPlatform: + - Android # Build an Android apk. + - StandaloneWindows64 # Build a Windows 64-bit standalone. + - WSAPlayer # Build a UWP App + - tvOS # Build an Apple TV XCode project + enableGpu: + - false + include: + # Additionally test enableGpu build for a standalone windows target + - projectPath: test-project + unityVersion: 2023.2.2f1 + targetPlatform: StandaloneWindows64 + enableGpu: true + - unityVersion: 6000.0.36f1 + targetPlatform: StandaloneWindows64 + - unityVersion: 6000.0.36f1 + targetPlatform: StandaloneWindows64 + buildProfile: 'Assets/Settings/Build Profiles/Sample Windows Build Profile.asset' + + steps: + ########################### + # Checkout # + ########################### + - uses: actions/checkout@v4 + with: + lfs: true + + ########################### + # Cache # + ########################### + - uses: actions/cache@v4 + with: + path: ${{ matrix.projectPath }}/Library + key: Library-${{ matrix.projectPath }}-windows-${{ matrix.targetPlatform }} + restore-keys: | + Library-${{ matrix.projectPath }}-windows- + Library- + + ########################### + # Set Scripting Backend # + ########################### + - name: Set Scripting Backend To il2cpp + run: | + Move-Item -Path "./test-project/ProjectSettings/ProjectSettingsIl2cpp.asset" -Destination "./test-project/ProjectSettings/ProjectSettings.asset" -Force + + ########################### + # Docker Readiness # + ########################### + - name: Ensure Docker daemon is ready + timeout-minutes: 2 + shell: powershell + run: | + $maxRetries = 10 + $retryDelay = 6 + for ($i = 0; $i -lt $maxRetries; $i++) { + $svc = Get-Service docker -ErrorAction SilentlyContinue + if ($svc -and $svc.Status -eq 'Running') { + docker version 2>$null + if ($LASTEXITCODE -eq 0) { + Write-Host "Docker is ready." + exit 0 + } + } + if ($svc -and $svc.Status -eq 'Stopped') { + Write-Host "Docker service stopped, attempting to start..." + Start-Service docker -ErrorAction SilentlyContinue + } + Write-Host "Waiting for Docker daemon (attempt $($i+1)/$maxRetries)..." + Start-Sleep -Seconds $retryDelay + } + Write-Error "Docker daemon did not start within $($maxRetries * $retryDelay) seconds" + exit 1 + + ########################### + # Build # + ########################### + - name: Build + uses: ./ + id: build-1 + continue-on-error: true + timeout-minutes: 30 + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} + with: + buildName: 'GameCI Test Build' + projectPath: ${{ matrix.projectPath }} + unityVersion: ${{ matrix.unityVersion }} + targetPlatform: ${{ matrix.targetPlatform }} + buildProfile: ${{ matrix.buildProfile }} + enableGpu: ${{ matrix.enableGpu }} + customParameters: -profile SomeProfile -someBoolean -someValue exampleValue + allowDirtyBuild: true + # We use dirty build because we are replacing the default project settings file above + + - name: Sleep for Retry + if: ${{ steps.build-1.outcome == 'failure' }} + run: | + Start-Sleep -s 120 + + - name: Build Retry 1 + uses: ./ + id: build-2 + continue-on-error: true + timeout-minutes: 30 + if: steps.build-1.outcome == 'failure' + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} + with: + buildName: 'GameCI Test Build' + projectPath: ${{ matrix.projectPath }} + unityVersion: ${{ matrix.unityVersion }} + targetPlatform: ${{ matrix.targetPlatform }} + enableGpu: ${{ matrix.enableGpu }} + customParameters: -profile SomeProfile -someBoolean -someValue exampleValue + allowDirtyBuild: true + # We use dirty build because we are replacing the default project settings file above + + - name: Sleep for Retry + if: ${{ steps.build-1.outcome == 'failure' && steps.build-2.outcome == 'failure' }} + run: | + Start-Sleep -s 240 + + - name: Build Retry 2 + uses: ./ + id: build-3 + timeout-minutes: 30 + if: ${{ steps.build-1.outcome == 'failure' && steps.build-2.outcome == 'failure' }} + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} + with: + buildName: 'GameCI Test Build' + projectPath: ${{ matrix.projectPath }} + unityVersion: ${{ matrix.unityVersion }} + targetPlatform: ${{ matrix.targetPlatform }} + enableGpu: ${{ matrix.enableGpu }} + customParameters: -profile SomeProfile -someBoolean -someValue exampleValue + allowDirtyBuild: true + # We use dirty build because we are replacing the default project settings file above + + ########################### + # Upload # + ########################### + - uses: actions/upload-artifact@v4 + with: + name: + Build ${{ matrix.targetPlatform }} on Windows (${{ matrix.unityVersion }})${{ matrix.enableGpu && ' With + GPU' || '' }}${{ matrix.buildProfile && ' With Build Profile' || '' }} + path: build + retention-days: 14 diff --git a/.github/workflows/cats.yml b/.github/workflows/cats.yml new file mode 100644 index 0000000..4e49253 --- /dev/null +++ b/.github/workflows/cats.yml @@ -0,0 +1,16 @@ +name: Cats 😺 + +on: + pull_request_target: + types: + - opened + - reopened + +jobs: + aCatForCreatingThePullRequest: + name: A cat for your effort! + runs-on: ubuntu-latest + steps: + - uses: ruairidhwm/action-cats@1.0.2 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/integrity-check.yml b/.github/workflows/integrity-check.yml index 3cbf618..b491fc8 100644 --- a/.github/workflows/integrity-check.yml +++ b/.github/workflows/integrity-check.yml @@ -2,13 +2,17 @@ name: Integrity on: push: { branches: [main] } - pull_request: {} + pull_request: + types: [opened, synchronize, reopened, labeled] permissions: contents: read checks: write statuses: write +env: + CODECOV_TOKEN: '2f2eb890-30e2-4724-83eb-7633832cf0de' + concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true @@ -18,17 +22,41 @@ jobs: name: Tests runs-on: ubuntu-latest steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1 + - uses: actions/checkout@v4 + - name: Install package manager (from package.json) + run: | + corepack enable + corepack install + - uses: actions/setup-node@v4 with: - egress-policy: audit - - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + node-version: '18' + - name: Resolve yarn cache folder + id: yarn-config + run: echo "cacheFolder=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT" + - name: Restore yarn install cache (node_modules + cacheFolder + install-state) + uses: actions/cache@v4 with: - node-version: '24' - - run: yarn + path: | + ${{ steps.yarn-config.outputs.cacheFolder }} + .yarn/install-state.gz + key: yarn-v2-${{ runner.os }}-node-18-${{ hashFiles('yarn.lock') }} + restore-keys: | + yarn-v2-${{ runner.os }}-node-18- + - name: Install deps + env: + YARN_ENABLE_HARDENED_MODE: 'false' + run: | + case "$(yarn --version)" in 1.*) echo 'expected up-to-date yarn version'; exit 1 ;; esac + yarn install --immutable - run: yarn lint - - run: yarn test:ci + - run: yarn test:ci --coverage + - run: bash <(curl -s https://codecov.io/bash) - run: yarn build || { echo "build command should always succeed" ; exit 61; } # - run: yarn build --quiet && git diff --quiet dist || { echo "dist should be auto generated" ; git diff dist ; exit 62; } + + orchestrator-integration: + name: Orchestrator Integration + if: >- + github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'run-integration') + uses: ./.github/workflows/validate-orchestrator-integration.yml + secrets: inherit diff --git a/.github/workflows/sync-secrets.yml b/.github/workflows/sync-secrets.yml new file mode 100644 index 0000000..b2af4e8 --- /dev/null +++ b/.github/workflows/sync-secrets.yml @@ -0,0 +1,91 @@ +name: Sync Secrets to Repositories + +on: + workflow_dispatch: + inputs: + target_repo: + description: 'Target repository (org/repo format)' + required: true + default: 'game-ci/orchestrator' + type: choice + options: + - game-ci/orchestrator + - game-ci/cli + dry_run: + description: 'Dry run (list secrets to sync without writing)' + required: false + default: false + type: boolean + +permissions: + contents: read + +jobs: + sync-secrets: + name: Sync secrets to ${{ inputs.target_repo }} + runs-on: ubuntu-latest + steps: + - name: Sync secrets + env: + GH_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + TARGET_REPO: ${{ inputs.target_repo }} + DRY_RUN: ${{ inputs.dry_run }} + # Secrets to sync — values come from repo + org secrets available here + SECRET_UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + SECRET_UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + SECRET_UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + SECRET_GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + SECRET_GOOGLE_SERVICE_ACCOUNT_EMAIL: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_EMAIL }} + SECRET_GOOGLE_SERVICE_ACCOUNT_KEY: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_KEY }} + SECRET_CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + SECRET_UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} + SECRET_NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + SECRETS=( + "UNITY_EMAIL:SECRET_UNITY_EMAIL" + "UNITY_PASSWORD:SECRET_UNITY_PASSWORD" + "UNITY_SERIAL:SECRET_UNITY_SERIAL" + "UNITY_LICENSE:SECRET_UNITY_LICENSE" + "GIT_PRIVATE_TOKEN:SECRET_GIT_PRIVATE_TOKEN" + "GOOGLE_SERVICE_ACCOUNT_EMAIL:SECRET_GOOGLE_SERVICE_ACCOUNT_EMAIL" + "GOOGLE_SERVICE_ACCOUNT_KEY:SECRET_GOOGLE_SERVICE_ACCOUNT_KEY" + "CODECOV_TOKEN:SECRET_CODECOV_TOKEN" + "NPM_TOKEN:SECRET_NPM_TOKEN" + ) + + synced=0 + skipped=0 + + for entry in "${SECRETS[@]}"; do + name="${entry%%:*}" + env_var="${entry##*:}" + value="${!env_var}" + + if [ -z "$value" ]; then + echo "⏭ SKIP: $name (not available in this repo's context)" + skipped=$((skipped + 1)) + continue + fi + + if [ "$DRY_RUN" = "true" ]; then + echo "🔍 DRY RUN: would sync $name → $TARGET_REPO" + else + if echo "$value" | gh secret set "$name" -R "$TARGET_REPO" --body - 2>/dev/null; then + echo "✅ SYNCED: $name → $TARGET_REPO" + else + echo "⚠️ FAILED: $name → $TARGET_REPO (continuing)" + skipped=$((skipped + 1)) + synced=$((synced - 1)) + fi + fi + synced=$((synced + 1)) + done + + echo "" + echo "=== Summary ===" + echo "Synced: $synced" + echo "Skipped (not available): $skipped" + echo "Target: $TARGET_REPO" + if [ "$DRY_RUN" = "true" ]; then + echo "Mode: DRY RUN (no secrets were written)" + fi diff --git a/.github/workflows/validate-community-plugins.yml b/.github/workflows/validate-community-plugins.yml new file mode 100644 index 0000000..da6928a --- /dev/null +++ b/.github/workflows/validate-community-plugins.yml @@ -0,0 +1,205 @@ +name: Validate Community Plugins + +on: + schedule: + # Run weekly on Sunday at 02:00 UTC + - cron: '0 2 * * 0' + workflow_dispatch: + inputs: + plugin_filter: + description: 'Filter plugins by name (regex pattern, empty = all)' + required: false + default: '' + unity_version: + description: 'Override Unity version (empty = use plugin default)' + required: false + default: '' + +permissions: + contents: read + issues: write + +jobs: + load-plugins: + name: Load Plugin Registry + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.parse.outputs.matrix }} + plugin_count: ${{ steps.parse.outputs.count }} + steps: + - uses: actions/checkout@v4 + + - name: Parse plugin registry + id: parse + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const yaml = require('js-yaml'); + + const registry = yaml.load(fs.readFileSync('community-plugins.yml', 'utf8')); + let plugins = registry.plugins || []; + + // Apply name filter if provided + const filter = '${{ github.event.inputs.plugin_filter }}'; + if (filter) { + const regex = new RegExp(filter, 'i'); + plugins = plugins.filter(p => regex.test(p.name)); + } + + // Expand platform matrix + const matrix = []; + for (const plugin of plugins) { + const platforms = plugin.platforms || ['StandaloneLinux64']; + for (const platform of platforms) { + matrix.push({ + name: plugin.name, + package: plugin.package, + source: plugin.source || 'git', + unity: '${{ github.event.inputs.unity_version }}' || plugin.unity || '2021.3', + platform: platform, + timeout: plugin.timeout || 30 + }); + } + } + + core.setOutput('matrix', JSON.stringify({ include: matrix })); + core.setOutput('count', matrix.length); + console.log(`Found ${matrix.length} plugin-platform combinations to validate`); + + validate: + name: '${{ matrix.name }} (${{ matrix.platform }})' + needs: load-plugins + if: needs.load-plugins.outputs.plugin_count > 0 + runs-on: ubuntu-latest + timeout-minutes: ${{ fromJson(matrix.timeout) }} + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.load-plugins.outputs.matrix) }} + steps: + - uses: actions/checkout@v4 + + - name: Create test project + run: | + mkdir -p test-project/Assets + mkdir -p test-project/Packages + mkdir -p test-project/ProjectSettings + + # Create minimal manifest.json + if [ "${{ matrix.source }}" = "git" ]; then + cat > test-project/Packages/manifest.json << 'MANIFEST' + { + "dependencies": { + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + } + MANIFEST + + # Add git package via manifest + cd test-project + python3 -c " + import sys, json + manifest = json.load(sys.stdin) + manifest['dependencies']['${{ matrix.name }}'] = '${{ matrix.package }}' + json.dump(manifest, sys.stdout, indent=2) + " < Packages/manifest.json > Packages/manifest.tmp && mv Packages/manifest.tmp Packages/manifest.json + cd .. + fi + + # Create minimal ProjectSettings + cat > test-project/ProjectSettings/ProjectVersion.txt << EOF + m_EditorVersion: ${{ matrix.unity }} + EOF + + - name: Build with unity-builder + uses: ./ + id: build + with: + projectPath: test-project + targetPlatform: ${{ matrix.platform }} + unityVersion: ${{ matrix.unity }} + continue-on-error: true + + - name: Record result + if: always() + run: | + STATUS="${{ steps.build.outcome }}" + { + echo "## ${{ matrix.name }} — ${{ matrix.platform }}" + echo "" + if [ "$STATUS" = "success" ]; then + echo "✅ **PASSED** — Compiled and built successfully" + else + echo "❌ **FAILED** — Build or compilation failed" + fi + echo "" + echo "- Unity: ${{ matrix.unity }}" + echo "- Platform: ${{ matrix.platform }}" + echo "- Source: ${{ matrix.source }}" + echo "- Package: \`${{ matrix.package }}\`" + } >> "$GITHUB_STEP_SUMMARY" + + report: + name: Validation Report + needs: [load-plugins, validate] + if: always() + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Generate summary + uses: actions/github-script@v7 + with: + script: | + const { data: run } = await github.rest.actions.listJobsForWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.runId + }); + + const validateJobs = run.jobs.filter(j => j.name.startsWith('validate')); + const passed = validateJobs.filter(j => j.conclusion === 'success').length; + const failed = validateJobs.filter(j => j.conclusion === 'failure').length; + const total = validateJobs.length; + + let summary = `# Community Plugin Validation Report\n\n`; + summary += `**${passed}/${total} passed** | ${failed} failed\n\n`; + summary += `| Plugin | Platform | Status |\n|--------|----------|--------|\n`; + + for (const job of validateJobs) { + const icon = job.conclusion === 'success' ? '✅' : '❌'; + summary += `| ${job.name} | | ${icon} ${job.conclusion} |\n`; + } + + await core.summary.addRaw(summary).write(); + + // Create or update issue if there are failures + if (failed > 0) { + const title = `Community Plugin Validation: ${failed} failure(s) — ${new Date().toISOString().split('T')[0]}`; + const body = summary + `\n\n[Workflow Run](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})`; + + const { data: issues } = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + labels: 'community-plugin-validation' + }); + + if (issues.length > 0) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issues[0].number, + body: body + }); + } else { + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: title, + body: body, + labels: ['community-plugin-validation'] + }); + } + } diff --git a/.github/workflows/validate-orchestrator-integration.yml b/.github/workflows/validate-orchestrator-integration.yml new file mode 100644 index 0000000..88bf485 --- /dev/null +++ b/.github/workflows/validate-orchestrator-integration.yml @@ -0,0 +1,1269 @@ +name: Orchestrator Integration Tests + +# ============================================================================== +# Exhaustive integration tests — runs on a daily cron and manual dispatch. +# Slow (~1-2h wall-clock): k8s, AWS, local-docker, rclone via MiniStack + k3d. +# +# Mirrors the full orchestrator-integrity.yml test suite from the orchestrator +# repo, run from unity-builder's perspective to catch cross-repo regressions. +# +# For fast per-PR checks, see validate-orchestrator.yml. +# ============================================================================== + +on: + workflow_dispatch: + workflow_call: # Allow integrity-check.yml and other workflows to invoke these tests + schedule: + - cron: '0 3 * * *' # Daily at 3 AM UTC + +permissions: + contents: read + checks: write + statuses: write + +# Note: no concurrency block here — when invoked via workflow_call, the caller +# (integrity-check.yml) manages concurrency. For direct dispatch/cron, runs are +# naturally serialized by GitHub's single-concurrency-per-ref default. + +env: + AWS_STACK_NAME: game-ci-team-pipelines + DEBUG: true + PROJECT_PATH: test-project + USE_IL2CPP: false + +# ============================================================================== +# 4 parallel jobs on separate runners (fresh 14GB disk each). +# Matches the orchestrator-integrity.yml architecture. +# ============================================================================== + +jobs: + # ============================================================================ + # PLUGIN INTERFACE (fast gate — fails fast before slow jobs waste time) + # ============================================================================ + plugin-interface: + name: Plugin Interface Tests + runs-on: ubuntu-latest + steps: + - name: Checkout unity-builder + uses: actions/checkout@v4 + + - name: Checkout orchestrator (matching branch) + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + ref: ${{ github.head_ref || github.ref_name }} + path: orchestrator-standalone + continue-on-error: true + id: orchestrator-branch + + - name: Fallback to orchestrator main branch + if: steps.orchestrator-branch.outcome == 'failure' + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + path: orchestrator-standalone + + - name: Install package manager (from package.json) + run: | + corepack enable + corepack install + - uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Resolve yarn cache folder + id: yarn-config + run: echo "cacheFolder=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT" + - name: Restore yarn install cache (node_modules + cacheFolder + install-state) + uses: actions/cache@v4 + with: + path: | + ${{ steps.yarn-config.outputs.cacheFolder }} + .yarn/install-state.gz + key: yarn-v2-${{ runner.os }}-node-20-${{ hashFiles('yarn.lock') }} + restore-keys: | + yarn-v2-${{ runner.os }}-node-20- + + - name: Install unity-builder dependencies + run: yarn install --immutable + + - name: Build unity-builder + run: | + echo "Building unity-builder TypeScript..." + npx tsc + echo "✓ unity-builder compiles successfully" + + - name: Run plugin interface unit tests + run: | + echo "Running orchestrator-plugin unit tests..." + npx vitest run orchestrator-plugin --reporter=verbose + + - name: Build and pack orchestrator + working-directory: orchestrator-standalone + run: | + yarn install --immutable + echo "Building orchestrator..." + npx tsc + echo "✓ orchestrator compiles successfully" + echo "Packing orchestrator as tarball..." + npm pack + + - name: Install orchestrator into unity-builder + run: | + echo "Installing orchestrator into unity-builder workspace..." + npm install ./orchestrator-standalone/game-ci-orchestrator-*.tgz --no-save --legacy-peer-deps + + - name: Verify plugin loader returns exports with orchestrator installed + run: | + node -e " + const { loadOrchestratorPlugin } = require('./lib/model/orchestrator-plugin'); + (async () => { + const plugin = await loadOrchestratorPlugin(); + if (plugin === undefined) { + console.error('ERROR: loadOrchestratorPlugin should return defined plugin when package is installed'); + process.exit(1); + } + const lifecycleMethods = [ + 'initialize', 'canHandleBuild', 'handleBuild', + 'beforeLocalBuild', 'afterLocalBuild', 'handlePostBuild', + ]; + for (const method of lifecycleMethods) { + if (typeof plugin[method] !== 'function') { + console.error('ERROR: plugin.' + method + ' should be a function, got ' + typeof plugin[method]); + process.exit(1); + } + } + console.log('✓ loadOrchestratorPlugin() returns plugin with all ' + lifecycleMethods.length + ' lifecycle methods'); + })(); + " + + - name: Verify type declarations match exports + run: | + node -e " + const orch = require('@game-ci/orchestrator'); + const expected = ['Orchestrator','BuildReliabilityService','TestWorkflowService','HotRunnerService','OutputService','OutputTypeRegistry','ArtifactUploadHandler','IncrementalSyncService','ChildWorkspaceService','LocalCacheService','SubmoduleProfileService','LfsAgentService','GitHooksService']; + const missing = expected.filter(e => orch[e] === undefined); + if (missing.length > 0) { console.error('Missing exports:', missing.join(', ')); process.exit(1); } + console.log('✓ All ' + expected.length + ' exports present'); + " + + # ============================================================================ + # K8S INTEGRATION TESTS (k3d + MiniStack) + # ============================================================================ + k8s-integration: + name: K8s Integration Tests + runs-on: ubuntu-latest + env: + K3D_NODE_CONTAINERS: 'k3d-unity-builder-agent-0' + AWS_FORCE_PROVIDER: aws-local + RESOURCE_TRACKING: 'true' + K8S_LOCALSTACK_HOST: localstack-main + steps: + - name: Checkout orchestrator (matching branch) + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + ref: ${{ github.head_ref || github.ref_name }} + lfs: false + continue-on-error: true + id: orch-branch + + - name: Clean corrupted checkout + if: steps.orch-branch.outcome == 'failure' + run: rm -rf .git || true + + - name: Fallback to orchestrator main branch + if: steps.orch-branch.outcome == 'failure' + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + lfs: false + + - name: Install package manager (from package.json) + run: | + corepack enable + corepack install + - uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Resolve yarn cache folder + id: yarn-config + run: echo "cacheFolder=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT" + - name: Restore yarn install cache (node_modules + cacheFolder + install-state) + uses: actions/cache@v4 + with: + path: | + ${{ steps.yarn-config.outputs.cacheFolder }} + .yarn/install-state.gz + key: yarn-v2-${{ runner.os }}-node-20-${{ hashFiles('yarn.lock') }} + restore-keys: | + yarn-v2-${{ runner.os }}-node-20- + + - name: Set up kubectl + uses: azure/setup-kubectl@v4 + with: + version: 'v1.34.1' + + - name: Install k3d + run: | + curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash + k3d version | cat + + - name: Define cleanup functions + run: | + cat > /tmp/cleanup-functions.sh << 'CLEANUP_EOF' + light_cleanup() { + echo "--- Light cleanup ---" + rm -rf ./orchestrator-cache/* || true + docker system prune -f || true + df -h + } + + k8s_resource_cleanup() { + echo "--- K8s resource cleanup ---" + kubectl delete jobs --all --ignore-not-found=true -n default || true + kubectl get pods -n default -o name 2>/dev/null | grep -E "(unity-builder-job-|helper-pod-)" | while read pod; do + kubectl delete "$pod" --ignore-not-found=true || true + done || true + kubectl get pvc -n default -o name 2>/dev/null | grep "unity-builder-pvc-" | while read pvc; do + kubectl delete "$pvc" --ignore-not-found=true || true + done || true + kubectl get secrets -n default -o name 2>/dev/null | grep "build-credentials-" | while read secret; do + kubectl delete "$secret" --ignore-not-found=true || true + done || true + } + + k3d_node_cleanup() { + echo "--- K3d node image cleanup (preserving Unity images) ---" + K3D_NODE_CONTAINERS="${K3D_NODE_CONTAINERS:-k3d-unity-builder-agent-0 k3d-unity-builder-server-0}" + for NODE in $K3D_NODE_CONTAINERS; do + docker exec "$NODE" sh -c "crictl rm --all 2>/dev/null || true" || true + docker exec "$NODE" sh -c "for img in \$(crictl images -q 2>/dev/null); do repo=\$(crictl inspecti \$img --format '{{.repo}}' 2>/dev/null || echo ''); if echo \"\$repo\" | grep -qvE 'unityci/editor|unity'; then crictl rmi \$img 2>/dev/null || true; fi; done" || true + docker exec "$NODE" sh -c "crictl rmi --prune 2>/dev/null || true" || true + done || true + } + + full_k8s_cleanup() { + k8s_resource_cleanup + k3d_node_cleanup + light_cleanup + } + CLEANUP_EOF + echo "Cleanup functions defined at /tmp/cleanup-functions.sh" + + - name: Initial disk space cleanup + run: | + echo "Initial disk space cleanup..." + df -h + k3d cluster delete unity-builder || true + docker stop localstack-main 2>/dev/null || true + docker rm localstack-main 2>/dev/null || true + docker system prune -af --volumes || true + docker network rm orchestrator-net 2>/dev/null || true + docker network create orchestrator-net || true + echo "Disk usage after cleanup:" + df -h + + - name: Start MiniStack + run: | + echo "Starting MiniStack..." + docker run -d \ + --name localstack-main \ + --network orchestrator-net \ + --add-host=host.docker.internal:host-gateway \ + -p 4566:4566 \ + ministackorg/ministack:latest || true + echo "Waiting for MiniStack to be ready..." + MAX_ATTEMPTS=60 + READY=false + for i in $(seq 1 $MAX_ATTEMPTS); do + if ! docker ps | grep -q localstack-main; then sleep 2; continue; fi + HEALTH=$(curl -s http://localhost:4566/_localstack/health 2>/dev/null || echo "") + if [ -z "$HEALTH" ] || ! echo "$HEALTH" | grep -q "services"; then sleep 2; continue; fi + if echo "$HEALTH" | grep -q '"s3"'; then + echo "MiniStack is ready (attempt $i/$MAX_ATTEMPTS)" + READY=true + break + fi + sleep 2 + done + if [ "$READY" != "true" ]; then + echo "ERROR: MiniStack did not become ready" + docker logs localstack-main --tail 100 || true + exit 1 + fi + + - name: Install AWS CLI tools + run: | + if ! command -v aws > /dev/null 2>&1; then pip install awscli || true; fi + pip install awscli-local || true + + - name: Create S3 bucket for tests + run: | + for _ in {1..10}; do + if curl -s http://localhost:4566/_localstack/health > /dev/null 2>&1; then break; fi + sleep 1 + done + for _ in {1..5}; do + if command -v awslocal > /dev/null 2>&1; then + awslocal s3 mb s3://"$AWS_STACK_NAME" 2>&1 && break + else + aws --endpoint-url=http://localhost:4566 s3 mb s3://"$AWS_STACK_NAME" 2>&1 && break + fi + sleep 2 + done + + - run: yarn install --immutable + + - name: Build orchestrator + run: | + echo "Building orchestrator TypeScript..." + yarn build + echo "✓ orchestrator build successful" + + # --- Fast unit tests (fast-fail gate) --- + - name: Run orchestrator unit tests (fast, no infra) + timeout-minutes: 2 + run: >- + yarn vitest run + "orchestrator-guid" + "orchestrator-folders" + "task-parameter-serializer" + "follow-log-stream-service" + "runner-availability-service" + "provider-url-parser" + "provider-loader" + "provider-git-manager" + "orchestrator-image" + "orchestrator-hooks" + "orchestrator-github-checks" + "middleware-service" + --reporter=verbose --no-file-parallelism + + # --- K8s cluster setup --- + - name: Clean up disk space before K8s tests + run: | + rm -rf ./orchestrator-cache/* || true + sudo apt-get clean || true + docker system prune -f || true + df -h + + - name: Create k3s cluster (k3d) + timeout-minutes: 5 + run: | + LOCALSTACK_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' localstack-main 2>/dev/null || echo "") + echo "MiniStack container IP: $LOCALSTACK_IP" + k3d cluster create unity-builder \ + --agents 1 \ + --network orchestrator-net \ + --wait + kubectl config current-context | cat + echo "LOCALSTACK_IP=$LOCALSTACK_IP" >> "$GITHUB_ENV" + + - name: Verify cluster readiness and MiniStack connectivity + timeout-minutes: 2 + run: | + for i in {1..60}; do + if kubectl get nodes 2>/dev/null | grep -q Ready; then echo "Cluster is ready"; break; fi + echo "Waiting for cluster... ($i/60)" + sleep 5 + done + kubectl get nodes + LOCALSTACK_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' localstack-main 2>/dev/null || echo "") + kubectl run test-localstack --image=curlimages/curl --rm -i --restart=Never --timeout=30s -- \ + curl -v --max-time 10 http://"${LOCALSTACK_IP}":4566/_localstack/health 2>&1 | head -30 || \ + echo "Cluster connectivity test - MiniStack may not be accessible from k3d" + + - name: Clean up K8s resources before tests + run: | + source /tmp/cleanup-functions.sh + k8s_resource_cleanup + for _ in {1..30}; do + PVC_COUNT=$(kubectl get pvc -n default 2>/dev/null | grep -c "unity-builder-pvc-" || echo "0") + if [ "$PVC_COUNT" -eq 0 ]; then echo "All PVCs deleted"; break; fi + sleep 1 + done + docker system prune -f || true + + # --- K8s Test 1: orchestrator-image --- + - name: Run orchestrator-image test (K8s) + timeout-minutes: 10 + run: yarn run test "orchestrator-image" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneWindows64 + orchestratorTests: true + versioning: None + KUBE_STORAGE_CLASS: local-path + PROVIDER_STRATEGY: k8s + KUBE_VOLUME_SIZE: 2Gi + containerCpu: '512' + containerMemory: '512' + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-image (K8s) + if: always() + run: | + source /tmp/cleanup-functions.sh + full_k8s_cleanup + + # --- K8s Test 2: orchestrator-kubernetes --- + - name: Run orchestrator-kubernetes test + timeout-minutes: 30 + run: yarn run test "orchestrator-kubernetes" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + KUBE_STORAGE_CLASS: local-path + PROVIDER_STRATEGY: k8s + KUBE_VOLUME_SIZE: 2Gi + containerCpu: '1000' + containerMemory: '1024' + AWS_ACCESS_KEY_ID: test + AWS_SECRET_ACCESS_KEY: test + AWS_S3_ENDPOINT: http://localhost:4566 + AWS_ENDPOINT: http://localhost:4566 + INPUT_AWSS3ENDPOINT: http://localhost:4566 + INPUT_AWSENDPOINT: http://localhost:4566 + AWS_S3_FORCE_PATH_STYLE: 'true' + AWS_EC2_METADATA_DISABLED: 'true' + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-kubernetes + if: always() + run: | + source /tmp/cleanup-functions.sh + full_k8s_cleanup + + # --- K8s Test 3: orchestrator-s3-steps --- + - name: Run orchestrator-s3-steps test (K8s) + timeout-minutes: 30 + run: yarn run test "orchestrator-s3-steps" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + KUBE_STORAGE_CLASS: local-path + PROVIDER_STRATEGY: k8s + KUBE_VOLUME_SIZE: 2Gi + containerCpu: '1000' + containerMemory: '1024' + AWS_ACCESS_KEY_ID: test + AWS_SECRET_ACCESS_KEY: test + AWS_S3_ENDPOINT: http://localhost:4566 + AWS_ENDPOINT: http://localhost:4566 + INPUT_AWSS3ENDPOINT: http://localhost:4566 + INPUT_AWSENDPOINT: http://localhost:4566 + AWS_S3_FORCE_PATH_STYLE: 'true' + AWS_EC2_METADATA_DISABLED: 'true' + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-s3-steps (K8s) + if: always() + run: | + source /tmp/cleanup-functions.sh + full_k8s_cleanup + + # --- K8s Test 4: orchestrator-end2end-caching --- + - name: Run orchestrator-end2end-caching test (K8s) + timeout-minutes: 60 + continue-on-error: true + run: yarn run test "orchestrator-end2end-caching" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + KUBE_STORAGE_CLASS: local-path + PROVIDER_STRATEGY: k8s + KUBE_VOLUME_SIZE: 2Gi + containerCpu: '1000' + containerMemory: '1024' + AWS_ACCESS_KEY_ID: test + AWS_SECRET_ACCESS_KEY: test + AWS_S3_ENDPOINT: http://localhost:4566 + AWS_ENDPOINT: http://localhost:4566 + INPUT_AWSS3ENDPOINT: http://localhost:4566 + INPUT_AWSENDPOINT: http://localhost:4566 + AWS_S3_FORCE_PATH_STYLE: 'true' + AWS_EC2_METADATA_DISABLED: 'true' + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-end2end-caching (K8s) + if: always() + run: | + source /tmp/cleanup-functions.sh + full_k8s_cleanup + + # --- K8s Test 5: orchestrator-end2end-retaining --- + - name: Extra disk cleanup before retaining test + run: | + source /tmp/cleanup-functions.sh + full_k8s_cleanup + docker system prune -af --volumes || true + df -h + - name: Run orchestrator-end2end-retaining test (K8s) + timeout-minutes: 60 + continue-on-error: true + run: yarn run test "orchestrator-end2end-retaining" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + KUBE_STORAGE_CLASS: local-path + PROVIDER_STRATEGY: k8s + KUBE_VOLUME_SIZE: 2Gi + containerCpu: '1000' + containerMemory: '1024' + AWS_ACCESS_KEY_ID: test + AWS_SECRET_ACCESS_KEY: test + AWS_S3_ENDPOINT: http://localhost:4566 + AWS_ENDPOINT: http://localhost:4566 + INPUT_AWSS3ENDPOINT: http://localhost:4566 + INPUT_AWSENDPOINT: http://localhost:4566 + AWS_S3_FORCE_PATH_STYLE: 'true' + AWS_EC2_METADATA_DISABLED: 'true' + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-end2end-retaining (K8s) + if: always() + run: | + source /tmp/cleanup-functions.sh + full_k8s_cleanup + + # --- K8s teardown --- + - name: Delete k3d cluster and final cleanup + if: always() + run: | + k3d cluster delete unity-builder || true + docker stop localstack-main 2>/dev/null || true + docker rm localstack-main 2>/dev/null || true + docker system prune -af --volumes || true + df -h + + # ============================================================================ + # AWS/LOCALSTACK INTEGRATION TESTS + # ============================================================================ + aws-integration: + name: AWS Integration Tests + runs-on: ubuntu-latest + env: + AWS_ACCESS_KEY_ID: test + AWS_SECRET_ACCESS_KEY: test + AWS_ENDPOINT: http://localhost:4566 + AWS_ENDPOINT_URL: http://localhost:4566 + steps: + - name: Checkout orchestrator (matching branch) + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + ref: ${{ github.head_ref || github.ref_name }} + lfs: false + continue-on-error: true + id: orch-branch + + - name: Clean corrupted checkout + if: steps.orch-branch.outcome == 'failure' + run: rm -rf .git || true + + - name: Fallback to orchestrator main branch + if: steps.orch-branch.outcome == 'failure' + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + lfs: false + + - name: Install package manager (from package.json) + run: | + corepack enable + corepack install + - uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Resolve yarn cache folder + id: yarn-config + run: echo "cacheFolder=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT" + - name: Restore yarn install cache (node_modules + cacheFolder + install-state) + uses: actions/cache@v4 + with: + path: | + ${{ steps.yarn-config.outputs.cacheFolder }} + .yarn/install-state.gz + key: yarn-v2-${{ runner.os }}-node-20-${{ hashFiles('yarn.lock') }} + restore-keys: | + yarn-v2-${{ runner.os }}-node-20- + + - name: Define cleanup functions + run: | + cat > /tmp/cleanup-functions.sh << 'CLEANUP_EOF' + light_cleanup() { + echo "--- Light cleanup ---" + rm -rf ./orchestrator-cache/* || true + docker system prune -f || true + df -h + } + heavy_cleanup() { + echo "--- Heavy cleanup ---" + rm -rf ./orchestrator-cache/* || true + docker system prune -af --volumes || true + df -h + } + CLEANUP_EOF + + - name: Initial disk space cleanup + run: | + df -h + docker system prune -af --volumes || true + df -h + + - name: Start MiniStack + run: | + docker run -d \ + --name localstack-main \ + -p 4566:4566 \ + ministackorg/ministack:latest || true + MAX_ATTEMPTS=60 + for i in $(seq 1 $MAX_ATTEMPTS); do + HEALTH=$(curl -s http://localhost:4566/_localstack/health 2>/dev/null || echo "") + if echo "$HEALTH" | grep -q '"s3"'; then echo "MiniStack ready ($i/$MAX_ATTEMPTS)"; break; fi + sleep 2 + done + + - name: Install AWS CLI tools + run: | + if ! command -v aws > /dev/null 2>&1; then pip install awscli || true; fi + pip install awscli-local || true + + - name: Create S3 bucket for tests + run: | + for _ in {1..5}; do + if command -v awslocal > /dev/null 2>&1; then + awslocal s3 mb s3://"$AWS_STACK_NAME" 2>&1 && break + else + aws --endpoint-url=http://localhost:4566 s3 mb s3://"$AWS_STACK_NAME" 2>&1 && break + fi + sleep 2 + done + + - run: yarn install --immutable + + - name: Build orchestrator + run: | + echo "Building orchestrator TypeScript..." + yarn build + echo "✓ orchestrator build successful" + + # --- AWS Test 1: orchestrator-image --- + - name: Run orchestrator-image test (AWS) + timeout-minutes: 10 + run: yarn run test "orchestrator-image" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneWindows64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: aws + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-image (AWS) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- AWS Test 2: orchestrator-environment --- + - name: Run orchestrator-environment test (AWS) + timeout-minutes: 30 + run: yarn run test "orchestrator-environment" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneWindows64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: aws + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-environment (AWS) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- AWS Test 3: orchestrator-s3-steps --- + - name: Run orchestrator-s3-steps test (AWS) + timeout-minutes: 30 + run: yarn run test "orchestrator-s3-steps" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneWindows64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: aws + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-s3-steps (AWS) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- AWS Test 4: orchestrator-hooks --- + - name: Run orchestrator-hooks test (AWS) + timeout-minutes: 30 + run: yarn run test "orchestrator-hooks" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneWindows64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: aws + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-hooks (AWS) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- AWS Test 5: orchestrator-caching --- + - name: Run orchestrator-caching test (AWS) + timeout-minutes: 60 + run: yarn run test "orchestrator-caching" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneWindows64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: aws + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-caching (AWS) + if: always() + run: source /tmp/cleanup-functions.sh && heavy_cleanup + + # --- AWS Test 6: orchestrator-locking-core --- + - name: Run orchestrator-locking-core test (AWS) + timeout-minutes: 60 + run: yarn run test "orchestrator-locking-core" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneWindows64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: aws + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-locking-core (AWS) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- AWS Test 7: orchestrator-locking-get-locked --- + - name: Run orchestrator-locking-get-locked test (AWS) + timeout-minutes: 60 + run: yarn run test "orchestrator-locking-get-locked" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneWindows64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: aws + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-locking-get-locked (AWS) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # End-to-end tests (continue-on-error) — run LAST to prevent + # workspace corruption from affecting mandatory tests above. + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + # --- AWS Test 8: orchestrator-end2end-caching --- + - name: Run orchestrator-end2end-caching test (AWS) + timeout-minutes: 60 + continue-on-error: true + run: yarn run test "orchestrator-end2end-caching" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneWindows64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: aws + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-end2end-caching (AWS) + if: always() + run: source /tmp/cleanup-functions.sh && heavy_cleanup + + # --- AWS Test 9: orchestrator-end2end-retaining --- + - name: Run orchestrator-end2end-retaining test (AWS) + timeout-minutes: 60 + continue-on-error: true + run: yarn run test "orchestrator-end2end-retaining" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneWindows64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: aws + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-end2end-retaining (AWS) + if: always() + run: source /tmp/cleanup-functions.sh && heavy_cleanup + + # --- AWS Test 10: orchestrator-end2end-locking --- + - name: Run orchestrator-end2end-locking test (AWS) + timeout-minutes: 60 + continue-on-error: true + run: yarn run test "orchestrator-end2end-locking" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneWindows64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: aws + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-end2end-locking (AWS) + if: always() + run: source /tmp/cleanup-functions.sh && heavy_cleanup + + # --- Final cleanup --- + - name: Final cleanup + if: always() + run: | + docker stop localstack-main 2>/dev/null || true + docker rm localstack-main 2>/dev/null || true + docker system prune -af --volumes || true + df -h + + # ============================================================================ + # LOCAL-DOCKER INTEGRATION TESTS + # ============================================================================ + local-docker-integration: + name: Local Docker Integration Tests + runs-on: ubuntu-latest + env: + AWS_ACCESS_KEY_ID: test + AWS_SECRET_ACCESS_KEY: test + AWS_ENDPOINT: http://localhost:4566 + AWS_ENDPOINT_URL: http://localhost:4566 + steps: + - name: Checkout orchestrator (matching branch) + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + ref: ${{ github.head_ref || github.ref_name }} + lfs: false + continue-on-error: true + id: orch-branch + + - name: Clean corrupted checkout + if: steps.orch-branch.outcome == 'failure' + run: rm -rf .git || true + + - name: Fallback to orchestrator main branch + if: steps.orch-branch.outcome == 'failure' + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + lfs: false + + - name: Install package manager (from package.json) + run: | + corepack enable + corepack install + - uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Resolve yarn cache folder + id: yarn-config + run: echo "cacheFolder=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT" + - name: Restore yarn install cache (node_modules + cacheFolder + install-state) + uses: actions/cache@v4 + with: + path: | + ${{ steps.yarn-config.outputs.cacheFolder }} + .yarn/install-state.gz + key: yarn-v2-${{ runner.os }}-node-20-${{ hashFiles('yarn.lock') }} + restore-keys: | + yarn-v2-${{ runner.os }}-node-20- + + - name: Define cleanup functions + run: | + cat > /tmp/cleanup-functions.sh << 'CLEANUP_EOF' + light_cleanup() { + echo "--- Light cleanup ---" + rm -rf ./orchestrator-cache/* || true + docker system prune -f || true + df -h + } + heavy_cleanup() { + echo "--- Heavy cleanup ---" + rm -rf ./orchestrator-cache/* || true + docker system prune -af --volumes || true + df -h + } + CLEANUP_EOF + + - name: Initial disk space cleanup + run: | + df -h + docker system prune -af --volumes || true + df -h + + - name: Start MiniStack (for S3-dependent tests) + run: | + docker run -d \ + --name localstack-main \ + -p 4566:4566 \ + ministackorg/ministack:latest || true + MAX_ATTEMPTS=60 + for i in $(seq 1 $MAX_ATTEMPTS); do + HEALTH=$(curl -s http://localhost:4566/_localstack/health 2>/dev/null || echo "") + if echo "$HEALTH" | grep -q '"s3"'; then echo "MiniStack ready ($i/$MAX_ATTEMPTS)"; break; fi + sleep 2 + done + + - name: Install AWS CLI tools + run: | + if ! command -v aws > /dev/null 2>&1; then pip install awscli || true; fi + pip install awscli-local || true + + - name: Create S3 bucket for tests + run: | + for _ in {1..5}; do + if command -v awslocal > /dev/null 2>&1; then + awslocal s3 mb s3://"$AWS_STACK_NAME" 2>&1 && break + else + aws --endpoint-url=http://localhost:4566 s3 mb s3://"$AWS_STACK_NAME" 2>&1 && break + fi + sleep 2 + done + + - run: yarn install --immutable + + - name: Build orchestrator + run: | + yarn build + echo "✓ orchestrator build successful" + + # --- Local Docker Test 1: orchestrator-image --- + - name: Run orchestrator-image test (local-docker) + timeout-minutes: 10 + run: yarn run test "orchestrator-image" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: local-docker + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-image (local-docker) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- Local Docker Test 2: orchestrator-hooks --- + - name: Run orchestrator-hooks test (local-docker) + timeout-minutes: 30 + run: yarn run test "orchestrator-hooks" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: local-docker + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-hooks (local-docker) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- Local Docker Test 3: orchestrator-local-persistence --- + - name: Run orchestrator-local-persistence test (local-docker) + timeout-minutes: 30 + run: yarn run test "orchestrator-local-persistence" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: local-docker + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-local-persistence (local-docker) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- Local Docker Test 4: orchestrator-caching --- + - name: Run orchestrator-caching test (local-docker) + timeout-minutes: 30 + run: yarn run test "orchestrator-caching" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: local-docker + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-caching (local-docker) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- Local Docker Test 5: orchestrator-github-checks --- + - name: Run orchestrator-github-checks test (local-docker) + timeout-minutes: 30 + run: yarn run test "orchestrator-github-checks" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: local-docker + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-github-checks (local-docker) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- Local Docker Test 6: orchestrator-locking-core (with S3) --- + - name: Run orchestrator-locking-core test (local-docker + S3) + timeout-minutes: 30 + run: yarn run test "orchestrator-locking-core" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: local-docker + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-locking-core (local-docker) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- Local Docker Test 7: orchestrator-locking-get-locked (with S3) --- + - name: Run orchestrator-locking-get-locked test (local-docker + S3) + timeout-minutes: 30 + run: yarn run test "orchestrator-locking-get-locked" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: local-docker + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-locking-get-locked (local-docker) + if: always() + run: source /tmp/cleanup-functions.sh && light_cleanup + + # --- Local Docker Test 8: orchestrator-s3-steps (with S3) --- + - name: Run orchestrator-s3-steps test (local-docker + S3) + timeout-minutes: 30 + run: yarn run test "orchestrator-s3-steps" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: local-docker + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-s3-steps (local-docker) + if: always() + run: source /tmp/cleanup-functions.sh && heavy_cleanup + + # --- Local Docker Test 9: orchestrator-end2end-caching (with S3) --- + - name: Run orchestrator-end2end-caching test (local-docker + S3) + timeout-minutes: 60 + continue-on-error: true + run: yarn run test "orchestrator-end2end-caching" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: local-docker + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + - name: Cleanup after orchestrator-end2end-caching (local-docker) + if: always() + run: source /tmp/cleanup-functions.sh && heavy_cleanup + + # --- Final cleanup --- + - name: Final cleanup + if: always() + run: | + docker stop localstack-main 2>/dev/null || true + docker rm localstack-main 2>/dev/null || true + docker system prune -af --volumes || true + df -h + + # ============================================================================ + # RCLONE INTEGRATION TESTS + # ============================================================================ + rclone-integration: + name: Rclone Integration Tests + runs-on: ubuntu-latest + env: + AWS_ACCESS_KEY_ID: test + AWS_SECRET_ACCESS_KEY: test + AWS_ENDPOINT: http://localhost:4566 + AWS_ENDPOINT_URL: http://localhost:4566 + steps: + - name: Checkout orchestrator (matching branch) + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + ref: ${{ github.head_ref || github.ref_name }} + lfs: false + continue-on-error: true + id: orch-branch + + - name: Clean corrupted checkout + if: steps.orch-branch.outcome == 'failure' + run: rm -rf .git || true + + - name: Fallback to orchestrator main branch + if: steps.orch-branch.outcome == 'failure' + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + lfs: false + + - name: Install package manager (from package.json) + run: | + corepack enable + corepack install + - uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Resolve yarn cache folder + id: yarn-config + run: echo "cacheFolder=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT" + - name: Restore yarn install cache (node_modules + cacheFolder + install-state) + uses: actions/cache@v4 + with: + path: | + ${{ steps.yarn-config.outputs.cacheFolder }} + .yarn/install-state.gz + key: yarn-v2-${{ runner.os }}-node-20-${{ hashFiles('yarn.lock') }} + restore-keys: | + yarn-v2-${{ runner.os }}-node-20- + + - name: Initial disk space cleanup + run: | + docker system prune -af --volumes || true + df -h + + - name: Start MiniStack + run: | + docker run -d \ + --name localstack-main \ + -p 4566:4566 \ + ministackorg/ministack:latest || true + MAX_ATTEMPTS=60 + for i in $(seq 1 $MAX_ATTEMPTS); do + HEALTH=$(curl -s http://localhost:4566/_localstack/health 2>/dev/null || echo "") + if echo "$HEALTH" | grep -q '"s3"'; then echo "MiniStack ready ($i/$MAX_ATTEMPTS)"; break; fi + sleep 2 + done + + - name: Install rclone + run: | + curl https://rclone.org/install.sh | sudo bash || true + rclone version || echo "rclone not available" + + - name: Install AWS CLI tools + run: | + if ! command -v aws > /dev/null 2>&1; then pip install awscli || true; fi + pip install awscli-local || true + + - name: Create S3 bucket for tests + run: | + for _ in {1..5}; do + if command -v awslocal > /dev/null 2>&1; then + awslocal s3 mb s3://"$AWS_STACK_NAME" 2>&1 && break + else + aws --endpoint-url=http://localhost:4566 s3 mb s3://"$AWS_STACK_NAME" 2>&1 && break + fi + sleep 2 + done + + - run: yarn install --immutable + + - name: Build orchestrator + run: | + yarn build + echo "✓ orchestrator build successful" + + # --- Rclone Test --- + - name: Run orchestrator-rclone-steps test + timeout-minutes: 30 + run: yarn run test "orchestrator-rclone-steps" --no-file-parallelism + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + TARGET_PLATFORM: StandaloneLinux64 + orchestratorTests: true + versioning: None + PROVIDER_STRATEGY: local-docker + GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }} + + # --- Final cleanup --- + - name: Final cleanup + if: always() + run: | + docker stop localstack-main 2>/dev/null || true + docker rm localstack-main 2>/dev/null || true + docker system prune -af --volumes || true + df -h diff --git a/.github/workflows/validate-orchestrator.yml b/.github/workflows/validate-orchestrator.yml new file mode 100644 index 0000000..61f7a2f --- /dev/null +++ b/.github/workflows/validate-orchestrator.yml @@ -0,0 +1,255 @@ +name: Validate Orchestrator Compatibility + +# ============================================================================== +# Essential plugin health checks — runs on every PR and push. +# Fast (~5 min): compilation, unit tests, plugin interface, type declarations. +# +# For exhaustive integration tests (k8s, AWS, local-docker, rclone) see +# validate-orchestrator-integration.yml which runs on a daily cron. +# ============================================================================== + +on: + workflow_dispatch: + push: + branches: [main, 'release/**', 'feature/**', 'refactor/**'] + paths: + - 'src/model/orchestrator-plugin.ts' + - 'src/model/build-parameters.ts' + - 'src/model/input.ts' + - 'src/model/github.ts' + - 'src/model/cli/cli.ts' + - 'src/model/input-readers/**' + - 'src/index.ts' + - 'src/types/game-ci-orchestrator.d.ts' + - 'action.yml' + - 'package.json' + - 'yarn.lock' + - '.github/workflows/validate-orchestrator.yml' + pull_request: + branches: [main, 'release/**'] + paths: + - 'src/model/orchestrator-plugin.ts' + - 'src/model/build-parameters.ts' + - 'src/model/input.ts' + - 'src/model/github.ts' + - 'src/model/cli/cli.ts' + - 'src/model/input-readers/**' + - 'src/index.ts' + - 'src/types/game-ci-orchestrator.d.ts' + - 'action.yml' + - 'package.json' + - 'yarn.lock' + - '.github/workflows/validate-orchestrator.yml' + +permissions: + contents: read + packages: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + # ============================================================================ + # PLUGIN ARCHITECTURE HEALTH CHECK + # ============================================================================ + # Validates that: + # 1. unity-builder compiles and its unit tests pass + # 2. Plugin loader degrades gracefully without orchestrator + # 3. Orchestrator compiles and its unit tests pass + # 4. Plugin loader loads all services when orchestrator is installed + # 5. Type declarations match actual exports + # ============================================================================ + plugin-health: + name: Plugin Architecture Health + runs-on: ubuntu-latest + steps: + - name: Checkout unity-builder + uses: actions/checkout@v4 + + - name: Checkout orchestrator + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + ref: ${{ github.head_ref || github.ref_name }} + path: orchestrator-standalone + continue-on-error: true + id: orchestrator-branch + + - name: Fallback to orchestrator main branch + if: steps.orchestrator-branch.outcome == 'failure' + uses: actions/checkout@v4 + with: + repository: game-ci/orchestrator + path: orchestrator-standalone + + - name: Install package manager (from package.json) + run: | + corepack enable + corepack install + - uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Resolve yarn cache folder + id: yarn-config + run: echo "cacheFolder=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT" + - name: Restore yarn install cache (node_modules + cacheFolder + install-state) + uses: actions/cache@v4 + with: + path: | + ${{ steps.yarn-config.outputs.cacheFolder }} + .yarn/install-state.gz + key: yarn-v2-${{ runner.os }}-node-20-${{ hashFiles('yarn.lock') }} + restore-keys: | + yarn-v2-${{ runner.os }}-node-20- + + # --- unity-builder compilation and tests --- + - name: Install unity-builder dependencies + env: + YARN_ENABLE_HARDENED_MODE: 'false' + run: | + case "$(yarn --version)" in 1.*) echo 'expected up-to-date yarn version'; exit 1 ;; esac + yarn install --immutable + + - name: Build unity-builder + run: | + echo "Building unity-builder TypeScript..." + npx tsc + echo "✓ unity-builder compiles successfully" + + - name: Run orchestrator-plugin unit tests + run: | + echo "Running orchestrator-plugin unit tests..." + yarn vitest run orchestrator-plugin + + # --- Plugin loader without orchestrator --- + - name: Verify plugin loader returns undefined without orchestrator + run: | + echo "Checking plugin loader handles missing @game-ci/orchestrator..." + node -e " + const { loadOrchestratorPlugin } = require('./lib/model/orchestrator-plugin'); + (async () => { + const plugin = await loadOrchestratorPlugin(); + if (plugin !== undefined) { + console.error('ERROR: loadOrchestratorPlugin should return undefined when package not installed'); + process.exit(1); + } + console.log('✓ loadOrchestratorPlugin() returns undefined when package not installed'); + })(); + " + + - name: Verify orchestrator type declarations exist + run: | + if [ -f "src/types/game-ci-orchestrator.d.ts" ]; then + echo "✓ Type declarations for @game-ci/orchestrator exist" + else + echo "::error::Missing type declarations: src/types/game-ci-orchestrator.d.ts" + exit 1 + fi + + # --- Orchestrator compilation and tests --- + - name: Build and pack orchestrator + working-directory: orchestrator-standalone + run: | + yarn install --immutable + echo "Building orchestrator..." + npx tsc + echo "✓ orchestrator compiles successfully" + echo "Packing orchestrator as tarball..." + npm pack + + - name: Run orchestrator unit tests + working-directory: orchestrator-standalone + run: | + echo "Running orchestrator unit tests..." + yarn vitest run 2>&1 | tail -30 + + # --- Plugin loader with orchestrator installed --- + - name: Install orchestrator into unity-builder + run: | + echo "Installing orchestrator into unity-builder workspace..." + npm install ./orchestrator-standalone/game-ci-orchestrator-*.tgz --no-save --legacy-peer-deps + + - name: Verify plugin loader returns exports with orchestrator installed + run: | + echo "Checking plugin loader returns defined exports..." + node -e " + const { loadOrchestratorPlugin } = require('./lib/model/orchestrator-plugin'); + (async () => { + const plugin = await loadOrchestratorPlugin(); + if (plugin === undefined) { + console.error('ERROR: loadOrchestratorPlugin should return defined plugin when package is installed'); + process.exit(1); + } + const lifecycleMethods = [ + 'initialize', 'canHandleBuild', 'handleBuild', + 'beforeLocalBuild', 'afterLocalBuild', 'handlePostBuild', + ]; + for (const method of lifecycleMethods) { + if (typeof plugin[method] !== 'function') { + console.error('ERROR: plugin.' + method + ' should be a function, got ' + typeof plugin[method]); + process.exit(1); + } + } + console.log('✓ loadOrchestratorPlugin() returns plugin with all ' + lifecycleMethods.length + ' lifecycle methods'); + })(); + " + + - name: Verify type declarations match orchestrator exports + run: | + echo "Checking type declarations align with orchestrator exports..." + node -e " + const orch = require('@game-ci/orchestrator'); + const expectedExports = [ + 'Orchestrator', 'BuildReliabilityService', 'TestWorkflowService', + 'HotRunnerService', 'OutputService', 'OutputTypeRegistry', + 'ArtifactUploadHandler', 'IncrementalSyncService', + 'ChildWorkspaceService', 'LocalCacheService', 'SubmoduleProfileService', + 'LfsAgentService', 'GitHooksService', + ]; + const missing = expectedExports.filter(e => orch[e] === undefined); + if (missing.length > 0) { + console.error('ERROR: Missing exports from @game-ci/orchestrator:', missing.join(', ')); + process.exit(1); + } + console.log('✓ All ' + expectedExports.length + ' declared exports present in orchestrator package'); + " + + - name: Smoke test orchestrator build wiring + run: | + echo "Verifying orchestrator build wiring end-to-end..." + node -e " + const { loadOrchestratorPlugin } = require('./lib/model/orchestrator-plugin'); + + (async () => { + // Verify plugin loads successfully with orchestrator installed + const plugin = await loadOrchestratorPlugin(); + if (plugin === undefined) { + console.error('ERROR: plugin should be defined when orchestrator is installed'); + process.exit(1); + } + + // Verify all lifecycle methods are callable + const lifecycleMethods = [ + 'initialize', 'canHandleBuild', 'handleBuild', + 'beforeLocalBuild', 'afterLocalBuild', 'handlePostBuild', + ]; + for (const m of lifecycleMethods) { + if (typeof plugin[m] !== 'function') { + console.error('ERROR: plugin.' + m + ' should be a function, got ' + typeof plugin[m]); + process.exit(1); + } + } + console.log('✓ Plugin has all ' + lifecycleMethods.length + ' lifecycle methods'); + + // Verify canHandleBuild returns a boolean + const canHandle = plugin.canHandleBuild(); + if (typeof canHandle !== 'boolean') { + console.error('ERROR: canHandleBuild() should return a boolean, got ' + typeof canHandle); + process.exit(1); + } + console.log('✓ canHandleBuild() returns boolean'); + + console.log('✓ Plugin architecture wiring verified'); + })(); + " diff --git a/.github/workflows/versioning.yml b/.github/workflows/versioning.yml new file mode 100644 index 0000000..2ead694 --- /dev/null +++ b/.github/workflows/versioning.yml @@ -0,0 +1,12 @@ +name: Versioning + +on: + release: + types: [published, edited] + +jobs: + updateMajorTag: + name: Update major tag + runs-on: ubuntu-latest + steps: + - uses: Actions-R-Us/actions-tagger@v2 diff --git a/.gitignore b/.gitignore index 90e072c..8b37de6 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,13 @@ yarn-error.log .orig $LOG_FILE temp/ -**/.DS_Store \ No newline at end of file + +# yarn 4 (berry) +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions +dist/.DS_Store diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..baa6797 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,7 @@ +#!/usr/bin/env sh +yarn lint-staged +yarn typecheck + +if command -v gitleaks >/dev/null 2>&1; then + gitleaks protect --staged --no-banner --redact +fi diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 0000000..3bf1670 --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,17 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "all", + "printWidth": 100, + "proseWrap": "preserve", + "sortPackageJson": false, + "ignorePatterns": [ + "**/node_modules/**", + "**/dist/**", + "**/coverage/**", + "**/.yarn/**", + "default-build-script/**", + "test-runner/**", + "platforms/**" + ] +} diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 0000000..0b83443 --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,58 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript", "vitest", "unicorn", "oxc"], + "categories": { + "correctness": "error", + "suspicious": "error", + "perf": "error" + }, + "rules": { + "vitest/require-mock-type-parameters": "off", + "vitest/valid-title": "off", + "vitest/valid-describe-callback": "off", + "vitest/expect-expect": "off", + "vitest/no-conditional-tests": "off", + "vitest/no-conditional-expect": "off", + "vitest/require-to-throw-message": "off", + "vitest/no-disabled-tests": "warn", + "unicorn/prefer-array-flat-map": "warn", + "typescript/no-explicit-any": "warn", + "typescript/ban-ts-comment": "off", + "typescript/no-namespace": "off", + "typescript/no-extraneous-class": "off", + "no-bitwise": "off", + "no-shadow": "off", + "no-await-in-loop": "off", + "no-underscore-dangle": "off", + "unicorn/no-array-sort": "off", + "unicorn/prefer-set-has": "off", + "unicorn/consistent-function-scoping": "off", + "unicorn/no-useless-spread": "warn", + "eslint/preserve-caught-error": "warn", + "oxc/no-map-spread": "warn" + }, + "overrides": [ + { + "files": ["**/*.test.ts", "**/*.spec.ts"], + "rules": { + "typescript/no-explicit-any": "off", + "no-unused-vars": "off" + } + } + ], + "env": { + "browser": false, + "node": true, + "es2024": true, + "vitest/globals": true + }, + "ignorePatterns": [ + "**/node_modules/**", + "**/dist/**", + "**/coverage/**", + "**/.yarn/**", + "default-build-script/**", + "test-runner/**", + "platforms/**" + ] +} diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index cb3fd15..0000000 --- a/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -**/node_modules/** -**/dist/** diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 23de5df..0000000 --- a/.prettierrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "semi": true, - "singleQuote": true, - "trailingComma": "all", - "printWidth": 120, - "proseWrap": "always" -} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..ade9bd7 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,32 @@ +{ + "configurations": [ + { + "name": "PowerShell Launch Current File", + "type": "PowerShell", + "request": "launch", + "script": "${file}", + "cwd": "${cwd}" + }, + { + "type": "node", + "request": "launch", + "name": "Debug Jest Test", + "program": "${workspaceRoot}/node_modules/jest/bin/jest.js", + "args": [ + "--collectCoverage=false", + "--colors", + "--config", + "${workspaceRoot}/jest.config.js", + "--runInBand", + "--runTestsByPath", + "${relativeFile}", + "--testPathPattern=${fileDirname}", + "--testTimeout=10000000" + ], + "outputCapture": "std", + "internalConsoleOptions": "openOnSessionStart", + "envFile": "${workspaceRoot}/.env", + "skipFiles": ["${workspaceRoot}/../../node_modules/**/*", "/**/*"] + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5a33b7a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,33 @@ +{ + "files.eol": "\n", + "god.tsconfig": "./tsconfig.json", + "yaml.customTags": [ + "!And", + "!And sequence", + "!If", + "!If sequence", + "!Not", + "!Not sequence", + "!Equals", + "!Equals sequence", + "!Or", + "!Or sequence", + "!FindInMap", + "!FindInMap sequence", + "!Base64", + "!Join", + "!Join sequence", + "!Cidr", + "!Ref", + "!Sub", + "!Sub sequence", + "!GetAtt", + "!GetAZs", + "!ImportValue", + "!ImportValue sequence", + "!Select", + "!Select sequence", + "!Split", + "!Split sequence" + ] +} diff --git a/.yarnrc b/.yarnrc deleted file mode 100644 index 7cd45b8..0000000 --- a/.yarnrc +++ /dev/null @@ -1,3 +0,0 @@ -save-prefix "^" ---install.audit true ---add.audit true diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 0000000..e002c33 --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1,10 @@ +approvedGitRepositories: + - '**' + +compressionLevel: mixed + +enableGlobalCache: false + +enableHardenedMode: false + +nodeLinker: node-modules diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..a5bb987 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at webber@takken.io. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..a9228ba --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,44 @@ +# Contributing + +## How to Contribute + +#### Code of Conduct + +This repository has adopted the Contributor Covenant as it's Code of Conduct. It is expected that participants adhere to +it. + +#### Proposing a Change + +If you are unsure about whether or not a change is desired, you can create an issue. This is useful because it creates +the possibility for a discussion that's visible to everyone. + +When fixing a bug it is fine to submit a pull request right away. + +#### Sending a Pull Request + +Steps to be performed to submit a pull request: + +1. Fork the repository and create your branch from `main`. +2. Run `yarn` in the repository root. +3. If you've fixed a bug or added code that should be tested, add tests! +4. Fill out the description, link any related issues and submit your pull request. + +#### Pull Request Prerequisites + +You have [Node](https://nodejs.org/) installed at v18+ and [Yarn](https://yarnpkg.com/) at v1.22.0+. + +Please note that commit hooks will run automatically to perform some tasks; + +- format your code +- run tests +- build distributable files + +#### Windows users + +Make sure your editor and terminal that run the tests are set to `Powershell 7` or above with +`Git's Unix tools for Windows` installed. This is because some tests require you to be able to run `sh` and other +unix commands. + +#### License + +By contributing to this repository, you agree that your contributions will be licensed under its MIT license. diff --git a/LICENSE b/LICENSE index bdd644b..2835022 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,6 @@ -The MIT License (MIT) +MIT License Copyright (c) 2019-present Webber Takken -Copyright (c) 2026 StepSecurity Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -10,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index b7c14d1..de6becf 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,54 @@ # Unity - Builder [![StepSecurity Maintained Action](https://raw.githubusercontent.com/step-security/maintained-actions-assets/main/assets/maintained-action-banner.png)](https://docs.stepsecurity.io/actions/stepsecurity-maintained-actions) +(Not affiliated with Unity Technologies) -## How to use +GitHub Action to +[build Unity projects](https://github.com/marketplace/actions/unity-builder) +for different platforms. + +Part of the GameCI open source project. +
+
-```yml -name: Actions 😎 - -on: [push, pull_request] - -jobs: - build: - name: Build my project ✨ - runs-on: ubuntu-latest - steps: - # Checkout - - name: Checkout repository - uses: actions/checkout@v6 - with: - lfs: true - - # Cache - - uses: actions/cache@v5 - with: - path: Library - key: Library-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }} - restore-keys: | - Library- - - # Test - - name: Run tests - uses: game-ci/unity-test-runner@v4 - env: - UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} - UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} - UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} - with: - githubToken: ${{ secrets.GITHUB_TOKEN }} - - # Build - - name: Build project - uses: step-security/unity-builder@v4 - env: - UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} - UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} - UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} - with: - targetPlatform: WebGL - - # Output - - uses: actions/upload-artifact@v7 - with: - name: Build - path: build -``` +[![Builds - Ubuntu](https://github.com/game-ci/unity-builder/actions/workflows/build-tests-ubuntu.yml/badge.svg)](https://github.com/game-ci/unity-builder/actions/workflows/build-tests-ubuntu.yml) +[![Builds - Windows](https://github.com/game-ci/unity-builder/actions/workflows/build-tests-windows.yml/badge.svg)](https://github.com/game-ci/unity-builder/actions/workflows/build-tests-windows.yml) +[![Builds - MacOS](https://github.com/game-ci/unity-builder/actions/workflows/build-tests-mac.yml/badge.svg)](https://github.com/game-ci/unity-builder/actions/workflows/build-tests-mac.yml) +[![codecov - test coverage](https://codecov.io/gh/game-ci/unity-builder/branch/master/graph/badge.svg)](https://codecov.io/gh/game-ci/unity-builder) +
+
+ +## How to use Find the [docs](https://game.ci/docs/github/builder) on the GameCI [documentation website](https://game.ci/docs). +## Related actions + +Visit the +GameCI Unity Actions +status repository for related Actions. + +## Community + +Feel free to join us on +Discord +and engage with the community. + +## Contributing + +To help improve the documentation, please find the docs [repository](https://github.com/game-ci/documentation). + +To contribute to Unity Builder, kindly read the [contribution guide](./CONTRIBUTING.md). + +## Support us + +GameCI is free for everyone forever. + +You can support us at [OpenCollective](https://opencollective.com/game-ci). + ## Licence This repository is [MIT](./LICENSE) licensed. diff --git a/action.yml b/action.yml index 3b7b149..0959514 100644 --- a/action.yml +++ b/action.yml @@ -9,8 +9,7 @@ inputs: unityVersion: required: false default: 'auto' - description: - 'Version of unity to use for building the project. Use "auto" to get from your ProjectSettings/ProjectVersion.txt' + description: 'Version of unity to use for building the project. Use "auto" to get from your ProjectSettings/ProjectVersion.txt' customImage: required: false default: '' @@ -47,6 +46,10 @@ inputs: required: false default: '' description: 'Custom parameters to configure the build.' + useHostNetwork: + required: false + default: false + description: 'Initialises Docker using the host network. (Linux only)' versioning: required: false default: 'Semantic' @@ -104,11 +107,13 @@ inputs: gitPrivateToken: required: false default: '' - description: '[Orchestrator] Github private token to pull from github' - githubOwner: + description: 'Github private token to pull from github' + providerStrategy: + default: 'local' required: false - default: '' - description: '[Orchestrator] GitHub owner name or organization/team name' + description: + 'Build execution strategy. Use "local" for local Docker/Mac builds. For remote builds (aws, k8s, etc.), install + @game-ci/orchestrator and use the game-ci/orchestrator action which declares its own inputs.' runAsHostUser: required: false default: 'false' @@ -118,8 +123,7 @@ inputs: chownFilesTo: required: false default: '' - description: - 'User and optionally group (user or user:group or uid:gid) to give ownership of the resulting build artifacts' + description: 'User and optionally group (user or user:group or uid:gid) to give ownership of the resulting build artifacts' dockerCpuLimit: required: false default: '' @@ -149,102 +153,7 @@ inputs: allowDirtyBuild: required: false default: '' - description: '[Orchestrator] Allows the branch of the build to be dirty, and still generate the build.' - postBuildSteps: - required: false - default: '' - description: - '[Orchestrator] run a post build job in yaml format with the keys image, secrets (name, value object array), - command string' - preBuildSteps: - required: false - default: '' - description: - '[Orchestrator] Run a pre build job after the repository setup but before the build job (in yaml format with the - keys image, secrets (name, value object array), command line string)' - containerHookFiles: - required: false - default: '' - description: - '[Orchestrator] Specify the names (by file name) of custom steps to run before or after orchestrator jobs, must - match a yaml step file inside your repo in the folder .game-ci/steps/' - customHookFiles: - required: false - default: '' - description: - '[Orchestrator] Specify the names (by file name) of custom hooks to run before or after orchestrator jobs, must - match a yaml step file inside your repo in the folder .game-ci/hooks/' - customCommandHooks: - required: false - default: '' - description: '[Orchestrator] Specify custom commands and trigger hooks (injects commands into jobs)' - customJob: - required: false - default: '' - description: - '[Orchestrator] Run a custom job instead of the standard build automation for orchestrator (in yaml format with the - keys image, secrets (name, value object array), command line string)' - awsStackName: - default: 'game-ci' - required: false - description: '[Orchestrator] The Cloud Formation stack name that must be setup before using this option.' - providerStrategy: - default: 'local' - required: false - description: - '[Orchestrator] Either local, k8s or aws can be used to run builds on a remote cluster. Additional parameters must - be configured.' - resourceTracking: - default: 'false' - required: false - description: '[Orchestrator] Enable resource tracking logs for disk usage and allocation summaries.' - containerCpu: - default: '' - required: false - description: '[Orchestrator] Amount of CPU time to assign the remote build container' - containerMemory: - default: '' - required: false - description: '[Orchestrator] Amount of memory to assign the remote build container' - readInputFromOverrideList: - default: '' - required: false - description: '[Orchestrator] Comma separated list of input value names to read from "input override command"' - readInputOverrideCommand: - default: '' - required: false - description: - '[Orchestrator] Extend game ci by specifying a command to execute to pull input from external source e.g cloud - provider secret managers' - kubeConfig: - default: '' - required: false - description: - '[Orchestrator] Supply a base64 encoded kubernetes config to run builds on kubernetes and stream logs until - completion.' - kubeVolume: - default: '' - required: false - description: '[Orchestrator] Supply a Persistent Volume Claim name to use for the Unity build.' - kubeStorageClass: - default: '' - required: false - description: - '[Orchestrator] Kubernetes storage class to use for orchestrator jobs, leave empty to install rook cluster.' - kubeVolumeSize: - default: '5Gi' - required: false - description: '[Orchestrator] Amount of disc space to assign the Kubernetes Persistent Volume' - cacheKey: - default: '' - required: false - description: '[Orchestrator] Cache key to indicate bucket for cache' - watchToEnd: - default: 'true' - required: false - description: - '[Orchestrator] Whether or not to watch the build to the end. Can be used for especially long running jobs e.g - imports or self-hosted ephemeral runners.' + description: 'Allows the branch of the build to be dirty, and still generate the build.' cacheUnityInstallationOnMac: default: 'false' required: false @@ -269,16 +178,11 @@ inputs: default: 'false' required: false description: 'Skip the activation/deactivation of Unity. This assumes Unity is already activated.' - cloneDepth: - default: '50' - required: false - description: '[Orchestrator] Specifies the depth of the git clone for the repository. Use 0 for full clone.' - orchestratorRepoName: - default: 'step-security/unity-builder' + linux64RemoveExecutableExtension: + default: 'false' required: false description: - '[Orchestrator] Specifies the repo for the unity builder. Useful if you forked the repo for testing, features, or - fixes.' + 'When building for StandaloneLinux64, remove the default file extension of `.x86_64`. Set to true to restore the extensionless behavior from v4.' outputs: volume: diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..9c5e80b --- /dev/null +++ b/codecov.yml @@ -0,0 +1,39 @@ +codecov: + require_ci_to_pass: yes + +coverage: + precision: 2 + round: down + range: '70...100' + + status: + patch: + default: + # basic + target: auto + threshold: 100% # don't require patch to have coverage per se + base: auto + + project: + default: + # basic + target: auto + threshold: 5% + base: auto + flags: + - unit + paths: + - 'src' + +parsers: + gcov: + branch_detection: + conditional: yes + loop: yes + method: no + macro: no + +comment: + layout: 'reach,diff,flags,tree' + behavior: default + require_changes: no diff --git a/community-plugins.yml b/community-plugins.yml new file mode 100644 index 0000000..45a028b --- /dev/null +++ b/community-plugins.yml @@ -0,0 +1,27 @@ +# Community Plugin Validation Registry +# Packages listed here are automatically tested on a schedule +# to ensure compatibility with unity-builder. +# +# Format: +# - name: Human-readable name +# package: UPM package name or git URL +# source: upm | git | asset-store +# unity: Minimum Unity version (optional, defaults to 2021.3) +# platforms: List of platforms to test (optional, defaults to [StandaloneLinux64]) +# timeout: Build timeout in minutes (optional, defaults to 30) + +plugins: + # Example entries — community members can submit PRs to add their packages + - name: UniTask + package: https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask + source: git + platforms: [StandaloneLinux64, StandaloneWindows64] + + - name: NaughtyAttributes + package: https://github.com/dbrizov/NaughtyAttributes.git?path=Assets/NaughtyAttributes + source: git + + - name: Unity Atoms + package: https://github.com/unity-atoms/unity-atoms.git + source: git + platforms: [StandaloneLinux64] diff --git a/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/AndroidSettings.cs b/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/AndroidSettings.cs index 258f66c..8317dee 100644 --- a/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/AndroidSettings.cs +++ b/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/AndroidSettings.cs @@ -1,150 +1,150 @@ -using System; -using System.Collections.Generic; -using UnityEditor; -using System.Reflection; - -namespace UnityBuilderAction.Input -{ - public static class AndroidSettings - { - public static void Apply(Dictionary options) - { -#if UNITY_2019_1_OR_NEWER - if (options.TryGetValue("androidKeystoreName", out string keystoreName) && !string.IsNullOrEmpty(keystoreName)) - { - PlayerSettings.Android.useCustomKeystore = true; - PlayerSettings.Android.keystoreName = keystoreName; - } -#endif - // Can't use out variable declaration as Unity 2018 doesn't support it - string keystorePass; - if (options.TryGetValue("androidKeystorePass", out keystorePass) && !string.IsNullOrEmpty(keystorePass)) - PlayerSettings.Android.keystorePass = keystorePass; - - string keyaliasName; - if (options.TryGetValue("androidKeyaliasName", out keyaliasName) && !string.IsNullOrEmpty(keyaliasName)) - PlayerSettings.Android.keyaliasName = keyaliasName; - - string keyaliasPass; - if (options.TryGetValue("androidKeyaliasPass", out keyaliasPass) && !string.IsNullOrEmpty(keyaliasPass)) - PlayerSettings.Android.keyaliasPass = keyaliasPass; - - string androidTargetSdkVersion; - if (options.TryGetValue("androidTargetSdkVersion", out androidTargetSdkVersion) && !string.IsNullOrEmpty(androidTargetSdkVersion)) - { - var targetSdkVersion = AndroidSdkVersions.AndroidApiLevelAuto; - try - { - targetSdkVersion = - (AndroidSdkVersions) Enum.Parse(typeof(AndroidSdkVersions), androidTargetSdkVersion); - } - catch - { - UnityEngine.Debug.Log("Failed to parse androidTargetSdkVersion! Fallback to AndroidApiLevelAuto"); - } - PlayerSettings.Android.targetSdkVersion = targetSdkVersion; - } - - string androidExportType; - if (options.TryGetValue("androidExportType", out androidExportType) && !string.IsNullOrEmpty(androidExportType)) - { - // Only exists in 2018.3 and above - PropertyInfo buildAppBundle = typeof(EditorUserBuildSettings) - .GetProperty("buildAppBundle", BindingFlags.Public | BindingFlags.Static); - switch (androidExportType) - { - case "androidStudioProject": - EditorUserBuildSettings.exportAsGoogleAndroidProject = true; - if (buildAppBundle != null) - buildAppBundle.SetValue(null, false, null); - break; - case "androidAppBundle": - EditorUserBuildSettings.exportAsGoogleAndroidProject = false; - if (buildAppBundle != null) - buildAppBundle.SetValue(null, true, null); - break; - case "androidPackage": - EditorUserBuildSettings.exportAsGoogleAndroidProject = false; - if (buildAppBundle != null) - buildAppBundle.SetValue(null, false, null); - break; - } - } - - string symbolType; - if (options.TryGetValue("androidSymbolType", out symbolType) && !string.IsNullOrEmpty(symbolType)) - { -#if UNITY_6000_0_OR_NEWER - switch (symbolType) - { - case "public": - SetDebugSymbols("SymbolTable"); - break; - case "debugging": - SetDebugSymbols("Full"); - break; - case "none": - SetDebugSymbols("None"); - break; - } -#elif UNITY_2021_1_OR_NEWER - switch (symbolType) - { - case "public": - EditorUserBuildSettings.androidCreateSymbols = AndroidCreateSymbols.Public; - break; - case "debugging": - EditorUserBuildSettings.androidCreateSymbols = AndroidCreateSymbols.Debugging; - break; - case "none": - EditorUserBuildSettings.androidCreateSymbols = AndroidCreateSymbols.Disabled; - break; - } -#elif UNITY_2019_2_OR_NEWER - switch (symbolType) - { - case "public": - case "debugging": - EditorUserBuildSettings.androidCreateSymbolsZip = true; - break; - case "none": - EditorUserBuildSettings.androidCreateSymbolsZip = false; - break; - } -#endif - } - } - -#if UNITY_6000_0_OR_NEWER - private static void SetDebugSymbols(string enumValueName) - { - // UnityEditor.Android.UserBuildSettings and Unity.Android.Types.DebugSymbolLevel are part of the Unity Android module. - // Reflection is used here to ensure the code works even if the module is not installed. - - var debugSymbolsType = Type.GetType("UnityEditor.Android.UserBuildSettings+DebugSymbols, UnityEditor.Android.Extensions"); - if (debugSymbolsType == null) - { - return; - } - - var levelProp = debugSymbolsType.GetProperty("level", BindingFlags.Static | BindingFlags.Public); - if (levelProp == null) - { - return; - } - - var enumType = Type.GetType("Unity.Android.Types.DebugSymbolLevel, Unity.Android.Types"); - if (enumType == null) - { - return; - } - - if (!Enum.TryParse(enumType, enumValueName, false , out var enumValue)) - { - return; - } - levelProp.SetValue(null, enumValue); - } -#endif - } -} +using System; +using System.Collections.Generic; +using UnityEditor; +using System.Reflection; + +namespace UnityBuilderAction.Input +{ + public static class AndroidSettings + { + public static void Apply(Dictionary options) + { +#if UNITY_2019_1_OR_NEWER + if (options.TryGetValue("androidKeystoreName", out string keystoreName) && !string.IsNullOrEmpty(keystoreName)) + { + PlayerSettings.Android.useCustomKeystore = true; + PlayerSettings.Android.keystoreName = keystoreName; + } +#endif + // Can't use out variable declaration as Unity 2018 doesn't support it + string keystorePass; + if (options.TryGetValue("androidKeystorePass", out keystorePass) && !string.IsNullOrEmpty(keystorePass)) + PlayerSettings.Android.keystorePass = keystorePass; + + string keyaliasName; + if (options.TryGetValue("androidKeyaliasName", out keyaliasName) && !string.IsNullOrEmpty(keyaliasName)) + PlayerSettings.Android.keyaliasName = keyaliasName; + + string keyaliasPass; + if (options.TryGetValue("androidKeyaliasPass", out keyaliasPass) && !string.IsNullOrEmpty(keyaliasPass)) + PlayerSettings.Android.keyaliasPass = keyaliasPass; + + string androidTargetSdkVersion; + if (options.TryGetValue("androidTargetSdkVersion", out androidTargetSdkVersion) && !string.IsNullOrEmpty(androidTargetSdkVersion)) + { + var targetSdkVersion = AndroidSdkVersions.AndroidApiLevelAuto; + try + { + targetSdkVersion = + (AndroidSdkVersions) Enum.Parse(typeof(AndroidSdkVersions), androidTargetSdkVersion); + } + catch + { + UnityEngine.Debug.Log("Failed to parse androidTargetSdkVersion! Fallback to AndroidApiLevelAuto"); + } + PlayerSettings.Android.targetSdkVersion = targetSdkVersion; + } + + string androidExportType; + if (options.TryGetValue("androidExportType", out androidExportType) && !string.IsNullOrEmpty(androidExportType)) + { + // Only exists in 2018.3 and above + PropertyInfo buildAppBundle = typeof(EditorUserBuildSettings) + .GetProperty("buildAppBundle", BindingFlags.Public | BindingFlags.Static); + switch (androidExportType) + { + case "androidStudioProject": + EditorUserBuildSettings.exportAsGoogleAndroidProject = true; + if (buildAppBundle != null) + buildAppBundle.SetValue(null, false, null); + break; + case "androidAppBundle": + EditorUserBuildSettings.exportAsGoogleAndroidProject = false; + if (buildAppBundle != null) + buildAppBundle.SetValue(null, true, null); + break; + case "androidPackage": + EditorUserBuildSettings.exportAsGoogleAndroidProject = false; + if (buildAppBundle != null) + buildAppBundle.SetValue(null, false, null); + break; + } + } + + string symbolType; + if (options.TryGetValue("androidSymbolType", out symbolType) && !string.IsNullOrEmpty(symbolType)) + { +#if UNITY_6000_0_OR_NEWER + switch (symbolType) + { + case "public": + SetDebugSymbols("SymbolTable"); + break; + case "debugging": + SetDebugSymbols("Full"); + break; + case "none": + SetDebugSymbols("None"); + break; + } +#elif UNITY_2021_1_OR_NEWER + switch (symbolType) + { + case "public": + EditorUserBuildSettings.androidCreateSymbols = AndroidCreateSymbols.Public; + break; + case "debugging": + EditorUserBuildSettings.androidCreateSymbols = AndroidCreateSymbols.Debugging; + break; + case "none": + EditorUserBuildSettings.androidCreateSymbols = AndroidCreateSymbols.Disabled; + break; + } +#elif UNITY_2019_2_OR_NEWER + switch (symbolType) + { + case "public": + case "debugging": + EditorUserBuildSettings.androidCreateSymbolsZip = true; + break; + case "none": + EditorUserBuildSettings.androidCreateSymbolsZip = false; + break; + } +#endif + } + } + +#if UNITY_6000_0_OR_NEWER + private static void SetDebugSymbols(string enumValueName) + { + // UnityEditor.Android.UserBuildSettings and Unity.Android.Types.DebugSymbolLevel are part of the Unity Android module. + // Reflection is used here to ensure the code works even if the module is not installed. + + var debugSymbolsType = Type.GetType("UnityEditor.Android.UserBuildSettings+DebugSymbols, UnityEditor.Android.Extensions"); + if (debugSymbolsType == null) + { + return; + } + + var levelProp = debugSymbolsType.GetProperty("level", BindingFlags.Static | BindingFlags.Public); + if (levelProp == null) + { + return; + } + + var enumType = Type.GetType("Unity.Android.Types.DebugSymbolLevel, Unity.Android.Types"); + if (enumType == null) + { + return; + } + + if (!Enum.TryParse(enumType, enumValueName, false , out var enumValue)) + { + return; + } + levelProp.SetValue(null, enumValue); + } +#endif + } +} diff --git a/dist/index.js b/dist/index.js index 786e576..32899d8 100644 --- a/dist/index.js +++ b/dist/index.js @@ -33,76 +33,45 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.runMain = void 0; const core = __importStar(__nccwpck_require__(42186)); -const github = __importStar(__nccwpck_require__(95438)); -const axios_1 = __importStar(__nccwpck_require__(88757)); const model_1 = __nccwpck_require__(41359); -const cli_1 = __nccwpck_require__(55651); const mac_builder_1 = __importDefault(__nccwpck_require__(39364)); const platform_setup_1 = __importDefault(__nccwpck_require__(64423)); -async function validateSubscription() { - const repoPrivate = github.context?.payload?.repository?.private; - const upstream = 'game-ci/unity-builder'; - const action = process.env.GITHUB_ACTION_REPOSITORY; - const docsUrl = 'https://docs.stepsecurity.io/actions/stepsecurity-maintained-actions'; - core.info(''); - core.info('\u001b[1;36mStepSecurity Maintained Action\u001b[0m'); - core.info(`Secure drop-in replacement for ${upstream}`); - if (repoPrivate === false) - core.info('\u001b[32m\u2713 Free for public repositories\u001b[0m'); - core.info(`\u001b[36mLearn more:\u001b[0m ${docsUrl}`); - core.info(''); - if (repoPrivate === false) - return; - const serverUrl = process.env.GITHUB_SERVER_URL || 'https://github.com'; - const body = { action: action || '' }; - if (serverUrl !== 'https://github.com') - body.ghes_server = serverUrl; - try { - await axios_1.default.post(`https://agent.api.stepsecurity.io/v1/github/${process.env.GITHUB_REPOSITORY}/actions/maintained-actions-subscription`, body, { timeout: 3000 }); - } - catch (error) { - if ((0, axios_1.isAxiosError)(error) && error.response?.status === 403) { - core.error(`\u001b[1;31mThis action requires a StepSecurity subscription for private repositories.\u001b[0m`); - core.error(`\u001b[31mLearn how to enable a subscription: ${docsUrl}\u001b[0m`); - process.exit(1); - } - core.info('Timeout or API not reachable. Continuing to next step.'); - } -} +const plugin_1 = __nccwpck_require__(67270); +// Exported so tests can drive the lifecycle directly without depending on +// vitest's module re-loading (which changed in vitest 4). async function runMain() { try { - await validateSubscription(); - if (cli_1.Cli.InitCliMode()) { - await cli_1.Cli.RunCli(); - return; - } model_1.Action.checkCompatibility(); model_1.Cache.verify(); const { workspace, actionFolder } = model_1.Action; const buildParameters = await model_1.BuildParameters.create(); const baseImage = new model_1.ImageTag(buildParameters); + // Load optional plugin. The default implementation is @game-ci/orchestrator. + const plugin = await (0, plugin_1.loadPlugin)(); + await plugin?.initialize(buildParameters, workspace); let exitCode = -1; - if (buildParameters.providerStrategy === 'local') { - core.info('Building locally'); - await platform_setup_1.default.setup(buildParameters, actionFolder); - exitCode = - process.platform === 'darwin' - ? await mac_builder_1.default.run(actionFolder) - : await model_1.Docker.run(baseImage.toString(), { - workspace, - actionFolder, - ...buildParameters, - }); + if (plugin?.canHandleBuild()) { + // Plugin handles the build entirely (remote providers, hot runner, test workflows) + const result = await plugin.handleBuild(baseImage.toString()); + exitCode = result.fallbackToLocal + ? await runLocalBuild(buildParameters, baseImage, workspace, actionFolder, plugin) + : result.exitCode; + } + else if (buildParameters.providerStrategy === 'local') { + exitCode = await runLocalBuild(buildParameters, baseImage, workspace, actionFolder, plugin); } else { - await model_1.Orchestrator.run(buildParameters, baseImage.toString()); - exitCode = 0; + throw new Error(`Provider strategy "${buildParameters.providerStrategy}" requires @game-ci/orchestrator. ` + + 'Install it via the game-ci/orchestrator action, or use providerStrategy=local.'); } - // Set output + // Set core outputs await model_1.Output.setBuildVersion(buildParameters.buildVersion); await model_1.Output.setAndroidVersionCode(buildParameters.androidVersionCode); await model_1.Output.setEngineExitCode(exitCode); + // Plugin handles post-build (artifacts, archiving, retention) + await plugin?.handlePostBuild(exitCode); if (exitCode !== 0) { core.setFailed(`Build failed with exit code ${exitCode}`); } @@ -111,7 +80,26 @@ async function runMain() { core.setFailed(error.message); } } -runMain(); +exports.runMain = runMain; +async function runLocalBuild(buildParameters, baseImage, workspace, actionFolder, plugin) { + await plugin?.beforeLocalBuild(workspace); + await platform_setup_1.default.setup(buildParameters, actionFolder); + const exitCode = process.platform === 'darwin' + ? await mac_builder_1.default.run(actionFolder) + : await model_1.Docker.run(baseImage.toString(), { + workspace, + actionFolder, + ...buildParameters, + }); + await plugin?.afterLocalBuild(workspace, exitCode); + return exitCode; +} +// Auto-run when this module is the entry point. Tests import the file via +// `await import('./index')` purely to register the mock factories and then +// call `runMain()` directly. +if (process.env.NODE_ENV !== 'test') { + runMain(); +} /***/ }), @@ -267,25 +255,68 @@ var __importDefault = (this && this.__importDefault) || function (mod) { Object.defineProperty(exports, "__esModule", ({ value: true })); const nanoid_1 = __nccwpck_require__(17592); const android_versioning_1 = __importDefault(__nccwpck_require__(43059)); -const orchestrator_constants_1 = __importDefault(__nccwpck_require__(47214)); -const orchestrator_guid_1 = __importDefault(__nccwpck_require__(38612)); -const input_1 = __importDefault(__nccwpck_require__(48096)); +const input_1 = __importDefault(__nccwpck_require__(91933)); const platform_1 = __importDefault(__nccwpck_require__(9707)); const unity_versioning_1 = __importDefault(__nccwpck_require__(17146)); const versioning_1 = __importDefault(__nccwpck_require__(88729)); const git_repo_1 = __nccwpck_require__(24271); const github_cli_1 = __nccwpck_require__(44990); -const cli_1 = __nccwpck_require__(55651); +const plugin_options_1 = __nccwpck_require__(77038); const github_1 = __importDefault(__nccwpck_require__(83654)); -const orchestrator_options_1 = __importDefault(__nccwpck_require__(82473)); -const orchestrator_1 = __importDefault(__nccwpck_require__(8330)); const core = __importStar(__nccwpck_require__(42186)); class BuildParameters { - static shouldUseRetainedWorkspaceMode(buildParameters) { - return buildParameters.maxRetainedWorkspaces > 0 && orchestrator_1.default.lockedWorkspace !== ``; - } + editorVersion; + customImage; + unitySerial; + unityLicensingServer; + skipActivation; + runnerTempPath; + targetPlatform; + projectPath; + buildProfile; + buildName; + buildPath; + buildFile; + buildMethod; + buildVersion; + manualExit; + enableGpu; + androidVersionCode; + androidKeystoreName; + androidKeystoreBase64; + androidKeystorePass; + androidKeyaliasName; + androidKeyaliasPass; + androidTargetSdkVersion; + androidSdkManagerParameters; + androidExportType; + androidSymbolType; + dockerCpuLimit; + dockerMemoryLimit; + dockerIsolationMode; + containerRegistryRepository; + containerRegistryImageVersion; + customParameters; + useHostNetwork; + sshAgent; + sshPublicKeysDirectoryPath; + providerStrategy; + gitPrivateToken; + runAsHostUser; + chownFilesTo; + runNumber; + branch; + githubRepo; + gitSha; + logId; + buildGuid; + buildPlatform; + isCliMode; + cacheUnityInstallationOnMac; + unityHubVersionOnMac; + dockerWorkspacePath; static async create() { - const buildFile = this.parseBuildFile(input_1.default.buildName, input_1.default.targetPlatform, input_1.default.androidExportType); + const buildFile = this.parseBuildFile(input_1.default.buildName, input_1.default.targetPlatform, input_1.default.androidExportType, input_1.default.linux64RemoveExecutableExtension); const editorVersion = unity_versioning_1.default.determineUnityVersion(input_1.default.projectPath, input_1.default.unityVersion); const buildVersion = await versioning_1.default.determineBuildVersion(input_1.default.versioningStrategy, input_1.default.specifiedVersion); const androidVersionCode = android_versioning_1.default.determineVersionCode(buildVersion, input_1.default.androidVersionCode); @@ -321,6 +352,7 @@ class BuildParameters { core.setSecret(unitySerial); core.setSecret(`${unitySerial.slice(0, -4)}XXXX`); } + const providerStrategy = input_1.default.getInput('providerStrategy') || (plugin_options_1.PluginOptions.isPluginMode ? 'aws' : 'local'); return { editorVersion, customImage: input_1.default.customImage, @@ -349,6 +381,7 @@ class BuildParameters { androidExportType: input_1.default.androidExportType, androidSymbolType: androidSymbolExportType, customParameters: input_1.default.customParameters, + useHostNetwork: input_1.default.useHostNetwork, sshAgent: input_1.default.sshAgent, sshPublicKeysDirectoryPath: input_1.default.sshPublicKeysDirectoryPath, gitPrivateToken: input_1.default.gitPrivateToken ?? (await github_cli_1.GithubCliReader.GetGitHubAuthToken()), @@ -359,58 +392,21 @@ class BuildParameters { dockerIsolationMode: input_1.default.dockerIsolationMode, containerRegistryRepository: input_1.default.containerRegistryRepository, containerRegistryImageVersion: input_1.default.containerRegistryImageVersion, - providerStrategy: orchestrator_options_1.default.providerStrategy, - buildPlatform: orchestrator_options_1.default.buildPlatform, - kubeConfig: orchestrator_options_1.default.kubeConfig, - containerMemory: orchestrator_options_1.default.containerMemory, - containerCpu: orchestrator_options_1.default.containerCpu, - containerNamespace: orchestrator_options_1.default.containerNamespace, - kubeVolumeSize: orchestrator_options_1.default.kubeVolumeSize, - kubeVolume: orchestrator_options_1.default.kubeVolume, - postBuildContainerHooks: orchestrator_options_1.default.postBuildContainerHooks, - preBuildContainerHooks: orchestrator_options_1.default.preBuildContainerHooks, - customJob: orchestrator_options_1.default.customJob, + providerStrategy, + buildPlatform: providerStrategy !== 'local' ? 'linux' : process.platform, runNumber: input_1.default.runNumber, branch: input_1.default.branch.replace('/head', '') || (await git_repo_1.GitRepoReader.GetBranch()), - orchestratorBranch: orchestrator_options_1.default.orchestratorBranch.split('/').reverse()[0], - orchestratorDebug: orchestrator_options_1.default.orchestratorDebug, - githubRepo: (input_1.default.githubRepo ?? (await git_repo_1.GitRepoReader.GetRemote())) || orchestrator_options_1.default.orchestratorRepoName, - orchestratorRepoName: orchestrator_options_1.default.orchestratorRepoName, - cloneDepth: Number.parseInt(orchestrator_options_1.default.cloneDepth), - isCliMode: cli_1.Cli.isCliMode, - awsStackName: orchestrator_options_1.default.awsStackName, - awsEndpoint: orchestrator_options_1.default.awsEndpoint, - awsCloudFormationEndpoint: orchestrator_options_1.default.awsCloudFormationEndpoint, - awsEcsEndpoint: orchestrator_options_1.default.awsEcsEndpoint, - awsKinesisEndpoint: orchestrator_options_1.default.awsKinesisEndpoint, - awsCloudWatchLogsEndpoint: orchestrator_options_1.default.awsCloudWatchLogsEndpoint, - awsS3Endpoint: orchestrator_options_1.default.awsS3Endpoint, - storageProvider: orchestrator_options_1.default.storageProvider, - rcloneRemote: orchestrator_options_1.default.rcloneRemote, + githubRepo: (input_1.default.githubRepo ?? (await git_repo_1.GitRepoReader.GetRemote())) || 'game-ci/unity-builder', gitSha: input_1.default.gitSha, - logId: (0, nanoid_1.customAlphabet)(orchestrator_constants_1.default.alphabet, 9)(), - buildGuid: orchestrator_guid_1.default.generateGuid(input_1.default.runNumber, input_1.default.targetPlatform), - commandHooks: orchestrator_options_1.default.commandHooks, - inputPullCommand: orchestrator_options_1.default.inputPullCommand, - pullInputList: orchestrator_options_1.default.pullInputList, - kubeStorageClass: orchestrator_options_1.default.kubeStorageClass, - cacheKey: orchestrator_options_1.default.cacheKey, - maxRetainedWorkspaces: Number.parseInt(orchestrator_options_1.default.maxRetainedWorkspaces), - useLargePackages: orchestrator_options_1.default.useLargePackages, - useCompressionStrategy: orchestrator_options_1.default.useCompressionStrategy, - garbageMaxAge: orchestrator_options_1.default.garbageMaxAge, - githubChecks: orchestrator_options_1.default.githubChecks, - asyncWorkflow: orchestrator_options_1.default.asyncOrchestrator, - githubCheckId: orchestrator_options_1.default.githubCheckId, - finalHooks: orchestrator_options_1.default.finalHooks, - skipLfs: orchestrator_options_1.default.skipLfs, - skipCache: orchestrator_options_1.default.skipCache, + logId: (0, nanoid_1.customAlphabet)('0123456789abcdefghijklmnopqrstuvwxyz', 9)(), + buildGuid: `${input_1.default.runNumber}-${input_1.default.targetPlatform.toLowerCase().replace('standalone', '')}-${(0, nanoid_1.customAlphabet)('0123456789abcdefghijklmnopqrstuvwxyz', 4)()}`, + isCliMode: plugin_options_1.PluginOptions.isPluginMode, cacheUnityInstallationOnMac: input_1.default.cacheUnityInstallationOnMac, unityHubVersionOnMac: input_1.default.unityHubVersionOnMac, dockerWorkspacePath: input_1.default.dockerWorkspacePath, }; } - static parseBuildFile(filename, platform, androidExportType) { + static parseBuildFile(filename, platform, androidExportType, linux64RemoveExecutableExtension) { if (platform_1.default.isWindows(platform)) { return `${filename}.exe`; } @@ -426,6 +422,9 @@ class BuildParameters { throw new Error(`Unknown Android Export Type: ${androidExportType}. Must be one of androidPackage for apk, androidAppBundle for aab, androidStudioProject for android project`); } } + if (platform === platform_1.default.types.StandaloneLinux64 && !linux64RemoveExecutableExtension) { + return `${filename}.x86_64`; + } return filename; } static getSerialFromLicenseFile(license) { @@ -501,254 +500,6 @@ class Cache { exports["default"] = Cache; -/***/ }), - -/***/ 85301: -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.CliFunction = exports.CliFunctionsRepository = void 0; -class CliFunctionsRepository { - static PushCliFunction(target, propertyKey, descriptor, key, description) { - CliFunctionsRepository.targets.push({ - target, - propertyKey, - descriptor, - key, - description, - }); - } - static GetCliFunctions(key) { - const results = CliFunctionsRepository.targets.find((x) => x.key === key); - if (results === undefined || results.length === 0) { - throw new Error(`no CLI mode found for ${key}`); - } - return results; - } - static GetAllCliModes() { - return CliFunctionsRepository.targets.map((x) => { - return { - key: x.key, - description: x.description, - }; - }); - } - // eslint-disable-next-line no-unused-vars - static PushCliFunctionSource(cliFunction) { } -} -exports.CliFunctionsRepository = CliFunctionsRepository; -CliFunctionsRepository.targets = []; -function CliFunction(key, description) { - return (target, propertyKey, descriptor) => { - CliFunctionsRepository.PushCliFunction(target, propertyKey, descriptor, key, description); - }; -} -exports.CliFunction = CliFunction; - - -/***/ }), - -/***/ 55651: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Cli = void 0; -const commander_ts_1 = __nccwpck_require__(40451); -const __1 = __nccwpck_require__(41359); -const core = __importStar(__nccwpck_require__(42186)); -const action_yaml_1 = __nccwpck_require__(11091); -const orchestrator_logger_1 = __importDefault(__nccwpck_require__(32549)); -const orchestrator_query_override_1 = __importDefault(__nccwpck_require__(34664)); -const cli_functions_repository_1 = __nccwpck_require__(85301); -const caching_1 = __nccwpck_require__(6435); -const lfs_hashing_1 = __nccwpck_require__(23451); -const remote_client_1 = __nccwpck_require__(85666); -const orchestrator_options_reader_1 = __importDefault(__nccwpck_require__(54381)); -const github_1 = __importDefault(__nccwpck_require__(83654)); -class Cli { - static get isCliMode() { - return Cli.options !== undefined && Cli.options.mode !== undefined && Cli.options.mode !== ''; - } - static query(key, alternativeKey) { - if (Cli.options && Cli.options[key] !== undefined) { - return Cli.options[key]; - } - if (Cli.options && alternativeKey && Cli.options[alternativeKey] !== undefined) { - return Cli.options[alternativeKey]; - } - return; - } - static InitCliMode() { - cli_functions_repository_1.CliFunctionsRepository.PushCliFunctionSource(remote_client_1.RemoteClient); - cli_functions_repository_1.CliFunctionsRepository.PushCliFunctionSource(caching_1.Caching); - cli_functions_repository_1.CliFunctionsRepository.PushCliFunctionSource(lfs_hashing_1.LfsHashing); - const program = new commander_ts_1.Command(); - program.version('0.0.1'); - const properties = orchestrator_options_reader_1.default.GetProperties(); - const actionYamlReader = new action_yaml_1.ActionYamlReader(); - for (const element of properties) { - program.option(`--${element} <${element}>`, actionYamlReader.GetActionYamlValue(element)); - } - program.option('-m, --mode ', cli_functions_repository_1.CliFunctionsRepository.GetAllCliModes() - .map((x) => `${x.key} (${x.description})`) - .join(` | `)); - program.option('--populateOverride ', 'should use override query to pull input false by default'); - program.option('--cachePushFrom ', 'cache push from source folder'); - program.option('--cachePushTo ', 'cache push to caching folder'); - program.option('--artifactName ', 'caching artifact name'); - program.option('--select `).join('\n'); - - return ` - - Requesting Authorization - - -
- ${formInputs} -
- -`; + return replaceNamedType(type); } - /** - * @name endSessionUrl - * @api public - */ - endSessionUrl(params = {}) { - assertIssuerConfiguration(this.issuer, 'end_session_endpoint'); - - const { - 0: postLogout, - length, - } = this.post_logout_redirect_uris || []; - - const { - post_logout_redirect_uri = length === 1 ? postLogout : undefined, - } = params; + function replaceNamedType(type) { + return typeMap[type.name]; + } - let hint = params.id_token_hint; + function replaceMaybeType(maybeType) { + return maybeType && replaceNamedType(maybeType); + } - if (hint instanceof TokenSet) { - if (!hint.id_token) { - throw new TypeError('id_token not present in TokenSet'); - } - hint = hint.id_token; - } + function sortDirective(directive) { + const config = directive.toConfig(); + return new _directives.GraphQLDirective({ + ...config, + locations: sortBy(config.locations, (x) => x), + args: sortArgs(config.args), + }); + } - const target = url.parse(this.issuer.end_session_endpoint, true); - target.search = null; - target.query = { - ...params, - ...target.query, - ...{ - post_logout_redirect_uri, - id_token_hint: hint, - }, - }; + function sortArgs(args) { + return sortObjMap(args, (arg) => ({ ...arg, type: replaceType(arg.type) })); + } - Object.entries(target.query).forEach(([key, value]) => { - if (value === null || value === undefined) { - delete target.query[key]; - } - }); + function sortFields(fieldsMap) { + return sortObjMap(fieldsMap, (field) => ({ + ...field, + type: replaceType(field.type), + args: field.args && sortArgs(field.args), + })); + } - return url.format(target); + function sortInputFields(fieldsMap) { + return sortObjMap(fieldsMap, (field) => ({ + ...field, + type: replaceType(field.type), + })); } - /** - * @name callbackParams - * @api public - */ - callbackParams(input) { // eslint-disable-line class-methods-use-this - const isIncomingMessage = input instanceof stdhttp.IncomingMessage - || (input && input.method && input.url); - const isString = typeof input === 'string'; - - if (!isString && !isIncomingMessage) { - throw new TypeError('#callbackParams only accepts string urls, http.IncomingMessage or a lookalike'); - } - - if (isIncomingMessage) { - switch (input.method) { - case 'GET': - return pickCb(url.parse(input.url, true).query); - case 'POST': - if (input.body === undefined) { - throw new TypeError('incoming message body missing, include a body parser prior to this method call'); - } - switch (typeof input.body) { - case 'object': - case 'string': - if (Buffer.isBuffer(input.body)) { - return pickCb(querystring.parse(input.body.toString('utf-8'))); - } - if (typeof input.body === 'string') { - return pickCb(querystring.parse(input.body)); - } + function sortTypes(array) { + return sortByName(array).map(replaceNamedType); + } - return pickCb(input.body); - default: - throw new TypeError('invalid IncomingMessage body object'); - } - default: - throw new TypeError('invalid IncomingMessage method'); - } - } else { - return pickCb(url.parse(input, true).query); + function sortNamedType(type) { + if ( + (0, _definition.isScalarType)(type) || + (0, _introspection.isIntrospectionType)(type) + ) { + return type; } - } - /** - * @name callback - * @api public - */ - async callback( - redirectUri, - parameters, - checks = {}, - { exchangeBody, clientAssertionPayload, DPoP } = {}, - ) { - let params = pickCb(parameters); + if ((0, _definition.isObjectType)(type)) { + const config = type.toConfig(); + return new _definition.GraphQLObjectType({ + ...config, + interfaces: () => sortTypes(config.interfaces), + fields: () => sortFields(config.fields), + }); + } - if (checks.jarm && !('response' in parameters)) { - throw new RPError({ - message: 'expected a JARM response', - checks, - params, + if ((0, _definition.isInterfaceType)(type)) { + const config = type.toConfig(); + return new _definition.GraphQLInterfaceType({ + ...config, + interfaces: () => sortTypes(config.interfaces), + fields: () => sortFields(config.fields), }); - } else if ('response' in parameters) { - const decrypted = await this.decryptJARM(params.response); - params = await this.validateJARM(decrypted); - } - - if (this.default_max_age && !checks.max_age) { - checks.max_age = this.default_max_age; } - if (params.state && !checks.state) { - throw new TypeError('checks.state argument is missing'); - } - - if (!params.state && checks.state) { - throw new RPError({ - message: 'state missing from the response', - checks, - params, + if ((0, _definition.isUnionType)(type)) { + const config = type.toConfig(); + return new _definition.GraphQLUnionType({ + ...config, + types: () => sortTypes(config.types), }); } - if (checks.state !== params.state) { - throw new RPError({ - printf: ['state mismatch, expected %s, got: %s', checks.state, params.state], - checks, - params, + if ((0, _definition.isEnumType)(type)) { + const config = type.toConfig(); + return new _definition.GraphQLEnumType({ + ...config, + values: sortObjMap(config.values, (value) => value), }); } - if (params.error) { - throw new OPError(params); + if ((0, _definition.isInputObjectType)(type)) { + const config = type.toConfig(); + return new _definition.GraphQLInputObjectType({ + ...config, + fields: () => sortInputFields(config.fields), + }); } + /* c8 ignore next 3 */ + // Not reachable, all possible types have been considered. - const RESPONSE_TYPE_REQUIRED_PARAMS = { - code: ['code'], - id_token: ['id_token'], - token: ['access_token', 'token_type'], - }; + false || + (0, _invariant.invariant)( + false, + 'Unexpected type: ' + (0, _inspect.inspect)(type), + ); + } +} - if (checks.response_type) { - for (const type of checks.response_type.split(' ')) { // eslint-disable-line no-restricted-syntax - if (type === 'none') { - if (params.code || params.id_token || params.access_token) { - throw new RPError({ - message: 'unexpected params encountered for "none" response', - checks, - params, - }); - } - } else { - for (const param of RESPONSE_TYPE_REQUIRED_PARAMS[type]) { // eslint-disable-line no-restricted-syntax, max-len - if (!params[param]) { - throw new RPError({ - message: `${param} missing from response`, - checks, - params, - }); - } - } - } - } - } +function sortObjMap(map, sortValueFn) { + const sortedMap = Object.create(null); - if (params.id_token) { - const tokenset = new TokenSet(params); - await this.decryptIdToken(tokenset); - await this.validateIdToken(tokenset, checks.nonce, 'authorization', checks.max_age, checks.state); + for (const key of Object.keys(map).sort(_naturalCompare.naturalCompare)) { + sortedMap[key] = sortValueFn(map[key]); + } - if (!params.code) { - return tokenset; - } - } + return sortedMap; +} - if (params.code) { - const tokenset = await this.grant({ - ...exchangeBody, - grant_type: 'authorization_code', - code: params.code, - redirect_uri: redirectUri, - code_verifier: checks.code_verifier, - }, { clientAssertionPayload, DPoP }); +function sortByName(array) { + return sortBy(array, (obj) => obj.name); +} - await this.decryptIdToken(tokenset); - await this.validateIdToken(tokenset, checks.nonce, 'token', checks.max_age); +function sortBy(array, mapToKey) { + return array.slice().sort((obj1, obj2) => { + const key1 = mapToKey(obj1); + const key2 = mapToKey(obj2); + return (0, _naturalCompare.naturalCompare)(key1, key2); + }); +} - if (params.session_state) { - tokenset.session_state = params.session_state; - } - return tokenset; - } +/***/ }), - return new TokenSet(params); - } +/***/ 84166: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - /** - * @name oauthCallback - * @api public - */ - async oauthCallback( - redirectUri, - parameters, - checks = {}, - { exchangeBody, clientAssertionPayload, DPoP } = {}, - ) { - let params = pickCb(parameters); +"use strict"; - if (checks.jarm && !('response' in parameters)) { - throw new RPError({ - message: 'expected a JARM response', - checks, - params, - }); - } else if ('response' in parameters) { - const decrypted = await this.decryptJARM(params.response); - params = await this.validateJARM(decrypted); - } - if (params.state && !checks.state) { - throw new TypeError('checks.state argument is missing'); - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.printIntrospectionSchema = printIntrospectionSchema; +exports.printSchema = printSchema; +exports.printType = printType; - if (!params.state && checks.state) { - throw new RPError({ - message: 'state missing from the response', - checks, - params, - }); - } +var _inspect = __nccwpck_require__(10102); - if (checks.state !== params.state) { - throw new RPError({ - printf: ['state mismatch, expected %s, got: %s', checks.state, params.state], - checks, - params, - }); - } +var _invariant = __nccwpck_require__(28847); - if (params.error) { - throw new OPError(params); - } +var _blockString = __nccwpck_require__(4515); - const RESPONSE_TYPE_REQUIRED_PARAMS = { - code: ['code'], - token: ['access_token', 'token_type'], - }; +var _kinds = __nccwpck_require__(11927); - if (checks.response_type) { - for (const type of checks.response_type.split(' ')) { // eslint-disable-line no-restricted-syntax - if (type === 'none') { - if (params.code || params.id_token || params.access_token) { - throw new RPError({ - message: 'unexpected params encountered for "none" response', - checks, - params, - }); - } - } +var _printer = __nccwpck_require__(68203); - if (RESPONSE_TYPE_REQUIRED_PARAMS[type]) { - for (const param of RESPONSE_TYPE_REQUIRED_PARAMS[type]) { // eslint-disable-line no-restricted-syntax, max-len - if (!params[param]) { - throw new RPError({ - message: `${param} missing from response`, - checks, - params, - }); - } - } - } - } - } +var _definition = __nccwpck_require__(5821); - if (params.code) { - return this.grant({ - ...exchangeBody, - grant_type: 'authorization_code', - code: params.code, - redirect_uri: redirectUri, - code_verifier: checks.code_verifier, - }, { clientAssertionPayload, DPoP }); - } +var _directives = __nccwpck_require__(83614); - return new TokenSet(params); - } +var _introspection = __nccwpck_require__(28344); - /** - * @name decryptIdToken - * @api private - */ - async decryptIdToken(token) { - if (!this.id_token_encrypted_response_alg) { - return token; - } +var _scalars = __nccwpck_require__(93145); - let idToken = token; +var _astFromValue = __nccwpck_require__(12653); - if (idToken instanceof TokenSet) { - if (!idToken.id_token) { - throw new TypeError('id_token not present in TokenSet'); - } - idToken = idToken.id_token; - } +function printSchema(schema) { + return printFilteredSchema( + schema, + (n) => !(0, _directives.isSpecifiedDirective)(n), + isDefinedType, + ); +} - const expectedAlg = this.id_token_encrypted_response_alg; - const expectedEnc = this.id_token_encrypted_response_enc; +function printIntrospectionSchema(schema) { + return printFilteredSchema( + schema, + _directives.isSpecifiedDirective, + _introspection.isIntrospectionType, + ); +} - const result = await this.decryptJWE(idToken, expectedAlg, expectedEnc); +function isDefinedType(type) { + return ( + !(0, _scalars.isSpecifiedScalarType)(type) && + !(0, _introspection.isIntrospectionType)(type) + ); +} - if (token instanceof TokenSet) { - token.id_token = result; - return token; - } +function printFilteredSchema(schema, directiveFilter, typeFilter) { + const directives = schema.getDirectives().filter(directiveFilter); + const types = Object.values(schema.getTypeMap()).filter(typeFilter); + return [ + printSchemaDefinition(schema), + ...directives.map((directive) => printDirective(directive)), + ...types.map((type) => printType(type)), + ] + .filter(Boolean) + .join('\n\n'); +} - return result; +function printSchemaDefinition(schema) { + if (schema.description == null && isSchemaOfCommonNames(schema)) { + return; } - async validateJWTUserinfo(body) { - const expectedAlg = this.userinfo_signed_response_alg; + const operationTypes = []; + const queryType = schema.getQueryType(); - return this.validateJWT(body, expectedAlg, []); + if (queryType) { + operationTypes.push(` query: ${queryType.name}`); } - /** - * @name decryptJARM - * @api private - */ - async decryptJARM(response) { - if (!this.authorization_encrypted_response_alg) { - return response; - } - - const expectedAlg = this.authorization_encrypted_response_alg; - const expectedEnc = this.authorization_encrypted_response_enc; + const mutationType = schema.getMutationType(); - return this.decryptJWE(response, expectedAlg, expectedEnc); + if (mutationType) { + operationTypes.push(` mutation: ${mutationType.name}`); } - /** - * @name decryptJWTUserinfo - * @api private - */ - async decryptJWTUserinfo(body) { - if (!this.userinfo_encrypted_response_alg) { - return body; - } - - const expectedAlg = this.userinfo_encrypted_response_alg; - const expectedEnc = this.userinfo_encrypted_response_enc; + const subscriptionType = schema.getSubscriptionType(); - return this.decryptJWE(body, expectedAlg, expectedEnc); + if (subscriptionType) { + operationTypes.push(` subscription: ${subscriptionType.name}`); } - /** - * @name decryptJWE - * @api private - */ - async decryptJWE(jwe, expectedAlg, expectedEnc = 'A128CBC-HS256') { - const header = JSON.parse(base64url.decode(jwe.split('.')[0])); + return printDescription(schema) + `schema {\n${operationTypes.join('\n')}\n}`; +} +/** + * GraphQL schema define root types for each type of operation. These types are + * the same as any other type and can be named in any manner, however there is + * a common naming convention: + * + * ```graphql + * schema { + * query: Query + * mutation: Mutation + * subscription: Subscription + * } + * ``` + * + * When using this naming convention, the schema description can be omitted. + */ - if (header.alg !== expectedAlg) { - throw new RPError({ - printf: ['unexpected JWE alg received, expected %s, got: %s', expectedAlg, header.alg], - jwt: jwe, - }); - } +function isSchemaOfCommonNames(schema) { + const queryType = schema.getQueryType(); - if (header.enc !== expectedEnc) { - throw new RPError({ - printf: ['unexpected JWE enc received, expected %s, got: %s', expectedEnc, header.enc], - jwt: jwe, - }); - } + if (queryType && queryType.name !== 'Query') { + return false; + } - let keyOrStore; + const mutationType = schema.getMutationType(); - if (expectedAlg.match(/^(?:RSA|ECDH)/)) { - keyOrStore = instance(this).get('keystore'); - } else { - keyOrStore = await this.joseSecret(expectedAlg === 'dir' ? expectedEnc : expectedAlg); - } + if (mutationType && mutationType.name !== 'Mutation') { + return false; + } + + const subscriptionType = schema.getSubscriptionType(); - const payload = jose.JWE.decrypt(jwe, keyOrStore); - return payload.toString('utf8'); + if (subscriptionType && subscriptionType.name !== 'Subscription') { + return false; } - /** - * @name validateIdToken - * @api private - */ - async validateIdToken(tokenSet, nonce, returnedBy, maxAge, state) { - let idToken = tokenSet; + return true; +} - const expectedAlg = this.id_token_signed_response_alg; +function printType(type) { + if ((0, _definition.isScalarType)(type)) { + return printScalar(type); + } - const isTokenSet = idToken instanceof TokenSet; + if ((0, _definition.isObjectType)(type)) { + return printObject(type); + } - if (isTokenSet) { - if (!idToken.id_token) { - throw new TypeError('id_token not present in TokenSet'); - } - idToken = idToken.id_token; - } + if ((0, _definition.isInterfaceType)(type)) { + return printInterface(type); + } - idToken = String(idToken); + if ((0, _definition.isUnionType)(type)) { + return printUnion(type); + } - const timestamp = now(); - const { protected: header, payload, key } = await this.validateJWT(idToken, expectedAlg); + if ((0, _definition.isEnumType)(type)) { + return printEnum(type); + } - if (maxAge || (maxAge !== null && this.require_auth_time)) { - if (!payload.auth_time) { - throw new RPError({ - message: 'missing required JWT property auth_time', - jwt: idToken, - }); - } - if (typeof payload.auth_time !== 'number') { - throw new RPError({ - message: 'JWT auth_time claim must be a JSON numeric value', - jwt: idToken, - }); - } - } + if ((0, _definition.isInputObjectType)(type)) { + return printInputObject(type); + } + /* c8 ignore next 3 */ + // Not reachable, all possible types have been considered. - if (maxAge && (payload.auth_time + maxAge < timestamp - this[CLOCK_TOLERANCE])) { - throw new RPError({ - printf: ['too much time has elapsed since the last End-User authentication, max_age %i, auth_time: %i, now %i', maxAge, payload.auth_time, timestamp - this[CLOCK_TOLERANCE]], - now: timestamp, - tolerance: this[CLOCK_TOLERANCE], - auth_time: payload.auth_time, - jwt: idToken, - }); - } + false || + (0, _invariant.invariant)( + false, + 'Unexpected type: ' + (0, _inspect.inspect)(type), + ); +} - if (nonce !== null && (payload.nonce || nonce !== undefined) && payload.nonce !== nonce) { - throw new RPError({ - printf: ['nonce mismatch, expected %s, got: %s', nonce, payload.nonce], - jwt: idToken, - }); - } +function printScalar(type) { + return ( + printDescription(type) + `scalar ${type.name}` + printSpecifiedByURL(type) + ); +} - const fapi = this.constructor.name === 'FAPIClient'; +function printImplementedInterfaces(type) { + const interfaces = type.getInterfaces(); + return interfaces.length + ? ' implements ' + interfaces.map((i) => i.name).join(' & ') + : ''; +} - if (returnedBy === 'authorization') { - if (!payload.at_hash && tokenSet.access_token) { - throw new RPError({ - message: 'missing required property at_hash', - jwt: idToken, - }); - } +function printObject(type) { + return ( + printDescription(type) + + `type ${type.name}` + + printImplementedInterfaces(type) + + printFields(type) + ); +} - if (!payload.c_hash && tokenSet.code) { - throw new RPError({ - message: 'missing required property c_hash', - jwt: idToken, - }); - } +function printInterface(type) { + return ( + printDescription(type) + + `interface ${type.name}` + + printImplementedInterfaces(type) + + printFields(type) + ); +} - if (fapi) { - if (!payload.s_hash && (tokenSet.state || state)) { - throw new RPError({ - message: 'missing required property s_hash', - jwt: idToken, - }); - } - } +function printUnion(type) { + const types = type.getTypes(); + const possibleTypes = types.length ? ' = ' + types.join(' | ') : ''; + return printDescription(type) + 'union ' + type.name + possibleTypes; +} - if (payload.s_hash) { - if (!state) { - throw new TypeError('cannot verify s_hash, "checks.state" property not provided'); - } +function printEnum(type) { + const values = type + .getValues() + .map( + (value, i) => + printDescription(value, ' ', !i) + + ' ' + + value.name + + printDeprecated(value.deprecationReason), + ); + return printDescription(type) + `enum ${type.name}` + printBlock(values); +} - try { - tokenHash.validate({ claim: 's_hash', source: 'state' }, payload.s_hash, state, header.alg, key && key.crv); - } catch (err) { - throw new RPError({ message: err.message, jwt: idToken }); - } - } - } +function printInputObject(type) { + const fields = Object.values(type.getFields()).map( + (f, i) => printDescription(f, ' ', !i) + ' ' + printInputValue(f), + ); + return ( + printDescription(type) + + `input ${type.name}` + + (type.isOneOf ? ' @oneOf' : '') + + printBlock(fields) + ); +} - if (fapi && payload.iat < timestamp - 3600) { - throw new RPError({ - printf: ['JWT issued too far in the past, now %i, iat %i', timestamp, payload.iat], - now: timestamp, - tolerance: this[CLOCK_TOLERANCE], - iat: payload.iat, - jwt: idToken, - }); - } +function printFields(type) { + const fields = Object.values(type.getFields()).map( + (f, i) => + printDescription(f, ' ', !i) + + ' ' + + f.name + + printArgs(f.args, ' ') + + ': ' + + String(f.type) + + printDeprecated(f.deprecationReason), + ); + return printBlock(fields); +} - if (tokenSet.access_token && payload.at_hash !== undefined) { - try { - tokenHash.validate({ claim: 'at_hash', source: 'access_token' }, payload.at_hash, tokenSet.access_token, header.alg, key && key.crv); - } catch (err) { - throw new RPError({ message: err.message, jwt: idToken }); - } - } +function printBlock(items) { + return items.length !== 0 ? ' {\n' + items.join('\n') + '\n}' : ''; +} - if (tokenSet.code && payload.c_hash !== undefined) { - try { - tokenHash.validate({ claim: 'c_hash', source: 'code' }, payload.c_hash, tokenSet.code, header.alg, key && key.crv); - } catch (err) { - throw new RPError({ message: err.message, jwt: idToken }); - } - } +function printArgs(args, indentation = '') { + if (args.length === 0) { + return ''; + } // If every arg does not have a description, print them on one line. - return tokenSet; + if (args.every((arg) => !arg.description)) { + return '(' + args.map(printInputValue).join(', ') + ')'; } - /** - * @name validateJWT - * @api private - */ - async validateJWT(jwt, expectedAlg, required = ['iss', 'sub', 'aud', 'exp', 'iat']) { - const isSelfIssued = this.issuer.issuer === 'https://self-issued.me'; - const timestamp = now(); - let header; - let payload; - try { - ({ header, payload } = jose.JWT.decode(jwt, { complete: true })); - } catch (err) { - throw new RPError({ - printf: ['failed to decode JWT (%s: %s)', err.name, err.message], - jwt, - }); - } + return ( + '(\n' + + args + .map( + (arg, i) => + printDescription(arg, ' ' + indentation, !i) + + ' ' + + indentation + + printInputValue(arg), + ) + .join('\n') + + '\n' + + indentation + + ')' + ); +} - if (header.alg !== expectedAlg) { - throw new RPError({ - printf: ['unexpected JWT alg received, expected %s, got: %s', expectedAlg, header.alg], - jwt, - }); - } +function printInputValue(arg) { + const defaultAST = (0, _astFromValue.astFromValue)( + arg.defaultValue, + arg.type, + ); + let argDecl = arg.name + ': ' + String(arg.type); - if (isSelfIssued) { - required = [...required, 'sub_jwk']; // eslint-disable-line no-param-reassign - } + if (defaultAST) { + argDecl += ` = ${(0, _printer.print)(defaultAST)}`; + } - required.forEach(verifyPresence.bind(undefined, payload, jwt)); + return argDecl + printDeprecated(arg.deprecationReason); +} - if (payload.iss !== undefined) { - let expectedIss = this.issuer.issuer; +function printDirective(directive) { + return ( + printDescription(directive) + + 'directive @' + + directive.name + + printArgs(directive.args) + + (directive.isRepeatable ? ' repeatable' : '') + + ' on ' + + directive.locations.join(' | ') + ); +} - if (aadIssValidation) { - expectedIss = this.issuer.issuer.replace('{tenantid}', payload.tid); - } +function printDeprecated(reason) { + if (reason == null) { + return ''; + } - if (payload.iss !== expectedIss) { - throw new RPError({ - printf: ['unexpected iss value, expected %s, got: %s', expectedIss, payload.iss], - jwt, - }); - } - } + if (reason !== _directives.DEFAULT_DEPRECATION_REASON) { + const astValue = (0, _printer.print)({ + kind: _kinds.Kind.STRING, + value: reason, + }); + return ` @deprecated(reason: ${astValue})`; + } - if (payload.iat !== undefined) { - if (typeof payload.iat !== 'number') { - throw new RPError({ - message: 'JWT iat claim must be a JSON numeric value', - jwt, - }); - } - } + return ' @deprecated'; +} - if (payload.nbf !== undefined) { - if (typeof payload.nbf !== 'number') { - throw new RPError({ - message: 'JWT nbf claim must be a JSON numeric value', - jwt, - }); - } - if (payload.nbf > timestamp + this[CLOCK_TOLERANCE]) { - throw new RPError({ - printf: ['JWT not active yet, now %i, nbf %i', timestamp + this[CLOCK_TOLERANCE], payload.nbf], - now: timestamp, - tolerance: this[CLOCK_TOLERANCE], - nbf: payload.nbf, - jwt, - }); - } - } +function printSpecifiedByURL(scalar) { + if (scalar.specifiedByURL == null) { + return ''; + } - if (payload.exp !== undefined) { - if (typeof payload.exp !== 'number') { - throw new RPError({ - message: 'JWT exp claim must be a JSON numeric value', - jwt, - }); - } - if (timestamp - this[CLOCK_TOLERANCE] >= payload.exp) { - throw new RPError({ - printf: ['JWT expired, now %i, exp %i', timestamp - this[CLOCK_TOLERANCE], payload.exp], - now: timestamp, - tolerance: this[CLOCK_TOLERANCE], - exp: payload.exp, - jwt, - }); - } - } + const astValue = (0, _printer.print)({ + kind: _kinds.Kind.STRING, + value: scalar.specifiedByURL, + }); + return ` @specifiedBy(url: ${astValue})`; +} - if (payload.aud !== undefined) { - if (Array.isArray(payload.aud)) { - if (payload.aud.length > 1 && !payload.azp) { - throw new RPError({ - message: 'missing required JWT property azp', - jwt, - }); - } +function printDescription(def, indentation = '', firstInBlock = true) { + const { description } = def; - if (!payload.aud.includes(this.client_id)) { - throw new RPError({ - printf: ['aud is missing the client_id, expected %s to be included in %j', this.client_id, payload.aud], - jwt, - }); - } - } else if (payload.aud !== this.client_id) { - throw new RPError({ - printf: ['aud mismatch, expected %s, got: %s', this.client_id, payload.aud], - jwt, - }); - } - } + if (description == null) { + return ''; + } - if (payload.azp !== undefined) { - let { additionalAuthorizedParties } = instance(this).get('options') || {}; + const blockString = (0, _printer.print)({ + kind: _kinds.Kind.STRING, + value: description, + block: (0, _blockString.isPrintableAsBlockString)(description), + }); + const prefix = + indentation && !firstInBlock ? '\n' + indentation : indentation; + return prefix + blockString.replace(/\n/g, '\n' + indentation) + '\n'; +} - if (typeof additionalAuthorizedParties === 'string') { - additionalAuthorizedParties = [this.client_id, additionalAuthorizedParties]; - } else if (Array.isArray(additionalAuthorizedParties)) { - additionalAuthorizedParties = [this.client_id, ...additionalAuthorizedParties]; - } else { - additionalAuthorizedParties = [this.client_id]; - } - if (!additionalAuthorizedParties.includes(payload.azp)) { - throw new RPError({ - printf: ['azp mismatch, got: %s', payload.azp], - jwt, - }); - } - } +/***/ }), - let key; +/***/ 34109: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (isSelfIssued) { - try { - assert(isPlainObject(payload.sub_jwk)); - key = jose.JWK.asKey(payload.sub_jwk); - assert.equal(key.type, 'public'); - } catch (err) { - throw new RPError({ - message: 'failed to use sub_jwk claim as an asymmetric JSON Web Key', - jwt, - }); - } - if (key.thumbprint !== payload.sub) { - throw new RPError({ - message: 'failed to match the subject with sub_jwk', - jwt, - }); - } - } else if (header.alg.startsWith('HS')) { - key = await this.joseSecret(); - } else if (header.alg !== 'none') { - key = await this.issuer.queryKeyStore(header); - } +"use strict"; - if (!key && header.alg === 'none') { - return { protected: header, payload }; - } - try { - return { - ...jose.JWS.verify(jwt, key, { complete: true }), - payload, - }; - } catch (err) { - throw new RPError({ - message: 'failed to validate JWT signature', - jwt, - }); - } - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.resolveASTSchemaCoordinate = resolveASTSchemaCoordinate; +exports.resolveSchemaCoordinate = resolveSchemaCoordinate; - /** - * @name refresh - * @api public - */ - async refresh(refreshToken, { exchangeBody, clientAssertionPayload, DPoP } = {}) { - let token = refreshToken; +var _inspect = __nccwpck_require__(10102); - if (token instanceof TokenSet) { - if (!token.refresh_token) { - throw new TypeError('refresh_token not present in TokenSet'); - } - token = token.refresh_token; - } - - const tokenset = await this.grant({ - ...exchangeBody, - grant_type: 'refresh_token', - refresh_token: String(token), - }, { clientAssertionPayload, DPoP }); - - if (tokenset.id_token) { - await this.decryptIdToken(tokenset); - await this.validateIdToken(tokenset, null, 'token', null); - - if (refreshToken instanceof TokenSet && refreshToken.id_token) { - const expectedSub = refreshToken.claims().sub; - const actualSub = tokenset.claims().sub; - if (actualSub !== expectedSub) { - throw new RPError({ - printf: ['sub mismatch, expected %s, got: %s', expectedSub, actualSub], - jwt: tokenset.id_token, - }); - } - } - } +var _kinds = __nccwpck_require__(11927); - return tokenset; - } +var _parser = __nccwpck_require__(50655); - async requestResource( - resourceUrl, - accessToken, - { - method, - headers, - body, - DPoP, - // eslint-disable-next-line no-nested-ternary - tokenType = DPoP ? 'DPoP' : accessToken instanceof TokenSet ? accessToken.token_type : 'Bearer', - } = {}, - ) { - if (accessToken instanceof TokenSet) { - if (!accessToken.access_token) { - throw new TypeError('access_token not present in TokenSet'); - } - accessToken = accessToken.access_token; // eslint-disable-line no-param-reassign - } +var _definition = __nccwpck_require__(5821); - const requestOpts = { - headers: { - Authorization: authorizationHeaderValue(accessToken, tokenType), - ...headers, - }, - body, - }; +/** + * A schema coordinate is resolved in the context of a GraphQL schema to + * uniquely identify a schema element. It returns undefined if the schema + * coordinate does not resolve to a schema element, meta-field, or introspection + * schema element. It will throw if the containing schema element (if + * applicable) does not exist. + * + * https://spec.graphql.org/draft/#sec-Schema-Coordinates.Semantics + */ +function resolveSchemaCoordinate(schema, schemaCoordinate) { + return resolveASTSchemaCoordinate( + schema, + (0, _parser.parseSchemaCoordinate)(schemaCoordinate), + ); +} +/** + * TypeCoordinate : Name + */ - const mTLS = !!this.tls_client_certificate_bound_access_tokens; +function resolveTypeCoordinate(schema, schemaCoordinate) { + // 1. Let {typeName} be the value of {Name}. + const typeName = schemaCoordinate.name.value; + const type = schema.getType(typeName); // 2. Return the type in the {schema} named {typeName} if it exists. - return request.call(this, { - ...requestOpts, - responseType: 'buffer', - method, - url: resourceUrl, - }, { accessToken, mTLS, DPoP }); + if (type == null) { + return; } - /** - * @name userinfo - * @api public - */ - async userinfo(accessToken, { - method = 'GET', via = 'header', tokenType, params, DPoP, - } = {}) { - assertIssuerConfiguration(this.issuer, 'userinfo_endpoint'); - const options = { - tokenType, - method: String(method).toUpperCase(), - DPoP, - }; - - if (options.method !== 'GET' && options.method !== 'POST') { - throw new TypeError('#userinfo() method can only be POST or a GET'); - } + return { + kind: 'NamedType', + type, + }; +} +/** + * MemberCoordinate : Name . Name + */ - if (via === 'query' && options.method !== 'GET') { - throw new TypeError('userinfo endpoints will only parse query strings for GET requests'); - } else if (via === 'body' && options.method !== 'POST') { - throw new TypeError('can only send body on POST'); - } +function resolveMemberCoordinate(schema, schemaCoordinate) { + // 1. Let {typeName} be the value of the first {Name}. + // 2. Let {type} be the type in the {schema} named {typeName}. + const typeName = schemaCoordinate.name.value; + const type = schema.getType(typeName); // 3. Assert: {type} must exist, and must be an Enum, Input Object, Object or Interface type. - const jwt = !!(this.userinfo_signed_response_alg || this.userinfo_encrypted_response_alg); + if (!type) { + throw new Error( + `Expected ${(0, _inspect.inspect)( + typeName, + )} to be defined as a type in the schema.`, + ); + } - if (jwt) { - options.headers = { Accept: 'application/jwt' }; - } else { - options.headers = { Accept: 'application/json' }; - } + if ( + !(0, _definition.isEnumType)(type) && + !(0, _definition.isInputObjectType)(type) && + !(0, _definition.isObjectType)(type) && + !(0, _definition.isInterfaceType)(type) + ) { + throw new Error( + `Expected ${(0, _inspect.inspect)( + typeName, + )} to be an Enum, Input Object, Object or Interface type.`, + ); + } // 4. If {type} is an Enum type: - const mTLS = !!this.tls_client_certificate_bound_access_tokens; + if ((0, _definition.isEnumType)(type)) { + // 1. Let {enumValueName} be the value of the second {Name}. + const enumValueName = schemaCoordinate.memberName.value; + const enumValue = type.getValue(enumValueName); // 2. Return the enum value of {type} named {enumValueName} if it exists. - let targetUrl; - if (mTLS && this.issuer.mtls_endpoint_aliases) { - targetUrl = this.issuer.mtls_endpoint_aliases.userinfo_endpoint; + if (enumValue == null) { + return; } - targetUrl = new url.URL(targetUrl || this.issuer.userinfo_endpoint); - - // when via is not header we clear the Authorization header and add either - // query string parameters or urlencoded body access_token parameter - if (via === 'query') { - options.headers.Authorization = undefined; - targetUrl.searchParams.append('access_token', accessToken instanceof TokenSet ? accessToken.access_token : accessToken); - } else if (via === 'body') { - options.headers.Authorization = undefined; - options.headers['Content-Type'] = 'application/x-www-form-urlencoded'; - options.body = new url.URLSearchParams(); - options.body.append('access_token', accessToken instanceof TokenSet ? accessToken.access_token : accessToken); - } + return { + kind: 'EnumValue', + type, + enumValue, + }; + } // 5. Otherwise, if {type} is an Input Object type: - // handle additional parameters, GET via querystring, POST via urlencoded body - if (params) { - if (options.method === 'GET') { - Object.entries(params).forEach(([key, value]) => { - targetUrl.searchParams.append(key, value); - }); - } else if (options.body) { // POST && via body - Object.entries(params).forEach(([key, value]) => { - options.body.append(key, value); - }); - } else { // POST && via header - options.body = new url.URLSearchParams(); - options.headers['Content-Type'] = 'application/x-www-form-urlencoded'; - Object.entries(params).forEach(([key, value]) => { - options.body.append(key, value); - }); - } - } + if ((0, _definition.isInputObjectType)(type)) { + // 1. Let {inputFieldName} be the value of the second {Name}. + const inputFieldName = schemaCoordinate.memberName.value; + const inputField = type.getFields()[inputFieldName]; // 2. Return the input field of {type} named {inputFieldName} if it exists. - if (options.body) { - options.body = options.body.toString(); + if (inputField == null) { + return; } - const response = await this.requestResource(targetUrl, accessToken, options); + return { + kind: 'InputField', + type, + inputField, + }; + } // 6. Otherwise: + // 1. Let {fieldName} be the value of the second {Name}. - let parsed = processResponse(response, { bearer: true }); + const fieldName = schemaCoordinate.memberName.value; + const field = type.getFields()[fieldName]; // 2. Return the field of {type} named {fieldName} if it exists. - if (jwt) { - if (!JWT_CONTENT.test(response.headers['content-type'])) { - throw new RPError({ - message: 'expected application/jwt response from the userinfo_endpoint', - response, - }); - } + if (field == null) { + return; + } - const body = response.body.toString(); - const userinfo = await this.decryptJWTUserinfo(body); - if (!this.userinfo_signed_response_alg) { - try { - parsed = JSON.parse(userinfo); - assert(isPlainObject(parsed)); - } catch (err) { - throw new RPError({ - message: 'failed to parse userinfo JWE payload as JSON', - jwt: userinfo, - }); - } - } else { - ({ payload: parsed } = await this.validateJWTUserinfo(userinfo)); - } - } else { - try { - parsed = JSON.parse(response.body); - } catch (error) { - throw new ParseError(error, response); - } - } + return { + kind: 'Field', + type, + field, + }; +} +/** + * ArgumentCoordinate : Name . Name ( Name : ) + */ - if (accessToken instanceof TokenSet && accessToken.id_token) { - const expectedSub = accessToken.claims().sub; - if (parsed.sub !== expectedSub) { - throw new RPError({ - printf: ['userinfo sub mismatch, expected %s, got: %s', expectedSub, parsed.sub], - body: parsed, - jwt: accessToken.id_token, - }); - } - } +function resolveArgumentCoordinate(schema, schemaCoordinate) { + // 1. Let {typeName} be the value of the first {Name}. + // 2. Let {type} be the type in the {schema} named {typeName}. + const typeName = schemaCoordinate.name.value; + const type = schema.getType(typeName); // 3. Assert: {type} must exist, and be an Object or Interface type. - return parsed; + if (type == null) { + throw new Error( + `Expected ${(0, _inspect.inspect)( + typeName, + )} to be defined as a type in the schema.`, + ); } - /** - * @name derivedKey - * @api private - */ - async derivedKey(len) { - const cacheKey = `${len}_key`; - if (instance(this).has(cacheKey)) { - return instance(this).get(cacheKey); - } + if ( + !(0, _definition.isObjectType)(type) && + !(0, _definition.isInterfaceType)(type) + ) { + throw new Error( + `Expected ${(0, _inspect.inspect)( + typeName, + )} to be an object type or interface type.`, + ); + } // 4. Let {fieldName} be the value of the second {Name}. + // 5. Let {field} be the field of {type} named {fieldName}. - const hash = len <= 256 ? 'sha256' : len <= 384 ? 'sha384' : len <= 512 ? 'sha512' : false; // eslint-disable-line no-nested-ternary - if (!hash) { - throw new Error('unsupported symmetric encryption key derivation'); - } + const fieldName = schemaCoordinate.fieldName.value; + const field = type.getFields()[fieldName]; // 7. Assert: {field} must exist. - const derivedBuffer = crypto.createHash(hash) - .update(this.client_secret) - .digest() - .slice(0, len / 8); + if (field == null) { + throw new Error( + `Expected ${(0, _inspect.inspect)( + fieldName, + )} to exist as a field of type ${(0, _inspect.inspect)( + typeName, + )} in the schema.`, + ); + } // 7. Let {fieldArgumentName} be the value of the third {Name}. - const key = jose.JWK.asKey({ k: base64url.encode(derivedBuffer), kty: 'oct' }); - instance(this).set(cacheKey, key); + const fieldArgumentName = schemaCoordinate.argumentName.value; + const fieldArgument = field.args.find( + (arg) => arg.name === fieldArgumentName, + ); // 8. Return the argument of {field} named {fieldArgumentName} if it exists. - return key; + if (fieldArgument == null) { + return; } - /** - * @name joseSecret - * @api private - */ - async joseSecret(alg) { - if (!this.client_secret) { - throw new TypeError('client_secret is required'); - } - if (/^A(\d{3})(?:GCM)?KW$/.test(alg)) { - return this.derivedKey(parseInt(RegExp.$1, 10)); - } + return { + kind: 'FieldArgument', + type, + field, + fieldArgument, + }; +} +/** + * DirectiveCoordinate : \@ Name + */ - if (/^A(\d{3})(?:GCM|CBC-HS(\d{3}))$/.test(alg)) { - return this.derivedKey(parseInt(RegExp.$2 || RegExp.$1, 10)); - } +function resolveDirectiveCoordinate(schema, schemaCoordinate) { + // 1. Let {directiveName} be the value of {Name}. + const directiveName = schemaCoordinate.name.value; + const directive = schema.getDirective(directiveName); // 2. Return the directive in the {schema} named {directiveName} if it exists. - if (instance(this).has('jose_secret')) { - return instance(this).get('jose_secret'); - } + if (!directive) { + return; + } - const key = jose.JWK.asKey({ k: base64url.encode(this.client_secret), kty: 'oct' }); - instance(this).set('jose_secret', key); + return { + kind: 'Directive', + directive, + }; +} +/** + * DirectiveArgumentCoordinate : \@ Name ( Name : ) + */ - return key; - } +function resolveDirectiveArgumentCoordinate(schema, schemaCoordinate) { + // 1. Let {directiveName} be the value of the first {Name}. + // 2. Let {directive} be the directive in the {schema} named {directiveName}. + const directiveName = schemaCoordinate.name.value; + const directive = schema.getDirective(directiveName); // 3. Assert {directive} must exist. - /** - * @name grant - * @api public - */ - async grant(body, { clientAssertionPayload, DPoP } = {}) { - assertIssuerConfiguration(this.issuer, 'token_endpoint'); - const response = await authenticatedPost.call( - this, - 'token', - { - form: body, - responseType: 'json', - }, - { clientAssertionPayload, DPoP }, + if (!directive) { + throw new Error( + `Expected ${(0, _inspect.inspect)( + directiveName, + )} to be defined as a directive in the schema.`, ); - const responseBody = processResponse(response); + } // 4. Let {directiveArgumentName} be the value of the second {Name}. + + const { + argumentName: { value: directiveArgumentName }, + } = schemaCoordinate; + const directiveArgument = directive.args.find( + (arg) => arg.name === directiveArgumentName, + ); // 5. Return the argument of {directive} named {directiveArgumentName} if it exists. - return new TokenSet(responseBody); + if (!directiveArgument) { + return; } - /** - * @name deviceAuthorization - * @api public - */ - async deviceAuthorization(params = {}, { exchangeBody, clientAssertionPayload, DPoP } = {}) { - assertIssuerConfiguration(this.issuer, 'device_authorization_endpoint'); - assertIssuerConfiguration(this.issuer, 'token_endpoint'); - - const body = authorizationParams.call(this, { - client_id: this.client_id, - redirect_uri: null, - response_type: null, - ...params, - }); + return { + kind: 'DirectiveArgument', + directive, + directiveArgument, + }; +} +/** + * Resolves schema coordinate from a parsed SchemaCoordinate node. + */ - const response = await authenticatedPost.call( - this, - 'device_authorization', - { - responseType: 'json', - form: body, - }, - { clientAssertionPayload, endpointAuthMethod: 'token' }, - ); - const responseBody = processResponse(response); - - return new DeviceFlowHandle({ - client: this, - exchangeBody, - clientAssertionPayload, - response: responseBody, - maxAge: params.max_age, - DPoP, - }); - } +function resolveASTSchemaCoordinate(schema, schemaCoordinate) { + switch (schemaCoordinate.kind) { + case _kinds.Kind.TYPE_COORDINATE: + return resolveTypeCoordinate(schema, schemaCoordinate); - /** - * @name revoke - * @api public - */ - async revoke(token, hint, { revokeBody, clientAssertionPayload } = {}) { - assertIssuerConfiguration(this.issuer, 'revocation_endpoint'); - if (hint !== undefined && typeof hint !== 'string') { - throw new TypeError('hint must be a string'); - } + case _kinds.Kind.MEMBER_COORDINATE: + return resolveMemberCoordinate(schema, schemaCoordinate); - const form = { ...revokeBody, token }; + case _kinds.Kind.ARGUMENT_COORDINATE: + return resolveArgumentCoordinate(schema, schemaCoordinate); - if (hint) { - form.token_type_hint = hint; - } + case _kinds.Kind.DIRECTIVE_COORDINATE: + return resolveDirectiveCoordinate(schema, schemaCoordinate); - const response = await authenticatedPost.call( - this, - 'revocation', { - form, - }, { clientAssertionPayload }, - ); - processResponse(response, { body: false }); + case _kinds.Kind.DIRECTIVE_ARGUMENT_COORDINATE: + return resolveDirectiveArgumentCoordinate(schema, schemaCoordinate); } +} - /** - * @name introspect - * @api public - */ - async introspect(token, hint, { introspectBody, clientAssertionPayload } = {}) { - assertIssuerConfiguration(this.issuer, 'introspection_endpoint'); - if (hint !== undefined && typeof hint !== 'string') { - throw new TypeError('hint must be a string'); - } - - const form = { ...introspectBody, token }; - if (hint) { - form.token_type_hint = hint; - } - const response = await authenticatedPost.call( - this, - 'introspection', - { form, responseType: 'json' }, - { clientAssertionPayload }, - ); +/***/ }), - const responseBody = processResponse(response); +/***/ 29125: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - return responseBody; - } +"use strict"; - /** - * @name fetchDistributedClaims - * @api public - */ - async fetchDistributedClaims(claims, tokens = {}) { - if (!isPlainObject(claims)) { - throw new TypeError('claims argument must be a plain object'); - } - if (!isPlainObject(claims._claim_sources)) { - return claims; - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.separateOperations = separateOperations; - if (!isPlainObject(claims._claim_names)) { - return claims; - } +var _kinds = __nccwpck_require__(11927); - const distributedSources = Object.entries(claims._claim_sources) - .filter(([, value]) => value && value.endpoint); +var _visitor = __nccwpck_require__(5678); - await Promise.all(distributedSources.map(async ([sourceName, def]) => { - try { - const requestOpts = { - headers: { - Accept: 'application/jwt', - Authorization: authorizationHeaderValue(def.access_token || tokens[sourceName]), - }, - }; +/** + * separateOperations accepts a single AST document which may contain many + * operations and fragments and returns a collection of AST documents each of + * which contains a single operation as well the fragment definitions it + * refers to. + */ +function separateOperations(documentAST) { + const operations = []; + const depGraph = Object.create(null); // Populate metadata and build a dependency graph. - const response = await request.call(this, { - ...requestOpts, - method: 'GET', - url: def.endpoint, - }); - const body = processResponse(response, { bearer: true }); + for (const definitionNode of documentAST.definitions) { + switch (definitionNode.kind) { + case _kinds.Kind.OPERATION_DEFINITION: + operations.push(definitionNode); + break; - const decoded = await claimJWT.call(this, 'distributed', body); - delete claims._claim_sources[sourceName]; - Object.entries(claims._claim_names).forEach( - assignClaim(claims, decoded, sourceName, false), + case _kinds.Kind.FRAGMENT_DEFINITION: + depGraph[definitionNode.name.value] = collectDependencies( + definitionNode.selectionSet, ); - } catch (err) { - err.src = sourceName; - throw err; - } - })); - - cleanUpClaims(claims); - return claims; - } + break; - /** - * @name unpackAggregatedClaims - * @api public - */ - async unpackAggregatedClaims(claims) { - if (!isPlainObject(claims)) { - throw new TypeError('claims argument must be a plain object'); + default: // ignore non-executable definitions } + } // For each operation, produce a new synthesized AST which includes only what + // is necessary for completing that operation. - if (!isPlainObject(claims._claim_sources)) { - return claims; - } + const separatedDocumentASTs = Object.create(null); - if (!isPlainObject(claims._claim_names)) { - return claims; - } + for (const operation of operations) { + const dependencies = new Set(); - const aggregatedSources = Object.entries(claims._claim_sources) - .filter(([, value]) => value && value.JWT); + for (const fragmentName of collectDependencies(operation.selectionSet)) { + collectTransitiveDependencies(dependencies, depGraph, fragmentName); + } // Provides the empty string for anonymous operations. - await Promise.all(aggregatedSources.map(async ([sourceName, def]) => { - try { - const decoded = await claimJWT.call(this, 'aggregated', def.JWT); - delete claims._claim_sources[sourceName]; - Object.entries(claims._claim_names).forEach(assignClaim(claims, decoded, sourceName)); - } catch (err) { - err.src = sourceName; - throw err; - } - })); + const operationName = operation.name ? operation.name.value : ''; // The list of definition nodes to be included for this operation, sorted + // to retain the same order as the original document. - cleanUpClaims(claims); - return claims; + separatedDocumentASTs[operationName] = { + kind: _kinds.Kind.DOCUMENT, + definitions: documentAST.definitions.filter( + (node) => + node === operation || + (node.kind === _kinds.Kind.FRAGMENT_DEFINITION && + dependencies.has(node.name.value)), + ), + }; } - /** - * @name register - * @api public - */ - static async register(metadata, options = {}) { - const { initialAccessToken, jwks, ...clientOptions } = options; + return separatedDocumentASTs; +} - assertIssuerConfiguration(this.issuer, 'registration_endpoint'); +// From a dependency graph, collects a list of transitive dependencies by +// recursing through a dependency graph. +function collectTransitiveDependencies(collected, depGraph, fromName) { + if (!collected.has(fromName)) { + collected.add(fromName); + const immediateDeps = depGraph[fromName]; - if (jwks !== undefined && !(metadata.jwks || metadata.jwks_uri)) { - const keystore = getKeystore.call(this, jwks); - metadata.jwks = keystore.toJWKS(false); - // eslint-disable-next-line no-restricted-syntax - for (const jwk of metadata.jwks.keys) { - if (jwk.kid.startsWith('DONOTUSE.')) { - delete jwk.kid; - } + if (immediateDeps !== undefined) { + for (const toName of immediateDeps) { + collectTransitiveDependencies(collected, depGraph, toName); } } + } +} - const response = await request.call(this, { - headers: initialAccessToken ? { - Authorization: authorizationHeaderValue(initialAccessToken), - } : undefined, - responseType: 'json', - json: metadata, - url: this.issuer.registration_endpoint, - method: 'POST', - }); - const responseBody = processResponse(response, { statusCode: 201, bearer: true }); +function collectDependencies(selectionSet) { + const dependencies = []; + (0, _visitor.visit)(selectionSet, { + FragmentSpread(node) { + dependencies.push(node.name.value); + }, + }); + return dependencies; +} - return new this(responseBody, jwks, clientOptions); - } - /** - * @name metadata - * @api public - */ - get metadata() { - const copy = {}; - instance(this).get('metadata').forEach((value, key) => { - copy[key] = value; - }); - return copy; - } +/***/ }), - /** - * @name fromUri - * @api public - */ - static async fromUri(registrationClientUri, registrationAccessToken, jwks, clientOptions) { - const response = await request.call(this, { - method: 'GET', - url: registrationClientUri, - responseType: 'json', - headers: { Authorization: authorizationHeaderValue(registrationAccessToken) }, - }); - const responseBody = processResponse(response, { bearer: true }); +/***/ 82278: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - return new this(responseBody, jwks, clientOptions); - } +"use strict"; - /** - * @name requestObject - * @api public - */ - async requestObject(requestObject = {}, { - sign: signingAlgorithm = this.request_object_signing_alg || 'none', - encrypt: { - alg: eKeyManagement = this.request_object_encryption_alg, - enc: eContentEncryption = this.request_object_encryption_enc || 'A128CBC-HS256', - } = {}, - } = {}) { - if (!isPlainObject(requestObject)) { - throw new TypeError('requestObject must be a plain object'); - } - let signed; - let key; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.sortValueNode = sortValueNode; - const fapi = this.constructor.name === 'FAPIClient'; - const unix = now(); - const header = { alg: signingAlgorithm, typ: 'oauth-authz-req+jwt' }; - const payload = JSON.stringify(defaults({}, requestObject, { - iss: this.client_id, - aud: this.issuer.issuer, - client_id: this.client_id, - jti: random(), - iat: unix, - exp: unix + 300, - ...(fapi ? { nbf: unix } : undefined), - })); +var _naturalCompare = __nccwpck_require__(20038); - if (signingAlgorithm === 'none') { - signed = [ - base64url.encode(JSON.stringify(header)), - base64url.encode(payload), - '', - ].join('.'); - } else { - const symmetric = signingAlgorithm.startsWith('HS'); - if (symmetric) { - key = await this.joseSecret(); - } else { - const keystore = instance(this).get('keystore'); +var _kinds = __nccwpck_require__(11927); - if (!keystore) { - throw new TypeError(`no keystore present for client, cannot sign using alg ${signingAlgorithm}`); - } - key = keystore.get({ alg: signingAlgorithm, use: 'sig' }); - if (!key) { - throw new TypeError(`no key to sign with found for alg ${signingAlgorithm}`); - } - } +/** + * Sort ValueNode. + * + * This function returns a sorted copy of the given ValueNode. + * + * @internal + */ +function sortValueNode(valueNode) { + switch (valueNode.kind) { + case _kinds.Kind.OBJECT: + return { ...valueNode, fields: sortFields(valueNode.fields) }; - signed = jose.JWS.sign(payload, key, { - ...header, - kid: symmetric || key.kid.startsWith('DONOTUSE.') ? undefined : key.kid, - }); - } + case _kinds.Kind.LIST: + return { ...valueNode, values: valueNode.values.map(sortValueNode) }; - if (!eKeyManagement) { - return signed; - } + case _kinds.Kind.INT: + case _kinds.Kind.FLOAT: + case _kinds.Kind.STRING: + case _kinds.Kind.BOOLEAN: + case _kinds.Kind.NULL: + case _kinds.Kind.ENUM: + case _kinds.Kind.VARIABLE: + return valueNode; + } +} - const fields = { alg: eKeyManagement, enc: eContentEncryption, cty: 'oauth-authz-req+jwt' }; +function sortFields(fields) { + return fields + .map((fieldNode) => ({ + ...fieldNode, + value: sortValueNode(fieldNode.value), + })) + .sort((fieldA, fieldB) => + (0, _naturalCompare.naturalCompare)(fieldA.name.value, fieldB.name.value), + ); +} - if (fields.alg.match(/^(RSA|ECDH)/)) { - [key] = await this.issuer.queryKeyStore({ - alg: fields.alg, - enc: fields.enc, - use: 'enc', - }, { allowMulti: true }); - } else { - key = await this.joseSecret(fields.alg === 'dir' ? fields.enc : fields.alg); - } - return jose.JWE.encrypt(signed, key, { - ...fields, - kid: key.kty === 'oct' ? undefined : key.kid, - }); - } +/***/ }), - /** - * @name pushedAuthorizationRequest - * @api public - */ - async pushedAuthorizationRequest(params = {}, { clientAssertionPayload } = {}) { - assertIssuerConfiguration(this.issuer, 'pushed_authorization_request_endpoint'); +/***/ 17766: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - const body = { - ...('request' in params ? params : authorizationParams.call(this, params)), - client_id: this.client_id, - }; +"use strict"; - const response = await authenticatedPost.call( - this, - 'pushed_authorization_request', - { - responseType: 'json', - form: body, - }, - { clientAssertionPayload, endpointAuthMethod: 'token' }, - ); - const responseBody = processResponse(response, { statusCode: 201 }); - if (!('expires_in' in responseBody)) { - throw new RPError({ - message: 'expected expires_in in Pushed Authorization Successful Response', - response, - }); - } - if (typeof responseBody.expires_in !== 'number') { - throw new RPError({ - message: 'invalid expires_in value in Pushed Authorization Successful Response', - response, - }); - } - if (!('request_uri' in responseBody)) { - throw new RPError({ - message: 'expected request_uri in Pushed Authorization Successful Response', - response, - }); - } - if (typeof responseBody.request_uri !== 'string') { - throw new RPError({ - message: 'invalid request_uri value in Pushed Authorization Successful Response', - response, - }); - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.stripIgnoredCharacters = stripIgnoredCharacters; - return responseBody; - } +var _blockString = __nccwpck_require__(4515); - /** - * @name issuer - * @api public - */ - static get issuer() { - return issuer; - } +var _lexer = __nccwpck_require__(24605); - /** - * @name issuer - * @api public - */ - get issuer() { // eslint-disable-line class-methods-use-this - return issuer; - } +var _source = __nccwpck_require__(65521); - /* istanbul ignore next */ - [inspect.custom]() { - return `${this.constructor.name} ${inspect(this.metadata, { - depth: Infinity, - colors: process.stdout.isTTY, - compact: false, - sorted: true, - })}`; - } -}; +var _tokenKind = __nccwpck_require__(91565); /** - * @name validateJARM - * @api private + * Strips characters that are not significant to the validity or execution + * of a GraphQL document: + * - UnicodeBOM + * - WhiteSpace + * - LineTerminator + * - Comment + * - Comma + * - BlockString indentation + * + * Note: It is required to have a delimiter character between neighboring + * non-punctuator tokens and this function always uses single space as delimiter. + * + * It is guaranteed that both input and output documents if parsed would result + * in the exact same AST except for nodes location. + * + * Warning: It is guaranteed that this function will always produce stable results. + * However, it's not guaranteed that it will stay the same between different + * releases due to bugfixes or changes in the GraphQL specification. + * + * Query example: + * + * ```graphql + * query SomeQuery($foo: String!, $bar: String) { + * someField(foo: $foo, bar: $bar) { + * a + * b { + * c + * d + * } + * } + * } + * ``` + * + * Becomes: + * + * ```graphql + * query SomeQuery($foo:String!$bar:String){someField(foo:$foo bar:$bar){a b{c d}}} + * ``` + * + * SDL example: + * + * ```graphql + * """ + * Type description + * """ + * type Foo { + * """ + * Field description + * """ + * bar: String + * } + * ``` + * + * Becomes: + * + * ```graphql + * """Type description""" type Foo{"""Field description""" bar:String} + * ``` */ -async function validateJARM(response) { - const expectedAlg = this.authorization_signed_response_alg; - const { payload } = await this.validateJWT(response, expectedAlg, ['iss', 'exp', 'aud']); - return pickCb(payload); -} +function stripIgnoredCharacters(source) { + const sourceObj = (0, _source.isSource)(source) + ? source + : new _source.Source(source); + const body = sourceObj.body; + const lexer = new _lexer.Lexer(sourceObj); + let strippedBody = ''; + let wasLastAddedTokenNonPunctuator = false; -Object.defineProperty(BaseClient.prototype, 'validateJARM', { - enumerable: true, - configurable: true, - value(...args) { - process.emitWarning( - "The JARM API implements an OIDF implementer's draft. Breaking draft implementations are included as minor versions of the openid-client library, therefore, the ~ semver operator should be used and close attention be payed to library changelog as well as the drafts themselves.", - 'DraftWarning', - ); - Object.defineProperty(BaseClient.prototype, 'validateJARM', { - enumerable: true, - configurable: true, - value: validateJARM, - }); - return this.validateJARM(...args); - }, -}); + while (lexer.advance().kind !== _tokenKind.TokenKind.EOF) { + const currentToken = lexer.token; + const tokenKind = currentToken.kind; + /** + * Every two non-punctuator tokens should have space between them. + * Also prevent case of non-punctuator token following by spread resulting + * in invalid token (e.g. `1...` is invalid Float token). + */ -/** - * @name dpopProof - * @api private - */ -function dpopProof(payload, jwk, accessToken) { - if (!isPlainObject(payload)) { - throw new TypeError('payload must be a plain object'); - } + const isNonPunctuator = !(0, _lexer.isPunctuatorTokenKind)( + currentToken.kind, + ); - let key; - try { - key = jose.JWK.asKey(jwk); - assert(key.type === 'private'); - } catch (err) { - throw new TypeError('"DPoP" option must be an asymmetric private key to sign the DPoP Proof JWT with'); - } + if (wasLastAddedTokenNonPunctuator) { + if ( + isNonPunctuator || + currentToken.kind === _tokenKind.TokenKind.SPREAD + ) { + strippedBody += ' '; + } + } - let { alg } = key; + const tokenBody = body.slice(currentToken.start, currentToken.end); - if (!alg && this.issuer.dpop_signing_alg_values_supported) { - const algs = key.algorithms('sign'); - alg = this.issuer.dpop_signing_alg_values_supported.find((a) => algs.has(a)); - } + if (tokenKind === _tokenKind.TokenKind.BLOCK_STRING) { + strippedBody += (0, _blockString.printBlockString)(currentToken.value, { + minimize: true, + }); + } else { + strippedBody += tokenBody; + } - if (!alg) { - [alg] = key.algorithms('sign'); + wasLastAddedTokenNonPunctuator = isNonPunctuator; } - return jose.JWS.sign({ - iat: now(), - jti: random(), - ath: accessToken ? base64url.encode(crypto.createHash('sha256').update(accessToken).digest()) : undefined, - ...payload, - }, jwk, { - alg, - typ: 'dpop+jwt', - jwk: pick(key, 'kty', 'crv', 'x', 'y', 'e', 'n'), - }); + return strippedBody; } -Object.defineProperty(BaseClient.prototype, 'dpopProof', { - enumerable: true, - configurable: true, - value(...args) { - process.emitWarning( - 'The DPoP APIs implements an IETF draft (https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-03.html). Breaking draft implementations are included as minor versions of the openid-client library, therefore, the ~ semver operator should be used and close attention be payed to library changelog as well as the drafts themselves.', - 'DraftWarning', - ); - Object.defineProperty(BaseClient.prototype, 'dpopProof', { - enumerable: true, - configurable: true, - value: dpopProof, - }); - return this.dpopProof(...args); - }, -}); -module.exports.BaseClient = BaseClient; +/***/ }), +/***/ 10333: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/***/ }), +"use strict"; -/***/ 23979: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -/* eslint-disable camelcase */ -const { inspect } = __nccwpck_require__(73837); +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.doTypesOverlap = doTypesOverlap; +exports.isEqualType = isEqualType; +exports.isTypeSubTypeOf = isTypeSubTypeOf; -const { RPError, OPError } = __nccwpck_require__(45061); -const instance = __nccwpck_require__(27702); -const now = __nccwpck_require__(8542); -const { authenticatedPost } = __nccwpck_require__(7619); -const processResponse = __nccwpck_require__(28576); -const TokenSet = __nccwpck_require__(39029); +var _definition = __nccwpck_require__(5821); -class DeviceFlowHandle { - constructor({ - client, exchangeBody, clientAssertionPayload, response, maxAge, DPoP, - }) { - ['verification_uri', 'user_code', 'device_code'].forEach((prop) => { - if (typeof response[prop] !== 'string' || !response[prop]) { - throw new RPError(`expected ${prop} string to be returned by Device Authorization Response, got %j`, response[prop]); - } - }); +/** + * Provided two types, return true if the types are equal (invariant). + */ +function isEqualType(typeA, typeB) { + // Equivalent types are equal. + if (typeA === typeB) { + return true; + } // If either type is non-null, the other must also be non-null. - if (!Number.isSafeInteger(response.expires_in)) { - throw new RPError('expected expires_in number to be returned by Device Authorization Response, got %j', response.expires_in); - } + if ( + (0, _definition.isNonNullType)(typeA) && + (0, _definition.isNonNullType)(typeB) + ) { + return isEqualType(typeA.ofType, typeB.ofType); + } // If either type is a list, the other must also be a list. - instance(this).expires_at = now() + response.expires_in; - instance(this).client = client; - instance(this).DPoP = DPoP; - instance(this).maxAge = maxAge; - instance(this).exchangeBody = exchangeBody; - instance(this).clientAssertionPayload = clientAssertionPayload; - instance(this).response = response; - instance(this).interval = response.interval * 1000 || 5000; - } + if ( + (0, _definition.isListType)(typeA) && + (0, _definition.isListType)(typeB) + ) { + return isEqualType(typeA.ofType, typeB.ofType); + } // Otherwise the types are not equal. - abort() { - instance(this).aborted = true; - } + return false; +} +/** + * Provided a type and a super type, return true if the first type is either + * equal or a subset of the second super type (covariant). + */ - async poll({ signal } = {}) { - if ((signal && signal.aborted) || instance(this).aborted) { - throw new RPError('polling aborted'); - } +function isTypeSubTypeOf(schema, maybeSubType, superType) { + // Equivalent type is a valid subtype + if (maybeSubType === superType) { + return true; + } // If superType is non-null, maybeSubType must also be non-null. - if (this.expired()) { - throw new RPError('the device code %j has expired and the device authorization session has concluded', this.device_code); + if ((0, _definition.isNonNullType)(superType)) { + if ((0, _definition.isNonNullType)(maybeSubType)) { + return isTypeSubTypeOf(schema, maybeSubType.ofType, superType.ofType); } - await new Promise((resolve) => setTimeout(resolve, instance(this).interval)); - - const response = await authenticatedPost.call( - instance(this).client, - 'token', - { - form: { - ...instance(this).exchangeBody, - grant_type: 'urn:ietf:params:oauth:grant-type:device_code', - device_code: this.device_code, - }, - responseType: 'json', - }, - { clientAssertionPayload: instance(this).clientAssertionPayload, DPoP: instance(this).DPoP }, - ); - - let responseBody; - try { - responseBody = processResponse(response); - } catch (err) { - switch (err instanceof OPError && err.error) { - case 'slow_down': - instance(this).interval += 5000; - case 'authorization_pending': // eslint-disable-line no-fallthrough - return this.poll({ signal }); - default: - throw err; - } - } + return false; + } - const tokenset = new TokenSet(responseBody); + if ((0, _definition.isNonNullType)(maybeSubType)) { + // If superType is nullable, maybeSubType may be non-null or nullable. + return isTypeSubTypeOf(schema, maybeSubType.ofType, superType); + } // If superType type is a list, maybeSubType type must also be a list. - if ('id_token' in tokenset) { - await instance(this).client.decryptIdToken(tokenset); - await instance(this).client.validateIdToken(tokenset, undefined, 'token', instance(this).maxAge); + if ((0, _definition.isListType)(superType)) { + if ((0, _definition.isListType)(maybeSubType)) { + return isTypeSubTypeOf(schema, maybeSubType.ofType, superType.ofType); } - return tokenset; + return false; } - get device_code() { - return instance(this).response.device_code; - } + if ((0, _definition.isListType)(maybeSubType)) { + // If superType is not a list, maybeSubType must also be not a list. + return false; + } // If superType type is an abstract type, check if it is super type of maybeSubType. + // Otherwise, the child type is not a valid subtype of the parent type. - get user_code() { - return instance(this).response.user_code; - } + return ( + (0, _definition.isAbstractType)(superType) && + ((0, _definition.isInterfaceType)(maybeSubType) || + (0, _definition.isObjectType)(maybeSubType)) && + schema.isSubType(superType, maybeSubType) + ); +} +/** + * Provided two composite types, determine if they "overlap". Two composite + * types overlap when the Sets of possible concrete types for each intersect. + * + * This is often used to determine if a fragment of a given type could possibly + * be visited in a context of another type. + * + * This function is commutative. + */ - get verification_uri() { - return instance(this).response.verification_uri; +function doTypesOverlap(schema, typeA, typeB) { + // Equivalent types overlap + if (typeA === typeB) { + return true; } - get verification_uri_complete() { - return instance(this).response.verification_uri_complete; - } + if ((0, _definition.isAbstractType)(typeA)) { + if ((0, _definition.isAbstractType)(typeB)) { + // If both types are abstract, then determine if there is any intersection + // between possible concrete types of each. + return schema + .getPossibleTypes(typeA) + .some((type) => schema.isSubType(typeB, type)); + } // Determine if the latter type is a possible concrete type of the former. - get expires_in() { - return Math.max.apply(null, [instance(this).expires_at - now(), 0]); + return schema.isSubType(typeA, typeB); } - expired() { - return this.expires_in === 0; - } + if ((0, _definition.isAbstractType)(typeB)) { + // Determine if the former type is a possible concrete type of the latter. + return schema.isSubType(typeB, typeA); + } // Otherwise the types do not overlap. - /* istanbul ignore next */ - [inspect.custom]() { - return `${this.constructor.name} ${inspect(instance(this).response, { - depth: Infinity, - colors: process.stdout.isTTY, - compact: false, - sorted: true, - })}`; - } + return false; } -module.exports = DeviceFlowHandle; - /***/ }), -/***/ 45061: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 27664: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/* eslint-disable camelcase */ -const { format } = __nccwpck_require__(73837); - -const makeError = __nccwpck_require__(21381); - -function OPError({ - error_description, - error, - error_uri, - session_state, - state, - scope, -}, response) { - OPError.super.call(this, !error_description ? error : `${error} (${error_description})`); - - Object.assign( - this, - { error }, - (error_description && { error_description }), - (error_uri && { error_uri }), - (state && { state }), - (scope && { scope }), - (session_state && { session_state }), - ); +"use strict"; - if (response) { - Object.defineProperty(this, 'response', { - value: response, - }); - } -} -makeError(OPError); +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.typeFromAST = typeFromAST; + +var _kinds = __nccwpck_require__(11927); -function RPError(...args) { - if (typeof args[0] === 'string') { - RPError.super.call(this, format(...args)); - } else { - const { - message, printf, response, ...rest - } = args[0]; - if (printf) { - RPError.super.call(this, format(...printf)); - } else { - RPError.super.call(this, message); +var _definition = __nccwpck_require__(5821); + +function typeFromAST(schema, typeNode) { + switch (typeNode.kind) { + case _kinds.Kind.LIST_TYPE: { + const innerType = typeFromAST(schema, typeNode.type); + return innerType && new _definition.GraphQLList(innerType); } - Object.assign(this, rest); - if (response) { - Object.defineProperty(this, 'response', { - value: response, - }); + + case _kinds.Kind.NON_NULL_TYPE: { + const innerType = typeFromAST(schema, typeNode.type); + return innerType && new _definition.GraphQLNonNull(innerType); } + + case _kinds.Kind.NAMED_TYPE: + return schema.getType(typeNode.name.value); } } -makeError(RPError); - -module.exports = { - OPError, - RPError, -}; - /***/ }), -/***/ 63217: -/***/ ((module) => { - -function assertSigningAlgValuesSupport(endpoint, issuer, properties) { - if (!issuer[`${endpoint}_endpoint`]) return; - - const eam = `${endpoint}_endpoint_auth_method`; - const easa = `${endpoint}_endpoint_auth_signing_alg`; - const easavs = `${endpoint}_endpoint_auth_signing_alg_values_supported`; - - if (properties[eam] && properties[eam].endsWith('_jwt') && !properties[easa] && !issuer[easavs]) { - throw new TypeError(`${easavs} must be configured on the issuer if ${easa} is not defined on a client`); - } -} - -function assertIssuerConfiguration(issuer, endpoint) { - if (!issuer[endpoint]) { - throw new TypeError(`${endpoint} must be configured on the issuer`); - } -} +/***/ 83181: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -module.exports = { - assertSigningAlgValuesSupport, - assertIssuerConfiguration, -}; +"use strict"; -/***/ }), +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.valueFromAST = valueFromAST; -/***/ 61827: -/***/ ((module) => { +var _inspect = __nccwpck_require__(10102); -let encode; -if (Buffer.isEncoding('base64url')) { - encode = (input, encoding = 'utf8') => Buffer.from(input, encoding).toString('base64url'); -} else { - const fromBase64 = (base64) => base64.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); - encode = (input, encoding = 'utf8') => fromBase64(Buffer.from(input, encoding).toString('base64')); -} +var _invariant = __nccwpck_require__(28847); -const decode = (input) => Buffer.from(input, 'base64'); +var _keyMap = __nccwpck_require__(10711); -module.exports.decode = decode; -module.exports.encode = encode; +var _kinds = __nccwpck_require__(11927); +var _definition = __nccwpck_require__(5821); -/***/ }), +/** + * Produces a JavaScript value given a GraphQL Value AST. + * + * A GraphQL type must be provided, which will be used to interpret different + * GraphQL Value literals. + * + * Returns `undefined` when the value could not be validly coerced according to + * the provided type. + * + * | GraphQL Value | JSON Value | + * | -------------------- | ------------- | + * | Input Object | Object | + * | List | Array | + * | Boolean | Boolean | + * | String | String | + * | Int / Float | Number | + * | Enum Value | Unknown | + * | NullValue | null | + * + */ +function valueFromAST(valueNode, type, variables) { + if (!valueNode) { + // When there is no node, then there is also no value. + // Importantly, this is different from returning the value null. + return; + } -/***/ 7619: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (valueNode.kind === _kinds.Kind.VARIABLE) { + const variableName = valueNode.name.value; -const jose = __nccwpck_require__(16425); + if (variables == null || variables[variableName] === undefined) { + // No valid return value. + return; + } -const { assertIssuerConfiguration } = __nccwpck_require__(63217); -const { random } = __nccwpck_require__(75421); -const now = __nccwpck_require__(8542); -const request = __nccwpck_require__(92946); -const instance = __nccwpck_require__(27702); -const merge = __nccwpck_require__(2494); + const variableValue = variables[variableName]; -const formUrlEncode = (value) => encodeURIComponent(value).replace(/%20/g, '+'); + if (variableValue === null && (0, _definition.isNonNullType)(type)) { + return; // Invalid: intentionally return no value. + } // Note: This does no further checking that this variable is correct. + // This assumes that this query has been validated and the variable + // usage here is of the correct type. -async function clientAssertion(endpoint, payload) { - let alg = this[`${endpoint}_endpoint_auth_signing_alg`]; - if (!alg) { - assertIssuerConfiguration(this.issuer, `${endpoint}_endpoint_auth_signing_alg_values_supported`); + return variableValue; } - if (this[`${endpoint}_endpoint_auth_method`] === 'client_secret_jwt') { - const key = await this.joseSecret(); - - if (!alg) { - const supported = this.issuer[`${endpoint}_endpoint_auth_signing_alg_values_supported`]; - alg = Array.isArray(supported) && supported.find((signAlg) => key.algorithms('sign').has(signAlg)); + if ((0, _definition.isNonNullType)(type)) { + if (valueNode.kind === _kinds.Kind.NULL) { + return; // Invalid: intentionally return no value. } - return jose.JWS.sign(payload, key, { alg, typ: 'JWT' }); + return valueFromAST(valueNode, type.ofType, variables); } - const keystore = instance(this).get('keystore'); - - if (!keystore) { - throw new TypeError('no client jwks provided for signing a client assertion with'); + if (valueNode.kind === _kinds.Kind.NULL) { + // This is explicitly returning the value null. + return null; } - if (!alg) { - const algs = new Set(); + if ((0, _definition.isListType)(type)) { + const itemType = type.ofType; - keystore.all().forEach((key) => { - key.algorithms('sign').forEach(Set.prototype.add.bind(algs)); - }); + if (valueNode.kind === _kinds.Kind.LIST) { + const coercedValues = []; - const supported = this.issuer[`${endpoint}_endpoint_auth_signing_alg_values_supported`]; - alg = Array.isArray(supported) && supported.find((signAlg) => algs.has(signAlg)); - } + for (const itemNode of valueNode.values) { + if (isMissingVariable(itemNode, variables)) { + // If an array contains a missing variable, it is either coerced to + // null or if the item type is non-null, it considered invalid. + if ((0, _definition.isNonNullType)(itemType)) { + return; // Invalid: intentionally return no value. + } - const key = keystore.get({ alg, use: 'sig' }); - if (!key) { - throw new TypeError(`no key found in client jwks to sign a client assertion with using alg ${alg}`); - } - return jose.JWS.sign(payload, key, { alg, typ: 'JWT', kid: key.kid.startsWith('DONOTUSE.') ? undefined : key.kid }); -} + coercedValues.push(null); + } else { + const itemValue = valueFromAST(itemNode, itemType, variables); + + if (itemValue === undefined) { + return; // Invalid: intentionally return no value. + } -async function authFor(endpoint, { clientAssertionPayload } = {}) { - const authMethod = this[`${endpoint}_endpoint_auth_method`]; - switch (authMethod) { - case 'self_signed_tls_client_auth': - case 'tls_client_auth': - case 'none': - return { form: { client_id: this.client_id } }; - case 'client_secret_post': - if (!this.client_secret) { - throw new TypeError('client_secret_post client authentication method requires a client_secret'); + coercedValues.push(itemValue); + } } - return { form: { client_id: this.client_id, client_secret: this.client_secret } }; - case 'private_key_jwt': - case 'client_secret_jwt': { - const timestamp = now(); - - const mTLS = endpoint === 'token' && this.tls_client_certificate_bound_access_tokens; - const audience = [...new Set([ - this.issuer.issuer, - this.issuer.token_endpoint, - this.issuer[`${endpoint}_endpoint`], - mTLS && this.issuer.mtls_endpoint_aliases - ? this.issuer.mtls_endpoint_aliases.token_endpoint : undefined, - ].filter(Boolean))]; - - const assertion = await clientAssertion.call(this, endpoint, { - iat: timestamp, - exp: timestamp + 60, - jti: random(), - iss: this.client_id, - sub: this.client_id, - aud: audience, - ...clientAssertionPayload, - }); - return { - form: { - client_id: this.client_id, - client_assertion: assertion, - client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer', - }, - }; + return coercedValues; } - default: { // client_secret_basic - // This is correct behaviour, see https://tools.ietf.org/html/rfc6749#section-2.3.1 and the - // related appendix. (also https://github.com/panva/node-openid-client/pull/91) - // > The client identifier is encoded using the - // > "application/x-www-form-urlencoded" encoding algorithm per - // > Appendix B, and the encoded value is used as the username; the client - // > password is encoded using the same algorithm and used as the - // > password. - if (!this.client_secret) { - throw new TypeError('client_secret_basic client authentication method requires a client_secret'); - } - const encoded = `${formUrlEncode(this.client_id)}:${formUrlEncode(this.client_secret)}`; - const value = Buffer.from(encoded).toString('base64'); - return { headers: { Authorization: `Basic ${value}` } }; + + const coercedValue = valueFromAST(valueNode, itemType, variables); + + if (coercedValue === undefined) { + return; // Invalid: intentionally return no value. } + + return [coercedValue]; } -} -function resolveResponseType() { - const { length, 0: value } = this.response_types; + if ((0, _definition.isInputObjectType)(type)) { + if (valueNode.kind !== _kinds.Kind.OBJECT) { + return; // Invalid: intentionally return no value. + } - if (length === 1) { - return value; - } + const coercedObj = Object.create(null); + const fieldNodes = (0, _keyMap.keyMap)( + valueNode.fields, + (field) => field.name.value, + ); - return undefined; -} + for (const field of Object.values(type.getFields())) { + const fieldNode = fieldNodes[field.name]; -function resolveRedirectUri() { - const { length, 0: value } = this.redirect_uris || []; + if (!fieldNode || isMissingVariable(fieldNode.value, variables)) { + if (field.defaultValue !== undefined) { + coercedObj[field.name] = field.defaultValue; + } else if ((0, _definition.isNonNullType)(field.type)) { + return; // Invalid: intentionally return no value. + } - if (length === 1) { - return value; - } + continue; + } - return undefined; -} + const fieldValue = valueFromAST(fieldNode.value, field.type, variables); -async function authenticatedPost(endpoint, opts, { - clientAssertionPayload, endpointAuthMethod = endpoint, DPoP, -} = {}) { - const auth = await authFor.call(this, endpointAuthMethod, { clientAssertionPayload }); - const requestOpts = merge(opts, auth); + if (fieldValue === undefined) { + return; // Invalid: intentionally return no value. + } - const mTLS = this[`${endpointAuthMethod}_endpoint_auth_method`].includes('tls_client_auth') - || (endpoint === 'token' && this.tls_client_certificate_bound_access_tokens); + coercedObj[field.name] = fieldValue; + } - let targetUrl; - if (mTLS && this.issuer.mtls_endpoint_aliases) { - targetUrl = this.issuer.mtls_endpoint_aliases[`${endpoint}_endpoint`]; - } + if (type.isOneOf) { + const keys = Object.keys(coercedObj); - targetUrl = targetUrl || this.issuer[`${endpoint}_endpoint`]; + if (keys.length !== 1) { + return; // Invalid: not exactly one key, intentionally return no value. + } - if ('form' in requestOpts) { - for (const [key, value] of Object.entries(requestOpts.form)) { // eslint-disable-line no-restricted-syntax, max-len - if (typeof value === 'undefined') { - delete requestOpts.form[key]; + if (coercedObj[keys[0]] === null) { + return; // Invalid: value not non-null, intentionally return no value. } } - } - - return request.call(this, { - ...requestOpts, - method: 'POST', - url: targetUrl, - }, { mTLS, DPoP }); -} -module.exports = { - resolveResponseType, - resolveRedirectUri, - authFor, - authenticatedPost, -}; + return coercedObj; + } + if ((0, _definition.isLeafType)(type)) { + // Scalars and Enums fulfill parsing a literal value via parseLiteral(). + // Invalid values represent a failure to parse correctly, in which case + // no value is returned. + let result; -/***/ }), + try { + result = type.parseLiteral(valueNode, variables); + } catch (_error) { + return; // Invalid: intentionally return no value. + } -/***/ 27556: -/***/ ((module) => { + if (result === undefined) { + return; // Invalid: intentionally return no value. + } -const OIDC_DISCOVERY = '/.well-known/openid-configuration'; -const OAUTH2_DISCOVERY = '/.well-known/oauth-authorization-server'; -const WEBFINGER = '/.well-known/webfinger'; -const REL = 'http://openid.net/specs/connect/1.0/issuer'; -const AAD_MULTITENANT_DISCOVERY = [ - `https://login.microsoftonline.com/common${OIDC_DISCOVERY}`, - `https://login.microsoftonline.com/common/v2.0${OIDC_DISCOVERY}`, - `https://login.microsoftonline.com/organizations/v2.0${OIDC_DISCOVERY}`, - `https://login.microsoftonline.com/consumers/v2.0${OIDC_DISCOVERY}`, -]; + return result; + } + /* c8 ignore next 3 */ + // Not reachable, all possible input types have been considered. -const CLIENT_DEFAULTS = { - grant_types: ['authorization_code'], - id_token_signed_response_alg: 'RS256', - authorization_signed_response_alg: 'RS256', - response_types: ['code'], - token_endpoint_auth_method: 'client_secret_basic', -}; + false || + (0, _invariant.invariant)( + false, + 'Unexpected input type: ' + (0, _inspect.inspect)(type), + ); +} // Returns true if the provided valueNode is a variable which is not defined +// in the set of variables. -const ISSUER_DEFAULTS = { - claim_types_supported: ['normal'], - claims_parameter_supported: false, - grant_types_supported: ['authorization_code', 'implicit'], - request_parameter_supported: false, - request_uri_parameter_supported: true, - require_request_uri_registration: false, - response_modes_supported: ['query', 'fragment'], - token_endpoint_auth_methods_supported: ['client_secret_basic'], -}; +function isMissingVariable(valueNode, variables) { + return ( + valueNode.kind === _kinds.Kind.VARIABLE && + (variables == null || variables[valueNode.name.value] === undefined) + ); +} -const CALLBACK_PROPERTIES = [ - 'access_token', // 6749 - 'code', // 6749 - 'error', // 6749 - 'error_description', // 6749 - 'error_uri', // 6749 - 'expires_in', // 6749 - 'id_token', // Core 1.0 - 'state', // 6749 - 'token_type', // 6749 - 'session_state', // Session Management - 'response', // JARM -]; -const JWT_CONTENT = /^application\/jwt/; +/***/ }), -const HTTP_OPTIONS = Symbol('openid-client.custom.http-options'); -const CLOCK_TOLERANCE = Symbol('openid-client.custom.clock-tolerance'); +/***/ 86699: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -module.exports = { - AAD_MULTITENANT_DISCOVERY, - CALLBACK_PROPERTIES, - CLIENT_DEFAULTS, - CLOCK_TOLERANCE, - HTTP_OPTIONS, - ISSUER_DEFAULTS, - JWT_CONTENT, - OAUTH2_DISCOVERY, - OIDC_DISCOVERY, - REL, - WEBFINGER, -}; +"use strict"; -/***/ }), +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.valueFromASTUntyped = valueFromASTUntyped; -/***/ 21004: -/***/ ((module) => { +var _keyValMap = __nccwpck_require__(49268); -module.exports = (obj) => JSON.parse(JSON.stringify(obj)); +var _kinds = __nccwpck_require__(11927); +/** + * Produces a JavaScript value given a GraphQL Value AST. + * + * Unlike `valueFromAST()`, no type is provided. The resulting JavaScript value + * will reflect the provided GraphQL value AST. + * + * | GraphQL Value | JavaScript Value | + * | -------------------- | ---------------- | + * | Input Object | Object | + * | List | Array | + * | Boolean | Boolean | + * | String / Enum | String | + * | Int / Float | Number | + * | Null | null | + * + */ +function valueFromASTUntyped(valueNode, variables) { + switch (valueNode.kind) { + case _kinds.Kind.NULL: + return null; -/***/ }), + case _kinds.Kind.INT: + return parseInt(valueNode.value, 10); -/***/ 13098: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + case _kinds.Kind.FLOAT: + return parseFloat(valueNode.value); -/* eslint-disable no-restricted-syntax, no-continue */ + case _kinds.Kind.STRING: + case _kinds.Kind.ENUM: + case _kinds.Kind.BOOLEAN: + return valueNode.value; -const isPlainObject = __nccwpck_require__(39862); + case _kinds.Kind.LIST: + return valueNode.values.map((node) => + valueFromASTUntyped(node, variables), + ); -function defaults(deep, target, ...sources) { - for (const source of sources) { - if (!isPlainObject(source)) { - continue; - } - for (const [key, value] of Object.entries(source)) { - /* istanbul ignore if */ - if (key === '__proto__' || key === 'constructor') { - continue; - } - if (typeof target[key] === 'undefined' && typeof value !== 'undefined') { - target[key] = value; - } + case _kinds.Kind.OBJECT: + return (0, _keyValMap.keyValMap)( + valueNode.fields, + (field) => field.name.value, + (field) => valueFromASTUntyped(field.value, variables), + ); - if (deep && isPlainObject(target[key]) && isPlainObject(value)) { - defaults(true, target[key], value); - } - } + case _kinds.Kind.VARIABLE: + return variables === null || variables === void 0 + ? void 0 + : variables[valueNode.name.value]; } - - return target; } -module.exports = defaults.bind(undefined, false); -module.exports.deep = defaults.bind(undefined, true); - /***/ }), -/***/ 75421: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const { createHash, randomBytes } = __nccwpck_require__(6113); - -const base64url = __nccwpck_require__(61827); +/***/ 28263: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -const random = (bytes = 32) => base64url.encode(randomBytes(bytes)); +"use strict"; -module.exports = { - random, - state: random, - nonce: random, - codeVerifier: random, - codeChallenge: (codeVerifier) => base64url.encode(createHash('sha256').update(codeVerifier).digest()), -}; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.ValidationContext = + exports.SDLValidationContext = + exports.ASTValidationContext = + void 0; -/***/ }), +var _kinds = __nccwpck_require__(11927); -/***/ 61797: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var _visitor = __nccwpck_require__(5678); -const url = __nccwpck_require__(57310); -const { strict: assert } = __nccwpck_require__(39491); +var _TypeInfo = __nccwpck_require__(76625); -module.exports = (target) => { - try { - const { protocol } = new url.URL(target); - assert(protocol.match(/^(https?:)$/)); - return true; - } catch (err) { - throw new TypeError('only valid absolute URLs can be requested'); +/** + * An instance of this class is passed as the "this" context to all validators, + * allowing access to commonly useful contextual information from within a + * validation rule. + */ +class ASTValidationContext { + constructor(ast, onError) { + this._ast = ast; + this._fragments = undefined; + this._fragmentSpreads = new Map(); + this._recursivelyReferencedFragments = new Map(); + this._onError = onError; } -}; - - -/***/ }), - -/***/ 39862: -/***/ ((module) => { - -module.exports = (a) => !!a && a.constructor === Object; + get [Symbol.toStringTag]() { + return 'ASTValidationContext'; + } -/***/ }), + reportError(error) { + this._onError(error); + } -/***/ 2494: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + getDocument() { + return this._ast; + } -/* eslint-disable no-restricted-syntax, no-param-reassign, no-continue */ + getFragment(name) { + let fragments; -const isPlainObject = __nccwpck_require__(39862); + if (this._fragments) { + fragments = this._fragments; + } else { + fragments = Object.create(null); -function merge(target, ...sources) { - for (const source of sources) { - if (!isPlainObject(source)) { - continue; - } - for (const [key, value] of Object.entries(source)) { - /* istanbul ignore if */ - if (key === '__proto__' || key === 'constructor') { - continue; - } - if (isPlainObject(target[key]) && isPlainObject(value)) { - target[key] = merge(target[key], value); - } else if (typeof value !== 'undefined') { - target[key] = value; + for (const defNode of this.getDocument().definitions) { + if (defNode.kind === _kinds.Kind.FRAGMENT_DEFINITION) { + fragments[defNode.name.value] = defNode; + } } - } - } - return target; -} + this._fragments = fragments; + } -module.exports = merge; + return fragments[name]; + } + getFragmentSpreads(node) { + let spreads = this._fragmentSpreads.get(node); -/***/ }), + if (!spreads) { + spreads = []; + const setsToVisit = [node]; + let set; -/***/ 78857: -/***/ ((module) => { + while ((set = setsToVisit.pop())) { + for (const selection of set.selections) { + if (selection.kind === _kinds.Kind.FRAGMENT_SPREAD) { + spreads.push(selection); + } else if (selection.selectionSet) { + setsToVisit.push(selection.selectionSet); + } + } + } -module.exports = function pick(object, ...paths) { - const obj = {}; - for (const path of paths) { // eslint-disable-line no-restricted-syntax - if (object[path]) { - obj[path] = object[path]; + this._fragmentSpreads.set(node, spreads); } - } - return obj; -}; + return spreads; + } -/***/ }), + getRecursivelyReferencedFragments(operation) { + let fragments = this._recursivelyReferencedFragments.get(operation); -/***/ 28576: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!fragments) { + fragments = []; + const collectedNames = Object.create(null); + const nodesToVisit = [operation.selectionSet]; + let node; -const { STATUS_CODES } = __nccwpck_require__(13685); -const { format } = __nccwpck_require__(73837); + while ((node = nodesToVisit.pop())) { + for (const spread of this.getFragmentSpreads(node)) { + const fragName = spread.name.value; -const { OPError } = __nccwpck_require__(45061); + if (collectedNames[fragName] !== true) { + collectedNames[fragName] = true; + const fragment = this.getFragment(fragName); -const REGEXP = /(\w+)=("[^"]*")/g; -const throwAuthenticateErrors = (response) => { - const params = {}; - try { - while ((REGEXP.exec(response.headers['www-authenticate'])) !== null) { - if (RegExp.$1 && RegExp.$2) { - params[RegExp.$1] = RegExp.$2.slice(1, -1); + if (fragment) { + fragments.push(fragment); + nodesToVisit.push(fragment.selectionSet); + } + } + } } - } - } catch (err) {} - - if (params.error) { - throw new OPError(params, response); - } -}; -const isStandardBodyError = (response) => { - let result = false; - try { - let jsonbody; - if (typeof response.body !== 'object' || Buffer.isBuffer(response.body)) { - jsonbody = JSON.parse(response.body); - } else { - jsonbody = response.body; + this._recursivelyReferencedFragments.set(operation, fragments); } - result = typeof jsonbody.error === 'string' && jsonbody.error.length; - if (result) response.body = jsonbody; - } catch (err) {} - return result; -}; - -function processResponse(response, { statusCode = 200, body = true, bearer = false } = {}) { - if (response.statusCode !== statusCode) { - if (bearer) { - throwAuthenticateErrors(response); - } + return fragments; + } +} - if (isStandardBodyError(response)) { - throw new OPError(response.body, response); - } +exports.ASTValidationContext = ASTValidationContext; - throw new OPError({ - error: format('expected %i %s, got: %i %s', statusCode, STATUS_CODES[statusCode], response.statusCode, STATUS_CODES[response.statusCode]), - }, response); +class SDLValidationContext extends ASTValidationContext { + constructor(ast, schema, onError) { + super(ast, onError); + this._schema = schema; } - if (body && !response.body) { - throw new OPError({ - error: format('expected %i %s with body but no body was returned', statusCode, STATUS_CODES[statusCode]), - }, response); + get [Symbol.toStringTag]() { + return 'SDLValidationContext'; } - return response.body; + getSchema() { + return this._schema; + } } -module.exports = processResponse; - - -/***/ }), - -/***/ 92946: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +exports.SDLValidationContext = SDLValidationContext; -const Got = __nccwpck_require__(93061); +class ValidationContext extends ASTValidationContext { + constructor(schema, ast, typeInfo, onError) { + super(ast, onError); + this._schema = schema; + this._typeInfo = typeInfo; + this._variableUsages = new Map(); + this._recursiveVariableUsages = new Map(); + } -const pkg = __nccwpck_require__(82696); + get [Symbol.toStringTag]() { + return 'ValidationContext'; + } -const { deep: defaultsDeep } = __nccwpck_require__(13098); -const isAbsoluteUrl = __nccwpck_require__(61797); -const { HTTP_OPTIONS } = __nccwpck_require__(27556); + getSchema() { + return this._schema; + } -let DEFAULT_HTTP_OPTIONS; -let got; + getVariableUsages(node) { + let usages = this._variableUsages.get(node); -const setDefaults = (options) => { - DEFAULT_HTTP_OPTIONS = defaultsDeep({}, options, DEFAULT_HTTP_OPTIONS); - got = Got.extend(DEFAULT_HTTP_OPTIONS); -}; + if (!usages) { + const newUsages = []; + const typeInfo = new _TypeInfo.TypeInfo(this._schema); + (0, _visitor.visit)( + node, + (0, _TypeInfo.visitWithTypeInfo)(typeInfo, { + VariableDefinition: () => false, -setDefaults({ - followRedirect: false, - headers: { 'User-Agent': `${pkg.name}/${pkg.version} (${pkg.homepage})` }, - retry: 0, - timeout: 3500, - throwHttpErrors: false, -}); + Variable(variable) { + newUsages.push({ + node: variable, + type: typeInfo.getInputType(), + defaultValue: typeInfo.getDefaultValue(), + parentType: typeInfo.getParentInputType(), + }); + }, + }), + ); + usages = newUsages; -module.exports = async function request(options, { accessToken, mTLS = false, DPoP } = {}) { - const { url } = options; - isAbsoluteUrl(url); - const optsFn = this[HTTP_OPTIONS]; - let opts = options; + this._variableUsages.set(node, usages); + } - if (DPoP && 'dpopProof' in this) { - opts.headers = opts.headers || {}; - opts.headers.DPoP = this.dpopProof({ - htu: url, - htm: options.method, - }, DPoP, accessToken); + return usages; } - if (optsFn) { - opts = optsFn.call(this, defaultsDeep({}, opts, DEFAULT_HTTP_OPTIONS)); - } + getRecursiveVariableUsages(operation) { + let usages = this._recursiveVariableUsages.get(operation); - if ( - mTLS - && ( - (!opts.key || !opts.cert) - && (!opts.https || !((opts.https.key && opts.https.certificate) || opts.https.pfx)) - ) - ) { - throw new TypeError('mutual-TLS certificate and key not set'); - } + if (!usages) { + usages = this.getVariableUsages(operation); - return got(opts); -}; + for (const frag of this.getRecursivelyReferencedFragments(operation)) { + usages = usages.concat(this.getVariableUsages(frag)); + } -module.exports.setDefaults = setDefaults; + this._recursiveVariableUsages.set(operation, usages); + } + return usages; + } -/***/ }), + getType() { + return this._typeInfo.getType(); + } -/***/ 8542: -/***/ ((module) => { + getParentType() { + return this._typeInfo.getParentType(); + } -module.exports = () => Math.floor(Date.now() / 1000); + getInputType() { + return this._typeInfo.getInputType(); + } + getParentInputType() { + return this._typeInfo.getParentInputType(); + } -/***/ }), + getFieldDef() { + return this._typeInfo.getFieldDef(); + } -/***/ 27702: -/***/ ((module) => { + getDirective() { + return this._typeInfo.getDirective(); + } -const privateProps = new WeakMap(); + getArgument() { + return this._typeInfo.getArgument(); + } -module.exports = (ctx) => { - if (!privateProps.has(ctx)) { - privateProps.set(ctx, new Map([['metadata', new Map()]])); + getEnumValue() { + return this._typeInfo.getEnumValue(); } - return privateProps.get(ctx); -}; +} +exports.ValidationContext = ValidationContext; -/***/ }), -/***/ 27416: -/***/ ((module) => { +/***/ }), -// Credit: https://github.com/rohe/pyoidc/blob/master/src/oic/utils/webfinger.py +/***/ 82201: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -// -- Normalization -- -// A string of any other type is interpreted as a URI either the form of scheme -// "://" authority path-abempty [ "?" query ] [ "#" fragment ] or authority -// path-abempty [ "?" query ] [ "#" fragment ] per RFC 3986 [RFC3986] and is -// normalized according to the following rules: -// -// If the user input Identifier does not have an RFC 3986 [RFC3986] scheme -// portion, the string is interpreted as [userinfo "@"] host [":" port] -// path-abempty [ "?" query ] [ "#" fragment ] per RFC 3986 [RFC3986]. -// If the userinfo component is present and all of the path component, query -// component, and port component are empty, the acct scheme is assumed. In this -// case, the normalized URI is formed by prefixing acct: to the string as the -// scheme. Per the 'acct' URI Scheme [I‑D.ietf‑appsawg‑acct‑uri], if there is an -// at-sign character ('@') in the userinfo component, it needs to be -// percent-encoded as described in RFC 3986 [RFC3986]. -// For all other inputs without a scheme portion, the https scheme is assumed, -// and the normalized URI is formed by prefixing https:// to the string as the -// scheme. -// If the resulting URI contains a fragment portion, it MUST be stripped off -// together with the fragment delimiter character "#". -// The WebFinger [I‑D.ietf‑appsawg‑webfinger] Resource in this case is the -// resulting URI, and the WebFinger Host is the authority component. -// -// Note: Since the definition of authority in RFC 3986 [RFC3986] is -// [ userinfo "@" ] host [ ":" port ], it is legal to have a user input -// identifier like userinfo@host:port, e.g., alice@example.com:8080. +"use strict"; -const PORT = /^\d+$/; -function hasScheme(input) { - if (input.includes('://')) return true; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +Object.defineProperty(exports, "ExecutableDefinitionsRule", ({ + enumerable: true, + get: function () { + return _ExecutableDefinitionsRule.ExecutableDefinitionsRule; + }, +})); +Object.defineProperty(exports, "FieldsOnCorrectTypeRule", ({ + enumerable: true, + get: function () { + return _FieldsOnCorrectTypeRule.FieldsOnCorrectTypeRule; + }, +})); +Object.defineProperty(exports, "FragmentsOnCompositeTypesRule", ({ + enumerable: true, + get: function () { + return _FragmentsOnCompositeTypesRule.FragmentsOnCompositeTypesRule; + }, +})); +Object.defineProperty(exports, "KnownArgumentNamesRule", ({ + enumerable: true, + get: function () { + return _KnownArgumentNamesRule.KnownArgumentNamesRule; + }, +})); +Object.defineProperty(exports, "KnownDirectivesRule", ({ + enumerable: true, + get: function () { + return _KnownDirectivesRule.KnownDirectivesRule; + }, +})); +Object.defineProperty(exports, "KnownFragmentNamesRule", ({ + enumerable: true, + get: function () { + return _KnownFragmentNamesRule.KnownFragmentNamesRule; + }, +})); +Object.defineProperty(exports, "KnownTypeNamesRule", ({ + enumerable: true, + get: function () { + return _KnownTypeNamesRule.KnownTypeNamesRule; + }, +})); +Object.defineProperty(exports, "LoneAnonymousOperationRule", ({ + enumerable: true, + get: function () { + return _LoneAnonymousOperationRule.LoneAnonymousOperationRule; + }, +})); +Object.defineProperty(exports, "LoneSchemaDefinitionRule", ({ + enumerable: true, + get: function () { + return _LoneSchemaDefinitionRule.LoneSchemaDefinitionRule; + }, +})); +Object.defineProperty(exports, "MaxIntrospectionDepthRule", ({ + enumerable: true, + get: function () { + return _MaxIntrospectionDepthRule.MaxIntrospectionDepthRule; + }, +})); +Object.defineProperty(exports, "NoDeprecatedCustomRule", ({ + enumerable: true, + get: function () { + return _NoDeprecatedCustomRule.NoDeprecatedCustomRule; + }, +})); +Object.defineProperty(exports, "NoFragmentCyclesRule", ({ + enumerable: true, + get: function () { + return _NoFragmentCyclesRule.NoFragmentCyclesRule; + }, +})); +Object.defineProperty(exports, "NoSchemaIntrospectionCustomRule", ({ + enumerable: true, + get: function () { + return _NoSchemaIntrospectionCustomRule.NoSchemaIntrospectionCustomRule; + }, +})); +Object.defineProperty(exports, "NoUndefinedVariablesRule", ({ + enumerable: true, + get: function () { + return _NoUndefinedVariablesRule.NoUndefinedVariablesRule; + }, +})); +Object.defineProperty(exports, "NoUnusedFragmentsRule", ({ + enumerable: true, + get: function () { + return _NoUnusedFragmentsRule.NoUnusedFragmentsRule; + }, +})); +Object.defineProperty(exports, "NoUnusedVariablesRule", ({ + enumerable: true, + get: function () { + return _NoUnusedVariablesRule.NoUnusedVariablesRule; + }, +})); +Object.defineProperty(exports, "OverlappingFieldsCanBeMergedRule", ({ + enumerable: true, + get: function () { + return _OverlappingFieldsCanBeMergedRule.OverlappingFieldsCanBeMergedRule; + }, +})); +Object.defineProperty(exports, "PossibleFragmentSpreadsRule", ({ + enumerable: true, + get: function () { + return _PossibleFragmentSpreadsRule.PossibleFragmentSpreadsRule; + }, +})); +Object.defineProperty(exports, "PossibleTypeExtensionsRule", ({ + enumerable: true, + get: function () { + return _PossibleTypeExtensionsRule.PossibleTypeExtensionsRule; + }, +})); +Object.defineProperty(exports, "ProvidedRequiredArgumentsRule", ({ + enumerable: true, + get: function () { + return _ProvidedRequiredArgumentsRule.ProvidedRequiredArgumentsRule; + }, +})); +Object.defineProperty(exports, "ScalarLeafsRule", ({ + enumerable: true, + get: function () { + return _ScalarLeafsRule.ScalarLeafsRule; + }, +})); +Object.defineProperty(exports, "SingleFieldSubscriptionsRule", ({ + enumerable: true, + get: function () { + return _SingleFieldSubscriptionsRule.SingleFieldSubscriptionsRule; + }, +})); +Object.defineProperty(exports, "UniqueArgumentDefinitionNamesRule", ({ + enumerable: true, + get: function () { + return _UniqueArgumentDefinitionNamesRule.UniqueArgumentDefinitionNamesRule; + }, +})); +Object.defineProperty(exports, "UniqueArgumentNamesRule", ({ + enumerable: true, + get: function () { + return _UniqueArgumentNamesRule.UniqueArgumentNamesRule; + }, +})); +Object.defineProperty(exports, "UniqueDirectiveNamesRule", ({ + enumerable: true, + get: function () { + return _UniqueDirectiveNamesRule.UniqueDirectiveNamesRule; + }, +})); +Object.defineProperty(exports, "UniqueDirectivesPerLocationRule", ({ + enumerable: true, + get: function () { + return _UniqueDirectivesPerLocationRule.UniqueDirectivesPerLocationRule; + }, +})); +Object.defineProperty(exports, "UniqueEnumValueNamesRule", ({ + enumerable: true, + get: function () { + return _UniqueEnumValueNamesRule.UniqueEnumValueNamesRule; + }, +})); +Object.defineProperty(exports, "UniqueFieldDefinitionNamesRule", ({ + enumerable: true, + get: function () { + return _UniqueFieldDefinitionNamesRule.UniqueFieldDefinitionNamesRule; + }, +})); +Object.defineProperty(exports, "UniqueFragmentNamesRule", ({ + enumerable: true, + get: function () { + return _UniqueFragmentNamesRule.UniqueFragmentNamesRule; + }, +})); +Object.defineProperty(exports, "UniqueInputFieldNamesRule", ({ + enumerable: true, + get: function () { + return _UniqueInputFieldNamesRule.UniqueInputFieldNamesRule; + }, +})); +Object.defineProperty(exports, "UniqueOperationNamesRule", ({ + enumerable: true, + get: function () { + return _UniqueOperationNamesRule.UniqueOperationNamesRule; + }, +})); +Object.defineProperty(exports, "UniqueOperationTypesRule", ({ + enumerable: true, + get: function () { + return _UniqueOperationTypesRule.UniqueOperationTypesRule; + }, +})); +Object.defineProperty(exports, "UniqueTypeNamesRule", ({ + enumerable: true, + get: function () { + return _UniqueTypeNamesRule.UniqueTypeNamesRule; + }, +})); +Object.defineProperty(exports, "UniqueVariableNamesRule", ({ + enumerable: true, + get: function () { + return _UniqueVariableNamesRule.UniqueVariableNamesRule; + }, +})); +Object.defineProperty(exports, "ValidationContext", ({ + enumerable: true, + get: function () { + return _ValidationContext.ValidationContext; + }, +})); +Object.defineProperty(exports, "ValuesOfCorrectTypeRule", ({ + enumerable: true, + get: function () { + return _ValuesOfCorrectTypeRule.ValuesOfCorrectTypeRule; + }, +})); +Object.defineProperty(exports, "VariablesAreInputTypesRule", ({ + enumerable: true, + get: function () { + return _VariablesAreInputTypesRule.VariablesAreInputTypesRule; + }, +})); +Object.defineProperty(exports, "VariablesInAllowedPositionRule", ({ + enumerable: true, + get: function () { + return _VariablesInAllowedPositionRule.VariablesInAllowedPositionRule; + }, +})); +Object.defineProperty(exports, "recommendedRules", ({ + enumerable: true, + get: function () { + return _specifiedRules.recommendedRules; + }, +})); +Object.defineProperty(exports, "specifiedRules", ({ + enumerable: true, + get: function () { + return _specifiedRules.specifiedRules; + }, +})); +Object.defineProperty(exports, "validate", ({ + enumerable: true, + get: function () { + return _validate.validate; + }, +})); - const authority = input.replace(/(\/|\?)/g, '#').split('#')[0]; - if (authority.includes(':')) { - const index = authority.indexOf(':'); - const hostOrPort = authority.slice(index + 1); - if (!PORT.test(hostOrPort)) { - return true; - } - } +var _validate = __nccwpck_require__(14193); - return false; -} +var _ValidationContext = __nccwpck_require__(28263); -function acctSchemeAssumed(input) { - if (!input.includes('@')) return false; - const parts = input.split('@'); - const host = parts[parts.length - 1]; - return !(host.includes(':') || host.includes('/') || host.includes('?')); -} +var _specifiedRules = __nccwpck_require__(84908); -function normalize(input) { - if (typeof input !== 'string') { - throw new TypeError('input must be a string'); - } +var _ExecutableDefinitionsRule = __nccwpck_require__(89199); - let output; - if (hasScheme(input)) { - output = input; - } else if (acctSchemeAssumed(input)) { - output = `acct:${input}`; - } else { - output = `https://${input}`; - } +var _FieldsOnCorrectTypeRule = __nccwpck_require__(63016); - return output.split('#')[0]; -} +var _FragmentsOnCompositeTypesRule = __nccwpck_require__(60381); -module.exports = normalize; +var _KnownArgumentNamesRule = __nccwpck_require__(67147); +var _KnownDirectivesRule = __nccwpck_require__(85303); -/***/ }), +var _KnownFragmentNamesRule = __nccwpck_require__(15166); -/***/ 53140: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var _KnownTypeNamesRule = __nccwpck_require__(42509); -const Issuer = __nccwpck_require__(27213); -const { OPError, RPError } = __nccwpck_require__(45061); -const Registry = __nccwpck_require__(30730); -const Strategy = __nccwpck_require__(22134); -const TokenSet = __nccwpck_require__(39029); -const { CLOCK_TOLERANCE, HTTP_OPTIONS } = __nccwpck_require__(27556); -const generators = __nccwpck_require__(75421); -const { setDefaults } = __nccwpck_require__(92946); +var _LoneAnonymousOperationRule = __nccwpck_require__(45726); -module.exports = { - Issuer, - Registry, - Strategy, - TokenSet, - errors: { - OPError, - RPError, - }, - custom: { - setHttpOptionsDefaults: setDefaults, - http_options: HTTP_OPTIONS, - clock_tolerance: CLOCK_TOLERANCE, - }, - generators, -}; +var _NoFragmentCyclesRule = __nccwpck_require__(62564); +var _NoUndefinedVariablesRule = __nccwpck_require__(61671); -/***/ }), +var _NoUnusedFragmentsRule = __nccwpck_require__(192); -/***/ 27213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var _NoUnusedVariablesRule = __nccwpck_require__(40242); -/* eslint-disable max-classes-per-file */ +var _OverlappingFieldsCanBeMergedRule = __nccwpck_require__(23577); -const { inspect } = __nccwpck_require__(73837); -const url = __nccwpck_require__(57310); +var _PossibleFragmentSpreadsRule = __nccwpck_require__(62450); -const AggregateError = __nccwpck_require__(61231); -const jose = __nccwpck_require__(16425); -const LRU = __nccwpck_require__(7129); -const objectHash = __nccwpck_require__(24856); +var _ProvidedRequiredArgumentsRule = __nccwpck_require__(57669); -const { RPError } = __nccwpck_require__(45061); -const getClient = __nccwpck_require__(28300); -const registry = __nccwpck_require__(30730); -const processResponse = __nccwpck_require__(28576); -const webfingerNormalize = __nccwpck_require__(27416); -const instance = __nccwpck_require__(27702); -const request = __nccwpck_require__(92946); -const { assertIssuerConfiguration } = __nccwpck_require__(63217); -const { - ISSUER_DEFAULTS, OIDC_DISCOVERY, OAUTH2_DISCOVERY, WEBFINGER, REL, AAD_MULTITENANT_DISCOVERY, -} = __nccwpck_require__(27556); +var _ScalarLeafsRule = __nccwpck_require__(16830); -const AAD_MULTITENANT = Symbol('AAD_MULTITENANT'); +var _SingleFieldSubscriptionsRule = __nccwpck_require__(4365); -class Issuer { - /** - * @name constructor - * @api public - */ - constructor(meta = {}) { - const aadIssValidation = meta[AAD_MULTITENANT]; - delete meta[AAD_MULTITENANT]; +var _UniqueArgumentNamesRule = __nccwpck_require__(45799); - ['introspection', 'revocation'].forEach((endpoint) => { - // if intro/revocation endpoint auth specific meta is missing use the token ones if they - // are defined - if ( - meta[`${endpoint}_endpoint`] - && meta[`${endpoint}_endpoint_auth_methods_supported`] === undefined - && meta[`${endpoint}_endpoint_auth_signing_alg_values_supported`] === undefined - ) { - if (meta.token_endpoint_auth_methods_supported) { - meta[`${endpoint}_endpoint_auth_methods_supported`] = meta.token_endpoint_auth_methods_supported; - } - if (meta.token_endpoint_auth_signing_alg_values_supported) { - meta[`${endpoint}_endpoint_auth_signing_alg_values_supported`] = meta.token_endpoint_auth_signing_alg_values_supported; - } - } - }); +var _UniqueDirectivesPerLocationRule = __nccwpck_require__(61944); - Object.entries(meta).forEach(([key, value]) => { - instance(this).get('metadata').set(key, value); - if (!this[key]) { - Object.defineProperty(this, key, { - get() { return instance(this).get('metadata').get(key); }, - enumerable: true, - }); - } - }); +var _UniqueFragmentNamesRule = __nccwpck_require__(79402); - instance(this).set('cache', new LRU({ max: 100 })); +var _UniqueInputFieldNamesRule = __nccwpck_require__(83552); - registry.set(this.issuer, this); +var _UniqueOperationNamesRule = __nccwpck_require__(94865); - const Client = getClient(this, aadIssValidation); +var _UniqueVariableNamesRule = __nccwpck_require__(65931); - Object.defineProperties(this, { - Client: { value: Client }, - FAPIClient: { value: class FAPIClient extends Client {} }, - }); - } +var _ValuesOfCorrectTypeRule = __nccwpck_require__(39091); - /** - * @name keystore - * @api public - */ - async keystore(reload = false) { - assertIssuerConfiguration(this, 'jwks_uri'); - - const keystore = instance(this).get('keystore'); - const cache = instance(this).get('cache'); - - if (reload || !keystore) { - cache.reset(); - const response = await request.call(this, { - method: 'GET', - responseType: 'json', - url: this.jwks_uri, - }); - const jwks = processResponse(response); +var _VariablesAreInputTypesRule = __nccwpck_require__(99506); - const joseKeyStore = jose.JWKS.asKeyStore(jwks, { ignoreErrors: true }); - cache.set('throttle', true, 60 * 1000); - instance(this).set('keystore', joseKeyStore); - return joseKeyStore; - } +var _VariablesInAllowedPositionRule = __nccwpck_require__(8815); - return keystore; - } +var _MaxIntrospectionDepthRule = __nccwpck_require__(53318); - /** - * @name queryKeyStore - * @api private - */ - async queryKeyStore({ - kid, kty, alg, use, key_ops: ops, - }, { allowMulti = false } = {}) { - const cache = instance(this).get('cache'); +var _LoneSchemaDefinitionRule = __nccwpck_require__(48307); - const def = { - kid, kty, alg, use, key_ops: ops, - }; +var _UniqueOperationTypesRule = __nccwpck_require__(31492); - const defHash = objectHash(def, { - algorithm: 'sha256', - ignoreUnknown: true, - unorderedArrays: true, - unorderedSets: true, - }); +var _UniqueTypeNamesRule = __nccwpck_require__(24316); - // refresh keystore on every unknown key but also only upto once every minute - const freshJwksUri = cache.get(defHash) || cache.get('throttle'); +var _UniqueEnumValueNamesRule = __nccwpck_require__(44437); - const keystore = await this.keystore(!freshJwksUri); - const keys = keystore.all(def); +var _UniqueFieldDefinitionNamesRule = __nccwpck_require__(9502); - if (keys.length === 0) { - throw new RPError({ - printf: ["no valid key found in issuer's jwks_uri for key parameters %j", def], - jwks: keystore, - }); - } +var _UniqueArgumentDefinitionNamesRule = __nccwpck_require__(55104); - if (!allowMulti && keys.length > 1 && !kid) { - throw new RPError({ - printf: ["multiple matching keys found in issuer's jwks_uri for key parameters %j, kid must be provided in this case", def], - jwks: keystore, - }); - } +var _UniqueDirectiveNamesRule = __nccwpck_require__(17074); - cache.set(defHash, true); +var _PossibleTypeExtensionsRule = __nccwpck_require__(70075); - return new jose.JWKS.KeyStore(keys); - } +var _NoDeprecatedCustomRule = __nccwpck_require__(33915); - /** - * @name metadata - * @api public - */ - get metadata() { - const copy = {}; - instance(this).get('metadata').forEach((value, key) => { - copy[key] = value; - }); - return copy; - } +var _NoSchemaIntrospectionCustomRule = __nccwpck_require__(39478); - /** - * @name webfinger - * @api public - */ - static async webfinger(input) { - const resource = webfingerNormalize(input); - const { host } = url.parse(resource); - const webfingerUrl = `https://${host}${WEBFINGER}`; - - const response = await request.call(this, { - method: 'GET', - url: webfingerUrl, - responseType: 'json', - searchParams: { resource, rel: REL }, - followRedirect: true, - }); - const body = processResponse(response); - const location = Array.isArray(body.links) && body.links.find((link) => typeof link === 'object' && link.rel === REL && link.href); +/***/ }), - if (!location) { - throw new RPError({ - message: 'no issuer found in webfinger response', - body, - }); - } +/***/ 89199: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (typeof location.href !== 'string' || !location.href.startsWith('https://')) { - throw new RPError({ - printf: ['invalid issuer location %s', location.href], - body, - }); - } +"use strict"; - const expectedIssuer = location.href; - if (registry.has(expectedIssuer)) { - return registry.get(expectedIssuer); - } - const issuer = await this.discover(expectedIssuer); +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.ExecutableDefinitionsRule = ExecutableDefinitionsRule; - if (issuer.issuer !== expectedIssuer) { - registry.delete(issuer.issuer); - throw new RPError('discovered issuer mismatch, expected %s, got: %s', expectedIssuer, issuer.issuer); - } - return issuer; - } +var _GraphQLError = __nccwpck_require__(4797); - /** - * @name discover - * @api public - */ - static async discover(uri) { - const parsed = url.parse(uri); - - if (parsed.pathname.includes('/.well-known/')) { - const response = await request.call(this, { - method: 'GET', - responseType: 'json', - url: uri, - }); - const body = processResponse(response); - return new Issuer({ - ...ISSUER_DEFAULTS, - ...body, - [AAD_MULTITENANT]: !!AAD_MULTITENANT_DISCOVERY.find( - (discoveryURL) => uri.startsWith(discoveryURL), - ), - }); - } +var _kinds = __nccwpck_require__(11927); - const pathnames = []; - if (parsed.pathname.endsWith('/')) { - pathnames.push(`${parsed.pathname}${OIDC_DISCOVERY.substring(1)}`); - } else { - pathnames.push(`${parsed.pathname}${OIDC_DISCOVERY}`); - } - if (parsed.pathname === '/') { - pathnames.push(`${OAUTH2_DISCOVERY}`); - } else { - pathnames.push(`${OAUTH2_DISCOVERY}${parsed.pathname}`); - } +var _predicates = __nccwpck_require__(20535); - const errors = []; - // eslint-disable-next-line no-restricted-syntax - for (const pathname of pathnames) { - try { - const wellKnownUri = url.format({ ...parsed, pathname }); - // eslint-disable-next-line no-await-in-loop - const response = await request.call(this, { - method: 'GET', - responseType: 'json', - url: wellKnownUri, - }); - const body = processResponse(response); - return new Issuer({ - ...ISSUER_DEFAULTS, - ...body, - [AAD_MULTITENANT]: !!AAD_MULTITENANT_DISCOVERY.find( - (discoveryURL) => wellKnownUri.startsWith(discoveryURL), - ), - }); - } catch (err) { - errors.push(err); +/** + * Executable definitions + * + * A GraphQL document is only valid for execution if all definitions are either + * operation or fragment definitions. + * + * See https://spec.graphql.org/draft/#sec-Executable-Definitions + */ +function ExecutableDefinitionsRule(context) { + return { + Document(node) { + for (const definition of node.definitions) { + if (!(0, _predicates.isExecutableDefinitionNode)(definition)) { + const defName = + definition.kind === _kinds.Kind.SCHEMA_DEFINITION || + definition.kind === _kinds.Kind.SCHEMA_EXTENSION + ? 'schema' + : '"' + definition.name.value + '"'; + context.reportError( + new _GraphQLError.GraphQLError( + `The ${defName} definition is not executable.`, + { + nodes: definition, + }, + ), + ); + } } - } - - const err = new AggregateError(errors); - err.message = `Issuer.discover() failed.${err.message.split('\n') - .filter((line) => !line.startsWith(' at')).join('\n')}`; - throw err; - } - /* istanbul ignore next */ - [inspect.custom]() { - return `${this.constructor.name} ${inspect(this.metadata, { - depth: Infinity, - colors: process.stdout.isTTY, - compact: false, - sorted: true, - })}`; - } + return false; + }, + }; } -module.exports = Issuer; - /***/ }), -/***/ 30730: -/***/ ((module) => { - -const REGISTRY = new Map(); +/***/ 63016: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -module.exports = REGISTRY; +"use strict"; -/***/ }), +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.FieldsOnCorrectTypeRule = FieldsOnCorrectTypeRule; -/***/ 22134: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var _didYouMean = __nccwpck_require__(42878); -/* eslint-disable no-underscore-dangle */ +var _naturalCompare = __nccwpck_require__(20038); -const url = __nccwpck_require__(57310); -const { format } = __nccwpck_require__(73837); +var _suggestionList = __nccwpck_require__(57704); -const cloneDeep = __nccwpck_require__(21004); -const { RPError, OPError } = __nccwpck_require__(45061); -const { BaseClient } = __nccwpck_require__(28300); -const { random, codeChallenge } = __nccwpck_require__(75421); -const pick = __nccwpck_require__(78857); -const { resolveResponseType, resolveRedirectUri } = __nccwpck_require__(7619); +var _GraphQLError = __nccwpck_require__(4797); -function verified(err, user, info = {}) { - if (err) { - this.error(err); - } else if (!user) { - this.fail(info); - } else { - this.success(user, info); - } -} +var _definition = __nccwpck_require__(5821); /** - * @name constructor - * @api public + * Fields on correct type + * + * A GraphQL document is only valid if all fields selected are defined by the + * parent type, or are an allowed meta field such as __typename. + * + * See https://spec.graphql.org/draft/#sec-Field-Selections */ -function OpenIDConnectStrategy({ - client, - params = {}, - passReqToCallback = false, - sessionKey, - usePKCE = true, - extras = {}, -} = {}, verify) { - if (!(client instanceof BaseClient)) { - throw new TypeError('client must be an instance of openid-client Client'); - } - - if (typeof verify !== 'function') { - throw new TypeError('verify callback must be a function'); - } - - if (!client.issuer || !client.issuer.issuer) { - throw new TypeError('client must have an issuer with an identifier'); - } - - this._client = client; - this._issuer = client.issuer; - this._verify = verify; - this._passReqToCallback = passReqToCallback; - this._usePKCE = usePKCE; - this._key = sessionKey || `oidc:${url.parse(this._issuer.issuer).hostname}`; - this._params = cloneDeep(params); - this._extras = cloneDeep(extras); - - if (!this._params.response_type) this._params.response_type = resolveResponseType.call(client); - if (!this._params.redirect_uri) this._params.redirect_uri = resolveRedirectUri.call(client); - if (!this._params.scope) this._params.scope = 'openid'; - - if (this._usePKCE === true) { - const supportedMethods = Array.isArray(this._issuer.code_challenge_methods_supported) - ? this._issuer.code_challenge_methods_supported : false; - - if (supportedMethods && supportedMethods.includes('S256')) { - this._usePKCE = 'S256'; - } else if (supportedMethods && supportedMethods.includes('plain')) { - this._usePKCE = 'plain'; - } else if (supportedMethods) { - throw new TypeError('neither code_challenge_method supported by the client is supported by the issuer'); - } else { - this._usePKCE = 'S256'; - } - } else if (typeof this._usePKCE === 'string' && !['plain', 'S256'].includes(this._usePKCE)) { - throw new TypeError(`${this._usePKCE} is not valid/implemented PKCE code_challenge_method`); - } - - this.name = url.parse(client.issuer.issuer).hostname; -} - -OpenIDConnectStrategy.prototype.authenticate = function authenticate(req, options) { - (async () => { - const client = this._client; - if (!req.session) { - throw new TypeError('authentication requires session support'); - } - const reqParams = client.callbackParams(req); - const sessionKey = this._key; +function FieldsOnCorrectTypeRule(context) { + return { + Field(node) { + const type = context.getParentType(); - /* start authentication request */ - if (Object.keys(reqParams).length === 0) { - // provide options object with extra authentication parameters - const params = { - state: random(), - ...this._params, - ...options, - }; + if (type) { + const fieldDef = context.getFieldDef(); - if (!params.nonce && params.response_type.includes('id_token')) { - params.nonce = random(); - } + if (!fieldDef) { + // This field doesn't exist, lets look for suggestions. + const schema = context.getSchema(); + const fieldName = node.name.value; // First determine if there are any suggested types to condition on. - req.session[sessionKey] = pick(params, 'nonce', 'state', 'max_age', 'response_type'); + let suggestion = (0, _didYouMean.didYouMean)( + 'to use an inline fragment on', + getSuggestedTypeNames(schema, type, fieldName), + ); // If there are no suggested types, then perhaps this was a typo? - if (this._usePKCE && params.response_type.includes('code')) { - const verifier = random(); - req.session[sessionKey].code_verifier = verifier; + if (suggestion === '') { + suggestion = (0, _didYouMean.didYouMean)( + getSuggestedFieldNames(type, fieldName), + ); + } // Report an error, including helpful suggestions. - switch (this._usePKCE) { // eslint-disable-line default-case - case 'S256': - params.code_challenge = codeChallenge(verifier); - params.code_challenge_method = 'S256'; - break; - case 'plain': - params.code_challenge = verifier; - break; + context.reportError( + new _GraphQLError.GraphQLError( + `Cannot query field "${fieldName}" on type "${type.name}".` + + suggestion, + { + nodes: node, + }, + ), + ); } } + }, + }; +} +/** + * Go through all of the implementations of type, as well as the interfaces that + * they implement. If any of those types include the provided field, suggest them, + * sorted by how often the type is referenced. + */ - this.redirect(client.authorizationUrl(params)); - return; - } - /* end authentication request */ +function getSuggestedTypeNames(schema, type, fieldName) { + if (!(0, _definition.isAbstractType)(type)) { + // Must be an Object type, which does not have possible fields. + return []; + } - /* start authentication response */ + const suggestedTypes = new Set(); + const usageCount = Object.create(null); - const session = req.session[sessionKey]; - if (Object.keys(session || {}).length === 0) { - throw new Error(format('did not find expected authorization request details in session, req.session["%s"] is %j', sessionKey, session)); - } + for (const possibleType of schema.getPossibleTypes(type)) { + if (!possibleType.getFields()[fieldName]) { + continue; + } // This object type defines this field. - const { - state, nonce, max_age: maxAge, code_verifier: codeVerifier, response_type: responseType, - } = session; + suggestedTypes.add(possibleType); + usageCount[possibleType.name] = 1; - try { - delete req.session[sessionKey]; - } catch (err) {} + for (const possibleInterface of possibleType.getInterfaces()) { + var _usageCount$possibleI; - const opts = { - redirect_uri: this._params.redirect_uri, - ...options, - }; + if (!possibleInterface.getFields()[fieldName]) { + continue; + } // This interface type defines this field. - const checks = { - state, - nonce, - max_age: maxAge, - code_verifier: codeVerifier, - response_type: responseType, - }; + suggestedTypes.add(possibleInterface); + usageCount[possibleInterface.name] = + ((_usageCount$possibleI = usageCount[possibleInterface.name]) !== + null && _usageCount$possibleI !== void 0 + ? _usageCount$possibleI + : 0) + 1; + } + } - const tokenset = await client.callback(opts.redirect_uri, reqParams, checks, this._extras); + return [...suggestedTypes] + .sort((typeA, typeB) => { + // Suggest both interface and object types based on how common they are. + const usageCountDiff = usageCount[typeB.name] - usageCount[typeA.name]; - const passReq = this._passReqToCallback; - const loadUserinfo = this._verify.length > (passReq ? 3 : 2) && client.issuer.userinfo_endpoint; + if (usageCountDiff !== 0) { + return usageCountDiff; + } // Suggest super types first followed by subtypes - const args = [tokenset, verified.bind(this)]; + if ( + (0, _definition.isInterfaceType)(typeA) && + schema.isSubType(typeA, typeB) + ) { + return -1; + } - if (loadUserinfo) { - if (!tokenset.access_token) { - throw new RPError({ - message: 'expected access_token to be returned when asking for userinfo in verify callback', - tokenset, - }); + if ( + (0, _definition.isInterfaceType)(typeB) && + schema.isSubType(typeB, typeA) + ) { + return 1; } - const userinfo = await client.userinfo(tokenset); - args.splice(1, 0, userinfo); - } - if (passReq) { - args.unshift(req); - } + return (0, _naturalCompare.naturalCompare)(typeA.name, typeB.name); + }) + .map((x) => x.name); +} +/** + * For the field name provided, determine if there are any similar field names + * that may be the result of a typo. + */ - this._verify(...args); - /* end authentication response */ - })().catch((error) => { - if ( - (error instanceof OPError && error.error !== 'server_error' && !error.error.startsWith('invalid')) - || error instanceof RPError - ) { - this.fail(error); - } else { - this.error(error); - } - }); -}; +function getSuggestedFieldNames(type, fieldName) { + if ( + (0, _definition.isObjectType)(type) || + (0, _definition.isInterfaceType)(type) + ) { + const possibleFieldNames = Object.keys(type.getFields()); + return (0, _suggestionList.suggestionList)(fieldName, possibleFieldNames); + } // Otherwise, must be a Union type, which does not define fields. -module.exports = OpenIDConnectStrategy; + return []; +} /***/ }), -/***/ 39029: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const base64url = __nccwpck_require__(61827); -const now = __nccwpck_require__(8542); - -class TokenSet { - /** - * @name constructor - * @api public - */ - constructor(values) { - Object.assign(this, values); - } - - /** - * @name expires_in= - * @api public - */ - set expires_in(value) { // eslint-disable-line camelcase - this.expires_at = now() + Number(value); - } +/***/ 60381: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - /** - * @name expires_in - * @api public - */ - get expires_in() { // eslint-disable-line camelcase - return Math.max.apply(null, [this.expires_at - now(), 0]); - } +"use strict"; - /** - * @name expired - * @api public - */ - expired() { - return this.expires_in === 0; - } - /** - * @name claims - * @api public - */ - claims() { - if (!this.id_token) { - throw new TypeError('id_token not present in TokenSet'); - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.FragmentsOnCompositeTypesRule = FragmentsOnCompositeTypesRule; - return JSON.parse(base64url.decode(this.id_token.split('.')[1])); - } -} +var _GraphQLError = __nccwpck_require__(4797); -module.exports = TokenSet; +var _printer = __nccwpck_require__(68203); +var _definition = __nccwpck_require__(5821); -/***/ }), +var _typeFromAST = __nccwpck_require__(27664); -/***/ 19072: -/***/ ((module) => { +/** + * Fragments on composite type + * + * Fragments use a type condition to determine if they apply, since fragments + * can only be spread into a composite type (object, interface, or union), the + * type condition must also be a composite type. + * + * See https://spec.graphql.org/draft/#sec-Fragments-On-Composite-Types + */ +function FragmentsOnCompositeTypesRule(context) { + return { + InlineFragment(node) { + const typeCondition = node.typeCondition; -"use strict"; + if (typeCondition) { + const type = (0, _typeFromAST.typeFromAST)( + context.getSchema(), + typeCondition, + ); + if (type && !(0, _definition.isCompositeType)(type)) { + const typeStr = (0, _printer.print)(typeCondition); + context.reportError( + new _GraphQLError.GraphQLError( + `Fragment cannot condition on non composite type "${typeStr}".`, + { + nodes: typeCondition, + }, + ), + ); + } + } + }, -class CancelError extends Error { - constructor(reason) { - super(reason || 'Promise was canceled'); - this.name = 'CancelError'; - } + FragmentDefinition(node) { + const type = (0, _typeFromAST.typeFromAST)( + context.getSchema(), + node.typeCondition, + ); - get isCanceled() { - return true; - } + if (type && !(0, _definition.isCompositeType)(type)) { + const typeStr = (0, _printer.print)(node.typeCondition); + context.reportError( + new _GraphQLError.GraphQLError( + `Fragment "${node.name.value}" cannot condition on non composite type "${typeStr}".`, + { + nodes: node.typeCondition, + }, + ), + ); + } + }, + }; } -class PCancelable { - static fn(userFn) { - return (...arguments_) => { - return new PCancelable((resolve, reject, onCancel) => { - arguments_.push(onCancel); - // eslint-disable-next-line promise/prefer-await-to-then - userFn(...arguments_).then(resolve, reject); - }); - }; - } - - constructor(executor) { - this._cancelHandlers = []; - this._isPending = true; - this._isCanceled = false; - this._rejectOnCancel = true; - - this._promise = new Promise((resolve, reject) => { - this._reject = reject; - - const onResolve = value => { - if (!this._isCanceled || !onCancel.shouldReject) { - this._isPending = false; - resolve(value); - } - }; - const onReject = error => { - this._isPending = false; - reject(error); - }; +/***/ }), - const onCancel = handler => { - if (!this._isPending) { - throw new Error('The `onCancel` handler was attached after the promise settled.'); - } +/***/ 67147: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - this._cancelHandlers.push(handler); - }; +"use strict"; - Object.defineProperties(onCancel, { - shouldReject: { - get: () => this._rejectOnCancel, - set: boolean => { - this._rejectOnCancel = boolean; - } - } - }); - return executor(onResolve, onReject, onCancel); - }); - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.KnownArgumentNamesOnDirectivesRule = KnownArgumentNamesOnDirectivesRule; +exports.KnownArgumentNamesRule = KnownArgumentNamesRule; - then(onFulfilled, onRejected) { - // eslint-disable-next-line promise/prefer-await-to-then - return this._promise.then(onFulfilled, onRejected); - } +var _didYouMean = __nccwpck_require__(42878); - catch(onRejected) { - return this._promise.catch(onRejected); - } +var _suggestionList = __nccwpck_require__(57704); - finally(onFinally) { - return this._promise.finally(onFinally); - } +var _GraphQLError = __nccwpck_require__(4797); - cancel(reason) { - if (!this._isPending || this._isCanceled) { - return; - } +var _kinds = __nccwpck_require__(11927); - this._isCanceled = true; +var _directives = __nccwpck_require__(83614); - if (this._cancelHandlers.length > 0) { - try { - for (const handler of this._cancelHandlers) { - handler(); - } - } catch (error) { - this._reject(error); - return; - } - } +/** + * Known argument names + * + * A GraphQL field is only valid if all supplied arguments are defined by + * that field. + * + * See https://spec.graphql.org/draft/#sec-Argument-Names + * See https://spec.graphql.org/draft/#sec-Directives-Are-In-Valid-Locations + */ +function KnownArgumentNamesRule(context) { + return { + // eslint-disable-next-line new-cap + ...KnownArgumentNamesOnDirectivesRule(context), - if (this._rejectOnCancel) { - this._reject(new CancelError(reason)); - } - } + Argument(argNode) { + const argDef = context.getArgument(); + const fieldDef = context.getFieldDef(); + const parentType = context.getParentType(); - get isCanceled() { - return this._isCanceled; - } + if (!argDef && fieldDef && parentType) { + const argName = argNode.name.value; + const knownArgsNames = fieldDef.args.map((arg) => arg.name); + const suggestions = (0, _suggestionList.suggestionList)( + argName, + knownArgsNames, + ); + context.reportError( + new _GraphQLError.GraphQLError( + `Unknown argument "${argName}" on field "${parentType.name}.${fieldDef.name}".` + + (0, _didYouMean.didYouMean)(suggestions), + { + nodes: argNode, + }, + ), + ); + } + }, + }; } +/** + * @internal + */ -Object.setPrototypeOf(PCancelable.prototype, Promise.prototype); +function KnownArgumentNamesOnDirectivesRule(context) { + const directiveArgs = Object.create(null); + const schema = context.getSchema(); + const definedDirectives = schema + ? schema.getDirectives() + : _directives.specifiedDirectives; -module.exports = PCancelable; -module.exports.CancelError = CancelError; + for (const directive of definedDirectives) { + directiveArgs[directive.name] = directive.args.map((arg) => arg.name); + } + const astDefinitions = context.getDocument().definitions; -/***/ }), + for (const def of astDefinitions) { + if (def.kind === _kinds.Kind.DIRECTIVE_DEFINITION) { + var _def$arguments; -/***/ 38714: -/***/ ((module) => { + // FIXME: https://github.com/graphql/graphql-js/issues/2203 -"use strict"; + /* c8 ignore next */ + const argsNodes = + (_def$arguments = def.arguments) !== null && _def$arguments !== void 0 + ? _def$arguments + : []; + directiveArgs[def.name.value] = argsNodes.map((arg) => arg.name.value); + } + } + return { + Directive(directiveNode) { + const directiveName = directiveNode.name.value; + const knownArgs = directiveArgs[directiveName]; -function posix(path) { - return path.charAt(0) === '/'; -} + if (directiveNode.arguments && knownArgs) { + for (const argNode of directiveNode.arguments) { + const argName = argNode.name.value; -function win32(path) { - // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 - var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; - var result = splitDeviceRe.exec(path); - var device = result[1] || ''; - var isUnc = Boolean(device && device.charAt(1) !== ':'); + if (!knownArgs.includes(argName)) { + const suggestions = (0, _suggestionList.suggestionList)( + argName, + knownArgs, + ); + context.reportError( + new _GraphQLError.GraphQLError( + `Unknown argument "${argName}" on directive "@${directiveName}".` + + (0, _didYouMean.didYouMean)(suggestions), + { + nodes: argNode, + }, + ), + ); + } + } + } - // UNC paths are always absolute - return Boolean(result[2] || isUnc); + return false; + }, + }; } -module.exports = process.platform === 'win32' ? win32 : posix; -module.exports.posix = posix; -module.exports.win32 = win32; - /***/ }), -/***/ 20539: -/***/ ((module) => { +/***/ 85303: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -const pathKey = (options = {}) => { - const environment = options.env || process.env; - const platform = options.platform || process.platform; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.KnownDirectivesRule = KnownDirectivesRule; - if (platform !== 'win32') { - return 'PATH'; - } +var _inspect = __nccwpck_require__(10102); - return Object.keys(environment).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path'; -}; +var _invariant = __nccwpck_require__(28847); -module.exports = pathKey; -// TODO: Remove this for the next major release -module.exports["default"] = pathKey; +var _GraphQLError = __nccwpck_require__(4797); +var _ast = __nccwpck_require__(45494); -/***/ }), +var _directiveLocation = __nccwpck_require__(81205); -/***/ 85644: -/***/ (function(module) { +var _kinds = __nccwpck_require__(11927); -// Generated by CoffeeScript 1.12.2 -(function() { - var getNanoSeconds, hrtime, loadTime, moduleLoadTime, nodeLoadTime, upTime; +var _directives = __nccwpck_require__(83614); - if ((typeof performance !== "undefined" && performance !== null) && performance.now) { - module.exports = function() { - return performance.now(); - }; - } else if ((typeof process !== "undefined" && process !== null) && process.hrtime) { - module.exports = function() { - return (getNanoSeconds() - nodeLoadTime) / 1e6; - }; - hrtime = process.hrtime; - getNanoSeconds = function() { - var hr; - hr = hrtime(); - return hr[0] * 1e9 + hr[1]; - }; - moduleLoadTime = getNanoSeconds(); - upTime = process.uptime() * 1e9; - nodeLoadTime = moduleLoadTime - upTime; - } else if (Date.now) { - module.exports = function() { - return Date.now() - loadTime; - }; - loadTime = Date.now(); - } else { - module.exports = function() { - return new Date().getTime() - loadTime; - }; - loadTime = new Date().getTime(); +/** + * Known directives + * + * A GraphQL document is only valid if all `@directives` are known by the + * schema and legally positioned. + * + * See https://spec.graphql.org/draft/#sec-Directives-Are-Defined + */ +function KnownDirectivesRule(context) { + const locationsMap = Object.create(null); + const schema = context.getSchema(); + const definedDirectives = schema + ? schema.getDirectives() + : _directives.specifiedDirectives; + + for (const directive of definedDirectives) { + locationsMap[directive.name] = directive.locations; } -}).call(this); + const astDefinitions = context.getDocument().definitions; -//# sourceMappingURL=performance-now.js.map + for (const def of astDefinitions) { + if (def.kind === _kinds.Kind.DIRECTIVE_DEFINITION) { + locationsMap[def.name.value] = def.locations.map((name) => name.value); + } + } + return { + Directive(node, _key, _parent, _path, ancestors) { + const name = node.name.value; + const locations = locationsMap[name]; -/***/ }), + if (!locations) { + context.reportError( + new _GraphQLError.GraphQLError(`Unknown directive "@${name}".`, { + nodes: node, + }), + ); + return; + } -/***/ 29975: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + const candidateLocation = getDirectiveLocationForASTPath(ancestors); -"use strict"; -/*eslint no-var:0, prefer-arrow-callback: 0, object-shorthand: 0 */ + if (candidateLocation && !locations.includes(candidateLocation)) { + context.reportError( + new _GraphQLError.GraphQLError( + `Directive "@${name}" may not be used on ${candidateLocation}.`, + { + nodes: node, + }, + ), + ); + } + }, + }; +} +function getDirectiveLocationForASTPath(ancestors) { + const appliedTo = ancestors[ancestors.length - 1]; + 'kind' in appliedTo || (0, _invariant.invariant)(false); + switch (appliedTo.kind) { + case _kinds.Kind.OPERATION_DEFINITION: + return getDirectiveLocationForOperation(appliedTo.operation); -var Punycode = __nccwpck_require__(85477); + case _kinds.Kind.FIELD: + return _directiveLocation.DirectiveLocation.FIELD; + case _kinds.Kind.FRAGMENT_SPREAD: + return _directiveLocation.DirectiveLocation.FRAGMENT_SPREAD; -var internals = {}; + case _kinds.Kind.INLINE_FRAGMENT: + return _directiveLocation.DirectiveLocation.INLINE_FRAGMENT; + case _kinds.Kind.FRAGMENT_DEFINITION: + return _directiveLocation.DirectiveLocation.FRAGMENT_DEFINITION; -// -// Read rules from file. -// -internals.rules = (__nccwpck_require__(3704).map)(function (rule) { + case _kinds.Kind.VARIABLE_DEFINITION: + return _directiveLocation.DirectiveLocation.VARIABLE_DEFINITION; - return { - rule: rule, - suffix: rule.replace(/^(\*\.|\!)/, ''), - punySuffix: -1, - wildcard: rule.charAt(0) === '*', - exception: rule.charAt(0) === '!' - }; -}); + case _kinds.Kind.SCHEMA_DEFINITION: + case _kinds.Kind.SCHEMA_EXTENSION: + return _directiveLocation.DirectiveLocation.SCHEMA; + case _kinds.Kind.SCALAR_TYPE_DEFINITION: + case _kinds.Kind.SCALAR_TYPE_EXTENSION: + return _directiveLocation.DirectiveLocation.SCALAR; -// -// Check is given string ends with `suffix`. -// -internals.endsWith = function (str, suffix) { + case _kinds.Kind.OBJECT_TYPE_DEFINITION: + case _kinds.Kind.OBJECT_TYPE_EXTENSION: + return _directiveLocation.DirectiveLocation.OBJECT; - return str.indexOf(suffix, str.length - suffix.length) !== -1; -}; + case _kinds.Kind.FIELD_DEFINITION: + return _directiveLocation.DirectiveLocation.FIELD_DEFINITION; + case _kinds.Kind.INTERFACE_TYPE_DEFINITION: + case _kinds.Kind.INTERFACE_TYPE_EXTENSION: + return _directiveLocation.DirectiveLocation.INTERFACE; -// -// Find rule for a given domain. -// -internals.findRule = function (domain) { - - var punyDomain = Punycode.toASCII(domain); - return internals.rules.reduce(function (memo, rule) { - - if (rule.punySuffix === -1){ - rule.punySuffix = Punycode.toASCII(rule.suffix); - } - if (!internals.endsWith(punyDomain, '.' + rule.punySuffix) && punyDomain !== rule.punySuffix) { - return memo; - } - // This has been commented out as it never seems to run. This is because - // sub tlds always appear after their parents and we never find a shorter - // match. - //if (memo) { - // var memoSuffix = Punycode.toASCII(memo.suffix); - // if (memoSuffix.length >= punySuffix.length) { - // return memo; - // } - //} - return rule; - }, null); -}; + case _kinds.Kind.UNION_TYPE_DEFINITION: + case _kinds.Kind.UNION_TYPE_EXTENSION: + return _directiveLocation.DirectiveLocation.UNION; + case _kinds.Kind.ENUM_TYPE_DEFINITION: + case _kinds.Kind.ENUM_TYPE_EXTENSION: + return _directiveLocation.DirectiveLocation.ENUM; -// -// Error codes and messages. -// -exports.errorCodes = { - DOMAIN_TOO_SHORT: 'Domain name too short.', - DOMAIN_TOO_LONG: 'Domain name too long. It should be no more than 255 chars.', - LABEL_STARTS_WITH_DASH: 'Domain name label can not start with a dash.', - LABEL_ENDS_WITH_DASH: 'Domain name label can not end with a dash.', - LABEL_TOO_LONG: 'Domain name label should be at most 63 chars long.', - LABEL_TOO_SHORT: 'Domain name label should be at least 1 character long.', - LABEL_INVALID_CHARS: 'Domain name label can only contain alphanumeric characters or dashes.' -}; + case _kinds.Kind.ENUM_VALUE_DEFINITION: + return _directiveLocation.DirectiveLocation.ENUM_VALUE; + case _kinds.Kind.INPUT_OBJECT_TYPE_DEFINITION: + case _kinds.Kind.INPUT_OBJECT_TYPE_EXTENSION: + return _directiveLocation.DirectiveLocation.INPUT_OBJECT; -// -// Validate domain name and throw if not valid. -// -// From wikipedia: -// -// Hostnames are composed of series of labels concatenated with dots, as are all -// domain names. Each label must be between 1 and 63 characters long, and the -// entire hostname (including the delimiting dots) has a maximum of 255 chars. -// -// Allowed chars: -// -// * `a-z` -// * `0-9` -// * `-` but not as a starting or ending character -// * `.` as a separator for the textual portions of a domain name -// -// * http://en.wikipedia.org/wiki/Domain_name -// * http://en.wikipedia.org/wiki/Hostname -// -internals.validate = function (input) { + case _kinds.Kind.INPUT_VALUE_DEFINITION: { + const parentNode = ancestors[ancestors.length - 3]; + 'kind' in parentNode || (0, _invariant.invariant)(false); + return parentNode.kind === _kinds.Kind.INPUT_OBJECT_TYPE_DEFINITION + ? _directiveLocation.DirectiveLocation.INPUT_FIELD_DEFINITION + : _directiveLocation.DirectiveLocation.ARGUMENT_DEFINITION; + } + // Not reachable, all possible types have been considered. - // Before we can validate we need to take care of IDNs with unicode chars. - var ascii = Punycode.toASCII(input); + /* c8 ignore next */ - if (ascii.length < 1) { - return 'DOMAIN_TOO_SHORT'; - } - if (ascii.length > 255) { - return 'DOMAIN_TOO_LONG'; + default: + false || + (0, _invariant.invariant)( + false, + 'Unexpected kind: ' + (0, _inspect.inspect)(appliedTo.kind), + ); } +} - // Check each part's length and allowed chars. - var labels = ascii.split('.'); - var label; +function getDirectiveLocationForOperation(operation) { + switch (operation) { + case _ast.OperationTypeNode.QUERY: + return _directiveLocation.DirectiveLocation.QUERY; - for (var i = 0; i < labels.length; ++i) { - label = labels[i]; - if (!label.length) { - return 'LABEL_TOO_SHORT'; - } - if (label.length > 63) { - return 'LABEL_TOO_LONG'; - } - if (label.charAt(0) === '-') { - return 'LABEL_STARTS_WITH_DASH'; - } - if (label.charAt(label.length - 1) === '-') { - return 'LABEL_ENDS_WITH_DASH'; - } - if (!/^[a-z0-9\-]+$/.test(label)) { - return 'LABEL_INVALID_CHARS'; - } + case _ast.OperationTypeNode.MUTATION: + return _directiveLocation.DirectiveLocation.MUTATION; + + case _ast.OperationTypeNode.SUBSCRIPTION: + return _directiveLocation.DirectiveLocation.SUBSCRIPTION; } -}; +} -// -// Public API -// +/***/ }), +/***/ 15166: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -// -// Parse domain. -// -exports.parse = function (input) { +"use strict"; - if (typeof input !== 'string') { - throw new TypeError('Domain name must be a string.'); - } - // Force domain to lowercase. - var domain = input.slice(0).toLowerCase(); +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.KnownFragmentNamesRule = KnownFragmentNamesRule; - // Handle FQDN. - // TODO: Simply remove trailing dot? - if (domain.charAt(domain.length - 1) === '.') { - domain = domain.slice(0, domain.length - 1); - } +var _GraphQLError = __nccwpck_require__(4797); - // Validate and sanitise input. - var error = internals.validate(domain); - if (error) { - return { - input: input, - error: { - message: exports.errorCodes[error], - code: error - } - }; - } +/** + * Known fragment names + * + * A GraphQL document is only valid if all `...Fragment` fragment spreads refer + * to fragments defined in the same document. + * + * See https://spec.graphql.org/draft/#sec-Fragment-spread-target-defined + */ +function KnownFragmentNamesRule(context) { + return { + FragmentSpread(node) { + const fragmentName = node.name.value; + const fragment = context.getFragment(fragmentName); - var parsed = { - input: input, - tld: null, - sld: null, - domain: null, - subdomain: null, - listed: false + if (!fragment) { + context.reportError( + new _GraphQLError.GraphQLError( + `Unknown fragment "${fragmentName}".`, + { + nodes: node.name, + }, + ), + ); + } + }, }; +} - var domainParts = domain.split('.'); - - // Non-Internet TLD - if (domainParts[domainParts.length - 1] === 'local') { - return parsed; - } - var handlePunycode = function () { +/***/ }), - if (!/xn--/.test(domain)) { - return parsed; - } - if (parsed.domain) { - parsed.domain = Punycode.toASCII(parsed.domain); - } - if (parsed.subdomain) { - parsed.subdomain = Punycode.toASCII(parsed.subdomain); - } - return parsed; - }; +/***/ 42509: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var rule = internals.findRule(domain); +"use strict"; - // Unlisted tld. - if (!rule) { - if (domainParts.length < 2) { - return parsed; - } - parsed.tld = domainParts.pop(); - parsed.sld = domainParts.pop(); - parsed.domain = [parsed.sld, parsed.tld].join('.'); - if (domainParts.length) { - parsed.subdomain = domainParts.pop(); - } - return handlePunycode(); - } - // At this point we know the public suffix is listed. - parsed.listed = true; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.KnownTypeNamesRule = KnownTypeNamesRule; - var tldParts = rule.suffix.split('.'); - var privateParts = domainParts.slice(0, domainParts.length - tldParts.length); +var _didYouMean = __nccwpck_require__(42878); - if (rule.exception) { - privateParts.push(tldParts.shift()); - } +var _suggestionList = __nccwpck_require__(57704); - parsed.tld = tldParts.join('.'); +var _GraphQLError = __nccwpck_require__(4797); - if (!privateParts.length) { - return handlePunycode(); - } +var _predicates = __nccwpck_require__(20535); - if (rule.wildcard) { - tldParts.unshift(privateParts.pop()); - parsed.tld = tldParts.join('.'); - } +var _introspection = __nccwpck_require__(28344); - if (!privateParts.length) { - return handlePunycode(); - } +var _scalars = __nccwpck_require__(93145); - parsed.sld = privateParts.pop(); - parsed.domain = [parsed.sld, parsed.tld].join('.'); +/** + * Known type names + * + * A GraphQL document is only valid if referenced types (specifically + * variable definitions and fragment conditions) are defined by the type schema. + * + * See https://spec.graphql.org/draft/#sec-Fragment-Spread-Type-Existence + */ +function KnownTypeNamesRule(context) { + const schema = context.getSchema(); + const existingTypesMap = schema ? schema.getTypeMap() : Object.create(null); + const definedTypes = Object.create(null); - if (privateParts.length) { - parsed.subdomain = privateParts.join('.'); + for (const def of context.getDocument().definitions) { + if ((0, _predicates.isTypeDefinitionNode)(def)) { + definedTypes[def.name.value] = true; + } } - return handlePunycode(); -}; + const typeNames = [ + ...Object.keys(existingTypesMap), + ...Object.keys(definedTypes), + ]; + return { + NamedType(node, _1, parent, _2, ancestors) { + const typeName = node.name.value; + if (!existingTypesMap[typeName] && !definedTypes[typeName]) { + var _ancestors$; -// -// Get domain. -// -exports.get = function (domain) { + const definitionNode = + (_ancestors$ = ancestors[2]) !== null && _ancestors$ !== void 0 + ? _ancestors$ + : parent; + const isSDL = definitionNode != null && isSDLNode(definitionNode); - if (!domain) { - return null; - } - return exports.parse(domain).domain || null; -}; + if (isSDL && standardTypeNames.includes(typeName)) { + return; + } + const suggestedTypes = (0, _suggestionList.suggestionList)( + typeName, + isSDL ? standardTypeNames.concat(typeNames) : typeNames, + ); + context.reportError( + new _GraphQLError.GraphQLError( + `Unknown type "${typeName}".` + + (0, _didYouMean.didYouMean)(suggestedTypes), + { + nodes: node, + }, + ), + ); + } + }, + }; +} -// -// Check whether domain belongs to a known public suffix. -// -exports.isValid = function (domain) { +const standardTypeNames = [ + ..._scalars.specifiedScalarTypes, + ..._introspection.introspectionTypes, +].map((type) => type.name); - var parsed = exports.parse(domain); - return Boolean(parsed.domain && parsed.listed); -}; +function isSDLNode(value) { + return ( + 'kind' in value && + ((0, _predicates.isTypeSystemDefinitionNode)(value) || + (0, _predicates.isTypeSystemExtensionNode)(value)) + ); +} /***/ }), -/***/ 18341: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 45726: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var once = __nccwpck_require__(1223) -var eos = __nccwpck_require__(81205) -var fs = __nccwpck_require__(57147) // we only need fs to get the ReadStream and WriteStream prototypes +"use strict"; -var noop = function () {} -var ancient = /^v?\.0/.test(process.version) -var isFn = function (fn) { - return typeof fn === 'function' -} +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.LoneAnonymousOperationRule = LoneAnonymousOperationRule; -var isFS = function (stream) { - if (!ancient) return false // newer node version do not need to care about fs is a special way - if (!fs) return false // browser - return (stream instanceof (fs.ReadStream || noop) || stream instanceof (fs.WriteStream || noop)) && isFn(stream.close) -} +var _GraphQLError = __nccwpck_require__(4797); -var isRequest = function (stream) { - return stream.setHeader && isFn(stream.abort) -} +var _kinds = __nccwpck_require__(11927); -var destroyer = function (stream, reading, writing, callback) { - callback = once(callback) +/** + * Lone anonymous operation + * + * A GraphQL document is only valid if when it contains an anonymous operation + * (the query short-hand) that it contains only that one operation definition. + * + * See https://spec.graphql.org/draft/#sec-Lone-Anonymous-Operation + */ +function LoneAnonymousOperationRule(context) { + let operationCount = 0; + return { + Document(node) { + operationCount = node.definitions.filter( + (definition) => definition.kind === _kinds.Kind.OPERATION_DEFINITION, + ).length; + }, - var closed = false - stream.on('close', function () { - closed = true - }) + OperationDefinition(node) { + if (!node.name && operationCount > 1) { + context.reportError( + new _GraphQLError.GraphQLError( + 'This anonymous operation must be the only defined operation.', + { + nodes: node, + }, + ), + ); + } + }, + }; +} - eos(stream, {readable: reading, writable: writing}, function (err) { - if (err) return callback(err) - closed = true - callback() - }) - var destroyed = false - return function (err) { - if (closed) return - if (destroyed) return - destroyed = true +/***/ }), - if (isFS(stream)) return stream.close(noop) // use close for fs streams to avoid fd leaks - if (isRequest(stream)) return stream.abort() // request.destroy just do .end - .abort is what we want +/***/ 48307: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (isFn(stream.destroy)) return stream.destroy() +"use strict"; - callback(err || new Error('stream was destroyed')) - } -} -var call = function (fn) { - fn() -} +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.LoneSchemaDefinitionRule = LoneSchemaDefinitionRule; -var pipe = function (from, to) { - return from.pipe(to) -} +var _GraphQLError = __nccwpck_require__(4797); -var pump = function () { - var streams = Array.prototype.slice.call(arguments) - var callback = isFn(streams[streams.length - 1] || noop) && streams.pop() || noop +/** + * Lone Schema definition + * + * A GraphQL document is only valid if it contains only one schema definition. + */ +function LoneSchemaDefinitionRule(context) { + var _ref, _ref2, _oldSchema$astNode; - if (Array.isArray(streams[0])) streams = streams[0] - if (streams.length < 2) throw new Error('pump requires two streams per minimum') + const oldSchema = context.getSchema(); + const alreadyDefined = + (_ref = + (_ref2 = + (_oldSchema$astNode = + oldSchema === null || oldSchema === void 0 + ? void 0 + : oldSchema.astNode) !== null && _oldSchema$astNode !== void 0 + ? _oldSchema$astNode + : oldSchema === null || oldSchema === void 0 + ? void 0 + : oldSchema.getQueryType()) !== null && _ref2 !== void 0 + ? _ref2 + : oldSchema === null || oldSchema === void 0 + ? void 0 + : oldSchema.getMutationType()) !== null && _ref !== void 0 + ? _ref + : oldSchema === null || oldSchema === void 0 + ? void 0 + : oldSchema.getSubscriptionType(); + let schemaDefinitionsCount = 0; + return { + SchemaDefinition(node) { + if (alreadyDefined) { + context.reportError( + new _GraphQLError.GraphQLError( + 'Cannot define a new schema within a schema extension.', + { + nodes: node, + }, + ), + ); + return; + } - var error - var destroys = streams.map(function (stream, i) { - var reading = i < streams.length - 1 - var writing = i > 0 - return destroyer(stream, reading, writing, function (err) { - if (!error) error = err - if (err) destroys.forEach(call) - if (reading) return - destroys.forEach(call) - callback(error) - }) - }) + if (schemaDefinitionsCount > 0) { + context.reportError( + new _GraphQLError.GraphQLError( + 'Must provide only one schema definition.', + { + nodes: node, + }, + ), + ); + } - return streams.reduce(pipe) + ++schemaDefinitionsCount; + }, + }; } -module.exports = pump - /***/ }), -/***/ 74907: -/***/ ((module) => { +/***/ 53318: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var replace = String.prototype.replace; -var percentTwenties = /%20/g; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.MaxIntrospectionDepthRule = MaxIntrospectionDepthRule; -module.exports = { - 'default': 'RFC3986', - formatters: { - RFC1738: function (value) { - return replace.call(value, percentTwenties, '+'); - }, - RFC3986: function (value) { - return String(value); - } - }, - RFC1738: 'RFC1738', - RFC3986: 'RFC3986' -}; +var _GraphQLError = __nccwpck_require__(4797); +var _kinds = __nccwpck_require__(11927); -/***/ }), +const MAX_LISTS_DEPTH = 3; -/***/ 22760: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function MaxIntrospectionDepthRule(context) { + /** + * Counts the depth of list fields in "__Type" recursively and + * returns `true` if the limit has been reached. + */ + function checkDepth(node, visitedFragments = Object.create(null), depth = 0) { + if (node.kind === _kinds.Kind.FRAGMENT_SPREAD) { + const fragmentName = node.name.value; -"use strict"; + if (visitedFragments[fragmentName] === true) { + // Fragment cycles are handled by `NoFragmentCyclesRule`. + return false; + } + const fragment = context.getFragment(fragmentName); -var stringify = __nccwpck_require__(79954); -var parse = __nccwpck_require__(33912); -var formats = __nccwpck_require__(74907); + if (!fragment) { + // Missing fragments checks are handled by `KnownFragmentNamesRule`. + return false; + } // Rather than following an immutable programming pattern which has + // significant memory and garbage collection overhead, we've opted to + // take a mutable approach for efficiency's sake. Importantly visiting a + // fragment twice is fine, so long as you don't do one visit inside the + // other. -module.exports = { - formats: formats, - parse: parse, - stringify: stringify -}; + try { + visitedFragments[fragmentName] = true; + return checkDepth(fragment, visitedFragments, depth); + } finally { + visitedFragments[fragmentName] = undefined; + } + } + if ( + node.kind === _kinds.Kind.FIELD && // check all introspection lists + (node.name.value === 'fields' || + node.name.value === 'interfaces' || + node.name.value === 'possibleTypes' || + node.name.value === 'inputFields') + ) { + // eslint-disable-next-line no-param-reassign + depth++; -/***/ }), + if (depth >= MAX_LISTS_DEPTH) { + return true; + } + } // handles fields and inline fragments -/***/ 33912: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if ('selectionSet' in node && node.selectionSet) { + for (const child of node.selectionSet.selections) { + if (checkDepth(child, visitedFragments, depth)) { + return true; + } + } + } -"use strict"; + return false; + } + return { + Field(node) { + if (node.name.value === '__schema' || node.name.value === '__type') { + if (checkDepth(node)) { + context.reportError( + new _GraphQLError.GraphQLError( + 'Maximum introspection depth exceeded', + { + nodes: [node], + }, + ), + ); + return false; + } + } + }, + }; +} -var utils = __nccwpck_require__(72360); -var has = Object.prototype.hasOwnProperty; +/***/ }), -var defaults = { - allowDots: false, - allowPrototypes: false, - arrayLimit: 20, - decoder: utils.decode, - delimiter: '&', - depth: 5, - parameterLimit: 1000, - plainObjects: false, - strictNullHandling: false -}; +/***/ 62564: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var parseValues = function parseQueryStringValues(str, options) { - var obj = {}; - var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str; - var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit; - var parts = cleanStr.split(options.delimiter, limit); +"use strict"; - for (var i = 0; i < parts.length; ++i) { - var part = parts[i]; - var bracketEqualsPos = part.indexOf(']='); - var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.NoFragmentCyclesRule = NoFragmentCyclesRule; - var key, val; - if (pos === -1) { - key = options.decoder(part, defaults.decoder); - val = options.strictNullHandling ? null : ''; - } else { - key = options.decoder(part.slice(0, pos), defaults.decoder); - val = options.decoder(part.slice(pos + 1), defaults.decoder); - } - if (has.call(obj, key)) { - obj[key] = [].concat(obj[key]).concat(val); - } else { - obj[key] = val; - } - } +var _GraphQLError = __nccwpck_require__(4797); - return obj; -}; +/** + * No fragment cycles + * + * The graph of fragment spreads must not form any cycles including spreading itself. + * Otherwise an operation could infinitely spread or infinitely execute on cycles in the underlying data. + * + * See https://spec.graphql.org/draft/#sec-Fragment-spreads-must-not-form-cycles + */ +function NoFragmentCyclesRule(context) { + // Tracks already visited fragments to maintain O(N) and to ensure that cycles + // are not redundantly reported. + const visitedFrags = Object.create(null); // Array of AST nodes used to produce meaningful errors -var parseObject = function (chain, val, options) { - var leaf = val; + const spreadPath = []; // Position in the spread path - for (var i = chain.length - 1; i >= 0; --i) { - var obj; - var root = chain[i]; + const spreadPathIndexByName = Object.create(null); + return { + OperationDefinition: () => false, - if (root === '[]' && options.parseArrays) { - obj = [].concat(leaf); - } else { - obj = options.plainObjects ? Object.create(null) : {}; - var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root; - var index = parseInt(cleanRoot, 10); - if (!options.parseArrays && cleanRoot === '') { - obj = { 0: leaf }; - } else if ( - !isNaN(index) - && root !== cleanRoot - && String(index) === cleanRoot - && index >= 0 - && (options.parseArrays && index <= options.arrayLimit) - ) { - obj = []; - obj[index] = leaf; - } else if (cleanRoot !== '__proto__') { - obj[cleanRoot] = leaf; - } - } + FragmentDefinition(node) { + detectCycleRecursive(node); + return false; + }, + }; // This does a straight-forward DFS to find cycles. + // It does not terminate when a cycle was found but continues to explore + // the graph to find all possible cycles. - leaf = obj; + function detectCycleRecursive(fragment) { + if (visitedFrags[fragment.name.value]) { + return; } - return leaf; -}; + const fragmentName = fragment.name.value; + visitedFrags[fragmentName] = true; + const spreadNodes = context.getFragmentSpreads(fragment.selectionSet); -var parseKeys = function parseQueryStringKeys(givenKey, val, options) { - if (!givenKey) { - return; + if (spreadNodes.length === 0) { + return; } - // Transform dot notation to bracket notation - var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey; - - // The regex chunks - - var brackets = /(\[[^[\]]*])/; - var child = /(\[[^[\]]*])/g; - - // Get the parent + spreadPathIndexByName[fragmentName] = spreadPath.length; - var segment = brackets.exec(key); - var parent = segment ? key.slice(0, segment.index) : key; + for (const spreadNode of spreadNodes) { + const spreadName = spreadNode.name.value; + const cycleIndex = spreadPathIndexByName[spreadName]; + spreadPath.push(spreadNode); - // Stash the parent if it exists + if (cycleIndex === undefined) { + const spreadFragment = context.getFragment(spreadName); - var keys = []; - if (parent) { - // If we aren't using plain objects, optionally prefix keys - // that would overwrite object prototype properties - if (!options.plainObjects && has.call(Object.prototype, parent)) { - if (!options.allowPrototypes) { - return; - } + if (spreadFragment) { + detectCycleRecursive(spreadFragment); } + } else { + const cyclePath = spreadPath.slice(cycleIndex); + const viaPath = cyclePath + .slice(0, -1) + .map((s) => '"' + s.name.value + '"') + .join(', '); + context.reportError( + new _GraphQLError.GraphQLError( + `Cannot spread fragment "${spreadName}" within itself` + + (viaPath !== '' ? ` via ${viaPath}.` : '.'), + { + nodes: cyclePath, + }, + ), + ); + } - keys.push(parent); + spreadPath.pop(); } - // Loop through children appending to the array until we hit depth + spreadPathIndexByName[fragmentName] = undefined; + } +} - var i = 0; - while ((segment = child.exec(key)) !== null && i < options.depth) { - i += 1; - if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) { - if (!options.allowPrototypes) { - return; - } - } - keys.push(segment[1]); - } - // If there's a remainder, just add whatever is left +/***/ }), - if (segment) { - keys.push('[' + key.slice(segment.index) + ']'); - } +/***/ 61671: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - return parseObject(keys, val, options); -}; +"use strict"; -module.exports = function (str, opts) { - var options = opts ? utils.assign({}, opts) : {}; - if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') { - throw new TypeError('Decoder has to be a function.'); - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.NoUndefinedVariablesRule = NoUndefinedVariablesRule; - options.ignoreQueryPrefix = options.ignoreQueryPrefix === true; - options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter; - options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth; - options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit; - options.parseArrays = options.parseArrays !== false; - options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder; - options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : defaults.allowDots; - options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects; - options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes; - options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit; - options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; +var _GraphQLError = __nccwpck_require__(4797); - if (str === '' || str === null || typeof str === 'undefined') { - return options.plainObjects ? Object.create(null) : {}; - } +/** + * No undefined variables + * + * A GraphQL operation is only valid if all variables encountered, both directly + * and via fragment spreads, are defined by that operation. + * + * See https://spec.graphql.org/draft/#sec-All-Variable-Uses-Defined + */ +function NoUndefinedVariablesRule(context) { + let variableNameDefined = Object.create(null); + return { + OperationDefinition: { + enter() { + variableNameDefined = Object.create(null); + }, - var tempObj = typeof str === 'string' ? parseValues(str, options) : str; - var obj = options.plainObjects ? Object.create(null) : {}; + leave(operation) { + const usages = context.getRecursiveVariableUsages(operation); - // Iterate over the keys and setup the new object + for (const { node } of usages) { + const varName = node.name.value; - var keys = Object.keys(tempObj); - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - var newObj = parseKeys(key, tempObj[key], options); - obj = utils.merge(obj, newObj, options); - } + if (variableNameDefined[varName] !== true) { + context.reportError( + new _GraphQLError.GraphQLError( + operation.name + ? `Variable "$${varName}" is not defined by operation "${operation.name.value}".` + : `Variable "$${varName}" is not defined.`, + { + nodes: [node, operation], + }, + ), + ); + } + } + }, + }, - return utils.compact(obj); -}; + VariableDefinition(node) { + variableNameDefined[node.variable.name.value] = true; + }, + }; +} /***/ }), -/***/ 79954: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 192: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var utils = __nccwpck_require__(72360); -var formats = __nccwpck_require__(74907); - -var arrayPrefixGenerators = { - brackets: function brackets(prefix) { - return prefix + '[]'; - }, - indices: function indices(prefix, key) { - return prefix + '[' + key + ']'; - }, - repeat: function repeat(prefix) { - return prefix; - } -}; - -var isArray = Array.isArray; -var push = Array.prototype.push; -var pushToArray = function (arr, valueOrArray) { - push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]); -}; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.NoUnusedFragmentsRule = NoUnusedFragmentsRule; -var toISO = Date.prototype.toISOString; +var _GraphQLError = __nccwpck_require__(4797); -var defaults = { - delimiter: '&', - encode: true, - encoder: utils.encode, - encodeValuesOnly: false, - serializeDate: function serializeDate(date) { - return toISO.call(date); +/** + * No unused fragments + * + * A GraphQL document is only valid if all fragment definitions are spread + * within operations, or spread within other fragments spread within operations. + * + * See https://spec.graphql.org/draft/#sec-Fragments-Must-Be-Used + */ +function NoUnusedFragmentsRule(context) { + const operationDefs = []; + const fragmentDefs = []; + return { + OperationDefinition(node) { + operationDefs.push(node); + return false; }, - skipNulls: false, - strictNullHandling: false -}; -var stringify = function stringify( - object, - prefix, - generateArrayPrefix, - strictNullHandling, - skipNulls, - encoder, - filter, - sort, - allowDots, - serializeDate, - formatter, - encodeValuesOnly -) { - var obj = object; - if (typeof filter === 'function') { - obj = filter(prefix, obj); - } else if (obj instanceof Date) { - obj = serializeDate(obj); - } - - if (obj === null) { - if (strictNullHandling) { - return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder) : prefix; - } + FragmentDefinition(node) { + fragmentDefs.push(node); + return false; + }, - obj = ''; - } + Document: { + leave() { + const fragmentNameUsed = Object.create(null); - if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) { - if (encoder) { - var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder); - return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder))]; + for (const operation of operationDefs) { + for (const fragment of context.getRecursivelyReferencedFragments( + operation, + )) { + fragmentNameUsed[fragment.name.value] = true; + } } - return [formatter(prefix) + '=' + formatter(String(obj))]; - } - - var values = []; - - if (typeof obj === 'undefined') { - return values; - } - - var objKeys; - if (isArray(filter)) { - objKeys = filter; - } else { - var keys = Object.keys(obj); - objKeys = sort ? keys.sort(sort) : keys; - } - - for (var i = 0; i < objKeys.length; ++i) { - var key = objKeys[i]; - if (skipNulls && obj[key] === null) { - continue; - } + for (const fragmentDef of fragmentDefs) { + const fragName = fragmentDef.name.value; - if (isArray(obj)) { - pushToArray(values, stringify( - obj[key], - generateArrayPrefix(prefix, key), - generateArrayPrefix, - strictNullHandling, - skipNulls, - encoder, - filter, - sort, - allowDots, - serializeDate, - formatter, - encodeValuesOnly - )); - } else { - pushToArray(values, stringify( - obj[key], - prefix + (allowDots ? '.' + key : '[' + key + ']'), - generateArrayPrefix, - strictNullHandling, - skipNulls, - encoder, - filter, - sort, - allowDots, - serializeDate, - formatter, - encodeValuesOnly - )); + if (fragmentNameUsed[fragName] !== true) { + context.reportError( + new _GraphQLError.GraphQLError( + `Fragment "${fragName}" is never used.`, + { + nodes: fragmentDef, + }, + ), + ); + } } - } - - return values; -}; + }, + }, + }; +} -module.exports = function (object, opts) { - var obj = object; - var options = opts ? utils.assign({}, opts) : {}; - if (options.encoder !== null && typeof options.encoder !== 'undefined' && typeof options.encoder !== 'function') { - throw new TypeError('Encoder has to be a function.'); - } +/***/ }), - var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter; - var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; - var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls; - var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode; - var encoder = typeof options.encoder === 'function' ? options.encoder : defaults.encoder; - var sort = typeof options.sort === 'function' ? options.sort : null; - var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots; - var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate; - var encodeValuesOnly = typeof options.encodeValuesOnly === 'boolean' ? options.encodeValuesOnly : defaults.encodeValuesOnly; - if (typeof options.format === 'undefined') { - options.format = formats['default']; - } else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) { - throw new TypeError('Unknown format option provided.'); - } - var formatter = formats.formatters[options.format]; - var objKeys; - var filter; +/***/ 40242: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (typeof options.filter === 'function') { - filter = options.filter; - obj = filter('', obj); - } else if (isArray(options.filter)) { - filter = options.filter; - objKeys = filter; - } +"use strict"; - var keys = []; - if (typeof obj !== 'object' || obj === null) { - return ''; - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.NoUnusedVariablesRule = NoUnusedVariablesRule; - var arrayFormat; - if (options.arrayFormat in arrayPrefixGenerators) { - arrayFormat = options.arrayFormat; - } else if ('indices' in options) { - arrayFormat = options.indices ? 'indices' : 'repeat'; - } else { - arrayFormat = 'indices'; - } +var _GraphQLError = __nccwpck_require__(4797); - var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; +/** + * No unused variables + * + * A GraphQL operation is only valid if all variables defined by an operation + * are used, either directly or within a spread fragment. + * + * See https://spec.graphql.org/draft/#sec-All-Variables-Used + */ +function NoUnusedVariablesRule(context) { + let variableDefs = []; + return { + OperationDefinition: { + enter() { + variableDefs = []; + }, - if (!objKeys) { - objKeys = Object.keys(obj); - } + leave(operation) { + const variableNameUsed = Object.create(null); + const usages = context.getRecursiveVariableUsages(operation); - if (sort) { - objKeys.sort(sort); - } + for (const { node } of usages) { + variableNameUsed[node.name.value] = true; + } - for (var i = 0; i < objKeys.length; ++i) { - var key = objKeys[i]; + for (const variableDef of variableDefs) { + const variableName = variableDef.variable.name.value; - if (skipNulls && obj[key] === null) { - continue; + if (variableNameUsed[variableName] !== true) { + context.reportError( + new _GraphQLError.GraphQLError( + operation.name + ? `Variable "$${variableName}" is never used in operation "${operation.name.value}".` + : `Variable "$${variableName}" is never used.`, + { + nodes: variableDef, + }, + ), + ); + } } - pushToArray(keys, stringify( - obj[key], - key, - generateArrayPrefix, - strictNullHandling, - skipNulls, - encode ? encoder : null, - filter, - sort, - allowDots, - serializeDate, - formatter, - encodeValuesOnly - )); - } - - var joined = keys.join(delimiter); - var prefix = options.addQueryPrefix === true ? '?' : ''; - - return joined.length > 0 ? prefix + joined : ''; -}; + }, + }, + + VariableDefinition(def) { + variableDefs.push(def); + }, + }; +} /***/ }), -/***/ 72360: -/***/ ((module) => { +/***/ 23577: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var has = Object.prototype.hasOwnProperty; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.OverlappingFieldsCanBeMergedRule = OverlappingFieldsCanBeMergedRule; -var hexTable = (function () { - var array = []; - for (var i = 0; i < 256; ++i) { - array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase()); - } +var _inspect = __nccwpck_require__(10102); - return array; -}()); +var _GraphQLError = __nccwpck_require__(4797); -var compactQueue = function compactQueue(queue) { - var obj; +var _kinds = __nccwpck_require__(11927); - while (queue.length) { - var item = queue.pop(); - obj = item.obj[item.prop]; +var _printer = __nccwpck_require__(68203); - if (Array.isArray(obj)) { - var compacted = []; +var _definition = __nccwpck_require__(5821); - for (var j = 0; j < obj.length; ++j) { - if (typeof obj[j] !== 'undefined') { - compacted.push(obj[j]); - } - } +var _sortValueNode = __nccwpck_require__(82278); - item.obj[item.prop] = compacted; - } - } +var _typeFromAST = __nccwpck_require__(27664); - return obj; -}; +function reasonMessage(reason) { + if (Array.isArray(reason)) { + return reason + .map( + ([responseName, subReason]) => + `subfields "${responseName}" conflict because ` + + reasonMessage(subReason), + ) + .join(' and '); + } -var arrayToObject = function arrayToObject(source, options) { - var obj = options && options.plainObjects ? Object.create(null) : {}; - for (var i = 0; i < source.length; ++i) { - if (typeof source[i] !== 'undefined') { - obj[i] = source[i]; - } - } + return reason; +} +/** + * Overlapping fields can be merged + * + * A selection set is only valid if all fields (including spreading any + * fragments) either correspond to distinct response names or can be merged + * without ambiguity. + * + * See https://spec.graphql.org/draft/#sec-Field-Selection-Merging + */ - return obj; -}; +function OverlappingFieldsCanBeMergedRule(context) { + // A memoization for when fields and a fragment or two fragments are compared + // "between" each other for conflicts. Comparisons made be made many times, + // so memoizing this can dramatically improve the performance of this validator. + const comparedFieldsAndFragmentPairs = new OrderedPairSet(); + const comparedFragmentPairs = new PairSet(); // A cache for the "field map" and list of fragment names found in any given + // selection set. Selection sets may be asked for this information multiple + // times, so this improves the performance of this validator. -var merge = function merge(target, source, options) { - if (!source) { - return target; - } + const cachedFieldsAndFragmentNames = new Map(); + return { + SelectionSet(selectionSet) { + const conflicts = findConflictsWithinSelectionSet( + context, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + context.getParentType(), + selectionSet, + ); - if (typeof source !== 'object') { - if (Array.isArray(target)) { - target.push(source); - } else if (target && typeof target === 'object') { - if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) { - target[source] = true; - } - } else { - return [target, source]; - } + for (const [[responseName, reason], fields1, fields2] of conflicts) { + const reasonMsg = reasonMessage(reason); + context.reportError( + new _GraphQLError.GraphQLError( + `Fields "${responseName}" conflict because ${reasonMsg}. Use different aliases on the fields to fetch both if this was intentional.`, + { + nodes: fields1.concat(fields2), + }, + ), + ); + } + }, + }; +} - return target; - } +/** + * Algorithm: + * + * Conflicts occur when two fields exist in a query which will produce the same + * response name, but represent differing values, thus creating a conflict. + * The algorithm below finds all conflicts via making a series of comparisons + * between fields. In order to compare as few fields as possible, this makes + * a series of comparisons "within" sets of fields and "between" sets of fields. + * + * Given any selection set, a collection produces both a set of fields by + * also including all inline fragments, as well as a list of fragments + * referenced by fragment spreads. + * + * A) Each selection set represented in the document first compares "within" its + * collected set of fields, finding any conflicts between every pair of + * overlapping fields. + * Note: This is the *only time* that a the fields "within" a set are compared + * to each other. After this only fields "between" sets are compared. + * + * B) Also, if any fragment is referenced in a selection set, then a + * comparison is made "between" the original set of fields and the + * referenced fragment. + * + * C) Also, if multiple fragments are referenced, then comparisons + * are made "between" each referenced fragment. + * + * D) When comparing "between" a set of fields and a referenced fragment, first + * a comparison is made between each field in the original set of fields and + * each field in the the referenced set of fields. + * + * E) Also, if any fragment is referenced in the referenced selection set, + * then a comparison is made "between" the original set of fields and the + * referenced fragment (recursively referring to step D). + * + * F) When comparing "between" two fragments, first a comparison is made between + * each field in the first referenced set of fields and each field in the the + * second referenced set of fields. + * + * G) Also, any fragments referenced by the first must be compared to the + * second, and any fragments referenced by the second must be compared to the + * first (recursively referring to step F). + * + * H) When comparing two fields, if both have selection sets, then a comparison + * is made "between" both selection sets, first comparing the set of fields in + * the first selection set with the set of fields in the second. + * + * I) Also, if any fragment is referenced in either selection set, then a + * comparison is made "between" the other set of fields and the + * referenced fragment. + * + * J) Also, if two fragments are referenced in both selection sets, then a + * comparison is made "between" the two fragments. + * + */ +// Find all conflicts found "within" a selection set, including those found +// via spreading in fragments. Called when visiting each SelectionSet in the +// GraphQL Document. +function findConflictsWithinSelectionSet( + context, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + parentType, + selectionSet, +) { + const conflicts = []; + const [fieldMap, fragmentNames] = getFieldsAndFragmentNames( + context, + cachedFieldsAndFragmentNames, + parentType, + selectionSet, + ); // (A) Find find all conflicts "within" the fields of this selection set. + // Note: this is the *only place* `collectConflictsWithin` is called. - if (!target || typeof target !== 'object') { - return [target].concat(source); - } + collectConflictsWithin( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + fieldMap, + ); - var mergeTarget = target; - if (Array.isArray(target) && !Array.isArray(source)) { - mergeTarget = arrayToObject(target, options); - } + if (fragmentNames.length !== 0) { + // (B) Then collect conflicts between these fields and those represented by + // each spread fragment name found. + for (let i = 0; i < fragmentNames.length; i++) { + collectConflictsBetweenFieldsAndFragment( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + false, + fieldMap, + fragmentNames[i], + ); // (C) Then compare this fragment with all other fragments found in this + // selection set to collect conflicts between fragments spread together. + // This compares each item in the list of fragment names to every other + // item in that same list (except for itself). - if (Array.isArray(target) && Array.isArray(source)) { - source.forEach(function (item, i) { - if (has.call(target, i)) { - var targetItem = target[i]; - if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') { - target[i] = merge(targetItem, item, options); - } else { - target.push(item); - } - } else { - target[i] = item; - } - }); - return target; + for (let j = i + 1; j < fragmentNames.length; j++) { + collectConflictsBetweenFragments( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + false, + fragmentNames[i], + fragmentNames[j], + ); + } } + } - return Object.keys(source).reduce(function (acc, key) { - var value = source[key]; + return conflicts; +} // Collect all conflicts found between a set of fields and a fragment reference +// including via spreading in any nested fragments. - if (has.call(acc, key)) { - acc[key] = merge(acc[key], value, options); - } else { - acc[key] = value; - } - return acc; - }, mergeTarget); -}; +function collectConflictsBetweenFieldsAndFragment( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + fieldMap, + fragmentName, +) { + // Memoize so the fields and fragments are not compared for conflicts more + // than once. + if ( + comparedFieldsAndFragmentPairs.has( + fieldMap, + fragmentName, + areMutuallyExclusive, + ) + ) { + return; + } -var assign = function assignSingleSource(target, source) { - return Object.keys(source).reduce(function (acc, key) { - acc[key] = source[key]; - return acc; - }, target); -}; + comparedFieldsAndFragmentPairs.add( + fieldMap, + fragmentName, + areMutuallyExclusive, + ); + const fragment = context.getFragment(fragmentName); -var decode = function (str) { - try { - return decodeURIComponent(str.replace(/\+/g, ' ')); - } catch (e) { - return str; - } -}; + if (!fragment) { + return; + } -var encode = function encode(str) { - // This code was originally written by Brian White (mscdex) for the io.js core querystring library. - // It has been adapted here for stricter adherence to RFC 3986 - if (str.length === 0) { - return str; - } + const [fieldMap2, referencedFragmentNames] = + getReferencedFieldsAndFragmentNames( + context, + cachedFieldsAndFragmentNames, + fragment, + ); // Do not compare a fragment's fieldMap to itself. - var string = typeof str === 'string' ? str : String(str); + if (fieldMap === fieldMap2) { + return; + } // (D) First collect any conflicts between the provided collection of fields + // and the collection of fields represented by the given fragment. - var out = ''; - for (var i = 0; i < string.length; ++i) { - var c = string.charCodeAt(i); + collectConflictsBetween( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + fieldMap, + fieldMap2, + ); // (E) Then collect any conflicts between the provided collection of fields + // and any fragment names found in the given fragment. - if ( - c === 0x2D // - - || c === 0x2E // . - || c === 0x5F // _ - || c === 0x7E // ~ - || (c >= 0x30 && c <= 0x39) // 0-9 - || (c >= 0x41 && c <= 0x5A) // a-z - || (c >= 0x61 && c <= 0x7A) // A-Z - ) { - out += string.charAt(i); - continue; - } + for (const referencedFragmentName of referencedFragmentNames) { + collectConflictsBetweenFieldsAndFragment( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + fieldMap, + referencedFragmentName, + ); + } +} // Collect all conflicts found between two fragments, including via spreading in +// any nested fragments. - if (c < 0x80) { - out = out + hexTable[c]; - continue; - } +function collectConflictsBetweenFragments( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + fragmentName1, + fragmentName2, +) { + // No need to compare a fragment to itself. + if (fragmentName1 === fragmentName2) { + return; + } // Memoize so two fragments are not compared for conflicts more than once. - if (c < 0x800) { - out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]); - continue; - } + if ( + comparedFragmentPairs.has( + fragmentName1, + fragmentName2, + areMutuallyExclusive, + ) + ) { + return; + } - if (c < 0xD800 || c >= 0xE000) { - out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]); - continue; - } + comparedFragmentPairs.add(fragmentName1, fragmentName2, areMutuallyExclusive); + const fragment1 = context.getFragment(fragmentName1); + const fragment2 = context.getFragment(fragmentName2); - i += 1; - c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF)); - /* eslint operator-linebreak: [2, "before"] */ - out += hexTable[0xF0 | (c >> 18)] - + hexTable[0x80 | ((c >> 12) & 0x3F)] - + hexTable[0x80 | ((c >> 6) & 0x3F)] - + hexTable[0x80 | (c & 0x3F)]; - } + if (!fragment1 || !fragment2) { + return; + } - return out; -}; + const [fieldMap1, referencedFragmentNames1] = + getReferencedFieldsAndFragmentNames( + context, + cachedFieldsAndFragmentNames, + fragment1, + ); + const [fieldMap2, referencedFragmentNames2] = + getReferencedFieldsAndFragmentNames( + context, + cachedFieldsAndFragmentNames, + fragment2, + ); // (F) First, collect all conflicts between these two collections of fields + // (not including any nested fragments). -var compact = function compact(value) { - var queue = [{ obj: { o: value }, prop: 'o' }]; - var refs = []; - - for (var i = 0; i < queue.length; ++i) { - var item = queue[i]; - var obj = item.obj[item.prop]; - - var keys = Object.keys(obj); - for (var j = 0; j < keys.length; ++j) { - var key = keys[j]; - var val = obj[key]; - if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) { - queue.push({ obj: obj, prop: key }); - refs.push(val); - } - } - } + collectConflictsBetween( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + fieldMap1, + fieldMap2, + ); // (G) Then collect conflicts between the first fragment and any nested + // fragments spread in the second fragment. - return compactQueue(queue); -}; + for (const referencedFragmentName2 of referencedFragmentNames2) { + collectConflictsBetweenFragments( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + fragmentName1, + referencedFragmentName2, + ); + } // (G) Then collect conflicts between the second fragment and any nested + // fragments spread in the first fragment. -var isRegExp = function isRegExp(obj) { - return Object.prototype.toString.call(obj) === '[object RegExp]'; -}; + for (const referencedFragmentName1 of referencedFragmentNames1) { + collectConflictsBetweenFragments( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + referencedFragmentName1, + fragmentName2, + ); + } +} // Find all conflicts found between two selection sets, including those found +// via spreading in fragments. Called when determining if conflicts exist +// between the sub-fields of two overlapping fields. -var isBuffer = function isBuffer(obj) { - if (obj === null || typeof obj === 'undefined') { - return false; - } +function findConflictsBetweenSubSelectionSets( + context, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + parentType1, + selectionSet1, + parentType2, + selectionSet2, +) { + const conflicts = []; + const [fieldMap1, fragmentNames1] = getFieldsAndFragmentNames( + context, + cachedFieldsAndFragmentNames, + parentType1, + selectionSet1, + ); + const [fieldMap2, fragmentNames2] = getFieldsAndFragmentNames( + context, + cachedFieldsAndFragmentNames, + parentType2, + selectionSet2, + ); // (H) First, collect all conflicts between these two collections of field. - return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); -}; + collectConflictsBetween( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + fieldMap1, + fieldMap2, + ); // (I) Then collect conflicts between the first collection of fields and + // those referenced by each fragment name associated with the second. -module.exports = { - arrayToObject: arrayToObject, - assign: assign, - compact: compact, - decode: decode, - encode: encode, - isBuffer: isBuffer, - isRegExp: isRegExp, - merge: merge -}; + for (const fragmentName2 of fragmentNames2) { + collectConflictsBetweenFieldsAndFragment( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + fieldMap1, + fragmentName2, + ); + } // (I) Then collect conflicts between the second collection of fields and + // those referenced by each fragment name associated with the first. + for (const fragmentName1 of fragmentNames1) { + collectConflictsBetweenFieldsAndFragment( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + fieldMap2, + fragmentName1, + ); + } // (J) Also collect conflicts between any fragment names by the first and + // fragment names by the second. This compares each item in the first set of + // names to each item in the second set of names. -/***/ }), + for (const fragmentName1 of fragmentNames1) { + for (const fragmentName2 of fragmentNames2) { + collectConflictsBetweenFragments( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + fragmentName1, + fragmentName2, + ); + } + } -/***/ 49273: -/***/ ((module) => { + return conflicts; +} // Collect all Conflicts "within" one collection of fields. -"use strict"; +function collectConflictsWithin( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + fieldMap, +) { + // A field map is a keyed collection, where each key represents a response + // name and the value at that key is a list of all fields which provide that + // response name. For every response name, if there are multiple fields, they + // must be compared to find a potential conflict. + for (const [responseName, fields] of Object.entries(fieldMap)) { + // This compares every field in the list to every other field in this list + // (except to itself). If the list only has one item, nothing needs to + // be compared. + if (fields.length > 1) { + for (let i = 0; i < fields.length; i++) { + for (let j = i + 1; j < fields.length; j++) { + const conflict = findConflict( + context, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + false, // within one collection is never mutually exclusive + responseName, + fields[i], + fields[j], + ); + if (conflict) { + conflicts.push(conflict); + } + } + } + } + } +} // Collect all Conflicts between two collections of fields. This is similar to, +// but different from the `collectConflictsWithin` function above. This check +// assumes that `collectConflictsWithin` has already been called on each +// provided collection of fields. This is true because this validator traverses +// each individual selection set. -class QuickLRU { - constructor(options = {}) { - if (!(options.maxSize && options.maxSize > 0)) { - throw new TypeError('`maxSize` must be a number greater than 0'); - } +function collectConflictsBetween( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + parentFieldsAreMutuallyExclusive, + fieldMap1, + fieldMap2, +) { + // A field map is a keyed collection, where each key represents a response + // name and the value at that key is a list of all fields which provide that + // response name. For any response name which appears in both provided field + // maps, each field from the first field map must be compared to every field + // in the second field map to find potential conflicts. + for (const [responseName, fields1] of Object.entries(fieldMap1)) { + const fields2 = fieldMap2[responseName]; - this.maxSize = options.maxSize; - this.onEviction = options.onEviction; - this.cache = new Map(); - this.oldCache = new Map(); - this._size = 0; - } + if (fields2) { + for (const field1 of fields1) { + for (const field2 of fields2) { + const conflict = findConflict( + context, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + parentFieldsAreMutuallyExclusive, + responseName, + field1, + field2, + ); - _set(key, value) { - this.cache.set(key, value); - this._size++; + if (conflict) { + conflicts.push(conflict); + } + } + } + } + } +} // Determines if there is a conflict between two particular fields, including +// comparing their sub-fields. - if (this._size >= this.maxSize) { - this._size = 0; +function findConflict( + context, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + parentFieldsAreMutuallyExclusive, + responseName, + field1, + field2, +) { + const [parentType1, node1, def1] = field1; + const [parentType2, node2, def2] = field2; // If it is known that two fields could not possibly apply at the same + // time, due to the parent types, then it is safe to permit them to diverge + // in aliased field or arguments used as they will not present any ambiguity + // by differing. + // It is known that two parent types could never overlap if they are + // different Object types. Interface or Union types might overlap - if not + // in the current state of the schema, then perhaps in some future version, + // thus may not safely diverge. - if (typeof this.onEviction === 'function') { - for (const [key, value] of this.oldCache.entries()) { - this.onEviction(key, value); - } - } + const areMutuallyExclusive = + parentFieldsAreMutuallyExclusive || + (parentType1 !== parentType2 && + (0, _definition.isObjectType)(parentType1) && + (0, _definition.isObjectType)(parentType2)); - this.oldCache = this.cache; - this.cache = new Map(); - } - } + if (!areMutuallyExclusive) { + // Two aliases must refer to the same field. + const name1 = node1.name.value; + const name2 = node2.name.value; - get(key) { - if (this.cache.has(key)) { - return this.cache.get(key); - } + if (name1 !== name2) { + return [ + [responseName, `"${name1}" and "${name2}" are different fields`], + [node1], + [node2], + ]; + } // Two field calls must have the same arguments. - if (this.oldCache.has(key)) { - const value = this.oldCache.get(key); - this.oldCache.delete(key); - this._set(key, value); - return value; - } - } + if (!sameArguments(node1, node2)) { + return [ + [responseName, 'they have differing arguments'], + [node1], + [node2], + ]; + } + } // The return type for each field. - set(key, value) { - if (this.cache.has(key)) { - this.cache.set(key, value); - } else { - this._set(key, value); - } + const type1 = def1 === null || def1 === void 0 ? void 0 : def1.type; + const type2 = def2 === null || def2 === void 0 ? void 0 : def2.type; - return this; - } + if (type1 && type2 && doTypesConflict(type1, type2)) { + return [ + [ + responseName, + `they return conflicting types "${(0, _inspect.inspect)( + type1, + )}" and "${(0, _inspect.inspect)(type2)}"`, + ], + [node1], + [node2], + ]; + } // Collect and compare sub-fields. Use the same "visited fragment names" list + // for both collections so fields in a fragment reference are never + // compared to themselves. - has(key) { - return this.cache.has(key) || this.oldCache.has(key); - } + const selectionSet1 = node1.selectionSet; + const selectionSet2 = node2.selectionSet; - peek(key) { - if (this.cache.has(key)) { - return this.cache.get(key); - } + if (selectionSet1 && selectionSet2) { + const conflicts = findConflictsBetweenSubSelectionSets( + context, + cachedFieldsAndFragmentNames, + comparedFieldsAndFragmentPairs, + comparedFragmentPairs, + areMutuallyExclusive, + (0, _definition.getNamedType)(type1), + selectionSet1, + (0, _definition.getNamedType)(type2), + selectionSet2, + ); + return subfieldConflicts(conflicts, responseName, node1, node2); + } +} - if (this.oldCache.has(key)) { - return this.oldCache.get(key); - } - } +function sameArguments(node1, node2) { + const args1 = node1.arguments; + const args2 = node2.arguments; - delete(key) { - const deleted = this.cache.delete(key); - if (deleted) { - this._size--; - } + if (args1 === undefined || args1.length === 0) { + return args2 === undefined || args2.length === 0; + } - return this.oldCache.delete(key) || deleted; - } + if (args2 === undefined || args2.length === 0) { + return false; + } + /* c8 ignore next */ - clear() { - this.cache.clear(); - this.oldCache.clear(); - this._size = 0; - } + if (args1.length !== args2.length) { + /* c8 ignore next */ + return false; + /* c8 ignore next */ + } - * keys() { - for (const [key] of this) { - yield key; - } - } + const values2 = new Map(args2.map(({ name, value }) => [name.value, value])); + return args1.every((arg1) => { + const value1 = arg1.value; + const value2 = values2.get(arg1.name.value); - * values() { - for (const [, value] of this) { - yield value; - } - } + if (value2 === undefined) { + return false; + } - * [Symbol.iterator]() { - for (const item of this.cache) { - yield item; - } + return stringifyValue(value1) === stringifyValue(value2); + }); +} - for (const item of this.oldCache) { - const [key] = item; - if (!this.cache.has(key)) { - yield item; - } - } - } +function stringifyValue(value) { + return (0, _printer.print)((0, _sortValueNode.sortValueNode)(value)); +} // Two types conflict if both types could not apply to a value simultaneously. +// Composite types are ignored as their individual field types will be compared +// later recursively. However List and Non-Null types must match. - get size() { - let oldCacheSize = 0; - for (const key of this.oldCache.keys()) { - if (!this.cache.has(key)) { - oldCacheSize++; - } - } +function doTypesConflict(type1, type2) { + if ((0, _definition.isListType)(type1)) { + return (0, _definition.isListType)(type2) + ? doTypesConflict(type1.ofType, type2.ofType) + : true; + } - return Math.min(this._size + oldCacheSize, this.maxSize); - } -} + if ((0, _definition.isListType)(type2)) { + return true; + } -module.exports = QuickLRU; + if ((0, _definition.isNonNullType)(type1)) { + return (0, _definition.isNonNullType)(type2) + ? doTypesConflict(type1.ofType, type2.ofType) + : true; + } + if ((0, _definition.isNonNullType)(type2)) { + return true; + } -/***/ }), + if ( + (0, _definition.isLeafType)(type1) || + (0, _definition.isLeafType)(type2) + ) { + return type1 !== type2; + } -/***/ 29977: -/***/ (() => { + return false; +} // Given a selection set, return the collection of fields (a mapping of response +// name to field nodes and definitions) as well as a list of fragment names +// referenced via fragment spreads. -/*! ***************************************************************************** -Copyright (C) Microsoft. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 +function getFieldsAndFragmentNames( + context, + cachedFieldsAndFragmentNames, + parentType, + selectionSet, +) { + const cached = cachedFieldsAndFragmentNames.get(selectionSet); -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. + if (cached) { + return cached; + } -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ -var Reflect; -(function (Reflect) { - // Metadata Proposal - // https://rbuckton.github.io/reflect-metadata/ - (function (factory) { - var root = typeof global === "object" ? global : - typeof self === "object" ? self : - typeof this === "object" ? this : - Function("return this;")(); - var exporter = makeExporter(Reflect); - if (typeof root.Reflect === "undefined") { - root.Reflect = Reflect; - } - else { - exporter = makeExporter(root.Reflect, exporter); - } - factory(exporter); - function makeExporter(target, previous) { - return function (key, value) { - if (typeof target[key] !== "function") { - Object.defineProperty(target, key, { configurable: true, writable: true, value: value }); - } - if (previous) - previous(key, value); - }; - } - })(function (exporter) { - var hasOwn = Object.prototype.hasOwnProperty; - // feature test for Symbol support - var supportsSymbol = typeof Symbol === "function"; - var toPrimitiveSymbol = supportsSymbol && typeof Symbol.toPrimitive !== "undefined" ? Symbol.toPrimitive : "@@toPrimitive"; - var iteratorSymbol = supportsSymbol && typeof Symbol.iterator !== "undefined" ? Symbol.iterator : "@@iterator"; - var supportsCreate = typeof Object.create === "function"; // feature test for Object.create support - var supportsProto = { __proto__: [] } instanceof Array; // feature test for __proto__ support - var downLevel = !supportsCreate && !supportsProto; - var HashMap = { - // create an object in dictionary mode (a.k.a. "slow" mode in v8) - create: supportsCreate - ? function () { return MakeDictionary(Object.create(null)); } - : supportsProto - ? function () { return MakeDictionary({ __proto__: null }); } - : function () { return MakeDictionary({}); }, - has: downLevel - ? function (map, key) { return hasOwn.call(map, key); } - : function (map, key) { return key in map; }, - get: downLevel - ? function (map, key) { return hasOwn.call(map, key) ? map[key] : undefined; } - : function (map, key) { return map[key]; }, - }; - // Load global or shim versions of Map, Set, and WeakMap - var functionPrototype = Object.getPrototypeOf(Function); - var usePolyfill = typeof process === "object" && process.env && process.env["REFLECT_METADATA_USE_MAP_POLYFILL"] === "true"; - var _Map = !usePolyfill && typeof Map === "function" && typeof Map.prototype.entries === "function" ? Map : CreateMapPolyfill(); - var _Set = !usePolyfill && typeof Set === "function" && typeof Set.prototype.entries === "function" ? Set : CreateSetPolyfill(); - var _WeakMap = !usePolyfill && typeof WeakMap === "function" ? WeakMap : CreateWeakMapPolyfill(); - // [[Metadata]] internal slot - // https://rbuckton.github.io/reflect-metadata/#ordinary-object-internal-methods-and-internal-slots - var Metadata = new _WeakMap(); - /** - * Applies a set of decorators to a property of a target object. - * @param decorators An array of decorators. - * @param target The target object. - * @param propertyKey (Optional) The property key to decorate. - * @param attributes (Optional) The property descriptor for the target key. - * @remarks Decorators are applied in reverse order. - * @example - * - * class Example { - * // property declarations are not part of ES6, though they are valid in TypeScript: - * // static staticProperty; - * // property; - * - * constructor(p) { } - * static staticMethod(p) { } - * method(p) { } - * } - * - * // constructor - * Example = Reflect.decorate(decoratorsArray, Example); - * - * // property (on constructor) - * Reflect.decorate(decoratorsArray, Example, "staticProperty"); - * - * // property (on prototype) - * Reflect.decorate(decoratorsArray, Example.prototype, "property"); - * - * // method (on constructor) - * Object.defineProperty(Example, "staticMethod", - * Reflect.decorate(decoratorsArray, Example, "staticMethod", - * Object.getOwnPropertyDescriptor(Example, "staticMethod"))); - * - * // method (on prototype) - * Object.defineProperty(Example.prototype, "method", - * Reflect.decorate(decoratorsArray, Example.prototype, "method", - * Object.getOwnPropertyDescriptor(Example.prototype, "method"))); - * - */ - function decorate(decorators, target, propertyKey, attributes) { - if (!IsUndefined(propertyKey)) { - if (!IsArray(decorators)) - throw new TypeError(); - if (!IsObject(target)) - throw new TypeError(); - if (!IsObject(attributes) && !IsUndefined(attributes) && !IsNull(attributes)) - throw new TypeError(); - if (IsNull(attributes)) - attributes = undefined; - propertyKey = ToPropertyKey(propertyKey); - return DecorateProperty(decorators, target, propertyKey, attributes); - } - else { - if (!IsArray(decorators)) - throw new TypeError(); - if (!IsConstructor(target)) - throw new TypeError(); - return DecorateConstructor(decorators, target); - } - } - exporter("decorate", decorate); - // 4.1.2 Reflect.metadata(metadataKey, metadataValue) - // https://rbuckton.github.io/reflect-metadata/#reflect.metadata - /** - * A default metadata decorator factory that can be used on a class, class member, or parameter. - * @param metadataKey The key for the metadata entry. - * @param metadataValue The value for the metadata entry. - * @returns A decorator function. - * @remarks - * If `metadataKey` is already defined for the target and target key, the - * metadataValue for that key will be overwritten. - * @example - * - * // constructor - * @Reflect.metadata(key, value) - * class Example { - * } - * - * // property (on constructor, TypeScript only) - * class Example { - * @Reflect.metadata(key, value) - * static staticProperty; - * } - * - * // property (on prototype, TypeScript only) - * class Example { - * @Reflect.metadata(key, value) - * property; - * } - * - * // method (on constructor) - * class Example { - * @Reflect.metadata(key, value) - * static staticMethod() { } - * } - * - * // method (on prototype) - * class Example { - * @Reflect.metadata(key, value) - * method() { } - * } - * - */ - function metadata(metadataKey, metadataValue) { - function decorator(target, propertyKey) { - if (!IsObject(target)) - throw new TypeError(); - if (!IsUndefined(propertyKey) && !IsPropertyKey(propertyKey)) - throw new TypeError(); - OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey); - } - return decorator; - } - exporter("metadata", metadata); - /** - * Define a unique metadata entry on the target. - * @param metadataKey A key used to store and retrieve metadata. - * @param metadataValue A value that contains attached metadata. - * @param target The target object on which to define metadata. - * @param propertyKey (Optional) The property key for the target. - * @example - * - * class Example { - * // property declarations are not part of ES6, though they are valid in TypeScript: - * // static staticProperty; - * // property; - * - * constructor(p) { } - * static staticMethod(p) { } - * method(p) { } - * } - * - * // constructor - * Reflect.defineMetadata("custom:annotation", options, Example); - * - * // property (on constructor) - * Reflect.defineMetadata("custom:annotation", options, Example, "staticProperty"); - * - * // property (on prototype) - * Reflect.defineMetadata("custom:annotation", options, Example.prototype, "property"); - * - * // method (on constructor) - * Reflect.defineMetadata("custom:annotation", options, Example, "staticMethod"); - * - * // method (on prototype) - * Reflect.defineMetadata("custom:annotation", options, Example.prototype, "method"); - * - * // decorator factory as metadata-producing annotation. - * function MyAnnotation(options): Decorator { - * return (target, key?) => Reflect.defineMetadata("custom:annotation", options, target, key); - * } - * - */ - function defineMetadata(metadataKey, metadataValue, target, propertyKey) { - if (!IsObject(target)) - throw new TypeError(); - if (!IsUndefined(propertyKey)) - propertyKey = ToPropertyKey(propertyKey); - return OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey); - } - exporter("defineMetadata", defineMetadata); - /** - * Gets a value indicating whether the target object or its prototype chain has the provided metadata key defined. - * @param metadataKey A key used to store and retrieve metadata. - * @param target The target object on which the metadata is defined. - * @param propertyKey (Optional) The property key for the target. - * @returns `true` if the metadata key was defined on the target object or its prototype chain; otherwise, `false`. - * @example - * - * class Example { - * // property declarations are not part of ES6, though they are valid in TypeScript: - * // static staticProperty; - * // property; - * - * constructor(p) { } - * static staticMethod(p) { } - * method(p) { } - * } - * - * // constructor - * result = Reflect.hasMetadata("custom:annotation", Example); - * - * // property (on constructor) - * result = Reflect.hasMetadata("custom:annotation", Example, "staticProperty"); - * - * // property (on prototype) - * result = Reflect.hasMetadata("custom:annotation", Example.prototype, "property"); - * - * // method (on constructor) - * result = Reflect.hasMetadata("custom:annotation", Example, "staticMethod"); - * - * // method (on prototype) - * result = Reflect.hasMetadata("custom:annotation", Example.prototype, "method"); - * - */ - function hasMetadata(metadataKey, target, propertyKey) { - if (!IsObject(target)) - throw new TypeError(); - if (!IsUndefined(propertyKey)) - propertyKey = ToPropertyKey(propertyKey); - return OrdinaryHasMetadata(metadataKey, target, propertyKey); - } - exporter("hasMetadata", hasMetadata); - /** - * Gets a value indicating whether the target object has the provided metadata key defined. - * @param metadataKey A key used to store and retrieve metadata. - * @param target The target object on which the metadata is defined. - * @param propertyKey (Optional) The property key for the target. - * @returns `true` if the metadata key was defined on the target object; otherwise, `false`. - * @example - * - * class Example { - * // property declarations are not part of ES6, though they are valid in TypeScript: - * // static staticProperty; - * // property; - * - * constructor(p) { } - * static staticMethod(p) { } - * method(p) { } - * } - * - * // constructor - * result = Reflect.hasOwnMetadata("custom:annotation", Example); - * - * // property (on constructor) - * result = Reflect.hasOwnMetadata("custom:annotation", Example, "staticProperty"); - * - * // property (on prototype) - * result = Reflect.hasOwnMetadata("custom:annotation", Example.prototype, "property"); - * - * // method (on constructor) - * result = Reflect.hasOwnMetadata("custom:annotation", Example, "staticMethod"); - * - * // method (on prototype) - * result = Reflect.hasOwnMetadata("custom:annotation", Example.prototype, "method"); - * - */ - function hasOwnMetadata(metadataKey, target, propertyKey) { - if (!IsObject(target)) - throw new TypeError(); - if (!IsUndefined(propertyKey)) - propertyKey = ToPropertyKey(propertyKey); - return OrdinaryHasOwnMetadata(metadataKey, target, propertyKey); - } - exporter("hasOwnMetadata", hasOwnMetadata); - /** - * Gets the metadata value for the provided metadata key on the target object or its prototype chain. - * @param metadataKey A key used to store and retrieve metadata. - * @param target The target object on which the metadata is defined. - * @param propertyKey (Optional) The property key for the target. - * @returns The metadata value for the metadata key if found; otherwise, `undefined`. - * @example - * - * class Example { - * // property declarations are not part of ES6, though they are valid in TypeScript: - * // static staticProperty; - * // property; - * - * constructor(p) { } - * static staticMethod(p) { } - * method(p) { } - * } - * - * // constructor - * result = Reflect.getMetadata("custom:annotation", Example); - * - * // property (on constructor) - * result = Reflect.getMetadata("custom:annotation", Example, "staticProperty"); - * - * // property (on prototype) - * result = Reflect.getMetadata("custom:annotation", Example.prototype, "property"); - * - * // method (on constructor) - * result = Reflect.getMetadata("custom:annotation", Example, "staticMethod"); - * - * // method (on prototype) - * result = Reflect.getMetadata("custom:annotation", Example.prototype, "method"); - * - */ - function getMetadata(metadataKey, target, propertyKey) { - if (!IsObject(target)) - throw new TypeError(); - if (!IsUndefined(propertyKey)) - propertyKey = ToPropertyKey(propertyKey); - return OrdinaryGetMetadata(metadataKey, target, propertyKey); - } - exporter("getMetadata", getMetadata); - /** - * Gets the metadata value for the provided metadata key on the target object. - * @param metadataKey A key used to store and retrieve metadata. - * @param target The target object on which the metadata is defined. - * @param propertyKey (Optional) The property key for the target. - * @returns The metadata value for the metadata key if found; otherwise, `undefined`. - * @example - * - * class Example { - * // property declarations are not part of ES6, though they are valid in TypeScript: - * // static staticProperty; - * // property; - * - * constructor(p) { } - * static staticMethod(p) { } - * method(p) { } - * } - * - * // constructor - * result = Reflect.getOwnMetadata("custom:annotation", Example); - * - * // property (on constructor) - * result = Reflect.getOwnMetadata("custom:annotation", Example, "staticProperty"); - * - * // property (on prototype) - * result = Reflect.getOwnMetadata("custom:annotation", Example.prototype, "property"); - * - * // method (on constructor) - * result = Reflect.getOwnMetadata("custom:annotation", Example, "staticMethod"); - * - * // method (on prototype) - * result = Reflect.getOwnMetadata("custom:annotation", Example.prototype, "method"); - * - */ - function getOwnMetadata(metadataKey, target, propertyKey) { - if (!IsObject(target)) - throw new TypeError(); - if (!IsUndefined(propertyKey)) - propertyKey = ToPropertyKey(propertyKey); - return OrdinaryGetOwnMetadata(metadataKey, target, propertyKey); - } - exporter("getOwnMetadata", getOwnMetadata); - /** - * Gets the metadata keys defined on the target object or its prototype chain. - * @param target The target object on which the metadata is defined. - * @param propertyKey (Optional) The property key for the target. - * @returns An array of unique metadata keys. - * @example - * - * class Example { - * // property declarations are not part of ES6, though they are valid in TypeScript: - * // static staticProperty; - * // property; - * - * constructor(p) { } - * static staticMethod(p) { } - * method(p) { } - * } - * - * // constructor - * result = Reflect.getMetadataKeys(Example); - * - * // property (on constructor) - * result = Reflect.getMetadataKeys(Example, "staticProperty"); - * - * // property (on prototype) - * result = Reflect.getMetadataKeys(Example.prototype, "property"); - * - * // method (on constructor) - * result = Reflect.getMetadataKeys(Example, "staticMethod"); - * - * // method (on prototype) - * result = Reflect.getMetadataKeys(Example.prototype, "method"); - * - */ - function getMetadataKeys(target, propertyKey) { - if (!IsObject(target)) - throw new TypeError(); - if (!IsUndefined(propertyKey)) - propertyKey = ToPropertyKey(propertyKey); - return OrdinaryMetadataKeys(target, propertyKey); - } - exporter("getMetadataKeys", getMetadataKeys); - /** - * Gets the unique metadata keys defined on the target object. - * @param target The target object on which the metadata is defined. - * @param propertyKey (Optional) The property key for the target. - * @returns An array of unique metadata keys. - * @example - * - * class Example { - * // property declarations are not part of ES6, though they are valid in TypeScript: - * // static staticProperty; - * // property; - * - * constructor(p) { } - * static staticMethod(p) { } - * method(p) { } - * } - * - * // constructor - * result = Reflect.getOwnMetadataKeys(Example); - * - * // property (on constructor) - * result = Reflect.getOwnMetadataKeys(Example, "staticProperty"); - * - * // property (on prototype) - * result = Reflect.getOwnMetadataKeys(Example.prototype, "property"); - * - * // method (on constructor) - * result = Reflect.getOwnMetadataKeys(Example, "staticMethod"); - * - * // method (on prototype) - * result = Reflect.getOwnMetadataKeys(Example.prototype, "method"); - * - */ - function getOwnMetadataKeys(target, propertyKey) { - if (!IsObject(target)) - throw new TypeError(); - if (!IsUndefined(propertyKey)) - propertyKey = ToPropertyKey(propertyKey); - return OrdinaryOwnMetadataKeys(target, propertyKey); - } - exporter("getOwnMetadataKeys", getOwnMetadataKeys); - /** - * Deletes the metadata entry from the target object with the provided key. - * @param metadataKey A key used to store and retrieve metadata. - * @param target The target object on which the metadata is defined. - * @param propertyKey (Optional) The property key for the target. - * @returns `true` if the metadata entry was found and deleted; otherwise, false. - * @example - * - * class Example { - * // property declarations are not part of ES6, though they are valid in TypeScript: - * // static staticProperty; - * // property; - * - * constructor(p) { } - * static staticMethod(p) { } - * method(p) { } - * } - * - * // constructor - * result = Reflect.deleteMetadata("custom:annotation", Example); - * - * // property (on constructor) - * result = Reflect.deleteMetadata("custom:annotation", Example, "staticProperty"); - * - * // property (on prototype) - * result = Reflect.deleteMetadata("custom:annotation", Example.prototype, "property"); - * - * // method (on constructor) - * result = Reflect.deleteMetadata("custom:annotation", Example, "staticMethod"); - * - * // method (on prototype) - * result = Reflect.deleteMetadata("custom:annotation", Example.prototype, "method"); - * - */ - function deleteMetadata(metadataKey, target, propertyKey) { - if (!IsObject(target)) - throw new TypeError(); - if (!IsUndefined(propertyKey)) - propertyKey = ToPropertyKey(propertyKey); - var metadataMap = GetOrCreateMetadataMap(target, propertyKey, /*Create*/ false); - if (IsUndefined(metadataMap)) - return false; - if (!metadataMap.delete(metadataKey)) - return false; - if (metadataMap.size > 0) - return true; - var targetMetadata = Metadata.get(target); - targetMetadata.delete(propertyKey); - if (targetMetadata.size > 0) - return true; - Metadata.delete(target); - return true; - } - exporter("deleteMetadata", deleteMetadata); - function DecorateConstructor(decorators, target) { - for (var i = decorators.length - 1; i >= 0; --i) { - var decorator = decorators[i]; - var decorated = decorator(target); - if (!IsUndefined(decorated) && !IsNull(decorated)) { - if (!IsConstructor(decorated)) - throw new TypeError(); - target = decorated; - } - } - return target; - } - function DecorateProperty(decorators, target, propertyKey, descriptor) { - for (var i = decorators.length - 1; i >= 0; --i) { - var decorator = decorators[i]; - var decorated = decorator(target, propertyKey, descriptor); - if (!IsUndefined(decorated) && !IsNull(decorated)) { - if (!IsObject(decorated)) - throw new TypeError(); - descriptor = decorated; - } - } - return descriptor; - } - function GetOrCreateMetadataMap(O, P, Create) { - var targetMetadata = Metadata.get(O); - if (IsUndefined(targetMetadata)) { - if (!Create) - return undefined; - targetMetadata = new _Map(); - Metadata.set(O, targetMetadata); - } - var metadataMap = targetMetadata.get(P); - if (IsUndefined(metadataMap)) { - if (!Create) - return undefined; - metadataMap = new _Map(); - targetMetadata.set(P, metadataMap); - } - return metadataMap; - } - // 3.1.1.1 OrdinaryHasMetadata(MetadataKey, O, P) - // https://rbuckton.github.io/reflect-metadata/#ordinaryhasmetadata - function OrdinaryHasMetadata(MetadataKey, O, P) { - var hasOwn = OrdinaryHasOwnMetadata(MetadataKey, O, P); - if (hasOwn) - return true; - var parent = OrdinaryGetPrototypeOf(O); - if (!IsNull(parent)) - return OrdinaryHasMetadata(MetadataKey, parent, P); - return false; - } - // 3.1.2.1 OrdinaryHasOwnMetadata(MetadataKey, O, P) - // https://rbuckton.github.io/reflect-metadata/#ordinaryhasownmetadata - function OrdinaryHasOwnMetadata(MetadataKey, O, P) { - var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false); - if (IsUndefined(metadataMap)) - return false; - return ToBoolean(metadataMap.has(MetadataKey)); - } - // 3.1.3.1 OrdinaryGetMetadata(MetadataKey, O, P) - // https://rbuckton.github.io/reflect-metadata/#ordinarygetmetadata - function OrdinaryGetMetadata(MetadataKey, O, P) { - var hasOwn = OrdinaryHasOwnMetadata(MetadataKey, O, P); - if (hasOwn) - return OrdinaryGetOwnMetadata(MetadataKey, O, P); - var parent = OrdinaryGetPrototypeOf(O); - if (!IsNull(parent)) - return OrdinaryGetMetadata(MetadataKey, parent, P); - return undefined; - } - // 3.1.4.1 OrdinaryGetOwnMetadata(MetadataKey, O, P) - // https://rbuckton.github.io/reflect-metadata/#ordinarygetownmetadata - function OrdinaryGetOwnMetadata(MetadataKey, O, P) { - var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false); - if (IsUndefined(metadataMap)) - return undefined; - return metadataMap.get(MetadataKey); - } - // 3.1.5.1 OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P) - // https://rbuckton.github.io/reflect-metadata/#ordinarydefineownmetadata - function OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P) { - var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ true); - metadataMap.set(MetadataKey, MetadataValue); - } - // 3.1.6.1 OrdinaryMetadataKeys(O, P) - // https://rbuckton.github.io/reflect-metadata/#ordinarymetadatakeys - function OrdinaryMetadataKeys(O, P) { - var ownKeys = OrdinaryOwnMetadataKeys(O, P); - var parent = OrdinaryGetPrototypeOf(O); - if (parent === null) - return ownKeys; - var parentKeys = OrdinaryMetadataKeys(parent, P); - if (parentKeys.length <= 0) - return ownKeys; - if (ownKeys.length <= 0) - return parentKeys; - var set = new _Set(); - var keys = []; - for (var _i = 0, ownKeys_1 = ownKeys; _i < ownKeys_1.length; _i++) { - var key = ownKeys_1[_i]; - var hasKey = set.has(key); - if (!hasKey) { - set.add(key); - keys.push(key); - } - } - for (var _a = 0, parentKeys_1 = parentKeys; _a < parentKeys_1.length; _a++) { - var key = parentKeys_1[_a]; - var hasKey = set.has(key); - if (!hasKey) { - set.add(key); - keys.push(key); - } - } - return keys; - } - // 3.1.7.1 OrdinaryOwnMetadataKeys(O, P) - // https://rbuckton.github.io/reflect-metadata/#ordinaryownmetadatakeys - function OrdinaryOwnMetadataKeys(O, P) { - var keys = []; - var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false); - if (IsUndefined(metadataMap)) - return keys; - var keysObj = metadataMap.keys(); - var iterator = GetIterator(keysObj); - var k = 0; - while (true) { - var next = IteratorStep(iterator); - if (!next) { - keys.length = k; - return keys; - } - var nextValue = IteratorValue(next); - try { - keys[k] = nextValue; - } - catch (e) { - try { - IteratorClose(iterator); - } - finally { - throw e; - } - } - k++; - } - } - // 6 ECMAScript Data Typ0es and Values - // https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values - function Type(x) { - if (x === null) - return 1 /* Null */; - switch (typeof x) { - case "undefined": return 0 /* Undefined */; - case "boolean": return 2 /* Boolean */; - case "string": return 3 /* String */; - case "symbol": return 4 /* Symbol */; - case "number": return 5 /* Number */; - case "object": return x === null ? 1 /* Null */ : 6 /* Object */; - default: return 6 /* Object */; - } - } - // 6.1.1 The Undefined Type - // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-undefined-type - function IsUndefined(x) { - return x === undefined; - } - // 6.1.2 The Null Type - // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-null-type - function IsNull(x) { - return x === null; - } - // 6.1.5 The Symbol Type - // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-symbol-type - function IsSymbol(x) { - return typeof x === "symbol"; - } - // 6.1.7 The Object Type - // https://tc39.github.io/ecma262/#sec-object-type - function IsObject(x) { - return typeof x === "object" ? x !== null : typeof x === "function"; - } - // 7.1 Type Conversion - // https://tc39.github.io/ecma262/#sec-type-conversion - // 7.1.1 ToPrimitive(input [, PreferredType]) - // https://tc39.github.io/ecma262/#sec-toprimitive - function ToPrimitive(input, PreferredType) { - switch (Type(input)) { - case 0 /* Undefined */: return input; - case 1 /* Null */: return input; - case 2 /* Boolean */: return input; - case 3 /* String */: return input; - case 4 /* Symbol */: return input; - case 5 /* Number */: return input; - } - var hint = PreferredType === 3 /* String */ ? "string" : PreferredType === 5 /* Number */ ? "number" : "default"; - var exoticToPrim = GetMethod(input, toPrimitiveSymbol); - if (exoticToPrim !== undefined) { - var result = exoticToPrim.call(input, hint); - if (IsObject(result)) - throw new TypeError(); - return result; - } - return OrdinaryToPrimitive(input, hint === "default" ? "number" : hint); - } - // 7.1.1.1 OrdinaryToPrimitive(O, hint) - // https://tc39.github.io/ecma262/#sec-ordinarytoprimitive - function OrdinaryToPrimitive(O, hint) { - if (hint === "string") { - var toString_1 = O.toString; - if (IsCallable(toString_1)) { - var result = toString_1.call(O); - if (!IsObject(result)) - return result; - } - var valueOf = O.valueOf; - if (IsCallable(valueOf)) { - var result = valueOf.call(O); - if (!IsObject(result)) - return result; - } - } - else { - var valueOf = O.valueOf; - if (IsCallable(valueOf)) { - var result = valueOf.call(O); - if (!IsObject(result)) - return result; - } - var toString_2 = O.toString; - if (IsCallable(toString_2)) { - var result = toString_2.call(O); - if (!IsObject(result)) - return result; - } - } - throw new TypeError(); - } - // 7.1.2 ToBoolean(argument) - // https://tc39.github.io/ecma262/2016/#sec-toboolean - function ToBoolean(argument) { - return !!argument; - } - // 7.1.12 ToString(argument) - // https://tc39.github.io/ecma262/#sec-tostring - function ToString(argument) { - return "" + argument; - } - // 7.1.14 ToPropertyKey(argument) - // https://tc39.github.io/ecma262/#sec-topropertykey - function ToPropertyKey(argument) { - var key = ToPrimitive(argument, 3 /* String */); - if (IsSymbol(key)) - return key; - return ToString(key); - } - // 7.2 Testing and Comparison Operations - // https://tc39.github.io/ecma262/#sec-testing-and-comparison-operations - // 7.2.2 IsArray(argument) - // https://tc39.github.io/ecma262/#sec-isarray - function IsArray(argument) { - return Array.isArray - ? Array.isArray(argument) - : argument instanceof Object - ? argument instanceof Array - : Object.prototype.toString.call(argument) === "[object Array]"; - } - // 7.2.3 IsCallable(argument) - // https://tc39.github.io/ecma262/#sec-iscallable - function IsCallable(argument) { - // NOTE: This is an approximation as we cannot check for [[Call]] internal method. - return typeof argument === "function"; - } - // 7.2.4 IsConstructor(argument) - // https://tc39.github.io/ecma262/#sec-isconstructor - function IsConstructor(argument) { - // NOTE: This is an approximation as we cannot check for [[Construct]] internal method. - return typeof argument === "function"; - } - // 7.2.7 IsPropertyKey(argument) - // https://tc39.github.io/ecma262/#sec-ispropertykey - function IsPropertyKey(argument) { - switch (Type(argument)) { - case 3 /* String */: return true; - case 4 /* Symbol */: return true; - default: return false; - } - } - // 7.3 Operations on Objects - // https://tc39.github.io/ecma262/#sec-operations-on-objects - // 7.3.9 GetMethod(V, P) - // https://tc39.github.io/ecma262/#sec-getmethod - function GetMethod(V, P) { - var func = V[P]; - if (func === undefined || func === null) - return undefined; - if (!IsCallable(func)) - throw new TypeError(); - return func; - } - // 7.4 Operations on Iterator Objects - // https://tc39.github.io/ecma262/#sec-operations-on-iterator-objects - function GetIterator(obj) { - var method = GetMethod(obj, iteratorSymbol); - if (!IsCallable(method)) - throw new TypeError(); // from Call - var iterator = method.call(obj); - if (!IsObject(iterator)) - throw new TypeError(); - return iterator; - } - // 7.4.4 IteratorValue(iterResult) - // https://tc39.github.io/ecma262/2016/#sec-iteratorvalue - function IteratorValue(iterResult) { - return iterResult.value; - } - // 7.4.5 IteratorStep(iterator) - // https://tc39.github.io/ecma262/#sec-iteratorstep - function IteratorStep(iterator) { - var result = iterator.next(); - return result.done ? false : result; - } - // 7.4.6 IteratorClose(iterator, completion) - // https://tc39.github.io/ecma262/#sec-iteratorclose - function IteratorClose(iterator) { - var f = iterator["return"]; - if (f) - f.call(iterator); - } - // 9.1 Ordinary Object Internal Methods and Internal Slots - // https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots - // 9.1.1.1 OrdinaryGetPrototypeOf(O) - // https://tc39.github.io/ecma262/#sec-ordinarygetprototypeof - function OrdinaryGetPrototypeOf(O) { - var proto = Object.getPrototypeOf(O); - if (typeof O !== "function" || O === functionPrototype) - return proto; - // TypeScript doesn't set __proto__ in ES5, as it's non-standard. - // Try to determine the superclass constructor. Compatible implementations - // must either set __proto__ on a subclass constructor to the superclass constructor, - // or ensure each class has a valid `constructor` property on its prototype that - // points back to the constructor. - // If this is not the same as Function.[[Prototype]], then this is definately inherited. - // This is the case when in ES6 or when using __proto__ in a compatible browser. - if (proto !== functionPrototype) - return proto; - // If the super prototype is Object.prototype, null, or undefined, then we cannot determine the heritage. - var prototype = O.prototype; - var prototypeProto = prototype && Object.getPrototypeOf(prototype); - if (prototypeProto == null || prototypeProto === Object.prototype) - return proto; - // If the constructor was not a function, then we cannot determine the heritage. - var constructor = prototypeProto.constructor; - if (typeof constructor !== "function") - return proto; - // If we have some kind of self-reference, then we cannot determine the heritage. - if (constructor === O) - return proto; - // we have a pretty good guess at the heritage. - return constructor; - } - // naive Map shim - function CreateMapPolyfill() { - var cacheSentinel = {}; - var arraySentinel = []; - var MapIterator = /** @class */ (function () { - function MapIterator(keys, values, selector) { - this._index = 0; - this._keys = keys; - this._values = values; - this._selector = selector; - } - MapIterator.prototype["@@iterator"] = function () { return this; }; - MapIterator.prototype[iteratorSymbol] = function () { return this; }; - MapIterator.prototype.next = function () { - var index = this._index; - if (index >= 0 && index < this._keys.length) { - var result = this._selector(this._keys[index], this._values[index]); - if (index + 1 >= this._keys.length) { - this._index = -1; - this._keys = arraySentinel; - this._values = arraySentinel; - } - else { - this._index++; - } - return { value: result, done: false }; - } - return { value: undefined, done: true }; - }; - MapIterator.prototype.throw = function (error) { - if (this._index >= 0) { - this._index = -1; - this._keys = arraySentinel; - this._values = arraySentinel; - } - throw error; - }; - MapIterator.prototype.return = function (value) { - if (this._index >= 0) { - this._index = -1; - this._keys = arraySentinel; - this._values = arraySentinel; - } - return { value: value, done: true }; - }; - return MapIterator; - }()); - return /** @class */ (function () { - function Map() { - this._keys = []; - this._values = []; - this._cacheKey = cacheSentinel; - this._cacheIndex = -2; - } - Object.defineProperty(Map.prototype, "size", { - get: function () { return this._keys.length; }, - enumerable: true, - configurable: true - }); - Map.prototype.has = function (key) { return this._find(key, /*insert*/ false) >= 0; }; - Map.prototype.get = function (key) { - var index = this._find(key, /*insert*/ false); - return index >= 0 ? this._values[index] : undefined; - }; - Map.prototype.set = function (key, value) { - var index = this._find(key, /*insert*/ true); - this._values[index] = value; - return this; - }; - Map.prototype.delete = function (key) { - var index = this._find(key, /*insert*/ false); - if (index >= 0) { - var size = this._keys.length; - for (var i = index + 1; i < size; i++) { - this._keys[i - 1] = this._keys[i]; - this._values[i - 1] = this._values[i]; - } - this._keys.length--; - this._values.length--; - if (key === this._cacheKey) { - this._cacheKey = cacheSentinel; - this._cacheIndex = -2; - } - return true; - } - return false; - }; - Map.prototype.clear = function () { - this._keys.length = 0; - this._values.length = 0; - this._cacheKey = cacheSentinel; - this._cacheIndex = -2; - }; - Map.prototype.keys = function () { return new MapIterator(this._keys, this._values, getKey); }; - Map.prototype.values = function () { return new MapIterator(this._keys, this._values, getValue); }; - Map.prototype.entries = function () { return new MapIterator(this._keys, this._values, getEntry); }; - Map.prototype["@@iterator"] = function () { return this.entries(); }; - Map.prototype[iteratorSymbol] = function () { return this.entries(); }; - Map.prototype._find = function (key, insert) { - if (this._cacheKey !== key) { - this._cacheIndex = this._keys.indexOf(this._cacheKey = key); - } - if (this._cacheIndex < 0 && insert) { - this._cacheIndex = this._keys.length; - this._keys.push(key); - this._values.push(undefined); - } - return this._cacheIndex; - }; - return Map; - }()); - function getKey(key, _) { - return key; - } - function getValue(_, value) { - return value; - } - function getEntry(key, value) { - return [key, value]; - } - } - // naive Set shim - function CreateSetPolyfill() { - return /** @class */ (function () { - function Set() { - this._map = new _Map(); - } - Object.defineProperty(Set.prototype, "size", { - get: function () { return this._map.size; }, - enumerable: true, - configurable: true - }); - Set.prototype.has = function (value) { return this._map.has(value); }; - Set.prototype.add = function (value) { return this._map.set(value, value), this; }; - Set.prototype.delete = function (value) { return this._map.delete(value); }; - Set.prototype.clear = function () { this._map.clear(); }; - Set.prototype.keys = function () { return this._map.keys(); }; - Set.prototype.values = function () { return this._map.values(); }; - Set.prototype.entries = function () { return this._map.entries(); }; - Set.prototype["@@iterator"] = function () { return this.keys(); }; - Set.prototype[iteratorSymbol] = function () { return this.keys(); }; - return Set; - }()); - } - // naive WeakMap shim - function CreateWeakMapPolyfill() { - var UUID_SIZE = 16; - var keys = HashMap.create(); - var rootKey = CreateUniqueKey(); - return /** @class */ (function () { - function WeakMap() { - this._key = CreateUniqueKey(); - } - WeakMap.prototype.has = function (target) { - var table = GetOrCreateWeakMapTable(target, /*create*/ false); - return table !== undefined ? HashMap.has(table, this._key) : false; - }; - WeakMap.prototype.get = function (target) { - var table = GetOrCreateWeakMapTable(target, /*create*/ false); - return table !== undefined ? HashMap.get(table, this._key) : undefined; - }; - WeakMap.prototype.set = function (target, value) { - var table = GetOrCreateWeakMapTable(target, /*create*/ true); - table[this._key] = value; - return this; - }; - WeakMap.prototype.delete = function (target) { - var table = GetOrCreateWeakMapTable(target, /*create*/ false); - return table !== undefined ? delete table[this._key] : false; - }; - WeakMap.prototype.clear = function () { - // NOTE: not a real clear, just makes the previous data unreachable - this._key = CreateUniqueKey(); - }; - return WeakMap; - }()); - function CreateUniqueKey() { - var key; - do - key = "@@WeakMap@@" + CreateUUID(); - while (HashMap.has(keys, key)); - keys[key] = true; - return key; - } - function GetOrCreateWeakMapTable(target, create) { - if (!hasOwn.call(target, rootKey)) { - if (!create) - return undefined; - Object.defineProperty(target, rootKey, { value: HashMap.create() }); - } - return target[rootKey]; - } - function FillRandomBytes(buffer, size) { - for (var i = 0; i < size; ++i) - buffer[i] = Math.random() * 0xff | 0; - return buffer; - } - function GenRandomBytes(size) { - if (typeof Uint8Array === "function") { - if (typeof crypto !== "undefined") - return crypto.getRandomValues(new Uint8Array(size)); - if (typeof msCrypto !== "undefined") - return msCrypto.getRandomValues(new Uint8Array(size)); - return FillRandomBytes(new Uint8Array(size), size); - } - return FillRandomBytes(new Array(size), size); - } - function CreateUUID() { - var data = GenRandomBytes(UUID_SIZE); - // mark as random - RFC 4122 § 4.4 - data[6] = data[6] & 0x4f | 0x40; - data[8] = data[8] & 0xbf | 0x80; - var result = ""; - for (var offset = 0; offset < UUID_SIZE; ++offset) { - var byte = data[offset]; - if (offset === 4 || offset === 6 || offset === 8) - result += "-"; - if (byte < 16) - result += "0"; - result += byte.toString(16).toLowerCase(); - } - return result; - } - } - // uses a heuristic used by v8 and chakra to force an object into dictionary mode. - function MakeDictionary(obj) { - obj.__ = undefined; - delete obj.__; - return obj; - } - }); -})(Reflect || (Reflect = {})); + const nodeAndDefs = Object.create(null); + const fragmentNames = Object.create(null); + _collectFieldsAndFragmentNames( + context, + parentType, + selectionSet, + nodeAndDefs, + fragmentNames, + ); -/***/ }), + const result = [nodeAndDefs, Object.keys(fragmentNames)]; + cachedFieldsAndFragmentNames.set(selectionSet, result); + return result; +} // Given a reference to a fragment, return the represented collection of fields +// as well as a list of nested fragment names referenced via fragment spreads. -/***/ 48699: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function getReferencedFieldsAndFragmentNames( + context, + cachedFieldsAndFragmentNames, + fragment, +) { + // Short-circuit building a type from the node if possible. + const cached = cachedFieldsAndFragmentNames.get(fragment.selectionSet); -"use strict"; -// Copyright 2010-2012 Mikeal Rogers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. + if (cached) { + return cached; + } + const fragmentType = (0, _typeFromAST.typeFromAST)( + context.getSchema(), + fragment.typeCondition, + ); + return getFieldsAndFragmentNames( + context, + cachedFieldsAndFragmentNames, + fragmentType, + fragment.selectionSet, + ); +} +function _collectFieldsAndFragmentNames( + context, + parentType, + selectionSet, + nodeAndDefs, + fragmentNames, +) { + for (const selection of selectionSet.selections) { + switch (selection.kind) { + case _kinds.Kind.FIELD: { + const fieldName = selection.name.value; + let fieldDef; -var extend = __nccwpck_require__(38171) -var cookies = __nccwpck_require__(50976) -var helpers = __nccwpck_require__(74845) + if ( + (0, _definition.isObjectType)(parentType) || + (0, _definition.isInterfaceType)(parentType) + ) { + fieldDef = parentType.getFields()[fieldName]; + } -var paramsHaveRequestBody = helpers.paramsHaveRequestBody + const responseName = selection.alias + ? selection.alias.value + : fieldName; -// organize params for patch, post, put, head, del -function initParams (uri, options, callback) { - if (typeof options === 'function') { - callback = options - } + if (!nodeAndDefs[responseName]) { + nodeAndDefs[responseName] = []; + } - var params = {} - if (options !== null && typeof options === 'object') { - extend(params, options, {uri: uri}) - } else if (typeof uri === 'string') { - extend(params, {uri: uri}) - } else { - extend(params, uri) + nodeAndDefs[responseName].push([parentType, selection, fieldDef]); + break; + } + + case _kinds.Kind.FRAGMENT_SPREAD: + fragmentNames[selection.name.value] = true; + break; + + case _kinds.Kind.INLINE_FRAGMENT: { + const typeCondition = selection.typeCondition; + const inlineFragmentType = typeCondition + ? (0, _typeFromAST.typeFromAST)(context.getSchema(), typeCondition) + : parentType; + + _collectFieldsAndFragmentNames( + context, + inlineFragmentType, + selection.selectionSet, + nodeAndDefs, + fragmentNames, + ); + + break; + } + } } +} // Given a series of Conflicts which occurred between two sub-fields, generate +// a single Conflict. - params.callback = callback || params.callback - return params +function subfieldConflicts(conflicts, responseName, node1, node2) { + if (conflicts.length > 0) { + return [ + [responseName, conflicts.map(([reason]) => reason)], + [node1, ...conflicts.map(([, fields1]) => fields1).flat()], + [node2, ...conflicts.map(([, , fields2]) => fields2).flat()], + ]; + } } +/** + * A way to keep track of pairs of things where the ordering of the pair + * matters. + * + * Provides a third argument for has/set to allow flagging the pair as + * weakly or strongly present within the collection. + */ -function request (uri, options, callback) { - if (typeof uri === 'undefined') { - throw new Error('undefined is not a valid uri or options object.') +class OrderedPairSet { + constructor() { + this._data = new Map(); } - var params = initParams(uri, options, callback) + has(a, b, weaklyPresent) { + var _this$_data$get; + + const result = + (_this$_data$get = this._data.get(a)) === null || + _this$_data$get === void 0 + ? void 0 + : _this$_data$get.get(b); - if (params.method === 'HEAD' && paramsHaveRequestBody(params)) { - throw new Error('HTTP HEAD requests MUST NOT include a request body.') + if (result === undefined) { + return false; + } + + return weaklyPresent ? true : weaklyPresent === result; } - return new request.Request(params) -} + add(a, b, weaklyPresent) { + const map = this._data.get(a); -function verbFunc (verb) { - var method = verb.toUpperCase() - return function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.method = method - return request(params, params.callback) + if (map === undefined) { + this._data.set(a, new Map([[b, weaklyPresent]])); + } else { + map.set(b, weaklyPresent); + } } } +/** + * A way to keep track of pairs of similar things when the ordering of the pair + * does not matter. + */ -// define like this to please codeintel/intellisense IDEs -request.get = verbFunc('get') -request.head = verbFunc('head') -request.options = verbFunc('options') -request.post = verbFunc('post') -request.put = verbFunc('put') -request.patch = verbFunc('patch') -request.del = verbFunc('delete') -request['delete'] = verbFunc('delete') +class PairSet { + constructor() { + this._orderedPairSet = new OrderedPairSet(); + } -request.jar = function (store) { - return cookies.jar(store) -} + has(a, b, weaklyPresent) { + return a < b + ? this._orderedPairSet.has(a, b, weaklyPresent) + : this._orderedPairSet.has(b, a, weaklyPresent); + } -request.cookie = function (str) { - return cookies.parse(str) + add(a, b, weaklyPresent) { + if (a < b) { + this._orderedPairSet.add(a, b, weaklyPresent); + } else { + this._orderedPairSet.add(b, a, weaklyPresent); + } + } } -function wrapRequestMethod (method, options, requester, verb) { - return function (uri, opts, callback) { - var params = initParams(uri, opts, callback) - var target = {} - extend(true, target, options, params) +/***/ }), - target.pool = params.pool || options.pool +/***/ 62450: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (verb) { - target.method = verb.toUpperCase() - } +"use strict"; - if (typeof requester === 'function') { - method = requester - } - return method(target, target.callback) - } -} +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.PossibleFragmentSpreadsRule = PossibleFragmentSpreadsRule; -request.defaults = function (options, requester) { - var self = this +var _inspect = __nccwpck_require__(10102); - options = options || {} +var _GraphQLError = __nccwpck_require__(4797); - if (typeof options === 'function') { - requester = options - options = {} - } +var _definition = __nccwpck_require__(5821); - var defaults = wrapRequestMethod(self, options, requester) +var _typeComparators = __nccwpck_require__(10333); - var verbs = ['get', 'head', 'post', 'put', 'patch', 'del', 'delete'] - verbs.forEach(function (verb) { - defaults[verb] = wrapRequestMethod(self[verb], options, requester, verb) - }) +var _typeFromAST = __nccwpck_require__(27664); - defaults.cookie = wrapRequestMethod(self.cookie, options, requester) - defaults.jar = self.jar - defaults.defaults = self.defaults - return defaults -} +/** + * Possible fragment spread + * + * A fragment spread is only valid if the type condition could ever possibly + * be true: if there is a non-empty intersection of the possible parent types, + * and possible types which pass the type condition. + */ +function PossibleFragmentSpreadsRule(context) { + return { + InlineFragment(node) { + const fragType = context.getType(); + const parentType = context.getParentType(); -request.forever = function (agentOptions, optionsArg) { - var options = {} - if (optionsArg) { - extend(options, optionsArg) - } - if (agentOptions) { - options.agentOptions = agentOptions - } + if ( + (0, _definition.isCompositeType)(fragType) && + (0, _definition.isCompositeType)(parentType) && + !(0, _typeComparators.doTypesOverlap)( + context.getSchema(), + fragType, + parentType, + ) + ) { + const parentTypeStr = (0, _inspect.inspect)(parentType); + const fragTypeStr = (0, _inspect.inspect)(fragType); + context.reportError( + new _GraphQLError.GraphQLError( + `Fragment cannot be spread here as objects of type "${parentTypeStr}" can never be of type "${fragTypeStr}".`, + { + nodes: node, + }, + ), + ); + } + }, + + FragmentSpread(node) { + const fragName = node.name.value; + const fragType = getFragmentType(context, fragName); + const parentType = context.getParentType(); - options.forever = true - return request.defaults(options) + if ( + fragType && + parentType && + !(0, _typeComparators.doTypesOverlap)( + context.getSchema(), + fragType, + parentType, + ) + ) { + const parentTypeStr = (0, _inspect.inspect)(parentType); + const fragTypeStr = (0, _inspect.inspect)(fragType); + context.reportError( + new _GraphQLError.GraphQLError( + `Fragment "${fragName}" cannot be spread here as objects of type "${parentTypeStr}" can never be of type "${fragTypeStr}".`, + { + nodes: node, + }, + ), + ); + } + }, + }; } -// Exports +function getFragmentType(context, name) { + const frag = context.getFragment(name); -module.exports = request -request.Request = __nccwpck_require__(70304) -request.initParams = initParams + if (frag) { + const type = (0, _typeFromAST.typeFromAST)( + context.getSchema(), + frag.typeCondition, + ); -// Backwards compatibility for request.debug -Object.defineProperty(request, 'debug', { - enumerable: true, - get: function () { - return request.Request.debug - }, - set: function (debug) { - request.Request.debug = debug + if ((0, _definition.isCompositeType)(type)) { + return type; + } } -}) +} /***/ }), -/***/ 76996: +/***/ 70075: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var caseless = __nccwpck_require__(35684) -var uuid = __nccwpck_require__(71435) -var helpers = __nccwpck_require__(74845) +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.PossibleTypeExtensionsRule = PossibleTypeExtensionsRule; + +var _didYouMean = __nccwpck_require__(42878); + +var _inspect = __nccwpck_require__(10102); -var md5 = helpers.md5 -var toBase64 = helpers.toBase64 +var _invariant = __nccwpck_require__(28847); -function Auth (request) { - // define all public properties here - this.request = request - this.hasAuth = false - this.sentAuth = false - this.bearerToken = null - this.user = null - this.pass = null -} +var _suggestionList = __nccwpck_require__(57704); -Auth.prototype.basic = function (user, pass, sendImmediately) { - var self = this - if (typeof user !== 'string' || (pass !== undefined && typeof pass !== 'string')) { - self.request.emit('error', new Error('auth() received invalid user or password')) - } - self.user = user - self.pass = pass - self.hasAuth = true - var header = user + ':' + (pass || '') - if (sendImmediately || typeof sendImmediately === 'undefined') { - var authHeader = 'Basic ' + toBase64(header) - self.sentAuth = true - return authHeader - } -} +var _GraphQLError = __nccwpck_require__(4797); -Auth.prototype.bearer = function (bearer, sendImmediately) { - var self = this - self.bearerToken = bearer - self.hasAuth = true - if (sendImmediately || typeof sendImmediately === 'undefined') { - if (typeof bearer === 'function') { - bearer = bearer() +var _kinds = __nccwpck_require__(11927); + +var _predicates = __nccwpck_require__(20535); + +var _definition = __nccwpck_require__(5821); + +/** + * Possible type extension + * + * A type extension is only valid if the type is defined and has the same kind. + */ +function PossibleTypeExtensionsRule(context) { + const schema = context.getSchema(); + const definedTypes = Object.create(null); + + for (const def of context.getDocument().definitions) { + if ((0, _predicates.isTypeDefinitionNode)(def)) { + definedTypes[def.name.value] = def; } - var authHeader = 'Bearer ' + (bearer || '') - self.sentAuth = true - return authHeader } -} -Auth.prototype.digest = function (method, path, authHeader) { - // TODO: More complete implementation of RFC 2617. - // - handle challenge.domain - // - support qop="auth-int" only - // - handle Authentication-Info (not necessarily?) - // - check challenge.stale (not necessarily?) - // - increase nc (not necessarily?) - // For reference: - // http://tools.ietf.org/html/rfc2617#section-3 - // https://github.com/bagder/curl/blob/master/lib/http_digest.c + return { + ScalarTypeExtension: checkExtension, + ObjectTypeExtension: checkExtension, + InterfaceTypeExtension: checkExtension, + UnionTypeExtension: checkExtension, + EnumTypeExtension: checkExtension, + InputObjectTypeExtension: checkExtension, + }; - var self = this + function checkExtension(node) { + const typeName = node.name.value; + const defNode = definedTypes[typeName]; + const existingType = + schema === null || schema === void 0 ? void 0 : schema.getType(typeName); + let expectedKind; - var challenge = {} - var re = /([a-z0-9_-]+)=(?:"([^"]+)"|([a-z0-9_-]+))/gi - while (true) { - var match = re.exec(authHeader) - if (!match) { - break + if (defNode) { + expectedKind = defKindToExtKind[defNode.kind]; + } else if (existingType) { + expectedKind = typeToExtKind(existingType); } - challenge[match[1]] = match[2] || match[3] - } - /** - * RFC 2617: handle both MD5 and MD5-sess algorithms. - * - * If the algorithm directive's value is "MD5" or unspecified, then HA1 is - * HA1=MD5(username:realm:password) - * If the algorithm directive's value is "MD5-sess", then HA1 is - * HA1=MD5(MD5(username:realm:password):nonce:cnonce) - */ - var ha1Compute = function (algorithm, user, realm, pass, nonce, cnonce) { - var ha1 = md5(user + ':' + realm + ':' + pass) - if (algorithm && algorithm.toLowerCase() === 'md5-sess') { - return md5(ha1 + ':' + nonce + ':' + cnonce) - } else { - return ha1 - } - } - - var qop = /(^|,)\s*auth\s*($|,)/.test(challenge.qop) && 'auth' - var nc = qop && '00000001' - var cnonce = qop && uuid().replace(/-/g, '') - var ha1 = ha1Compute(challenge.algorithm, self.user, challenge.realm, self.pass, challenge.nonce, cnonce) - var ha2 = md5(method + ':' + path) - var digestResponse = qop - ? md5(ha1 + ':' + challenge.nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2) - : md5(ha1 + ':' + challenge.nonce + ':' + ha2) - var authValues = { - username: self.user, - realm: challenge.realm, - nonce: challenge.nonce, - uri: path, - qop: qop, - response: digestResponse, - nc: nc, - cnonce: cnonce, - algorithm: challenge.algorithm, - opaque: challenge.opaque - } - - authHeader = [] - for (var k in authValues) { - if (authValues[k]) { - if (k === 'qop' || k === 'nc' || k === 'algorithm') { - authHeader.push(k + '=' + authValues[k]) - } else { - authHeader.push(k + '="' + authValues[k] + '"') + if (expectedKind) { + if (expectedKind !== node.kind) { + const kindStr = extensionKindToTypeName(node.kind); + context.reportError( + new _GraphQLError.GraphQLError( + `Cannot extend non-${kindStr} type "${typeName}".`, + { + nodes: defNode ? [defNode, node] : node, + }, + ), + ); } + } else { + const allTypeNames = Object.keys({ + ...definedTypes, + ...(schema === null || schema === void 0 + ? void 0 + : schema.getTypeMap()), + }); + const suggestedTypes = (0, _suggestionList.suggestionList)( + typeName, + allTypeNames, + ); + context.reportError( + new _GraphQLError.GraphQLError( + `Cannot extend type "${typeName}" because it is not defined.` + + (0, _didYouMean.didYouMean)(suggestedTypes), + { + nodes: node.name, + }, + ), + ); } } - authHeader = 'Digest ' + authHeader.join(', ') - self.sentAuth = true - return authHeader } -Auth.prototype.onRequest = function (user, pass, sendImmediately, bearer) { - var self = this - var request = self.request +const defKindToExtKind = { + [_kinds.Kind.SCALAR_TYPE_DEFINITION]: _kinds.Kind.SCALAR_TYPE_EXTENSION, + [_kinds.Kind.OBJECT_TYPE_DEFINITION]: _kinds.Kind.OBJECT_TYPE_EXTENSION, + [_kinds.Kind.INTERFACE_TYPE_DEFINITION]: _kinds.Kind.INTERFACE_TYPE_EXTENSION, + [_kinds.Kind.UNION_TYPE_DEFINITION]: _kinds.Kind.UNION_TYPE_EXTENSION, + [_kinds.Kind.ENUM_TYPE_DEFINITION]: _kinds.Kind.ENUM_TYPE_EXTENSION, + [_kinds.Kind.INPUT_OBJECT_TYPE_DEFINITION]: + _kinds.Kind.INPUT_OBJECT_TYPE_EXTENSION, +}; - var authHeader - if (bearer === undefined && user === undefined) { - self.request.emit('error', new Error('no auth mechanism defined')) - } else if (bearer !== undefined) { - authHeader = self.bearer(bearer, sendImmediately) - } else { - authHeader = self.basic(user, pass, sendImmediately) +function typeToExtKind(type) { + if ((0, _definition.isScalarType)(type)) { + return _kinds.Kind.SCALAR_TYPE_EXTENSION; + } + + if ((0, _definition.isObjectType)(type)) { + return _kinds.Kind.OBJECT_TYPE_EXTENSION; + } + + if ((0, _definition.isInterfaceType)(type)) { + return _kinds.Kind.INTERFACE_TYPE_EXTENSION; + } + + if ((0, _definition.isUnionType)(type)) { + return _kinds.Kind.UNION_TYPE_EXTENSION; + } + + if ((0, _definition.isEnumType)(type)) { + return _kinds.Kind.ENUM_TYPE_EXTENSION; } - if (authHeader) { - request.setHeader('authorization', authHeader) + + if ((0, _definition.isInputObjectType)(type)) { + return _kinds.Kind.INPUT_OBJECT_TYPE_EXTENSION; } + /* c8 ignore next 3 */ + // Not reachable. All possible types have been considered + + false || + (0, _invariant.invariant)( + false, + 'Unexpected type: ' + (0, _inspect.inspect)(type), + ); } -Auth.prototype.onResponse = function (response) { - var self = this - var request = self.request +function extensionKindToTypeName(kind) { + switch (kind) { + case _kinds.Kind.SCALAR_TYPE_EXTENSION: + return 'scalar'; + + case _kinds.Kind.OBJECT_TYPE_EXTENSION: + return 'object'; - if (!self.hasAuth || self.sentAuth) { return null } + case _kinds.Kind.INTERFACE_TYPE_EXTENSION: + return 'interface'; - var c = caseless(response.headers) + case _kinds.Kind.UNION_TYPE_EXTENSION: + return 'union'; - var authHeader = c.get('www-authenticate') - var authVerb = authHeader && authHeader.split(' ')[0].toLowerCase() - request.debug('reauth', authVerb) + case _kinds.Kind.ENUM_TYPE_EXTENSION: + return 'enum'; - switch (authVerb) { - case 'basic': - return self.basic(self.user, self.pass, true) + case _kinds.Kind.INPUT_OBJECT_TYPE_EXTENSION: + return 'input object'; + // Not reachable. All possible types have been considered - case 'bearer': - return self.bearer(self.bearerToken, true) + /* c8 ignore next */ - case 'digest': - return self.digest(request.method, request.path, authHeader) + default: + false || + (0, _invariant.invariant)( + false, + 'Unexpected kind: ' + (0, _inspect.inspect)(kind), + ); } } -exports.g = Auth - /***/ }), -/***/ 50976: +/***/ 57669: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var tough = __nccwpck_require__(47372) +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.ProvidedRequiredArgumentsOnDirectivesRule = + ProvidedRequiredArgumentsOnDirectivesRule; +exports.ProvidedRequiredArgumentsRule = ProvidedRequiredArgumentsRule; -var Cookie = tough.Cookie -var CookieJar = tough.CookieJar +var _inspect = __nccwpck_require__(10102); -exports.parse = function (str) { - if (str && str.uri) { - str = str.uri - } - if (typeof str !== 'string') { - throw new Error('The cookie function only accepts STRING as param') - } - return Cookie.parse(str, {loose: true}) -} +var _keyMap = __nccwpck_require__(10711); -// Adapt the sometimes-Async api of tough.CookieJar to our requirements -function RequestJar (store) { - var self = this - self._jar = new CookieJar(store, {looseMode: true}) -} -RequestJar.prototype.setCookie = function (cookieOrStr, uri, options) { - var self = this - return self._jar.setCookieSync(cookieOrStr, uri, options || {}) -} -RequestJar.prototype.getCookieString = function (uri) { - var self = this - return self._jar.getCookieStringSync(uri) -} -RequestJar.prototype.getCookies = function (uri) { - var self = this - return self._jar.getCookiesSync(uri) -} +var _GraphQLError = __nccwpck_require__(4797); -exports.jar = function (store) { - return new RequestJar(store) -} +var _kinds = __nccwpck_require__(11927); +var _printer = __nccwpck_require__(68203); -/***/ }), +var _definition = __nccwpck_require__(5821); -/***/ 75654: -/***/ ((module) => { +var _directives = __nccwpck_require__(83614); -"use strict"; +/** + * Provided required arguments + * + * A field or directive is only valid if all required (non-null without a + * default value) field arguments have been provided. + */ +function ProvidedRequiredArgumentsRule(context) { + return { + // eslint-disable-next-line new-cap + ...ProvidedRequiredArgumentsOnDirectivesRule(context), + Field: { + // Validate on leave to allow for deeper errors to appear first. + leave(fieldNode) { + var _fieldNode$arguments; + + const fieldDef = context.getFieldDef(); + + if (!fieldDef) { + return false; + } + const providedArgs = new Set( // FIXME: https://github.com/graphql/graphql-js/issues/2203 + /* c8 ignore next */ + (_fieldNode$arguments = fieldNode.arguments) === null || + _fieldNode$arguments === void 0 + ? void 0 + : _fieldNode$arguments.map((arg) => arg.name.value), + ); -function formatHostname (hostname) { - // canonicalize the hostname, so that 'oogle.com' won't match 'google.com' - return hostname.replace(/^\.*/, '.').toLowerCase() + for (const argDef of fieldDef.args) { + if ( + !providedArgs.has(argDef.name) && + (0, _definition.isRequiredArgument)(argDef) + ) { + const argTypeStr = (0, _inspect.inspect)(argDef.type); + context.reportError( + new _GraphQLError.GraphQLError( + `Field "${fieldDef.name}" argument "${argDef.name}" of type "${argTypeStr}" is required, but it was not provided.`, + { + nodes: fieldNode, + }, + ), + ); + } + } + }, + }, + }; } +/** + * @internal + */ -function parseNoProxyZone (zone) { - zone = zone.trim().toLowerCase() +function ProvidedRequiredArgumentsOnDirectivesRule(context) { + var _schema$getDirectives; - var zoneParts = zone.split(':', 2) - var zoneHost = formatHostname(zoneParts[0]) - var zonePort = zoneParts[1] - var hasPort = zone.indexOf(':') > -1 + const requiredArgsMap = Object.create(null); + const schema = context.getSchema(); + const definedDirectives = + (_schema$getDirectives = + schema === null || schema === void 0 + ? void 0 + : schema.getDirectives()) !== null && _schema$getDirectives !== void 0 + ? _schema$getDirectives + : _directives.specifiedDirectives; - return {hostname: zoneHost, port: zonePort, hasPort: hasPort} -} + for (const directive of definedDirectives) { + requiredArgsMap[directive.name] = (0, _keyMap.keyMap)( + directive.args.filter(_definition.isRequiredArgument), + (arg) => arg.name, + ); + } -function uriInNoProxy (uri, noProxy) { - var port = uri.port || (uri.protocol === 'https:' ? '443' : '80') - var hostname = formatHostname(uri.hostname) - var noProxyList = noProxy.split(',') + const astDefinitions = context.getDocument().definitions; - // iterate through the noProxyList until it finds a match. - return noProxyList.map(parseNoProxyZone).some(function (noProxyZone) { - var isMatchedAt = hostname.indexOf(noProxyZone.hostname) - var hostnameMatched = ( - isMatchedAt > -1 && - (isMatchedAt === hostname.length - noProxyZone.hostname.length) - ) + for (const def of astDefinitions) { + if (def.kind === _kinds.Kind.DIRECTIVE_DEFINITION) { + var _def$arguments; + + // FIXME: https://github.com/graphql/graphql-js/issues/2203 - if (noProxyZone.hasPort) { - return (port === noProxyZone.port) && hostnameMatched + /* c8 ignore next */ + const argNodes = + (_def$arguments = def.arguments) !== null && _def$arguments !== void 0 + ? _def$arguments + : []; + requiredArgsMap[def.name.value] = (0, _keyMap.keyMap)( + argNodes.filter(isRequiredArgumentNode), + (arg) => arg.name.value, + ); } + } - return hostnameMatched - }) + return { + Directive: { + // Validate on leave to allow for deeper errors to appear first. + leave(directiveNode) { + const directiveName = directiveNode.name.value; + const requiredArgs = requiredArgsMap[directiveName]; + + if (requiredArgs) { + var _directiveNode$argume; + + // FIXME: https://github.com/graphql/graphql-js/issues/2203 + + /* c8 ignore next */ + const argNodes = + (_directiveNode$argume = directiveNode.arguments) !== null && + _directiveNode$argume !== void 0 + ? _directiveNode$argume + : []; + const argNodeMap = new Set(argNodes.map((arg) => arg.name.value)); + + for (const [argName, argDef] of Object.entries(requiredArgs)) { + if (!argNodeMap.has(argName)) { + const argType = (0, _definition.isType)(argDef.type) + ? (0, _inspect.inspect)(argDef.type) + : (0, _printer.print)(argDef.type); + context.reportError( + new _GraphQLError.GraphQLError( + `Directive "@${directiveName}" argument "${argName}" of type "${argType}" is required, but it was not provided.`, + { + nodes: directiveNode, + }, + ), + ); + } + } + } + }, + }, + }; +} + +function isRequiredArgumentNode(arg) { + return ( + arg.type.kind === _kinds.Kind.NON_NULL_TYPE && arg.defaultValue == null + ); } -function getProxyFromURI (uri) { - // Decide the proper request proxy to use based on the request URI object and the - // environmental variables (NO_PROXY, HTTP_PROXY, etc.) - // respect NO_PROXY environment variables (see: https://lynx.invisible-island.net/lynx2.8.7/breakout/lynx_help/keystrokes/environments.html) - var noProxy = process.env.NO_PROXY || process.env.no_proxy || '' +/***/ }), - // if the noProxy is a wildcard then return null +/***/ 16830: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (noProxy === '*') { - return null - } +"use strict"; - // if the noProxy is not empty and the uri is found return null - if (noProxy !== '' && uriInNoProxy(uri, noProxy)) { - return null - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.ScalarLeafsRule = ScalarLeafsRule; - // Check for HTTP or HTTPS Proxy in environment Else default to null +var _inspect = __nccwpck_require__(10102); - if (uri.protocol === 'http:') { - return process.env.HTTP_PROXY || - process.env.http_proxy || null - } +var _GraphQLError = __nccwpck_require__(4797); - if (uri.protocol === 'https:') { - return process.env.HTTPS_PROXY || - process.env.https_proxy || - process.env.HTTP_PROXY || - process.env.http_proxy || null - } +var _definition = __nccwpck_require__(5821); - // if none of that works, return null - // (What uri protocol are you using then?) +/** + * Scalar leafs + * + * A GraphQL document is valid only if all leaf fields (fields without + * sub selections) are of scalar or enum types. + */ +function ScalarLeafsRule(context) { + return { + Field(node) { + const type = context.getType(); + const selectionSet = node.selectionSet; - return null + if (type) { + if ((0, _definition.isLeafType)((0, _definition.getNamedType)(type))) { + if (selectionSet) { + const fieldName = node.name.value; + const typeStr = (0, _inspect.inspect)(type); + context.reportError( + new _GraphQLError.GraphQLError( + `Field "${fieldName}" must not have a selection since type "${typeStr}" has no subfields.`, + { + nodes: selectionSet, + }, + ), + ); + } + } else if (!selectionSet) { + const fieldName = node.name.value; + const typeStr = (0, _inspect.inspect)(type); + context.reportError( + new _GraphQLError.GraphQLError( + `Field "${fieldName}" of type "${typeStr}" must have a selection of subfields. Did you mean "${fieldName} { ... }"?`, + { + nodes: node, + }, + ), + ); + } else if (selectionSet.selections.length === 0) { + const fieldName = node.name.value; + const typeStr = (0, _inspect.inspect)(type); + context.reportError( + new _GraphQLError.GraphQLError( + `Field "${fieldName}" of type "${typeStr}" must have at least one field selected.`, + { + nodes: node, + }, + ), + ); + } + } + }, + }; } -module.exports = getProxyFromURI - /***/ }), -/***/ 3248: +/***/ 4365: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var fs = __nccwpck_require__(57147) -var qs = __nccwpck_require__(63477) -var validate = __nccwpck_require__(75697) -var extend = __nccwpck_require__(38171) +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.SingleFieldSubscriptionsRule = SingleFieldSubscriptionsRule; -function Har (request) { - this.request = request -} +var _GraphQLError = __nccwpck_require__(4797); -Har.prototype.reducer = function (obj, pair) { - // new property ? - if (obj[pair.name] === undefined) { - obj[pair.name] = pair.value - return obj - } +var _kinds = __nccwpck_require__(11927); - // existing? convert to array - var arr = [ - obj[pair.name], - pair.value - ] +var _collectFields = __nccwpck_require__(49942); - obj[pair.name] = arr +/** + * Subscriptions must only include a non-introspection field. + * + * A GraphQL subscription is valid only if it contains a single root field and + * that root field is not an introspection field. + * + * See https://spec.graphql.org/draft/#sec-Single-root-field + */ +function SingleFieldSubscriptionsRule(context) { + return { + OperationDefinition(node) { + if (node.operation === 'subscription') { + const schema = context.getSchema(); + const subscriptionType = schema.getSubscriptionType(); - return obj -} + if (subscriptionType) { + const operationName = node.name ? node.name.value : null; + const variableValues = Object.create(null); + const document = context.getDocument(); + const fragments = Object.create(null); -Har.prototype.prep = function (data) { - // construct utility properties - data.queryObj = {} - data.headersObj = {} - data.postData.jsonObj = false - data.postData.paramsObj = false + for (const definition of document.definitions) { + if (definition.kind === _kinds.Kind.FRAGMENT_DEFINITION) { + fragments[definition.name.value] = definition; + } + } - // construct query objects - if (data.queryString && data.queryString.length) { - data.queryObj = data.queryString.reduce(this.reducer, {}) - } + const fields = (0, _collectFields.collectFields)( + schema, + fragments, + variableValues, + subscriptionType, + node.selectionSet, + ); - // construct headers objects - if (data.headers && data.headers.length) { - // loweCase header keys - data.headersObj = data.headers.reduceRight(function (headers, header) { - headers[header.name] = header.value - return headers - }, {}) - } + if (fields.size > 1) { + const fieldSelectionLists = [...fields.values()]; + const extraFieldSelectionLists = fieldSelectionLists.slice(1); + const extraFieldSelections = extraFieldSelectionLists.flat(); + context.reportError( + new _GraphQLError.GraphQLError( + operationName != null + ? `Subscription "${operationName}" must select only one top level field.` + : 'Anonymous Subscription must select only one top level field.', + { + nodes: extraFieldSelections, + }, + ), + ); + } - // construct Cookie header - if (data.cookies && data.cookies.length) { - var cookies = data.cookies.map(function (cookie) { - return cookie.name + '=' + cookie.value - }) + for (const fieldNodes of fields.values()) { + const field = fieldNodes[0]; + const fieldName = field.name.value; - if (cookies.length) { - data.headersObj.cookie = cookies.join('; ') - } - } + if (fieldName.startsWith('__')) { + context.reportError( + new _GraphQLError.GraphQLError( + operationName != null + ? `Subscription "${operationName}" must not select an introspection top level field.` + : 'Anonymous Subscription must not select an introspection top level field.', + { + nodes: fieldNodes, + }, + ), + ); + } + } + } + } + }, + }; +} - // prep body - function some (arr) { - return arr.some(function (type) { - return data.postData.mimeType.indexOf(type) === 0 - }) - } - if (some([ - 'multipart/mixed', - 'multipart/related', - 'multipart/form-data', - 'multipart/alternative'])) { - // reset values - data.postData.mimeType = 'multipart/form-data' - } else if (some([ - 'application/x-www-form-urlencoded'])) { - if (!data.postData.params) { - data.postData.text = '' - } else { - data.postData.paramsObj = data.postData.params.reduce(this.reducer, {}) +/***/ }), - // always overwrite - data.postData.text = qs.stringify(data.postData.paramsObj) - } - } else if (some([ - 'text/json', - 'text/x-json', - 'application/json', - 'application/x-json'])) { - data.postData.mimeType = 'application/json' +/***/ 55104: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (data.postData.text) { - try { - data.postData.jsonObj = JSON.parse(data.postData.text) - } catch (e) { - this.request.debug(e) +"use strict"; - // force back to text/plain - data.postData.mimeType = 'text/plain' - } - } - } - return data -} +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueArgumentDefinitionNamesRule = UniqueArgumentDefinitionNamesRule; -Har.prototype.options = function (options) { - // skip if no har property defined - if (!options.har) { - return options - } +var _groupBy = __nccwpck_require__(93173); - var har = {} - extend(har, options.har) +var _GraphQLError = __nccwpck_require__(4797); - // only process the first entry - if (har.log && har.log.entries) { - har = har.log.entries[0] - } +/** + * Unique argument definition names + * + * A GraphQL Object or Interface type is only valid if all its fields have uniquely named arguments. + * A GraphQL Directive is only valid if all its arguments are uniquely named. + */ +function UniqueArgumentDefinitionNamesRule(context) { + return { + DirectiveDefinition(directiveNode) { + var _directiveNode$argume; - // add optional properties to make validation successful - har.url = har.url || options.url || options.uri || options.baseUrl || '/' - har.httpVersion = har.httpVersion || 'HTTP/1.1' - har.queryString = har.queryString || [] - har.headers = har.headers || [] - har.cookies = har.cookies || [] - har.postData = har.postData || {} - har.postData.mimeType = har.postData.mimeType || 'application/octet-stream' + // FIXME: https://github.com/graphql/graphql-js/issues/2203 - har.bodySize = 0 - har.headersSize = 0 - har.postData.size = 0 + /* c8 ignore next */ + const argumentNodes = + (_directiveNode$argume = directiveNode.arguments) !== null && + _directiveNode$argume !== void 0 + ? _directiveNode$argume + : []; + return checkArgUniqueness(`@${directiveNode.name.value}`, argumentNodes); + }, - if (!validate.request(har)) { - return options - } + InterfaceTypeDefinition: checkArgUniquenessPerField, + InterfaceTypeExtension: checkArgUniquenessPerField, + ObjectTypeDefinition: checkArgUniquenessPerField, + ObjectTypeExtension: checkArgUniquenessPerField, + }; - // clean up and get some utility properties - var req = this.prep(har) + function checkArgUniquenessPerField(typeNode) { + var _typeNode$fields; - // construct new options - if (req.url) { - options.url = req.url - } + const typeName = typeNode.name.value; // FIXME: https://github.com/graphql/graphql-js/issues/2203 - if (req.method) { - options.method = req.method - } + /* c8 ignore next */ - if (Object.keys(req.queryObj).length) { - options.qs = req.queryObj - } + const fieldNodes = + (_typeNode$fields = typeNode.fields) !== null && + _typeNode$fields !== void 0 + ? _typeNode$fields + : []; - if (Object.keys(req.headersObj).length) { - options.headers = req.headersObj - } + for (const fieldDef of fieldNodes) { + var _fieldDef$arguments; - function test (type) { - return req.postData.mimeType.indexOf(type) === 0 - } - if (test('application/x-www-form-urlencoded')) { - options.form = req.postData.paramsObj - } else if (test('application/json')) { - if (req.postData.jsonObj) { - options.body = req.postData.jsonObj - options.json = true - } - } else if (test('multipart/form-data')) { - options.formData = {} + const fieldName = fieldDef.name.value; // FIXME: https://github.com/graphql/graphql-js/issues/2203 - req.postData.params.forEach(function (param) { - var attachment = {} + /* c8 ignore next */ - if (!param.fileName && !param.contentType) { - options.formData[param.name] = param.value - return - } + const argumentNodes = + (_fieldDef$arguments = fieldDef.arguments) !== null && + _fieldDef$arguments !== void 0 + ? _fieldDef$arguments + : []; + checkArgUniqueness(`${typeName}.${fieldName}`, argumentNodes); + } - // attempt to read from disk! - if (param.fileName && !param.value) { - attachment.value = fs.createReadStream(param.fileName) - } else if (param.value) { - attachment.value = param.value - } + return false; + } - if (param.fileName) { - attachment.options = { - filename: param.fileName, - contentType: param.contentType ? param.contentType : null - } - } + function checkArgUniqueness(parentName, argumentNodes) { + const seenArgs = (0, _groupBy.groupBy)( + argumentNodes, + (arg) => arg.name.value, + ); - options.formData[param.name] = attachment - }) - } else { - if (req.postData.text) { - options.body = req.postData.text + for (const [argName, argNodes] of seenArgs) { + if (argNodes.length > 1) { + context.reportError( + new _GraphQLError.GraphQLError( + `Argument "${parentName}(${argName}:)" can only be defined once.`, + { + nodes: argNodes.map((node) => node.name), + }, + ), + ); + } } - } - return options + return false; + } } -exports.t = Har - /***/ }), -/***/ 34473: +/***/ 45799: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var crypto = __nccwpck_require__(6113) +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueArgumentNamesRule = UniqueArgumentNamesRule; + +var _groupBy = __nccwpck_require__(93173); -function randomString (size) { - var bits = (size + 1) * 6 - var buffer = crypto.randomBytes(Math.ceil(bits / 8)) - var string = buffer.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '') - return string.slice(0, size) -} +var _GraphQLError = __nccwpck_require__(4797); -function calculatePayloadHash (payload, algorithm, contentType) { - var hash = crypto.createHash(algorithm) - hash.update('hawk.1.payload\n') - hash.update((contentType ? contentType.split(';')[0].trim().toLowerCase() : '') + '\n') - hash.update(payload || '') - hash.update('\n') - return hash.digest('base64') -} +/** + * Unique argument names + * + * A GraphQL field or directive is only valid if all supplied arguments are + * uniquely named. + * + * See https://spec.graphql.org/draft/#sec-Argument-Names + */ +function UniqueArgumentNamesRule(context) { + return { + Field: checkArgUniqueness, + Directive: checkArgUniqueness, + }; -exports.calculateMac = function (credentials, opts) { - var normalized = 'hawk.1.header\n' + - opts.ts + '\n' + - opts.nonce + '\n' + - (opts.method || '').toUpperCase() + '\n' + - opts.resource + '\n' + - opts.host.toLowerCase() + '\n' + - opts.port + '\n' + - (opts.hash || '') + '\n' + function checkArgUniqueness(parentNode) { + var _parentNode$arguments; - if (opts.ext) { - normalized = normalized + opts.ext.replace('\\', '\\\\').replace('\n', '\\n') - } + // FIXME: https://github.com/graphql/graphql-js/issues/2203 - normalized = normalized + '\n' + /* c8 ignore next */ + const argumentNodes = + (_parentNode$arguments = parentNode.arguments) !== null && + _parentNode$arguments !== void 0 + ? _parentNode$arguments + : []; + const seenArgs = (0, _groupBy.groupBy)( + argumentNodes, + (arg) => arg.name.value, + ); - if (opts.app) { - normalized = normalized + opts.app + '\n' + (opts.dlg || '') + '\n' + for (const [argName, argNodes] of seenArgs) { + if (argNodes.length > 1) { + context.reportError( + new _GraphQLError.GraphQLError( + `There can be only one argument named "${argName}".`, + { + nodes: argNodes.map((node) => node.name), + }, + ), + ); + } + } } - - var hmac = crypto.createHmac(credentials.algorithm, credentials.key).update(normalized) - var digest = hmac.digest('base64') - return digest } -exports.header = function (uri, method, opts) { - var timestamp = opts.timestamp || Math.floor((Date.now() + (opts.localtimeOffsetMsec || 0)) / 1000) - var credentials = opts.credentials - if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) { - return '' - } - if (['sha1', 'sha256'].indexOf(credentials.algorithm) === -1) { - return '' - } +/***/ }), - var artifacts = { - ts: timestamp, - nonce: opts.nonce || randomString(6), - method: method, - resource: uri.pathname + (uri.search || ''), - host: uri.hostname, - port: uri.port || (uri.protocol === 'http:' ? 80 : 443), - hash: opts.hash, - ext: opts.ext, - app: opts.app, - dlg: opts.dlg - } +/***/ 17074: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (!artifacts.hash && (opts.payload || opts.payload === '')) { - artifacts.hash = calculatePayloadHash(opts.payload, credentials.algorithm, opts.contentType) - } +"use strict"; - var mac = exports.calculateMac(credentials, artifacts) - var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== '' - var header = 'Hawk id="' + credentials.id + - '", ts="' + artifacts.ts + - '", nonce="' + artifacts.nonce + - (artifacts.hash ? '", hash="' + artifacts.hash : '') + - (hasExt ? '", ext="' + artifacts.ext.replace(/\\/g, '\\\\').replace(/"/g, '\\"') : '') + - '", mac="' + mac + '"' +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueDirectiveNamesRule = UniqueDirectiveNamesRule; - if (artifacts.app) { - header = header + ', app="' + artifacts.app + (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"' - } +var _GraphQLError = __nccwpck_require__(4797); + +/** + * Unique directive names + * + * A GraphQL document is only valid if all defined directives have unique names. + */ +function UniqueDirectiveNamesRule(context) { + const knownDirectiveNames = Object.create(null); + const schema = context.getSchema(); + return { + DirectiveDefinition(node) { + const directiveName = node.name.value; + + if ( + schema !== null && + schema !== void 0 && + schema.getDirective(directiveName) + ) { + context.reportError( + new _GraphQLError.GraphQLError( + `Directive "@${directiveName}" already exists in the schema. It cannot be redefined.`, + { + nodes: node.name, + }, + ), + ); + return; + } + + if (knownDirectiveNames[directiveName]) { + context.reportError( + new _GraphQLError.GraphQLError( + `There can be only one directive named "@${directiveName}".`, + { + nodes: [knownDirectiveNames[directiveName], node.name], + }, + ), + ); + } else { + knownDirectiveNames[directiveName] = node.name; + } - return header + return false; + }, + }; } /***/ }), -/***/ 74845: +/***/ 61944: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var jsonSafeStringify = __nccwpck_require__(57073) -var crypto = __nccwpck_require__(6113) -var Buffer = (__nccwpck_require__(21867).Buffer) +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueDirectivesPerLocationRule = UniqueDirectivesPerLocationRule; -var defer = typeof setImmediate === 'undefined' - ? process.nextTick - : setImmediate +var _GraphQLError = __nccwpck_require__(4797); -function paramsHaveRequestBody (params) { - return ( - params.body || - params.requestBodyStream || - (params.json && typeof params.json !== 'boolean') || - params.multipart - ) -} +var _kinds = __nccwpck_require__(11927); -function safeStringify (obj, replacer) { - var ret - try { - ret = JSON.stringify(obj, replacer) - } catch (e) { - ret = jsonSafeStringify(obj, replacer) - } - return ret -} +var _predicates = __nccwpck_require__(20535); -function md5 (str) { - return crypto.createHash('md5').update(str).digest('hex') -} +var _directives = __nccwpck_require__(83614); -function isReadStream (rs) { - return rs.readable && rs.path && rs.mode -} +/** + * Unique directive names per location + * + * A GraphQL document is only valid if all non-repeatable directives at + * a given location are uniquely named. + * + * See https://spec.graphql.org/draft/#sec-Directives-Are-Unique-Per-Location + */ +function UniqueDirectivesPerLocationRule(context) { + const uniqueDirectiveMap = Object.create(null); + const schema = context.getSchema(); + const definedDirectives = schema + ? schema.getDirectives() + : _directives.specifiedDirectives; -function toBase64 (str) { - return Buffer.from(str || '', 'utf8').toString('base64') -} + for (const directive of definedDirectives) { + uniqueDirectiveMap[directive.name] = !directive.isRepeatable; + } -function copy (obj) { - var o = {} - Object.keys(obj).forEach(function (i) { - o[i] = obj[i] - }) - return o -} + const astDefinitions = context.getDocument().definitions; -function version () { - var numbers = process.version.replace('v', '').split('.') - return { - major: parseInt(numbers[0], 10), - minor: parseInt(numbers[1], 10), - patch: parseInt(numbers[2], 10) + for (const def of astDefinitions) { + if (def.kind === _kinds.Kind.DIRECTIVE_DEFINITION) { + uniqueDirectiveMap[def.name.value] = !def.repeatable; + } } + + const schemaDirectives = Object.create(null); + const typeDirectivesMap = Object.create(null); + return { + // Many different AST nodes may contain directives. Rather than listing + // them all, just listen for entering any node, and check to see if it + // defines any directives. + enter(node) { + if (!('directives' in node) || !node.directives) { + return; + } + + let seenDirectives; + + if ( + node.kind === _kinds.Kind.SCHEMA_DEFINITION || + node.kind === _kinds.Kind.SCHEMA_EXTENSION + ) { + seenDirectives = schemaDirectives; + } else if ( + (0, _predicates.isTypeDefinitionNode)(node) || + (0, _predicates.isTypeExtensionNode)(node) + ) { + const typeName = node.name.value; + seenDirectives = typeDirectivesMap[typeName]; + + if (seenDirectives === undefined) { + typeDirectivesMap[typeName] = seenDirectives = Object.create(null); + } + } else { + seenDirectives = Object.create(null); + } + + for (const directive of node.directives) { + const directiveName = directive.name.value; + + if (uniqueDirectiveMap[directiveName]) { + if (seenDirectives[directiveName]) { + context.reportError( + new _GraphQLError.GraphQLError( + `The directive "@${directiveName}" can only be used once at this location.`, + { + nodes: [seenDirectives[directiveName], directive], + }, + ), + ); + } else { + seenDirectives[directiveName] = directive; + } + } + } + }, + }; } -exports.paramsHaveRequestBody = paramsHaveRequestBody -exports.safeStringify = safeStringify -exports.md5 = md5 -exports.isReadStream = isReadStream -exports.toBase64 = toBase64 -exports.copy = copy -exports.version = version -exports.defer = defer - /***/ }), -/***/ 87810: +/***/ 44437: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var uuid = __nccwpck_require__(71435) -var CombinedStream = __nccwpck_require__(85443) -var isstream = __nccwpck_require__(83362) -var Buffer = (__nccwpck_require__(21867).Buffer) - -function Multipart (request) { - this.request = request - this.boundary = uuid() - this.chunked = false - this.body = null -} - -Multipart.prototype.isChunked = function (options) { - var self = this - var chunked = false - var parts = options.data || options - - if (!parts.forEach) { - self.request.emit('error', new Error('Argument error, options.multipart.')) - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueEnumValueNamesRule = UniqueEnumValueNamesRule; - if (options.chunked !== undefined) { - chunked = options.chunked - } +var _GraphQLError = __nccwpck_require__(4797); - if (self.request.getHeader('transfer-encoding') === 'chunked') { - chunked = true - } +var _definition = __nccwpck_require__(5821); - if (!chunked) { - parts.forEach(function (part) { - if (typeof part.body === 'undefined') { - self.request.emit('error', new Error('Body attribute missing in multipart.')) - } - if (isstream(part.body)) { - chunked = true - } - }) - } +/** + * Unique enum value names + * + * A GraphQL enum type is only valid if all its values are uniquely named. + */ +function UniqueEnumValueNamesRule(context) { + const schema = context.getSchema(); + const existingTypeMap = schema ? schema.getTypeMap() : Object.create(null); + const knownValueNames = Object.create(null); + return { + EnumTypeDefinition: checkValueUniqueness, + EnumTypeExtension: checkValueUniqueness, + }; - return chunked -} + function checkValueUniqueness(node) { + var _node$values; -Multipart.prototype.setHeaders = function (chunked) { - var self = this + const typeName = node.name.value; - if (chunked && !self.request.hasHeader('transfer-encoding')) { - self.request.setHeader('transfer-encoding', 'chunked') - } + if (!knownValueNames[typeName]) { + knownValueNames[typeName] = Object.create(null); + } // FIXME: https://github.com/graphql/graphql-js/issues/2203 - var header = self.request.getHeader('content-type') + /* c8 ignore next */ - if (!header || header.indexOf('multipart') === -1) { - self.request.setHeader('content-type', 'multipart/related; boundary=' + self.boundary) - } else { - if (header.indexOf('boundary') !== -1) { - self.boundary = header.replace(/.*boundary=([^\s;]+).*/, '$1') - } else { - self.request.setHeader('content-type', header + '; boundary=' + self.boundary) - } - } -} + const valueNodes = + (_node$values = node.values) !== null && _node$values !== void 0 + ? _node$values + : []; + const valueNames = knownValueNames[typeName]; -Multipart.prototype.build = function (parts, chunked) { - var self = this - var body = chunked ? new CombinedStream() : [] + for (const valueDef of valueNodes) { + const valueName = valueDef.name.value; + const existingType = existingTypeMap[typeName]; - function add (part) { - if (typeof part === 'number') { - part = part.toString() + if ( + (0, _definition.isEnumType)(existingType) && + existingType.getValue(valueName) + ) { + context.reportError( + new _GraphQLError.GraphQLError( + `Enum value "${typeName}.${valueName}" already exists in the schema. It cannot also be defined in this type extension.`, + { + nodes: valueDef.name, + }, + ), + ); + } else if (valueNames[valueName]) { + context.reportError( + new _GraphQLError.GraphQLError( + `Enum value "${typeName}.${valueName}" can only be defined once.`, + { + nodes: [valueNames[valueName], valueDef.name], + }, + ), + ); + } else { + valueNames[valueName] = valueDef.name; + } } - return chunked ? body.append(part) : body.push(Buffer.from(part)) - } - - if (self.request.preambleCRLF) { - add('\r\n') - } - - parts.forEach(function (part) { - var preamble = '--' + self.boundary + '\r\n' - Object.keys(part).forEach(function (key) { - if (key === 'body') { return } - preamble += key + ': ' + part[key] + '\r\n' - }) - preamble += '\r\n' - add(preamble) - add(part.body) - add('\r\n') - }) - add('--' + self.boundary + '--') - if (self.request.postambleCRLF) { - add('\r\n') + return false; } - - return body -} - -Multipart.prototype.onRequest = function (options) { - var self = this - - var chunked = self.isChunked(options) - var parts = options.data || options - - self.setHeaders(chunked) - self.chunked = chunked - self.body = self.build(parts, chunked) } -exports.$ = Multipart - /***/ }), -/***/ 41174: +/***/ 9502: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var url = __nccwpck_require__(57310) -var qs = __nccwpck_require__(22760) -var caseless = __nccwpck_require__(35684) -var uuid = __nccwpck_require__(71435) -var oauth = __nccwpck_require__(43248) -var crypto = __nccwpck_require__(6113) -var Buffer = (__nccwpck_require__(21867).Buffer) - -function OAuth (request) { - this.request = request - this.params = null -} +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueFieldDefinitionNamesRule = UniqueFieldDefinitionNamesRule; -OAuth.prototype.buildParams = function (_oauth, uri, method, query, form, qsLib) { - var oa = {} - for (var i in _oauth) { - oa['oauth_' + i] = _oauth[i] - } - if (!oa.oauth_version) { - oa.oauth_version = '1.0' - } - if (!oa.oauth_timestamp) { - oa.oauth_timestamp = Math.floor(Date.now() / 1000).toString() - } - if (!oa.oauth_nonce) { - oa.oauth_nonce = uuid().replace(/-/g, '') - } - if (!oa.oauth_signature_method) { - oa.oauth_signature_method = 'HMAC-SHA1' - } +var _GraphQLError = __nccwpck_require__(4797); - var consumer_secret_or_private_key = oa.oauth_consumer_secret || oa.oauth_private_key // eslint-disable-line camelcase - delete oa.oauth_consumer_secret - delete oa.oauth_private_key +var _definition = __nccwpck_require__(5821); - var token_secret = oa.oauth_token_secret // eslint-disable-line camelcase - delete oa.oauth_token_secret +/** + * Unique field definition names + * + * A GraphQL complex type is only valid if all its fields are uniquely named. + */ +function UniqueFieldDefinitionNamesRule(context) { + const schema = context.getSchema(); + const existingTypeMap = schema ? schema.getTypeMap() : Object.create(null); + const knownFieldNames = Object.create(null); + return { + InputObjectTypeDefinition: checkFieldUniqueness, + InputObjectTypeExtension: checkFieldUniqueness, + InterfaceTypeDefinition: checkFieldUniqueness, + InterfaceTypeExtension: checkFieldUniqueness, + ObjectTypeDefinition: checkFieldUniqueness, + ObjectTypeExtension: checkFieldUniqueness, + }; - var realm = oa.oauth_realm - delete oa.oauth_realm - delete oa.oauth_transport_method + function checkFieldUniqueness(node) { + var _node$fields; - var baseurl = uri.protocol + '//' + uri.host + uri.pathname - var params = qsLib.parse([].concat(query, form, qsLib.stringify(oa)).join('&')) + const typeName = node.name.value; - oa.oauth_signature = oauth.sign( - oa.oauth_signature_method, - method, - baseurl, - params, - consumer_secret_or_private_key, // eslint-disable-line camelcase - token_secret // eslint-disable-line camelcase - ) + if (!knownFieldNames[typeName]) { + knownFieldNames[typeName] = Object.create(null); + } // FIXME: https://github.com/graphql/graphql-js/issues/2203 - if (realm) { - oa.realm = realm - } + /* c8 ignore next */ - return oa -} + const fieldNodes = + (_node$fields = node.fields) !== null && _node$fields !== void 0 + ? _node$fields + : []; + const fieldNames = knownFieldNames[typeName]; -OAuth.prototype.buildBodyHash = function (_oauth, body) { - if (['HMAC-SHA1', 'RSA-SHA1'].indexOf(_oauth.signature_method || 'HMAC-SHA1') < 0) { - this.request.emit('error', new Error('oauth: ' + _oauth.signature_method + - ' signature_method not supported with body_hash signing.')) - } + for (const fieldDef of fieldNodes) { + const fieldName = fieldDef.name.value; - var shasum = crypto.createHash('sha1') - shasum.update(body || '') - var sha1 = shasum.digest('hex') + if (hasField(existingTypeMap[typeName], fieldName)) { + context.reportError( + new _GraphQLError.GraphQLError( + `Field "${typeName}.${fieldName}" already exists in the schema. It cannot also be defined in this type extension.`, + { + nodes: fieldDef.name, + }, + ), + ); + } else if (fieldNames[fieldName]) { + context.reportError( + new _GraphQLError.GraphQLError( + `Field "${typeName}.${fieldName}" can only be defined once.`, + { + nodes: [fieldNames[fieldName], fieldDef.name], + }, + ), + ); + } else { + fieldNames[fieldName] = fieldDef.name; + } + } - return Buffer.from(sha1, 'hex').toString('base64') + return false; + } } -OAuth.prototype.concatParams = function (oa, sep, wrap) { - wrap = wrap || '' - - var params = Object.keys(oa).filter(function (i) { - return i !== 'realm' && i !== 'oauth_signature' - }).sort() - - if (oa.realm) { - params.splice(0, 0, 'realm') +function hasField(type, fieldName) { + if ( + (0, _definition.isObjectType)(type) || + (0, _definition.isInterfaceType)(type) || + (0, _definition.isInputObjectType)(type) + ) { + return type.getFields()[fieldName] != null; } - params.push('oauth_signature') - return params.map(function (i) { - return i + '=' + wrap + oauth.rfc3986(oa[i]) + wrap - }).join(sep) + return false; } -OAuth.prototype.onRequest = function (_oauth) { - var self = this - self.params = _oauth - var uri = self.request.uri || {} - var method = self.request.method || '' - var headers = caseless(self.request.headers) - var body = self.request.body || '' - var qsLib = self.request.qsLib || qs +/***/ }), + +/***/ 79402: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var form - var query - var contentType = headers.get('content-type') || '' - var formContentType = 'application/x-www-form-urlencoded' - var transport = _oauth.transport_method || 'header' +"use strict"; - if (contentType.slice(0, formContentType.length) === formContentType) { - contentType = formContentType - form = body - } - if (uri.query) { - query = uri.query - } - if (transport === 'body' && (method !== 'POST' || contentType !== formContentType)) { - self.request.emit('error', new Error('oauth: transport_method of body requires POST ' + - 'and content-type ' + formContentType)) - } - if (!form && typeof _oauth.body_hash === 'boolean') { - _oauth.body_hash = self.buildBodyHash(_oauth, self.request.body.toString()) - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueFragmentNamesRule = UniqueFragmentNamesRule; - var oa = self.buildParams(_oauth, uri, method, query, form, qsLib) +var _GraphQLError = __nccwpck_require__(4797); - switch (transport) { - case 'header': - self.request.setHeader('Authorization', 'OAuth ' + self.concatParams(oa, ',', '"')) - break +/** + * Unique fragment names + * + * A GraphQL document is only valid if all defined fragments have unique names. + * + * See https://spec.graphql.org/draft/#sec-Fragment-Name-Uniqueness + */ +function UniqueFragmentNamesRule(context) { + const knownFragmentNames = Object.create(null); + return { + OperationDefinition: () => false, - case 'query': - var href = self.request.uri.href += (query ? '&' : '?') + self.concatParams(oa, '&') - self.request.uri = url.parse(href) - self.request.path = self.request.uri.path - break + FragmentDefinition(node) { + const fragmentName = node.name.value; - case 'body': - self.request.body = (form ? form + '&' : '') + self.concatParams(oa, '&') - break + if (knownFragmentNames[fragmentName]) { + context.reportError( + new _GraphQLError.GraphQLError( + `There can be only one fragment named "${fragmentName}".`, + { + nodes: [knownFragmentNames[fragmentName], node.name], + }, + ), + ); + } else { + knownFragmentNames[fragmentName] = node.name; + } - default: - self.request.emit('error', new Error('oauth: transport_method invalid')) - } + return false; + }, + }; } -exports.f = OAuth - /***/ }), -/***/ 66476: +/***/ 83552: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var qs = __nccwpck_require__(22760) -var querystring = __nccwpck_require__(63477) - -function Querystring (request) { - this.request = request - this.lib = null - this.useQuerystring = null - this.parseOptions = null - this.stringifyOptions = null -} +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueInputFieldNamesRule = UniqueInputFieldNamesRule; -Querystring.prototype.init = function (options) { - if (this.lib) { return } +var _invariant = __nccwpck_require__(28847); - this.useQuerystring = options.useQuerystring - this.lib = (this.useQuerystring ? querystring : qs) +var _GraphQLError = __nccwpck_require__(4797); - this.parseOptions = options.qsParseOptions || {} - this.stringifyOptions = options.qsStringifyOptions || {} -} +/** + * Unique input field names + * + * A GraphQL input object value is only valid if all supplied fields are + * uniquely named. + * + * See https://spec.graphql.org/draft/#sec-Input-Object-Field-Uniqueness + */ +function UniqueInputFieldNamesRule(context) { + const knownNameStack = []; + let knownNames = Object.create(null); + return { + ObjectValue: { + enter() { + knownNameStack.push(knownNames); + knownNames = Object.create(null); + }, -Querystring.prototype.stringify = function (obj) { - return (this.useQuerystring) - ? this.rfc3986(this.lib.stringify(obj, - this.stringifyOptions.sep || null, - this.stringifyOptions.eq || null, - this.stringifyOptions)) - : this.lib.stringify(obj, this.stringifyOptions) -} + leave() { + const prevKnownNames = knownNameStack.pop(); + prevKnownNames || (0, _invariant.invariant)(false); + knownNames = prevKnownNames; + }, + }, -Querystring.prototype.parse = function (str) { - return (this.useQuerystring) - ? this.lib.parse(str, - this.parseOptions.sep || null, - this.parseOptions.eq || null, - this.parseOptions) - : this.lib.parse(str, this.parseOptions) -} + ObjectField(node) { + const fieldName = node.name.value; -Querystring.prototype.rfc3986 = function (str) { - return str.replace(/[!'()*]/g, function (c) { - return '%' + c.charCodeAt(0).toString(16).toUpperCase() - }) + if (knownNames[fieldName]) { + context.reportError( + new _GraphQLError.GraphQLError( + `There can be only one input field named "${fieldName}".`, + { + nodes: [knownNames[fieldName], node.name], + }, + ), + ); + } else { + knownNames[fieldName] = node.name; + } + }, + }; } -Querystring.prototype.unescape = querystring.unescape - -exports.h = Querystring - /***/ }), -/***/ 3048: +/***/ 94865: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var url = __nccwpck_require__(57310) -var isUrl = /^https?:/ - -function Redirect (request) { - this.request = request - this.followRedirect = true - this.followRedirects = true - this.followAllRedirects = false - this.followOriginalHttpMethod = false - this.allowRedirect = function () { return true } - this.maxRedirects = 10 - this.redirects = [] - this.redirectsFollowed = 0 - this.removeRefererHeader = false -} +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueOperationNamesRule = UniqueOperationNamesRule; -Redirect.prototype.onRequest = function (options) { - var self = this +var _GraphQLError = __nccwpck_require__(4797); - if (options.maxRedirects !== undefined) { - self.maxRedirects = options.maxRedirects - } - if (typeof options.followRedirect === 'function') { - self.allowRedirect = options.followRedirect - } - if (options.followRedirect !== undefined) { - self.followRedirects = !!options.followRedirect - } - if (options.followAllRedirects !== undefined) { - self.followAllRedirects = options.followAllRedirects - } - if (self.followRedirects || self.followAllRedirects) { - self.redirects = self.redirects || [] - } - if (options.removeRefererHeader !== undefined) { - self.removeRefererHeader = options.removeRefererHeader - } - if (options.followOriginalHttpMethod !== undefined) { - self.followOriginalHttpMethod = options.followOriginalHttpMethod - } -} +/** + * Unique operation names + * + * A GraphQL document is only valid if all defined operations have unique names. + * + * See https://spec.graphql.org/draft/#sec-Operation-Name-Uniqueness + */ +function UniqueOperationNamesRule(context) { + const knownOperationNames = Object.create(null); + return { + OperationDefinition(node) { + const operationName = node.name; -Redirect.prototype.redirectTo = function (response) { - var self = this - var request = self.request - - var redirectTo = null - if (response.statusCode >= 300 && response.statusCode < 400 && response.caseless.has('location')) { - var location = response.caseless.get('location') - request.debug('redirect', location) - - if (self.followAllRedirects) { - redirectTo = location - } else if (self.followRedirects) { - switch (request.method) { - case 'PATCH': - case 'PUT': - case 'POST': - case 'DELETE': - // Do not follow redirects - break - default: - redirectTo = location - break + if (operationName) { + if (knownOperationNames[operationName.value]) { + context.reportError( + new _GraphQLError.GraphQLError( + `There can be only one operation named "${operationName.value}".`, + { + nodes: [ + knownOperationNames[operationName.value], + operationName, + ], + }, + ), + ); + } else { + knownOperationNames[operationName.value] = operationName; + } } - } - } else if (response.statusCode === 401) { - var authHeader = request._auth.onResponse(response) - if (authHeader) { - request.setHeader('authorization', authHeader) - redirectTo = request.uri - } - } - return redirectTo -} -Redirect.prototype.onResponse = function (response) { - var self = this - var request = self.request + return false; + }, - var redirectTo = self.redirectTo(response) - if (!redirectTo || !self.allowRedirect.call(request, response)) { - return false - } + FragmentDefinition: () => false, + }; +} - request.debug('redirect to', redirectTo) - // ignore any potential response body. it cannot possibly be useful - // to us at this point. - // response.resume should be defined, but check anyway before calling. Workaround for browserify. - if (response.resume) { - response.resume() - } +/***/ }), - if (self.redirectsFollowed >= self.maxRedirects) { - request.emit('error', new Error('Exceeded maxRedirects. Probably stuck in a redirect loop ' + request.uri.href)) - return false - } - self.redirectsFollowed += 1 +/***/ 31492: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (!isUrl.test(redirectTo)) { - redirectTo = url.resolve(request.uri.href, redirectTo) - } +"use strict"; - var uriPrev = request.uri - request.uri = url.parse(redirectTo) - // handle the case where we change protocol from https to http or vice versa - if (request.uri.protocol !== uriPrev.protocol) { - delete request.agent - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueOperationTypesRule = UniqueOperationTypesRule; - self.redirects.push({ statusCode: response.statusCode, redirectUri: redirectTo }) +var _GraphQLError = __nccwpck_require__(4797); - if (self.followAllRedirects && request.method !== 'HEAD' && - response.statusCode !== 401 && response.statusCode !== 307) { - request.method = self.followOriginalHttpMethod ? request.method : 'GET' - } - // request.method = 'GET' // Force all redirects to use GET || commented out fixes #215 - delete request.src - delete request.req - delete request._started - if (response.statusCode !== 401 && response.statusCode !== 307) { - // Remove parameters from the previous response, unless this is the second request - // for a server that requires digest authentication. - delete request.body - delete request._form - if (request.headers) { - request.removeHeader('host') - request.removeHeader('content-type') - request.removeHeader('content-length') - if (request.uri.hostname !== request.originalHost.split(':')[0]) { - // Remove authorization if changing hostnames (but not if just - // changing ports or protocols). This matches the behavior of curl: - // https://github.com/bagder/curl/blob/6beb0eee/lib/http.c#L710 - request.removeHeader('authorization') +/** + * Unique operation types + * + * A GraphQL document is only valid if it has only one type per operation. + */ +function UniqueOperationTypesRule(context) { + const schema = context.getSchema(); + const definedOperationTypes = Object.create(null); + const existingOperationTypes = schema + ? { + query: schema.getQueryType(), + mutation: schema.getMutationType(), + subscription: schema.getSubscriptionType(), } - } - } + : {}; + return { + SchemaDefinition: checkOperationTypes, + SchemaExtension: checkOperationTypes, + }; - if (!self.removeRefererHeader) { - request.setHeader('referer', uriPrev.href) - } + function checkOperationTypes(node) { + var _node$operationTypes; - request.emit('redirect') + // See: https://github.com/graphql/graphql-js/issues/2203 - request.init() + /* c8 ignore next */ + const operationTypesNodes = + (_node$operationTypes = node.operationTypes) !== null && + _node$operationTypes !== void 0 + ? _node$operationTypes + : []; - return true -} + for (const operationType of operationTypesNodes) { + const operation = operationType.operation; + const alreadyDefinedOperationType = definedOperationTypes[operation]; + + if (existingOperationTypes[operation]) { + context.reportError( + new _GraphQLError.GraphQLError( + `Type for ${operation} already defined in the schema. It cannot be redefined.`, + { + nodes: operationType, + }, + ), + ); + } else if (alreadyDefinedOperationType) { + context.reportError( + new _GraphQLError.GraphQLError( + `There can be only one ${operation} type in schema.`, + { + nodes: [alreadyDefinedOperationType, operationType], + }, + ), + ); + } else { + definedOperationTypes[operation] = operationType; + } + } -exports.l = Redirect + return false; + } +} /***/ }), -/***/ 17619: +/***/ 24316: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var url = __nccwpck_require__(57310) -var tunnel = __nccwpck_require__(11137) - -var defaultProxyHeaderWhiteList = [ - 'accept', - 'accept-charset', - 'accept-encoding', - 'accept-language', - 'accept-ranges', - 'cache-control', - 'content-encoding', - 'content-language', - 'content-location', - 'content-md5', - 'content-range', - 'content-type', - 'connection', - 'date', - 'expect', - 'max-forwards', - 'pragma', - 'referer', - 'te', - 'user-agent', - 'via' -] +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueTypeNamesRule = UniqueTypeNamesRule; -var defaultProxyHeaderExclusiveList = [ - 'proxy-authorization' -] +var _GraphQLError = __nccwpck_require__(4797); -function constructProxyHost (uriObject) { - var port = uriObject.port - var protocol = uriObject.protocol - var proxyHost = uriObject.hostname + ':' +/** + * Unique type names + * + * A GraphQL document is only valid if all defined types have unique names. + */ +function UniqueTypeNamesRule(context) { + const knownTypeNames = Object.create(null); + const schema = context.getSchema(); + return { + ScalarTypeDefinition: checkTypeName, + ObjectTypeDefinition: checkTypeName, + InterfaceTypeDefinition: checkTypeName, + UnionTypeDefinition: checkTypeName, + EnumTypeDefinition: checkTypeName, + InputObjectTypeDefinition: checkTypeName, + }; - if (port) { - proxyHost += port - } else if (protocol === 'https:') { - proxyHost += '443' - } else { - proxyHost += '80' - } + function checkTypeName(node) { + const typeName = node.name.value; - return proxyHost -} + if (schema !== null && schema !== void 0 && schema.getType(typeName)) { + context.reportError( + new _GraphQLError.GraphQLError( + `Type "${typeName}" already exists in the schema. It cannot also be defined in this type definition.`, + { + nodes: node.name, + }, + ), + ); + return; + } -function constructProxyHeaderWhiteList (headers, proxyHeaderWhiteList) { - var whiteList = proxyHeaderWhiteList - .reduce(function (set, header) { - set[header.toLowerCase()] = true - return set - }, {}) + if (knownTypeNames[typeName]) { + context.reportError( + new _GraphQLError.GraphQLError( + `There can be only one type named "${typeName}".`, + { + nodes: [knownTypeNames[typeName], node.name], + }, + ), + ); + } else { + knownTypeNames[typeName] = node.name; + } - return Object.keys(headers) - .filter(function (header) { - return whiteList[header.toLowerCase()] - }) - .reduce(function (set, header) { - set[header] = headers[header] - return set - }, {}) + return false; + } } -function constructTunnelOptions (request, proxyHeaders) { - var proxy = request.proxy - - var tunnelOptions = { - proxy: { - host: proxy.hostname, - port: +proxy.port, - proxyAuth: proxy.auth, - headers: proxyHeaders - }, - headers: request.headers, - ca: request.ca, - cert: request.cert, - key: request.key, - passphrase: request.passphrase, - pfx: request.pfx, - ciphers: request.ciphers, - rejectUnauthorized: request.rejectUnauthorized, - secureOptions: request.secureOptions, - secureProtocol: request.secureProtocol - } - return tunnelOptions -} +/***/ }), -function constructTunnelFnName (uri, proxy) { - var uriProtocol = (uri.protocol === 'https:' ? 'https' : 'http') - var proxyProtocol = (proxy.protocol === 'https:' ? 'Https' : 'Http') - return [uriProtocol, proxyProtocol].join('Over') -} +/***/ 65931: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -function getTunnelFn (request) { - var uri = request.uri - var proxy = request.proxy - var tunnelFnName = constructTunnelFnName(uri, proxy) - return tunnel[tunnelFnName] -} +"use strict"; -function Tunnel (request) { - this.request = request - this.proxyHeaderWhiteList = defaultProxyHeaderWhiteList - this.proxyHeaderExclusiveList = [] - if (typeof request.tunnel !== 'undefined') { - this.tunnelOverride = request.tunnel - } -} -Tunnel.prototype.isEnabled = function () { - var self = this - var request = self.request - // Tunnel HTTPS by default. Allow the user to override this setting. +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.UniqueVariableNamesRule = UniqueVariableNamesRule; - // If self.tunnelOverride is set (the user specified a value), use it. - if (typeof self.tunnelOverride !== 'undefined') { - return self.tunnelOverride - } +var _groupBy = __nccwpck_require__(93173); - // If the destination is HTTPS, tunnel. - if (request.uri.protocol === 'https:') { - return true - } +var _GraphQLError = __nccwpck_require__(4797); - // Otherwise, do not use tunnel. - return false -} +/** + * Unique variable names + * + * A GraphQL operation is only valid if all its variables are uniquely named. + */ +function UniqueVariableNamesRule(context) { + return { + OperationDefinition(operationNode) { + var _operationNode$variab; -Tunnel.prototype.setup = function (options) { - var self = this - var request = self.request + // See: https://github.com/graphql/graphql-js/issues/2203 - options = options || {} + /* c8 ignore next */ + const variableDefinitions = + (_operationNode$variab = operationNode.variableDefinitions) !== null && + _operationNode$variab !== void 0 + ? _operationNode$variab + : []; + const seenVariableDefinitions = (0, _groupBy.groupBy)( + variableDefinitions, + (node) => node.variable.name.value, + ); - if (typeof request.proxy === 'string') { - request.proxy = url.parse(request.proxy) - } + for (const [variableName, variableNodes] of seenVariableDefinitions) { + if (variableNodes.length > 1) { + context.reportError( + new _GraphQLError.GraphQLError( + `There can be only one variable named "$${variableName}".`, + { + nodes: variableNodes.map((node) => node.variable.name), + }, + ), + ); + } + } + }, + }; +} - if (!request.proxy || !request.tunnel) { - return false - } - // Setup Proxy Header Exclusive List and White List - if (options.proxyHeaderWhiteList) { - self.proxyHeaderWhiteList = options.proxyHeaderWhiteList - } - if (options.proxyHeaderExclusiveList) { - self.proxyHeaderExclusiveList = options.proxyHeaderExclusiveList - } +/***/ }), - var proxyHeaderExclusiveList = self.proxyHeaderExclusiveList.concat(defaultProxyHeaderExclusiveList) - var proxyHeaderWhiteList = self.proxyHeaderWhiteList.concat(proxyHeaderExclusiveList) +/***/ 39091: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // Setup Proxy Headers and Proxy Headers Host - // Only send the Proxy White Listed Header names - var proxyHeaders = constructProxyHeaderWhiteList(request.headers, proxyHeaderWhiteList) - proxyHeaders.host = constructProxyHost(request.uri) +"use strict"; - proxyHeaderExclusiveList.forEach(request.removeHeader, request) - // Set Agent from Tunnel Data - var tunnelFn = getTunnelFn(request) - var tunnelOptions = constructTunnelOptions(request, proxyHeaders) - request.agent = tunnelFn(tunnelOptions) +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.ValuesOfCorrectTypeRule = ValuesOfCorrectTypeRule; - return true -} +var _didYouMean = __nccwpck_require__(42878); -Tunnel.defaultProxyHeaderWhiteList = defaultProxyHeaderWhiteList -Tunnel.defaultProxyHeaderExclusiveList = defaultProxyHeaderExclusiveList -exports.n = Tunnel +var _inspect = __nccwpck_require__(10102); +var _keyMap = __nccwpck_require__(10711); -/***/ }), +var _suggestionList = __nccwpck_require__(57704); -/***/ 11377: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var _GraphQLError = __nccwpck_require__(4797); -var CombinedStream = __nccwpck_require__(85443); -var util = __nccwpck_require__(73837); -var path = __nccwpck_require__(71017); -var http = __nccwpck_require__(13685); -var https = __nccwpck_require__(95687); -var parseUrl = (__nccwpck_require__(57310).parse); -var fs = __nccwpck_require__(57147); -var mime = __nccwpck_require__(43583); -var asynckit = __nccwpck_require__(14812); -var populate = __nccwpck_require__(94932); +var _kinds = __nccwpck_require__(11927); -// Public API -module.exports = FormData; +var _printer = __nccwpck_require__(68203); -// make it a Stream -util.inherits(FormData, CombinedStream); +var _definition = __nccwpck_require__(5821); /** - * Create readable "multipart/form-data" streams. - * Can be used to submit forms - * and file uploads to other web applications. + * Value literals of correct type + * + * A GraphQL document is only valid if all value literals are of the type + * expected at their position. * - * @constructor - * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream + * See https://spec.graphql.org/draft/#sec-Values-of-Correct-Type */ -function FormData(options) { - if (!(this instanceof FormData)) { - return new FormData(); - } - - this._overheadLength = 0; - this._valueLength = 0; - this._valuesToMeasure = []; +function ValuesOfCorrectTypeRule(context) { + return { + ListValue(node) { + // Note: TypeInfo will traverse into a list's item type, so look to the + // parent input type to check if it is a list. + const type = (0, _definition.getNullableType)( + context.getParentInputType(), + ); - CombinedStream.call(this); + if (!(0, _definition.isListType)(type)) { + isValidValueNode(context, node); + return false; // Don't traverse further. + } + }, - options = options || {}; - for (var option in options) { - this[option] = options[option]; - } -} + ObjectValue(node) { + const type = (0, _definition.getNamedType)(context.getInputType()); -FormData.LINE_BREAK = '\r\n'; -FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; + if (!(0, _definition.isInputObjectType)(type)) { + isValidValueNode(context, node); + return false; // Don't traverse further. + } // Ensure every required field exists. -FormData.prototype.append = function(field, value, options) { + const fieldNodeMap = (0, _keyMap.keyMap)( + node.fields, + (field) => field.name.value, + ); - options = options || {}; + for (const fieldDef of Object.values(type.getFields())) { + const fieldNode = fieldNodeMap[fieldDef.name]; - // allow filename as single option - if (typeof options == 'string') { - options = {filename: options}; - } + if (!fieldNode && (0, _definition.isRequiredInputField)(fieldDef)) { + const typeStr = (0, _inspect.inspect)(fieldDef.type); + context.reportError( + new _GraphQLError.GraphQLError( + `Field "${type.name}.${fieldDef.name}" of required type "${typeStr}" was not provided.`, + { + nodes: node, + }, + ), + ); + } + } - var append = CombinedStream.prototype.append.bind(this); + if (type.isOneOf) { + validateOneOfInputObject(context, node, type, fieldNodeMap); + } + }, - // all that streamy business can't handle numbers - if (typeof value == 'number') { - value = '' + value; - } + ObjectField(node) { + const parentType = (0, _definition.getNamedType)( + context.getParentInputType(), + ); + const fieldType = context.getInputType(); - // https://github.com/felixge/node-form-data/issues/38 - if (util.isArray(value)) { - // Please convert your array into string - // the way web server expects it - this._error(new Error('Arrays are not supported.')); - return; - } + if (!fieldType && (0, _definition.isInputObjectType)(parentType)) { + const suggestions = (0, _suggestionList.suggestionList)( + node.name.value, + Object.keys(parentType.getFields()), + ); + context.reportError( + new _GraphQLError.GraphQLError( + `Field "${node.name.value}" is not defined by type "${parentType.name}".` + + (0, _didYouMean.didYouMean)(suggestions), + { + nodes: node, + }, + ), + ); + } + }, - var header = this._multiPartHeader(field, value, options); - var footer = this._multiPartFooter(); + NullValue(node) { + const type = context.getInputType(); - append(header); - append(value); - append(footer); + if ((0, _definition.isNonNullType)(type)) { + context.reportError( + new _GraphQLError.GraphQLError( + `Expected value of type "${(0, _inspect.inspect)( + type, + )}", found ${(0, _printer.print)(node)}.`, + { + nodes: node, + }, + ), + ); + } + }, - // pass along options.knownLength - this._trackLength(header, value, options); -}; + EnumValue: (node) => isValidValueNode(context, node), + IntValue: (node) => isValidValueNode(context, node), + FloatValue: (node) => isValidValueNode(context, node), + // Descriptions are string values that would not validate according + // to the below logic, but since (per the specification) descriptions must + // not affect validation, they are ignored entirely when visiting the AST + // and do not require special handling. + // See https://spec.graphql.org/draft/#sec-Descriptions + StringValue: (node) => isValidValueNode(context, node), + BooleanValue: (node) => isValidValueNode(context, node), + }; +} +/** + * Any value literal may be a valid representation of a Scalar, depending on + * that scalar type. + */ -FormData.prototype._trackLength = function(header, value, options) { - var valueLength = 0; +function isValidValueNode(context, node) { + // Report any error at the full type expected by the location. + const locationType = context.getInputType(); - // used w/ getLengthSync(), when length is known. - // e.g. for streaming directly from a remote server, - // w/ a known file a size, and not wanting to wait for - // incoming file to finish to get its size. - if (options.knownLength != null) { - valueLength += +options.knownLength; - } else if (Buffer.isBuffer(value)) { - valueLength = value.length; - } else if (typeof value === 'string') { - valueLength = Buffer.byteLength(value); + if (!locationType) { + return; } - this._valueLength += valueLength; - - // @check why add CRLF? does this account for custom/multiple CRLFs? - this._overheadLength += - Buffer.byteLength(header) + - FormData.LINE_BREAK.length; + const type = (0, _definition.getNamedType)(locationType); - // empty or either doesn't have path or not an http response - if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) { + if (!(0, _definition.isLeafType)(type)) { + const typeStr = (0, _inspect.inspect)(locationType); + context.reportError( + new _GraphQLError.GraphQLError( + `Expected value of type "${typeStr}", found ${(0, _printer.print)( + node, + )}.`, + { + nodes: node, + }, + ), + ); return; - } - - // no need to bother with the length - if (!options.knownLength) { - this._valuesToMeasure.push(value); - } -}; + } // Scalars and Enums determine if a literal value is valid via parseLiteral(), + // which may throw or return an invalid value to indicate failure. -FormData.prototype._lengthRetriever = function(value, callback) { + try { + const parseResult = type.parseLiteral( + node, + undefined, + /* variables */ + ); - if (value.hasOwnProperty('fd')) { + if (parseResult === undefined) { + const typeStr = (0, _inspect.inspect)(locationType); + context.reportError( + new _GraphQLError.GraphQLError( + `Expected value of type "${typeStr}", found ${(0, _printer.print)( + node, + )}.`, + { + nodes: node, + }, + ), + ); + } + } catch (error) { + const typeStr = (0, _inspect.inspect)(locationType); - // take read range into a account - // `end` = Infinity –> read file till the end - // - // TODO: Looks like there is bug in Node fs.createReadStream - // it doesn't respect `end` options without `start` options - // Fix it when node fixes it. - // https://github.com/joyent/node/issues/7819 - if (value.end != undefined && value.end != Infinity && value.start != undefined) { - - // when end specified - // no need to calculate range - // inclusive, starts with 0 - callback(null, value.end + 1 - (value.start ? value.start : 0)); - - // not that fast snoopy + if (error instanceof _GraphQLError.GraphQLError) { + context.reportError(error); } else { - // still need to fetch file size from fs - fs.stat(value.path, function(err, stat) { - - var fileSize; - - if (err) { - callback(err); - return; - } - - // update final size based on the range options - fileSize = stat.size - (value.start ? value.start : 0); - callback(null, fileSize); - }); + context.reportError( + new _GraphQLError.GraphQLError( + `Expected value of type "${typeStr}", found ${(0, _printer.print)( + node, + )}; ` + error.message, + { + nodes: node, + originalError: error, + }, + ), + ); } + } +} - // or http response - } else if (value.hasOwnProperty('httpVersion')) { - callback(null, +value.headers['content-length']); - - // or request stream http://github.com/mikeal/request - } else if (value.hasOwnProperty('httpModule')) { - // wait till response come back - value.on('response', function(response) { - value.pause(); - callback(null, +response.headers['content-length']); - }); - value.resume(); +function validateOneOfInputObject(context, node, type, fieldNodeMap) { + var _fieldNodeMap$keys$; - // something else - } else { - callback('Unknown stream'); - } -}; + const keys = Object.keys(fieldNodeMap); + const isNotExactlyOneField = keys.length !== 1; -FormData.prototype._multiPartHeader = function(field, value, options) { - // custom header specified (as string)? - // it becomes responsible for boundary - // (e.g. to handle extra CRLFs on .NET servers) - if (typeof options.header == 'string') { - return options.header; + if (isNotExactlyOneField) { + context.reportError( + new _GraphQLError.GraphQLError( + `OneOf Input Object "${type.name}" must specify exactly one key.`, + { + nodes: [node], + }, + ), + ); + return; } - var contentDisposition = this._getContentDisposition(value, options); - var contentType = this._getContentType(value, options); - - var contents = ''; - var headers = { - // add custom disposition as third element or keep it two elements if not - 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), - // if no content type. allow it to be empty array - 'Content-Type': [].concat(contentType || []) - }; + const value = + (_fieldNodeMap$keys$ = fieldNodeMap[keys[0]]) === null || + _fieldNodeMap$keys$ === void 0 + ? void 0 + : _fieldNodeMap$keys$.value; + const isNullLiteral = !value || value.kind === _kinds.Kind.NULL; - // allow custom headers. - if (typeof options.header == 'object') { - populate(headers, options.header); + if (isNullLiteral) { + context.reportError( + new _GraphQLError.GraphQLError( + `Field "${type.name}.${keys[0]}" must be non-null.`, + { + nodes: [node], + }, + ), + ); } +} - var header; - for (var prop in headers) { - if (!headers.hasOwnProperty(prop)) continue; - header = headers[prop]; - - // skip nullish headers. - if (header == null) { - continue; - } - // convert all headers to arrays. - if (!Array.isArray(header)) { - header = [header]; - } +/***/ }), - // add non-empty headers. - if (header.length) { - contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; - } - } +/***/ 99506: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; -}; +"use strict"; -FormData.prototype._getContentDisposition = function(value, options) { - var filename - , contentDisposition - ; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.VariablesAreInputTypesRule = VariablesAreInputTypesRule; - if (typeof options.filepath === 'string') { - // custom filepath for relative paths - filename = path.normalize(options.filepath).replace(/\\/g, '/'); - } else if (options.filename || value.name || value.path) { - // custom filename take precedence - // formidable and the browser add a name property - // fs- and request- streams have path property - filename = path.basename(options.filename || value.name || value.path); - } else if (value.readable && value.hasOwnProperty('httpVersion')) { - // or try http response - filename = path.basename(value.client._httpMessage.path); - } +var _GraphQLError = __nccwpck_require__(4797); - if (filename) { - contentDisposition = 'filename="' + filename + '"'; - } +var _printer = __nccwpck_require__(68203); - return contentDisposition; -}; +var _definition = __nccwpck_require__(5821); -FormData.prototype._getContentType = function(value, options) { +var _typeFromAST = __nccwpck_require__(27664); - // use custom content-type above all - var contentType = options.contentType; +/** + * Variables are input types + * + * A GraphQL operation is only valid if all the variables it defines are of + * input types (scalar, enum, or input object). + * + * See https://spec.graphql.org/draft/#sec-Variables-Are-Input-Types + */ +function VariablesAreInputTypesRule(context) { + return { + VariableDefinition(node) { + const type = (0, _typeFromAST.typeFromAST)( + context.getSchema(), + node.type, + ); - // or try `name` from formidable, browser - if (!contentType && value.name) { - contentType = mime.lookup(value.name); - } + if (type !== undefined && !(0, _definition.isInputType)(type)) { + const variableName = node.variable.name.value; + const typeName = (0, _printer.print)(node.type); + context.reportError( + new _GraphQLError.GraphQLError( + `Variable "$${variableName}" cannot be non-input type "${typeName}".`, + { + nodes: node.type, + }, + ), + ); + } + }, + }; +} - // or try `path` from fs-, request- streams - if (!contentType && value.path) { - contentType = mime.lookup(value.path); - } - // or if it's http-reponse - if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { - contentType = value.headers['content-type']; - } +/***/ }), - // or guess it from the filepath or filename - if (!contentType && (options.filepath || options.filename)) { - contentType = mime.lookup(options.filepath || options.filename); - } +/***/ 8815: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // fallback to the default content type if `value` is not simple value - if (!contentType && typeof value == 'object') { - contentType = FormData.DEFAULT_CONTENT_TYPE; - } +"use strict"; - return contentType; -}; -FormData.prototype._multiPartFooter = function() { - return function(next) { - var footer = FormData.LINE_BREAK; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.VariablesInAllowedPositionRule = VariablesInAllowedPositionRule; - var lastPart = (this._streams.length === 0); - if (lastPart) { - footer += this._lastBoundary(); - } +var _inspect = __nccwpck_require__(10102); - next(footer); - }.bind(this); -}; +var _GraphQLError = __nccwpck_require__(4797); -FormData.prototype._lastBoundary = function() { - return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; -}; +var _kinds = __nccwpck_require__(11927); -FormData.prototype.getHeaders = function(userHeaders) { - var header; - var formHeaders = { - 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() - }; +var _definition = __nccwpck_require__(5821); - for (header in userHeaders) { - if (userHeaders.hasOwnProperty(header)) { - formHeaders[header.toLowerCase()] = userHeaders[header]; - } - } +var _typeComparators = __nccwpck_require__(10333); - return formHeaders; -}; +var _typeFromAST = __nccwpck_require__(27664); -FormData.prototype.getBoundary = function() { - if (!this._boundary) { - this._generateBoundary(); - } +/** + * Variables in allowed position + * + * Variable usages must be compatible with the arguments they are passed to. + * + * See https://spec.graphql.org/draft/#sec-All-Variable-Usages-are-Allowed + */ +function VariablesInAllowedPositionRule(context) { + let varDefMap = Object.create(null); + return { + OperationDefinition: { + enter() { + varDefMap = Object.create(null); + }, - return this._boundary; -}; + leave(operation) { + const usages = context.getRecursiveVariableUsages(operation); -FormData.prototype._generateBoundary = function() { - // This generates a 50 character boundary similar to those used by Firefox. - // They are optimized for boyer-moore parsing. - var boundary = '--------------------------'; - for (var i = 0; i < 24; i++) { - boundary += Math.floor(Math.random() * 10).toString(16); - } + for (const { node, type, defaultValue, parentType } of usages) { + const varName = node.name.value; + const varDef = varDefMap[varName]; - this._boundary = boundary; -}; + if (varDef && type) { + // A var type is allowed if it is the same or more strict (e.g. is + // a subtype of) than the expected type. It can be more strict if + // the variable type is non-null when the expected type is nullable. + // If both are list types, the variable item type can be more strict + // than the expected item type (contravariant). + const schema = context.getSchema(); + const varType = (0, _typeFromAST.typeFromAST)(schema, varDef.type); -// Note: getLengthSync DOESN'T calculate streams length -// As workaround one can calculate file size manually -// and add it as knownLength option -FormData.prototype.getLengthSync = function() { - var knownLength = this._overheadLength + this._valueLength; + if ( + varType && + !allowedVariableUsage( + schema, + varType, + varDef.defaultValue, + type, + defaultValue, + ) + ) { + const varTypeStr = (0, _inspect.inspect)(varType); + const typeStr = (0, _inspect.inspect)(type); + context.reportError( + new _GraphQLError.GraphQLError( + `Variable "$${varName}" of type "${varTypeStr}" used in position expecting type "${typeStr}".`, + { + nodes: [varDef, node], + }, + ), + ); + } - // Don't get confused, there are 3 "internal" streams for each keyval pair - // so it basically checks if there is any value added to the form - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } + if ( + (0, _definition.isInputObjectType)(parentType) && + parentType.isOneOf && + (0, _definition.isNullableType)(varType) + ) { + context.reportError( + new _GraphQLError.GraphQLError( + `Variable "$${varName}" is of type "${varType}" but must be non-nullable to be used for OneOf Input Object "${parentType}".`, + { + nodes: [varDef, node], + }, + ), + ); + } + } + } + }, + }, - // https://github.com/form-data/form-data/issues/40 - if (!this.hasKnownLength()) { - // Some async length retrievers are present - // therefore synchronous length calculation is false. - // Please use getLength(callback) to get proper length - this._error(new Error('Cannot calculate proper length in synchronous way.')); - } + VariableDefinition(node) { + varDefMap[node.variable.name.value] = node; + }, + }; +} +/** + * Returns true if the variable is allowed in the location it was found, + * which includes considering if default values exist for either the variable + * or the location at which it is located. + */ - return knownLength; -}; +function allowedVariableUsage( + schema, + varType, + varDefaultValue, + locationType, + locationDefaultValue, +) { + if ( + (0, _definition.isNonNullType)(locationType) && + !(0, _definition.isNonNullType)(varType) + ) { + const hasNonNullVariableDefaultValue = + varDefaultValue != null && varDefaultValue.kind !== _kinds.Kind.NULL; + const hasLocationDefaultValue = locationDefaultValue !== undefined; -// Public API to check if length of added values is known -// https://github.com/form-data/form-data/issues/196 -// https://github.com/form-data/form-data/issues/262 -FormData.prototype.hasKnownLength = function() { - var hasKnownLength = true; + if (!hasNonNullVariableDefaultValue && !hasLocationDefaultValue) { + return false; + } - if (this._valuesToMeasure.length) { - hasKnownLength = false; + const nullableLocationType = locationType.ofType; + return (0, _typeComparators.isTypeSubTypeOf)( + schema, + varType, + nullableLocationType, + ); } - return hasKnownLength; -}; + return (0, _typeComparators.isTypeSubTypeOf)(schema, varType, locationType); +} -FormData.prototype.getLength = function(cb) { - var knownLength = this._overheadLength + this._valueLength; - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } +/***/ }), - if (!this._valuesToMeasure.length) { - process.nextTick(cb.bind(this, null, knownLength)); - return; - } +/***/ 33915: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { - if (err) { - cb(err); - return; - } +"use strict"; - values.forEach(function(length) { - knownLength += length; - }); - cb(null, knownLength); - }); -}; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.NoDeprecatedCustomRule = NoDeprecatedCustomRule; -FormData.prototype.submit = function(params, cb) { - var request - , options - , defaults = {method: 'post'} - ; +var _invariant = __nccwpck_require__(28847); - // parse provided url if it's string - // or treat it as options object - if (typeof params == 'string') { +var _GraphQLError = __nccwpck_require__(4797); - params = parseUrl(params); - options = populate({ - port: params.port, - path: params.pathname, - host: params.hostname, - protocol: params.protocol - }, defaults); +var _definition = __nccwpck_require__(5821); - // use custom params - } else { +/** + * No deprecated + * + * A GraphQL document is only valid if all selected fields and all used enum values have not been + * deprecated. + * + * Note: This rule is optional and is not part of the Validation section of the GraphQL + * Specification. The main purpose of this rule is detection of deprecated usages and not + * necessarily to forbid their use when querying a service. + */ +function NoDeprecatedCustomRule(context) { + return { + Field(node) { + const fieldDef = context.getFieldDef(); + const deprecationReason = + fieldDef === null || fieldDef === void 0 + ? void 0 + : fieldDef.deprecationReason; - options = populate(params, defaults); - // if no port provided use default one - if (!options.port) { - options.port = options.protocol == 'https:' ? 443 : 80; - } - } + if (fieldDef && deprecationReason != null) { + const parentType = context.getParentType(); + parentType != null || (0, _invariant.invariant)(false); + context.reportError( + new _GraphQLError.GraphQLError( + `The field ${parentType.name}.${fieldDef.name} is deprecated. ${deprecationReason}`, + { + nodes: node, + }, + ), + ); + } + }, - // put that good code in getHeaders to some use - options.headers = this.getHeaders(params.headers); + Argument(node) { + const argDef = context.getArgument(); + const deprecationReason = + argDef === null || argDef === void 0 + ? void 0 + : argDef.deprecationReason; - // https if specified, fallback to http in any other case - if (options.protocol == 'https:') { - request = https.request(options); - } else { - request = http.request(options); - } + if (argDef && deprecationReason != null) { + const directiveDef = context.getDirective(); - // get content length and fire away - this.getLength(function(err, length) { - if (err) { - this._error(err); - return; - } + if (directiveDef != null) { + context.reportError( + new _GraphQLError.GraphQLError( + `Directive "@${directiveDef.name}" argument "${argDef.name}" is deprecated. ${deprecationReason}`, + { + nodes: node, + }, + ), + ); + } else { + const parentType = context.getParentType(); + const fieldDef = context.getFieldDef(); + (parentType != null && fieldDef != null) || + (0, _invariant.invariant)(false); + context.reportError( + new _GraphQLError.GraphQLError( + `Field "${parentType.name}.${fieldDef.name}" argument "${argDef.name}" is deprecated. ${deprecationReason}`, + { + nodes: node, + }, + ), + ); + } + } + }, - // add content length - request.setHeader('Content-Length', length); + ObjectField(node) { + const inputObjectDef = (0, _definition.getNamedType)( + context.getParentInputType(), + ); - this.pipe(request); - if (cb) { - request.on('error', cb); - request.on('response', cb.bind(this, null)); - } - }.bind(this)); + if ((0, _definition.isInputObjectType)(inputObjectDef)) { + const inputFieldDef = inputObjectDef.getFields()[node.name.value]; + const deprecationReason = + inputFieldDef === null || inputFieldDef === void 0 + ? void 0 + : inputFieldDef.deprecationReason; - return request; -}; + if (deprecationReason != null) { + context.reportError( + new _GraphQLError.GraphQLError( + `The input field ${inputObjectDef.name}.${inputFieldDef.name} is deprecated. ${deprecationReason}`, + { + nodes: node, + }, + ), + ); + } + } + }, -FormData.prototype._error = function(err) { - if (!this.error) { - this.error = err; - this.pause(); - this.emit('error', err); - } -}; + EnumValue(node) { + const enumValueDef = context.getEnumValue(); + const deprecationReason = + enumValueDef === null || enumValueDef === void 0 + ? void 0 + : enumValueDef.deprecationReason; -FormData.prototype.toString = function () { - return '[object FormData]'; -}; + if (enumValueDef && deprecationReason != null) { + const enumTypeDef = (0, _definition.getNamedType)( + context.getInputType(), + ); + enumTypeDef != null || (0, _invariant.invariant)(false); + context.reportError( + new _GraphQLError.GraphQLError( + `The enum value "${enumTypeDef.name}.${enumValueDef.name}" is deprecated. ${deprecationReason}`, + { + nodes: node, + }, + ), + ); + } + }, + }; +} /***/ }), -/***/ 94932: -/***/ ((module) => { +/***/ 39478: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -// populates missing values -module.exports = function(dst, src) { +"use strict"; - Object.keys(src).forEach(function(prop) - { - dst[prop] = dst[prop] || src[prop]; - }); - return dst; -}; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.NoSchemaIntrospectionCustomRule = NoSchemaIntrospectionCustomRule; +var _GraphQLError = __nccwpck_require__(4797); -/***/ }), +var _definition = __nccwpck_require__(5821); -/***/ 67087: -/***/ ((module) => { +var _introspection = __nccwpck_require__(28344); /** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + * Prohibit introspection queries + * + * A GraphQL document is only valid if all fields selected are not fields that + * return an introspection type. + * + * Note: This rule is optional and is not part of the Validation section of the + * GraphQL Specification. This rule effectively disables introspection, which + * does not reflect best practices and should only be done if absolutely necessary. */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} +function NoSchemaIntrospectionCustomRule(context) { + return { + Field(node) { + const type = (0, _definition.getNamedType)(context.getType()); -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([ - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]] - ]).join(''); + if (type && (0, _introspection.isIntrospectionType)(type)) { + context.reportError( + new _GraphQLError.GraphQLError( + `GraphQL introspection has been disabled, but the requested query contained the field "${node.name.value}".`, + { + nodes: node, + }, + ), + ); + } + }, + }; } -module.exports = bytesToUuid; - /***/ }), -/***/ 9117: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 84908: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -// Unique ID creation requires a high quality random # generator. In node.js -// this is pretty straight-forward - we use the crypto API. +"use strict"; -var crypto = __nccwpck_require__(6113); -module.exports = function nodeRNG() { - return crypto.randomBytes(16); -}; +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.specifiedSDLRules = + exports.specifiedRules = + exports.recommendedRules = + void 0; +var _ExecutableDefinitionsRule = __nccwpck_require__(89199); -/***/ }), +var _FieldsOnCorrectTypeRule = __nccwpck_require__(63016); -/***/ 71435: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var _FragmentsOnCompositeTypesRule = __nccwpck_require__(60381); -var rng = __nccwpck_require__(9117); -var bytesToUuid = __nccwpck_require__(67087); +var _KnownArgumentNamesRule = __nccwpck_require__(67147); -function v4(options, buf, offset) { - var i = buf && offset || 0; +var _KnownDirectivesRule = __nccwpck_require__(85303); - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; +var _KnownFragmentNamesRule = __nccwpck_require__(15166); - var rnds = options.random || (options.rng || rng)(); +var _KnownTypeNamesRule = __nccwpck_require__(42509); - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; +var _LoneAnonymousOperationRule = __nccwpck_require__(45726); - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } +var _LoneSchemaDefinitionRule = __nccwpck_require__(48307); - return buf || bytesToUuid(rnds); -} +var _MaxIntrospectionDepthRule = __nccwpck_require__(53318); -module.exports = v4; +var _NoFragmentCyclesRule = __nccwpck_require__(62564); +var _NoUndefinedVariablesRule = __nccwpck_require__(61671); -/***/ }), +var _NoUnusedFragmentsRule = __nccwpck_require__(192); -/***/ 70304: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var _NoUnusedVariablesRule = __nccwpck_require__(40242); -"use strict"; +var _OverlappingFieldsCanBeMergedRule = __nccwpck_require__(23577); +var _PossibleFragmentSpreadsRule = __nccwpck_require__(62450); -var http = __nccwpck_require__(13685) -var https = __nccwpck_require__(95687) -var url = __nccwpck_require__(57310) -var util = __nccwpck_require__(73837) -var stream = __nccwpck_require__(12781) -var zlib = __nccwpck_require__(59796) -var aws2 = __nccwpck_require__(96342) -var aws4 = __nccwpck_require__(16071) -var httpSignature = __nccwpck_require__(42479) -var mime = __nccwpck_require__(43583) -var caseless = __nccwpck_require__(35684) -var ForeverAgent = __nccwpck_require__(47568) -var FormData = __nccwpck_require__(11377) -var extend = __nccwpck_require__(38171) -var isstream = __nccwpck_require__(83362) -var isTypedArray = (__nccwpck_require__(10657).strict) -var helpers = __nccwpck_require__(74845) -var cookies = __nccwpck_require__(50976) -var getProxyFromURI = __nccwpck_require__(75654) -var Querystring = (__nccwpck_require__(66476)/* .Querystring */ .h) -var Har = (__nccwpck_require__(3248)/* .Har */ .t) -var Auth = (__nccwpck_require__(76996)/* .Auth */ .g) -var OAuth = (__nccwpck_require__(41174)/* .OAuth */ .f) -var hawk = __nccwpck_require__(34473) -var Multipart = (__nccwpck_require__(87810)/* .Multipart */ .$) -var Redirect = (__nccwpck_require__(3048)/* .Redirect */ .l) -var Tunnel = (__nccwpck_require__(17619)/* .Tunnel */ .n) -var now = __nccwpck_require__(85644) -var Buffer = (__nccwpck_require__(21867).Buffer) - -var safeStringify = helpers.safeStringify -var isReadStream = helpers.isReadStream -var toBase64 = helpers.toBase64 -var defer = helpers.defer -var copy = helpers.copy -var version = helpers.version -var globalCookieJar = cookies.jar() - -var globalPool = {} - -function filterForNonReserved (reserved, options) { - // Filter out properties that are not reserved. - // Reserved values are passed in at call site. - - var object = {} - for (var i in options) { - var notReserved = (reserved.indexOf(i) === -1) - if (notReserved) { - object[i] = options[i] - } - } - return object -} - -function filterOutReservedFunctions (reserved, options) { - // Filter out properties that are functions and are reserved. - // Reserved values are passed in at call site. - - var object = {} - for (var i in options) { - var isReserved = !(reserved.indexOf(i) === -1) - var isFunction = (typeof options[i] === 'function') - if (!(isReserved && isFunction)) { - object[i] = options[i] - } - } - return object -} - -// Return a simpler request object to allow serialization -function requestToJSON () { - var self = this - return { - uri: self.uri, - method: self.method, - headers: self.headers - } -} +var _PossibleTypeExtensionsRule = __nccwpck_require__(70075); -// Return a simpler response object to allow serialization -function responseToJSON () { - var self = this - return { - statusCode: self.statusCode, - body: self.body, - headers: self.headers, - request: requestToJSON.call(self.request) - } -} +var _ProvidedRequiredArgumentsRule = __nccwpck_require__(57669); -function Request (options) { - // if given the method property in options, set property explicitMethod to true +var _ScalarLeafsRule = __nccwpck_require__(16830); - // extend the Request instance with any non-reserved properties - // remove any reserved functions from the options object - // set Request instance to be readable and writable - // call init +var _SingleFieldSubscriptionsRule = __nccwpck_require__(4365); - var self = this +var _UniqueArgumentDefinitionNamesRule = __nccwpck_require__(55104); - // start with HAR, then override with additional options - if (options.har) { - self._har = new Har(self) - options = self._har.options(options) - } +var _UniqueArgumentNamesRule = __nccwpck_require__(45799); - stream.Stream.call(self) - var reserved = Object.keys(Request.prototype) - var nonReserved = filterForNonReserved(reserved, options) +var _UniqueDirectiveNamesRule = __nccwpck_require__(17074); - extend(self, nonReserved) - options = filterOutReservedFunctions(reserved, options) +var _UniqueDirectivesPerLocationRule = __nccwpck_require__(61944); - self.readable = true - self.writable = true - if (options.method) { - self.explicitMethod = true - } - self._qs = new Querystring(self) - self._auth = new Auth(self) - self._oauth = new OAuth(self) - self._multipart = new Multipart(self) - self._redirect = new Redirect(self) - self._tunnel = new Tunnel(self) - self.init(options) -} +var _UniqueEnumValueNamesRule = __nccwpck_require__(44437); -util.inherits(Request, stream.Stream) +var _UniqueFieldDefinitionNamesRule = __nccwpck_require__(9502); -// Debugging -Request.debug = process.env.NODE_DEBUG && /\brequest\b/.test(process.env.NODE_DEBUG) -function debug () { - if (Request.debug) { - console.error('REQUEST %s', util.format.apply(util, arguments)) - } -} -Request.prototype.debug = debug +var _UniqueFragmentNamesRule = __nccwpck_require__(79402); -Request.prototype.init = function (options) { - // init() contains all the code to setup the request object. - // the actual outgoing request is not started until start() is called - // this function is called from both the constructor and on redirect. - var self = this - if (!options) { - options = {} - } - self.headers = self.headers ? copy(self.headers) : {} +var _UniqueInputFieldNamesRule = __nccwpck_require__(83552); - // Delete headers with value undefined since they break - // ClientRequest.OutgoingMessage.setHeader in node 0.12 - for (var headerName in self.headers) { - if (typeof self.headers[headerName] === 'undefined') { - delete self.headers[headerName] - } - } +var _UniqueOperationNamesRule = __nccwpck_require__(94865); - caseless.httpify(self, self.headers) +var _UniqueOperationTypesRule = __nccwpck_require__(31492); - if (!self.method) { - self.method = options.method || 'GET' - } - if (!self.localAddress) { - self.localAddress = options.localAddress - } +var _UniqueTypeNamesRule = __nccwpck_require__(24316); - self._qs.init(options) +var _UniqueVariableNamesRule = __nccwpck_require__(65931); - debug(options) - if (!self.pool && self.pool !== false) { - self.pool = globalPool - } - self.dests = self.dests || [] - self.__isRequestRequest = true +var _ValuesOfCorrectTypeRule = __nccwpck_require__(39091); - // Protect against double callback - if (!self._callback && self.callback) { - self._callback = self.callback - self.callback = function () { - if (self._callbackCalled) { - return // Print a warning maybe? - } - self._callbackCalled = true - self._callback.apply(self, arguments) - } - self.on('error', self.callback.bind()) - self.on('complete', self.callback.bind(self, null)) - } +var _VariablesAreInputTypesRule = __nccwpck_require__(99506); - // People use this property instead all the time, so support it - if (!self.uri && self.url) { - self.uri = self.url - delete self.url - } +var _VariablesInAllowedPositionRule = __nccwpck_require__(8815); - // If there's a baseUrl, then use it as the base URL (i.e. uri must be - // specified as a relative path and is appended to baseUrl). - if (self.baseUrl) { - if (typeof self.baseUrl !== 'string') { - return self.emit('error', new Error('options.baseUrl must be a string')) - } +// Spec Section: "Executable Definitions" +// Spec Section: "Field Selections on Objects, Interfaces, and Unions Types" +// Spec Section: "Fragments on Composite Types" +// Spec Section: "Argument Names" +// Spec Section: "Directives Are Defined" +// Spec Section: "Fragment spread target defined" +// Spec Section: "Fragment Spread Type Existence" +// Spec Section: "Lone Anonymous Operation" +// SDL-specific validation rules +// TODO: Spec Section +// Spec Section: "Fragments must not form cycles" +// Spec Section: "All Variable Used Defined" +// Spec Section: "Fragments must be used" +// Spec Section: "All Variables Used" +// Spec Section: "Field Selection Merging" +// Spec Section: "Fragment spread is possible" +// Spec Section: "Argument Optionality" +// Spec Section: "Leaf Field Selections" +// Spec Section: "Subscriptions with Single Root Field" +// Spec Section: "Argument Uniqueness" +// Spec Section: "Directives Are Unique Per Location" +// Spec Section: "Fragment Name Uniqueness" +// Spec Section: "Input Object Field Uniqueness" +// Spec Section: "Operation Name Uniqueness" +// Spec Section: "Variable Uniqueness" +// Spec Section: "Value Type Correctness" +// Spec Section: "Variables are Input Types" +// Spec Section: "All Variable Usages Are Allowed" - if (typeof self.uri !== 'string') { - return self.emit('error', new Error('options.uri must be a string when using options.baseUrl')) - } +/** + * Technically these aren't part of the spec but they are strongly encouraged + * validation rules. + */ +const recommendedRules = Object.freeze([ + _MaxIntrospectionDepthRule.MaxIntrospectionDepthRule, +]); +/** + * This set includes all validation rules defined by the GraphQL spec. + * + * The order of the rules in this list has been adjusted to lead to the + * most clear output when encountering multiple validation errors. + */ - if (self.uri.indexOf('//') === 0 || self.uri.indexOf('://') !== -1) { - return self.emit('error', new Error('options.uri must be a path when using options.baseUrl')) - } +exports.recommendedRules = recommendedRules; +const specifiedRules = Object.freeze([ + _ExecutableDefinitionsRule.ExecutableDefinitionsRule, + _UniqueOperationNamesRule.UniqueOperationNamesRule, + _LoneAnonymousOperationRule.LoneAnonymousOperationRule, + _SingleFieldSubscriptionsRule.SingleFieldSubscriptionsRule, + _KnownTypeNamesRule.KnownTypeNamesRule, + _FragmentsOnCompositeTypesRule.FragmentsOnCompositeTypesRule, + _VariablesAreInputTypesRule.VariablesAreInputTypesRule, + _ScalarLeafsRule.ScalarLeafsRule, + _FieldsOnCorrectTypeRule.FieldsOnCorrectTypeRule, + _UniqueFragmentNamesRule.UniqueFragmentNamesRule, + _KnownFragmentNamesRule.KnownFragmentNamesRule, + _NoUnusedFragmentsRule.NoUnusedFragmentsRule, + _PossibleFragmentSpreadsRule.PossibleFragmentSpreadsRule, + _NoFragmentCyclesRule.NoFragmentCyclesRule, + _UniqueVariableNamesRule.UniqueVariableNamesRule, + _NoUndefinedVariablesRule.NoUndefinedVariablesRule, + _NoUnusedVariablesRule.NoUnusedVariablesRule, + _KnownDirectivesRule.KnownDirectivesRule, + _UniqueDirectivesPerLocationRule.UniqueDirectivesPerLocationRule, + _KnownArgumentNamesRule.KnownArgumentNamesRule, + _UniqueArgumentNamesRule.UniqueArgumentNamesRule, + _ValuesOfCorrectTypeRule.ValuesOfCorrectTypeRule, + _ProvidedRequiredArgumentsRule.ProvidedRequiredArgumentsRule, + _VariablesInAllowedPositionRule.VariablesInAllowedPositionRule, + _OverlappingFieldsCanBeMergedRule.OverlappingFieldsCanBeMergedRule, + _UniqueInputFieldNamesRule.UniqueInputFieldNamesRule, + ...recommendedRules, +]); +/** + * @internal + */ - // Handle all cases to make sure that there's only one slash between - // baseUrl and uri. - var baseUrlEndsWithSlash = self.baseUrl.lastIndexOf('/') === self.baseUrl.length - 1 - var uriStartsWithSlash = self.uri.indexOf('/') === 0 +exports.specifiedRules = specifiedRules; +const specifiedSDLRules = Object.freeze([ + _LoneSchemaDefinitionRule.LoneSchemaDefinitionRule, + _UniqueOperationTypesRule.UniqueOperationTypesRule, + _UniqueTypeNamesRule.UniqueTypeNamesRule, + _UniqueEnumValueNamesRule.UniqueEnumValueNamesRule, + _UniqueFieldDefinitionNamesRule.UniqueFieldDefinitionNamesRule, + _UniqueArgumentDefinitionNamesRule.UniqueArgumentDefinitionNamesRule, + _UniqueDirectiveNamesRule.UniqueDirectiveNamesRule, + _KnownTypeNamesRule.KnownTypeNamesRule, + _KnownDirectivesRule.KnownDirectivesRule, + _UniqueDirectivesPerLocationRule.UniqueDirectivesPerLocationRule, + _PossibleTypeExtensionsRule.PossibleTypeExtensionsRule, + _KnownArgumentNamesRule.KnownArgumentNamesOnDirectivesRule, + _UniqueArgumentNamesRule.UniqueArgumentNamesRule, + _UniqueInputFieldNamesRule.UniqueInputFieldNamesRule, + _ProvidedRequiredArgumentsRule.ProvidedRequiredArgumentsOnDirectivesRule, +]); +exports.specifiedSDLRules = specifiedSDLRules; - if (baseUrlEndsWithSlash && uriStartsWithSlash) { - self.uri = self.baseUrl + self.uri.slice(1) - } else if (baseUrlEndsWithSlash || uriStartsWithSlash) { - self.uri = self.baseUrl + self.uri - } else if (self.uri === '') { - self.uri = self.baseUrl - } else { - self.uri = self.baseUrl + '/' + self.uri - } - delete self.baseUrl - } - // A URI is needed by this point, emit error if we haven't been able to get one - if (!self.uri) { - return self.emit('error', new Error('options.uri is a required argument')) - } +/***/ }), - // If a string URI/URL was given, parse it into a URL object - if (typeof self.uri === 'string') { - self.uri = url.parse(self.uri) - } +/***/ 14193: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // Some URL objects are not from a URL parsed string and need href added - if (!self.uri.href) { - self.uri.href = url.format(self.uri) - } +"use strict"; - // DEPRECATED: Warning for users of the old Unix Sockets URL Scheme - if (self.uri.protocol === 'unix:') { - return self.emit('error', new Error('`unix://` URL scheme is no longer supported. Please use the format `http://unix:SOCKET:PATH`')) - } - // Support Unix Sockets - if (self.uri.host === 'unix') { - self.enableUnixSocket() - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.assertValidSDL = assertValidSDL; +exports.assertValidSDLExtension = assertValidSDLExtension; +exports.validate = validate; +exports.validateSDL = validateSDL; - if (self.strictSSL === false) { - self.rejectUnauthorized = false - } +var _devAssert = __nccwpck_require__(46514); - if (!self.uri.pathname) { self.uri.pathname = '/' } +var _mapValue = __nccwpck_require__(32223); - if (!(self.uri.host || (self.uri.hostname && self.uri.port)) && !self.uri.isUnix) { - // Invalid URI: it may generate lot of bad errors, like 'TypeError: Cannot call method `indexOf` of undefined' in CookieJar - // Detect and reject it as soon as possible - var faultyUri = url.format(self.uri) - var message = 'Invalid URI "' + faultyUri + '"' - if (Object.keys(options).length === 0) { - // No option ? This can be the sign of a redirect - // As this is a case where the user cannot do anything (they didn't call request directly with this URL) - // they should be warned that it can be caused by a redirection (can save some hair) - message += '. This can be caused by a crappy redirection.' - } - // This error was fatal - self.abort() - return self.emit('error', new Error(message)) - } +var _GraphQLError = __nccwpck_require__(4797); - if (!self.hasOwnProperty('proxy')) { - self.proxy = getProxyFromURI(self.uri) - } +var _ast = __nccwpck_require__(45494); - self.tunnel = self._tunnel.isEnabled() - if (self.proxy) { - self._tunnel.setup(options) - } +var _visitor = __nccwpck_require__(5678); - self._redirect.onRequest(options) +var _validate = __nccwpck_require__(22430); - self.setHost = false - if (!self.hasHeader('host')) { - var hostHeaderName = self.originalHostHeaderName || 'host' - self.setHeader(hostHeaderName, self.uri.host) - // Drop :port suffix from Host header if known protocol. - if (self.uri.port) { - if ((self.uri.port === '80' && self.uri.protocol === 'http:') || - (self.uri.port === '443' && self.uri.protocol === 'https:')) { - self.setHeader(hostHeaderName, self.uri.hostname) - } - } - self.setHost = true - } +var _TypeInfo = __nccwpck_require__(76625); - self.jar(self._jar || options.jar) +var _specifiedRules = __nccwpck_require__(84908); - if (!self.uri.port) { - if (self.uri.protocol === 'http:') { self.uri.port = 80 } else if (self.uri.protocol === 'https:') { self.uri.port = 443 } - } +var _ValidationContext = __nccwpck_require__(28263); - if (self.proxy && !self.tunnel) { - self.port = self.proxy.port - self.host = self.proxy.hostname - } else { - self.port = self.uri.port - self.host = self.uri.hostname - } +// Per the specification, descriptions must not affect validation. +// See https://spec.graphql.org/draft/#sec-Descriptions +const QueryDocumentKeysToValidate = (0, _mapValue.mapValue)( + _ast.QueryDocumentKeys, + (keys) => keys.filter((key) => key !== 'description'), +); +/** + * Implements the "Validation" section of the spec. + * + * Validation runs synchronously, returning an array of encountered errors, or + * an empty array if no errors were encountered and the document is valid. + * + * A list of specific validation rules may be provided. If not provided, the + * default list of rules defined by the GraphQL specification will be used. + * + * Each validation rules is a function which returns a visitor + * (see the language/visitor API). Visitor methods are expected to return + * GraphQLErrors, or Arrays of GraphQLErrors when invalid. + * + * Validate will stop validation after a `maxErrors` limit has been reached. + * Attackers can send pathologically invalid queries to induce a DoS attack, + * so by default `maxErrors` set to 100 errors. + * + * Optionally a custom TypeInfo instance may be provided. If not provided, one + * will be created from the provided schema. + */ - if (options.form) { - self.form(options.form) - } +function validate( + schema, + documentAST, + rules = _specifiedRules.specifiedRules, + options, + /** @deprecated will be removed in 17.0.0 */ + typeInfo = new _TypeInfo.TypeInfo(schema), +) { + var _options$maxErrors; - if (options.formData) { - var formData = options.formData - var requestForm = self.form() - var appendFormValue = function (key, value) { - if (value && value.hasOwnProperty('value') && value.hasOwnProperty('options')) { - requestForm.append(key, value.value, value.options) - } else { - requestForm.append(key, value) - } - } - for (var formKey in formData) { - if (formData.hasOwnProperty(formKey)) { - var formValue = formData[formKey] - if (formValue instanceof Array) { - for (var j = 0; j < formValue.length; j++) { - appendFormValue(formKey, formValue[j]) - } - } else { - appendFormValue(formKey, formValue) - } - } - } - } + const maxErrors = + (_options$maxErrors = + options === null || options === void 0 ? void 0 : options.maxErrors) !== + null && _options$maxErrors !== void 0 + ? _options$maxErrors + : 100; + documentAST || (0, _devAssert.devAssert)(false, 'Must provide document.'); // If the schema used for validation is invalid, throw an error. - if (options.qs) { - self.qs(options.qs) - } + (0, _validate.assertValidSchema)(schema); + const abortObj = Object.freeze({}); + const errors = []; + const context = new _ValidationContext.ValidationContext( + schema, + documentAST, + typeInfo, + (error) => { + if (errors.length >= maxErrors) { + errors.push( + new _GraphQLError.GraphQLError( + 'Too many validation errors, error limit reached. Validation aborted.', + ), + ); // eslint-disable-next-line @typescript-eslint/no-throw-literal - if (self.uri.path) { - self.path = self.uri.path - } else { - self.path = self.uri.pathname + (self.uri.search || '') - } + throw abortObj; + } - if (self.path.length === 0) { - self.path = '/' - } + errors.push(error); + }, + ); // This uses a specialized visitor which runs multiple visitors in parallel, + // while maintaining the visitor skip and break API. - // Auth must happen last in case signing is dependent on other headers - if (options.aws) { - self.aws(options.aws) - } + const visitor = (0, _visitor.visitInParallel)( + rules.map((rule) => rule(context)), + ); // Visit the whole document with each instance of all provided rules. - if (options.hawk) { - self.hawk(options.hawk) + try { + (0, _visitor.visit)( + documentAST, + (0, _TypeInfo.visitWithTypeInfo)(typeInfo, visitor), + QueryDocumentKeysToValidate, + ); + } catch (e) { + if (e !== abortObj) { + throw e; + } } - if (options.httpSignature) { - self.httpSignature(options.httpSignature) - } + return errors; +} +/** + * @internal + */ - if (options.auth) { - if (Object.prototype.hasOwnProperty.call(options.auth, 'username')) { - options.auth.user = options.auth.username - } - if (Object.prototype.hasOwnProperty.call(options.auth, 'password')) { - options.auth.pass = options.auth.password - } +function validateSDL( + documentAST, + schemaToExtend, + rules = _specifiedRules.specifiedSDLRules, +) { + const errors = []; + const context = new _ValidationContext.SDLValidationContext( + documentAST, + schemaToExtend, + (error) => { + errors.push(error); + }, + ); + const visitors = rules.map((rule) => rule(context)); + (0, _visitor.visit)(documentAST, (0, _visitor.visitInParallel)(visitors)); + return errors; +} +/** + * Utility function which asserts a SDL document is valid by throwing an error + * if it is invalid. + * + * @internal + */ - self.auth( - options.auth.user, - options.auth.pass, - options.auth.sendImmediately, - options.auth.bearer - ) - } +function assertValidSDL(documentAST) { + const errors = validateSDL(documentAST); - if (self.gzip && !self.hasHeader('accept-encoding')) { - self.setHeader('accept-encoding', 'gzip, deflate') + if (errors.length !== 0) { + throw new Error(errors.map((error) => error.message).join('\n\n')); } +} +/** + * Utility function which asserts a SDL document is valid by throwing an error + * if it is invalid. + * + * @internal + */ - if (self.uri.auth && !self.hasHeader('authorization')) { - var uriAuthPieces = self.uri.auth.split(':').map(function (item) { return self._qs.unescape(item) }) - self.auth(uriAuthPieces[0], uriAuthPieces.slice(1).join(':'), true) - } +function assertValidSDLExtension(documentAST, schema) { + const errors = validateSDL(documentAST, schema); - if (!self.tunnel && self.proxy && self.proxy.auth && !self.hasHeader('proxy-authorization')) { - var proxyAuthPieces = self.proxy.auth.split(':').map(function (item) { return self._qs.unescape(item) }) - var authHeader = 'Basic ' + toBase64(proxyAuthPieces.join(':')) - self.setHeader('proxy-authorization', authHeader) + if (errors.length !== 0) { + throw new Error(errors.map((error) => error.message).join('\n\n')); } +} - if (self.proxy && !self.tunnel) { - self.path = (self.uri.protocol + '//' + self.uri.host + self.path) - } - if (options.json) { - self.json(options.json) - } - if (options.multipart) { - self.multipart(options.multipart) - } +/***/ }), - if (options.time) { - self.timing = true +/***/ 81923: +/***/ ((__unused_webpack_module, exports) => { - // NOTE: elapsedTime is deprecated in favor of .timings - self.elapsedTime = self.elapsedTime || 0 - } +"use strict"; - function setContentLength () { - if (isTypedArray(self.body)) { - self.body = Buffer.from(self.body) - } - if (!self.hasHeader('content-length')) { - var length - if (typeof self.body === 'string') { - length = Buffer.byteLength(self.body) - } else if (Array.isArray(self.body)) { - length = self.body.reduce(function (a, b) { return a + b.length }, 0) - } else { - length = self.body.length - } +Object.defineProperty(exports, "__esModule", ({ + value: true, +})); +exports.versionInfo = exports.version = void 0; +// Note: This file is autogenerated using "resources/gen-version.js" script and +// automatically updated by "npm version" command. - if (length) { - self.setHeader('content-length', length) - } else { - self.emit('error', new Error('Argument error, options.body.')) - } - } - } - if (self.body && !isstream(self.body)) { - setContentLength() - } +/** + * A string containing the version of the GraphQL.js library + */ +const version = '16.13.2'; +/** + * An object containing the components of the GraphQL.js version string + */ - if (options.oauth) { - self.oauth(options.oauth) - } else if (self._oauth.params && self.hasHeader('authorization')) { - self.oauth(self._oauth.params) - } +exports.version = version; +const versionInfo = Object.freeze({ + major: 16, + minor: 13, + patch: 2, + preReleaseTag: null, +}); +exports.versionInfo = versionInfo; - var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol - var defaultModules = {'http:': http, 'https:': https} - var httpModules = self.httpModules || {} - self.httpModule = httpModules[protocol] || defaultModules[protocol] +/***/ }), - if (!self.httpModule) { - return self.emit('error', new Error('Invalid protocol: ' + protocol)) - } +/***/ 31621: +/***/ ((module) => { - if (options.ca) { - self.ca = options.ca - } +"use strict"; - if (!self.agent) { - if (options.agentOptions) { - self.agentOptions = options.agentOptions - } - if (options.agentClass) { - self.agentClass = options.agentClass - } else if (options.forever) { - var v = version() - // use ForeverAgent in node 0.10- only - if (v.major === 0 && v.minor <= 10) { - self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL - } else { - self.agentClass = self.httpModule.Agent - self.agentOptions = self.agentOptions || {} - self.agentOptions.keepAlive = true - } - } else { - self.agentClass = self.httpModule.Agent - } - } +module.exports = (flag, argv = process.argv) => { + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const position = argv.indexOf(prefix + flag); + const terminatorPosition = argv.indexOf('--'); + return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); +}; - if (self.pool === false) { - self.agent = false - } else { - self.agent = self.agent || self.getNewAgent() - } - self.on('pipe', function (src) { - if (self.ntick && self._started) { - self.emit('error', new Error('You cannot pipe to this stream after the outbound request has started.')) - } - self.src = src - if (isReadStream(src)) { - if (!self.hasHeader('content-type')) { - self.setHeader('content-type', mime.lookup(src.path)) - } - } else { - if (src.headers) { - for (var i in src.headers) { - if (!self.hasHeader(i)) { - self.setHeader(i, src.headers[i]) - } - } - } - if (self._json && !self.hasHeader('content-type')) { - self.setHeader('content-type', 'application/json') - } - if (src.method && !self.explicitMethod) { - self.method = src.method - } - } +/***/ }), - // self.on('pipe', function () { - // console.error('You have already piped to this stream. Pipeing twice is likely to break the request.') - // }) - }) +/***/ 23764: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - defer(function () { - if (self._aborted) { - return - } +"use strict"; - var end = function () { - if (self._form) { - if (!self._auth.hasAuth) { - self._form.pipe(self) - } else if (self._auth.hasAuth && self._auth.sentAuth) { - self._form.pipe(self) - } - } - if (self._multipart && self._multipart.chunked) { - self._multipart.body.pipe(self) - } - if (self.body) { - if (isstream(self.body)) { - self.body.pipe(self) - } else { - setContentLength() - if (Array.isArray(self.body)) { - self.body.forEach(function (part) { - self.write(part) - }) - } else { - self.write(self.body) - } - self.end() - } - } else if (self.requestBodyStream) { - console.warn('options.requestBodyStream is deprecated, please pass the request object to stream.pipe.') - self.requestBodyStream.pipe(self) - } else if (!self.src) { - if (self._auth.hasAuth && !self._auth.sentAuth) { - self.end() - return +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.HttpProxyAgent = void 0; +const net = __importStar(__nccwpck_require__(41808)); +const tls = __importStar(__nccwpck_require__(24404)); +const debug_1 = __importDefault(__nccwpck_require__(38237)); +const events_1 = __nccwpck_require__(82361); +const agent_base_1 = __nccwpck_require__(70694); +const url_1 = __nccwpck_require__(57310); +const debug = (0, debug_1.default)('http-proxy-agent'); +/** + * The `HttpProxyAgent` implements an HTTP Agent subclass that connects + * to the specified "HTTP proxy server" in order to proxy HTTP requests. + */ +class HttpProxyAgent extends agent_base_1.Agent { + constructor(proxy, opts) { + super(opts); + this.proxy = typeof proxy === 'string' ? new url_1.URL(proxy) : proxy; + this.proxyHeaders = opts?.headers ?? {}; + debug('Creating new HttpProxyAgent instance: %o', this.proxy.href); + // Trim off the brackets from IPv6 addresses + const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, ''); + const port = this.proxy.port + ? parseInt(this.proxy.port, 10) + : this.proxy.protocol === 'https:' + ? 443 + : 80; + this.connectOpts = { + ...(opts ? omit(opts, 'headers') : null), + host, + port, + }; + } + addRequest(req, opts) { + req._header = null; + this.setRequestProps(req, opts); + // @ts-expect-error `addRequest()` isn't defined in `@types/node` + super.addRequest(req, opts); + } + setRequestProps(req, opts) { + const { proxy } = this; + const protocol = opts.secureEndpoint ? 'https:' : 'http:'; + const hostname = req.getHeader('host') || 'localhost'; + const base = `${protocol}//${hostname}`; + const url = new url_1.URL(req.path, base); + if (opts.port !== 80) { + url.port = String(opts.port); + } + // Change the `http.ClientRequest` instance's "path" field + // to the absolute path of the URL that will be requested. + req.path = String(url); + // Inject the `Proxy-Authorization` header if necessary. + const headers = typeof this.proxyHeaders === 'function' + ? this.proxyHeaders() + : { ...this.proxyHeaders }; + if (proxy.username || proxy.password) { + const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`; + headers['Proxy-Authorization'] = `Basic ${Buffer.from(auth).toString('base64')}`; + } + if (!headers['Proxy-Connection']) { + headers['Proxy-Connection'] = this.keepAlive + ? 'Keep-Alive' + : 'close'; + } + for (const name of Object.keys(headers)) { + const value = headers[name]; + if (value) { + req.setHeader(name, value); + } + } + } + async connect(req, opts) { + req._header = null; + if (!req.path.includes('://')) { + this.setRequestProps(req, opts); + } + // At this point, the http ClientRequest's internal `_header` field + // might have already been set. If this is the case then we'll need + // to re-generate the string since we just changed the `req.path`. + let first; + let endOfHeaders; + debug('Regenerating stored HTTP header string for request'); + req._implicitHeader(); + if (req.outputData && req.outputData.length > 0) { + debug('Patching connection write() output buffer with updated header'); + first = req.outputData[0].data; + endOfHeaders = first.indexOf('\r\n\r\n') + 4; + req.outputData[0].data = + req._header + first.substring(endOfHeaders); + debug('Output buffer: %o', req.outputData[0].data); + } + // Create a socket connection to the proxy server. + let socket; + if (this.proxy.protocol === 'https:') { + debug('Creating `tls.Socket`: %o', this.connectOpts); + socket = tls.connect(this.connectOpts); } - if (self.method !== 'GET' && typeof self.method !== 'undefined') { - self.setHeader('content-length', 0) + else { + debug('Creating `net.Socket`: %o', this.connectOpts); + socket = net.connect(this.connectOpts); } - self.end() - } + // Wait for the socket's `connect` event, so that this `callback()` + // function throws instead of the `http` request machinery. This is + // important for i.e. `PacProxyAgent` which determines a failed proxy + // connection via the `callback()` function throwing. + await (0, events_1.once)(socket, 'connect'); + return socket; } - - if (self._form && !self.hasHeader('content-length')) { - // Before ending the request, we had to compute the length of the whole form, asyncly - self.setHeader(self._form.getHeaders(), true) - self._form.getLength(function (err, length) { - if (!err && !isNaN(length)) { - self.setHeader('content-length', length) +} +HttpProxyAgent.protocols = ['http', 'https']; +exports.HttpProxyAgent = HttpProxyAgent; +function omit(obj, ...keys) { + const ret = {}; + let key; + for (key in obj) { + if (!keys.includes(key)) { + ret[key] = obj[key]; } - end() - }) - } else { - end() } - - self.ntick = true - }) + return ret; } +//# sourceMappingURL=index.js.map -Request.prototype.getNewAgent = function () { - var self = this - var Agent = self.agentClass - var options = {} - if (self.agentOptions) { - for (var i in self.agentOptions) { - options[i] = self.agentOptions[i] - } - } - if (self.ca) { - options.ca = self.ca - } - if (self.ciphers) { - options.ciphers = self.ciphers - } - if (self.secureProtocol) { - options.secureProtocol = self.secureProtocol - } - if (self.secureOptions) { - options.secureOptions = self.secureOptions - } - if (typeof self.rejectUnauthorized !== 'undefined') { - options.rejectUnauthorized = self.rejectUnauthorized - } - - if (self.cert && self.key) { - options.key = self.key - options.cert = self.cert - } - - if (self.pfx) { - options.pfx = self.pfx - } - - if (self.passphrase) { - options.passphrase = self.passphrase - } - - var poolKey = '' +/***/ }), - // different types of agents are in different pools - if (Agent !== self.httpModule.Agent) { - poolKey += Agent.name - } +/***/ 77219: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - // ca option is only relevant if proxy or destination are https - var proxy = self.proxy - if (typeof proxy === 'string') { - proxy = url.parse(proxy) - } - var isHttps = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:' +"use strict"; - if (isHttps) { - if (options.ca) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.ca +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; } - - if (typeof options.rejectUnauthorized !== 'undefined') { - if (poolKey) { - poolKey += ':' - } - poolKey += options.rejectUnauthorized + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.HttpsProxyAgent = void 0; +const net = __importStar(__nccwpck_require__(41808)); +const tls = __importStar(__nccwpck_require__(24404)); +const assert_1 = __importDefault(__nccwpck_require__(39491)); +const debug_1 = __importDefault(__nccwpck_require__(38237)); +const agent_base_1 = __nccwpck_require__(70694); +const url_1 = __nccwpck_require__(57310); +const parse_proxy_response_1 = __nccwpck_require__(595); +const debug = (0, debug_1.default)('https-proxy-agent'); +const setServernameFromNonIpHost = (options) => { + if (options.servername === undefined && + options.host && + !net.isIP(options.host)) { + return { + ...options, + servername: options.host, + }; } - - if (options.cert) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.cert.toString('ascii') + options.key.toString('ascii') + return options; +}; +/** + * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to + * the specified "HTTP(s) proxy server" in order to proxy HTTPS requests. + * + * Outgoing HTTP requests are first tunneled through the proxy server using the + * `CONNECT` HTTP request method to establish a connection to the proxy server, + * and then the proxy server connects to the destination target and issues the + * HTTP request from the proxy server. + * + * `https:` requests have their socket connection upgraded to TLS once + * the connection to the proxy server has been established. + */ +class HttpsProxyAgent extends agent_base_1.Agent { + constructor(proxy, opts) { + super(opts); + this.options = { path: undefined }; + this.proxy = typeof proxy === 'string' ? new url_1.URL(proxy) : proxy; + this.proxyHeaders = opts?.headers ?? {}; + debug('Creating new HttpsProxyAgent instance: %o', this.proxy.href); + // Trim off the brackets from IPv6 addresses + const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, ''); + const port = this.proxy.port + ? parseInt(this.proxy.port, 10) + : this.proxy.protocol === 'https:' + ? 443 + : 80; + this.connectOpts = { + // Attempt to negotiate http/1.1 for proxy servers that support http/2 + ALPNProtocols: ['http/1.1'], + ...(opts ? omit(opts, 'headers') : null), + host, + port, + }; } - - if (options.pfx) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.pfx.toString('ascii') + /** + * Called when the node-core HTTP client library is creating a + * new HTTP request. + */ + async connect(req, opts) { + const { proxy } = this; + if (!opts.host) { + throw new TypeError('No "host" provided'); + } + // Create a socket connection to the proxy server. + let socket; + if (proxy.protocol === 'https:') { + debug('Creating `tls.Socket`: %o', this.connectOpts); + socket = tls.connect(setServernameFromNonIpHost(this.connectOpts)); + } + else { + debug('Creating `net.Socket`: %o', this.connectOpts); + socket = net.connect(this.connectOpts); + } + const headers = typeof this.proxyHeaders === 'function' + ? this.proxyHeaders() + : { ...this.proxyHeaders }; + const host = net.isIPv6(opts.host) ? `[${opts.host}]` : opts.host; + let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\r\n`; + // Inject the `Proxy-Authorization` header if necessary. + if (proxy.username || proxy.password) { + const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`; + headers['Proxy-Authorization'] = `Basic ${Buffer.from(auth).toString('base64')}`; + } + headers.Host = `${host}:${opts.port}`; + if (!headers['Proxy-Connection']) { + headers['Proxy-Connection'] = this.keepAlive + ? 'Keep-Alive' + : 'close'; + } + for (const name of Object.keys(headers)) { + payload += `${name}: ${headers[name]}\r\n`; + } + const proxyResponsePromise = (0, parse_proxy_response_1.parseProxyResponse)(socket); + socket.write(`${payload}\r\n`); + const { connect, buffered } = await proxyResponsePromise; + req.emit('proxyConnect', connect); + this.emit('proxyConnect', connect, req); + if (connect.statusCode === 200) { + req.once('socket', resume); + if (opts.secureEndpoint) { + // The proxy is connecting to a TLS server, so upgrade + // this socket connection to a TLS connection. + debug('Upgrading socket connection to TLS'); + return tls.connect({ + ...omit(setServernameFromNonIpHost(opts), 'host', 'path', 'port'), + socket, + }); + } + return socket; + } + // Some other status code that's not 200... need to re-play the HTTP + // header "data" events onto the socket once the HTTP machinery is + // attached so that the node core `http` can parse and handle the + // error status code. + // Close the original socket, and a new "fake" socket is returned + // instead, so that the proxy doesn't get the HTTP request + // written to it (which may contain `Authorization` headers or other + // sensitive data). + // + // See: https://hackerone.com/reports/541502 + socket.destroy(); + const fakeSocket = new net.Socket({ writable: false }); + fakeSocket.readable = true; + // Need to wait for the "socket" event to re-play the "data" events. + req.once('socket', (s) => { + debug('Replaying proxy buffer for failed request'); + (0, assert_1.default)(s.listenerCount('data') > 0); + // Replay the "buffered" Buffer onto the fake `socket`, since at + // this point the HTTP module machinery has been hooked up for + // the user. + s.push(buffered); + s.push(null); + }); + return fakeSocket; + } +} +HttpsProxyAgent.protocols = ['http', 'https']; +exports.HttpsProxyAgent = HttpsProxyAgent; +function resume(socket) { + socket.resume(); +} +function omit(obj, ...keys) { + const ret = {}; + let key; + for (key in obj) { + if (!keys.includes(key)) { + ret[key] = obj[key]; + } } + return ret; +} +//# sourceMappingURL=index.js.map - if (options.ciphers) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.ciphers - } +/***/ }), - if (options.secureProtocol) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.secureProtocol - } +/***/ 595: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - if (options.secureOptions) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.secureOptions - } - } +"use strict"; - if (self.pool === globalPool && !poolKey && Object.keys(options).length === 0 && self.httpModule.globalAgent) { - // not doing anything special. Use the globalAgent - return self.httpModule.globalAgent - } +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.parseProxyResponse = void 0; +const debug_1 = __importDefault(__nccwpck_require__(38237)); +const debug = (0, debug_1.default)('https-proxy-agent:parse-proxy-response'); +function parseProxyResponse(socket) { + return new Promise((resolve, reject) => { + // we need to buffer any HTTP traffic that happens with the proxy before we get + // the CONNECT response, so that if the response is anything other than an "200" + // response code, then we can re-play the "data" events on the socket once the + // HTTP parser is hooked up... + let buffersLength = 0; + const buffers = []; + function read() { + const b = socket.read(); + if (b) + ondata(b); + else + socket.once('readable', read); + } + function cleanup() { + socket.removeListener('end', onend); + socket.removeListener('error', onerror); + socket.removeListener('readable', read); + } + function onend() { + cleanup(); + debug('onend'); + reject(new Error('Proxy connection ended before receiving CONNECT response')); + } + function onerror(err) { + cleanup(); + debug('onerror %o', err); + reject(err); + } + function ondata(b) { + buffers.push(b); + buffersLength += b.length; + const buffered = Buffer.concat(buffers, buffersLength); + const endOfHeaders = buffered.indexOf('\r\n\r\n'); + if (endOfHeaders === -1) { + // keep buffering + debug('have not received end of HTTP headers yet...'); + read(); + return; + } + const headerParts = buffered + .slice(0, endOfHeaders) + .toString('ascii') + .split('\r\n'); + const firstLine = headerParts.shift(); + if (!firstLine) { + socket.destroy(); + return reject(new Error('No header received from proxy CONNECT response')); + } + const firstLineParts = firstLine.split(' '); + const statusCode = +firstLineParts[1]; + const statusText = firstLineParts.slice(2).join(' '); + const headers = {}; + for (const header of headerParts) { + if (!header) + continue; + const firstColon = header.indexOf(':'); + if (firstColon === -1) { + socket.destroy(); + return reject(new Error(`Invalid header from proxy CONNECT response: "${header}"`)); + } + const key = header.slice(0, firstColon).toLowerCase(); + const value = header.slice(firstColon + 1).trimStart(); + const current = headers[key]; + if (typeof current === 'string') { + headers[key] = [current, value]; + } + else if (Array.isArray(current)) { + current.push(value); + } + else { + headers[key] = value; + } + } + debug('got proxy server response: %o %o', firstLine, headers); + cleanup(); + resolve({ + connect: { + statusCode, + statusText, + headers, + }, + buffered, + }); + } + socket.on('error', onerror); + socket.on('end', onend); + read(); + }); +} +exports.parseProxyResponse = parseProxyResponse; +//# sourceMappingURL=parse-proxy-response.js.map - // we're using a stored agent. Make sure it's protocol-specific - poolKey = self.uri.protocol + poolKey +/***/ }), - // generate a new agent for this setting if none yet exists - if (!self.pool[poolKey]) { - self.pool[poolKey] = new Agent(options) - // properly set maxSockets on new agents - if (self.pool.maxSockets) { - self.pool[poolKey].maxSockets = self.pool.maxSockets - } - } +/***/ 80900: +/***/ ((module) => { - return self.pool[poolKey] -} +/** + * Helpers. + */ -Request.prototype.start = function () { - // start() is called once we are ready to send the outgoing HTTP request. - // this is usually called on the first write(), end() or on nextTick() - var self = this +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var w = d * 7; +var y = d * 365.25; - if (self.timing) { - // All timings will be relative to this request's startTime. In order to do this, - // we need to capture the wall-clock start time (via Date), immediately followed - // by the high-resolution timer (via now()). While these two won't be set - // at the _exact_ same time, they should be close enough to be able to calculate - // high-resolution, monotonically non-decreasing timestamps relative to startTime. - var startTime = new Date().getTime() - var startTimeNow = now() - } +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} [options] + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ - if (self._aborted) { - return +module.exports = function (val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isFinite(val)) { + return options.long ? fmtLong(val) : fmtShort(val); } + throw new Error( + 'val is not a non-empty string or a valid number. val=' + + JSON.stringify(val) + ); +}; - self._started = true - self.method = self.method || 'GET' - self.href = self.uri.href +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ - if (self.src && self.src.stat && self.src.stat.size && !self.hasHeader('content-length')) { - self.setHeader('content-length', self.src.stat.size) +function parse(str) { + str = String(str); + if (str.length > 100) { + return; } - if (self._aws) { - self.aws(self._aws, true) + var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; } - - // We have a method named auth, which is completely different from the http.request - // auth option. If we don't remove it, we're gonna have a bad time. - var reqOptions = copy(self) - delete reqOptions.auth - - debug('make request', self.uri.href) - - // node v6.8.0 now supports a `timeout` value in `http.request()`, but we - // should delete it for now since we handle timeouts manually for better - // consistency with node versions before v6.8.0 - delete reqOptions.timeout - - try { - self.req = self.httpModule.request(reqOptions) - } catch (err) { - self.emit('error', err) - return + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'weeks': + case 'week': + case 'w': + return n * w; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; } +} - if (self.timing) { - self.startTime = startTime - self.startTimeNow = startTimeNow +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ - // Timing values will all be relative to startTime (by comparing to startTimeNow - // so we have an accurate clock) - self.timings = {} +function fmtShort(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return Math.round(ms / d) + 'd'; } - - var timeout - if (self.timeout && !self.timeoutTimer) { - if (self.timeout < 0) { - timeout = 0 - } else if (typeof self.timeout === 'number' && isFinite(self.timeout)) { - timeout = self.timeout - } + if (msAbs >= h) { + return Math.round(ms / h) + 'h'; } - - self.req.on('response', self.onRequestResponse.bind(self)) - self.req.on('error', self.onRequestError.bind(self)) - self.req.on('drain', function () { - self.emit('drain') - }) - - self.req.on('socket', function (socket) { - // `._connecting` was the old property which was made public in node v6.1.0 - var isConnecting = socket._connecting || socket.connecting - if (self.timing) { - self.timings.socket = now() - self.startTimeNow - - if (isConnecting) { - var onLookupTiming = function () { - self.timings.lookup = now() - self.startTimeNow - } - - var onConnectTiming = function () { - self.timings.connect = now() - self.startTimeNow - } - - socket.once('lookup', onLookupTiming) - socket.once('connect', onConnectTiming) - - // clean up timing event listeners if needed on error - self.req.once('error', function () { - socket.removeListener('lookup', onLookupTiming) - socket.removeListener('connect', onConnectTiming) - }) - } - } - - var setReqTimeout = function () { - // This timeout sets the amount of time to wait *between* bytes sent - // from the server once connected. - // - // In particular, it's useful for erroring if the server fails to send - // data halfway through streaming a response. - self.req.setTimeout(timeout, function () { - if (self.req) { - self.abort() - var e = new Error('ESOCKETTIMEDOUT') - e.code = 'ESOCKETTIMEDOUT' - e.connect = false - self.emit('error', e) - } - }) - } - if (timeout !== undefined) { - // Only start the connection timer if we're actually connecting a new - // socket, otherwise if we're already connected (because this is a - // keep-alive connection) do not bother. This is important since we won't - // get a 'connect' event for an already connected socket. - if (isConnecting) { - var onReqSockConnect = function () { - socket.removeListener('connect', onReqSockConnect) - self.clearTimeout() - setReqTimeout() - } - - socket.on('connect', onReqSockConnect) - - self.req.on('error', function (err) { // eslint-disable-line handle-callback-err - socket.removeListener('connect', onReqSockConnect) - }) - - // Set a timeout in memory - this block will throw if the server takes more - // than `timeout` to write the HTTP status and headers (corresponding to - // the on('response') event on the client). NB: this measures wall-clock - // time, not the time between bytes sent by the server. - self.timeoutTimer = setTimeout(function () { - socket.removeListener('connect', onReqSockConnect) - self.abort() - var e = new Error('ETIMEDOUT') - e.code = 'ETIMEDOUT' - e.connect = true - self.emit('error', e) - }, timeout) - } else { - // We're already connected - setReqTimeout() - } - } - self.emit('socket', socket) - }) - - self.emit('request', self.req) -} - -Request.prototype.onRequestError = function (error) { - var self = this - if (self._aborted) { - return + if (msAbs >= m) { + return Math.round(ms / m) + 'm'; } - if (self.req && self.req._reusedSocket && error.code === 'ECONNRESET' && - self.agent.addRequestNoreuse) { - self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) } - self.start() - self.req.end() - return + if (msAbs >= s) { + return Math.round(ms / s) + 's'; } - self.clearTimeout() - self.emit('error', error) + return ms + 'ms'; } -Request.prototype.onRequestResponse = function (response) { - var self = this - - if (self.timing) { - self.timings.response = now() - self.startTimeNow - } - - debug('onRequestResponse', self.uri.href, response.statusCode, response.headers) - response.on('end', function () { - if (self.timing) { - self.timings.end = now() - self.startTimeNow - response.timingStart = self.startTime - - // fill in the blanks for any periods that didn't trigger, such as - // no lookup or connect due to keep alive - if (!self.timings.socket) { - self.timings.socket = 0 - } - if (!self.timings.lookup) { - self.timings.lookup = self.timings.socket - } - if (!self.timings.connect) { - self.timings.connect = self.timings.lookup - } - if (!self.timings.response) { - self.timings.response = self.timings.connect - } - - debug('elapsed time', self.timings.end) - - // elapsedTime includes all redirects - self.elapsedTime += Math.round(self.timings.end) - - // NOTE: elapsedTime is deprecated in favor of .timings - response.elapsedTime = self.elapsedTime - - // timings is just for the final fetch - response.timings = self.timings - - // pre-calculate phase timings as well - response.timingPhases = { - wait: self.timings.socket, - dns: self.timings.lookup - self.timings.socket, - tcp: self.timings.connect - self.timings.lookup, - firstByte: self.timings.response - self.timings.connect, - download: self.timings.end - self.timings.response, - total: self.timings.end - } - } - debug('response end', self.uri.href, response.statusCode, response.headers) - }) - - if (self._aborted) { - debug('aborted', self.uri.href) - response.resume() - return - } - - self.response = response - response.request = self - response.toJSON = responseToJSON - - // XXX This is different on 0.10, because SSL is strict by default - if (self.httpModule === https && - self.strictSSL && (!response.hasOwnProperty('socket') || - !response.socket.authorized)) { - debug('strict ssl error', self.uri.href) - var sslErr = response.hasOwnProperty('socket') ? response.socket.authorizationError : self.uri.href + ' does not support SSL' - self.emit('error', new Error('SSL Error: ' + sslErr)) - return - } +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ - // Save the original host before any redirect (if it changes, we need to - // remove any authorization headers). Also remember the case of the header - // name because lots of broken servers expect Host instead of host and we - // want the caller to be able to specify this. - self.originalHost = self.getHeader('host') - if (!self.originalHostHeaderName) { - self.originalHostHeaderName = self.hasHeader('host') +function fmtLong(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, 'day'); } - if (self.setHost) { - self.removeHeader('host') + if (msAbs >= h) { + return plural(ms, msAbs, h, 'hour'); } - self.clearTimeout() - - var targetCookieJar = (self._jar && self._jar.setCookie) ? self._jar : globalCookieJar - var addCookie = function (cookie) { - // set the cookie if it's domain in the href's domain. - try { - targetCookieJar.setCookie(cookie, self.uri.href, {ignoreError: true}) - } catch (e) { - self.emit('error', e) - } + if (msAbs >= m) { + return plural(ms, msAbs, m, 'minute'); } - - response.caseless = caseless(response.headers) - - if (response.caseless.has('set-cookie') && (!self._disableCookies)) { - var headerName = response.caseless.has('set-cookie') - if (Array.isArray(response.headers[headerName])) { - response.headers[headerName].forEach(addCookie) - } else { - addCookie(response.headers[headerName]) - } + if (msAbs >= s) { + return plural(ms, msAbs, s, 'second'); } + return ms + ' ms'; +} - if (self._redirect.onResponse(response)) { - return // Ignore the rest of the response - } else { - // Be a good stream and emit end when the response is finished. - // Hack to emit end on close because of a core bug that never fires end - response.on('close', function () { - if (!self._ended) { - self.response.emit('end') - } - }) +/** + * Pluralization helper. + */ - response.once('end', function () { - self._ended = true - }) +function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); +} - var noBody = function (code) { - return ( - self.method === 'HEAD' || - // Informational - (code >= 100 && code < 200) || - // No Content - code === 204 || - // Not Modified - code === 304 - ) - } - var responseContent - if (self.gzip && !noBody(response.statusCode)) { - var contentEncoding = response.headers['content-encoding'] || 'identity' - contentEncoding = contentEncoding.trim().toLowerCase() +/***/ }), - // Be more lenient with decoding compressed responses, since (very rarely) - // servers send slightly invalid gzip responses that are still accepted - // by common browsers. - // Always using Z_SYNC_FLUSH is what cURL does. - var zlibOptions = { - flush: zlib.Z_SYNC_FLUSH, - finishFlush: zlib.Z_SYNC_FLUSH - } +/***/ 80467: +/***/ ((module, exports, __nccwpck_require__) => { - if (contentEncoding === 'gzip') { - responseContent = zlib.createGunzip(zlibOptions) - response.pipe(responseContent) - } else if (contentEncoding === 'deflate') { - responseContent = zlib.createInflate(zlibOptions) - response.pipe(responseContent) - } else { - // Since previous versions didn't check for Content-Encoding header, - // ignore any invalid values to preserve backwards-compatibility - if (contentEncoding !== 'identity') { - debug('ignoring unrecognized Content-Encoding ' + contentEncoding) - } - responseContent = response - } - } else { - responseContent = response - } +"use strict"; - if (self.encoding) { - if (self.dests.length !== 0) { - console.error('Ignoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.') - } else { - responseContent.setEncoding(self.encoding) - } - } - if (self._paused) { - responseContent.pause() - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - self.responseContent = responseContent +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - self.emit('response', response) +var Stream = _interopDefault(__nccwpck_require__(12781)); +var http = _interopDefault(__nccwpck_require__(13685)); +var Url = _interopDefault(__nccwpck_require__(57310)); +var whatwgUrl = _interopDefault(__nccwpck_require__(28665)); +var https = _interopDefault(__nccwpck_require__(95687)); +var zlib = _interopDefault(__nccwpck_require__(59796)); - self.dests.forEach(function (dest) { - self.pipeDest(dest) - }) +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js - responseContent.on('data', function (chunk) { - if (self.timing && !self.responseStarted) { - self.responseStartTime = (new Date()).getTime() +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; - // NOTE: responseStartTime is deprecated in favor of .timings - response.responseStartTime = self.responseStartTime - } - self._destdata = true - self.emit('data', chunk) - }) - responseContent.once('end', function (chunk) { - self.emit('end', chunk) - }) - responseContent.on('error', function (error) { - self.emit('error', error) - }) - responseContent.on('close', function () { self.emit('close') }) - - if (self.callback) { - self.readResponseBody(response) - } else { // if no callback - self.on('end', function () { - if (self._aborted) { - debug('aborted', self.uri.href) - return - } - self.emit('complete', response) - }) - } - } - debug('finish init function', self.uri.href) -} +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); -Request.prototype.readResponseBody = function (response) { - var self = this - debug("reading response's body") - var buffers = [] - var bufferLength = 0 - var strings = [] - - self.on('data', function (chunk) { - if (!Buffer.isBuffer(chunk)) { - strings.push(chunk) - } else if (chunk.length) { - bufferLength += chunk.length - buffers.push(chunk) - } - }) - self.on('end', function () { - debug('end event', self.uri.href) - if (self._aborted) { - debug('aborted', self.uri.href) - // `buffer` is defined in the parent scope and used in a closure it exists for the life of the request. - // This can lead to leaky behavior if the user retains a reference to the request object. - buffers = [] - bufferLength = 0 - return - } +class Blob { + constructor() { + this[TYPE] = ''; - if (bufferLength) { - debug('has body', self.uri.href, bufferLength) - response.body = Buffer.concat(buffers, bufferLength) - if (self.encoding !== null) { - response.body = response.body.toString(self.encoding) - } - // `buffer` is defined in the parent scope and used in a closure it exists for the life of the Request. - // This can lead to leaky behavior if the user retains a reference to the request object. - buffers = [] - bufferLength = 0 - } else if (strings.length) { - // The UTF8 BOM [0xEF,0xBB,0xBF] is converted to [0xFE,0xFF] in the JS UTC16/UCS2 representation. - // Strip this value out when the encoding is set to 'utf8', as upstream consumers won't expect it and it breaks JSON.parse(). - if (self.encoding === 'utf8' && strings[0].length > 0 && strings[0][0] === '\uFEFF') { - strings[0] = strings[0].substring(1) - } - response.body = strings.join('') - } + const blobParts = arguments[0]; + const options = arguments[1]; - if (self._json) { - try { - response.body = JSON.parse(response.body, self._jsonReviver) - } catch (e) { - debug('invalid JSON received', self.uri.href) - } - } - debug('emitting complete', self.uri.href) - if (typeof response.body === 'undefined' && !self._json) { - response.body = self.encoding === null ? Buffer.alloc(0) : '' - } - self.emit('complete', response, response.body) - }) -} + const buffers = []; + let size = 0; -Request.prototype.abort = function () { - var self = this - self._aborted = true + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } - if (self.req) { - self.req.abort() - } else if (self.response) { - self.response.destroy() - } + this[BUFFER] = Buffer.concat(buffers); - self.clearTimeout() - self.emit('abort') -} + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; -Request.prototype.pipeDest = function (dest) { - var self = this - var response = self.response - // Called after the response is received - if (dest.headers && !dest.headersSent) { - if (response.caseless.has('content-type')) { - var ctname = response.caseless.has('content-type') - if (dest.setHeader) { - dest.setHeader(ctname, response.headers[ctname]) - } else { - dest.headers[ctname] = response.headers[ctname] - } - } + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); - if (response.caseless.has('content-length')) { - var clname = response.caseless.has('content-length') - if (dest.setHeader) { - dest.setHeader(clname, response.headers[clname]) - } else { - dest.headers[clname] = response.headers[clname] - } - } - } - if (dest.setHeader && !dest.headersSent) { - for (var i in response.headers) { - // If the response content is being decoded, the Content-Encoding header - // of the response doesn't represent the piped content, so don't pass it. - if (!self.gzip || i !== 'content-encoding') { - dest.setHeader(i, response.headers[i]) - } - } - dest.statusCode = response.statusCode - } - if (self.pipefilter) { - self.pipefilter(response, dest) - } + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } } -Request.prototype.qs = function (q, clobber) { - var self = this - var base - if (!clobber && self.uri.query) { - base = self._qs.parse(self.uri.query) - } else { - base = {} - } +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); - for (var i in q) { - base[i] = q[i] - } +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); - var qs = self._qs.stringify(base) +/** + * fetch-error.js + * + * FetchError interface for operational errors + */ - if (qs === '') { - return self - } +/** + * Create FetchError instance + * + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError + */ +function FetchError(message, type, systemError) { + Error.call(this, message); - self.uri = url.parse(self.uri.href.split('?')[0] + '?' + qs) - self.url = self.uri - self.path = self.uri.path + this.message = message; + this.type = type; - if (self.uri.host === 'unix') { - self.enableUnixSocket() + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; } - return self -} -Request.prototype.form = function (form) { - var self = this - if (form) { - if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) { - self.setHeader('content-type', 'application/x-www-form-urlencoded') - } - self.body = (typeof form === 'string') - ? self._qs.rfc3986(form.toString('utf8')) - : self._qs.stringify(form).toString('utf8') - return self - } - // create form-data object - self._form = new FormData() - self._form.on('error', function (err) { - err.message = 'form-data: ' + err.message - self.emit('error', err) - self.abort() - }) - return self._form + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); } -Request.prototype.multipart = function (multipart) { - var self = this - self._multipart.onRequest(multipart) +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; - if (!self._multipart.chunked) { - self.body = self._multipart.body - } +let convert; +try { + convert = (__nccwpck_require__(22877).convert); +} catch (e) {} - return self -} -Request.prototype.json = function (val) { - var self = this +const INTERNALS = Symbol('Body internals'); - if (!self.hasHeader('accept')) { - self.setHeader('accept', 'application/json') - } +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; - if (typeof self.jsonReplacer === 'function') { - self._jsonReplacer = self.jsonReplacer - } +/** + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +function Body(body) { + var _this = this; - self._json = true - if (typeof val === 'boolean') { - if (self.body !== undefined) { - if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) { - self.body = safeStringify(self.body, self._jsonReplacer) - } else { - self.body = self._qs.rfc3986(self.body) - } - if (!self.hasHeader('content-type')) { - self.setHeader('content-type', 'application/json') - } - } - } else { - self.body = safeStringify(val, self._jsonReplacer) - if (!self.hasHeader('content-type')) { - self.setHeader('content-type', 'application/json') - } - } + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; - if (typeof self.jsonReviver === 'function') { - self._jsonReviver = self.jsonReviver - } + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; - return self -} -Request.prototype.getHeader = function (name, headers) { - var self = this - var result, re, match - if (!headers) { - headers = self.headers - } - Object.keys(headers).forEach(function (key) { - if (key.length !== name.length) { - return - } - re = new RegExp(name, 'i') - match = key.match(re) - if (match) { - result = headers[key] - } - }) - return result + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; + + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } } -Request.prototype.enableUnixSocket = function () { - // Get the socket & request paths from the URL - var unixParts = this.uri.path.split(':') - var host = unixParts[0] - var path = unixParts[1] - // Apply unix properties to request - this.socketPath = host - this.uri.pathname = path - this.uri.path = path - this.uri.host = host - this.uri.hostname = host - this.uri.isUnix = true -} - -Request.prototype.auth = function (user, pass, sendImmediately, bearer) { - var self = this - self._auth.onRequest(user, pass, sendImmediately, bearer) +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, - return self -} -Request.prototype.aws = function (opts, now) { - var self = this + get bodyUsed() { + return this[INTERNALS].disturbed; + }, - if (!now) { - self._aws = opts - return self - } + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, - if (opts.sign_version === 4 || opts.sign_version === '4') { - // use aws4 - var options = { - host: self.uri.host, - path: self.uri.path, - method: self.method, - headers: self.headers, - body: self.body - } - if (opts.service) { - options.service = opts.service - } - var signRes = aws4.sign(options, { - accessKeyId: opts.key, - secretAccessKey: opts.secret, - sessionToken: opts.session - }) - self.setHeader('authorization', signRes.headers.Authorization) - self.setHeader('x-amz-date', signRes.headers['X-Amz-Date']) - if (signRes.headers['X-Amz-Security-Token']) { - self.setHeader('x-amz-security-token', signRes.headers['X-Amz-Security-Token']) - } - } else { - // default: use aws-sign2 - var date = new Date() - self.setHeader('date', date.toUTCString()) - var auth = { - key: opts.key, - secret: opts.secret, - verb: self.method.toUpperCase(), - date: date, - contentType: self.getHeader('content-type') || '', - md5: self.getHeader('content-md5') || '', - amazonHeaders: aws2.canonicalizeHeaders(self.headers) - } - var path = self.uri.path - if (opts.bucket && path) { - auth.resource = '/' + opts.bucket + path - } else if (opts.bucket && !path) { - auth.resource = '/' + opts.bucket - } else if (!opts.bucket && path) { - auth.resource = path - } else if (!opts.bucket && !path) { - auth.resource = '/' - } - auth.resource = aws2.canonicalizeResource(auth.resource) - self.setHeader('authorization', aws2.authorization(auth)) - } - - return self -} -Request.prototype.httpSignature = function (opts) { - var self = this - httpSignature.signRequest({ - getHeader: function (header) { - return self.getHeader(header, self.headers) - }, - setHeader: function (header, value) { - self.setHeader(header, value) - }, - method: self.method, - path: self.path - }, opts) - debug('httpSignature authorization', self.getHeader('authorization')) + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, - return self -} -Request.prototype.hawk = function (opts) { - var self = this - self.setHeader('Authorization', hawk.header(self.uri, self.method, opts)) -} -Request.prototype.oauth = function (_oauth) { - var self = this + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; - self._oauth.onRequest(_oauth) + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, - return self -} + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, -Request.prototype.jar = function (jar) { - var self = this - var cookies + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, - if (self._redirect.redirectsFollowed === 0) { - self.originalCookieHeader = self.getHeader('cookie') - } + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; - if (!jar) { - // disable cookies - cookies = false - self._disableCookies = true - } else { - var targetCookieJar = jar.getCookieString ? jar : globalCookieJar - var urihref = self.uri.href - // fetch cookie in the Specified host - if (targetCookieJar) { - cookies = targetCookieJar.getCookieString(urihref) - } - } + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; - // if need cookie and cookie is not empty - if (cookies && cookies.length) { - if (self.originalCookieHeader) { - // Don't overwrite existing Cookie header - self.setHeader('cookie', self.originalCookieHeader + '; ' + cookies) - } else { - self.setHeader('cookie', cookies) - } - } - self._jar = jar - return self -} +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); -// Stream API -Request.prototype.pipe = function (dest, opts) { - var self = this +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; - if (self.response) { - if (self._destdata) { - self.emit('error', new Error('You cannot pipe after data has been emitted from the response.')) - } else if (self._ended) { - self.emit('error', new Error('You cannot pipe after the response has been ended.')) - } else { - stream.Stream.prototype.pipe.call(self, dest, opts) - self.pipeDest(dest) - return dest - } - } else { - self.dests.push(dest) - stream.Stream.prototype.pipe.call(self, dest, opts) - return dest - } -} -Request.prototype.write = function () { - var self = this - if (self._aborted) { return } +/** + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise + */ +function consumeBody() { + var _this4 = this; - if (!self._started) { - self.start() - } - if (self.req) { - return self.req.write.apply(self.req, arguments) - } -} -Request.prototype.end = function (chunk) { - var self = this - if (self._aborted) { return } + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } - if (chunk) { - self.write(chunk) - } - if (!self._started) { - self.start() - } - if (self.req) { - self.req.end() - } -} -Request.prototype.pause = function () { - var self = this - if (!self.responseContent) { - self._paused = true - } else { - self.responseContent.pause.apply(self.responseContent, arguments) - } -} -Request.prototype.resume = function () { - var self = this - if (!self.responseContent) { - self._paused = false - } else { - self.responseContent.resume.apply(self.responseContent, arguments) - } -} -Request.prototype.destroy = function () { - var self = this - this.clearTimeout() - if (!self._ended) { - self.end() - } else if (self.response) { - self.response.destroy() - } -} + this[INTERNALS].disturbed = true; -Request.prototype.clearTimeout = function () { - if (this.timeoutTimer) { - clearTimeout(this.timeoutTimer) - this.timeoutTimer = null - } -} + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } -Request.defaultProxyHeaderWhiteList = - Tunnel.defaultProxyHeaderWhiteList.slice() + let body = this.body; -Request.defaultProxyHeaderExclusiveList = - Tunnel.defaultProxyHeaderExclusiveList.slice() + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } -// Exports + // body is blob + if (isBlob(body)) { + body = body.stream(); + } -Request.prototype.toJSON = requestToJSON -module.exports = Request + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } -/***/ }), + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; -/***/ 46624: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return new Body.Promise(function (resolve, reject) { + let resTimeout; -"use strict"; + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } -const tls = __nccwpck_require__(24404); + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); -module.exports = (options = {}, connect = tls.connect) => new Promise((resolve, reject) => { - let timeout = false; + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } - let socket; + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } - const callback = async () => { - await socketPromise; + accumBytes += chunk.length; + accum.push(chunk); + }); - socket.off('timeout', onTimeout); - socket.off('error', reject); + body.on('end', function () { + if (abort) { + return; + } - if (options.resolveSocket) { - resolve({alpnProtocol: socket.alpnProtocol, socket, timeout}); + clearTimeout(resTimeout); - if (timeout) { - await Promise.resolve(); - socket.emit('timeout'); + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); } - } else { - socket.destroy(); - resolve({alpnProtocol: socket.alpnProtocol, timeout}); - } - }; + }); + }); +} - const onTimeout = async () => { - timeout = true; - callback(); - }; +/** + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding + * + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String + */ +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } - const socketPromise = (async () => { - try { - socket = await connect(options, callback); + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; - socket.on('error', reject); - socket.once('timeout', onTimeout); - } catch (error) { - reject(error); - } - })(); -}); + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); -/***/ }), + // html5 + if (!res && str) { + res = / { + // html4 + if (!res && str) { + res = / { + // check that body is a stream and not form-data object + // note: we can't clone the form-data object without having it as a dependency + if (body instanceof Stream && typeof body.getBoundary !== 'function') { + // tee instance body + p1 = new PassThrough(); + p2 = new PassThrough(); + body.pipe(p1); + body.pipe(p2); + // set instance body to teed body and return the other teed body + instance[INTERNALS].body = p1; + body = p2; + } -"use strict"; + return body; +} +/** + * Performs the operation "extract a `Content-Type` value from |object|" as + * specified in the specification: + * https://fetch.spec.whatwg.org/#concept-bodyinit-extract + * + * This function assumes that instance.body is present. + * + * @param Mixed instance Any options.body input + */ +function extractContentType(body) { + if (body === null) { + // body is null + return null; + } else if (typeof body === 'string') { + // body is string + return 'text/plain;charset=UTF-8'; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + return 'application/x-www-form-urlencoded;charset=UTF-8'; + } else if (isBlob(body)) { + // body is blob + return body.type || null; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return null; + } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + return null; + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + return null; + } else if (typeof body.getBoundary === 'function') { + // detect form data input from form-data module + return `multipart/form-data;boundary=${body.getBoundary()}`; + } else if (body instanceof Stream) { + // body is stream + // can't really do much about this + return null; + } else { + // Body constructor defaults other things to string + return 'text/plain;charset=UTF-8'; + } +} -Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * The Fetch Standard treats this as if "total bytes" is a property on the body. + * For us, we have to explicitly get it with a function. + * + * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes + * + * @param Body instance Instance of Body + * @return Number? Number of bytes, or null if not possible + */ +function getTotalBytes(instance) { + const body = instance.body; -/* eslint-disable @typescript-eslint/strict-boolean-expressions */ -function parse(string, encoding, opts) { - var _opts$out; - if (opts === void 0) { - opts = {}; - } + if (body === null) { + // body is null + return 0; + } else if (isBlob(body)) { + return body.size; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return body.length; + } else if (body && typeof body.getLengthSync === 'function') { + // detect form data input from form-data module + if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x + body.hasKnownLength && body.hasKnownLength()) { + // 2.x + return body.getLengthSync(); + } + return null; + } else { + // body is stream + return null; + } +} - // Build the character lookup table: - if (!encoding.codes) { - encoding.codes = {}; +/** + * Write a Body to a Node.js WritableStream (e.g. http.Request) object. + * + * @param Body instance Instance of Body + * @return Void + */ +function writeToStream(dest, instance) { + const body = instance.body; - for (var i = 0; i < encoding.chars.length; ++i) { - encoding.codes[encoding.chars[i]] = i; - } - } // The string must have a whole number of bytes: + if (body === null) { + // body is null + dest.end(); + } else if (isBlob(body)) { + body.stream().pipe(dest); + } else if (Buffer.isBuffer(body)) { + // body is buffer + dest.write(body); + dest.end(); + } else { + // body is stream + body.pipe(dest); + } +} - if (!opts.loose && string.length * encoding.bits & 7) { - throw new SyntaxError('Invalid padding'); - } // Count the padding bytes: +// expose Promise +Body.Promise = global.Promise; +/** + * headers.js + * + * Headers class offers convenient helpers + */ - var end = string.length; +const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; +const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; - while (string[end - 1] === '=') { - --end; // If we get a whole number of bytes, there is too much padding: +function validateName(name) { + name = `${name}`; + if (invalidTokenRegex.test(name) || name === '') { + throw new TypeError(`${name} is not a legal HTTP header name`); + } +} - if (!opts.loose && !((string.length - end) * encoding.bits & 7)) { - throw new SyntaxError('Invalid padding'); - } - } // Allocate the output: +function validateValue(value) { + value = `${value}`; + if (invalidHeaderCharRegex.test(value)) { + throw new TypeError(`${value} is not a legal HTTP header value`); + } +} +/** + * Find the key in the map object given a header name. + * + * Returns undefined if not found. + * + * @param String name Header name + * @return String|Undefined + */ +function find(map, name) { + name = name.toLowerCase(); + for (const key in map) { + if (key.toLowerCase() === name) { + return key; + } + } + return undefined; +} - var out = new ((_opts$out = opts.out) != null ? _opts$out : Uint8Array)(end * encoding.bits / 8 | 0); // Parse the data: +const MAP = Symbol('map'); +class Headers { + /** + * Headers class + * + * @param Object headers Response headers + * @return Void + */ + constructor() { + let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; - var bits = 0; // Number of bits currently in the buffer + this[MAP] = Object.create(null); - var buffer = 0; // Bits waiting to be written out, MSB first + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); - var written = 0; // Next byte to write + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } - for (var _i = 0; _i < end; ++_i) { - // Read one character from the string: - var value = encoding.codes[string[_i]]; + return; + } - if (value === undefined) { - throw new SyntaxError('Invalid character ' + string[_i]); - } // Append the bits to the buffer: + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } - buffer = buffer << encoding.bits | value; - bits += encoding.bits; // Write out some bits if the buffer has a byte's worth: + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } - if (bits >= 8) { - bits -= 8; - out[written++] = 0xff & buffer >> bits; - } - } // Verify that we have received just enough bits: + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } + return this[MAP][key].join(', '); + } - if (bits >= encoding.bits || 0xff & buffer << 8 - bits) { - throw new SyntaxError('Unexpected end of data'); - } + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; - return out; -} -function stringify(data, encoding, opts) { - if (opts === void 0) { - opts = {}; - } + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; - var _opts = opts, - _opts$pad = _opts.pad, - pad = _opts$pad === void 0 ? true : _opts$pad; - var mask = (1 << encoding.bits) - 1; - var out = ''; - var bits = 0; // Number of bits currently in the buffer + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } - var buffer = 0; // Bits waiting to be written out, MSB first + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } - for (var i = 0; i < data.length; ++i) { - // Slurp data into the buffer: - buffer = buffer << 8 | 0xff & data[i]; - bits += 8; // Write out as much as we can: + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } - while (bits > encoding.bits) { - bits -= encoding.bits; - out += encoding.chars[mask & buffer >> bits]; - } - } // Partial character: + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } - if (bits) { - out += encoding.chars[mask & buffer << encoding.bits - bits]; - } // Add padding characters until we hit a byte boundary: + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } - if (pad) { - while (out.length * encoding.bits & 7) { - out += '='; - } - } + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } - return out; + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } } +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; -/* eslint-disable @typescript-eslint/strict-boolean-expressions */ -var base16Encoding = { - chars: '0123456789ABCDEF', - bits: 4 -}; -var base32Encoding = { - chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', - bits: 5 -}; -var base32HexEncoding = { - chars: '0123456789ABCDEFGHIJKLMNOPQRSTUV', - bits: 5 -}; -var base64Encoding = { - chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', - bits: 6 -}; -var base64UrlEncoding = { - chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', - bits: 6 -}; -var base16 = { - parse: function parse$1(string, opts) { - return parse(string.toUpperCase(), base16Encoding, opts); - }, - stringify: function stringify$1(data, opts) { - return stringify(data, base16Encoding, opts); - } -}; -var base32 = { - parse: function parse$1(string, opts) { - if (opts === void 0) { - opts = {}; - } +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); - return parse(opts.loose ? string.toUpperCase().replace(/0/g, 'O').replace(/1/g, 'L').replace(/8/g, 'B') : string, base32Encoding, opts); - }, - stringify: function stringify$1(data, opts) { - return stringify(data, base32Encoding, opts); - } -}; -var base32hex = { - parse: function parse$1(string, opts) { - return parse(string, base32HexEncoding, opts); - }, - stringify: function stringify$1(data, opts) { - return stringify(data, base32HexEncoding, opts); - } -}; -var base64 = { - parse: function parse$1(string, opts) { - return parse(string, base64Encoding, opts); - }, - stringify: function stringify$1(data, opts) { - return stringify(data, base64Encoding, opts); - } -}; -var base64url = { - parse: function parse$1(string, opts) { - return parse(string, base64UrlEncoding, opts); - }, - stringify: function stringify$1(data, opts) { - return stringify(data, base64UrlEncoding, opts); - } -}; -var codec = { - parse: parse, - stringify: stringify -}; +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); -exports.base16 = base16; -exports.base32 = base32; -exports.base32hex = base32hex; -exports.base64 = base64; -exports.base64url = base64url; -exports.codec = codec; +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} -/***/ }), +const INTERNAL = Symbol('internal'); -/***/ 21867: -/***/ ((module, exports, __nccwpck_require__) => { +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; +} -/*! safe-buffer. MIT License. Feross Aboukhadijeh */ -/* eslint-disable node/no-deprecated-api */ -var buffer = __nccwpck_require__(14300) -var Buffer = buffer.Buffer +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } -// alternative to using Object.keys for old browsers -function copyProps (src, dst) { - for (var key in src) { - dst[key] = src[key] - } -} -if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { - module.exports = buffer -} else { - // Copy properties from require('buffer') - copyProps(buffer, exports) - exports.Buffer = SafeBuffer -} + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; -function SafeBuffer (arg, encodingOrOffset, length) { - return Buffer(arg, encodingOrOffset, length) -} + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } -SafeBuffer.prototype = Object.create(Buffer.prototype) + this[INTERNAL].index = index + 1; -// Copy static methods from Buffer -copyProps(Buffer, SafeBuffer) + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); -SafeBuffer.from = function (arg, encodingOrOffset, length) { - if (typeof arg === 'number') { - throw new TypeError('Argument must not be a number') - } - return Buffer(arg, encodingOrOffset, length) -} +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); -SafeBuffer.alloc = function (size, fill, encoding) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - var buf = Buffer(size) - if (fill !== undefined) { - if (typeof encoding === 'string') { - buf.fill(fill, encoding) - } else { - buf.fill(fill) - } - } else { - buf.fill(0) - } - return buf -} +/** + * Export the Headers object in a form that Node.js can consume. + * + * @param Headers headers + * @return Object + */ +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); -SafeBuffer.allocUnsafe = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return Buffer(size) + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } + + return obj; } -SafeBuffer.allocUnsafeSlow = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return buffer.SlowBuffer(size) +/** + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. + * + * @param Object obj Object of headers + * @return Headers + */ +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; } +const INTERNALS$1 = Symbol('Response internals'); -/***/ }), - -/***/ 15118: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; -/* eslint-disable node/no-deprecated-api */ +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; +/** + * Response class + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Body.call(this, body, opts); -var buffer = __nccwpck_require__(14300) -var Buffer = buffer.Buffer + const status = opts.status || 200; + const headers = new Headers(opts.headers); -var safer = {} + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } -var key + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } -for (key in buffer) { - if (!buffer.hasOwnProperty(key)) continue - if (key === 'SlowBuffer' || key === 'Buffer') continue - safer[key] = buffer[key] -} + get url() { + return this[INTERNALS$1].url || ''; + } -var Safer = safer.Buffer = {} -for (key in Buffer) { - if (!Buffer.hasOwnProperty(key)) continue - if (key === 'allocUnsafe' || key === 'allocUnsafeSlow') continue - Safer[key] = Buffer[key] -} + get status() { + return this[INTERNALS$1].status; + } -safer.Buffer.prototype = Buffer.prototype + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } -if (!Safer.from || Safer.from === Uint8Array.from) { - Safer.from = function (value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('The "value" argument must not be of type number. Received type ' + typeof value) - } - if (value && typeof value.length === 'undefined') { - throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type ' + typeof value) - } - return Buffer(value, encodingOrOffset, length) - } -} + get redirected() { + return this[INTERNALS$1].counter > 0; + } -if (!Safer.alloc) { - Safer.alloc = function (size, fill, encoding) { - if (typeof size !== 'number') { - throw new TypeError('The "size" argument must be of type number. Received type ' + typeof size) - } - if (size < 0 || size >= 2 * (1 << 30)) { - throw new RangeError('The value "' + size + '" is invalid for option "size"') - } - var buf = Buffer(size) - if (!fill || fill.length === 0) { - buf.fill(0) - } else if (typeof encoding === 'string') { - buf.fill(fill, encoding) - } else { - buf.fill(fill) - } - return buf - } -} + get statusText() { + return this[INTERNALS$1].statusText; + } -if (!safer.kStringMaxLength) { - try { - safer.kStringMaxLength = process.binding('buffer').kStringMaxLength - } catch (e) { - // we can't determine kStringMaxLength in environments where process.binding - // is unsupported, so let's not set it - } -} + get headers() { + return this[INTERNALS$1].headers; + } -if (!safer.constants) { - safer.constants = { - MAX_LENGTH: safer.kMaxLength - } - if (safer.kStringMaxLength) { - safer.constants.MAX_STRING_LENGTH = safer.kStringMaxLength - } + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } } -module.exports = safer - - -/***/ }), - -/***/ 72043: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -;(function (sax) { // wrapper for non-node envs - sax.parser = function (strict, opt) { return new SAXParser(strict, opt) } - sax.SAXParser = SAXParser - sax.SAXStream = SAXStream - sax.createStream = createStream - - // When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns. - // When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)), - // since that's the earliest that a buffer overrun could occur. This way, checks are - // as rare as required, but as often as necessary to ensure never crossing this bound. - // Furthermore, buffers are only tested at most once per write(), so passing a very - // large string into write() might have undesirable effects, but this is manageable by - // the caller, so it is assumed to be safe. Thus, a call to write() may, in the extreme - // edge case, result in creating at most one complete copy of the string passed in. - // Set to Infinity to have unlimited buffers. - sax.MAX_BUFFER_LENGTH = 64 * 1024 - - var buffers = [ - 'comment', 'sgmlDecl', 'textNode', 'tagName', 'doctype', - 'procInstName', 'procInstBody', 'entity', 'attribName', - 'attribValue', 'cdata', 'script' - ] - - sax.EVENTS = [ - 'text', - 'processinginstruction', - 'sgmldeclaration', - 'doctype', - 'comment', - 'opentagstart', - 'attribute', - 'opentag', - 'closetag', - 'opencdata', - 'cdata', - 'closecdata', - 'error', - 'end', - 'ready', - 'script', - 'opennamespace', - 'closenamespace' - ] - - function SAXParser (strict, opt) { - if (!(this instanceof SAXParser)) { - return new SAXParser(strict, opt) - } - - var parser = this - clearBuffers(parser) - parser.q = parser.c = '' - parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH - parser.opt = opt || {} - parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags - parser.looseCase = parser.opt.lowercase ? 'toLowerCase' : 'toUpperCase' - parser.tags = [] - parser.closed = parser.closedRoot = parser.sawRoot = false - parser.tag = parser.error = null - parser.strict = !!strict - parser.noscript = !!(strict || parser.opt.noscript) - parser.state = S.BEGIN - parser.strictEntities = parser.opt.strictEntities - parser.ENTITIES = parser.strictEntities ? Object.create(sax.XML_ENTITIES) : Object.create(sax.ENTITIES) - parser.attribList = [] - - // namespaces form a prototype chain. - // it always points at the current tag, - // which protos to its parent tag. - if (parser.opt.xmlns) { - parser.ns = Object.create(rootNS) - } - - // mostly just for error reporting - parser.trackPosition = parser.opt.position !== false - if (parser.trackPosition) { - parser.position = parser.line = parser.column = 0 - } - emit(parser, 'onready') - } - - if (!Object.create) { - Object.create = function (o) { - function F () {} - F.prototype = o - var newf = new F() - return newf - } - } - - if (!Object.keys) { - Object.keys = function (o) { - var a = [] - for (var i in o) if (o.hasOwnProperty(i)) a.push(i) - return a - } - } - - function checkBufferLength (parser) { - var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10) - var maxActual = 0 - for (var i = 0, l = buffers.length; i < l; i++) { - var len = parser[buffers[i]].length - if (len > maxAllowed) { - // Text/cdata nodes can get big, and since they're buffered, - // we can get here under normal conditions. - // Avoid issues by emitting the text node now, - // so at least it won't get any bigger. - switch (buffers[i]) { - case 'textNode': - closeText(parser) - break +Body.mixIn(Response.prototype); - case 'cdata': - emitNode(parser, 'oncdata', parser.cdata) - parser.cdata = '' - break +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); - case 'script': - emitNode(parser, 'onscript', parser.script) - parser.script = '' - break +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); - default: - error(parser, 'Max buffer length exceeded: ' + buffers[i]) - } - } - maxActual = Math.max(maxActual, len) - } - // schedule the next check for the earliest possible buffer overrun. - var m = sax.MAX_BUFFER_LENGTH - maxActual - parser.bufferCheckPosition = m + parser.position - } +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; - function clearBuffers (parser) { - for (var i = 0, l = buffers.length; i < l; i++) { - parser[buffers[i]] = '' - } - } +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; - function flushBuffers (parser) { - closeText(parser) - if (parser.cdata !== '') { - emitNode(parser, 'oncdata', parser.cdata) - parser.cdata = '' - } - if (parser.script !== '') { - emitNode(parser, 'onscript', parser.script) - parser.script = '' - } - } +/** + * Wrapper around `new URL` to handle arbitrary URLs + * + * @param {string} urlStr + * @return {void} + */ +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + */ + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } - SAXParser.prototype = { - end: function () { end(this) }, - write: write, - resume: function () { this.error = null; return this }, - close: function () { return this.write(null) }, - flush: function () { flushBuffers(this) } - } + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); +} - var Stream - try { - Stream = (__nccwpck_require__(12781).Stream) - } catch (ex) { - Stream = function () {} - } +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; - var streamWraps = sax.EVENTS.filter(function (ev) { - return ev !== 'error' && ev !== 'end' - }) +/** + * Check if a value is an instance of Request. + * + * @param Mixed input + * @return Boolean + */ +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; +} - function createStream (strict, opt) { - return new SAXStream(strict, opt) - } +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); +} - function SAXStream (strict, opt) { - if (!(this instanceof SAXStream)) { - return new SAXStream(strict, opt) - } +/** + * Request class + * + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void + */ +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - Stream.apply(this) + let parsedURL; - this._parser = new SAXParser(strict, opt) - this.writable = true - this.readable = true + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } - var me = this + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); - this._parser.onend = function () { - me.emit('end') - } + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } - this._parser.onerror = function (er) { - me.emit('error', er) + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; - // if didn't throw, then means error was handled. - // go ahead and clear error, so we can write again. - me._parser.error = null - } + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); - this._decoder = null + const headers = new Headers(init.headers || input.headers || {}); - streamWraps.forEach(function (ev) { - Object.defineProperty(me, 'on' + ev, { - get: function () { - return me._parser['on' + ev] - }, - set: function (h) { - if (!h) { - me.removeAllListeners(ev) - me._parser['on' + ev] = h - return h - } - me.on(ev, h) - }, - enumerable: true, - configurable: false - }) - }) - } + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } - SAXStream.prototype = Object.create(Stream.prototype, { - constructor: { - value: SAXStream - } - }) + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; - SAXStream.prototype.write = function (data) { - if (typeof Buffer === 'function' && - typeof Buffer.isBuffer === 'function' && - Buffer.isBuffer(data)) { - if (!this._decoder) { - var SD = (__nccwpck_require__(71576).StringDecoder) - this._decoder = new SD('utf8') - } - data = this._decoder.write(data) - } + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } - this._parser.write(data.toString()) - this.emit('data', data) - return true - } + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; - SAXStream.prototype.end = function (chunk) { - if (chunk && chunk.length) { - this.write(chunk) - } - this._parser.end() - return true - } + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } - SAXStream.prototype.on = function (ev, handler) { - var me = this - if (!me._parser['on' + ev] && streamWraps.indexOf(ev) !== -1) { - me._parser['on' + ev] = function () { - var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments) - args.splice(0, 0, ev) - me.emit.apply(me, args) - } - } + get method() { + return this[INTERNALS$2].method; + } - return Stream.prototype.on.call(me, ev, handler) - } - - // this really needs to be replaced with character classes. - // XML allows all manner of ridiculous numbers and digits. - var CDATA = '[CDATA[' - var DOCTYPE = 'DOCTYPE' - var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace' - var XMLNS_NAMESPACE = 'http://www.w3.org/2000/xmlns/' - var rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE } - - // http://www.w3.org/TR/REC-xml/#NT-NameStartChar - // This implementation works on strings, a single character at a time - // as such, it cannot ever support astral-plane characters (10000-EFFFF) - // without a significant breaking change to either this parser, or the - // JavaScript language. Implementation of an emoji-capable xml parser - // is left as an exercise for the reader. - var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/ - - var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/ - - var entityStart = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/ - var entityBody = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/ - - function isWhitespace (c) { - return c === ' ' || c === '\n' || c === '\r' || c === '\t' - } - - function isQuote (c) { - return c === '"' || c === '\'' - } - - function isAttribEnd (c) { - return c === '>' || isWhitespace(c) - } - - function isMatch (regex, c) { - return regex.test(c) - } - - function notMatch (regex, c) { - return !isMatch(regex, c) - } - - var S = 0 - sax.STATE = { - BEGIN: S++, // leading byte order mark or whitespace - BEGIN_WHITESPACE: S++, // leading whitespace - TEXT: S++, // general stuff - TEXT_ENTITY: S++, // & and such. - OPEN_WAKA: S++, // < - SGML_DECL: S++, // - SCRIPT: S++, //