From 7e215ef7477e4218fec8362090952b11f2629323 Mon Sep 17 00:00:00 2001 From: eth3lbert Date: Tue, 31 Dec 2024 01:27:32 +0800 Subject: [PATCH] mirage: Add `meta` field in `GET /api/v1/crates/:id/versions` (#10294) --- mirage/route-handlers/-utils.js | 16 ++++++++++++ mirage/route-handlers/crates.js | 17 +++++++++--- tests/mirage/crates/versions/list-test.js | 32 +++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/mirage/route-handlers/-utils.js b/mirage/route-handlers/-utils.js index b40b7ad4e49..cb727b41e98 100644 --- a/mirage/route-handlers/-utils.js +++ b/mirage/route-handlers/-utils.js @@ -1,4 +1,6 @@ import { Response } from 'miragejs'; +import semverParse from 'semver/functions/parse'; +import semverSort from 'semver/functions/rsort'; export function notFound() { return new Response( @@ -31,3 +33,17 @@ export function compareIsoDates(a, b) { let bDate = new Date(b); return aDate < bDate ? -1 : aDate > bDate ? 1 : 0; } + +export function releaseTracks(versions) { + let versionNums = versions.models.filter(it => !it.yanked).map(it => it.num); + semverSort(versionNums, { loose: true }); + let tracks = {}; + for (let num of versionNums) { + let semver = semverParse(num, { loose: true }); + if (!semver || semver.prerelease.length !== 0) continue; + let name = semver.major == 0 ? `0.${semver.minor}` : `${semver.major}`; + if (name in tracks) continue; + tracks[name] = { highest: num }; + } + return tracks; +} diff --git a/mirage/route-handlers/crates.js b/mirage/route-handlers/crates.js index 637dbf7430a..8633ae7f93f 100644 --- a/mirage/route-handlers/crates.js +++ b/mirage/route-handlers/crates.js @@ -1,7 +1,7 @@ import { Response } from 'miragejs'; import { getSession } from '../utils/session'; -import { compareIsoDates, compareStrings, notFound, pageParams } from './-utils'; +import { compareIsoDates, compareStrings, notFound, pageParams, releaseTracks } from './-utils'; export function list(schema, request) { const { start, end } = pageParams(request); @@ -140,12 +140,23 @@ export function register(server) { return { ok: true }; }); - server.get('/api/v1/crates/:name/versions', (schema, request) => { + server.get('/api/v1/crates/:name/versions', function (schema, request) { let { name } = request.params; let crate = schema.crates.findBy({ name }); if (!crate) return notFound(); - return crate.versions.sort((a, b) => compareIsoDates(b.created_at, a.created_at)); + let versions = crate.versions.sort((a, b) => compareIsoDates(b.created_at, a.created_at)); + let total = versions.length; + let include = request.queryParams?.include ?? ''; + let release_tracks = include.split(',').includes('release_tracks') && releaseTracks(crate.versions); + let resp = { + ...this.serialize(versions), + meta: { total, next_page: null }, + }; + if (release_tracks && Object.keys(release_tracks).length !== 0) { + resp.meta.release_tracks = release_tracks; + } + return resp; }); server.get('/api/v1/crates/:name/:version_num/authors', (schema, request) => { diff --git a/tests/mirage/crates/versions/list-test.js b/tests/mirage/crates/versions/list-test.js index 183c8dbb0b9..d4a4459849c 100644 --- a/tests/mirage/crates/versions/list-test.js +++ b/tests/mirage/crates/versions/list-test.js @@ -22,6 +22,7 @@ module('Mirage | GET /api/v1/crates/:id/versions', function (hooks) { assert.strictEqual(response.status, 200); assert.deepEqual(await response.json(), { versions: [], + meta: { total: 0, next_page: null }, }); }); @@ -103,6 +104,37 @@ module('Mirage | GET /api/v1/crates/:id/versions', function (hooks) { yank_message: null, }, ], + meta: { total: 3, next_page: null }, + }); + }); + + test('include `release_tracks` meta', async function (assert) { + let user = this.server.create('user'); + let crate = this.server.create('crate', { name: 'rand' }); + this.server.create('version', { crate, num: '0.0.1' }); + this.server.create('version', { crate, num: '0.0.2', yanked: true }); + this.server.create('version', { crate, num: '1.0.0' }); + this.server.create('version', { crate, num: '1.1.0', publishedBy: user }); + this.server.create('version', { crate, num: '1.2.0', rust_version: '1.69', yanked: true }); + + let req = await fetch('/api/v1/crates/rand/versions'); + let expected = await req.json(); + + let response = await fetch('/api/v1/crates/rand/versions?include=release_tracks'); + assert.strictEqual(response.status, 200); + assert.deepEqual(await response.json(), { + ...expected, + meta: { + ...expected.meta, + release_tracks: { + '0.0': { + highest: '0.0.1', + }, + 1: { + highest: '1.1.0', + }, + }, + }, }); }); });