Skip to content

Commit 9deef3e

Browse files
committed
Auto merge of #2112 - Turbo87:mirage, r=locks
mirage: Split route handlers into multiple files This makes the files a little more maintainable and scales better :) r? @locks
2 parents 2192bb3 + 1cd3aea commit 9deef3e

File tree

8 files changed

+331
-302
lines changed

8 files changed

+331
-302
lines changed

mirage/config.js

Lines changed: 13 additions & 302 deletions
Original file line numberDiff line numberDiff line change
@@ -1,307 +1,18 @@
1-
import Response from 'ember-cli-mirage/response';
1+
import * as Categories from './route-handlers/categories';
2+
import * as Crates from './route-handlers/crates';
3+
import * as Keywords from './route-handlers/keywords';
4+
import * as Summary from './route-handlers/summary';
5+
import * as Teams from './route-handlers/teams';
6+
import * as Users from './route-handlers/users';
27

38
export default function() {
9+
Categories.register(this);
10+
Crates.register(this);
11+
Keywords.register(this);
12+
Summary.register(this);
13+
Teams.register(this);
14+
Users.register(this);
15+
416
// Used by ember-cli-code-coverage
517
this.passthrough('/write-coverage');
6-
7-
this.namespace = '/api/v1';
8-
9-
this.get('/summary', function(schema) {
10-
let crates = schema.crates.all();
11-
12-
let just_updated = crates.sort((a, b) => compareIsoDates(b.updated_at, a.updated_at)).slice(0, 10);
13-
let most_downloaded = crates.sort((a, b) => b.downloads - a.downloads).slice(0, 10);
14-
let new_crates = crates.sort((a, b) => compareIsoDates(b.created_at, a.created_at)).slice(0, 10);
15-
let most_recently_downloaded = crates.sort((a, b) => b.recent_downloads - a.recent_downloads).slice(0, 10);
16-
17-
let num_crates = crates.length;
18-
let num_downloads = crates.models.reduce((sum, crate) => sum + crate.downloads, 0);
19-
20-
let popular_categories = schema.categories
21-
.all()
22-
.sort((a, b) => b.crates_cnt - a.crates_cnt)
23-
.slice(0, 10);
24-
let popular_keywords = schema.keywords
25-
.all()
26-
.sort((a, b) => b.crates_cnt - a.crates_cnt)
27-
.slice(0, 10);
28-
29-
return {
30-
just_updated: this.serialize(just_updated).crates.map(it => ({ ...it, versions: null })),
31-
most_downloaded: this.serialize(most_downloaded).crates.map(it => ({ ...it, versions: null })),
32-
new_crates: this.serialize(new_crates).crates.map(it => ({ ...it, versions: null })),
33-
most_recently_downloaded: this.serialize(most_recently_downloaded).crates.map(it => ({
34-
...it,
35-
versions: null,
36-
})),
37-
num_crates,
38-
num_downloads,
39-
popular_categories: this.serialize(popular_categories).categories,
40-
popular_keywords: this.serialize(popular_keywords).keywords,
41-
};
42-
});
43-
44-
this.get('/crates', function(schema, request) {
45-
const { start, end } = pageParams(request);
46-
47-
let crates = schema.crates.all();
48-
49-
if (request.queryParams.letter) {
50-
let letter = request.queryParams.letter.toLowerCase();
51-
crates = crates.filter(crate => crate.id[0].toLowerCase() === letter);
52-
}
53-
54-
if (request.queryParams.q) {
55-
let q = request.queryParams.q.toLowerCase();
56-
crates = crates.filter(crate => crate.id.toLowerCase().indexOf(q) !== -1);
57-
}
58-
59-
if (request.queryParams.user_id) {
60-
let userId = parseInt(request.queryParams.user_id, 10);
61-
crates = crates.filter(crate => (crate._owner_users || []).indexOf(userId) !== -1);
62-
}
63-
64-
if (request.queryParams.team_id) {
65-
let teamId = parseInt(request.queryParams.team_id, 10);
66-
crates = crates.filter(crate => (crate._owner_teams || []).indexOf(teamId) !== -1);
67-
}
68-
69-
if (request.queryParams.sort === 'alpha') {
70-
crates = crates.sort((a, b) => compareStrings(a.id.toLowerCase(), b.id.toLowerCase()));
71-
}
72-
73-
return withMeta(this.serialize(crates.slice(start, end)), { total: crates.length });
74-
});
75-
76-
this.get('/crates/:crate_id', function(schema, request) {
77-
let crateId = request.params.crate_id;
78-
let crate = schema.crates.find(crateId);
79-
let categories = schema.categories.all().filter(category => (crate.categories || []).indexOf(category.id) !== -1);
80-
let keywords = schema.keywords.all().filter(keyword => (crate.keywords || []).indexOf(keyword.id) !== -1);
81-
let versions = schema.versions
82-
.all()
83-
.filter(version => (crate.versions || []).indexOf(parseInt(version.id, 10)) !== -1);
84-
85-
return {
86-
...this.serialize(crate),
87-
...this.serialize(categories),
88-
...this.serialize(keywords),
89-
...this.serialize(versions),
90-
};
91-
});
92-
93-
this.get('/crates/:crate_id/following', (/* schema, request */) => {
94-
// TODO
95-
});
96-
97-
this.get('/crates/:crate_id/versions', (schema, request) => {
98-
let crate = request.params.crate_id;
99-
return schema.versions.where({ crate }).sort((a, b) => compareIsoDates(b.created_at, a.created_at));
100-
});
101-
102-
this.get('/crates/:crate_id/:version_num/authors', (schema, request) => {
103-
let crate = request.params.crate_id;
104-
let num = request.params.version_num;
105-
let version = schema.versions.findBy({ crate, num });
106-
return { meta: { names: version._authors }, users: [] };
107-
});
108-
109-
this.get('/crates/:crate_id/:version_num/dependencies', (schema, request) => {
110-
let crate = request.params.crate_id;
111-
let num = request.params.version_num;
112-
let version_id = schema.versions.findBy({ crate, num }).id;
113-
return schema.dependencies.where({ version_id });
114-
});
115-
116-
this.get('/crates/:crate_id/:version_num/downloads', function(schema, request) {
117-
let crateId = request.params.crate_id;
118-
let versionNum = request.params.version_num;
119-
let versionId = schema.versions.findBy({ crate: crateId, num: versionNum }).id;
120-
return schema.versionDownloads.where({ version: versionId });
121-
});
122-
123-
this.get('/crates/:crate_id/owner_user', function(schema, request) {
124-
let crateId = request.params.crate_id;
125-
let crate = schema.crates.find(crateId);
126-
let users = schema.users.find(crate._owner_users);
127-
128-
let response = this.serialize(users);
129-
130-
response.users.forEach(user => {
131-
user.kind = 'user';
132-
});
133-
134-
return response;
135-
});
136-
137-
this.get('/crates/:crate_id/owner_team', function(schema, request) {
138-
let crateId = request.params.crate_id;
139-
let crate = schema.crates.find(crateId);
140-
let teams = schema.teams.find(crate._owner_teams);
141-
142-
let response = this.serialize(teams);
143-
144-
response.teams.forEach(team => {
145-
team.kind = 'team';
146-
});
147-
148-
return response;
149-
});
150-
151-
this.get('/crates/:crate_id/reverse_dependencies', function(schema, request) {
152-
let { start, end } = pageParams(request);
153-
154-
let crate = request.params.crate_id;
155-
let allDependencies = schema.dependencies.where({ crate_id: crate });
156-
let dependencies = allDependencies.slice(start, end);
157-
let total = allDependencies.length;
158-
159-
let versions = schema.versions.find(dependencies.models.map(it => it.version_id));
160-
161-
return {
162-
...this.serialize(dependencies),
163-
...this.serialize(versions),
164-
meta: { total },
165-
};
166-
});
167-
168-
this.get('/crates/:crate_id/downloads', function(schema, request) {
169-
let crateId = request.params.crate_id;
170-
let crate = schema.crates.find(crateId);
171-
let versionDownloads = schema.versionDownloads
172-
.all()
173-
.filter(it => crate.versions.indexOf(parseInt(it.version, 10)) !== -1);
174-
175-
return withMeta(this.serialize(versionDownloads), { extra_downloads: crate._extra_downloads });
176-
});
177-
178-
this.get('/categories', function(schema, request) {
179-
let { start, end } = pageParams(request);
180-
181-
let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category));
182-
let categories = allCategories.slice(start, end);
183-
let total = allCategories.length;
184-
185-
return withMeta(this.serialize(categories), { total });
186-
});
187-
188-
this.get('/categories/:category_id', function(schema, request) {
189-
let catId = request.params.category_id;
190-
let category = schema.categories.find(catId);
191-
return category ? category : notFound();
192-
});
193-
194-
this.get('/category_slugs', function(schema) {
195-
let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category));
196-
return {
197-
category_slugs: this.serialize(allCategories).categories.map(cat => ({
198-
id: cat.id,
199-
slug: cat.slug,
200-
description: cat.description,
201-
})),
202-
};
203-
});
204-
205-
this.get('/keywords', function(schema, request) {
206-
let { start, end } = pageParams(request);
207-
208-
let allKeywords = schema.keywords.all().sort((a, b) => a.crates_cnt - b.crates_cnt);
209-
let keywords = allKeywords.slice(start, end);
210-
let total = allKeywords.length;
211-
212-
return withMeta(this.serialize(keywords), { total });
213-
});
214-
215-
this.get('/keywords/:keyword_id', (schema, request) => {
216-
let keywordId = request.params.keyword_id;
217-
let keyword = schema.keywords.find(keywordId);
218-
return keyword ? keyword : notFound();
219-
});
220-
221-
this.get('/teams/:team_id', (schema, request) => {
222-
let login = request.params.team_id;
223-
let team = schema.teams.findBy({ login });
224-
return team ? team : notFound();
225-
});
226-
227-
this.get('/users/:user_id', (schema, request) => {
228-
let login = request.params.user_id;
229-
let user = schema.users.findBy({ login });
230-
return user ? user : notFound();
231-
});
232-
233-
this.put('/crates/:crate_id/owners', (schema, request) => {
234-
const crateId = request.params.crate_id;
235-
const crate = schema.crates.find(crateId);
236-
237-
if (!crate) {
238-
return notFound();
239-
}
240-
241-
const body = JSON.parse(request.requestBody);
242-
const [ownerId] = body.owners;
243-
const user = schema.users.findBy({ login: ownerId });
244-
245-
if (!user) {
246-
return notFound();
247-
}
248-
249-
return { ok: true };
250-
});
251-
252-
this.delete('/crates/:crate_id/owners', (schema, request) => {
253-
const crateId = request.params.crate_id;
254-
const crate = schema.crates.find(crateId);
255-
256-
if (!crate) {
257-
return notFound();
258-
}
259-
260-
const body = JSON.parse(request.requestBody);
261-
const [ownerId] = body.owners;
262-
const user = schema.users.findBy({ login: ownerId });
263-
264-
if (!user) {
265-
return notFound();
266-
}
267-
268-
return {};
269-
});
270-
}
271-
272-
function notFound() {
273-
return new Response(
274-
404,
275-
{ 'Content-Type': 'application/json' },
276-
{
277-
errors: [{ detail: 'Not Found' }],
278-
},
279-
);
280-
}
281-
282-
function pageParams(request) {
283-
const { queryParams } = request;
284-
285-
const page = parseInt(queryParams.page || '1');
286-
const perPage = parseInt(queryParams.per_page || '10');
287-
288-
const start = (page - 1) * perPage;
289-
const end = start + perPage;
290-
291-
return { page, perPage, start, end };
292-
}
293-
294-
function withMeta(response, meta) {
295-
response.meta = meta;
296-
return response;
297-
}
298-
299-
function compareStrings(a, b) {
300-
return a < b ? -1 : a > b ? 1 : 0;
301-
}
302-
303-
function compareIsoDates(a, b) {
304-
let aDate = new Date(a);
305-
let bDate = new Date(b);
306-
return aDate < bDate ? -1 : aDate > bDate ? 1 : 0;
30718
}

