├── .github ├── CODEOWNERS ├── FUNDING.yml ├── boring-cyborg.yml ├── dependabot.yml ├── settings.yml └── workflows │ ├── ci.yml │ ├── craft-release.yaml │ └── set-milestone-on-pr.yaml ├── LICENSE ├── README.md ├── action.yml ├── composer.json ├── main.js ├── node_modules ├── .bin │ └── semver ├── lru-cache │ ├── LICENSE │ ├── README.md │ ├── index.js │ └── package.json ├── semver │ ├── LICENSE │ ├── README.md │ ├── bin │ │ └── semver.js │ ├── classes │ │ ├── comparator.js │ │ ├── index.js │ │ ├── range.js │ │ └── semver.js │ ├── functions │ │ ├── clean.js │ │ ├── cmp.js │ │ ├── coerce.js │ │ ├── compare-build.js │ │ ├── compare-loose.js │ │ ├── compare.js │ │ ├── diff.js │ │ ├── eq.js │ │ ├── gt.js │ │ ├── gte.js │ │ ├── inc.js │ │ ├── lt.js │ │ ├── lte.js │ │ ├── major.js │ │ ├── minor.js │ │ ├── neq.js │ │ ├── parse.js │ │ ├── patch.js │ │ ├── prerelease.js │ │ ├── rcompare.js │ │ ├── rsort.js │ │ ├── satisfies.js │ │ ├── sort.js │ │ └── valid.js │ ├── index.js │ ├── internal │ │ ├── constants.js │ │ ├── debug.js │ │ ├── identifiers.js │ │ ├── parse-options.js │ │ └── re.js │ ├── package.json │ ├── preload.js │ ├── range.bnf │ └── ranges │ │ ├── gtr.js │ │ ├── intersects.js │ │ ├── ltr.js │ │ ├── max-satisfying.js │ │ ├── min-satisfying.js │ │ ├── min-version.js │ │ ├── outside.js │ │ ├── simplify.js │ │ ├── subset.js │ │ ├── to-comparators.js │ │ └── valid.js └── yallist │ ├── LICENSE │ ├── README.md │ ├── iterator.js │ ├── package.json │ └── yallist.js ├── package-lock.json ├── package.json └── situations ├── another-working-directory └── composer.json ├── ext-parallel-composer.lock ├── composer.json └── composer.lock ├── wyrihaximus-react-phpunit-run-tests-in-fiber-composer.lock ├── composer.json └── composer.lock └── wyrihaximus-test-utilities-composer.lock ├── composer.json └── composer.lock /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @WyriHaximus 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: WyriHaximus -------------------------------------------------------------------------------- /.github/boring-cyborg.yml: -------------------------------------------------------------------------------- 1 | labelPRBasedOnFilePath: 2 | "Dependencies 📦": 3 | - Dockerfile* 4 | - composer.* 5 | - package.json 6 | - package-lock.json 7 | - yarn.lock 8 | "Docker 🐳": 9 | - Dockerfile* 10 | - .docker/**/* 11 | "Image 🖼": 12 | - "**/*.gif" 13 | - "**/*.jpg" 14 | - "**/*.jpeg" 15 | - "**/*.png" 16 | - "**/*.webp" 17 | "CSS 👩‍🎨": 18 | - "**/*.css" 19 | "HTML 👷‍♀️": 20 | - "**/*.htm" 21 | - "**/*.html" 22 | "NEON 🦹‍♂️": 23 | - "**/*.neon" 24 | "MarkDown 📝": 25 | - "**/*.md" 26 | "YAML 🍄": 27 | - "**/*.yml" 28 | - "**/*.yaml" 29 | "JSON 👨‍💼": 30 | - "**/*.json" 31 | "Go 🐹": 32 | - "**/*.go" 33 | "JavaScript 🦏": 34 | - "**/*.js" 35 | - package.json 36 | - package-lock.json 37 | - yarn.lock 38 | "PHP 🐘": 39 | - "**/*.php" 40 | - composer.* 41 | "Configuration ⚙": 42 | - .github/* 43 | "CI 🚧": 44 | - .github/workflows/* 45 | - .scrutinizer.yml 46 | "Templates 🌲": 47 | - "**/*.twig" 48 | - "**/*.tpl" 49 | "Helm ☸": 50 | - .helm/**/* 51 | "Tests 🧪": 52 | - tests/**/* 53 | "Source 🔮": 54 | - src/**/* 55 | 56 | labelerFlags: 57 | labelOnPRUpdates: true 58 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "composer" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | labels: 8 | - "Dependencies 📦" 9 | - "PHP 🐘" 10 | versioning-strategy: "increase-if-necessary" 11 | open-pull-requests-limit: 1 12 | -------------------------------------------------------------------------------- /.github/settings.yml: -------------------------------------------------------------------------------- 1 | repository: 2 | private: false 3 | has_issues: true 4 | has_wiki: false 5 | has_downloads: true 6 | default_branch: master 7 | allow_squash_merge: false 8 | allow_merge_commit: true 9 | allow_rebase_merge: false 10 | 11 | # Labels: define labels for Issues and Pull Requests 12 | labels: 13 | - name: "Dependencies 📦" 14 | color: 0025ff 15 | description: "Pull requests that update a dependency file" 16 | - name: "Image 🖼" 17 | color: 00ffff 18 | - name: "HTML 👷‍♀️" 19 | color: ffffff 20 | - name: "CSS 👩‍🎨" 21 | color: b3b3b3 22 | - name: "JavaScript 🦏" 23 | color: ffff00 24 | - name: "Go 🐹" 25 | color: 00ADD8 26 | - name: "JSON 👨‍💼" 27 | color: 00ADD8 28 | - name: "NEON 🦹‍♂️" 29 | color: CE3262 30 | - name: "MarkDown 📝" 31 | color: 000000 32 | - name: "YAML 🍄" 33 | color: ff1aff 34 | - name: "Templates 🌲" 35 | color: 009933 36 | - name: "Helm ☸" 37 | color: 091C84 38 | - name: "Tests 🧪" 39 | color: ffe6e6 40 | - name: "Source 🔮" 41 | color: e6ffe6 42 | - name: "Configuration ⚙" 43 | color: b3b3cc 44 | - name: "PHP 🐘" 45 | color: 8892BF 46 | description: "Hypertext Pre Processor" 47 | - name: "Docker 🐳" 48 | color: 0db7ed 49 | description: "Pull requests that relate to Docker" 50 | - name: "CI 🚧" 51 | color: ffff00 52 | - name: "Feature 🏗" 53 | color: 66ff99 54 | - name: "Documentation 📚" 55 | color: 6666ff 56 | - name: "Security 🕵️‍♀️" 57 | color: ff0000 58 | - name: "Hacktoberfest 🎃" 59 | color: 152347 60 | - name: "Bug 🐞" 61 | color: d73a4a 62 | description: "Something isn't working" 63 | oldname: bug 64 | - name: "Duplicate ♊" 65 | color: cfd3d7 66 | description: "This issue or pull request already exists" 67 | oldname: duplicate 68 | - name: "Enhancement ✨" 69 | color: a2eeef 70 | description: "New feature or request" 71 | oldname: enhancement 72 | - name: "Good First Issue" 73 | color: 7057ff 74 | description: "Good for newcomers" 75 | oldname: "good first issue" 76 | - name: "Help Wanted" 77 | color: 008672 78 | description: "Extra attention is needed" 79 | oldname: "help wanted" 80 | - name: Invalid 81 | color: e4e669 82 | description: "This doesn't seem right" 83 | oldname: invalid 84 | - name: "Question ❓" 85 | color: d876e3 86 | description: "Further information is requested" 87 | oldname: question 88 | - name: "Will not be fixed 🛑" 89 | color: ffffff 90 | description: "This will not be worked on" 91 | oldname: wontfix 92 | - name: "Sponsor Request ❤️" 93 | color: fedbf0 94 | description: "Issue/PR opened by sponsor" 95 | 96 | branches: 97 | - name: master 98 | protection: 99 | required_pull_request_reviews: 100 | required_approving_review_count: 1 101 | dismiss_stale_reviews: true 102 | require_code_owner_reviews: true 103 | # Required. Require status checks to pass before merging. Set to null to disable 104 | required_status_checks: 105 | # Required. Require branches to be up to date before merging. 106 | strict: true 107 | # Required. The list of status checks to require in order to merge into this branch 108 | contexts: [] 109 | # Required. Enforce all configured restrictions for administrators. Set to true to enforce required status checks for repository administrators. Set to null to disable. 110 | enforce_admins: true 111 | # Required. Restrict who can push to this branch. Team and user restrictions are only available for organization-owned repositories. Set to null to disable. 112 | restrictions: 113 | apps: [] 114 | users: [] 115 | teams: [] 116 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | pull_request: 7 | jobs: 8 | get-supported-php-versions: 9 | name: Test Composer PHP versions in range Tag on ${{ matrix.os }} in ${{ matrix.workingDirectory }} 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | include: 14 | - workingDirectory: "situations/another-working-directory/" 15 | highestUpcoming: "5.6" 16 | nightly: "5.6" 17 | highest: "5.6" 18 | lowest: "5.3" 19 | extensions: "ast,pcov,xdebug" 20 | requiredExtensions: "ast" 21 | requiredDevExtensions: "pcov,xdebug" 22 | os: ubuntu-latest 23 | - workingDirectory: "situations/another-working-directory" 24 | highestUpcoming: "5.6" 25 | nightly: "5.6" 26 | highest: "5.6" 27 | lowest: "5.3" 28 | extensions: "ast,pcov,xdebug" 29 | requiredExtensions: "ast" 30 | requiredDevExtensions: "pcov,xdebug" 31 | os: ubuntu-latest 32 | - workingDirectory: "situations/ext-parallel-composer.lock/" 33 | highestUpcoming: "8.4" 34 | nightly: "8.4" 35 | highest: "8.4" 36 | lowest: "8.2" 37 | extensions: "parallel,pcov,xdebug" 38 | requiredExtensions: "parallel" 39 | requiredDevExtensions: "pcov,xdebug" 40 | os: ubuntu-latest 41 | - workingDirectory: "situations/wyrihaximus-test-utilities-composer.lock/" 42 | highestUpcoming: "8.4" 43 | nightly: "8.4" 44 | highest: "8.4" 45 | lowest: "8.2" 46 | extensions: "bcmath,ctype,dom,filter,intl,json,libxml,mbstring,openssl,pcov,pcre,phar,reflection,simplexml,sodium,spl,tokenizer,xdebug,xml,xmlwriter" 47 | requiredExtensions: "bcmath,ctype,dom,filter,intl,json,libxml,mbstring,openssl,pcre,phar,reflection,simplexml,sodium,spl,tokenizer,xml,xmlwriter" 48 | requiredDevExtensions: "pcov,xdebug" 49 | os: ubuntu-latest 50 | - workingDirectory: "situations/wyrihaximus-react-phpunit-run-tests-in-fiber-composer.lock/" 51 | highestUpcoming: "8.4" 52 | nightly: "8.4" 53 | highest: "8.4" 54 | lowest: "8.2" 55 | extensions: "bcmath,ctype,dom,filter,intl,json,libxml,mbstring,openssl,pcre,phar,reflection,simplexml,sodium,spl,tokenizer,xml,xmlwriter" 56 | requiredExtensions: "" 57 | requiredDevExtensions: "bcmath,ctype,dom,filter,intl,json,libxml,mbstring,openssl,pcre,phar,reflection,simplexml,sodium,spl,tokenizer,xml,xmlwriter" 58 | os: ubuntu-latest 59 | os: 60 | - ubuntu-latest 61 | - windows-latest 62 | - macos-latest 63 | workingDirectory: 64 | - "" 65 | highestUpcoming: 66 | - "8.4" 67 | nightly: 68 | - "8.4" 69 | highest: 70 | - "8.4" 71 | lowest: 72 | - "7.3" 73 | extensions: 74 | - "ast,pcov,xdebug" 75 | requiredExtensions: 76 | - "ast" 77 | requiredDevExtensions: 78 | - "pcov,xdebug" 79 | outputs: 80 | highest: ${{ steps.versionsinrange.outputs.highest }} 81 | extensions: ${{ steps.versionsinrange.outputs.extensions }} 82 | requiredExtensions: ${{ steps.versionsinrange.outputs.requiredExtensions }} 83 | requiredDevExtensions: ${{ steps.versionsinrange.outputs.requiredDevExtensions }} 84 | runs-on: ${{ matrix.os }} 85 | steps: 86 | - uses: actions/checkout@v2 87 | - name: 'Composer PHP versions in range' 88 | id: versionsinrange 89 | uses: ./ 90 | with: 91 | workingDirectory: ${{ matrix.workingDirectory }} 92 | - run: | 93 | echo "${{ steps.versionsinrange.outputs.version }}" 94 | - name: 'Composer PHP versions in range including upcoming releases' 95 | id: versionsinrangeincludingupcomingreleases 96 | uses: ./ 97 | with: 98 | upcomingReleases: true 99 | workingDirectory: ${{ matrix.workingDirectory }} 100 | - run: | 101 | echo "${{ steps.versionsinrange.outputs.version }}" 102 | - name: 'Composer PHP versions in range including nightly' 103 | id: versionsinrangeincludingnightly 104 | uses: ./ 105 | with: 106 | nightly: true 107 | workingDirectory: ${{ matrix.workingDirectory }} 108 | - run: | 109 | echo "${{ steps.versionsinrangeincludingnightly.outputs.version }}" 110 | - name: 'Composer PHP versions in range including nightly and upcoming releases' 111 | id: versionsinrangeincludingnightlyandupcomingreleases 112 | uses: ./ 113 | with: 114 | upcomingReleases: true 115 | nightly: true 116 | workingDirectory: ${{ matrix.workingDirectory }} 117 | - run: | 118 | echo "${{ steps.versionsinrangeincludingnightlyandupcomingreleases.outputs.version }}" 119 | - name: "Assert Output: lowest" 120 | uses: nick-fields/assert-action@v1 121 | with: 122 | expected: ${{ matrix.lowest }} 123 | actual: ${{ steps.versionsinrange.outputs.lowest }} 124 | - name: "Assert Output: highest" 125 | uses: nick-fields/assert-action@v1 126 | with: 127 | expected: ${{ matrix.highest }} 128 | actual: ${{ steps.versionsinrange.outputs.highest }} 129 | - name: "Assert Output: highest (upcoming releases)" 130 | uses: nick-fields/assert-action@v1 131 | with: 132 | expected: ${{ matrix.highestUpcoming }} 133 | actual: ${{ steps.versionsinrangeincludingupcomingreleases.outputs.highest }} 134 | - name: "Assert Output: highest (nightly)" 135 | uses: nick-fields/assert-action@v1 136 | with: 137 | expected: ${{ matrix.nightly }} 138 | actual: ${{ steps.versionsinrangeincludingnightly.outputs.highest }} 139 | - name: "Assert Output: extensions" 140 | uses: nick-fields/assert-action@v1 141 | with: 142 | expected: ${{ matrix.extensions }} 143 | actual: ${{ join(fromJson(steps.versionsinrange.outputs.extensions), ',') }} 144 | - name: "Assert Output: requiredExtensions" 145 | uses: nick-fields/assert-action@v1 146 | with: 147 | expected: ${{ matrix.requiredExtensions }} 148 | actual: ${{ join(fromJson(steps.versionsinrange.outputs.requiredExtensions), ',') }} 149 | - name: "Assert Output: requiredDevExtensions" 150 | uses: nick-fields/assert-action@v1 151 | with: 152 | expected: ${{ matrix.requiredDevExtensions }} 153 | actual: ${{ join(fromJson(steps.versionsinrange.outputs.requiredDevExtensions), ',') }} 154 | extensions: 155 | name: Detected extensions on ${{ matrix.os }} 156 | strategy: 157 | matrix: 158 | os: 159 | - ubuntu-latest 160 | - windows-latest 161 | - macos-latest 162 | needs: 163 | - get-supported-php-versions 164 | runs-on: ${{ matrix.os }} 165 | steps: 166 | - run: | 167 | echo "All require extensions: ${{ needs.get-supported-php-versions.outputs.extensions }}" 168 | echo "Require extensions: ${{ needs.get-supported-php-versions.outputs.requiredExtensions }}" 169 | echo "Dev require extensions: ${{ needs.get-supported-php-versions.outputs.requiredDevExtensions }}" 170 | - uses: shivammathur/setup-php@v2 171 | with: 172 | php-version: ${{ needs.get-supported-php-versions.outputs.highest }} 173 | tools: composer 174 | coverage: none 175 | extensions: ${{ join(fromJson(needs.get-supported-php-versions.outputs.extensions), ',') }} 176 | -------------------------------------------------------------------------------- /.github/workflows/craft-release.yaml: -------------------------------------------------------------------------------- 1 | name: Create Release 2 | env: 3 | DOCKER_IMAGE: wyrihaximusgithubactions/jwage-changelog-generator 4 | MILESTONE: ${{ github.event.milestone.title }} 5 | on: 6 | milestone: 7 | types: 8 | - closed 9 | jobs: 10 | wait-for-status-checks: 11 | name: Wait for status checks 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v1 15 | - run: sleep 13 16 | - name: 'Wait for status checks' 17 | id: waitforstatuschecks 18 | uses: "WyriHaximus/github-action-wait-for-status@master" 19 | with: 20 | ignoreActions: "Wait for status checks" 21 | checkInterval: 5 22 | env: 23 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 24 | - if: steps.waitforstatuschecks.outputs.status != 'success' 25 | name: Fail 26 | run: exit 1 27 | generate-changelog: 28 | name: Generate Changelog 29 | runs-on: ubuntu-latest 30 | needs: 31 | - wait-for-status-checks 32 | outputs: 33 | changelog: ${{ steps.changelog.outputs.changelog }} 34 | steps: 35 | - name: Generate changelog 36 | uses: WyriHaximus/github-action-jwage-changelog-generator@master 37 | id: changelog 38 | env: 39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 40 | with: 41 | milestone: ${{ env.MILESTONE }} 42 | - name: Show changelog 43 | run: echo "${CHANGELOG}" 44 | env: 45 | CHANGELOG: ${{ steps.changelog.outputs.changelog }} 46 | create-release: 47 | name: Create Release 48 | needs: 49 | - generate-changelog 50 | runs-on: ubuntu-latest 51 | steps: 52 | - uses: actions/checkout@v1 53 | - name: Create release/${{ env.MILESTONE }} branch 54 | run: git checkout -b release/${{ env.MILESTONE }} ${GITHUB_SHA} 55 | - run: echo -e "${CHANGELOG}" > release-${{ env.MILESTONE }}-changelog.md 56 | env: 57 | CHANGELOG: ${{ needs.generate-changelog.outputs.changelog }} 58 | - run: | 59 | echo -e "${MILESTONE_DESCRIPTION}\r\n\r\n${CHANGELOG}" > release-${{ env.MILESTONE }}-release-message.md 60 | cat release-${{ env.MILESTONE }}-release-message.md 61 | release_message=$(cat release-${{ env.MILESTONE }}-release-message.md) 62 | release_message="${release_message//'%'/'%25'}" 63 | release_message="${release_message//$'\n'/'%0A'}" 64 | release_message="${release_message//$'\r'/'%0D'}" 65 | echo "::set-output name=release_message::$release_message" 66 | id: releasemessage 67 | env: 68 | MILESTONE_DESCRIPTION: ${{ github.event.milestone.description }} 69 | CHANGELOG: ${{ needs.generate-changelog.outputs.changelog }} 70 | - name: Create release 71 | uses: actions/create-release@v1 72 | env: 73 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 74 | with: 75 | tag_name: ${{ env.MILESTONE }} 76 | release_name: ${{ env.MILESTONE }} 77 | body: ${{ steps.releasemessage.outputs.release_message }} 78 | draft: false 79 | prerelease: false 80 | - name: Updated related tags 81 | uses: haya14busa/action-update-semver@v1 82 | with: 83 | tag: ${{ env.MILESTONE }} 84 | 85 | -------------------------------------------------------------------------------- /.github/workflows/set-milestone-on-pr.yaml: -------------------------------------------------------------------------------- 1 | name: Set Milestone 2 | on: 3 | pull_request: 4 | types: 5 | - assigned 6 | - opened 7 | - synchronize 8 | - reopened 9 | - edited 10 | - ready_for_review 11 | - review_requested 12 | jobs: 13 | set-milestone: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v1 17 | if: github.event.pull_request.milestone == null 18 | - name: 'Get Previous tag' 19 | if: github.event.pull_request.milestone == null 20 | id: previousgittag 21 | continue-on-error: true 22 | uses: "WyriHaximus/github-action-get-previous-tag@master" 23 | env: 24 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 25 | - run: | 26 | if [ $(echo ${GITTAG} | wc -c) -eq 1 ] ; then 27 | printf "Falling back to v1.0.0 as \"%s\" is unexpectedly empty\r\n" "${GITTAG}" 28 | printf "::set-output name=tag::%s" "v1.0.0" 29 | exit 0 30 | fi 31 | 32 | printf "Using \"%s\"\r\n" "${GITTAG}" 33 | printf "::set-output name=tag::%s" "${GITTAG}" 34 | name: Fall back to v1.0.0 if we haven't tagged anything yet 35 | if: github.event.pull_request.milestone == null 36 | id: previoustag 37 | env: 38 | GITTAG: ${{ steps.previousgittag.outputs.tag }} 39 | - name: 'Get next versions' 40 | if: github.event.pull_request.milestone == null 41 | id: semvers 42 | uses: "WyriHaximus/github-action-next-semvers@master" 43 | with: 44 | version: ${{ steps.previoustag.outputs.tag }} 45 | strict: false 46 | - run: | 47 | if [ "$IS_DEPENDABOT" = true ] ; then 48 | echo "Is dependabot PR" 49 | if [[ "$(printenv MILESTONES | jq -c '. | length')" -eq "0" ]] ; then 50 | echo "No milestone exists, usint patch version for next milestone" 51 | printf "::set-output name=milestone::%s" "${PATCH}" 52 | exit 0 53 | fi 54 | fi 55 | 56 | echo "Using default minor version for next milestone" 57 | printf "::set-output name=milestone::%s" "${MINOR}" 58 | name: Decide which version to use as milestone 59 | if: github.event.pull_request.milestone == null 60 | id: milestone 61 | env: 62 | MILESTONES: ${{ steps.milestones.outputs.milestones }} 63 | MAJOR: ${{ steps.semvers.outputs.v_major }} 64 | MINOR: ${{ steps.semvers.outputs.v_minor }} 65 | PATCH: ${{ steps.semvers.outputs.v_patch }} 66 | IS_DEPENDABOT: ${{ contains(github.ref, 'dependabot') }} 67 | GITTAG: ${{ steps.previousgittag.outputs.tag }} 68 | PREVIOUSTAG: ${{ steps.previoustag.outputs.tag }} 69 | - name: 'Get Milestones' 70 | if: github.event.pull_request.milestone == null 71 | uses: "WyriHaximus/github-action-get-milestones@master" 72 | id: milestones 73 | env: 74 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 75 | - run: printf "::set-output name=number::%s" $(printenv MILESTONES | jq --arg MILESTONE $(printenv MILESTONE) '.[] | select(.title == $MILESTONE) | .number') 76 | if: github.event.pull_request.milestone == null 77 | id: querymilestone 78 | env: 79 | MILESTONES: ${{ steps.milestones.outputs.milestones }} 80 | MILESTONE: ${{ steps.milestone.outputs.milestone }} 81 | - name: 'Create Milestone' 82 | if: github.event.pull_request.milestone == null && steps.querymilestone.outputs.number == '' 83 | id: createmilestone 84 | uses: "WyriHaximus/github-action-create-milestone@master" 85 | with: 86 | title: ${{ steps.milestone.outputs.milestone }} 87 | env: 88 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 89 | - name: 'Select found or created Milestone' 90 | if: github.event.pull_request.milestone == null 91 | id: selectmilestone 92 | run: | 93 | if [ $(echo ${QUERY_NUMBER} | wc -c) -eq 1 ] ; then 94 | printf "::set-output name=number::%s" "${CREATED_NUMBER}" 95 | exit 0 96 | fi 97 | 98 | printf "::set-output name=number::%s" "${QUERY_NUMBER}" 99 | env: 100 | CREATED_NUMBER: ${{ steps.createmilestone.outputs.number }} 101 | QUERY_NUMBER: ${{ steps.querymilestone.outputs.number }} 102 | - name: 'Set Milestone' 103 | if: github.event.pull_request.milestone == null 104 | uses: "WyriHaximus/github-action-set-milestone@master" 105 | with: 106 | issue_number: ${{ github.event.pull_request.number }} 107 | milestone_number: ${{ steps.selectmilestone.outputs.number }} 108 | env: 109 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 110 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Cees-Jan Kiewiet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Composer PHP Versions in range 2 | 3 | GitHub Action that gets the PHP versions in range from composer.json 4 | 5 | ## Options 6 | 7 | This action supports the following option. 8 | 9 | ### upcomingReleases 10 | 11 | Will include the next upcoming major or minor PHP release. For example, if enabled at the time of writing (May 2022) 12 | that will be `8.2`. Note that this version will be updated once the first alpha is out. Looking for more bleeding 13 | edge, `nightly` will hold the same value from the release day of the previous `X.Y.0` release. 14 | 15 | * *Required*: `No` 16 | * *Type*: `Boolean` 17 | * *Default*: `false` 18 | * *Example*: `true` for including upcoming new major or minor releases 19 | 20 | ### nightly 21 | 22 | Will include the nightly of the next new major or minor PHP release. For example, if enabled at the time of writing (December 2023) 23 | that will be `8.4`. 24 | 25 | * *Required*: `No` 26 | * *Type*: `Boolean` 27 | * *Default*: `false` 28 | * *Example*: `true` for including the nightly of the next new major or minor releases 29 | 30 | ### workingDirectory 31 | 32 | Set a different than the root directory to look for `composer.json` 33 | 34 | * *Required*: `No` 35 | * *Type*: `String` 36 | * *Default*: `""` 37 | * *Example*: `clients/GitHub` 38 | 39 | ## Output 40 | 41 | The action comes with 7 outputs, most importantly `version` which contains a JSON list with versions to be used in 42 | follow up steps: 43 | 44 | ```json 45 | ["7.3","7.4","8.0","8.1","8.2","8.3","8.4"] 46 | ``` 47 | 48 | And the `highest` and `lowest` outputs that provide the highest PHP version (`8.4` in the `version` output example) 49 | and the lowest PHP version (`7.3` in the `version` output example) from the `version` list. The 4rth output is 50 | `upcoming` and will be populated with the upcoming but in alpha/beta/rc next minor or major version of PHP. The 51 | `nightly` contains the current in development but not alpha/beta/rc tag next major or minor version. 52 | 53 | On top of that this action will also give you 3 lists of extensions. The extensions from `require` in 54 | `requiredExtensions`, dev extensions in `requiredDevExtensions`, and a combined list in `extensions`. 55 | 56 | ## Example 57 | 58 | This example will get the supported PHP version from `composer.json` and run tests of all those version: 59 | 60 | ```yaml 61 | name: CI 62 | 63 | on: 64 | push: 65 | pull_request: 66 | 67 | jobs: 68 | supported-versions-matrix: 69 | name: Supported Versions Matrix 70 | runs-on: ubuntu-latest 71 | outputs: 72 | extensions: ${{ steps.supported-versions-matrix.outputs.extensions }} 73 | version: ${{ steps.supported-versions-matrix.outputs.version }} 74 | steps: 75 | - uses: actions/checkout@v3 76 | - id: supported-versions-matrix 77 | uses: WyriHaximus/github-action-composer-php-versions-in-range@v1 78 | tests: 79 | name: PHP ${{ matrix.php }} Latest 80 | runs-on: ubuntu-latest 81 | needs: 82 | - supported-versions-matrix 83 | strategy: 84 | matrix: 85 | php: ${{ fromJson(needs.supported-versions-matrix.outputs.version) }} 86 | steps: 87 | - name: Checkout code 88 | uses: actions/checkout@v3 89 | - name: Setup PHP 90 | uses: shivammathur/setup-php@v2 91 | with: 92 | php-version: ${{ matrix.php }} 93 | tools: composer 94 | coverage: none 95 | extensions: ${{ join(fromJson(needs.supported-versions-matrix.outputs.extensions), ',') }} 96 | - name: Install dependencies 97 | uses: ramsey/composer-install@v2 98 | - name: Execute tests 99 | run: composer test 100 | ``` 101 | 102 | ## License ## 103 | 104 | Copyright 2024 [Cees-Jan Kiewiet](http://wyrihaximus.net/) 105 | 106 | Permission is hereby granted, free of charge, to any person 107 | obtaining a copy of this software and associated documentation 108 | files (the "Software"), to deal in the Software without 109 | restriction, including without limitation the rights to use, 110 | copy, modify, merge, publish, distribute, sublicense, and/or sell 111 | copies of the Software, and to permit persons to whom the 112 | Software is furnished to do so, subject to the following 113 | conditions: 114 | 115 | The above copyright notice and this permission notice shall be 116 | included in all copies or substantial portions of the Software. 117 | 118 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 119 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 120 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 121 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 122 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 123 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 124 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 125 | OTHER DEALINGS IN THE SOFTWARE. 126 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Composer PHP versions in range' 2 | description: 'Get PHP versions in range from composer.json' 3 | branding: 4 | icon: 'maximize' 5 | color: 'green' 6 | inputs: 7 | upcomingReleases: 8 | description: 'Include upcoming new major or minor releases' 9 | required: false 10 | nightly: 11 | description: 'Include nightly of the next new major or minor releases' 12 | required: false 13 | workingDirectory: 14 | description: The directory to run this action in 15 | default: "" 16 | required: false 17 | outputs: 18 | highest: 19 | description: 'The highest version found in range' 20 | lowest: 21 | description: 'The lowest version found in range' 22 | version: 23 | description: 'The versions found in range' 24 | upcoming: 25 | description: 'The upcoming version found in range, if any' 26 | nightly: 27 | description: 'The nightly version found in range, if any' 28 | extensions: 29 | description: 'The PHP extensions found in require and require-dev' 30 | requiredExtensions: 31 | description: 'The PHP extensions found in require only' 32 | requiredDevExtensions: 33 | description: 'The PHP extensions found in require-dev only' 34 | runs: 35 | using: 'node20' 36 | main: 'main.js' 37 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "php": "^9 || ^8 || ^7.3", 4 | "ext-ast": "*" 5 | }, 6 | "require-dev": { 7 | "ext-pcov": "*", 8 | "ext-xdebug": "*" 9 | } 10 | } -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | const semver = require('semver'); 2 | const fs = require('fs'); 3 | const composerJsonPath = ( 4 | process.env.INPUT_WORKINGDIRECTORY.toString().length > 0 ? ( 5 | (process.env.INPUT_WORKINGDIRECTORY.endsWith('/') ? process.env.INPUT_WORKINGDIRECTORY.slice(0, -1) : process.env.INPUT_WORKINGDIRECTORY) + '/' 6 | ) : '' 7 | ) + 'composer.json'; 8 | const composerLockPath = ( 9 | process.env.INPUT_WORKINGDIRECTORY.toString().length > 0 ? ( 10 | (process.env.INPUT_WORKINGDIRECTORY.endsWith('/') ? process.env.INPUT_WORKINGDIRECTORY.slice(0, -1) : process.env.INPUT_WORKINGDIRECTORY) + '/' 11 | ) : '' 12 | ) + 'composer.lock'; 13 | 14 | let composerJson = JSON.parse(fs.readFileSync(composerJsonPath)); 15 | let composerLockExists = fs.existsSync(composerLockPath); 16 | let composerLock = {}; 17 | if (composerLockExists) { 18 | composerLock = JSON.parse(fs.readFileSync(composerLockPath)); 19 | } 20 | let supportedVersionsRange = composerJson['require']['php'].toString().replaceAll('||', 'PIPEPIPEPLACEHOLDER').replaceAll('|', '||').replaceAll('PIPEPIPEPLACEHOLDER', '||'); 21 | 22 | let versions = []; 23 | let upcomingVersion = ''; 24 | let nightlyVersion = ''; 25 | 26 | [ 27 | '5.3', 28 | '5.4', 29 | '5.5', 30 | '5.6', 31 | '7.0', 32 | '7.1', 33 | '7.2', 34 | '7.3', 35 | '7.4', 36 | '8.0', 37 | '8.1', 38 | '8.2', 39 | '8.3', 40 | '8.4', 41 | ].forEach(function (version) { 42 | if (semver.satisfies(version + '.0', supportedVersionsRange)) { 43 | versions.push(version); 44 | } 45 | }); 46 | 47 | if (process.env.INPUT_UPCOMINGRELEASES === 'true') { 48 | [ 49 | ].forEach(function (version) { 50 | if (semver.satisfies(version + '.0', supportedVersionsRange)) { 51 | versions.push(version); 52 | upcomingVersion = version; 53 | } 54 | }); 55 | } 56 | 57 | if (process.env.INPUT_NIGHTLY === 'true') { 58 | [ 59 | ].forEach(function (version) { 60 | if (semver.satisfies(version + '.0', supportedVersionsRange)) { 61 | versions.push(version); 62 | nightlyVersion = version; 63 | } 64 | }); 65 | } 66 | 67 | versions = versions.filter( 68 | (value, index, array) => array.indexOf(value) === index 69 | ); 70 | 71 | console.log(`Versions found: ${JSON.stringify(versions)}`); 72 | console.log(`Lowest version found: ${versions[0]}`); 73 | console.log(`Highest version found: ${versions[versions.length - 1]}`); 74 | 75 | fs.appendFileSync(process.env.GITHUB_OUTPUT, `version=${JSON.stringify(versions)}\n`); 76 | fs.appendFileSync(process.env.GITHUB_OUTPUT, `lowest=${versions[0]}\n`); 77 | fs.appendFileSync(process.env.GITHUB_OUTPUT, `highest=${versions[versions.length - 1]}\n`); 78 | fs.appendFileSync(process.env.GITHUB_OUTPUT, `upcoming=${upcomingVersion}\n`); 79 | fs.appendFileSync(process.env.GITHUB_OUTPUT, `nightly=${nightlyVersion}\n`); 80 | 81 | // Extensions handling 82 | function getExtensionsFromJason(section, composer) { 83 | if (!composer.hasOwnProperty(section)) { 84 | return []; 85 | } 86 | 87 | return Object.entries(composer[section]) 88 | .map(function (dependency) { 89 | return dependency[0]; 90 | }) 91 | .filter(function(dependency) { 92 | return dependency.toString().startsWith("ext-"); 93 | }) 94 | .map(function (dependency) { 95 | return dependency.toString().substring(4); 96 | }); 97 | } 98 | function getExtensionsFromLock(section, composer) { 99 | if (!composer.hasOwnProperty('packages' + section)) { 100 | return []; 101 | } 102 | 103 | return composer['packages' + section] 104 | .flatMap(function (packageObject) { 105 | return getExtensionsFromJason('require', packageObject); 106 | }); 107 | } 108 | 109 | function sortAndFilterExtensions(array) { 110 | return array.sort().filter( 111 | (value, index, array) => array.indexOf(value) === index 112 | ); 113 | } 114 | 115 | let requiredExtensions = getExtensionsFromJason('require', composerJson); 116 | if (composerLockExists) { 117 | requiredExtensions = requiredExtensions.concat( 118 | getExtensionsFromLock('', composerLock) 119 | ); 120 | } 121 | requiredExtensions = sortAndFilterExtensions(requiredExtensions); 122 | 123 | let requiredDevExtensions = getExtensionsFromJason('require-dev', composerJson); 124 | if (composerLockExists) { 125 | requiredDevExtensions = requiredDevExtensions.concat( 126 | getExtensionsFromLock('-dev', composerLock) 127 | ); 128 | } 129 | requiredDevExtensions = sortAndFilterExtensions(requiredDevExtensions); 130 | 131 | let allExtensions = sortAndFilterExtensions([...requiredExtensions, ...requiredDevExtensions]); 132 | 133 | console.log(`All required extensions: ${JSON.stringify(allExtensions)}`); 134 | console.log(`Required extensions: ${JSON.stringify(requiredExtensions)}`); 135 | console.log(`Required dev extensions: ${JSON.stringify(requiredDevExtensions)}`); 136 | 137 | fs.appendFileSync(process.env.GITHUB_OUTPUT, `extensions=${JSON.stringify(allExtensions)}\n`); 138 | fs.appendFileSync(process.env.GITHUB_OUTPUT, `requiredExtensions=${JSON.stringify(requiredExtensions)}\n`); 139 | fs.appendFileSync(process.env.GITHUB_OUTPUT, `requiredDevExtensions=${JSON.stringify(requiredDevExtensions)}\n`); 140 | -------------------------------------------------------------------------------- /node_modules/.bin/semver: -------------------------------------------------------------------------------- 1 | ../semver/bin/semver.js -------------------------------------------------------------------------------- /node_modules/lru-cache/LICENSE: -------------------------------------------------------------------------------- 1 | The ISC License 2 | 3 | Copyright (c) Isaac Z. Schlueter and Contributors 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 15 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /node_modules/lru-cache/README.md: -------------------------------------------------------------------------------- 1 | # lru cache 2 | 3 | A cache object that deletes the least-recently-used items. 4 | 5 | [![Build Status](https://travis-ci.org/isaacs/node-lru-cache.svg?branch=master)](https://travis-ci.org/isaacs/node-lru-cache) [![Coverage Status](https://coveralls.io/repos/isaacs/node-lru-cache/badge.svg?service=github)](https://coveralls.io/github/isaacs/node-lru-cache) 6 | 7 | ## Installation: 8 | 9 | ```javascript 10 | npm install lru-cache --save 11 | ``` 12 | 13 | ## Usage: 14 | 15 | ```javascript 16 | var LRU = require("lru-cache") 17 | , options = { max: 500 18 | , length: function (n, key) { return n * 2 + key.length } 19 | , dispose: function (key, n) { n.close() } 20 | , maxAge: 1000 * 60 * 60 } 21 | , cache = new LRU(options) 22 | , otherCache = new LRU(50) // sets just the max size 23 | 24 | cache.set("key", "value") 25 | cache.get("key") // "value" 26 | 27 | // non-string keys ARE fully supported 28 | // but note that it must be THE SAME object, not 29 | // just a JSON-equivalent object. 30 | var someObject = { a: 1 } 31 | cache.set(someObject, 'a value') 32 | // Object keys are not toString()-ed 33 | cache.set('[object Object]', 'a different value') 34 | assert.equal(cache.get(someObject), 'a value') 35 | // A similar object with same keys/values won't work, 36 | // because it's a different object identity 37 | assert.equal(cache.get({ a: 1 }), undefined) 38 | 39 | cache.reset() // empty the cache 40 | ``` 41 | 42 | If you put more stuff in it, then items will fall out. 43 | 44 | If you try to put an oversized thing in it, then it'll fall out right 45 | away. 46 | 47 | ## Options 48 | 49 | * `max` The maximum size of the cache, checked by applying the length 50 | function to all values in the cache. Not setting this is kind of 51 | silly, since that's the whole purpose of this lib, but it defaults 52 | to `Infinity`. Setting it to a non-number or negative number will 53 | throw a `TypeError`. Setting it to 0 makes it be `Infinity`. 54 | * `maxAge` Maximum age in ms. Items are not pro-actively pruned out 55 | as they age, but if you try to get an item that is too old, it'll 56 | drop it and return undefined instead of giving it to you. 57 | Setting this to a negative value will make everything seem old! 58 | Setting it to a non-number will throw a `TypeError`. 59 | * `length` Function that is used to calculate the length of stored 60 | items. If you're storing strings or buffers, then you probably want 61 | to do something like `function(n, key){return n.length}`. The default is 62 | `function(){return 1}`, which is fine if you want to store `max` 63 | like-sized things. The item is passed as the first argument, and 64 | the key is passed as the second argumnet. 65 | * `dispose` Function that is called on items when they are dropped 66 | from the cache. This can be handy if you want to close file 67 | descriptors or do other cleanup tasks when items are no longer 68 | accessible. Called with `key, value`. It's called *before* 69 | actually removing the item from the internal cache, so if you want 70 | to immediately put it back in, you'll have to do that in a 71 | `nextTick` or `setTimeout` callback or it won't do anything. 72 | * `stale` By default, if you set a `maxAge`, it'll only actually pull 73 | stale items out of the cache when you `get(key)`. (That is, it's 74 | not pre-emptively doing a `setTimeout` or anything.) If you set 75 | `stale:true`, it'll return the stale value before deleting it. If 76 | you don't set this, then it'll return `undefined` when you try to 77 | get a stale entry, as if it had already been deleted. 78 | * `noDisposeOnSet` By default, if you set a `dispose()` method, then 79 | it'll be called whenever a `set()` operation overwrites an existing 80 | key. If you set this option, `dispose()` will only be called when a 81 | key falls out of the cache, not when it is overwritten. 82 | * `updateAgeOnGet` When using time-expiring entries with `maxAge`, 83 | setting this to `true` will make each item's effective time update 84 | to the current time whenever it is retrieved from cache, causing it 85 | to not expire. (It can still fall out of cache based on recency of 86 | use, of course.) 87 | 88 | ## API 89 | 90 | * `set(key, value, maxAge)` 91 | * `get(key) => value` 92 | 93 | Both of these will update the "recently used"-ness of the key. 94 | They do what you think. `maxAge` is optional and overrides the 95 | cache `maxAge` option if provided. 96 | 97 | If the key is not found, `get()` will return `undefined`. 98 | 99 | The key and val can be any value. 100 | 101 | * `peek(key)` 102 | 103 | Returns the key value (or `undefined` if not found) without 104 | updating the "recently used"-ness of the key. 105 | 106 | (If you find yourself using this a lot, you *might* be using the 107 | wrong sort of data structure, but there are some use cases where 108 | it's handy.) 109 | 110 | * `del(key)` 111 | 112 | Deletes a key out of the cache. 113 | 114 | * `reset()` 115 | 116 | Clear the cache entirely, throwing away all values. 117 | 118 | * `has(key)` 119 | 120 | Check if a key is in the cache, without updating the recent-ness 121 | or deleting it for being stale. 122 | 123 | * `forEach(function(value,key,cache), [thisp])` 124 | 125 | Just like `Array.prototype.forEach`. Iterates over all the keys 126 | in the cache, in order of recent-ness. (Ie, more recently used 127 | items are iterated over first.) 128 | 129 | * `rforEach(function(value,key,cache), [thisp])` 130 | 131 | The same as `cache.forEach(...)` but items are iterated over in 132 | reverse order. (ie, less recently used items are iterated over 133 | first.) 134 | 135 | * `keys()` 136 | 137 | Return an array of the keys in the cache. 138 | 139 | * `values()` 140 | 141 | Return an array of the values in the cache. 142 | 143 | * `length` 144 | 145 | Return total length of objects in cache taking into account 146 | `length` options function. 147 | 148 | * `itemCount` 149 | 150 | Return total quantity of objects currently in cache. Note, that 151 | `stale` (see options) items are returned as part of this item 152 | count. 153 | 154 | * `dump()` 155 | 156 | Return an array of the cache entries ready for serialization and usage 157 | with 'destinationCache.load(arr)`. 158 | 159 | * `load(cacheEntriesArray)` 160 | 161 | Loads another cache entries array, obtained with `sourceCache.dump()`, 162 | into the cache. The destination cache is reset before loading new entries 163 | 164 | * `prune()` 165 | 166 | Manually iterates over the entire cache proactively pruning old entries 167 | -------------------------------------------------------------------------------- /node_modules/lru-cache/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | // A linked list to keep track of recently-used-ness 4 | const Yallist = require('yallist') 5 | 6 | const MAX = Symbol('max') 7 | const LENGTH = Symbol('length') 8 | const LENGTH_CALCULATOR = Symbol('lengthCalculator') 9 | const ALLOW_STALE = Symbol('allowStale') 10 | const MAX_AGE = Symbol('maxAge') 11 | const DISPOSE = Symbol('dispose') 12 | const NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet') 13 | const LRU_LIST = Symbol('lruList') 14 | const CACHE = Symbol('cache') 15 | const UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet') 16 | 17 | const naiveLength = () => 1 18 | 19 | // lruList is a yallist where the head is the youngest 20 | // item, and the tail is the oldest. the list contains the Hit 21 | // objects as the entries. 22 | // Each Hit object has a reference to its Yallist.Node. This 23 | // never changes. 24 | // 25 | // cache is a Map (or PseudoMap) that matches the keys to 26 | // the Yallist.Node object. 27 | class LRUCache { 28 | constructor (options) { 29 | if (typeof options === 'number') 30 | options = { max: options } 31 | 32 | if (!options) 33 | options = {} 34 | 35 | if (options.max && (typeof options.max !== 'number' || options.max < 0)) 36 | throw new TypeError('max must be a non-negative number') 37 | // Kind of weird to have a default max of Infinity, but oh well. 38 | const max = this[MAX] = options.max || Infinity 39 | 40 | const lc = options.length || naiveLength 41 | this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc 42 | this[ALLOW_STALE] = options.stale || false 43 | if (options.maxAge && typeof options.maxAge !== 'number') 44 | throw new TypeError('maxAge must be a number') 45 | this[MAX_AGE] = options.maxAge || 0 46 | this[DISPOSE] = options.dispose 47 | this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false 48 | this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false 49 | this.reset() 50 | } 51 | 52 | // resize the cache when the max changes. 53 | set max (mL) { 54 | if (typeof mL !== 'number' || mL < 0) 55 | throw new TypeError('max must be a non-negative number') 56 | 57 | this[MAX] = mL || Infinity 58 | trim(this) 59 | } 60 | get max () { 61 | return this[MAX] 62 | } 63 | 64 | set allowStale (allowStale) { 65 | this[ALLOW_STALE] = !!allowStale 66 | } 67 | get allowStale () { 68 | return this[ALLOW_STALE] 69 | } 70 | 71 | set maxAge (mA) { 72 | if (typeof mA !== 'number') 73 | throw new TypeError('maxAge must be a non-negative number') 74 | 75 | this[MAX_AGE] = mA 76 | trim(this) 77 | } 78 | get maxAge () { 79 | return this[MAX_AGE] 80 | } 81 | 82 | // resize the cache when the lengthCalculator changes. 83 | set lengthCalculator (lC) { 84 | if (typeof lC !== 'function') 85 | lC = naiveLength 86 | 87 | if (lC !== this[LENGTH_CALCULATOR]) { 88 | this[LENGTH_CALCULATOR] = lC 89 | this[LENGTH] = 0 90 | this[LRU_LIST].forEach(hit => { 91 | hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key) 92 | this[LENGTH] += hit.length 93 | }) 94 | } 95 | trim(this) 96 | } 97 | get lengthCalculator () { return this[LENGTH_CALCULATOR] } 98 | 99 | get length () { return this[LENGTH] } 100 | get itemCount () { return this[LRU_LIST].length } 101 | 102 | rforEach (fn, thisp) { 103 | thisp = thisp || this 104 | for (let walker = this[LRU_LIST].tail; walker !== null;) { 105 | const prev = walker.prev 106 | forEachStep(this, fn, walker, thisp) 107 | walker = prev 108 | } 109 | } 110 | 111 | forEach (fn, thisp) { 112 | thisp = thisp || this 113 | for (let walker = this[LRU_LIST].head; walker !== null;) { 114 | const next = walker.next 115 | forEachStep(this, fn, walker, thisp) 116 | walker = next 117 | } 118 | } 119 | 120 | keys () { 121 | return this[LRU_LIST].toArray().map(k => k.key) 122 | } 123 | 124 | values () { 125 | return this[LRU_LIST].toArray().map(k => k.value) 126 | } 127 | 128 | reset () { 129 | if (this[DISPOSE] && 130 | this[LRU_LIST] && 131 | this[LRU_LIST].length) { 132 | this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value)) 133 | } 134 | 135 | this[CACHE] = new Map() // hash of items by key 136 | this[LRU_LIST] = new Yallist() // list of items in order of use recency 137 | this[LENGTH] = 0 // length of items in the list 138 | } 139 | 140 | dump () { 141 | return this[LRU_LIST].map(hit => 142 | isStale(this, hit) ? false : { 143 | k: hit.key, 144 | v: hit.value, 145 | e: hit.now + (hit.maxAge || 0) 146 | }).toArray().filter(h => h) 147 | } 148 | 149 | dumpLru () { 150 | return this[LRU_LIST] 151 | } 152 | 153 | set (key, value, maxAge) { 154 | maxAge = maxAge || this[MAX_AGE] 155 | 156 | if (maxAge && typeof maxAge !== 'number') 157 | throw new TypeError('maxAge must be a number') 158 | 159 | const now = maxAge ? Date.now() : 0 160 | const len = this[LENGTH_CALCULATOR](value, key) 161 | 162 | if (this[CACHE].has(key)) { 163 | if (len > this[MAX]) { 164 | del(this, this[CACHE].get(key)) 165 | return false 166 | } 167 | 168 | const node = this[CACHE].get(key) 169 | const item = node.value 170 | 171 | // dispose of the old one before overwriting 172 | // split out into 2 ifs for better coverage tracking 173 | if (this[DISPOSE]) { 174 | if (!this[NO_DISPOSE_ON_SET]) 175 | this[DISPOSE](key, item.value) 176 | } 177 | 178 | item.now = now 179 | item.maxAge = maxAge 180 | item.value = value 181 | this[LENGTH] += len - item.length 182 | item.length = len 183 | this.get(key) 184 | trim(this) 185 | return true 186 | } 187 | 188 | const hit = new Entry(key, value, len, now, maxAge) 189 | 190 | // oversized objects fall out of cache automatically. 191 | if (hit.length > this[MAX]) { 192 | if (this[DISPOSE]) 193 | this[DISPOSE](key, value) 194 | 195 | return false 196 | } 197 | 198 | this[LENGTH] += hit.length 199 | this[LRU_LIST].unshift(hit) 200 | this[CACHE].set(key, this[LRU_LIST].head) 201 | trim(this) 202 | return true 203 | } 204 | 205 | has (key) { 206 | if (!this[CACHE].has(key)) return false 207 | const hit = this[CACHE].get(key).value 208 | return !isStale(this, hit) 209 | } 210 | 211 | get (key) { 212 | return get(this, key, true) 213 | } 214 | 215 | peek (key) { 216 | return get(this, key, false) 217 | } 218 | 219 | pop () { 220 | const node = this[LRU_LIST].tail 221 | if (!node) 222 | return null 223 | 224 | del(this, node) 225 | return node.value 226 | } 227 | 228 | del (key) { 229 | del(this, this[CACHE].get(key)) 230 | } 231 | 232 | load (arr) { 233 | // reset the cache 234 | this.reset() 235 | 236 | const now = Date.now() 237 | // A previous serialized cache has the most recent items first 238 | for (let l = arr.length - 1; l >= 0; l--) { 239 | const hit = arr[l] 240 | const expiresAt = hit.e || 0 241 | if (expiresAt === 0) 242 | // the item was created without expiration in a non aged cache 243 | this.set(hit.k, hit.v) 244 | else { 245 | const maxAge = expiresAt - now 246 | // dont add already expired items 247 | if (maxAge > 0) { 248 | this.set(hit.k, hit.v, maxAge) 249 | } 250 | } 251 | } 252 | } 253 | 254 | prune () { 255 | this[CACHE].forEach((value, key) => get(this, key, false)) 256 | } 257 | } 258 | 259 | const get = (self, key, doUse) => { 260 | const node = self[CACHE].get(key) 261 | if (node) { 262 | const hit = node.value 263 | if (isStale(self, hit)) { 264 | del(self, node) 265 | if (!self[ALLOW_STALE]) 266 | return undefined 267 | } else { 268 | if (doUse) { 269 | if (self[UPDATE_AGE_ON_GET]) 270 | node.value.now = Date.now() 271 | self[LRU_LIST].unshiftNode(node) 272 | } 273 | } 274 | return hit.value 275 | } 276 | } 277 | 278 | const isStale = (self, hit) => { 279 | if (!hit || (!hit.maxAge && !self[MAX_AGE])) 280 | return false 281 | 282 | const diff = Date.now() - hit.now 283 | return hit.maxAge ? diff > hit.maxAge 284 | : self[MAX_AGE] && (diff > self[MAX_AGE]) 285 | } 286 | 287 | const trim = self => { 288 | if (self[LENGTH] > self[MAX]) { 289 | for (let walker = self[LRU_LIST].tail; 290 | self[LENGTH] > self[MAX] && walker !== null;) { 291 | // We know that we're about to delete this one, and also 292 | // what the next least recently used key will be, so just 293 | // go ahead and set it now. 294 | const prev = walker.prev 295 | del(self, walker) 296 | walker = prev 297 | } 298 | } 299 | } 300 | 301 | const del = (self, node) => { 302 | if (node) { 303 | const hit = node.value 304 | if (self[DISPOSE]) 305 | self[DISPOSE](hit.key, hit.value) 306 | 307 | self[LENGTH] -= hit.length 308 | self[CACHE].delete(hit.key) 309 | self[LRU_LIST].removeNode(node) 310 | } 311 | } 312 | 313 | class Entry { 314 | constructor (key, value, length, now, maxAge) { 315 | this.key = key 316 | this.value = value 317 | this.length = length 318 | this.now = now 319 | this.maxAge = maxAge || 0 320 | } 321 | } 322 | 323 | const forEachStep = (self, fn, node, thisp) => { 324 | let hit = node.value 325 | if (isStale(self, hit)) { 326 | del(self, node) 327 | if (!self[ALLOW_STALE]) 328 | hit = undefined 329 | } 330 | if (hit) 331 | fn.call(thisp, hit.value, hit.key, self) 332 | } 333 | 334 | module.exports = LRUCache 335 | -------------------------------------------------------------------------------- /node_modules/lru-cache/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_args": [ 3 | [ 4 | "lru-cache@6.0.0", 5 | "/home/wyrihaximus/Projects/WyriHaximus/github-action-composer-php-versions-in-range" 6 | ] 7 | ], 8 | "_from": "lru-cache@6.0.0", 9 | "_id": "lru-cache@6.0.0", 10 | "_inBundle": false, 11 | "_integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 12 | "_location": "/lru-cache", 13 | "_phantomChildren": {}, 14 | "_requested": { 15 | "type": "version", 16 | "registry": true, 17 | "raw": "lru-cache@6.0.0", 18 | "name": "lru-cache", 19 | "escapedName": "lru-cache", 20 | "rawSpec": "6.0.0", 21 | "saveSpec": null, 22 | "fetchSpec": "6.0.0" 23 | }, 24 | "_requiredBy": [ 25 | "/semver" 26 | ], 27 | "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 28 | "_spec": "6.0.0", 29 | "_where": "/home/wyrihaximus/Projects/WyriHaximus/github-action-composer-php-versions-in-range", 30 | "author": { 31 | "name": "Isaac Z. Schlueter", 32 | "email": "i@izs.me" 33 | }, 34 | "bugs": { 35 | "url": "https://github.com/isaacs/node-lru-cache/issues" 36 | }, 37 | "dependencies": { 38 | "yallist": "^4.0.0" 39 | }, 40 | "description": "A cache object that deletes the least-recently-used items.", 41 | "devDependencies": { 42 | "benchmark": "^2.1.4", 43 | "tap": "^14.10.7" 44 | }, 45 | "engines": { 46 | "node": ">=10" 47 | }, 48 | "files": [ 49 | "index.js" 50 | ], 51 | "homepage": "https://github.com/isaacs/node-lru-cache#readme", 52 | "keywords": [ 53 | "mru", 54 | "lru", 55 | "cache" 56 | ], 57 | "license": "ISC", 58 | "main": "index.js", 59 | "name": "lru-cache", 60 | "repository": { 61 | "type": "git", 62 | "url": "git://github.com/isaacs/node-lru-cache.git" 63 | }, 64 | "scripts": { 65 | "postversion": "npm publish", 66 | "prepublishOnly": "git push origin --follow-tags", 67 | "preversion": "npm test", 68 | "snap": "tap", 69 | "test": "tap" 70 | }, 71 | "version": "6.0.0" 72 | } 73 | -------------------------------------------------------------------------------- /node_modules/semver/LICENSE: -------------------------------------------------------------------------------- 1 | The ISC License 2 | 3 | Copyright (c) Isaac Z. Schlueter and Contributors 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 15 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /node_modules/semver/README.md: -------------------------------------------------------------------------------- 1 | semver(1) -- The semantic versioner for npm 2 | =========================================== 3 | 4 | ## Install 5 | 6 | ```bash 7 | npm install semver 8 | ```` 9 | 10 | ## Usage 11 | 12 | As a node module: 13 | 14 | ```js 15 | const semver = require('semver') 16 | 17 | semver.valid('1.2.3') // '1.2.3' 18 | semver.valid('a.b.c') // null 19 | semver.clean(' =v1.2.3 ') // '1.2.3' 20 | semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true 21 | semver.gt('1.2.3', '9.8.7') // false 22 | semver.lt('1.2.3', '9.8.7') // true 23 | semver.minVersion('>=1.0.0') // '1.0.0' 24 | semver.valid(semver.coerce('v2')) // '2.0.0' 25 | semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7' 26 | ``` 27 | 28 | You can also just load the module for the function that you care about, if 29 | you'd like to minimize your footprint. 30 | 31 | ```js 32 | // load the whole API at once in a single object 33 | const semver = require('semver') 34 | 35 | // or just load the bits you need 36 | // all of them listed here, just pick and choose what you want 37 | 38 | // classes 39 | const SemVer = require('semver/classes/semver') 40 | const Comparator = require('semver/classes/comparator') 41 | const Range = require('semver/classes/range') 42 | 43 | // functions for working with versions 44 | const semverParse = require('semver/functions/parse') 45 | const semverValid = require('semver/functions/valid') 46 | const semverClean = require('semver/functions/clean') 47 | const semverInc = require('semver/functions/inc') 48 | const semverDiff = require('semver/functions/diff') 49 | const semverMajor = require('semver/functions/major') 50 | const semverMinor = require('semver/functions/minor') 51 | const semverPatch = require('semver/functions/patch') 52 | const semverPrerelease = require('semver/functions/prerelease') 53 | const semverCompare = require('semver/functions/compare') 54 | const semverRcompare = require('semver/functions/rcompare') 55 | const semverCompareLoose = require('semver/functions/compare-loose') 56 | const semverCompareBuild = require('semver/functions/compare-build') 57 | const semverSort = require('semver/functions/sort') 58 | const semverRsort = require('semver/functions/rsort') 59 | 60 | // low-level comparators between versions 61 | const semverGt = require('semver/functions/gt') 62 | const semverLt = require('semver/functions/lt') 63 | const semverEq = require('semver/functions/eq') 64 | const semverNeq = require('semver/functions/neq') 65 | const semverGte = require('semver/functions/gte') 66 | const semverLte = require('semver/functions/lte') 67 | const semverCmp = require('semver/functions/cmp') 68 | const semverCoerce = require('semver/functions/coerce') 69 | 70 | // working with ranges 71 | const semverSatisfies = require('semver/functions/satisfies') 72 | const semverMaxSatisfying = require('semver/ranges/max-satisfying') 73 | const semverMinSatisfying = require('semver/ranges/min-satisfying') 74 | const semverToComparators = require('semver/ranges/to-comparators') 75 | const semverMinVersion = require('semver/ranges/min-version') 76 | const semverValidRange = require('semver/ranges/valid') 77 | const semverOutside = require('semver/ranges/outside') 78 | const semverGtr = require('semver/ranges/gtr') 79 | const semverLtr = require('semver/ranges/ltr') 80 | const semverIntersects = require('semver/ranges/intersects') 81 | const simplifyRange = require('semver/ranges/simplify') 82 | const rangeSubset = require('semver/ranges/subset') 83 | ``` 84 | 85 | As a command-line utility: 86 | 87 | ``` 88 | $ semver -h 89 | 90 | A JavaScript implementation of the https://semver.org/ specification 91 | Copyright Isaac Z. Schlueter 92 | 93 | Usage: semver [options] [ [...]] 94 | Prints valid versions sorted by SemVer precedence 95 | 96 | Options: 97 | -r --range 98 | Print versions that match the specified range. 99 | 100 | -i --increment [] 101 | Increment a version by the specified level. Level can 102 | be one of: major, minor, patch, premajor, preminor, 103 | prepatch, or prerelease. Default level is 'patch'. 104 | Only one version may be specified. 105 | 106 | --preid 107 | Identifier to be used to prefix premajor, preminor, 108 | prepatch or prerelease version increments. 109 | 110 | -l --loose 111 | Interpret versions and ranges loosely 112 | 113 | -n <0|1> 114 | This is the base to be used for the prerelease identifier. 115 | 116 | -p --include-prerelease 117 | Always include prerelease versions in range matching 118 | 119 | -c --coerce 120 | Coerce a string into SemVer if possible 121 | (does not imply --loose) 122 | 123 | --rtl 124 | Coerce version strings right to left 125 | 126 | --ltr 127 | Coerce version strings left to right (default) 128 | 129 | Program exits successfully if any valid version satisfies 130 | all supplied ranges, and prints all satisfying versions. 131 | 132 | If no satisfying versions are found, then exits failure. 133 | 134 | Versions are printed in ascending order, so supplying 135 | multiple versions to the utility will just sort them. 136 | ``` 137 | 138 | ## Versions 139 | 140 | A "version" is described by the `v2.0.0` specification found at 141 | . 142 | 143 | A leading `"="` or `"v"` character is stripped off and ignored. 144 | 145 | ## Ranges 146 | 147 | A `version range` is a set of `comparators` which specify versions 148 | that satisfy the range. 149 | 150 | A `comparator` is composed of an `operator` and a `version`. The set 151 | of primitive `operators` is: 152 | 153 | * `<` Less than 154 | * `<=` Less than or equal to 155 | * `>` Greater than 156 | * `>=` Greater than or equal to 157 | * `=` Equal. If no operator is specified, then equality is assumed, 158 | so this operator is optional, but MAY be included. 159 | 160 | For example, the comparator `>=1.2.7` would match the versions 161 | `1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6` 162 | or `1.1.0`. 163 | 164 | Comparators can be joined by whitespace to form a `comparator set`, 165 | which is satisfied by the **intersection** of all of the comparators 166 | it includes. 167 | 168 | A range is composed of one or more comparator sets, joined by `||`. A 169 | version matches a range if and only if every comparator in at least 170 | one of the `||`-separated comparator sets is satisfied by the version. 171 | 172 | For example, the range `>=1.2.7 <1.3.0` would match the versions 173 | `1.2.7`, `1.2.8`, and `1.2.99`, but not the versions `1.2.6`, `1.3.0`, 174 | or `1.1.0`. 175 | 176 | The range `1.2.7 || >=1.2.9 <2.0.0` would match the versions `1.2.7`, 177 | `1.2.9`, and `1.4.6`, but not the versions `1.2.8` or `2.0.0`. 178 | 179 | ### Prerelease Tags 180 | 181 | If a version has a prerelease tag (for example, `1.2.3-alpha.3`) then 182 | it will only be allowed to satisfy comparator sets if at least one 183 | comparator with the same `[major, minor, patch]` tuple also has a 184 | prerelease tag. 185 | 186 | For example, the range `>1.2.3-alpha.3` would be allowed to match the 187 | version `1.2.3-alpha.7`, but it would *not* be satisfied by 188 | `3.4.5-alpha.9`, even though `3.4.5-alpha.9` is technically "greater 189 | than" `1.2.3-alpha.3` according to the SemVer sort rules. The version 190 | range only accepts prerelease tags on the `1.2.3` version. The 191 | version `3.4.5` *would* satisfy the range, because it does not have a 192 | prerelease flag, and `3.4.5` is greater than `1.2.3-alpha.7`. 193 | 194 | The purpose for this behavior is twofold. First, prerelease versions 195 | frequently are updated very quickly, and contain many breaking changes 196 | that are (by the author's design) not yet fit for public consumption. 197 | Therefore, by default, they are excluded from range matching 198 | semantics. 199 | 200 | Second, a user who has opted into using a prerelease version has 201 | clearly indicated the intent to use *that specific* set of 202 | alpha/beta/rc versions. By including a prerelease tag in the range, 203 | the user is indicating that they are aware of the risk. However, it 204 | is still not appropriate to assume that they have opted into taking a 205 | similar risk on the *next* set of prerelease versions. 206 | 207 | Note that this behavior can be suppressed (treating all prerelease 208 | versions as if they were normal versions, for the purpose of range 209 | matching) by setting the `includePrerelease` flag on the options 210 | object to any 211 | [functions](https://github.com/npm/node-semver#functions) that do 212 | range matching. 213 | 214 | #### Prerelease Identifiers 215 | 216 | The method `.inc` takes an additional `identifier` string argument that 217 | will append the value of the string as a prerelease identifier: 218 | 219 | ```javascript 220 | semver.inc('1.2.3', 'prerelease', 'beta') 221 | // '1.2.4-beta.0' 222 | ``` 223 | 224 | command-line example: 225 | 226 | ```bash 227 | $ semver 1.2.3 -i prerelease --preid beta 228 | 1.2.4-beta.0 229 | ``` 230 | 231 | Which then can be used to increment further: 232 | 233 | ```bash 234 | $ semver 1.2.4-beta.0 -i prerelease 235 | 1.2.4-beta.1 236 | ``` 237 | 238 | #### Prerelease Identifier Base 239 | 240 | The method `.inc` takes an optional parameter 'identifierBase' string 241 | that will let you let your prerelease number as zero-based or one-based. 242 | Set to `false` to omit the prerelease number altogether. 243 | If you do not specify this parameter, it will default to zero-based. 244 | 245 | ```javascript 246 | semver.inc('1.2.3', 'prerelease', 'beta', '1') 247 | // '1.2.4-beta.1' 248 | ``` 249 | 250 | ```javascript 251 | semver.inc('1.2.3', 'prerelease', 'beta', false) 252 | // '1.2.4-beta' 253 | ``` 254 | 255 | command-line example: 256 | 257 | ```bash 258 | $ semver 1.2.3 -i prerelease --preid beta -n 1 259 | 1.2.4-beta.1 260 | ``` 261 | 262 | ```bash 263 | $ semver 1.2.3 -i prerelease --preid beta -n false 264 | 1.2.4-beta 265 | ``` 266 | 267 | ### Advanced Range Syntax 268 | 269 | Advanced range syntax desugars to primitive comparators in 270 | deterministic ways. 271 | 272 | Advanced ranges may be combined in the same way as primitive 273 | comparators using white space or `||`. 274 | 275 | #### Hyphen Ranges `X.Y.Z - A.B.C` 276 | 277 | Specifies an inclusive set. 278 | 279 | * `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4` 280 | 281 | If a partial version is provided as the first version in the inclusive 282 | range, then the missing pieces are replaced with zeroes. 283 | 284 | * `1.2 - 2.3.4` := `>=1.2.0 <=2.3.4` 285 | 286 | If a partial version is provided as the second version in the 287 | inclusive range, then all versions that start with the supplied parts 288 | of the tuple are accepted, but nothing that would be greater than the 289 | provided tuple parts. 290 | 291 | * `1.2.3 - 2.3` := `>=1.2.3 <2.4.0-0` 292 | * `1.2.3 - 2` := `>=1.2.3 <3.0.0-0` 293 | 294 | #### X-Ranges `1.2.x` `1.X` `1.2.*` `*` 295 | 296 | Any of `X`, `x`, or `*` may be used to "stand in" for one of the 297 | numeric values in the `[major, minor, patch]` tuple. 298 | 299 | * `*` := `>=0.0.0` (Any non-prerelease version satisfies, unless 300 | `includePrerelease` is specified, in which case any version at all 301 | satisfies) 302 | * `1.x` := `>=1.0.0 <2.0.0-0` (Matching major version) 303 | * `1.2.x` := `>=1.2.0 <1.3.0-0` (Matching major and minor versions) 304 | 305 | A partial version range is treated as an X-Range, so the special 306 | character is in fact optional. 307 | 308 | * `""` (empty string) := `*` := `>=0.0.0` 309 | * `1` := `1.x.x` := `>=1.0.0 <2.0.0-0` 310 | * `1.2` := `1.2.x` := `>=1.2.0 <1.3.0-0` 311 | 312 | #### Tilde Ranges `~1.2.3` `~1.2` `~1` 313 | 314 | Allows patch-level changes if a minor version is specified on the 315 | comparator. Allows minor-level changes if not. 316 | 317 | * `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0-0` 318 | * `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0-0` (Same as `1.2.x`) 319 | * `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0-0` (Same as `1.x`) 320 | * `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0-0` 321 | * `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0-0` (Same as `0.2.x`) 322 | * `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0-0` (Same as `0.x`) 323 | * `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0-0` Note that prereleases in 324 | the `1.2.3` version will be allowed, if they are greater than or 325 | equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but 326 | `1.2.4-beta.2` would not, because it is a prerelease of a 327 | different `[major, minor, patch]` tuple. 328 | 329 | #### Caret Ranges `^1.2.3` `^0.2.5` `^0.0.4` 330 | 331 | Allows changes that do not modify the left-most non-zero element in the 332 | `[major, minor, patch]` tuple. In other words, this allows patch and 333 | minor updates for versions `1.0.0` and above, patch updates for 334 | versions `0.X >=0.1.0`, and *no* updates for versions `0.0.X`. 335 | 336 | Many authors treat a `0.x` version as if the `x` were the major 337 | "breaking-change" indicator. 338 | 339 | Caret ranges are ideal when an author may make breaking changes 340 | between `0.2.4` and `0.3.0` releases, which is a common practice. 341 | However, it presumes that there will *not* be breaking changes between 342 | `0.2.4` and `0.2.5`. It allows for changes that are presumed to be 343 | additive (but non-breaking), according to commonly observed practices. 344 | 345 | * `^1.2.3` := `>=1.2.3 <2.0.0-0` 346 | * `^0.2.3` := `>=0.2.3 <0.3.0-0` 347 | * `^0.0.3` := `>=0.0.3 <0.0.4-0` 348 | * `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0-0` Note that prereleases in 349 | the `1.2.3` version will be allowed, if they are greater than or 350 | equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but 351 | `1.2.4-beta.2` would not, because it is a prerelease of a 352 | different `[major, minor, patch]` tuple. 353 | * `^0.0.3-beta` := `>=0.0.3-beta <0.0.4-0` Note that prereleases in the 354 | `0.0.3` version *only* will be allowed, if they are greater than or 355 | equal to `beta`. So, `0.0.3-pr.2` would be allowed. 356 | 357 | When parsing caret ranges, a missing `patch` value desugars to the 358 | number `0`, but will allow flexibility within that value, even if the 359 | major and minor versions are both `0`. 360 | 361 | * `^1.2.x` := `>=1.2.0 <2.0.0-0` 362 | * `^0.0.x` := `>=0.0.0 <0.1.0-0` 363 | * `^0.0` := `>=0.0.0 <0.1.0-0` 364 | 365 | A missing `minor` and `patch` values will desugar to zero, but also 366 | allow flexibility within those values, even if the major version is 367 | zero. 368 | 369 | * `^1.x` := `>=1.0.0 <2.0.0-0` 370 | * `^0.x` := `>=0.0.0 <1.0.0-0` 371 | 372 | ### Range Grammar 373 | 374 | Putting all this together, here is a Backus-Naur grammar for ranges, 375 | for the benefit of parser authors: 376 | 377 | ```bnf 378 | range-set ::= range ( logical-or range ) * 379 | logical-or ::= ( ' ' ) * '||' ( ' ' ) * 380 | range ::= hyphen | simple ( ' ' simple ) * | '' 381 | hyphen ::= partial ' - ' partial 382 | simple ::= primitive | partial | tilde | caret 383 | primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial 384 | partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? 385 | xr ::= 'x' | 'X' | '*' | nr 386 | nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) * 387 | tilde ::= '~' partial 388 | caret ::= '^' partial 389 | qualifier ::= ( '-' pre )? ( '+' build )? 390 | pre ::= parts 391 | build ::= parts 392 | parts ::= part ( '.' part ) * 393 | part ::= nr | [-0-9A-Za-z]+ 394 | ``` 395 | 396 | ## Functions 397 | 398 | All methods and classes take a final `options` object argument. All 399 | options in this object are `false` by default. The options supported 400 | are: 401 | 402 | - `loose` Be more forgiving about not-quite-valid semver strings. 403 | (Any resulting output will always be 100% strict compliant, of 404 | course.) For backwards compatibility reasons, if the `options` 405 | argument is a boolean value instead of an object, it is interpreted 406 | to be the `loose` param. 407 | - `includePrerelease` Set to suppress the [default 408 | behavior](https://github.com/npm/node-semver#prerelease-tags) of 409 | excluding prerelease tagged versions from ranges unless they are 410 | explicitly opted into. 411 | 412 | Strict-mode Comparators and Ranges will be strict about the SemVer 413 | strings that they parse. 414 | 415 | * `valid(v)`: Return the parsed version, or null if it's not valid. 416 | * `inc(v, release)`: Return the version incremented by the release 417 | type (`major`, `premajor`, `minor`, `preminor`, `patch`, 418 | `prepatch`, or `prerelease`), or null if it's not valid 419 | * `premajor` in one call will bump the version up to the next major 420 | version and down to a prerelease of that major version. 421 | `preminor`, and `prepatch` work the same way. 422 | * If called from a non-prerelease version, the `prerelease` will work the 423 | same as `prepatch`. It increments the patch version, then makes a 424 | prerelease. If the input version is already a prerelease it simply 425 | increments it. 426 | * `prerelease(v)`: Returns an array of prerelease components, or null 427 | if none exist. Example: `prerelease('1.2.3-alpha.1') -> ['alpha', 1]` 428 | * `major(v)`: Return the major version number. 429 | * `minor(v)`: Return the minor version number. 430 | * `patch(v)`: Return the patch version number. 431 | * `intersects(r1, r2, loose)`: Return true if the two supplied ranges 432 | or comparators intersect. 433 | * `parse(v)`: Attempt to parse a string as a semantic version, returning either 434 | a `SemVer` object or `null`. 435 | 436 | ### Comparison 437 | 438 | * `gt(v1, v2)`: `v1 > v2` 439 | * `gte(v1, v2)`: `v1 >= v2` 440 | * `lt(v1, v2)`: `v1 < v2` 441 | * `lte(v1, v2)`: `v1 <= v2` 442 | * `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent, 443 | even if they're not the exact same string. You already know how to 444 | compare strings. 445 | * `neq(v1, v2)`: `v1 != v2` The opposite of `eq`. 446 | * `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call 447 | the corresponding function above. `"==="` and `"!=="` do simple 448 | string comparison, but are included for completeness. Throws if an 449 | invalid comparison string is provided. 450 | * `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if 451 | `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. 452 | * `rcompare(v1, v2)`: The reverse of compare. Sorts an array of versions 453 | in descending order when passed to `Array.sort()`. 454 | * `compareBuild(v1, v2)`: The same as `compare` but considers `build` when two versions 455 | are equal. Sorts in ascending order if passed to `Array.sort()`. 456 | `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. 457 | * `diff(v1, v2)`: Returns difference between two versions by the release type 458 | (`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`), 459 | or null if the versions are the same. 460 | 461 | ### Comparators 462 | 463 | * `intersects(comparator)`: Return true if the comparators intersect 464 | 465 | ### Ranges 466 | 467 | * `validRange(range)`: Return the valid range or null if it's not valid 468 | * `satisfies(version, range)`: Return true if the version satisfies the 469 | range. 470 | * `maxSatisfying(versions, range)`: Return the highest version in the list 471 | that satisfies the range, or `null` if none of them do. 472 | * `minSatisfying(versions, range)`: Return the lowest version in the list 473 | that satisfies the range, or `null` if none of them do. 474 | * `minVersion(range)`: Return the lowest version that can possibly match 475 | the given range. 476 | * `gtr(version, range)`: Return `true` if version is greater than all the 477 | versions possible in the range. 478 | * `ltr(version, range)`: Return `true` if version is less than all the 479 | versions possible in the range. 480 | * `outside(version, range, hilo)`: Return true if the version is outside 481 | the bounds of the range in either the high or low direction. The 482 | `hilo` argument must be either the string `'>'` or `'<'`. (This is 483 | the function called by `gtr` and `ltr`.) 484 | * `intersects(range)`: Return true if any of the ranges comparators intersect 485 | * `simplifyRange(versions, range)`: Return a "simplified" range that 486 | matches the same items in `versions` list as the range specified. Note 487 | that it does *not* guarantee that it would match the same versions in all 488 | cases, only for the set of versions provided. This is useful when 489 | generating ranges by joining together multiple versions with `||` 490 | programmatically, to provide the user with something a bit more 491 | ergonomic. If the provided range is shorter in string-length than the 492 | generated range, then that is returned. 493 | * `subset(subRange, superRange)`: Return `true` if the `subRange` range is 494 | entirely contained by the `superRange` range. 495 | 496 | Note that, since ranges may be non-contiguous, a version might not be 497 | greater than a range, less than a range, *or* satisfy a range! For 498 | example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9` 499 | until `2.0.0`, so the version `1.2.10` would not be greater than the 500 | range (because `2.0.1` satisfies, which is higher), nor less than the 501 | range (since `1.2.8` satisfies, which is lower), and it also does not 502 | satisfy the range. 503 | 504 | If you want to know if a version satisfies or does not satisfy a 505 | range, use the `satisfies(version, range)` function. 506 | 507 | ### Coercion 508 | 509 | * `coerce(version, options)`: Coerces a string to semver if possible 510 | 511 | This aims to provide a very forgiving translation of a non-semver string to 512 | semver. It looks for the first digit in a string, and consumes all 513 | remaining characters which satisfy at least a partial semver (e.g., `1`, 514 | `1.2`, `1.2.3`) up to the max permitted length (256 characters). Longer 515 | versions are simply truncated (`4.6.3.9.2-alpha2` becomes `4.6.3`). All 516 | surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes 517 | `3.4.0`). Only text which lacks digits will fail coercion (`version one` 518 | is not valid). The maximum length for any semver component considered for 519 | coercion is 16 characters; longer components will be ignored 520 | (`10000000000000000.4.7.4` becomes `4.7.4`). The maximum value for any 521 | semver component is `Number.MAX_SAFE_INTEGER || (2**53 - 1)`; higher value 522 | components are invalid (`9999999999999999.4.7.4` is likely invalid). 523 | 524 | If the `options.rtl` flag is set, then `coerce` will return the right-most 525 | coercible tuple that does not share an ending index with a longer coercible 526 | tuple. For example, `1.2.3.4` will return `2.3.4` in rtl mode, not 527 | `4.0.0`. `1.2.3/4` will return `4.0.0`, because the `4` is not a part of 528 | any other overlapping SemVer tuple. 529 | 530 | ### Clean 531 | 532 | * `clean(version)`: Clean a string to be a valid semver if possible 533 | 534 | This will return a cleaned and trimmed semver version. If the provided 535 | version is not valid a null will be returned. This does not work for 536 | ranges. 537 | 538 | ex. 539 | * `s.clean(' = v 2.1.5foo')`: `null` 540 | * `s.clean(' = v 2.1.5foo', { loose: true })`: `'2.1.5-foo'` 541 | * `s.clean(' = v 2.1.5-foo')`: `null` 542 | * `s.clean(' = v 2.1.5-foo', { loose: true })`: `'2.1.5-foo'` 543 | * `s.clean('=v2.1.5')`: `'2.1.5'` 544 | * `s.clean(' =v2.1.5')`: `2.1.5` 545 | * `s.clean(' 2.1.5 ')`: `'2.1.5'` 546 | * `s.clean('~1.0.0')`: `null` 547 | 548 | ## Constants 549 | 550 | As a convenience, helper constants are exported to provide information about what `node-semver` supports: 551 | 552 | ### `RELEASE_TYPES` 553 | 554 | - major 555 | - premajor 556 | - minor 557 | - preminor 558 | - patch 559 | - prepatch 560 | - prerelease 561 | 562 | ``` 563 | const semver = require('semver'); 564 | 565 | if (semver.RELEASE_TYPES.includes(arbitraryUserInput)) { 566 | console.log('This is a valid release type!'); 567 | } else { 568 | console.warn('This is NOT a valid release type!'); 569 | } 570 | ``` 571 | 572 | ### `SEMVER_SPEC_VERSION` 573 | 574 | 2.0.0 575 | 576 | ``` 577 | const semver = require('semver'); 578 | 579 | console.log('We are currently using the semver specification version:', semver.SEMVER_SPEC_VERSION); 580 | ``` 581 | 582 | ## Exported Modules 583 | 584 | 589 | 590 | You may pull in just the part of this semver utility that you need, if you 591 | are sensitive to packing and tree-shaking concerns. The main 592 | `require('semver')` export uses getter functions to lazily load the parts 593 | of the API that are used. 594 | 595 | The following modules are available: 596 | 597 | * `require('semver')` 598 | * `require('semver/classes')` 599 | * `require('semver/classes/comparator')` 600 | * `require('semver/classes/range')` 601 | * `require('semver/classes/semver')` 602 | * `require('semver/functions/clean')` 603 | * `require('semver/functions/cmp')` 604 | * `require('semver/functions/coerce')` 605 | * `require('semver/functions/compare')` 606 | * `require('semver/functions/compare-build')` 607 | * `require('semver/functions/compare-loose')` 608 | * `require('semver/functions/diff')` 609 | * `require('semver/functions/eq')` 610 | * `require('semver/functions/gt')` 611 | * `require('semver/functions/gte')` 612 | * `require('semver/functions/inc')` 613 | * `require('semver/functions/lt')` 614 | * `require('semver/functions/lte')` 615 | * `require('semver/functions/major')` 616 | * `require('semver/functions/minor')` 617 | * `require('semver/functions/neq')` 618 | * `require('semver/functions/parse')` 619 | * `require('semver/functions/patch')` 620 | * `require('semver/functions/prerelease')` 621 | * `require('semver/functions/rcompare')` 622 | * `require('semver/functions/rsort')` 623 | * `require('semver/functions/satisfies')` 624 | * `require('semver/functions/sort')` 625 | * `require('semver/functions/valid')` 626 | * `require('semver/ranges/gtr')` 627 | * `require('semver/ranges/intersects')` 628 | * `require('semver/ranges/ltr')` 629 | * `require('semver/ranges/max-satisfying')` 630 | * `require('semver/ranges/min-satisfying')` 631 | * `require('semver/ranges/min-version')` 632 | * `require('semver/ranges/outside')` 633 | * `require('semver/ranges/to-comparators')` 634 | * `require('semver/ranges/valid')` 635 | 636 | -------------------------------------------------------------------------------- /node_modules/semver/bin/semver.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // Standalone semver comparison program. 3 | // Exits successfully and prints matching version(s) if 4 | // any supplied version is valid and passes all tests. 5 | 6 | const argv = process.argv.slice(2) 7 | 8 | let versions = [] 9 | 10 | const range = [] 11 | 12 | let inc = null 13 | 14 | const version = require('../package.json').version 15 | 16 | let loose = false 17 | 18 | let includePrerelease = false 19 | 20 | let coerce = false 21 | 22 | let rtl = false 23 | 24 | let identifier 25 | 26 | let identifierBase 27 | 28 | const semver = require('../') 29 | const parseOptions = require('../internal/parse-options') 30 | 31 | let reverse = false 32 | 33 | let options = {} 34 | 35 | const main = () => { 36 | if (!argv.length) { 37 | return help() 38 | } 39 | while (argv.length) { 40 | let a = argv.shift() 41 | const indexOfEqualSign = a.indexOf('=') 42 | if (indexOfEqualSign !== -1) { 43 | const value = a.slice(indexOfEqualSign + 1) 44 | a = a.slice(0, indexOfEqualSign) 45 | argv.unshift(value) 46 | } 47 | switch (a) { 48 | case '-rv': case '-rev': case '--rev': case '--reverse': 49 | reverse = true 50 | break 51 | case '-l': case '--loose': 52 | loose = true 53 | break 54 | case '-p': case '--include-prerelease': 55 | includePrerelease = true 56 | break 57 | case '-v': case '--version': 58 | versions.push(argv.shift()) 59 | break 60 | case '-i': case '--inc': case '--increment': 61 | switch (argv[0]) { 62 | case 'major': case 'minor': case 'patch': case 'prerelease': 63 | case 'premajor': case 'preminor': case 'prepatch': 64 | inc = argv.shift() 65 | break 66 | default: 67 | inc = 'patch' 68 | break 69 | } 70 | break 71 | case '--preid': 72 | identifier = argv.shift() 73 | break 74 | case '-r': case '--range': 75 | range.push(argv.shift()) 76 | break 77 | case '-n': 78 | identifierBase = argv.shift() 79 | if (identifierBase === 'false') { 80 | identifierBase = false 81 | } 82 | break 83 | case '-c': case '--coerce': 84 | coerce = true 85 | break 86 | case '--rtl': 87 | rtl = true 88 | break 89 | case '--ltr': 90 | rtl = false 91 | break 92 | case '-h': case '--help': case '-?': 93 | return help() 94 | default: 95 | versions.push(a) 96 | break 97 | } 98 | } 99 | 100 | options = parseOptions({ loose, includePrerelease, rtl }) 101 | 102 | versions = versions.map((v) => { 103 | return coerce ? (semver.coerce(v, options) || { version: v }).version : v 104 | }).filter((v) => { 105 | return semver.valid(v) 106 | }) 107 | if (!versions.length) { 108 | return fail() 109 | } 110 | if (inc && (versions.length !== 1 || range.length)) { 111 | return failInc() 112 | } 113 | 114 | for (let i = 0, l = range.length; i < l; i++) { 115 | versions = versions.filter((v) => { 116 | return semver.satisfies(v, range[i], options) 117 | }) 118 | if (!versions.length) { 119 | return fail() 120 | } 121 | } 122 | return success(versions) 123 | } 124 | 125 | const failInc = () => { 126 | console.error('--inc can only be used on a single version with no range') 127 | fail() 128 | } 129 | 130 | const fail = () => process.exit(1) 131 | 132 | const success = () => { 133 | const compare = reverse ? 'rcompare' : 'compare' 134 | versions.sort((a, b) => { 135 | return semver[compare](a, b, options) 136 | }).map((v) => { 137 | return semver.clean(v, options) 138 | }).map((v) => { 139 | return inc ? semver.inc(v, inc, options, identifier, identifierBase) : v 140 | }).forEach((v, i, _) => { 141 | console.log(v) 142 | }) 143 | } 144 | 145 | const help = () => console.log( 146 | `SemVer ${version} 147 | 148 | A JavaScript implementation of the https://semver.org/ specification 149 | Copyright Isaac Z. Schlueter 150 | 151 | Usage: semver [options] [ [...]] 152 | Prints valid versions sorted by SemVer precedence 153 | 154 | Options: 155 | -r --range 156 | Print versions that match the specified range. 157 | 158 | -i --increment [] 159 | Increment a version by the specified level. Level can 160 | be one of: major, minor, patch, premajor, preminor, 161 | prepatch, or prerelease. Default level is 'patch'. 162 | Only one version may be specified. 163 | 164 | --preid 165 | Identifier to be used to prefix premajor, preminor, 166 | prepatch or prerelease version increments. 167 | 168 | -l --loose 169 | Interpret versions and ranges loosely 170 | 171 | -p --include-prerelease 172 | Always include prerelease versions in range matching 173 | 174 | -c --coerce 175 | Coerce a string into SemVer if possible 176 | (does not imply --loose) 177 | 178 | --rtl 179 | Coerce version strings right to left 180 | 181 | --ltr 182 | Coerce version strings left to right (default) 183 | 184 | -n 185 | Base number to be used for the prerelease identifier. 186 | Can be either 0 or 1, or false to omit the number altogether. 187 | Defaults to 0. 188 | 189 | Program exits successfully if any valid version satisfies 190 | all supplied ranges, and prints all satisfying versions. 191 | 192 | If no satisfying versions are found, then exits failure. 193 | 194 | Versions are printed in ascending order, so supplying 195 | multiple versions to the utility will just sort them.`) 196 | 197 | main() 198 | -------------------------------------------------------------------------------- /node_modules/semver/classes/comparator.js: -------------------------------------------------------------------------------- 1 | const ANY = Symbol('SemVer ANY') 2 | // hoisted class for cyclic dependency 3 | class Comparator { 4 | static get ANY () { 5 | return ANY 6 | } 7 | 8 | constructor (comp, options) { 9 | options = parseOptions(options) 10 | 11 | if (comp instanceof Comparator) { 12 | if (comp.loose === !!options.loose) { 13 | return comp 14 | } else { 15 | comp = comp.value 16 | } 17 | } 18 | 19 | comp = comp.trim().split(/\s+/).join(' ') 20 | debug('comparator', comp, options) 21 | this.options = options 22 | this.loose = !!options.loose 23 | this.parse(comp) 24 | 25 | if (this.semver === ANY) { 26 | this.value = '' 27 | } else { 28 | this.value = this.operator + this.semver.version 29 | } 30 | 31 | debug('comp', this) 32 | } 33 | 34 | parse (comp) { 35 | const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] 36 | const m = comp.match(r) 37 | 38 | if (!m) { 39 | throw new TypeError(`Invalid comparator: ${comp}`) 40 | } 41 | 42 | this.operator = m[1] !== undefined ? m[1] : '' 43 | if (this.operator === '=') { 44 | this.operator = '' 45 | } 46 | 47 | // if it literally is just '>' or '' then allow anything. 48 | if (!m[2]) { 49 | this.semver = ANY 50 | } else { 51 | this.semver = new SemVer(m[2], this.options.loose) 52 | } 53 | } 54 | 55 | toString () { 56 | return this.value 57 | } 58 | 59 | test (version) { 60 | debug('Comparator.test', version, this.options.loose) 61 | 62 | if (this.semver === ANY || version === ANY) { 63 | return true 64 | } 65 | 66 | if (typeof version === 'string') { 67 | try { 68 | version = new SemVer(version, this.options) 69 | } catch (er) { 70 | return false 71 | } 72 | } 73 | 74 | return cmp(version, this.operator, this.semver, this.options) 75 | } 76 | 77 | intersects (comp, options) { 78 | if (!(comp instanceof Comparator)) { 79 | throw new TypeError('a Comparator is required') 80 | } 81 | 82 | if (this.operator === '') { 83 | if (this.value === '') { 84 | return true 85 | } 86 | return new Range(comp.value, options).test(this.value) 87 | } else if (comp.operator === '') { 88 | if (comp.value === '') { 89 | return true 90 | } 91 | return new Range(this.value, options).test(comp.semver) 92 | } 93 | 94 | options = parseOptions(options) 95 | 96 | // Special cases where nothing can possibly be lower 97 | if (options.includePrerelease && 98 | (this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) { 99 | return false 100 | } 101 | if (!options.includePrerelease && 102 | (this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0'))) { 103 | return false 104 | } 105 | 106 | // Same direction increasing (> or >=) 107 | if (this.operator.startsWith('>') && comp.operator.startsWith('>')) { 108 | return true 109 | } 110 | // Same direction decreasing (< or <=) 111 | if (this.operator.startsWith('<') && comp.operator.startsWith('<')) { 112 | return true 113 | } 114 | // same SemVer and both sides are inclusive (<= or >=) 115 | if ( 116 | (this.semver.version === comp.semver.version) && 117 | this.operator.includes('=') && comp.operator.includes('=')) { 118 | return true 119 | } 120 | // opposite directions less than 121 | if (cmp(this.semver, '<', comp.semver, options) && 122 | this.operator.startsWith('>') && comp.operator.startsWith('<')) { 123 | return true 124 | } 125 | // opposite directions greater than 126 | if (cmp(this.semver, '>', comp.semver, options) && 127 | this.operator.startsWith('<') && comp.operator.startsWith('>')) { 128 | return true 129 | } 130 | return false 131 | } 132 | } 133 | 134 | module.exports = Comparator 135 | 136 | const parseOptions = require('../internal/parse-options') 137 | const { safeRe: re, t } = require('../internal/re') 138 | const cmp = require('../functions/cmp') 139 | const debug = require('../internal/debug') 140 | const SemVer = require('./semver') 141 | const Range = require('./range') 142 | -------------------------------------------------------------------------------- /node_modules/semver/classes/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SemVer: require('./semver.js'), 3 | Range: require('./range.js'), 4 | Comparator: require('./comparator.js'), 5 | } 6 | -------------------------------------------------------------------------------- /node_modules/semver/classes/range.js: -------------------------------------------------------------------------------- 1 | // hoisted class for cyclic dependency 2 | class Range { 3 | constructor (range, options) { 4 | options = parseOptions(options) 5 | 6 | if (range instanceof Range) { 7 | if ( 8 | range.loose === !!options.loose && 9 | range.includePrerelease === !!options.includePrerelease 10 | ) { 11 | return range 12 | } else { 13 | return new Range(range.raw, options) 14 | } 15 | } 16 | 17 | if (range instanceof Comparator) { 18 | // just put it in the set and return 19 | this.raw = range.value 20 | this.set = [[range]] 21 | this.format() 22 | return this 23 | } 24 | 25 | this.options = options 26 | this.loose = !!options.loose 27 | this.includePrerelease = !!options.includePrerelease 28 | 29 | // First reduce all whitespace as much as possible so we do not have to rely 30 | // on potentially slow regexes like \s*. This is then stored and used for 31 | // future error messages as well. 32 | this.raw = range 33 | .trim() 34 | .split(/\s+/) 35 | .join(' ') 36 | 37 | // First, split on || 38 | this.set = this.raw 39 | .split('||') 40 | // map the range to a 2d array of comparators 41 | .map(r => this.parseRange(r)) 42 | // throw out any comparator lists that are empty 43 | // this generally means that it was not a valid range, which is allowed 44 | // in loose mode, but will still throw if the WHOLE range is invalid. 45 | .filter(c => c.length) 46 | 47 | if (!this.set.length) { 48 | throw new TypeError(`Invalid SemVer Range: ${this.raw}`) 49 | } 50 | 51 | // if we have any that are not the null set, throw out null sets. 52 | if (this.set.length > 1) { 53 | // keep the first one, in case they're all null sets 54 | const first = this.set[0] 55 | this.set = this.set.filter(c => !isNullSet(c[0])) 56 | if (this.set.length === 0) { 57 | this.set = [first] 58 | } else if (this.set.length > 1) { 59 | // if we have any that are *, then the range is just * 60 | for (const c of this.set) { 61 | if (c.length === 1 && isAny(c[0])) { 62 | this.set = [c] 63 | break 64 | } 65 | } 66 | } 67 | } 68 | 69 | this.format() 70 | } 71 | 72 | format () { 73 | this.range = this.set 74 | .map((comps) => comps.join(' ').trim()) 75 | .join('||') 76 | .trim() 77 | return this.range 78 | } 79 | 80 | toString () { 81 | return this.range 82 | } 83 | 84 | parseRange (range) { 85 | // memoize range parsing for performance. 86 | // this is a very hot path, and fully deterministic. 87 | const memoOpts = 88 | (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | 89 | (this.options.loose && FLAG_LOOSE) 90 | const memoKey = memoOpts + ':' + range 91 | const cached = cache.get(memoKey) 92 | if (cached) { 93 | return cached 94 | } 95 | 96 | const loose = this.options.loose 97 | // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` 98 | const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] 99 | range = range.replace(hr, hyphenReplace(this.options.includePrerelease)) 100 | debug('hyphen replace', range) 101 | // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` 102 | range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) 103 | debug('comparator trim', range) 104 | 105 | // `~ 1.2.3` => `~1.2.3` 106 | range = range.replace(re[t.TILDETRIM], tildeTrimReplace) 107 | 108 | // `^ 1.2.3` => `^1.2.3` 109 | range = range.replace(re[t.CARETTRIM], caretTrimReplace) 110 | 111 | // At this point, the range is completely trimmed and 112 | // ready to be split into comparators. 113 | 114 | let rangeList = range 115 | .split(' ') 116 | .map(comp => parseComparator(comp, this.options)) 117 | .join(' ') 118 | .split(/\s+/) 119 | // >=0.0.0 is equivalent to * 120 | .map(comp => replaceGTE0(comp, this.options)) 121 | 122 | if (loose) { 123 | // in loose mode, throw out any that are not valid comparators 124 | rangeList = rangeList.filter(comp => { 125 | debug('loose invalid filter', comp, this.options) 126 | return !!comp.match(re[t.COMPARATORLOOSE]) 127 | }) 128 | } 129 | debug('range list', rangeList) 130 | 131 | // if any comparators are the null set, then replace with JUST null set 132 | // if more than one comparator, remove any * comparators 133 | // also, don't include the same comparator more than once 134 | const rangeMap = new Map() 135 | const comparators = rangeList.map(comp => new Comparator(comp, this.options)) 136 | for (const comp of comparators) { 137 | if (isNullSet(comp)) { 138 | return [comp] 139 | } 140 | rangeMap.set(comp.value, comp) 141 | } 142 | if (rangeMap.size > 1 && rangeMap.has('')) { 143 | rangeMap.delete('') 144 | } 145 | 146 | const result = [...rangeMap.values()] 147 | cache.set(memoKey, result) 148 | return result 149 | } 150 | 151 | intersects (range, options) { 152 | if (!(range instanceof Range)) { 153 | throw new TypeError('a Range is required') 154 | } 155 | 156 | return this.set.some((thisComparators) => { 157 | return ( 158 | isSatisfiable(thisComparators, options) && 159 | range.set.some((rangeComparators) => { 160 | return ( 161 | isSatisfiable(rangeComparators, options) && 162 | thisComparators.every((thisComparator) => { 163 | return rangeComparators.every((rangeComparator) => { 164 | return thisComparator.intersects(rangeComparator, options) 165 | }) 166 | }) 167 | ) 168 | }) 169 | ) 170 | }) 171 | } 172 | 173 | // if ANY of the sets match ALL of its comparators, then pass 174 | test (version) { 175 | if (!version) { 176 | return false 177 | } 178 | 179 | if (typeof version === 'string') { 180 | try { 181 | version = new SemVer(version, this.options) 182 | } catch (er) { 183 | return false 184 | } 185 | } 186 | 187 | for (let i = 0; i < this.set.length; i++) { 188 | if (testSet(this.set[i], version, this.options)) { 189 | return true 190 | } 191 | } 192 | return false 193 | } 194 | } 195 | 196 | module.exports = Range 197 | 198 | const LRU = require('lru-cache') 199 | const cache = new LRU({ max: 1000 }) 200 | 201 | const parseOptions = require('../internal/parse-options') 202 | const Comparator = require('./comparator') 203 | const debug = require('../internal/debug') 204 | const SemVer = require('./semver') 205 | const { 206 | safeRe: re, 207 | t, 208 | comparatorTrimReplace, 209 | tildeTrimReplace, 210 | caretTrimReplace, 211 | } = require('../internal/re') 212 | const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require('../internal/constants') 213 | 214 | const isNullSet = c => c.value === '<0.0.0-0' 215 | const isAny = c => c.value === '' 216 | 217 | // take a set of comparators and determine whether there 218 | // exists a version which can satisfy it 219 | const isSatisfiable = (comparators, options) => { 220 | let result = true 221 | const remainingComparators = comparators.slice() 222 | let testComparator = remainingComparators.pop() 223 | 224 | while (result && remainingComparators.length) { 225 | result = remainingComparators.every((otherComparator) => { 226 | return testComparator.intersects(otherComparator, options) 227 | }) 228 | 229 | testComparator = remainingComparators.pop() 230 | } 231 | 232 | return result 233 | } 234 | 235 | // comprised of xranges, tildes, stars, and gtlt's at this point. 236 | // already replaced the hyphen ranges 237 | // turn into a set of JUST comparators. 238 | const parseComparator = (comp, options) => { 239 | debug('comp', comp, options) 240 | comp = replaceCarets(comp, options) 241 | debug('caret', comp) 242 | comp = replaceTildes(comp, options) 243 | debug('tildes', comp) 244 | comp = replaceXRanges(comp, options) 245 | debug('xrange', comp) 246 | comp = replaceStars(comp, options) 247 | debug('stars', comp) 248 | return comp 249 | } 250 | 251 | const isX = id => !id || id.toLowerCase() === 'x' || id === '*' 252 | 253 | // ~, ~> --> * (any, kinda silly) 254 | // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0 255 | // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0 256 | // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0 257 | // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0 258 | // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 259 | // ~0.0.1 --> >=0.0.1 <0.1.0-0 260 | const replaceTildes = (comp, options) => { 261 | return comp 262 | .trim() 263 | .split(/\s+/) 264 | .map((c) => replaceTilde(c, options)) 265 | .join(' ') 266 | } 267 | 268 | const replaceTilde = (comp, options) => { 269 | const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] 270 | return comp.replace(r, (_, M, m, p, pr) => { 271 | debug('tilde', comp, _, M, m, p, pr) 272 | let ret 273 | 274 | if (isX(M)) { 275 | ret = '' 276 | } else if (isX(m)) { 277 | ret = `>=${M}.0.0 <${+M + 1}.0.0-0` 278 | } else if (isX(p)) { 279 | // ~1.2 == >=1.2.0 <1.3.0-0 280 | ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0` 281 | } else if (pr) { 282 | debug('replaceTilde pr', pr) 283 | ret = `>=${M}.${m}.${p}-${pr 284 | } <${M}.${+m + 1}.0-0` 285 | } else { 286 | // ~1.2.3 == >=1.2.3 <1.3.0-0 287 | ret = `>=${M}.${m}.${p 288 | } <${M}.${+m + 1}.0-0` 289 | } 290 | 291 | debug('tilde return', ret) 292 | return ret 293 | }) 294 | } 295 | 296 | // ^ --> * (any, kinda silly) 297 | // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0 298 | // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0 299 | // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0 300 | // ^1.2.3 --> >=1.2.3 <2.0.0-0 301 | // ^1.2.0 --> >=1.2.0 <2.0.0-0 302 | // ^0.0.1 --> >=0.0.1 <0.0.2-0 303 | // ^0.1.0 --> >=0.1.0 <0.2.0-0 304 | const replaceCarets = (comp, options) => { 305 | return comp 306 | .trim() 307 | .split(/\s+/) 308 | .map((c) => replaceCaret(c, options)) 309 | .join(' ') 310 | } 311 | 312 | const replaceCaret = (comp, options) => { 313 | debug('caret', comp, options) 314 | const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET] 315 | const z = options.includePrerelease ? '-0' : '' 316 | return comp.replace(r, (_, M, m, p, pr) => { 317 | debug('caret', comp, _, M, m, p, pr) 318 | let ret 319 | 320 | if (isX(M)) { 321 | ret = '' 322 | } else if (isX(m)) { 323 | ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0` 324 | } else if (isX(p)) { 325 | if (M === '0') { 326 | ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0` 327 | } else { 328 | ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0` 329 | } 330 | } else if (pr) { 331 | debug('replaceCaret pr', pr) 332 | if (M === '0') { 333 | if (m === '0') { 334 | ret = `>=${M}.${m}.${p}-${pr 335 | } <${M}.${m}.${+p + 1}-0` 336 | } else { 337 | ret = `>=${M}.${m}.${p}-${pr 338 | } <${M}.${+m + 1}.0-0` 339 | } 340 | } else { 341 | ret = `>=${M}.${m}.${p}-${pr 342 | } <${+M + 1}.0.0-0` 343 | } 344 | } else { 345 | debug('no pr') 346 | if (M === '0') { 347 | if (m === '0') { 348 | ret = `>=${M}.${m}.${p 349 | }${z} <${M}.${m}.${+p + 1}-0` 350 | } else { 351 | ret = `>=${M}.${m}.${p 352 | }${z} <${M}.${+m + 1}.0-0` 353 | } 354 | } else { 355 | ret = `>=${M}.${m}.${p 356 | } <${+M + 1}.0.0-0` 357 | } 358 | } 359 | 360 | debug('caret return', ret) 361 | return ret 362 | }) 363 | } 364 | 365 | const replaceXRanges = (comp, options) => { 366 | debug('replaceXRanges', comp, options) 367 | return comp 368 | .split(/\s+/) 369 | .map((c) => replaceXRange(c, options)) 370 | .join(' ') 371 | } 372 | 373 | const replaceXRange = (comp, options) => { 374 | comp = comp.trim() 375 | const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE] 376 | return comp.replace(r, (ret, gtlt, M, m, p, pr) => { 377 | debug('xRange', comp, ret, gtlt, M, m, p, pr) 378 | const xM = isX(M) 379 | const xm = xM || isX(m) 380 | const xp = xm || isX(p) 381 | const anyX = xp 382 | 383 | if (gtlt === '=' && anyX) { 384 | gtlt = '' 385 | } 386 | 387 | // if we're including prereleases in the match, then we need 388 | // to fix this to -0, the lowest possible prerelease value 389 | pr = options.includePrerelease ? '-0' : '' 390 | 391 | if (xM) { 392 | if (gtlt === '>' || gtlt === '<') { 393 | // nothing is allowed 394 | ret = '<0.0.0-0' 395 | } else { 396 | // nothing is forbidden 397 | ret = '*' 398 | } 399 | } else if (gtlt && anyX) { 400 | // we know patch is an x, because we have any x at all. 401 | // replace X with 0 402 | if (xm) { 403 | m = 0 404 | } 405 | p = 0 406 | 407 | if (gtlt === '>') { 408 | // >1 => >=2.0.0 409 | // >1.2 => >=1.3.0 410 | gtlt = '>=' 411 | if (xm) { 412 | M = +M + 1 413 | m = 0 414 | p = 0 415 | } else { 416 | m = +m + 1 417 | p = 0 418 | } 419 | } else if (gtlt === '<=') { 420 | // <=0.7.x is actually <0.8.0, since any 0.7.x should 421 | // pass. Similarly, <=7.x is actually <8.0.0, etc. 422 | gtlt = '<' 423 | if (xm) { 424 | M = +M + 1 425 | } else { 426 | m = +m + 1 427 | } 428 | } 429 | 430 | if (gtlt === '<') { 431 | pr = '-0' 432 | } 433 | 434 | ret = `${gtlt + M}.${m}.${p}${pr}` 435 | } else if (xm) { 436 | ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0` 437 | } else if (xp) { 438 | ret = `>=${M}.${m}.0${pr 439 | } <${M}.${+m + 1}.0-0` 440 | } 441 | 442 | debug('xRange return', ret) 443 | 444 | return ret 445 | }) 446 | } 447 | 448 | // Because * is AND-ed with everything else in the comparator, 449 | // and '' means "any version", just remove the *s entirely. 450 | const replaceStars = (comp, options) => { 451 | debug('replaceStars', comp, options) 452 | // Looseness is ignored here. star is always as loose as it gets! 453 | return comp 454 | .trim() 455 | .replace(re[t.STAR], '') 456 | } 457 | 458 | const replaceGTE0 = (comp, options) => { 459 | debug('replaceGTE0', comp, options) 460 | return comp 461 | .trim() 462 | .replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '') 463 | } 464 | 465 | // This function is passed to string.replace(re[t.HYPHENRANGE]) 466 | // M, m, patch, prerelease, build 467 | // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 468 | // 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do 469 | // 1.2 - 3.4 => >=1.2.0 <3.5.0-0 470 | const hyphenReplace = incPr => ($0, 471 | from, fM, fm, fp, fpr, fb, 472 | to, tM, tm, tp, tpr, tb) => { 473 | if (isX(fM)) { 474 | from = '' 475 | } else if (isX(fm)) { 476 | from = `>=${fM}.0.0${incPr ? '-0' : ''}` 477 | } else if (isX(fp)) { 478 | from = `>=${fM}.${fm}.0${incPr ? '-0' : ''}` 479 | } else if (fpr) { 480 | from = `>=${from}` 481 | } else { 482 | from = `>=${from}${incPr ? '-0' : ''}` 483 | } 484 | 485 | if (isX(tM)) { 486 | to = '' 487 | } else if (isX(tm)) { 488 | to = `<${+tM + 1}.0.0-0` 489 | } else if (isX(tp)) { 490 | to = `<${tM}.${+tm + 1}.0-0` 491 | } else if (tpr) { 492 | to = `<=${tM}.${tm}.${tp}-${tpr}` 493 | } else if (incPr) { 494 | to = `<${tM}.${tm}.${+tp + 1}-0` 495 | } else { 496 | to = `<=${to}` 497 | } 498 | 499 | return `${from} ${to}`.trim() 500 | } 501 | 502 | const testSet = (set, version, options) => { 503 | for (let i = 0; i < set.length; i++) { 504 | if (!set[i].test(version)) { 505 | return false 506 | } 507 | } 508 | 509 | if (version.prerelease.length && !options.includePrerelease) { 510 | // Find the set of versions that are allowed to have prereleases 511 | // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 512 | // That should allow `1.2.3-pr.2` to pass. 513 | // However, `1.2.4-alpha.notready` should NOT be allowed, 514 | // even though it's within the range set by the comparators. 515 | for (let i = 0; i < set.length; i++) { 516 | debug(set[i].semver) 517 | if (set[i].semver === Comparator.ANY) { 518 | continue 519 | } 520 | 521 | if (set[i].semver.prerelease.length > 0) { 522 | const allowed = set[i].semver 523 | if (allowed.major === version.major && 524 | allowed.minor === version.minor && 525 | allowed.patch === version.patch) { 526 | return true 527 | } 528 | } 529 | } 530 | 531 | // Version has a -pre, but it's not one of the ones we like. 532 | return false 533 | } 534 | 535 | return true 536 | } 537 | -------------------------------------------------------------------------------- /node_modules/semver/classes/semver.js: -------------------------------------------------------------------------------- 1 | const debug = require('../internal/debug') 2 | const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants') 3 | const { safeRe: re, t } = require('../internal/re') 4 | 5 | const parseOptions = require('../internal/parse-options') 6 | const { compareIdentifiers } = require('../internal/identifiers') 7 | class SemVer { 8 | constructor (version, options) { 9 | options = parseOptions(options) 10 | 11 | if (version instanceof SemVer) { 12 | if (version.loose === !!options.loose && 13 | version.includePrerelease === !!options.includePrerelease) { 14 | return version 15 | } else { 16 | version = version.version 17 | } 18 | } else if (typeof version !== 'string') { 19 | throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`) 20 | } 21 | 22 | if (version.length > MAX_LENGTH) { 23 | throw new TypeError( 24 | `version is longer than ${MAX_LENGTH} characters` 25 | ) 26 | } 27 | 28 | debug('SemVer', version, options) 29 | this.options = options 30 | this.loose = !!options.loose 31 | // this isn't actually relevant for versions, but keep it so that we 32 | // don't run into trouble passing this.options around. 33 | this.includePrerelease = !!options.includePrerelease 34 | 35 | const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]) 36 | 37 | if (!m) { 38 | throw new TypeError(`Invalid Version: ${version}`) 39 | } 40 | 41 | this.raw = version 42 | 43 | // these are actually numbers 44 | this.major = +m[1] 45 | this.minor = +m[2] 46 | this.patch = +m[3] 47 | 48 | if (this.major > MAX_SAFE_INTEGER || this.major < 0) { 49 | throw new TypeError('Invalid major version') 50 | } 51 | 52 | if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { 53 | throw new TypeError('Invalid minor version') 54 | } 55 | 56 | if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { 57 | throw new TypeError('Invalid patch version') 58 | } 59 | 60 | // numberify any prerelease numeric ids 61 | if (!m[4]) { 62 | this.prerelease = [] 63 | } else { 64 | this.prerelease = m[4].split('.').map((id) => { 65 | if (/^[0-9]+$/.test(id)) { 66 | const num = +id 67 | if (num >= 0 && num < MAX_SAFE_INTEGER) { 68 | return num 69 | } 70 | } 71 | return id 72 | }) 73 | } 74 | 75 | this.build = m[5] ? m[5].split('.') : [] 76 | this.format() 77 | } 78 | 79 | format () { 80 | this.version = `${this.major}.${this.minor}.${this.patch}` 81 | if (this.prerelease.length) { 82 | this.version += `-${this.prerelease.join('.')}` 83 | } 84 | return this.version 85 | } 86 | 87 | toString () { 88 | return this.version 89 | } 90 | 91 | compare (other) { 92 | debug('SemVer.compare', this.version, this.options, other) 93 | if (!(other instanceof SemVer)) { 94 | if (typeof other === 'string' && other === this.version) { 95 | return 0 96 | } 97 | other = new SemVer(other, this.options) 98 | } 99 | 100 | if (other.version === this.version) { 101 | return 0 102 | } 103 | 104 | return this.compareMain(other) || this.comparePre(other) 105 | } 106 | 107 | compareMain (other) { 108 | if (!(other instanceof SemVer)) { 109 | other = new SemVer(other, this.options) 110 | } 111 | 112 | return ( 113 | compareIdentifiers(this.major, other.major) || 114 | compareIdentifiers(this.minor, other.minor) || 115 | compareIdentifiers(this.patch, other.patch) 116 | ) 117 | } 118 | 119 | comparePre (other) { 120 | if (!(other instanceof SemVer)) { 121 | other = new SemVer(other, this.options) 122 | } 123 | 124 | // NOT having a prerelease is > having one 125 | if (this.prerelease.length && !other.prerelease.length) { 126 | return -1 127 | } else if (!this.prerelease.length && other.prerelease.length) { 128 | return 1 129 | } else if (!this.prerelease.length && !other.prerelease.length) { 130 | return 0 131 | } 132 | 133 | let i = 0 134 | do { 135 | const a = this.prerelease[i] 136 | const b = other.prerelease[i] 137 | debug('prerelease compare', i, a, b) 138 | if (a === undefined && b === undefined) { 139 | return 0 140 | } else if (b === undefined) { 141 | return 1 142 | } else if (a === undefined) { 143 | return -1 144 | } else if (a === b) { 145 | continue 146 | } else { 147 | return compareIdentifiers(a, b) 148 | } 149 | } while (++i) 150 | } 151 | 152 | compareBuild (other) { 153 | if (!(other instanceof SemVer)) { 154 | other = new SemVer(other, this.options) 155 | } 156 | 157 | let i = 0 158 | do { 159 | const a = this.build[i] 160 | const b = other.build[i] 161 | debug('prerelease compare', i, a, b) 162 | if (a === undefined && b === undefined) { 163 | return 0 164 | } else if (b === undefined) { 165 | return 1 166 | } else if (a === undefined) { 167 | return -1 168 | } else if (a === b) { 169 | continue 170 | } else { 171 | return compareIdentifiers(a, b) 172 | } 173 | } while (++i) 174 | } 175 | 176 | // preminor will bump the version up to the next minor release, and immediately 177 | // down to pre-release. premajor and prepatch work the same way. 178 | inc (release, identifier, identifierBase) { 179 | switch (release) { 180 | case 'premajor': 181 | this.prerelease.length = 0 182 | this.patch = 0 183 | this.minor = 0 184 | this.major++ 185 | this.inc('pre', identifier, identifierBase) 186 | break 187 | case 'preminor': 188 | this.prerelease.length = 0 189 | this.patch = 0 190 | this.minor++ 191 | this.inc('pre', identifier, identifierBase) 192 | break 193 | case 'prepatch': 194 | // If this is already a prerelease, it will bump to the next version 195 | // drop any prereleases that might already exist, since they are not 196 | // relevant at this point. 197 | this.prerelease.length = 0 198 | this.inc('patch', identifier, identifierBase) 199 | this.inc('pre', identifier, identifierBase) 200 | break 201 | // If the input is a non-prerelease version, this acts the same as 202 | // prepatch. 203 | case 'prerelease': 204 | if (this.prerelease.length === 0) { 205 | this.inc('patch', identifier, identifierBase) 206 | } 207 | this.inc('pre', identifier, identifierBase) 208 | break 209 | 210 | case 'major': 211 | // If this is a pre-major version, bump up to the same major version. 212 | // Otherwise increment major. 213 | // 1.0.0-5 bumps to 1.0.0 214 | // 1.1.0 bumps to 2.0.0 215 | if ( 216 | this.minor !== 0 || 217 | this.patch !== 0 || 218 | this.prerelease.length === 0 219 | ) { 220 | this.major++ 221 | } 222 | this.minor = 0 223 | this.patch = 0 224 | this.prerelease = [] 225 | break 226 | case 'minor': 227 | // If this is a pre-minor version, bump up to the same minor version. 228 | // Otherwise increment minor. 229 | // 1.2.0-5 bumps to 1.2.0 230 | // 1.2.1 bumps to 1.3.0 231 | if (this.patch !== 0 || this.prerelease.length === 0) { 232 | this.minor++ 233 | } 234 | this.patch = 0 235 | this.prerelease = [] 236 | break 237 | case 'patch': 238 | // If this is not a pre-release version, it will increment the patch. 239 | // If it is a pre-release it will bump up to the same patch version. 240 | // 1.2.0-5 patches to 1.2.0 241 | // 1.2.0 patches to 1.2.1 242 | if (this.prerelease.length === 0) { 243 | this.patch++ 244 | } 245 | this.prerelease = [] 246 | break 247 | // This probably shouldn't be used publicly. 248 | // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. 249 | case 'pre': { 250 | const base = Number(identifierBase) ? 1 : 0 251 | 252 | if (!identifier && identifierBase === false) { 253 | throw new Error('invalid increment argument: identifier is empty') 254 | } 255 | 256 | if (this.prerelease.length === 0) { 257 | this.prerelease = [base] 258 | } else { 259 | let i = this.prerelease.length 260 | while (--i >= 0) { 261 | if (typeof this.prerelease[i] === 'number') { 262 | this.prerelease[i]++ 263 | i = -2 264 | } 265 | } 266 | if (i === -1) { 267 | // didn't increment anything 268 | if (identifier === this.prerelease.join('.') && identifierBase === false) { 269 | throw new Error('invalid increment argument: identifier already exists') 270 | } 271 | this.prerelease.push(base) 272 | } 273 | } 274 | if (identifier) { 275 | // 1.2.0-beta.1 bumps to 1.2.0-beta.2, 276 | // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 277 | let prerelease = [identifier, base] 278 | if (identifierBase === false) { 279 | prerelease = [identifier] 280 | } 281 | if (compareIdentifiers(this.prerelease[0], identifier) === 0) { 282 | if (isNaN(this.prerelease[1])) { 283 | this.prerelease = prerelease 284 | } 285 | } else { 286 | this.prerelease = prerelease 287 | } 288 | } 289 | break 290 | } 291 | default: 292 | throw new Error(`invalid increment argument: ${release}`) 293 | } 294 | this.raw = this.format() 295 | if (this.build.length) { 296 | this.raw += `+${this.build.join('.')}` 297 | } 298 | return this 299 | } 300 | } 301 | 302 | module.exports = SemVer 303 | -------------------------------------------------------------------------------- /node_modules/semver/functions/clean.js: -------------------------------------------------------------------------------- 1 | const parse = require('./parse') 2 | const clean = (version, options) => { 3 | const s = parse(version.trim().replace(/^[=v]+/, ''), options) 4 | return s ? s.version : null 5 | } 6 | module.exports = clean 7 | -------------------------------------------------------------------------------- /node_modules/semver/functions/cmp.js: -------------------------------------------------------------------------------- 1 | const eq = require('./eq') 2 | const neq = require('./neq') 3 | const gt = require('./gt') 4 | const gte = require('./gte') 5 | const lt = require('./lt') 6 | const lte = require('./lte') 7 | 8 | const cmp = (a, op, b, loose) => { 9 | switch (op) { 10 | case '===': 11 | if (typeof a === 'object') { 12 | a = a.version 13 | } 14 | if (typeof b === 'object') { 15 | b = b.version 16 | } 17 | return a === b 18 | 19 | case '!==': 20 | if (typeof a === 'object') { 21 | a = a.version 22 | } 23 | if (typeof b === 'object') { 24 | b = b.version 25 | } 26 | return a !== b 27 | 28 | case '': 29 | case '=': 30 | case '==': 31 | return eq(a, b, loose) 32 | 33 | case '!=': 34 | return neq(a, b, loose) 35 | 36 | case '>': 37 | return gt(a, b, loose) 38 | 39 | case '>=': 40 | return gte(a, b, loose) 41 | 42 | case '<': 43 | return lt(a, b, loose) 44 | 45 | case '<=': 46 | return lte(a, b, loose) 47 | 48 | default: 49 | throw new TypeError(`Invalid operator: ${op}`) 50 | } 51 | } 52 | module.exports = cmp 53 | -------------------------------------------------------------------------------- /node_modules/semver/functions/coerce.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | const parse = require('./parse') 3 | const { safeRe: re, t } = require('../internal/re') 4 | 5 | const coerce = (version, options) => { 6 | if (version instanceof SemVer) { 7 | return version 8 | } 9 | 10 | if (typeof version === 'number') { 11 | version = String(version) 12 | } 13 | 14 | if (typeof version !== 'string') { 15 | return null 16 | } 17 | 18 | options = options || {} 19 | 20 | let match = null 21 | if (!options.rtl) { 22 | match = version.match(re[t.COERCE]) 23 | } else { 24 | // Find the right-most coercible string that does not share 25 | // a terminus with a more left-ward coercible string. 26 | // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' 27 | // 28 | // Walk through the string checking with a /g regexp 29 | // Manually set the index so as to pick up overlapping matches. 30 | // Stop when we get a match that ends at the string end, since no 31 | // coercible string can be more right-ward without the same terminus. 32 | let next 33 | while ((next = re[t.COERCERTL].exec(version)) && 34 | (!match || match.index + match[0].length !== version.length) 35 | ) { 36 | if (!match || 37 | next.index + next[0].length !== match.index + match[0].length) { 38 | match = next 39 | } 40 | re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length 41 | } 42 | // leave it in a clean state 43 | re[t.COERCERTL].lastIndex = -1 44 | } 45 | 46 | if (match === null) { 47 | return null 48 | } 49 | 50 | return parse(`${match[2]}.${match[3] || '0'}.${match[4] || '0'}`, options) 51 | } 52 | module.exports = coerce 53 | -------------------------------------------------------------------------------- /node_modules/semver/functions/compare-build.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | const compareBuild = (a, b, loose) => { 3 | const versionA = new SemVer(a, loose) 4 | const versionB = new SemVer(b, loose) 5 | return versionA.compare(versionB) || versionA.compareBuild(versionB) 6 | } 7 | module.exports = compareBuild 8 | -------------------------------------------------------------------------------- /node_modules/semver/functions/compare-loose.js: -------------------------------------------------------------------------------- 1 | const compare = require('./compare') 2 | const compareLoose = (a, b) => compare(a, b, true) 3 | module.exports = compareLoose 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/compare.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | const compare = (a, b, loose) => 3 | new SemVer(a, loose).compare(new SemVer(b, loose)) 4 | 5 | module.exports = compare 6 | -------------------------------------------------------------------------------- /node_modules/semver/functions/diff.js: -------------------------------------------------------------------------------- 1 | const parse = require('./parse.js') 2 | 3 | const diff = (version1, version2) => { 4 | const v1 = parse(version1, null, true) 5 | const v2 = parse(version2, null, true) 6 | const comparison = v1.compare(v2) 7 | 8 | if (comparison === 0) { 9 | return null 10 | } 11 | 12 | const v1Higher = comparison > 0 13 | const highVersion = v1Higher ? v1 : v2 14 | const lowVersion = v1Higher ? v2 : v1 15 | const highHasPre = !!highVersion.prerelease.length 16 | const lowHasPre = !!lowVersion.prerelease.length 17 | 18 | if (lowHasPre && !highHasPre) { 19 | // Going from prerelease -> no prerelease requires some special casing 20 | 21 | // If the low version has only a major, then it will always be a major 22 | // Some examples: 23 | // 1.0.0-1 -> 1.0.0 24 | // 1.0.0-1 -> 1.1.1 25 | // 1.0.0-1 -> 2.0.0 26 | if (!lowVersion.patch && !lowVersion.minor) { 27 | return 'major' 28 | } 29 | 30 | // Otherwise it can be determined by checking the high version 31 | 32 | if (highVersion.patch) { 33 | // anything higher than a patch bump would result in the wrong version 34 | return 'patch' 35 | } 36 | 37 | if (highVersion.minor) { 38 | // anything higher than a minor bump would result in the wrong version 39 | return 'minor' 40 | } 41 | 42 | // bumping major/minor/patch all have same result 43 | return 'major' 44 | } 45 | 46 | // add the `pre` prefix if we are going to a prerelease version 47 | const prefix = highHasPre ? 'pre' : '' 48 | 49 | if (v1.major !== v2.major) { 50 | return prefix + 'major' 51 | } 52 | 53 | if (v1.minor !== v2.minor) { 54 | return prefix + 'minor' 55 | } 56 | 57 | if (v1.patch !== v2.patch) { 58 | return prefix + 'patch' 59 | } 60 | 61 | // high and low are preleases 62 | return 'prerelease' 63 | } 64 | 65 | module.exports = diff 66 | -------------------------------------------------------------------------------- /node_modules/semver/functions/eq.js: -------------------------------------------------------------------------------- 1 | const compare = require('./compare') 2 | const eq = (a, b, loose) => compare(a, b, loose) === 0 3 | module.exports = eq 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/gt.js: -------------------------------------------------------------------------------- 1 | const compare = require('./compare') 2 | const gt = (a, b, loose) => compare(a, b, loose) > 0 3 | module.exports = gt 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/gte.js: -------------------------------------------------------------------------------- 1 | const compare = require('./compare') 2 | const gte = (a, b, loose) => compare(a, b, loose) >= 0 3 | module.exports = gte 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/inc.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | 3 | const inc = (version, release, options, identifier, identifierBase) => { 4 | if (typeof (options) === 'string') { 5 | identifierBase = identifier 6 | identifier = options 7 | options = undefined 8 | } 9 | 10 | try { 11 | return new SemVer( 12 | version instanceof SemVer ? version.version : version, 13 | options 14 | ).inc(release, identifier, identifierBase).version 15 | } catch (er) { 16 | return null 17 | } 18 | } 19 | module.exports = inc 20 | -------------------------------------------------------------------------------- /node_modules/semver/functions/lt.js: -------------------------------------------------------------------------------- 1 | const compare = require('./compare') 2 | const lt = (a, b, loose) => compare(a, b, loose) < 0 3 | module.exports = lt 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/lte.js: -------------------------------------------------------------------------------- 1 | const compare = require('./compare') 2 | const lte = (a, b, loose) => compare(a, b, loose) <= 0 3 | module.exports = lte 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/major.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | const major = (a, loose) => new SemVer(a, loose).major 3 | module.exports = major 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/minor.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | const minor = (a, loose) => new SemVer(a, loose).minor 3 | module.exports = minor 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/neq.js: -------------------------------------------------------------------------------- 1 | const compare = require('./compare') 2 | const neq = (a, b, loose) => compare(a, b, loose) !== 0 3 | module.exports = neq 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/parse.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | const parse = (version, options, throwErrors = false) => { 3 | if (version instanceof SemVer) { 4 | return version 5 | } 6 | try { 7 | return new SemVer(version, options) 8 | } catch (er) { 9 | if (!throwErrors) { 10 | return null 11 | } 12 | throw er 13 | } 14 | } 15 | 16 | module.exports = parse 17 | -------------------------------------------------------------------------------- /node_modules/semver/functions/patch.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | const patch = (a, loose) => new SemVer(a, loose).patch 3 | module.exports = patch 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/prerelease.js: -------------------------------------------------------------------------------- 1 | const parse = require('./parse') 2 | const prerelease = (version, options) => { 3 | const parsed = parse(version, options) 4 | return (parsed && parsed.prerelease.length) ? parsed.prerelease : null 5 | } 6 | module.exports = prerelease 7 | -------------------------------------------------------------------------------- /node_modules/semver/functions/rcompare.js: -------------------------------------------------------------------------------- 1 | const compare = require('./compare') 2 | const rcompare = (a, b, loose) => compare(b, a, loose) 3 | module.exports = rcompare 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/rsort.js: -------------------------------------------------------------------------------- 1 | const compareBuild = require('./compare-build') 2 | const rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose)) 3 | module.exports = rsort 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/satisfies.js: -------------------------------------------------------------------------------- 1 | const Range = require('../classes/range') 2 | const satisfies = (version, range, options) => { 3 | try { 4 | range = new Range(range, options) 5 | } catch (er) { 6 | return false 7 | } 8 | return range.test(version) 9 | } 10 | module.exports = satisfies 11 | -------------------------------------------------------------------------------- /node_modules/semver/functions/sort.js: -------------------------------------------------------------------------------- 1 | const compareBuild = require('./compare-build') 2 | const sort = (list, loose) => list.sort((a, b) => compareBuild(a, b, loose)) 3 | module.exports = sort 4 | -------------------------------------------------------------------------------- /node_modules/semver/functions/valid.js: -------------------------------------------------------------------------------- 1 | const parse = require('./parse') 2 | const valid = (version, options) => { 3 | const v = parse(version, options) 4 | return v ? v.version : null 5 | } 6 | module.exports = valid 7 | -------------------------------------------------------------------------------- /node_modules/semver/index.js: -------------------------------------------------------------------------------- 1 | // just pre-load all the stuff that index.js lazily exports 2 | const internalRe = require('./internal/re') 3 | const constants = require('./internal/constants') 4 | const SemVer = require('./classes/semver') 5 | const identifiers = require('./internal/identifiers') 6 | const parse = require('./functions/parse') 7 | const valid = require('./functions/valid') 8 | const clean = require('./functions/clean') 9 | const inc = require('./functions/inc') 10 | const diff = require('./functions/diff') 11 | const major = require('./functions/major') 12 | const minor = require('./functions/minor') 13 | const patch = require('./functions/patch') 14 | const prerelease = require('./functions/prerelease') 15 | const compare = require('./functions/compare') 16 | const rcompare = require('./functions/rcompare') 17 | const compareLoose = require('./functions/compare-loose') 18 | const compareBuild = require('./functions/compare-build') 19 | const sort = require('./functions/sort') 20 | const rsort = require('./functions/rsort') 21 | const gt = require('./functions/gt') 22 | const lt = require('./functions/lt') 23 | const eq = require('./functions/eq') 24 | const neq = require('./functions/neq') 25 | const gte = require('./functions/gte') 26 | const lte = require('./functions/lte') 27 | const cmp = require('./functions/cmp') 28 | const coerce = require('./functions/coerce') 29 | const Comparator = require('./classes/comparator') 30 | const Range = require('./classes/range') 31 | const satisfies = require('./functions/satisfies') 32 | const toComparators = require('./ranges/to-comparators') 33 | const maxSatisfying = require('./ranges/max-satisfying') 34 | const minSatisfying = require('./ranges/min-satisfying') 35 | const minVersion = require('./ranges/min-version') 36 | const validRange = require('./ranges/valid') 37 | const outside = require('./ranges/outside') 38 | const gtr = require('./ranges/gtr') 39 | const ltr = require('./ranges/ltr') 40 | const intersects = require('./ranges/intersects') 41 | const simplifyRange = require('./ranges/simplify') 42 | const subset = require('./ranges/subset') 43 | module.exports = { 44 | parse, 45 | valid, 46 | clean, 47 | inc, 48 | diff, 49 | major, 50 | minor, 51 | patch, 52 | prerelease, 53 | compare, 54 | rcompare, 55 | compareLoose, 56 | compareBuild, 57 | sort, 58 | rsort, 59 | gt, 60 | lt, 61 | eq, 62 | neq, 63 | gte, 64 | lte, 65 | cmp, 66 | coerce, 67 | Comparator, 68 | Range, 69 | satisfies, 70 | toComparators, 71 | maxSatisfying, 72 | minSatisfying, 73 | minVersion, 74 | validRange, 75 | outside, 76 | gtr, 77 | ltr, 78 | intersects, 79 | simplifyRange, 80 | subset, 81 | SemVer, 82 | re: internalRe.re, 83 | src: internalRe.src, 84 | tokens: internalRe.t, 85 | SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, 86 | RELEASE_TYPES: constants.RELEASE_TYPES, 87 | compareIdentifiers: identifiers.compareIdentifiers, 88 | rcompareIdentifiers: identifiers.rcompareIdentifiers, 89 | } 90 | -------------------------------------------------------------------------------- /node_modules/semver/internal/constants.js: -------------------------------------------------------------------------------- 1 | // Note: this is the semver.org version of the spec that it implements 2 | // Not necessarily the package version of this code. 3 | const SEMVER_SPEC_VERSION = '2.0.0' 4 | 5 | const MAX_LENGTH = 256 6 | const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 7 | /* istanbul ignore next */ 9007199254740991 8 | 9 | // Max safe segment length for coercion. 10 | const MAX_SAFE_COMPONENT_LENGTH = 16 11 | 12 | const RELEASE_TYPES = [ 13 | 'major', 14 | 'premajor', 15 | 'minor', 16 | 'preminor', 17 | 'patch', 18 | 'prepatch', 19 | 'prerelease', 20 | ] 21 | 22 | module.exports = { 23 | MAX_LENGTH, 24 | MAX_SAFE_COMPONENT_LENGTH, 25 | MAX_SAFE_INTEGER, 26 | RELEASE_TYPES, 27 | SEMVER_SPEC_VERSION, 28 | FLAG_INCLUDE_PRERELEASE: 0b001, 29 | FLAG_LOOSE: 0b010, 30 | } 31 | -------------------------------------------------------------------------------- /node_modules/semver/internal/debug.js: -------------------------------------------------------------------------------- 1 | const debug = ( 2 | typeof process === 'object' && 3 | process.env && 4 | process.env.NODE_DEBUG && 5 | /\bsemver\b/i.test(process.env.NODE_DEBUG) 6 | ) ? (...args) => console.error('SEMVER', ...args) 7 | : () => {} 8 | 9 | module.exports = debug 10 | -------------------------------------------------------------------------------- /node_modules/semver/internal/identifiers.js: -------------------------------------------------------------------------------- 1 | const numeric = /^[0-9]+$/ 2 | const compareIdentifiers = (a, b) => { 3 | const anum = numeric.test(a) 4 | const bnum = numeric.test(b) 5 | 6 | if (anum && bnum) { 7 | a = +a 8 | b = +b 9 | } 10 | 11 | return a === b ? 0 12 | : (anum && !bnum) ? -1 13 | : (bnum && !anum) ? 1 14 | : a < b ? -1 15 | : 1 16 | } 17 | 18 | const rcompareIdentifiers = (a, b) => compareIdentifiers(b, a) 19 | 20 | module.exports = { 21 | compareIdentifiers, 22 | rcompareIdentifiers, 23 | } 24 | -------------------------------------------------------------------------------- /node_modules/semver/internal/parse-options.js: -------------------------------------------------------------------------------- 1 | // parse out just the options we care about 2 | const looseOption = Object.freeze({ loose: true }) 3 | const emptyOpts = Object.freeze({ }) 4 | const parseOptions = options => { 5 | if (!options) { 6 | return emptyOpts 7 | } 8 | 9 | if (typeof options !== 'object') { 10 | return looseOption 11 | } 12 | 13 | return options 14 | } 15 | module.exports = parseOptions 16 | -------------------------------------------------------------------------------- /node_modules/semver/internal/re.js: -------------------------------------------------------------------------------- 1 | const { MAX_SAFE_COMPONENT_LENGTH } = require('./constants') 2 | const debug = require('./debug') 3 | exports = module.exports = {} 4 | 5 | // The actual regexps go on exports.re 6 | const re = exports.re = [] 7 | const safeRe = exports.safeRe = [] 8 | const src = exports.src = [] 9 | const t = exports.t = {} 10 | let R = 0 11 | 12 | const createToken = (name, value, isGlobal) => { 13 | // Replace all greedy whitespace to prevent regex dos issues. These regex are 14 | // used internally via the safeRe object since all inputs in this library get 15 | // normalized first to trim and collapse all extra whitespace. The original 16 | // regexes are exported for userland consumption and lower level usage. A 17 | // future breaking change could export the safer regex only with a note that 18 | // all input should have extra whitespace removed. 19 | const safe = value 20 | .split('\\s*').join('\\s{0,1}') 21 | .split('\\s+').join('\\s') 22 | const index = R++ 23 | debug(name, index, value) 24 | t[name] = index 25 | src[index] = value 26 | re[index] = new RegExp(value, isGlobal ? 'g' : undefined) 27 | safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined) 28 | } 29 | 30 | // The following Regular Expressions can be used for tokenizing, 31 | // validating, and parsing SemVer version strings. 32 | 33 | // ## Numeric Identifier 34 | // A single `0`, or a non-zero digit followed by zero or more digits. 35 | 36 | createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*') 37 | createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+') 38 | 39 | // ## Non-numeric Identifier 40 | // Zero or more digits, followed by a letter or hyphen, and then zero or 41 | // more letters, digits, or hyphens. 42 | 43 | createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*') 44 | 45 | // ## Main Version 46 | // Three dot-separated numeric identifiers. 47 | 48 | createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` + 49 | `(${src[t.NUMERICIDENTIFIER]})\\.` + 50 | `(${src[t.NUMERICIDENTIFIER]})`) 51 | 52 | createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + 53 | `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + 54 | `(${src[t.NUMERICIDENTIFIERLOOSE]})`) 55 | 56 | // ## Pre-release Version Identifier 57 | // A numeric identifier, or a non-numeric identifier. 58 | 59 | createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER] 60 | }|${src[t.NONNUMERICIDENTIFIER]})`) 61 | 62 | createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE] 63 | }|${src[t.NONNUMERICIDENTIFIER]})`) 64 | 65 | // ## Pre-release Version 66 | // Hyphen, followed by one or more dot-separated pre-release version 67 | // identifiers. 68 | 69 | createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER] 70 | }(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`) 71 | 72 | createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] 73 | }(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`) 74 | 75 | // ## Build Metadata Identifier 76 | // Any combination of digits, letters, or hyphens. 77 | 78 | createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+') 79 | 80 | // ## Build Metadata 81 | // Plus sign, followed by one or more period-separated build metadata 82 | // identifiers. 83 | 84 | createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER] 85 | }(?:\\.${src[t.BUILDIDENTIFIER]})*))`) 86 | 87 | // ## Full Version String 88 | // A main version, followed optionally by a pre-release version and 89 | // build metadata. 90 | 91 | // Note that the only major, minor, patch, and pre-release sections of 92 | // the version string are capturing groups. The build metadata is not a 93 | // capturing group, because it should not ever be used in version 94 | // comparison. 95 | 96 | createToken('FULLPLAIN', `v?${src[t.MAINVERSION] 97 | }${src[t.PRERELEASE]}?${ 98 | src[t.BUILD]}?`) 99 | 100 | createToken('FULL', `^${src[t.FULLPLAIN]}$`) 101 | 102 | // like full, but allows v1.2.3 and =1.2.3, which people do sometimes. 103 | // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty 104 | // common in the npm registry. 105 | createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE] 106 | }${src[t.PRERELEASELOOSE]}?${ 107 | src[t.BUILD]}?`) 108 | 109 | createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`) 110 | 111 | createToken('GTLT', '((?:<|>)?=?)') 112 | 113 | // Something like "2.*" or "1.2.x". 114 | // Note that "x.x" is a valid xRange identifer, meaning "any version" 115 | // Only the first item is strictly required. 116 | createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`) 117 | createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`) 118 | 119 | createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` + 120 | `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + 121 | `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + 122 | `(?:${src[t.PRERELEASE]})?${ 123 | src[t.BUILD]}?` + 124 | `)?)?`) 125 | 126 | createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` + 127 | `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + 128 | `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + 129 | `(?:${src[t.PRERELEASELOOSE]})?${ 130 | src[t.BUILD]}?` + 131 | `)?)?`) 132 | 133 | createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`) 134 | createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`) 135 | 136 | // Coercion. 137 | // Extract anything that could conceivably be a part of a valid semver 138 | createToken('COERCE', `${'(^|[^\\d])' + 139 | '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + 140 | `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + 141 | `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + 142 | `(?:$|[^\\d])`) 143 | createToken('COERCERTL', src[t.COERCE], true) 144 | 145 | // Tilde ranges. 146 | // Meaning is "reasonably at or greater than" 147 | createToken('LONETILDE', '(?:~>?)') 148 | 149 | createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true) 150 | exports.tildeTrimReplace = '$1~' 151 | 152 | createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`) 153 | createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`) 154 | 155 | // Caret ranges. 156 | // Meaning is "at least and backwards compatible with" 157 | createToken('LONECARET', '(?:\\^)') 158 | 159 | createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true) 160 | exports.caretTrimReplace = '$1^' 161 | 162 | createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`) 163 | createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`) 164 | 165 | // A simple gt/lt/eq thing, or just "" to indicate "any version" 166 | createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`) 167 | createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`) 168 | 169 | // An expression to strip any whitespace between the gtlt and the thing 170 | // it modifies, so that `> 1.2.3` ==> `>1.2.3` 171 | createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT] 172 | }\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true) 173 | exports.comparatorTrimReplace = '$1$2$3' 174 | 175 | // Something like `1.2.3 - 1.2.4` 176 | // Note that these all use the loose form, because they'll be 177 | // checked against either the strict or loose comparator form 178 | // later. 179 | createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` + 180 | `\\s+-\\s+` + 181 | `(${src[t.XRANGEPLAIN]})` + 182 | `\\s*$`) 183 | 184 | createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` + 185 | `\\s+-\\s+` + 186 | `(${src[t.XRANGEPLAINLOOSE]})` + 187 | `\\s*$`) 188 | 189 | // Star ranges basically just allow anything at all. 190 | createToken('STAR', '(<|>)?=?\\s*\\*') 191 | // >=0.0.0 is like a star 192 | createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$') 193 | createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$') 194 | -------------------------------------------------------------------------------- /node_modules/semver/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_args": [ 3 | [ 4 | "semver@7.5.2", 5 | "/home/wyrihaximus/Projects/WyriHaximus/github-action-composer-php-versions-in-range" 6 | ] 7 | ], 8 | "_from": "semver@7.5.2", 9 | "_id": "semver@7.5.2", 10 | "_inBundle": false, 11 | "_integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", 12 | "_location": "/semver", 13 | "_phantomChildren": {}, 14 | "_requested": { 15 | "type": "version", 16 | "registry": true, 17 | "raw": "semver@7.5.2", 18 | "name": "semver", 19 | "escapedName": "semver", 20 | "rawSpec": "7.5.2", 21 | "saveSpec": null, 22 | "fetchSpec": "7.5.2" 23 | }, 24 | "_requiredBy": [ 25 | "/" 26 | ], 27 | "_resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", 28 | "_spec": "7.5.2", 29 | "_where": "/home/wyrihaximus/Projects/WyriHaximus/github-action-composer-php-versions-in-range", 30 | "author": { 31 | "name": "GitHub Inc." 32 | }, 33 | "bin": { 34 | "semver": "bin/semver.js" 35 | }, 36 | "bugs": { 37 | "url": "https://github.com/npm/node-semver/issues" 38 | }, 39 | "dependencies": { 40 | "lru-cache": "^6.0.0" 41 | }, 42 | "description": "The semantic version parser used by npm.", 43 | "devDependencies": { 44 | "@npmcli/eslint-config": "^4.0.0", 45 | "@npmcli/template-oss": "4.15.1", 46 | "tap": "^16.0.0" 47 | }, 48 | "engines": { 49 | "node": ">=10" 50 | }, 51 | "files": [ 52 | "bin/", 53 | "lib/", 54 | "classes/", 55 | "functions/", 56 | "internal/", 57 | "ranges/", 58 | "index.js", 59 | "preload.js", 60 | "range.bnf" 61 | ], 62 | "homepage": "https://github.com/npm/node-semver#readme", 63 | "license": "ISC", 64 | "main": "index.js", 65 | "name": "semver", 66 | "repository": { 67 | "type": "git", 68 | "url": "git+https://github.com/npm/node-semver.git" 69 | }, 70 | "scripts": { 71 | "lint": "eslint \"**/*.js\"", 72 | "lintfix": "npm run lint -- --fix", 73 | "postlint": "template-oss-check", 74 | "posttest": "npm run lint", 75 | "snap": "tap", 76 | "template-oss-apply": "template-oss-apply --force", 77 | "test": "tap" 78 | }, 79 | "tap": { 80 | "timeout": 30, 81 | "coverage-map": "map.js", 82 | "nyc-arg": [ 83 | "--exclude", 84 | "tap-snapshots/**" 85 | ] 86 | }, 87 | "templateOSS": { 88 | "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", 89 | "version": "4.15.1", 90 | "engines": ">=10", 91 | "ciVersions": [ 92 | "10.0.0", 93 | "10.x", 94 | "12.x", 95 | "14.x", 96 | "16.x", 97 | "18.x" 98 | ], 99 | "npmSpec": "8", 100 | "distPaths": [ 101 | "classes/", 102 | "functions/", 103 | "internal/", 104 | "ranges/", 105 | "index.js", 106 | "preload.js", 107 | "range.bnf" 108 | ], 109 | "allowPaths": [ 110 | "/classes/", 111 | "/functions/", 112 | "/internal/", 113 | "/ranges/", 114 | "/index.js", 115 | "/preload.js", 116 | "/range.bnf" 117 | ], 118 | "publish": "true" 119 | }, 120 | "version": "7.5.2" 121 | } 122 | -------------------------------------------------------------------------------- /node_modules/semver/preload.js: -------------------------------------------------------------------------------- 1 | // XXX remove in v8 or beyond 2 | module.exports = require('./index.js') 3 | -------------------------------------------------------------------------------- /node_modules/semver/range.bnf: -------------------------------------------------------------------------------- 1 | range-set ::= range ( logical-or range ) * 2 | logical-or ::= ( ' ' ) * '||' ( ' ' ) * 3 | range ::= hyphen | simple ( ' ' simple ) * | '' 4 | hyphen ::= partial ' - ' partial 5 | simple ::= primitive | partial | tilde | caret 6 | primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial 7 | partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? 8 | xr ::= 'x' | 'X' | '*' | nr 9 | nr ::= '0' | [1-9] ( [0-9] ) * 10 | tilde ::= '~' partial 11 | caret ::= '^' partial 12 | qualifier ::= ( '-' pre )? ( '+' build )? 13 | pre ::= parts 14 | build ::= parts 15 | parts ::= part ( '.' part ) * 16 | part ::= nr | [-0-9A-Za-z]+ 17 | -------------------------------------------------------------------------------- /node_modules/semver/ranges/gtr.js: -------------------------------------------------------------------------------- 1 | // Determine if version is greater than all the versions possible in the range. 2 | const outside = require('./outside') 3 | const gtr = (version, range, options) => outside(version, range, '>', options) 4 | module.exports = gtr 5 | -------------------------------------------------------------------------------- /node_modules/semver/ranges/intersects.js: -------------------------------------------------------------------------------- 1 | const Range = require('../classes/range') 2 | const intersects = (r1, r2, options) => { 3 | r1 = new Range(r1, options) 4 | r2 = new Range(r2, options) 5 | return r1.intersects(r2, options) 6 | } 7 | module.exports = intersects 8 | -------------------------------------------------------------------------------- /node_modules/semver/ranges/ltr.js: -------------------------------------------------------------------------------- 1 | const outside = require('./outside') 2 | // Determine if version is less than all the versions possible in the range 3 | const ltr = (version, range, options) => outside(version, range, '<', options) 4 | module.exports = ltr 5 | -------------------------------------------------------------------------------- /node_modules/semver/ranges/max-satisfying.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | const Range = require('../classes/range') 3 | 4 | const maxSatisfying = (versions, range, options) => { 5 | let max = null 6 | let maxSV = null 7 | let rangeObj = null 8 | try { 9 | rangeObj = new Range(range, options) 10 | } catch (er) { 11 | return null 12 | } 13 | versions.forEach((v) => { 14 | if (rangeObj.test(v)) { 15 | // satisfies(v, range, options) 16 | if (!max || maxSV.compare(v) === -1) { 17 | // compare(max, v, true) 18 | max = v 19 | maxSV = new SemVer(max, options) 20 | } 21 | } 22 | }) 23 | return max 24 | } 25 | module.exports = maxSatisfying 26 | -------------------------------------------------------------------------------- /node_modules/semver/ranges/min-satisfying.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | const Range = require('../classes/range') 3 | const minSatisfying = (versions, range, options) => { 4 | let min = null 5 | let minSV = null 6 | let rangeObj = null 7 | try { 8 | rangeObj = new Range(range, options) 9 | } catch (er) { 10 | return null 11 | } 12 | versions.forEach((v) => { 13 | if (rangeObj.test(v)) { 14 | // satisfies(v, range, options) 15 | if (!min || minSV.compare(v) === 1) { 16 | // compare(min, v, true) 17 | min = v 18 | minSV = new SemVer(min, options) 19 | } 20 | } 21 | }) 22 | return min 23 | } 24 | module.exports = minSatisfying 25 | -------------------------------------------------------------------------------- /node_modules/semver/ranges/min-version.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | const Range = require('../classes/range') 3 | const gt = require('../functions/gt') 4 | 5 | const minVersion = (range, loose) => { 6 | range = new Range(range, loose) 7 | 8 | let minver = new SemVer('0.0.0') 9 | if (range.test(minver)) { 10 | return minver 11 | } 12 | 13 | minver = new SemVer('0.0.0-0') 14 | if (range.test(minver)) { 15 | return minver 16 | } 17 | 18 | minver = null 19 | for (let i = 0; i < range.set.length; ++i) { 20 | const comparators = range.set[i] 21 | 22 | let setMin = null 23 | comparators.forEach((comparator) => { 24 | // Clone to avoid manipulating the comparator's semver object. 25 | const compver = new SemVer(comparator.semver.version) 26 | switch (comparator.operator) { 27 | case '>': 28 | if (compver.prerelease.length === 0) { 29 | compver.patch++ 30 | } else { 31 | compver.prerelease.push(0) 32 | } 33 | compver.raw = compver.format() 34 | /* fallthrough */ 35 | case '': 36 | case '>=': 37 | if (!setMin || gt(compver, setMin)) { 38 | setMin = compver 39 | } 40 | break 41 | case '<': 42 | case '<=': 43 | /* Ignore maximum versions */ 44 | break 45 | /* istanbul ignore next */ 46 | default: 47 | throw new Error(`Unexpected operation: ${comparator.operator}`) 48 | } 49 | }) 50 | if (setMin && (!minver || gt(minver, setMin))) { 51 | minver = setMin 52 | } 53 | } 54 | 55 | if (minver && range.test(minver)) { 56 | return minver 57 | } 58 | 59 | return null 60 | } 61 | module.exports = minVersion 62 | -------------------------------------------------------------------------------- /node_modules/semver/ranges/outside.js: -------------------------------------------------------------------------------- 1 | const SemVer = require('../classes/semver') 2 | const Comparator = require('../classes/comparator') 3 | const { ANY } = Comparator 4 | const Range = require('../classes/range') 5 | const satisfies = require('../functions/satisfies') 6 | const gt = require('../functions/gt') 7 | const lt = require('../functions/lt') 8 | const lte = require('../functions/lte') 9 | const gte = require('../functions/gte') 10 | 11 | const outside = (version, range, hilo, options) => { 12 | version = new SemVer(version, options) 13 | range = new Range(range, options) 14 | 15 | let gtfn, ltefn, ltfn, comp, ecomp 16 | switch (hilo) { 17 | case '>': 18 | gtfn = gt 19 | ltefn = lte 20 | ltfn = lt 21 | comp = '>' 22 | ecomp = '>=' 23 | break 24 | case '<': 25 | gtfn = lt 26 | ltefn = gte 27 | ltfn = gt 28 | comp = '<' 29 | ecomp = '<=' 30 | break 31 | default: 32 | throw new TypeError('Must provide a hilo val of "<" or ">"') 33 | } 34 | 35 | // If it satisfies the range it is not outside 36 | if (satisfies(version, range, options)) { 37 | return false 38 | } 39 | 40 | // From now on, variable terms are as if we're in "gtr" mode. 41 | // but note that everything is flipped for the "ltr" function. 42 | 43 | for (let i = 0; i < range.set.length; ++i) { 44 | const comparators = range.set[i] 45 | 46 | let high = null 47 | let low = null 48 | 49 | comparators.forEach((comparator) => { 50 | if (comparator.semver === ANY) { 51 | comparator = new Comparator('>=0.0.0') 52 | } 53 | high = high || comparator 54 | low = low || comparator 55 | if (gtfn(comparator.semver, high.semver, options)) { 56 | high = comparator 57 | } else if (ltfn(comparator.semver, low.semver, options)) { 58 | low = comparator 59 | } 60 | }) 61 | 62 | // If the edge version comparator has a operator then our version 63 | // isn't outside it 64 | if (high.operator === comp || high.operator === ecomp) { 65 | return false 66 | } 67 | 68 | // If the lowest version comparator has an operator and our version 69 | // is less than it then it isn't higher than the range 70 | if ((!low.operator || low.operator === comp) && 71 | ltefn(version, low.semver)) { 72 | return false 73 | } else if (low.operator === ecomp && ltfn(version, low.semver)) { 74 | return false 75 | } 76 | } 77 | return true 78 | } 79 | 80 | module.exports = outside 81 | -------------------------------------------------------------------------------- /node_modules/semver/ranges/simplify.js: -------------------------------------------------------------------------------- 1 | // given a set of versions and a range, create a "simplified" range 2 | // that includes the same versions that the original range does 3 | // If the original range is shorter than the simplified one, return that. 4 | const satisfies = require('../functions/satisfies.js') 5 | const compare = require('../functions/compare.js') 6 | module.exports = (versions, range, options) => { 7 | const set = [] 8 | let first = null 9 | let prev = null 10 | const v = versions.sort((a, b) => compare(a, b, options)) 11 | for (const version of v) { 12 | const included = satisfies(version, range, options) 13 | if (included) { 14 | prev = version 15 | if (!first) { 16 | first = version 17 | } 18 | } else { 19 | if (prev) { 20 | set.push([first, prev]) 21 | } 22 | prev = null 23 | first = null 24 | } 25 | } 26 | if (first) { 27 | set.push([first, null]) 28 | } 29 | 30 | const ranges = [] 31 | for (const [min, max] of set) { 32 | if (min === max) { 33 | ranges.push(min) 34 | } else if (!max && min === v[0]) { 35 | ranges.push('*') 36 | } else if (!max) { 37 | ranges.push(`>=${min}`) 38 | } else if (min === v[0]) { 39 | ranges.push(`<=${max}`) 40 | } else { 41 | ranges.push(`${min} - ${max}`) 42 | } 43 | } 44 | const simplified = ranges.join(' || ') 45 | const original = typeof range.raw === 'string' ? range.raw : String(range) 46 | return simplified.length < original.length ? simplified : range 47 | } 48 | -------------------------------------------------------------------------------- /node_modules/semver/ranges/subset.js: -------------------------------------------------------------------------------- 1 | const Range = require('../classes/range.js') 2 | const Comparator = require('../classes/comparator.js') 3 | const { ANY } = Comparator 4 | const satisfies = require('../functions/satisfies.js') 5 | const compare = require('../functions/compare.js') 6 | 7 | // Complex range `r1 || r2 || ...` is a subset of `R1 || R2 || ...` iff: 8 | // - Every simple range `r1, r2, ...` is a null set, OR 9 | // - Every simple range `r1, r2, ...` which is not a null set is a subset of 10 | // some `R1, R2, ...` 11 | // 12 | // Simple range `c1 c2 ...` is a subset of simple range `C1 C2 ...` iff: 13 | // - If c is only the ANY comparator 14 | // - If C is only the ANY comparator, return true 15 | // - Else if in prerelease mode, return false 16 | // - else replace c with `[>=0.0.0]` 17 | // - If C is only the ANY comparator 18 | // - if in prerelease mode, return true 19 | // - else replace C with `[>=0.0.0]` 20 | // - Let EQ be the set of = comparators in c 21 | // - If EQ is more than one, return true (null set) 22 | // - Let GT be the highest > or >= comparator in c 23 | // - Let LT be the lowest < or <= comparator in c 24 | // - If GT and LT, and GT.semver > LT.semver, return true (null set) 25 | // - If any C is a = range, and GT or LT are set, return false 26 | // - If EQ 27 | // - If GT, and EQ does not satisfy GT, return true (null set) 28 | // - If LT, and EQ does not satisfy LT, return true (null set) 29 | // - If EQ satisfies every C, return true 30 | // - Else return false 31 | // - If GT 32 | // - If GT.semver is lower than any > or >= comp in C, return false 33 | // - If GT is >=, and GT.semver does not satisfy every C, return false 34 | // - If GT.semver has a prerelease, and not in prerelease mode 35 | // - If no C has a prerelease and the GT.semver tuple, return false 36 | // - If LT 37 | // - If LT.semver is greater than any < or <= comp in C, return false 38 | // - If LT is <=, and LT.semver does not satisfy every C, return false 39 | // - If GT.semver has a prerelease, and not in prerelease mode 40 | // - If no C has a prerelease and the LT.semver tuple, return false 41 | // - Else return true 42 | 43 | const subset = (sub, dom, options = {}) => { 44 | if (sub === dom) { 45 | return true 46 | } 47 | 48 | sub = new Range(sub, options) 49 | dom = new Range(dom, options) 50 | let sawNonNull = false 51 | 52 | OUTER: for (const simpleSub of sub.set) { 53 | for (const simpleDom of dom.set) { 54 | const isSub = simpleSubset(simpleSub, simpleDom, options) 55 | sawNonNull = sawNonNull || isSub !== null 56 | if (isSub) { 57 | continue OUTER 58 | } 59 | } 60 | // the null set is a subset of everything, but null simple ranges in 61 | // a complex range should be ignored. so if we saw a non-null range, 62 | // then we know this isn't a subset, but if EVERY simple range was null, 63 | // then it is a subset. 64 | if (sawNonNull) { 65 | return false 66 | } 67 | } 68 | return true 69 | } 70 | 71 | const minimumVersionWithPreRelease = [new Comparator('>=0.0.0-0')] 72 | const minimumVersion = [new Comparator('>=0.0.0')] 73 | 74 | const simpleSubset = (sub, dom, options) => { 75 | if (sub === dom) { 76 | return true 77 | } 78 | 79 | if (sub.length === 1 && sub[0].semver === ANY) { 80 | if (dom.length === 1 && dom[0].semver === ANY) { 81 | return true 82 | } else if (options.includePrerelease) { 83 | sub = minimumVersionWithPreRelease 84 | } else { 85 | sub = minimumVersion 86 | } 87 | } 88 | 89 | if (dom.length === 1 && dom[0].semver === ANY) { 90 | if (options.includePrerelease) { 91 | return true 92 | } else { 93 | dom = minimumVersion 94 | } 95 | } 96 | 97 | const eqSet = new Set() 98 | let gt, lt 99 | for (const c of sub) { 100 | if (c.operator === '>' || c.operator === '>=') { 101 | gt = higherGT(gt, c, options) 102 | } else if (c.operator === '<' || c.operator === '<=') { 103 | lt = lowerLT(lt, c, options) 104 | } else { 105 | eqSet.add(c.semver) 106 | } 107 | } 108 | 109 | if (eqSet.size > 1) { 110 | return null 111 | } 112 | 113 | let gtltComp 114 | if (gt && lt) { 115 | gtltComp = compare(gt.semver, lt.semver, options) 116 | if (gtltComp > 0) { 117 | return null 118 | } else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) { 119 | return null 120 | } 121 | } 122 | 123 | // will iterate one or zero times 124 | for (const eq of eqSet) { 125 | if (gt && !satisfies(eq, String(gt), options)) { 126 | return null 127 | } 128 | 129 | if (lt && !satisfies(eq, String(lt), options)) { 130 | return null 131 | } 132 | 133 | for (const c of dom) { 134 | if (!satisfies(eq, String(c), options)) { 135 | return false 136 | } 137 | } 138 | 139 | return true 140 | } 141 | 142 | let higher, lower 143 | let hasDomLT, hasDomGT 144 | // if the subset has a prerelease, we need a comparator in the superset 145 | // with the same tuple and a prerelease, or it's not a subset 146 | let needDomLTPre = lt && 147 | !options.includePrerelease && 148 | lt.semver.prerelease.length ? lt.semver : false 149 | let needDomGTPre = gt && 150 | !options.includePrerelease && 151 | gt.semver.prerelease.length ? gt.semver : false 152 | // exception: <1.2.3-0 is the same as <1.2.3 153 | if (needDomLTPre && needDomLTPre.prerelease.length === 1 && 154 | lt.operator === '<' && needDomLTPre.prerelease[0] === 0) { 155 | needDomLTPre = false 156 | } 157 | 158 | for (const c of dom) { 159 | hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>=' 160 | hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<=' 161 | if (gt) { 162 | if (needDomGTPre) { 163 | if (c.semver.prerelease && c.semver.prerelease.length && 164 | c.semver.major === needDomGTPre.major && 165 | c.semver.minor === needDomGTPre.minor && 166 | c.semver.patch === needDomGTPre.patch) { 167 | needDomGTPre = false 168 | } 169 | } 170 | if (c.operator === '>' || c.operator === '>=') { 171 | higher = higherGT(gt, c, options) 172 | if (higher === c && higher !== gt) { 173 | return false 174 | } 175 | } else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) { 176 | return false 177 | } 178 | } 179 | if (lt) { 180 | if (needDomLTPre) { 181 | if (c.semver.prerelease && c.semver.prerelease.length && 182 | c.semver.major === needDomLTPre.major && 183 | c.semver.minor === needDomLTPre.minor && 184 | c.semver.patch === needDomLTPre.patch) { 185 | needDomLTPre = false 186 | } 187 | } 188 | if (c.operator === '<' || c.operator === '<=') { 189 | lower = lowerLT(lt, c, options) 190 | if (lower === c && lower !== lt) { 191 | return false 192 | } 193 | } else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) { 194 | return false 195 | } 196 | } 197 | if (!c.operator && (lt || gt) && gtltComp !== 0) { 198 | return false 199 | } 200 | } 201 | 202 | // if there was a < or >, and nothing in the dom, then must be false 203 | // UNLESS it was limited by another range in the other direction. 204 | // Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0 205 | if (gt && hasDomLT && !lt && gtltComp !== 0) { 206 | return false 207 | } 208 | 209 | if (lt && hasDomGT && !gt && gtltComp !== 0) { 210 | return false 211 | } 212 | 213 | // we needed a prerelease range in a specific tuple, but didn't get one 214 | // then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0, 215 | // because it includes prereleases in the 1.2.3 tuple 216 | if (needDomGTPre || needDomLTPre) { 217 | return false 218 | } 219 | 220 | return true 221 | } 222 | 223 | // >=1.2.3 is lower than >1.2.3 224 | const higherGT = (a, b, options) => { 225 | if (!a) { 226 | return b 227 | } 228 | const comp = compare(a.semver, b.semver, options) 229 | return comp > 0 ? a 230 | : comp < 0 ? b 231 | : b.operator === '>' && a.operator === '>=' ? b 232 | : a 233 | } 234 | 235 | // <=1.2.3 is higher than <1.2.3 236 | const lowerLT = (a, b, options) => { 237 | if (!a) { 238 | return b 239 | } 240 | const comp = compare(a.semver, b.semver, options) 241 | return comp < 0 ? a 242 | : comp > 0 ? b 243 | : b.operator === '<' && a.operator === '<=' ? b 244 | : a 245 | } 246 | 247 | module.exports = subset 248 | -------------------------------------------------------------------------------- /node_modules/semver/ranges/to-comparators.js: -------------------------------------------------------------------------------- 1 | const Range = require('../classes/range') 2 | 3 | // Mostly just for testing and legacy API reasons 4 | const toComparators = (range, options) => 5 | new Range(range, options).set 6 | .map(comp => comp.map(c => c.value).join(' ').trim().split(' ')) 7 | 8 | module.exports = toComparators 9 | -------------------------------------------------------------------------------- /node_modules/semver/ranges/valid.js: -------------------------------------------------------------------------------- 1 | const Range = require('../classes/range') 2 | const validRange = (range, options) => { 3 | try { 4 | // Return '*' instead of '' so that truthiness works. 5 | // This will throw if it's invalid anyway 6 | return new Range(range, options).range || '*' 7 | } catch (er) { 8 | return null 9 | } 10 | } 11 | module.exports = validRange 12 | -------------------------------------------------------------------------------- /node_modules/yallist/LICENSE: -------------------------------------------------------------------------------- 1 | The ISC License 2 | 3 | Copyright (c) Isaac Z. Schlueter and Contributors 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 15 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /node_modules/yallist/README.md: -------------------------------------------------------------------------------- 1 | # yallist 2 | 3 | Yet Another Linked List 4 | 5 | There are many doubly-linked list implementations like it, but this 6 | one is mine. 7 | 8 | For when an array would be too big, and a Map can't be iterated in 9 | reverse order. 10 | 11 | 12 | [![Build Status](https://travis-ci.org/isaacs/yallist.svg?branch=master)](https://travis-ci.org/isaacs/yallist) [![Coverage Status](https://coveralls.io/repos/isaacs/yallist/badge.svg?service=github)](https://coveralls.io/github/isaacs/yallist) 13 | 14 | ## basic usage 15 | 16 | ```javascript 17 | var yallist = require('yallist') 18 | var myList = yallist.create([1, 2, 3]) 19 | myList.push('foo') 20 | myList.unshift('bar') 21 | // of course pop() and shift() are there, too 22 | console.log(myList.toArray()) // ['bar', 1, 2, 3, 'foo'] 23 | myList.forEach(function (k) { 24 | // walk the list head to tail 25 | }) 26 | myList.forEachReverse(function (k, index, list) { 27 | // walk the list tail to head 28 | }) 29 | var myDoubledList = myList.map(function (k) { 30 | return k + k 31 | }) 32 | // now myDoubledList contains ['barbar', 2, 4, 6, 'foofoo'] 33 | // mapReverse is also a thing 34 | var myDoubledListReverse = myList.mapReverse(function (k) { 35 | return k + k 36 | }) // ['foofoo', 6, 4, 2, 'barbar'] 37 | 38 | var reduced = myList.reduce(function (set, entry) { 39 | set += entry 40 | return set 41 | }, 'start') 42 | console.log(reduced) // 'startfoo123bar' 43 | ``` 44 | 45 | ## api 46 | 47 | The whole API is considered "public". 48 | 49 | Functions with the same name as an Array method work more or less the 50 | same way. 51 | 52 | There's reverse versions of most things because that's the point. 53 | 54 | ### Yallist 55 | 56 | Default export, the class that holds and manages a list. 57 | 58 | Call it with either a forEach-able (like an array) or a set of 59 | arguments, to initialize the list. 60 | 61 | The Array-ish methods all act like you'd expect. No magic length, 62 | though, so if you change that it won't automatically prune or add 63 | empty spots. 64 | 65 | ### Yallist.create(..) 66 | 67 | Alias for Yallist function. Some people like factories. 68 | 69 | #### yallist.head 70 | 71 | The first node in the list 72 | 73 | #### yallist.tail 74 | 75 | The last node in the list 76 | 77 | #### yallist.length 78 | 79 | The number of nodes in the list. (Change this at your peril. It is 80 | not magic like Array length.) 81 | 82 | #### yallist.toArray() 83 | 84 | Convert the list to an array. 85 | 86 | #### yallist.forEach(fn, [thisp]) 87 | 88 | Call a function on each item in the list. 89 | 90 | #### yallist.forEachReverse(fn, [thisp]) 91 | 92 | Call a function on each item in the list, in reverse order. 93 | 94 | #### yallist.get(n) 95 | 96 | Get the data at position `n` in the list. If you use this a lot, 97 | probably better off just using an Array. 98 | 99 | #### yallist.getReverse(n) 100 | 101 | Get the data at position `n`, counting from the tail. 102 | 103 | #### yallist.map(fn, thisp) 104 | 105 | Create a new Yallist with the result of calling the function on each 106 | item. 107 | 108 | #### yallist.mapReverse(fn, thisp) 109 | 110 | Same as `map`, but in reverse. 111 | 112 | #### yallist.pop() 113 | 114 | Get the data from the list tail, and remove the tail from the list. 115 | 116 | #### yallist.push(item, ...) 117 | 118 | Insert one or more items to the tail of the list. 119 | 120 | #### yallist.reduce(fn, initialValue) 121 | 122 | Like Array.reduce. 123 | 124 | #### yallist.reduceReverse 125 | 126 | Like Array.reduce, but in reverse. 127 | 128 | #### yallist.reverse 129 | 130 | Reverse the list in place. 131 | 132 | #### yallist.shift() 133 | 134 | Get the data from the list head, and remove the head from the list. 135 | 136 | #### yallist.slice([from], [to]) 137 | 138 | Just like Array.slice, but returns a new Yallist. 139 | 140 | #### yallist.sliceReverse([from], [to]) 141 | 142 | Just like yallist.slice, but the result is returned in reverse. 143 | 144 | #### yallist.toArray() 145 | 146 | Create an array representation of the list. 147 | 148 | #### yallist.toArrayReverse() 149 | 150 | Create a reversed array representation of the list. 151 | 152 | #### yallist.unshift(item, ...) 153 | 154 | Insert one or more items to the head of the list. 155 | 156 | #### yallist.unshiftNode(node) 157 | 158 | Move a Node object to the front of the list. (That is, pull it out of 159 | wherever it lives, and make it the new head.) 160 | 161 | If the node belongs to a different list, then that list will remove it 162 | first. 163 | 164 | #### yallist.pushNode(node) 165 | 166 | Move a Node object to the end of the list. (That is, pull it out of 167 | wherever it lives, and make it the new tail.) 168 | 169 | If the node belongs to a list already, then that list will remove it 170 | first. 171 | 172 | #### yallist.removeNode(node) 173 | 174 | Remove a node from the list, preserving referential integrity of head 175 | and tail and other nodes. 176 | 177 | Will throw an error if you try to have a list remove a node that 178 | doesn't belong to it. 179 | 180 | ### Yallist.Node 181 | 182 | The class that holds the data and is actually the list. 183 | 184 | Call with `var n = new Node(value, previousNode, nextNode)` 185 | 186 | Note that if you do direct operations on Nodes themselves, it's very 187 | easy to get into weird states where the list is broken. Be careful :) 188 | 189 | #### node.next 190 | 191 | The next node in the list. 192 | 193 | #### node.prev 194 | 195 | The previous node in the list. 196 | 197 | #### node.value 198 | 199 | The data the node contains. 200 | 201 | #### node.list 202 | 203 | The list to which this node belongs. (Null if it does not belong to 204 | any list.) 205 | -------------------------------------------------------------------------------- /node_modules/yallist/iterator.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = function (Yallist) { 3 | Yallist.prototype[Symbol.iterator] = function* () { 4 | for (let walker = this.head; walker; walker = walker.next) { 5 | yield walker.value 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /node_modules/yallist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_args": [ 3 | [ 4 | "yallist@4.0.0", 5 | "/home/wyrihaximus/Projects/WyriHaximus/github-action-composer-php-versions-in-range" 6 | ] 7 | ], 8 | "_from": "yallist@4.0.0", 9 | "_id": "yallist@4.0.0", 10 | "_inBundle": false, 11 | "_integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 12 | "_location": "/yallist", 13 | "_phantomChildren": {}, 14 | "_requested": { 15 | "type": "version", 16 | "registry": true, 17 | "raw": "yallist@4.0.0", 18 | "name": "yallist", 19 | "escapedName": "yallist", 20 | "rawSpec": "4.0.0", 21 | "saveSpec": null, 22 | "fetchSpec": "4.0.0" 23 | }, 24 | "_requiredBy": [ 25 | "/lru-cache" 26 | ], 27 | "_resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 28 | "_spec": "4.0.0", 29 | "_where": "/home/wyrihaximus/Projects/WyriHaximus/github-action-composer-php-versions-in-range", 30 | "author": { 31 | "name": "Isaac Z. Schlueter", 32 | "email": "i@izs.me", 33 | "url": "http://blog.izs.me/" 34 | }, 35 | "bugs": { 36 | "url": "https://github.com/isaacs/yallist/issues" 37 | }, 38 | "dependencies": {}, 39 | "description": "Yet Another Linked List", 40 | "devDependencies": { 41 | "tap": "^12.1.0" 42 | }, 43 | "directories": { 44 | "test": "test" 45 | }, 46 | "files": [ 47 | "yallist.js", 48 | "iterator.js" 49 | ], 50 | "homepage": "https://github.com/isaacs/yallist#readme", 51 | "license": "ISC", 52 | "main": "yallist.js", 53 | "name": "yallist", 54 | "repository": { 55 | "type": "git", 56 | "url": "git+https://github.com/isaacs/yallist.git" 57 | }, 58 | "scripts": { 59 | "postpublish": "git push origin --all; git push origin --tags", 60 | "postversion": "npm publish", 61 | "preversion": "npm test", 62 | "test": "tap test/*.js --100" 63 | }, 64 | "version": "4.0.0" 65 | } 66 | -------------------------------------------------------------------------------- /node_modules/yallist/yallist.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = Yallist 3 | 4 | Yallist.Node = Node 5 | Yallist.create = Yallist 6 | 7 | function Yallist (list) { 8 | var self = this 9 | if (!(self instanceof Yallist)) { 10 | self = new Yallist() 11 | } 12 | 13 | self.tail = null 14 | self.head = null 15 | self.length = 0 16 | 17 | if (list && typeof list.forEach === 'function') { 18 | list.forEach(function (item) { 19 | self.push(item) 20 | }) 21 | } else if (arguments.length > 0) { 22 | for (var i = 0, l = arguments.length; i < l; i++) { 23 | self.push(arguments[i]) 24 | } 25 | } 26 | 27 | return self 28 | } 29 | 30 | Yallist.prototype.removeNode = function (node) { 31 | if (node.list !== this) { 32 | throw new Error('removing node which does not belong to this list') 33 | } 34 | 35 | var next = node.next 36 | var prev = node.prev 37 | 38 | if (next) { 39 | next.prev = prev 40 | } 41 | 42 | if (prev) { 43 | prev.next = next 44 | } 45 | 46 | if (node === this.head) { 47 | this.head = next 48 | } 49 | if (node === this.tail) { 50 | this.tail = prev 51 | } 52 | 53 | node.list.length-- 54 | node.next = null 55 | node.prev = null 56 | node.list = null 57 | 58 | return next 59 | } 60 | 61 | Yallist.prototype.unshiftNode = function (node) { 62 | if (node === this.head) { 63 | return 64 | } 65 | 66 | if (node.list) { 67 | node.list.removeNode(node) 68 | } 69 | 70 | var head = this.head 71 | node.list = this 72 | node.next = head 73 | if (head) { 74 | head.prev = node 75 | } 76 | 77 | this.head = node 78 | if (!this.tail) { 79 | this.tail = node 80 | } 81 | this.length++ 82 | } 83 | 84 | Yallist.prototype.pushNode = function (node) { 85 | if (node === this.tail) { 86 | return 87 | } 88 | 89 | if (node.list) { 90 | node.list.removeNode(node) 91 | } 92 | 93 | var tail = this.tail 94 | node.list = this 95 | node.prev = tail 96 | if (tail) { 97 | tail.next = node 98 | } 99 | 100 | this.tail = node 101 | if (!this.head) { 102 | this.head = node 103 | } 104 | this.length++ 105 | } 106 | 107 | Yallist.prototype.push = function () { 108 | for (var i = 0, l = arguments.length; i < l; i++) { 109 | push(this, arguments[i]) 110 | } 111 | return this.length 112 | } 113 | 114 | Yallist.prototype.unshift = function () { 115 | for (var i = 0, l = arguments.length; i < l; i++) { 116 | unshift(this, arguments[i]) 117 | } 118 | return this.length 119 | } 120 | 121 | Yallist.prototype.pop = function () { 122 | if (!this.tail) { 123 | return undefined 124 | } 125 | 126 | var res = this.tail.value 127 | this.tail = this.tail.prev 128 | if (this.tail) { 129 | this.tail.next = null 130 | } else { 131 | this.head = null 132 | } 133 | this.length-- 134 | return res 135 | } 136 | 137 | Yallist.prototype.shift = function () { 138 | if (!this.head) { 139 | return undefined 140 | } 141 | 142 | var res = this.head.value 143 | this.head = this.head.next 144 | if (this.head) { 145 | this.head.prev = null 146 | } else { 147 | this.tail = null 148 | } 149 | this.length-- 150 | return res 151 | } 152 | 153 | Yallist.prototype.forEach = function (fn, thisp) { 154 | thisp = thisp || this 155 | for (var walker = this.head, i = 0; walker !== null; i++) { 156 | fn.call(thisp, walker.value, i, this) 157 | walker = walker.next 158 | } 159 | } 160 | 161 | Yallist.prototype.forEachReverse = function (fn, thisp) { 162 | thisp = thisp || this 163 | for (var walker = this.tail, i = this.length - 1; walker !== null; i--) { 164 | fn.call(thisp, walker.value, i, this) 165 | walker = walker.prev 166 | } 167 | } 168 | 169 | Yallist.prototype.get = function (n) { 170 | for (var i = 0, walker = this.head; walker !== null && i < n; i++) { 171 | // abort out of the list early if we hit a cycle 172 | walker = walker.next 173 | } 174 | if (i === n && walker !== null) { 175 | return walker.value 176 | } 177 | } 178 | 179 | Yallist.prototype.getReverse = function (n) { 180 | for (var i = 0, walker = this.tail; walker !== null && i < n; i++) { 181 | // abort out of the list early if we hit a cycle 182 | walker = walker.prev 183 | } 184 | if (i === n && walker !== null) { 185 | return walker.value 186 | } 187 | } 188 | 189 | Yallist.prototype.map = function (fn, thisp) { 190 | thisp = thisp || this 191 | var res = new Yallist() 192 | for (var walker = this.head; walker !== null;) { 193 | res.push(fn.call(thisp, walker.value, this)) 194 | walker = walker.next 195 | } 196 | return res 197 | } 198 | 199 | Yallist.prototype.mapReverse = function (fn, thisp) { 200 | thisp = thisp || this 201 | var res = new Yallist() 202 | for (var walker = this.tail; walker !== null;) { 203 | res.push(fn.call(thisp, walker.value, this)) 204 | walker = walker.prev 205 | } 206 | return res 207 | } 208 | 209 | Yallist.prototype.reduce = function (fn, initial) { 210 | var acc 211 | var walker = this.head 212 | if (arguments.length > 1) { 213 | acc = initial 214 | } else if (this.head) { 215 | walker = this.head.next 216 | acc = this.head.value 217 | } else { 218 | throw new TypeError('Reduce of empty list with no initial value') 219 | } 220 | 221 | for (var i = 0; walker !== null; i++) { 222 | acc = fn(acc, walker.value, i) 223 | walker = walker.next 224 | } 225 | 226 | return acc 227 | } 228 | 229 | Yallist.prototype.reduceReverse = function (fn, initial) { 230 | var acc 231 | var walker = this.tail 232 | if (arguments.length > 1) { 233 | acc = initial 234 | } else if (this.tail) { 235 | walker = this.tail.prev 236 | acc = this.tail.value 237 | } else { 238 | throw new TypeError('Reduce of empty list with no initial value') 239 | } 240 | 241 | for (var i = this.length - 1; walker !== null; i--) { 242 | acc = fn(acc, walker.value, i) 243 | walker = walker.prev 244 | } 245 | 246 | return acc 247 | } 248 | 249 | Yallist.prototype.toArray = function () { 250 | var arr = new Array(this.length) 251 | for (var i = 0, walker = this.head; walker !== null; i++) { 252 | arr[i] = walker.value 253 | walker = walker.next 254 | } 255 | return arr 256 | } 257 | 258 | Yallist.prototype.toArrayReverse = function () { 259 | var arr = new Array(this.length) 260 | for (var i = 0, walker = this.tail; walker !== null; i++) { 261 | arr[i] = walker.value 262 | walker = walker.prev 263 | } 264 | return arr 265 | } 266 | 267 | Yallist.prototype.slice = function (from, to) { 268 | to = to || this.length 269 | if (to < 0) { 270 | to += this.length 271 | } 272 | from = from || 0 273 | if (from < 0) { 274 | from += this.length 275 | } 276 | var ret = new Yallist() 277 | if (to < from || to < 0) { 278 | return ret 279 | } 280 | if (from < 0) { 281 | from = 0 282 | } 283 | if (to > this.length) { 284 | to = this.length 285 | } 286 | for (var i = 0, walker = this.head; walker !== null && i < from; i++) { 287 | walker = walker.next 288 | } 289 | for (; walker !== null && i < to; i++, walker = walker.next) { 290 | ret.push(walker.value) 291 | } 292 | return ret 293 | } 294 | 295 | Yallist.prototype.sliceReverse = function (from, to) { 296 | to = to || this.length 297 | if (to < 0) { 298 | to += this.length 299 | } 300 | from = from || 0 301 | if (from < 0) { 302 | from += this.length 303 | } 304 | var ret = new Yallist() 305 | if (to < from || to < 0) { 306 | return ret 307 | } 308 | if (from < 0) { 309 | from = 0 310 | } 311 | if (to > this.length) { 312 | to = this.length 313 | } 314 | for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) { 315 | walker = walker.prev 316 | } 317 | for (; walker !== null && i > from; i--, walker = walker.prev) { 318 | ret.push(walker.value) 319 | } 320 | return ret 321 | } 322 | 323 | Yallist.prototype.splice = function (start, deleteCount, ...nodes) { 324 | if (start > this.length) { 325 | start = this.length - 1 326 | } 327 | if (start < 0) { 328 | start = this.length + start; 329 | } 330 | 331 | for (var i = 0, walker = this.head; walker !== null && i < start; i++) { 332 | walker = walker.next 333 | } 334 | 335 | var ret = [] 336 | for (var i = 0; walker && i < deleteCount; i++) { 337 | ret.push(walker.value) 338 | walker = this.removeNode(walker) 339 | } 340 | if (walker === null) { 341 | walker = this.tail 342 | } 343 | 344 | if (walker !== this.head && walker !== this.tail) { 345 | walker = walker.prev 346 | } 347 | 348 | for (var i = 0; i < nodes.length; i++) { 349 | walker = insert(this, walker, nodes[i]) 350 | } 351 | return ret; 352 | } 353 | 354 | Yallist.prototype.reverse = function () { 355 | var head = this.head 356 | var tail = this.tail 357 | for (var walker = head; walker !== null; walker = walker.prev) { 358 | var p = walker.prev 359 | walker.prev = walker.next 360 | walker.next = p 361 | } 362 | this.head = tail 363 | this.tail = head 364 | return this 365 | } 366 | 367 | function insert (self, node, value) { 368 | var inserted = node === self.head ? 369 | new Node(value, null, node, self) : 370 | new Node(value, node, node.next, self) 371 | 372 | if (inserted.next === null) { 373 | self.tail = inserted 374 | } 375 | if (inserted.prev === null) { 376 | self.head = inserted 377 | } 378 | 379 | self.length++ 380 | 381 | return inserted 382 | } 383 | 384 | function push (self, item) { 385 | self.tail = new Node(item, self.tail, null, self) 386 | if (!self.head) { 387 | self.head = self.tail 388 | } 389 | self.length++ 390 | } 391 | 392 | function unshift (self, item) { 393 | self.head = new Node(item, null, self.head, self) 394 | if (!self.tail) { 395 | self.tail = self.head 396 | } 397 | self.length++ 398 | } 399 | 400 | function Node (value, prev, next, list) { 401 | if (!(this instanceof Node)) { 402 | return new Node(value, prev, next, list) 403 | } 404 | 405 | this.list = list 406 | this.value = value 407 | 408 | if (prev) { 409 | prev.next = this 410 | this.prev = prev 411 | } else { 412 | this.prev = null 413 | } 414 | 415 | if (next) { 416 | next.prev = this 417 | this.next = next 418 | } else { 419 | this.next = null 420 | } 421 | } 422 | 423 | try { 424 | // add if support for Symbol.iterator is present 425 | require('./iterator.js')(Yallist) 426 | } catch (er) {} 427 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "lru-cache": { 6 | "version": "6.0.0", 7 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 8 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 9 | "requires": { 10 | "yallist": "^4.0.0" 11 | } 12 | }, 13 | "semver": { 14 | "version": "7.5.2", 15 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", 16 | "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", 17 | "requires": { 18 | "lru-cache": "^6.0.0" 19 | } 20 | }, 21 | "yallist": { 22 | "version": "4.0.0", 23 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 24 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "semver": "^7.5.2" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /situations/another-working-directory/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "php": "^5", 4 | "ext-ast": "*" 5 | }, 6 | "require-dev": { 7 | "ext-pcov": "*", 8 | "ext-xdebug": "*" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /situations/ext-parallel-composer.lock/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "php": "^8.2", 4 | "react-parallel/react-parallel": "^1" 5 | }, 6 | "require-dev": { 7 | "ext-pcov": "*", 8 | "ext-xdebug": "*" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /situations/wyrihaximus-react-phpunit-run-tests-in-fiber-composer.lock/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wyrihaximus/react-phpunit-run-tests-in-fiber", 3 | "description": "Trait to run all tests in a fiber", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Cees-Jan Kiewiet", 8 | "email": "ceesjank@gmail.com" 9 | } 10 | ], 11 | "require": { 12 | "php": "^8.2", 13 | "react/async": "^4.2.0", 14 | "react/event-loop": "^1.5.0", 15 | "react/promise": "^3.1" 16 | }, 17 | "require-dev": { 18 | "react/promise-timer": "^1.10.0", 19 | "wyrihaximus/test-utilities": "^6.0" 20 | }, 21 | "conflict": { 22 | "phpunit/phpunit": "<10" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "WyriHaximus\\React\\PHPUnit\\": "src/" 27 | } 28 | }, 29 | "autoload-dev": { 30 | "psr-4": { 31 | "WyriHaximus\\Tests\\React\\PHPUnit\\": "tests/" 32 | } 33 | }, 34 | "config": { 35 | "allow-plugins": { 36 | "dealerdirect/phpcodesniffer-composer-installer": true, 37 | "ergebnis/composer-normalize": true, 38 | "icanhazstring/composer-unused": true, 39 | "infection/extension-installer": true, 40 | "php-http/discovery": true 41 | }, 42 | "platform": { 43 | "php": "8.2.13" 44 | }, 45 | "sort-packages": true 46 | }, 47 | "scripts": { 48 | "post-install-cmd": [ 49 | "composer normalize" 50 | ], 51 | "post-update-cmd": [ 52 | "composer normalize" 53 | ] 54 | } 55 | } -------------------------------------------------------------------------------- /situations/wyrihaximus-test-utilities-composer.lock/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "php": "^8.2", 4 | "wyrihaximus/test-utilities": "^6" 5 | }, 6 | "require-dev": { 7 | "ext-pcov": "*", 8 | "ext-xdebug": "*" 9 | }, 10 | "config": { 11 | "allow-plugins": { 12 | "infection/extension-installer": true, 13 | "dealerdirect/phpcodesniffer-composer-installer": true, 14 | "ergebnis/composer-normalize": true 15 | } 16 | } 17 | } 18 | --------------------------------------------------------------------------------