From 1cd3aea02ce929d33cc6d0e8be1bbb50c828c0b7 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 9 Jan 2020 23:48:54 +0100 Subject: [PATCH] mirage: Split route handlers into multiple files --- mirage/config.js | 315 ++-------------------------- mirage/route-handlers/-utils.js | 38 ++++ mirage/route-handlers/categories.js | 30 +++ mirage/route-handlers/crates.js | 175 ++++++++++++++++ mirage/route-handlers/keywords.js | 19 ++ mirage/route-handlers/summary.js | 38 ++++ mirage/route-handlers/teams.js | 9 + mirage/route-handlers/users.js | 9 + 8 files changed, 331 insertions(+), 302 deletions(-) create mode 100644 mirage/route-handlers/-utils.js create mode 100644 mirage/route-handlers/categories.js create mode 100644 mirage/route-handlers/crates.js create mode 100644 mirage/route-handlers/keywords.js create mode 100644 mirage/route-handlers/summary.js create mode 100644 mirage/route-handlers/teams.js create mode 100644 mirage/route-handlers/users.js diff --git a/mirage/config.js b/mirage/config.js index 1dea65e0af..d8b55a7a86 100644 --- a/mirage/config.js +++ b/mirage/config.js @@ -1,307 +1,18 @@ -import Response from 'ember-cli-mirage/response'; +import * as Categories from './route-handlers/categories'; +import * as Crates from './route-handlers/crates'; +import * as Keywords from './route-handlers/keywords'; +import * as Summary from './route-handlers/summary'; +import * as Teams from './route-handlers/teams'; +import * as Users from './route-handlers/users'; export default function() { + Categories.register(this); + Crates.register(this); + Keywords.register(this); + Summary.register(this); + Teams.register(this); + Users.register(this); + // Used by ember-cli-code-coverage this.passthrough('/write-coverage'); - - this.namespace = '/api/v1'; - - this.get('/summary', function(schema) { - let crates = schema.crates.all(); - - let just_updated = crates.sort((a, b) => compareIsoDates(b.updated_at, a.updated_at)).slice(0, 10); - let most_downloaded = crates.sort((a, b) => b.downloads - a.downloads).slice(0, 10); - let new_crates = crates.sort((a, b) => compareIsoDates(b.created_at, a.created_at)).slice(0, 10); - let most_recently_downloaded = crates.sort((a, b) => b.recent_downloads - a.recent_downloads).slice(0, 10); - - let num_crates = crates.length; - let num_downloads = crates.models.reduce((sum, crate) => sum + crate.downloads, 0); - - let popular_categories = schema.categories - .all() - .sort((a, b) => b.crates_cnt - a.crates_cnt) - .slice(0, 10); - let popular_keywords = schema.keywords - .all() - .sort((a, b) => b.crates_cnt - a.crates_cnt) - .slice(0, 10); - - return { - just_updated: this.serialize(just_updated).crates.map(it => ({ ...it, versions: null })), - most_downloaded: this.serialize(most_downloaded).crates.map(it => ({ ...it, versions: null })), - new_crates: this.serialize(new_crates).crates.map(it => ({ ...it, versions: null })), - most_recently_downloaded: this.serialize(most_recently_downloaded).crates.map(it => ({ - ...it, - versions: null, - })), - num_crates, - num_downloads, - popular_categories: this.serialize(popular_categories).categories, - popular_keywords: this.serialize(popular_keywords).keywords, - }; - }); - - this.get('/crates', function(schema, request) { - const { start, end } = pageParams(request); - - let crates = schema.crates.all(); - - if (request.queryParams.letter) { - let letter = request.queryParams.letter.toLowerCase(); - crates = crates.filter(crate => crate.id[0].toLowerCase() === letter); - } - - if (request.queryParams.q) { - let q = request.queryParams.q.toLowerCase(); - crates = crates.filter(crate => crate.id.toLowerCase().indexOf(q) !== -1); - } - - if (request.queryParams.user_id) { - let userId = parseInt(request.queryParams.user_id, 10); - crates = crates.filter(crate => (crate._owner_users || []).indexOf(userId) !== -1); - } - - if (request.queryParams.team_id) { - let teamId = parseInt(request.queryParams.team_id, 10); - crates = crates.filter(crate => (crate._owner_teams || []).indexOf(teamId) !== -1); - } - - if (request.queryParams.sort === 'alpha') { - crates = crates.sort((a, b) => compareStrings(a.id.toLowerCase(), b.id.toLowerCase())); - } - - return withMeta(this.serialize(crates.slice(start, end)), { total: crates.length }); - }); - - this.get('/crates/:crate_id', function(schema, request) { - let crateId = request.params.crate_id; - let crate = schema.crates.find(crateId); - let categories = schema.categories.all().filter(category => (crate.categories || []).indexOf(category.id) !== -1); - let keywords = schema.keywords.all().filter(keyword => (crate.keywords || []).indexOf(keyword.id) !== -1); - let versions = schema.versions - .all() - .filter(version => (crate.versions || []).indexOf(parseInt(version.id, 10)) !== -1); - - return { - ...this.serialize(crate), - ...this.serialize(categories), - ...this.serialize(keywords), - ...this.serialize(versions), - }; - }); - - this.get('/crates/:crate_id/following', (/* schema, request */) => { - // TODO - }); - - this.get('/crates/:crate_id/versions', (schema, request) => { - let crate = request.params.crate_id; - return schema.versions.where({ crate }).sort((a, b) => compareIsoDates(b.created_at, a.created_at)); - }); - - this.get('/crates/:crate_id/:version_num/authors', (schema, request) => { - let crate = request.params.crate_id; - let num = request.params.version_num; - let version = schema.versions.findBy({ crate, num }); - return { meta: { names: version._authors }, users: [] }; - }); - - this.get('/crates/:crate_id/:version_num/dependencies', (schema, request) => { - let crate = request.params.crate_id; - let num = request.params.version_num; - let version_id = schema.versions.findBy({ crate, num }).id; - return schema.dependencies.where({ version_id }); - }); - - this.get('/crates/:crate_id/:version_num/downloads', function(schema, request) { - let crateId = request.params.crate_id; - let versionNum = request.params.version_num; - let versionId = schema.versions.findBy({ crate: crateId, num: versionNum }).id; - return schema.versionDownloads.where({ version: versionId }); - }); - - this.get('/crates/:crate_id/owner_user', function(schema, request) { - let crateId = request.params.crate_id; - let crate = schema.crates.find(crateId); - let users = schema.users.find(crate._owner_users); - - let response = this.serialize(users); - - response.users.forEach(user => { - user.kind = 'user'; - }); - - return response; - }); - - this.get('/crates/:crate_id/owner_team', function(schema, request) { - let crateId = request.params.crate_id; - let crate = schema.crates.find(crateId); - let teams = schema.teams.find(crate._owner_teams); - - let response = this.serialize(teams); - - response.teams.forEach(team => { - team.kind = 'team'; - }); - - return response; - }); - - this.get('/crates/:crate_id/reverse_dependencies', function(schema, request) { - let { start, end } = pageParams(request); - - let crate = request.params.crate_id; - let allDependencies = schema.dependencies.where({ crate_id: crate }); - let dependencies = allDependencies.slice(start, end); - let total = allDependencies.length; - - let versions = schema.versions.find(dependencies.models.map(it => it.version_id)); - - return { - ...this.serialize(dependencies), - ...this.serialize(versions), - meta: { total }, - }; - }); - - this.get('/crates/:crate_id/downloads', function(schema, request) { - let crateId = request.params.crate_id; - let crate = schema.crates.find(crateId); - let versionDownloads = schema.versionDownloads - .all() - .filter(it => crate.versions.indexOf(parseInt(it.version, 10)) !== -1); - - return withMeta(this.serialize(versionDownloads), { extra_downloads: crate._extra_downloads }); - }); - - this.get('/categories', function(schema, request) { - let { start, end } = pageParams(request); - - let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category)); - let categories = allCategories.slice(start, end); - let total = allCategories.length; - - return withMeta(this.serialize(categories), { total }); - }); - - this.get('/categories/:category_id', function(schema, request) { - let catId = request.params.category_id; - let category = schema.categories.find(catId); - return category ? category : notFound(); - }); - - this.get('/category_slugs', function(schema) { - let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category)); - return { - category_slugs: this.serialize(allCategories).categories.map(cat => ({ - id: cat.id, - slug: cat.slug, - description: cat.description, - })), - }; - }); - - this.get('/keywords', function(schema, request) { - let { start, end } = pageParams(request); - - let allKeywords = schema.keywords.all().sort((a, b) => a.crates_cnt - b.crates_cnt); - let keywords = allKeywords.slice(start, end); - let total = allKeywords.length; - - return withMeta(this.serialize(keywords), { total }); - }); - - this.get('/keywords/:keyword_id', (schema, request) => { - let keywordId = request.params.keyword_id; - let keyword = schema.keywords.find(keywordId); - return keyword ? keyword : notFound(); - }); - - this.get('/teams/:team_id', (schema, request) => { - let login = request.params.team_id; - let team = schema.teams.findBy({ login }); - return team ? team : notFound(); - }); - - this.get('/users/:user_id', (schema, request) => { - let login = request.params.user_id; - let user = schema.users.findBy({ login }); - return user ? user : notFound(); - }); - - this.put('/crates/:crate_id/owners', (schema, request) => { - const crateId = request.params.crate_id; - const crate = schema.crates.find(crateId); - - if (!crate) { - return notFound(); - } - - const body = JSON.parse(request.requestBody); - const [ownerId] = body.owners; - const user = schema.users.findBy({ login: ownerId }); - - if (!user) { - return notFound(); - } - - return { ok: true }; - }); - - this.delete('/crates/:crate_id/owners', (schema, request) => { - const crateId = request.params.crate_id; - const crate = schema.crates.find(crateId); - - if (!crate) { - return notFound(); - } - - const body = JSON.parse(request.requestBody); - const [ownerId] = body.owners; - const user = schema.users.findBy({ login: ownerId }); - - if (!user) { - return notFound(); - } - - return {}; - }); -} - -function notFound() { - return new Response( - 404, - { 'Content-Type': 'application/json' }, - { - errors: [{ detail: 'Not Found' }], - }, - ); -} - -function pageParams(request) { - const { queryParams } = request; - - const page = parseInt(queryParams.page || '1'); - const perPage = parseInt(queryParams.per_page || '10'); - - const start = (page - 1) * perPage; - const end = start + perPage; - - return { page, perPage, start, end }; -} - -function withMeta(response, meta) { - response.meta = meta; - return response; -} - -function compareStrings(a, b) { - return a < b ? -1 : a > b ? 1 : 0; -} - -function compareIsoDates(a, b) { - let aDate = new Date(a); - let bDate = new Date(b); - return aDate < bDate ? -1 : aDate > bDate ? 1 : 0; } diff --git a/mirage/route-handlers/-utils.js b/mirage/route-handlers/-utils.js new file mode 100644 index 0000000000..f091576dcd --- /dev/null +++ b/mirage/route-handlers/-utils.js @@ -0,0 +1,38 @@ +import Response from 'ember-cli-mirage/response'; + +export function notFound() { + return new Response( + 404, + { 'Content-Type': 'application/json' }, + { + errors: [{ detail: 'Not Found' }], + }, + ); +} + +export function pageParams(request) { + const { queryParams } = request; + + const page = parseInt(queryParams.page || '1'); + const perPage = parseInt(queryParams.per_page || '10'); + + const start = (page - 1) * perPage; + const end = start + perPage; + + return { page, perPage, start, end }; +} + +export function withMeta(response, meta) { + response.meta = meta; + return response; +} + +export function compareStrings(a, b) { + return a < b ? -1 : a > b ? 1 : 0; +} + +export function compareIsoDates(a, b) { + let aDate = new Date(a); + let bDate = new Date(b); + return aDate < bDate ? -1 : aDate > bDate ? 1 : 0; +} diff --git a/mirage/route-handlers/categories.js b/mirage/route-handlers/categories.js new file mode 100644 index 0000000000..d8fdc9fd20 --- /dev/null +++ b/mirage/route-handlers/categories.js @@ -0,0 +1,30 @@ +import { pageParams, compareStrings, withMeta, notFound } from './-utils'; + +export function register(server) { + server.get('/api/v1/categories', function(schema, request) { + let { start, end } = pageParams(request); + + let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category)); + let categories = allCategories.slice(start, end); + let total = allCategories.length; + + return withMeta(this.serialize(categories), { total }); + }); + + server.get('/api/v1/categories/:category_id', function(schema, request) { + let catId = request.params.category_id; + let category = schema.categories.find(catId); + return category ? category : notFound(); + }); + + server.get('/api/v1/category_slugs', function(schema) { + let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category)); + return { + category_slugs: this.serialize(allCategories).categories.map(cat => ({ + id: cat.id, + slug: cat.slug, + description: cat.description, + })), + }; + }); +} diff --git a/mirage/route-handlers/crates.js b/mirage/route-handlers/crates.js new file mode 100644 index 0000000000..a1723892d7 --- /dev/null +++ b/mirage/route-handlers/crates.js @@ -0,0 +1,175 @@ +import { pageParams, compareStrings, withMeta, compareIsoDates, notFound } from './-utils'; + +export function register(server) { + server.get('/api/v1/crates', function(schema, request) { + const { start, end } = pageParams(request); + + let crates = schema.crates.all(); + + if (request.queryParams.letter) { + let letter = request.queryParams.letter.toLowerCase(); + crates = crates.filter(crate => crate.id[0].toLowerCase() === letter); + } + + if (request.queryParams.q) { + let q = request.queryParams.q.toLowerCase(); + crates = crates.filter(crate => crate.id.toLowerCase().indexOf(q) !== -1); + } + + if (request.queryParams.user_id) { + let userId = parseInt(request.queryParams.user_id, 10); + crates = crates.filter(crate => (crate._owner_users || []).indexOf(userId) !== -1); + } + + if (request.queryParams.team_id) { + let teamId = parseInt(request.queryParams.team_id, 10); + crates = crates.filter(crate => (crate._owner_teams || []).indexOf(teamId) !== -1); + } + + if (request.queryParams.sort === 'alpha') { + crates = crates.sort((a, b) => compareStrings(a.id.toLowerCase(), b.id.toLowerCase())); + } + + return withMeta(this.serialize(crates.slice(start, end)), { total: crates.length }); + }); + + server.get('/api/v1/crates/:crate_id', function(schema, request) { + let crateId = request.params.crate_id; + let crate = schema.crates.find(crateId); + let categories = schema.categories.all().filter(category => (crate.categories || []).indexOf(category.id) !== -1); + let keywords = schema.keywords.all().filter(keyword => (crate.keywords || []).indexOf(keyword.id) !== -1); + let versions = schema.versions + .all() + .filter(version => (crate.versions || []).indexOf(parseInt(version.id, 10)) !== -1); + + return { + ...this.serialize(crate), + ...this.serialize(categories), + ...this.serialize(keywords), + ...this.serialize(versions), + }; + }); + + server.get('/api/v1/crates/:crate_id/following', (/* schema, request */) => { + // TODO + }); + + server.get('/api/v1/crates/:crate_id/versions', (schema, request) => { + let crate = request.params.crate_id; + return schema.versions.where({ crate }).sort((a, b) => compareIsoDates(b.created_at, a.created_at)); + }); + + server.get('/api/v1/crates/:crate_id/:version_num/authors', (schema, request) => { + let crate = request.params.crate_id; + let num = request.params.version_num; + let version = schema.versions.findBy({ crate, num }); + return { meta: { names: version._authors }, users: [] }; + }); + + server.get('/api/v1/crates/:crate_id/:version_num/dependencies', (schema, request) => { + let crate = request.params.crate_id; + let num = request.params.version_num; + let version_id = schema.versions.findBy({ crate, num }).id; + return schema.dependencies.where({ version_id }); + }); + + server.get('/api/v1/crates/:crate_id/:version_num/downloads', function(schema, request) { + let crateId = request.params.crate_id; + let versionNum = request.params.version_num; + let versionId = schema.versions.findBy({ crate: crateId, num: versionNum }).id; + return schema.versionDownloads.where({ version: versionId }); + }); + + server.get('/api/v1/crates/:crate_id/owner_user', function(schema, request) { + let crateId = request.params.crate_id; + let crate = schema.crates.find(crateId); + let users = schema.users.find(crate._owner_users); + + let response = this.serialize(users); + + response.users.forEach(user => { + user.kind = 'user'; + }); + + return response; + }); + + server.get('/api/v1/crates/:crate_id/owner_team', function(schema, request) { + let crateId = request.params.crate_id; + let crate = schema.crates.find(crateId); + let teams = schema.teams.find(crate._owner_teams); + + let response = this.serialize(teams); + + response.teams.forEach(team => { + team.kind = 'team'; + }); + + return response; + }); + + server.get('/api/v1/crates/:crate_id/reverse_dependencies', function(schema, request) { + let { start, end } = pageParams(request); + + let crate = request.params.crate_id; + let allDependencies = schema.dependencies.where({ crate_id: crate }); + let dependencies = allDependencies.slice(start, end); + let total = allDependencies.length; + + let versions = schema.versions.find(dependencies.models.map(it => it.version_id)); + + return { + ...this.serialize(dependencies), + ...this.serialize(versions), + meta: { total }, + }; + }); + + server.get('/api/v1/crates/:crate_id/downloads', function(schema, request) { + let crateId = request.params.crate_id; + let crate = schema.crates.find(crateId); + let versionDownloads = schema.versionDownloads + .all() + .filter(it => crate.versions.indexOf(parseInt(it.version, 10)) !== -1); + + return withMeta(this.serialize(versionDownloads), { extra_downloads: crate._extra_downloads }); + }); + + server.put('/api/v1/crates/:crate_id/owners', (schema, request) => { + const crateId = request.params.crate_id; + const crate = schema.crates.find(crateId); + + if (!crate) { + return notFound(); + } + + const body = JSON.parse(request.requestBody); + const [ownerId] = body.owners; + const user = schema.users.findBy({ login: ownerId }); + + if (!user) { + return notFound(); + } + + return { ok: true }; + }); + + server.delete('/api/v1/crates/:crate_id/owners', (schema, request) => { + const crateId = request.params.crate_id; + const crate = schema.crates.find(crateId); + + if (!crate) { + return notFound(); + } + + const body = JSON.parse(request.requestBody); + const [ownerId] = body.owners; + const user = schema.users.findBy({ login: ownerId }); + + if (!user) { + return notFound(); + } + + return {}; + }); +} diff --git a/mirage/route-handlers/keywords.js b/mirage/route-handlers/keywords.js new file mode 100644 index 0000000000..21a5420ee6 --- /dev/null +++ b/mirage/route-handlers/keywords.js @@ -0,0 +1,19 @@ +import { pageParams, withMeta, notFound } from './-utils'; + +export function register(server) { + server.get('/api/v1/keywords', function(schema, request) { + let { start, end } = pageParams(request); + + let allKeywords = schema.keywords.all().sort((a, b) => a.crates_cnt - b.crates_cnt); + let keywords = allKeywords.slice(start, end); + let total = allKeywords.length; + + return withMeta(this.serialize(keywords), { total }); + }); + + server.get('/api/v1/keywords/:keyword_id', (schema, request) => { + let keywordId = request.params.keyword_id; + let keyword = schema.keywords.find(keywordId); + return keyword ? keyword : notFound(); + }); +} diff --git a/mirage/route-handlers/summary.js b/mirage/route-handlers/summary.js new file mode 100644 index 0000000000..91cc0c11f5 --- /dev/null +++ b/mirage/route-handlers/summary.js @@ -0,0 +1,38 @@ +import { compareIsoDates } from './-utils'; + +export function register(server) { + server.get('/api/v1/summary', function(schema) { + let crates = schema.crates.all(); + + let just_updated = crates.sort((a, b) => compareIsoDates(b.updated_at, a.updated_at)).slice(0, 10); + let most_downloaded = crates.sort((a, b) => b.downloads - a.downloads).slice(0, 10); + let new_crates = crates.sort((a, b) => compareIsoDates(b.created_at, a.created_at)).slice(0, 10); + let most_recently_downloaded = crates.sort((a, b) => b.recent_downloads - a.recent_downloads).slice(0, 10); + + let num_crates = crates.length; + let num_downloads = crates.models.reduce((sum, crate) => sum + crate.downloads, 0); + + let popular_categories = schema.categories + .all() + .sort((a, b) => b.crates_cnt - a.crates_cnt) + .slice(0, 10); + let popular_keywords = schema.keywords + .all() + .sort((a, b) => b.crates_cnt - a.crates_cnt) + .slice(0, 10); + + return { + just_updated: this.serialize(just_updated).crates.map(it => ({ ...it, versions: null })), + most_downloaded: this.serialize(most_downloaded).crates.map(it => ({ ...it, versions: null })), + new_crates: this.serialize(new_crates).crates.map(it => ({ ...it, versions: null })), + most_recently_downloaded: this.serialize(most_recently_downloaded).crates.map(it => ({ + ...it, + versions: null, + })), + num_crates, + num_downloads, + popular_categories: this.serialize(popular_categories).categories, + popular_keywords: this.serialize(popular_keywords).keywords, + }; + }); +} diff --git a/mirage/route-handlers/teams.js b/mirage/route-handlers/teams.js new file mode 100644 index 0000000000..908f8727e2 --- /dev/null +++ b/mirage/route-handlers/teams.js @@ -0,0 +1,9 @@ +import { notFound } from './-utils'; + +export function register(server) { + server.get('/api/v1/teams/:team_id', (schema, request) => { + let login = request.params.team_id; + let team = schema.teams.findBy({ login }); + return team ? team : notFound(); + }); +} diff --git a/mirage/route-handlers/users.js b/mirage/route-handlers/users.js new file mode 100644 index 0000000000..50b1717ed4 --- /dev/null +++ b/mirage/route-handlers/users.js @@ -0,0 +1,9 @@ +import { notFound } from './-utils'; + +export function register(server) { + server.get('/api/v1/users/:user_id', (schema, request) => { + let login = request.params.user_id; + let user = schema.users.findBy({ login }); + return user ? user : notFound(); + }); +}