Tasks query API, yay!
This commit is contained in:
55
src/api.ts
55
src/api.ts
@@ -14,6 +14,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { db } from "@kredens/db";
|
||||
import { User } from "@kredens/db/models";
|
||||
import { ApolloServer, AuthenticationError, gql } from "apollo-server-express";
|
||||
import { Kind } from "graphql/language";
|
||||
import { GraphQLScalarType, GraphQLScalarTypeConfig } from "graphql/type";
|
||||
@@ -24,15 +25,40 @@ const typeDefs = gql`
|
||||
"A simple type for getting started"
|
||||
hello: String
|
||||
migrations: [Migration]!
|
||||
user(id: ID): User
|
||||
}
|
||||
|
||||
type Migration {
|
||||
id: ID
|
||||
id: ID!
|
||||
name: String!
|
||||
applied_at: DateTime!
|
||||
}
|
||||
|
||||
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!
|
||||
}
|
||||
|
||||
scalar DateTime
|
||||
|
||||
enum ScheduleType {
|
||||
ONCE
|
||||
DAILY
|
||||
WEEKLY
|
||||
MONTHLY
|
||||
YEARLY
|
||||
}
|
||||
`;
|
||||
|
||||
const dateTimeConfig: GraphQLScalarTypeConfig<DateTime, string> = {
|
||||
@@ -56,12 +82,29 @@ const dateTimeConfig: GraphQLScalarTypeConfig<DateTime, string> = {
|
||||
const resolvers = {
|
||||
DateTime: new GraphQLScalarType(dateTimeConfig),
|
||||
Query: {
|
||||
hello: async () => {
|
||||
return `Hello, world!`;
|
||||
},
|
||||
migrations: async () => {
|
||||
return db.migrations.applied();
|
||||
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());
|
||||
}
|
||||
},
|
||||
User: {
|
||||
tasks: (user: User) =>
|
||||
db.tasks.list(user.id).then(tasks =>
|
||||
tasks.map(t => ({
|
||||
...t,
|
||||
schedule: t.schedule.toUpperCase()
|
||||
}))
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -16,16 +16,23 @@
|
||||
import {
|
||||
Extensions,
|
||||
MigrationRepository,
|
||||
TaskRepository,
|
||||
UserRepository
|
||||
} from "@kredens/db/repos";
|
||||
|
||||
import { DateTime } from "luxon";
|
||||
import pg from "pg";
|
||||
import pgPromise, { IDatabase, IInitOptions } from "pg-promise";
|
||||
|
||||
const types = pg.types;
|
||||
types.setTypeParser(types.builtins.TIMESTAMPTZ, DateTime.fromSQL);
|
||||
types.setTypeParser(types.builtins.TIMESTAMP, DateTime.fromSQL);
|
||||
|
||||
type ExtendedProtocol = IDatabase<Extensions> & Extensions;
|
||||
|
||||
const initOptions: IInitOptions<Extensions> = {
|
||||
extend(obj: ExtendedProtocol, dc: any) {
|
||||
obj.migrations = new MigrationRepository(obj, pgp);
|
||||
obj.tasks = new TaskRepository(obj, pgp);
|
||||
obj.users = new UserRepository(obj, pgp);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -25,3 +25,16 @@ export interface User {
|
||||
id: number;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export type ScheduleType = "once" | "daily" | "weekly" | "monthly" | "yearly";
|
||||
|
||||
export interface Task {
|
||||
id: number;
|
||||
owner: number;
|
||||
name: string;
|
||||
notes?: string;
|
||||
schedule: ScheduleType;
|
||||
min_frequency?: number;
|
||||
max_frequency?: number;
|
||||
created_at: DateTime;
|
||||
}
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { MigrationRepository } from "@kredens/db/repos/migrations";
|
||||
import { TaskRepository } from "@kredens/db/repos/tasks";
|
||||
import { UserRepository } from "@kredens/db/repos/users";
|
||||
|
||||
export interface Extensions {
|
||||
migrations: MigrationRepository;
|
||||
users: UserRepository;
|
||||
tasks: TaskRepository;
|
||||
}
|
||||
|
||||
export { MigrationRepository, UserRepository };
|
||||
export { MigrationRepository, UserRepository, TaskRepository };
|
||||
|
||||
@@ -50,7 +50,7 @@ export class MigrationRepository {
|
||||
public async applied(): Promise<Migration[]> {
|
||||
return this.db.map<Migration>(sql.applied, [], row => {
|
||||
return {
|
||||
applied_at: DateTime.fromSQL(row.applied_at),
|
||||
applied_at: row.applied_at as DateTime,
|
||||
id: +row.id,
|
||||
name: row.name
|
||||
};
|
||||
|
||||
32
src/db/repos/tasks.ts
Normal file
32
src/db/repos/tasks.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
// 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/>.
|
||||
|
||||
import { ScheduleType, Task } from "@kredens/db/models";
|
||||
import { tasks as sql } from "@kredens/db/sql";
|
||||
import { IDatabase, IMain } from "pg-promise";
|
||||
|
||||
export class TaskRepository {
|
||||
private db: IDatabase<any>;
|
||||
|
||||
constructor(db: IDatabase<any>, pgp: IMain) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
public async list(owner: number): Promise<Task[]> {
|
||||
return this.db
|
||||
.manyOrNone<Task>(sql.list, [owner, 10, 0])
|
||||
.then(rows => (rows ? rows : []));
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,11 @@
|
||||
// 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/>.
|
||||
|
||||
import { User } from "@kredens/db/models";
|
||||
import { users as sql } from "@kredens/db/sql";
|
||||
import argon2 from "argon2";
|
||||
import { Maybe, None, Some } from "monet";
|
||||
import { IDatabase, IMain } from "pg-promise";
|
||||
import { User } from "@kredens/db/models";
|
||||
|
||||
export class UserRepository {
|
||||
private db: IDatabase<any>;
|
||||
|
||||
@@ -41,7 +41,11 @@ const users = {
|
||||
login: sql("users/login.sql")
|
||||
};
|
||||
|
||||
export { migrations, users };
|
||||
const tasks = {
|
||||
list: sql("tasks/list.sql")
|
||||
};
|
||||
|
||||
export { migrations, users, tasks };
|
||||
|
||||
/** Helper for linking to external query files */
|
||||
function sql(file: string): QueryFile {
|
||||
|
||||
Reference in New Issue
Block a user