tskredens/src/api.ts

128 lines
2.9 KiB
TypeScript
Raw Normal View History

2019-09-25 05:09:20 +02:00
// Copyright (C) 2019 ModZero <modzero@modzero.xyz>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
2019-09-26 20:19:57 +02:00
import { db } from "@kredens/db";
2019-10-08 02:36:30 +02:00
import { User } from "@kredens/db/models";
2019-10-07 23:31:51 +02:00
import { ApolloServer, AuthenticationError, gql } from "apollo-server-express";
2019-09-25 04:39:03 +02:00
import { Kind } from "graphql/language";
import { GraphQLScalarType, GraphQLScalarTypeConfig } from "graphql/type";
import { DateTime } from "luxon";
const typeDefs = gql`
type Query {
"A simple type for getting started"
hello: String
migrations: [Migration]!
2019-10-08 02:36:30 +02:00
user(id: ID): User
2019-09-25 04:39:03 +02:00
}
type Migration {
2019-10-08 02:36:30 +02:00
id: ID!
2019-09-25 04:39:03 +02:00
name: String!
applied_at: DateTime!
}
2019-10-08 02:36:30 +02:00
type User {
id: ID!
email: String!
tasks: [Task]!
}
type Task {
id: ID
name: String!
notes: String
schedule: ScheduleType!
min_frequency: Int
max_frequency: Int
created_at: DateTime!
}
2019-09-25 04:39:03 +02:00
scalar DateTime
2019-10-08 02:36:30 +02:00
enum ScheduleType {
ONCE
DAILY
WEEKLY
MONTHLY
YEARLY
}
2019-09-25 04:39:03 +02:00
`;
const dateTimeConfig: GraphQLScalarTypeConfig<DateTime, string> = {
description: "Date custom scalar type",
name: "DateTime",
parseValue(value) {
return DateTime.fromISO(value as string);
},
serialize(value) {
return (value as DateTime).toISO();
},
parseLiteral(ast) {
if (ast.kind === Kind.STRING) {
return DateTime.fromISO(ast.value);
}
return null;
}
};
const resolvers = {
DateTime: new GraphQLScalarType(dateTimeConfig),
Query: {
2019-10-08 02:36:30 +02:00
hello: () => `Hello, world!`,
migrations: () => db.migrations.applied(),
user: async (
parent: any,
{ id }: { id: string },
context: { user?: User }
) => {
if (!context.user || context.user.id !== +id) {
throw new AuthenticationError(
"You cannot query users other than yourself"
);
}
return db.users.details(+id).then(user => user.orNull());
2019-09-25 04:39:03 +02:00
}
2019-10-08 02:36:30 +02:00
},
User: {
tasks: (user: User) =>
db.tasks.list(user.id).then(tasks =>
tasks.map(t => ({
...t,
schedule: t.schedule.toUpperCase()
}))
)
2019-09-25 04:39:03 +02:00
}
};
export function server() {
return new ApolloServer({
2019-10-07 23:31:51 +02:00
context: async req => {
const user = req.req.user;
if (!user) {
throw new AuthenticationError("you must be logged in");
}
return {
user
};
},
2019-09-25 04:39:03 +02:00
resolvers,
typeDefs
});
}