mirage/route-handlers/-utils.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import Response from 'ember-cli-mirage/response';
2+
3+
export function notFound() {
4+
return new Response(
5+
404,
6+
{ 'Content-Type': 'application/json' },
7+
{
8+
errors: [{ detail: 'Not Found' }],
9+
},
10+
);
11+
}
12+
13+
export function pageParams(request) {
14+
const { queryParams } = request;
15+
16+
const page = parseInt(queryParams.page || '1');
17+
const perPage = parseInt(queryParams.per_page || '10');
18+
19+
const start = (page - 1) * perPage;
20+
const end = start + perPage;
21+
22+
return { page, perPage, start, end };
23+
}
24+
25+
export function withMeta(response, meta) {
26+
response.meta = meta;
27+
return response;
28+
}
29+
30+
export function compareStrings(a, b) {
31+
return a < b ? -1 : a > b ? 1 : 0;
32+
}
33+
34+
export function compareIsoDates(a, b) {
35+
let aDate = new Date(a);
36+
let bDate = new Date(b);
37+
return aDate < bDate ? -1 : aDate > bDate ? 1 : 0;
38+
}

mirage/route-handlers/categories.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { pageParams, compareStrings, withMeta, notFound } from './-utils';
2+
3+
export function register(server) {
4+
server.get('/api/v1/categories', function(schema, request) {
5+
let { start, end } = pageParams(request);
6+
7+
let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category));
8+
let categories = allCategories.slice(start, end);
9+
let total = allCategories.length;
10+
11+
return withMeta(this.serialize(categories), { total });
12+
});
13+
14+
server.get('/api/v1/categories/:category_id', function(schema, request) {
15+
let catId = request.params.category_id;
16+
let category = schema.categories.find(catId);
17+
return category ? category : notFound();
18+
});
19+
20+
server.get('/api/v1/category_slugs', function(schema) {
21+
let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category));
22+
return {
23+
category_slugs: this.serialize(allCategories).categories.map(cat => ({
24+
id: cat.id,
25+
slug: cat.slug,
26+
description: cat.description,
27+
})),
28+
};
29+
});
30+
}

0 commit comments

Comments
 (0)