-
Notifications
You must be signed in to change notification settings - Fork 103
fix: latest range #954
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
fix: latest range #954
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -114,16 +114,23 @@ export class PackageVersionService { | |
| version = versionMatchTag; | ||
| } else { | ||
| const range = new Range(fetchSpec); | ||
| const paddingSemVer = new SqlRange(range); | ||
| if (paddingSemVer.containPreRelease) { | ||
| const versions = await this.packageVersionRepository.findSatisfyVersionsWithPrerelease( | ||
| scope, | ||
| name, | ||
| paddingSemVer, | ||
| ); | ||
| version = semver.maxSatisfying(versions, range); | ||
| // Prefer latest tag version if it satisfies the range | ||
| // e.g., latest=4.1.0, newest=4.2.0, range=^4 should return 4.1.0 | ||
| const latestVersion = await this.packageVersionRepository.findVersionByTag(scope, name, 'latest'); | ||
| if (latestVersion && semver.satisfies(latestVersion, range)) { | ||
| version = latestVersion; | ||
|
Comment on lines
+119
to
+121
|
||
| } else { | ||
| version = await this.packageVersionRepository.findMaxSatisfyVersion(scope, name, paddingSemVer); | ||
| const paddingSemVer = new SqlRange(range); | ||
| if (paddingSemVer.containPreRelease) { | ||
| const versions = await this.packageVersionRepository.findSatisfyVersionsWithPrerelease( | ||
| scope, | ||
| name, | ||
| paddingSemVer, | ||
| ); | ||
| version = semver.maxSatisfying(versions, range); | ||
| } else { | ||
| version = await this.packageVersionRepository.findMaxSatisfyVersion(scope, name, paddingSemVer); | ||
| } | ||
| } | ||
|
Comment on lines
+119
to
134
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -276,6 +276,77 @@ describe('test/port/controller/package/ShowPackageVersionController.test.ts', () | |||||||||||||||||||||||
| assert.equal(res.body.error, `[NOT_FOUND] ${pkg.name}@beta-not-exists not found`); | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| it('should prefer latest tag version when it satisfies semver range', async () => { | ||||||||||||||||||||||||
| // Scenario: latest=4.1.0, newest=4.2.0, request ^4 should return 4.1.0 | ||||||||||||||||||||||||
| mock(app.config.cnpmcore, 'allowPublishNonScopePackage', true); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // Publish 4.1.0 | ||||||||||||||||||||||||
| const pkg410 = await TestUtil.getFullPackage({ | ||||||||||||||||||||||||
| name: 'foo-prefer-latest', | ||||||||||||||||||||||||
| version: '4.1.0', | ||||||||||||||||||||||||
| versionObject: { | ||||||||||||||||||||||||
| description: 'version 4.1.0', | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
| await app | ||||||||||||||||||||||||
| .httpRequest() | ||||||||||||||||||||||||
| .put(`/${pkg410.name}`) | ||||||||||||||||||||||||
| .set('authorization', publisher.authorization) | ||||||||||||||||||||||||
| .set('user-agent', publisher.ua) | ||||||||||||||||||||||||
| .send(pkg410) | ||||||||||||||||||||||||
| .expect(201); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // Publish 4.2.0 without updating latest tag | ||||||||||||||||||||||||
| const pkg420 = await TestUtil.getFullPackage({ | ||||||||||||||||||||||||
| name: 'foo-prefer-latest', | ||||||||||||||||||||||||
| version: '4.2.0', | ||||||||||||||||||||||||
| versionObject: { | ||||||||||||||||||||||||
| description: 'version 4.2.0', | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
| // Without dist-tags, latest tag won't be updated | ||||||||||||||||||||||||
| delete pkg420['dist-tags']; | ||||||||||||||||||||||||
| await app | ||||||||||||||||||||||||
| .httpRequest() | ||||||||||||||||||||||||
| .put(`/${pkg420.name}`) | ||||||||||||||||||||||||
| .set('authorization', publisher.authorization) | ||||||||||||||||||||||||
| .set('user-agent', publisher.ua) | ||||||||||||||||||||||||
| .send(pkg420) | ||||||||||||||||||||||||
| .expect(201); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // Verify latest tag is still 4.1.0 | ||||||||||||||||||||||||
| let res = await app.httpRequest().get(`/${pkg410.name}/latest`).expect(200); | ||||||||||||||||||||||||
|
Comment on lines
+318
to
+319
|
||||||||||||||||||||||||
| // Verify latest tag is still 4.1.0 | |
| let res = await app.httpRequest().get(`/${pkg410.name}/latest`).expect(200); | |
| // Verify both versions exist after second publish | |
| let res = await app.httpRequest().get(`/${pkg410.name}/4.1.0`).expect(200); | |
| assert.equal(res.body.version, '4.1.0'); | |
| res = await app.httpRequest().get(`/${pkg410.name}/4.2.0`).expect(200); | |
| assert.equal(res.body.version, '4.2.0'); | |
| // Verify latest tag is still 4.1.0 | |
| res = await app.httpRequest().get(`/${pkg410.name}/latest`).expect(200); |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test scenario is well-designed and covers multiple edge cases including URL-encoded version ranges. However, consider adding a test case for the wildcard * range to ensure it behaves as expected with the new logic. The wildcard is also parsed as a range and will be affected by the change to prefer the latest tag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
类似的 latest-4, latest-1 这种,需要做优先级处理吗?
如果同时存在 latest-4 和 latest,并且它们指向的版本不一致,以那个 tag 为最高优先级判断?