-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschema.ts
116 lines (102 loc) · 4.04 KB
/
schema.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { Collection, ObjectId } from 'mongodb';
const { gql } = require('apollo-server-express');
import _ from 'lodash';
// In 'typeDefs' for each function under Query / Mutation there is matching function in 'resolvers' (see 'resolversWithMongoDb').
export const typeDefs = gql`
type Series {
id: ID!
title: String!
yearBegin: Int!
yearEnd: Int!
popularity: Int!
}
type Query {
serieses: [Series]
series(title: String!): Series
}
type Mutation {
addSeries(title: String!, yearBegin: Int!, yearEnd: Int!, popularity: Int!): Series
updateSeries(id: ID!, title: String!, yearBegin: Int!, yearEnd: Int!, popularity: Int!): Series
deleteSeries(id: ID!): String
}
`;
// 'seriesesDb' represents a 'collection' within a MongoDb 'db':
export const resolversWithMongoDb = (seriesesDb: Collection<any>) => {
return {
Query: {
serieses: async (): Promise<TvSeries[]> => {
return (await seriesesDb.find().toArray()).map(series => {
return constructTvSeriesObject(series);
}).sort(compareTvSerieses); // sort by highest popularity, then alphabetic.
},
series: async (root: any, { title }: { title: string }): Promise<TvSeries> => {
return constructTvSeriesObject(await seriesesDb.findOne({ title }));
},
},
Mutation: {
addSeries: async (root: any, { title, yearBegin, yearEnd, popularity }: TvSeriesParameters): Promise<TvSeries> => {
const response = await seriesesDb.insertOne({ title, yearBegin, yearEnd, popularity });
return constructTvSeriesObject(response.ops[0]);
},
updateSeries: async (root: any, { id, title, yearBegin, yearEnd, popularity }: TvSeries): Promise<TvSeries> => {
const updateRes = await seriesesDb.findOneAndUpdate(
{ _id: new ObjectId(id) },
{
$set:
{
title: title,
yearBegin: yearBegin,
yearEnd: yearEnd,
popularity: popularity
}
}
);
// if 'find' failed, 'updateRes.value' is 'null':
if (!updateRes.value) {
return { id: "", title, yearBegin, yearEnd, popularity };
}
return { id, title, yearBegin, yearEnd, popularity };
},
deleteSeries: async (root: any, { id }: { id: string }): Promise<String> => {
const removeRes = await seriesesDb.findOneAndDelete({ "_id": new ObjectId(id) });
// If the tvSeries was removed, we return the id of the removed item:
if (removeRes?.value) {
return id;
}
// If could not remove the item, return "empty" id:
return "";
}
}
}
}
// Auxilary interfaces & functions:
interface TvSeriesParameters {
title: string,
yearBegin: number,
yearEnd: number,
popularity: number
}
interface MongoTvSeries extends TvSeriesParameters {
_id: string
}
interface TvSeries extends TvSeriesParameters {
id: string
}
function constructTvSeriesObject(mongoDbSeriesResult: MongoTvSeries): TvSeries {
return {
id: mongoDbSeriesResult._id.toLocaleString(),
title: mongoDbSeriesResult.title,
yearBegin: mongoDbSeriesResult.yearBegin,
yearEnd: mongoDbSeriesResult.yearEnd,
popularity: mongoDbSeriesResult.popularity
};
}
// Higher popularity comes first, then title
function compareTvSerieses(series1: TvSeries, series2: TvSeries): number {
if (series2.popularity !== series1.popularity) {
return series2.popularity - series1.popularity;
}
if (series1.title < series2.title) return -1;
if (series1.title > series2.title) return 1;
return 0;
}