Skip to content

Commit

Permalink
feat: added driveId exists middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
froid1911 committed Jun 7, 2024
1 parent b334196 commit 71b568b
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 18 deletions.
32 changes: 32 additions & 0 deletions api/src/errors/NotFoundError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { CustomError } from "./CustomError";

export default class NotFoundError extends CustomError {
private static readonly _statusCode = 404;
private readonly _code: number;
private readonly _logging: boolean;
private readonly _context: { [key: string]: any };

constructor(params?: { code?: number, message?: string, logging?: boolean, context?: { [key: string]: any } }) {
const { code, message, logging } = params || {};

super(message || "Not Found");
this._code = code || NotFoundError._statusCode;
this._logging = logging || false;
this._context = params?.context || {};

// Only because we are extending a built in class
Object.setPrototypeOf(this, NotFoundError.prototype);
}

get errors() {
return [{ message: this.message, context: this._context }];
}

get statusCode() {
return this._code;
}

get logging() {
return this._logging;
}
}
21 changes: 13 additions & 8 deletions api/src/graphql/server/generated/index/nexus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ declare global {


declare global {
interface NexusGen extends NexusGenTypes {}
interface NexusGen extends NexusGenTypes { }
}

export interface NexusGenInputs {
Expand Down Expand Up @@ -205,6 +205,7 @@ export interface NexusGenFieldTypes {
Query: { // field return type
coreUnit: NexusGenRootTypes['CoreUnit'] | null; // CoreUnit
coreUnits: Array<NexusGenRootTypes['CoreUnit'] | null> | null; // [CoreUnit]
driveIdBySlug: string | null; // String
drives: Array<string | null> | null; // [String]
system: NexusGenRootTypes['SwitchboardHost'] | null; // SwitchboardHost
}
Expand Down Expand Up @@ -288,6 +289,7 @@ export interface NexusGenFieldTypeNames {
Query: { // field return type name
coreUnit: 'CoreUnit'
coreUnits: 'CoreUnit'
driveIdBySlug: 'String'
drives: 'String'
system: 'SwitchboardHost'
}
Expand Down Expand Up @@ -345,6 +347,9 @@ export interface NexusGenArgTypes {
coreUnit: { // args
id?: string | null; // String
}
driveIdBySlug: { // args
slug?: string | null; // String
}
}
}

Expand Down Expand Up @@ -422,20 +427,20 @@ declare global {
* resolver from executing.
*/
authorize?: FieldAuthorizeResolver<TypeName, FieldName>

/**
* Async validation function. Reject when validation fails. Resolve otherwise.
*/
validate?:
NexusGenArgTypes extends HasTypeField<TypeName, FieldName>
? ArgsValidationConfig<NexusGenArgTypes[TypeName][FieldName]>
: never
validate?:
NexusGenArgTypes extends HasTypeField<TypeName, FieldName>
? ArgsValidationConfig<NexusGenArgTypes[TypeName][FieldName]>
: never

}
interface NexusGenPluginInputFieldConfig<TypeName extends string, FieldName extends string> {
}
interface NexusGenPluginSchemaConfig {
}
interface NexusGenPluginArgConfig {
}
}
}
3 changes: 2 additions & 1 deletion api/src/graphql/server/generated/index/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type Node {
type Query {
coreUnit(id: String): CoreUnit
coreUnits: [CoreUnit]
driveIdBySlug(slug: String): String
drives: [String]
system: SwitchboardHost
}
Expand Down Expand Up @@ -118,4 +119,4 @@ interface System {
type User {
address: String!
createdAt: Date!
}
}
18 changes: 18 additions & 0 deletions api/src/graphql/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { schemaWithMiddleware as indexSchema } from './index/schema';
import { schemaWithMiddleware as driveSchema } from './drive/schema';
import { Context, Context as IndexContext, createContext as createIndexContext } from './index/context';
import { Context as DriveContext, createContext as createDriveContext } from './drive/context';
import { getExtendedPrisma } from '../../importedModules';
import NotFoundError from '../../errors/NotFoundError';

function loggerPlugin(): ApolloServerPlugin<Context> {
return {
Expand Down Expand Up @@ -57,9 +59,25 @@ export const addGraphqlRoutes = async (
'/d/:driveId',
cors<cors.CorsRequest>(),
cookierParser(undefined, { decode: (value: string) => value }),
async (req, res, next) => {
const prisma = getExtendedPrisma();
const { driveId } = req.params;

if (!driveId) {
throw new Error("driveId required")
}

try {
await prisma.document.getDrive(driveId);
} catch (e) {
throw new NotFoundError({ message: (e as Error).message })
}
next();
},
expressMiddleware(apolloDrive, {
context: async (params) => createDriveContext(params),
}),

);
};

Expand Down
11 changes: 6 additions & 5 deletions api/src/middleware/errors.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { NextFunction, Request, Response } from "express";
import { getChildLogger } from "../logger";
import { CustomError } from "../errors/CustomError";

const logger = getChildLogger({ msgPrefix: 'Generic Error Handler', });

export const errorHandler = (err: Error, req: Request, res: Response, next: NextFunction) => {
const errorId = (res as { sentry?: string }).sentry;
err.cause = err.cause || 'Unknown';
logger.error(err, err.message, { errorId });
res.status(500).send({ errors: err.message, errorId });
export const errorHandler = (err: CustomError, req: Request, res: Response, next: NextFunction) => {
const errorId = (res as { sentry?: string }).sentry;
err.cause = err.cause || 'Unknown';
logger.error(err, err.message, { errorId });
res.status(err.statusCode ?? 500).send({ errors: err.message, errorId });
};
4 changes: 2 additions & 2 deletions api/src/modules/document-drive/drive-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const Node = objectType({
},
});

export const DocumentDriveState = objectType({
export const DocumentDriveStateObject = objectType({
name: 'DocumentDriveState',
definition(t) {
t.nonNull.id('id');
Expand Down Expand Up @@ -307,7 +307,7 @@ export const driveSystemQueryField = queryField('system', {
});

export const getDrive = queryField('drive', {
type: DocumentDriveState,
type: DocumentDriveStateObject,
resolve: async (_parent, _args, ctx: Context) => {
try {
const drive = await ctx.prisma.document.getDrive(ctx.driveId ?? '1') as DocumentDriveState;
Expand Down
21 changes: 19 additions & 2 deletions api/src/modules/document-drive/drives-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import {
nonNull,
objectType,
queryField,
stringArg,
} from 'nexus';
import { DocumentDriveState } from './drive-resolver';
import { DocumentDriveStateObject } from './drive-resolver';
import { Context } from '../../graphql/server/drive/context';
import logger from '../../logger';
import DocumentDriveError from '../../errors/DocumentDriveError';
Expand Down Expand Up @@ -49,11 +50,27 @@ export const getDrives = queryField('drives', {
},
});

export const getDriveBySlug = queryField('driveIdBySlug', {
type: 'String',
args: {
slug: stringArg()
},
resolve: async (_parent, args, ctx: Context) => {
try {
const drive = await ctx.prisma.document.getDriveBySlug(args.slug);
return drive.id;
} catch (e) {
logger.error(e);
throw new Error('Drive not found.');
}
},
});

const addDriveResponseDefinition = objectType({
name: 'AddDriveResponse',
definition(t) {
t.nonNull.field('global', {
type: DocumentDriveState
type: DocumentDriveStateObject
});
t.nonNull.field('local', {
type: DocumentDriveLocalState,
Expand Down
9 changes: 9 additions & 0 deletions api/src/modules/document/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ export function getDocumentDriveCRUD(prisma: Prisma.TransactionClient) {
throw new Error("Couldn't get drive");
}
},
getDriveBySlug: async (slug: string) => {
try {
const { state } = await driveServer.getDriveBySlug(slug);
return state.global;
} catch (e) {
logger.error(e);
throw new Error("Couldn't get drive");
}
},
getDrives: async () => {
try {
const driveIds = await driveServer.getDrives()
Expand Down

0 comments on commit 71b568b

Please sign in to comment.