From cf32ee460cd18edb9a2c88aad0db038fc4342aa9 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 26 Dec 2020 16:25:58 -0500 Subject: [PATCH] lays operation type pattern --- src/auth/getExecuteStaticAccess.ts | 2 +- src/auth/operations/access.ts | 8 +- src/auth/operations/forgotPassword.ts | 17 ++- src/auth/operations/local/forgotPassword.ts | 15 ++- src/auth/operations/local/login.ts | 33 ++++- src/auth/operations/login.ts | 22 +++- src/auth/operations/me.ts | 2 +- src/auth/operations/refresh.ts | 5 +- src/auth/requestHandlers/access.ts | 2 +- src/auth/requestHandlers/forgotPassword.ts | 2 +- src/auth/requestHandlers/init.ts | 2 +- src/auth/requestHandlers/login.ts | 2 +- src/auth/requestHandlers/logout.ts | 2 +- src/auth/requestHandlers/me.ts | 2 +- src/auth/requestHandlers/refresh.ts | 2 +- src/auth/requestHandlers/registerFirstUser.ts | 2 +- src/auth/requestHandlers/resetPassword.ts | 2 +- src/auth/requestHandlers/unlock.ts | 2 +- src/auth/requestHandlers/verifyEmail.ts | 2 +- src/auth/sendVerificationEmail.ts | 2 +- src/auth/types.ts | 4 +- src/collections/config/defaults.ts | 2 +- src/collections/config/types.ts | 2 +- src/collections/requestHandlers/create.ts | 4 +- src/collections/requestHandlers/delete.ts | 4 +- src/collections/requestHandlers/find.ts | 4 +- src/collections/requestHandlers/findByID.ts | 4 +- src/collections/requestHandlers/update.ts | 4 +- src/config/defaults.ts | 1 + src/config/types.ts | 14 ++- src/errors/ValidationError.ts | 2 +- src/express/middleware/errorHandler.ts | 6 +- src/express/middleware/index.ts | 1 + .../{types/payloadRequest.ts => types.ts} | 6 +- src/fields/baseFields/baseUploadFields.ts | 2 +- src/fields/config/types.ts | 2 +- src/globals/buildModel.ts | 4 +- src/globals/config/types.ts | 2 +- src/globals/requestHandlers/findOne.ts | 2 +- src/globals/requestHandlers/update.ts | 2 +- src/{init => graphql}/bindResolvers.ts | 27 +++++ src/graphql/errorHandler.ts | 1 + src/index.ts | 8 +- src/init/bindRequestHandlers.ts | 38 ++++-- src/localization/formatRefPathLocales.ts | 2 +- src/localization/plugin.ts | 4 +- src/mongoose/buildSchema.ts | 8 +- src/types/index.ts | 114 ------------------ src/webpack/getWebpackDevConfig.ts | 4 +- src/webpack/init.ts | 4 +- 50 files changed, 201 insertions(+), 209 deletions(-) rename src/express/{types/payloadRequest.ts => types.ts} (65%) rename src/{init => graphql}/bindResolvers.ts (75%) diff --git a/src/auth/getExecuteStaticAccess.ts b/src/auth/getExecuteStaticAccess.ts index 3edbceb56b..8947c46ff0 100644 --- a/src/auth/getExecuteStaticAccess.ts +++ b/src/auth/getExecuteStaticAccess.ts @@ -1,7 +1,7 @@ import { Response, NextFunction } from 'express'; import executeAccess from './executeAccess'; import { Forbidden } from '../errors'; -import { PayloadRequest } from '../express/types/payloadRequest'; +import { PayloadRequest } from '../express/types'; const getExecuteStaticAccess = ({ config, Model }) => async (req: PayloadRequest, res: Response, next: NextFunction) => { try { diff --git a/src/auth/operations/access.ts b/src/auth/operations/access.ts index 6b1c4b92a7..ed7db3dcfe 100644 --- a/src/auth/operations/access.ts +++ b/src/auth/operations/access.ts @@ -1,9 +1,13 @@ -import { OperationArguments } from '../../types'; +import { PayloadRequest } from '../../express/types'; import { Permissions } from '../types'; const allOperations = ['create', 'read', 'update', 'delete']; -async function accessOperation(args: OperationArguments): Promise { +type Arguments = { + req: PayloadRequest +} + +async function accessOperation(args: Arguments): Promise { const { config } = this; const { diff --git a/src/auth/operations/forgotPassword.ts b/src/auth/operations/forgotPassword.ts index 904c9d8867..6e3315051f 100644 --- a/src/auth/operations/forgotPassword.ts +++ b/src/auth/operations/forgotPassword.ts @@ -1,9 +1,22 @@ import crypto from 'crypto'; import { Document } from 'mongoose'; -import { AuthOperationArguments } from '../../types'; import { APIError } from '../../errors'; +import { PayloadRequest } from '../../express/types'; +import { Collection } from '../../collections/config/types'; -async function forgotPassword(incomingArgs: AuthOperationArguments): Promise { +export type Arguments = { + collection: Collection + data: { + [key: string]: unknown + } + disableEmail?: boolean + expiration?: number + req: PayloadRequest +} + +export type Result = string; + +async function forgotPassword(incomingArgs: Arguments): Promise { const { config, sendEmail: email } = this; if (!Object.prototype.hasOwnProperty.call(incomingArgs.data, 'email')) { diff --git a/src/auth/operations/local/forgotPassword.ts b/src/auth/operations/local/forgotPassword.ts index 3bfa1d25b0..a6c014508d 100644 --- a/src/auth/operations/local/forgotPassword.ts +++ b/src/auth/operations/local/forgotPassword.ts @@ -1,4 +1,17 @@ -async function forgotPassword(options) { +import { PayloadRequest } from '../../../express/types'; +import { Result } from '../forgotPassword'; + +export type Options = { + collection: string + data: { + email: string + } + expiration?: number + disableEmail?: boolean + req?: PayloadRequest +} + +async function forgotPassword(options: Options): Promise { const { collection: collectionSlug, data, diff --git a/src/auth/operations/local/login.ts b/src/auth/operations/local/login.ts index be69585fe5..37cea37b8c 100644 --- a/src/auth/operations/local/login.ts +++ b/src/auth/operations/local/login.ts @@ -1,4 +1,23 @@ -async function login(args) { +import { Response } from 'express'; +import { Result } from '../login'; +import { PayloadRequest } from '../../../express/types'; + +export type Options = { + collection: string + data: { + email: string + password: string + } + req?: PayloadRequest + res?: Response + depth?: number + locale?: string + fallbackLocale?: string + overrideAccess?: boolean + showHiddenFields?: boolean +} + +async function login(options: Options): Promise { const { collection: collectionSlug, req = {}, @@ -9,11 +28,11 @@ async function login(args) { data, overrideAccess = true, showHiddenFields, - } = args; + } = options; const collection = this.collections[collectionSlug]; - const options = { + const args = { depth, collection, overrideAccess, @@ -23,14 +42,16 @@ async function login(args) { ...req, payloadAPI: 'local', payload: this, + locale: undefined, + fallbackLocale: undefined, }, res, }; - if (locale) options.req.locale = locale; - if (fallbackLocale) options.req.fallbackLocale = fallbackLocale; + if (locale) args.req.locale = locale; + if (fallbackLocale) args.req.fallbackLocale = fallbackLocale; - return this.operations.collections.auth.login(options); + return this.operations.collections.auth.login(args); } export default login; diff --git a/src/auth/operations/login.ts b/src/auth/operations/login.ts index 7e809e3b07..1ea28ca5ad 100644 --- a/src/auth/operations/login.ts +++ b/src/auth/operations/login.ts @@ -1,20 +1,34 @@ import jwt from 'jsonwebtoken'; -import { CookieOptions } from 'express'; +import { CookieOptions, Response } from 'express'; import { AuthenticationError, LockedAuth } from '../../errors'; +import { PayloadRequest } from '../../express/types'; import getCookieExpiration from '../../utilities/getCookieExpiration'; import isLocked from '../isLocked'; import removeInternalFields from '../../utilities/removeInternalFields'; -import { OperationArguments } from '../../types'; import { Field, fieldHasSubFields } from '../../fields/config/types'; import { User } from '../types'; +import { Collection } from '../../collections/config/types'; -type LoginResponse = { +export type Result = { user?: User, token?: string, exp?: string, } -async function login(incomingArgs: OperationArguments): Promise { +export type Arguments = { + collection: Collection, + data: { + email: string + password: string + } + req: PayloadRequest + res?: Response + depth?: number + overrideAccess?: boolean + showHiddenFields?: boolean +} + +async function login(incomingArgs: Arguments): Promise { const { config, operations, secret } = this; let args = incomingArgs; diff --git a/src/auth/operations/me.ts b/src/auth/operations/me.ts index 9858321c26..7495b9fd28 100644 --- a/src/auth/operations/me.ts +++ b/src/auth/operations/me.ts @@ -1,6 +1,6 @@ import jwt from 'jsonwebtoken'; import { Collection } from '../../collections/config/types'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; import getExtractJWT from '../getExtractJWT'; import { User } from '../types'; diff --git a/src/auth/operations/refresh.ts b/src/auth/operations/refresh.ts index 5a2cea9c18..d56f117db9 100644 --- a/src/auth/operations/refresh.ts +++ b/src/auth/operations/refresh.ts @@ -29,8 +29,9 @@ async function refresh(incomingArgs) { }, } = args; - const opts = {}; - opts.expiresIn = args.collection.config.auth.tokenExpiration; + const opts = { + expiresIn: args.collection.config.auth.tokenExpiration, + }; if (typeof args.token !== 'string') throw new Forbidden(); diff --git a/src/auth/requestHandlers/access.ts b/src/auth/requestHandlers/access.ts index eb38a292f9..62a4b47920 100644 --- a/src/auth/requestHandlers/access.ts +++ b/src/auth/requestHandlers/access.ts @@ -1,6 +1,6 @@ import { Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; import { Permissions } from '../types'; export type AccessRequestHandler = (req: PayloadRequest, res: Response, next: NextFunction) => unknown; diff --git a/src/auth/requestHandlers/forgotPassword.ts b/src/auth/requestHandlers/forgotPassword.ts index 2263fd8cd2..1f22bd576a 100644 --- a/src/auth/requestHandlers/forgotPassword.ts +++ b/src/auth/requestHandlers/forgotPassword.ts @@ -1,6 +1,6 @@ import { Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; export default async function forgotPasswordHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise { try { diff --git a/src/auth/requestHandlers/init.ts b/src/auth/requestHandlers/init.ts index a085457ff7..34f7a8618f 100644 --- a/src/auth/requestHandlers/init.ts +++ b/src/auth/requestHandlers/init.ts @@ -1,5 +1,5 @@ import { Response, NextFunction } from 'express'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; export default async function initHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise { try { diff --git a/src/auth/requestHandlers/login.ts b/src/auth/requestHandlers/login.ts index 1e8481242f..1066990187 100644 --- a/src/auth/requestHandlers/login.ts +++ b/src/auth/requestHandlers/login.ts @@ -1,6 +1,6 @@ import { Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; export default async function loginHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise { try { diff --git a/src/auth/requestHandlers/logout.ts b/src/auth/requestHandlers/logout.ts index c8b46f4e5c..cd62865daa 100644 --- a/src/auth/requestHandlers/logout.ts +++ b/src/auth/requestHandlers/logout.ts @@ -1,5 +1,5 @@ import { Response, NextFunction } from 'express'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; export default async function logoutHandler(req: PayloadRequest, res: Response, next: NextFunction) { try { diff --git a/src/auth/requestHandlers/me.ts b/src/auth/requestHandlers/me.ts index c1ef6edd47..bda1f02b5c 100644 --- a/src/auth/requestHandlers/me.ts +++ b/src/auth/requestHandlers/me.ts @@ -1,5 +1,5 @@ import { NextFunction, Response } from 'express'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; export default async function me(req: PayloadRequest, res: Response, next: NextFunction): Promise { try { diff --git a/src/auth/requestHandlers/refresh.ts b/src/auth/requestHandlers/refresh.ts index 72cff828df..3ddb9cdd28 100644 --- a/src/auth/requestHandlers/refresh.ts +++ b/src/auth/requestHandlers/refresh.ts @@ -1,6 +1,6 @@ import { Response, NextFunction } from 'express'; import getExtractJWT from '../getExtractJWT'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; export default async function refreshHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise { try { diff --git a/src/auth/requestHandlers/registerFirstUser.ts b/src/auth/requestHandlers/registerFirstUser.ts index ad34e4ca59..2cd7e8b28c 100644 --- a/src/auth/requestHandlers/registerFirstUser.ts +++ b/src/auth/requestHandlers/registerFirstUser.ts @@ -1,5 +1,5 @@ import { Response, NextFunction } from 'express'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; export default async function registerFirstUser(req: PayloadRequest, res: Response, next: NextFunction): Promise { try { diff --git a/src/auth/requestHandlers/resetPassword.ts b/src/auth/requestHandlers/resetPassword.ts index dd8d4f5dd1..3d0120c0b0 100644 --- a/src/auth/requestHandlers/resetPassword.ts +++ b/src/auth/requestHandlers/resetPassword.ts @@ -1,6 +1,6 @@ import { Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; async function resetPassword(req: PayloadRequest, res: Response, next: NextFunction): Promise { try { diff --git a/src/auth/requestHandlers/unlock.ts b/src/auth/requestHandlers/unlock.ts index 371cf22441..7d78540260 100644 --- a/src/auth/requestHandlers/unlock.ts +++ b/src/auth/requestHandlers/unlock.ts @@ -1,6 +1,6 @@ import { Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; export default async function unlockHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise { try { diff --git a/src/auth/requestHandlers/verifyEmail.ts b/src/auth/requestHandlers/verifyEmail.ts index 5ca635e016..4ec383ec5e 100644 --- a/src/auth/requestHandlers/verifyEmail.ts +++ b/src/auth/requestHandlers/verifyEmail.ts @@ -1,6 +1,6 @@ import { Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; async function verifyEmail(req: PayloadRequest, res: Response, next: NextFunction): Promise { try { diff --git a/src/auth/sendVerificationEmail.ts b/src/auth/sendVerificationEmail.ts index fc5a1ca4be..e0d38a4ba2 100644 --- a/src/auth/sendVerificationEmail.ts +++ b/src/auth/sendVerificationEmail.ts @@ -1,5 +1,5 @@ import { Payload } from '..'; -import { PayloadRequest } from '../express/types/payloadRequest'; +import { PayloadRequest } from '../express/types'; import { Config } from '../config/types'; import { Collection } from '../collections/config/types'; import { User } from './types'; diff --git a/src/auth/types.ts b/src/auth/types.ts index a6363f9636..5d4a9b0ad8 100644 --- a/src/auth/types.ts +++ b/src/auth/types.ts @@ -1,5 +1,5 @@ import { DeepRequired } from 'ts-essentials'; -import { PayloadRequest } from '../express/types/payloadRequest'; +import { PayloadRequest } from '../express/types'; export type Permission = { permission: boolean @@ -55,7 +55,7 @@ export type User = { type GenerateVerifyEmailHTML = (args: { req: PayloadRequest, token: string, user: any}) => Promise | string type GenerateVerifyEmailSubject = (args: { req: PayloadRequest, token: string, user: any}) => Promise | string -type GenerateForgotPasswordEmailHTML = (args?: { req?: PayloadRequest, token?: string, user?: string}) => Promise | string +type GenerateForgotPasswordEmailHTML = (args?: { req?: PayloadRequest, token?: string, user?: unknown}) => Promise | string type GenerateForgotPasswordEmailSubject = (args?: { req?: PayloadRequest, token?: string, user?: any }) => Promise | string export interface IncomingAuthType { diff --git a/src/collections/config/defaults.ts b/src/collections/config/defaults.ts index ea1b1efd17..757dbe921f 100644 --- a/src/collections/config/defaults.ts +++ b/src/collections/config/defaults.ts @@ -1,4 +1,4 @@ -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; export const defaults = { access: { diff --git a/src/collections/config/types.ts b/src/collections/config/types.ts index a6aff5c64d..b71cb94917 100644 --- a/src/collections/config/types.ts +++ b/src/collections/config/types.ts @@ -4,7 +4,7 @@ import { PaginateModel, Document as MongooseDocument, PassportLocalModel } from import { Access } from '../../config/types'; import { Field } from '../../fields/config/types'; import { Document } from '../../types'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; import { IncomingAuthType, Auth } from '../../auth/types'; import { IncomingUploadType, Upload } from '../../uploads/types'; diff --git a/src/collections/requestHandlers/create.ts b/src/collections/requestHandlers/create.ts index 41c93319fc..6dfb85bc7f 100644 --- a/src/collections/requestHandlers/create.ts +++ b/src/collections/requestHandlers/create.ts @@ -1,11 +1,9 @@ import httpStatus from 'http-status'; import { Response, NextFunction } from 'express'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; import formatSuccessResponse from '../../express/responses/formatSuccess'; import { Document } from '../../types'; -export type CreateRequestHandler = (req: PayloadRequest, res: Response, next: NextFunction) => unknown; - export type CreateResult = { message: string doc: Document diff --git a/src/collections/requestHandlers/delete.ts b/src/collections/requestHandlers/delete.ts index 413bd009c3..56e7c7579c 100644 --- a/src/collections/requestHandlers/delete.ts +++ b/src/collections/requestHandlers/delete.ts @@ -1,11 +1,9 @@ import { Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; import { NotFound } from '../../errors'; import { Document } from '../../types'; -export type DeleteRequestHandler = (req: PayloadRequest, res: Response, next: NextFunction) => unknown; - export type DeleteResult = { message: string; doc: Document; diff --git a/src/collections/requestHandlers/find.ts b/src/collections/requestHandlers/find.ts index f262d48451..def099aba6 100644 --- a/src/collections/requestHandlers/find.ts +++ b/src/collections/requestHandlers/find.ts @@ -1,9 +1,7 @@ import { Response, NextFunction } from 'express'; import httpStatus from 'http-status'; import { FindResponse } from '../../types'; -import { PayloadRequest } from '../../express/types/payloadRequest'; - -export type FindRequestHandler = (req: PayloadRequest, res: Response, next: NextFunction) => unknown; +import { PayloadRequest } from '../../express/types'; export type FindResult = FindResponse; diff --git a/src/collections/requestHandlers/findByID.ts b/src/collections/requestHandlers/findByID.ts index 7160b51eb8..d42d81e404 100644 --- a/src/collections/requestHandlers/findByID.ts +++ b/src/collections/requestHandlers/findByID.ts @@ -1,9 +1,7 @@ import { Response, NextFunction } from 'express'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; import { Document } from '../../types'; -export type FindByIDRequestHandler = (req: PayloadRequest, res: Response, next: NextFunction) => unknown; - export type FindByIDResult = { message: string; doc: Document; diff --git a/src/collections/requestHandlers/update.ts b/src/collections/requestHandlers/update.ts index 2976819161..ca1f7f259a 100644 --- a/src/collections/requestHandlers/update.ts +++ b/src/collections/requestHandlers/update.ts @@ -1,10 +1,8 @@ import { Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; import formatSuccessResponse from '../../express/responses/formatSuccess'; -export type UpdateRequestHandler = (req: PayloadRequest, res: Response, next: NextFunction) => unknown; - export type UpdateResult = { message: string doc: Document diff --git a/src/config/defaults.ts b/src/config/defaults.ts index 653a904f84..e9769d8022 100644 --- a/src/config/defaults.ts +++ b/src/config/defaults.ts @@ -42,6 +42,7 @@ export const defaults = { rateLimit: { window: 15 * 60 * 100, // 15min default, max: 500, + skip: undefined, }, express: { json: {}, diff --git a/src/config/types.ts b/src/config/types.ts index 6f7d0fa1a1..3aa788f5a7 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -3,11 +3,11 @@ import { DeepRequired } from 'ts-essentials'; import { Transporter } from 'nodemailer'; import { Configuration } from 'webpack'; import SMTPConnection from 'nodemailer/lib/smtp-connection'; -import { GraphQLType } from 'graphql'; +import GraphQL from 'graphql'; import { Payload } from '..'; import { AfterErrorHook, PayloadCollectionConfig, CollectionConfig } from '../collections/config/types'; -import { PayloadGlobalConfig } from '../globals/config/types'; -import { PayloadRequest } from '../express/types/payloadRequest'; +import { PayloadGlobalConfig, GlobalConfig } from '../globals/config/types'; +import { PayloadRequest } from '../express/types'; import InitializeGraphQL from '../graphql'; import { Where } from '../types'; @@ -79,7 +79,7 @@ export type PayloadConfig = { serverURL: string; cookiePrefix?: string; csrf?: string[]; - cors?: string[]; + cors?: string[] | '*'; publicENV?: { [key: string]: string }; routes?: { api?: string; @@ -121,10 +121,10 @@ export type PayloadConfig = { graphQL?: { mutations?: { [key: string]: unknown - } | ((graphQL: GraphQLType, payload: InitializeGraphQL) => any), + } | ((graphQL: typeof GraphQL, payload: InitializeGraphQL) => any), queries?: { [key: string]: unknown - } | ((graphQL: GraphQLType, payload: InitializeGraphQL) => any), + } | ((graphQL: typeof GraphQL, payload: InitializeGraphQL) => any), maxComplexity?: number; disablePlaygroundInProduction?: boolean; }; @@ -134,9 +134,11 @@ export type PayloadConfig = { afterError?: AfterErrorHook; }; webpack?: (config: Configuration) => Configuration; + middleware?: any[] serverModules?: string[]; }; export type Config = Omit, 'collections'> & { collections: CollectionConfig[] + globals: GlobalConfig[] } diff --git a/src/errors/ValidationError.ts b/src/errors/ValidationError.ts index 3977decf11..1dc5e51e7b 100644 --- a/src/errors/ValidationError.ts +++ b/src/errors/ValidationError.ts @@ -2,7 +2,7 @@ import httpStatus from 'http-status'; import APIError from './APIError'; class ValidationError extends APIError { - constructor(results: any[]) { + constructor(results: Record) { super(`Bad request with ${results.length} errors`, httpStatus.BAD_REQUEST, results); } } diff --git a/src/express/middleware/errorHandler.ts b/src/express/middleware/errorHandler.ts index d4b9a1a551..fd8bcac2bb 100644 --- a/src/express/middleware/errorHandler.ts +++ b/src/express/middleware/errorHandler.ts @@ -3,14 +3,14 @@ import { NextFunction, Response } from 'express'; import { Logger } from 'pino'; import { Config } from '../../config/types'; import formatErrorResponse, { ErrorResponse } from '../responses/formatError'; -import { PayloadRequest } from '../types/payloadRequest'; +import { PayloadRequest } from '../types'; import APIError from '../../errors/APIError'; -export type ErrorHandler = (err: Error, req: PayloadRequest, res: Response) => Promise | void> +export type ErrorHandler = (err: APIError, req: PayloadRequest, res: Response, next: NextFunction) => Promise | void> // NextFunction must be passed for Express to use this middleware as error handler // eslint-disable-next-line @typescript-eslint/no-unused-vars -const errorHandler = (config: Config, logger: Logger) => async (err: APIError, req: PayloadRequest, res: Response, next: NextFunction): Promise => { +const errorHandler = (config: Config, logger: Logger) => async (err: APIError, req: PayloadRequest, res: Response, next: NextFunction): Promise | void> => { let response = formatErrorResponse(err); let status = err.status || httpStatus.INTERNAL_SERVER_ERROR; diff --git a/src/express/middleware/index.ts b/src/express/middleware/index.ts index 9338331ce1..aa00403a2c 100644 --- a/src/express/middleware/index.ts +++ b/src/express/middleware/index.ts @@ -15,6 +15,7 @@ const middleware = (payload: Payload) => { const rateLimitOptions = { windowMs: payload.config.rateLimit.window, max: payload.config.rateLimit.max, + skip: undefined, }; if (typeof payload.config.rateLimit.skip === 'function') rateLimitOptions.skip = payload.config.rateLimit.skip; diff --git a/src/express/types/payloadRequest.ts b/src/express/types.ts similarity index 65% rename from src/express/types/payloadRequest.ts rename to src/express/types.ts index 668697facd..d2655928eb 100644 --- a/src/express/types/payloadRequest.ts +++ b/src/express/types.ts @@ -1,7 +1,7 @@ import { Request } from 'express'; -import { Payload } from '../../index'; -import { Collection } from '../../collections/config/types'; -import { User } from '../../auth/types'; +import { Payload } from '../index'; +import { Collection } from '../collections/config/types'; +import { User } from '../auth/types'; export type PayloadRequest = Request & { payload: Payload; diff --git a/src/fields/baseFields/baseUploadFields.ts b/src/fields/baseFields/baseUploadFields.ts index c9018addee..42a1d9db96 100644 --- a/src/fields/baseFields/baseUploadFields.ts +++ b/src/fields/baseFields/baseUploadFields.ts @@ -8,7 +8,7 @@ export default [ beforeChange: [ ({ req, operation, value }) => { if (operation === 'create') { - const file = (req.files && req.files.file) ? req.files.file : req.file; + const file = (req.files && req.files.file) ? req.files.file as { name: string } : req.file; return file.name; } diff --git a/src/fields/config/types.ts b/src/fields/config/types.ts index 89ffd6f642..32b2924113 100644 --- a/src/fields/config/types.ts +++ b/src/fields/config/types.ts @@ -1,7 +1,7 @@ /* eslint-disable no-use-before-define */ import { CSSProperties } from 'react'; import { Editor } from 'slate'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; import { Access } from '../../config/types'; import { Document } from '../../types'; diff --git a/src/globals/buildModel.ts b/src/globals/buildModel.ts index d39afdfbf0..a874d97e1f 100644 --- a/src/globals/buildModel.ts +++ b/src/globals/buildModel.ts @@ -1,9 +1,9 @@ import mongoose from 'mongoose'; import buildSchema from '../mongoose/buildSchema'; import localizationPlugin from '../localization/plugin'; -import { PayloadConfig } from '../config/types'; +import { Config } from '../config/types'; -const buildModel = (config: PayloadConfig): mongoose.PaginateModel | null => { +const buildModel = (config: Config): mongoose.PaginateModel | null => { if (config.globals && config.globals.length > 0) { const globalsSchema = new mongoose.Schema({}, { discriminatorKey: 'globalType', timestamps: true }); diff --git a/src/globals/config/types.ts b/src/globals/config/types.ts index d67a3bafc7..427f34640d 100644 --- a/src/globals/config/types.ts +++ b/src/globals/config/types.ts @@ -31,5 +31,5 @@ export type GlobalConfig = DeepRequired export type Globals = { Model: GlobalModel - config: GlobalConfig + config: GlobalConfig[] } diff --git a/src/globals/requestHandlers/findOne.ts b/src/globals/requestHandlers/findOne.ts index 4d621203a6..c96cf0fa0a 100644 --- a/src/globals/requestHandlers/findOne.ts +++ b/src/globals/requestHandlers/findOne.ts @@ -1,6 +1,6 @@ import { Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; import { GlobalConfig } from '../config/types'; import { Document } from '../../types'; diff --git a/src/globals/requestHandlers/update.ts b/src/globals/requestHandlers/update.ts index 57aafb5604..3c42546c48 100644 --- a/src/globals/requestHandlers/update.ts +++ b/src/globals/requestHandlers/update.ts @@ -1,6 +1,6 @@ import { Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -import { PayloadRequest } from '../../express/types/payloadRequest'; +import { PayloadRequest } from '../../express/types'; import { GlobalConfig } from '../config/types'; import { Document } from '../../types'; diff --git a/src/init/bindResolvers.ts b/src/graphql/bindResolvers.ts similarity index 75% rename from src/init/bindResolvers.ts rename to src/graphql/bindResolvers.ts index 59482bd6b7..a61b2d1775 100644 --- a/src/init/bindResolvers.ts +++ b/src/graphql/bindResolvers.ts @@ -17,8 +17,35 @@ import deleteResolver from '../collections/graphql/resolvers/delete'; import findOne from '../globals/graphql/resolvers/findOne'; import globalUpdate from '../globals/graphql/resolvers/update'; + import { Payload } from '../index'; +export type GraphQLResolvers = { + collections: { + create: typeof create, + find: typeof find, + findByID: typeof findByID, + update: typeof update, + deleteResolver: typeof deleteResolver, + auth: { + access: typeof access, + forgotPassword: typeof forgotPassword, + init: typeof init, + login: typeof login, + logout: typeof logout, + me: typeof me, + refresh: typeof refresh, + resetPassword: typeof resetPassword, + verifyEmail: typeof verifyEmail, + unlock: typeof unlock, + } + } + globals: { + findOne: typeof findOne + update: typeof globalUpdate, + } +} + function bindResolvers(ctx: Payload): void { ctx.graphQL = { resolvers: { diff --git a/src/graphql/errorHandler.ts b/src/graphql/errorHandler.ts index cff9cd92f2..d71e8f85a7 100644 --- a/src/graphql/errorHandler.ts +++ b/src/graphql/errorHandler.ts @@ -15,6 +15,7 @@ const errorHandler = async (info, debug, afterErrorHook) => Promise.all(info.res let response = { message: err.message, data: (err && err.originalError && err.originalError.data) || undefined, + stack: undefined, }; if (afterErrorHook) { diff --git a/src/index.ts b/src/index.ts index b0d5f5bda7..45ee47bf74 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,7 +23,6 @@ import { import Logger from './utilities/logger'; import bindOperations from './init/bindOperations'; import bindRequestHandlers, { RequestHandlers } from './init/bindRequestHandlers'; -import bindResolvers from './init/bindResolvers'; import loadConfig from './config/load'; import authenticate, { PayloadAuthenticate } from './express/middleware/authenticate'; import connectMongoose from './mongoose/connect'; @@ -36,6 +35,7 @@ import { Globals } from './globals/config/types'; import initGraphQLPlayground from './graphql/initPlayground'; import initStatic from './express/static'; import GraphQL from './graphql'; +import bindResolvers, { GraphQLResolvers } from './graphql/bindResolvers'; import buildEmail from './email/build'; import identifyAPI from './express/middleware/identifyAPI'; import errorHandler, { ErrorHandler } from './express/middleware/errorHandler'; @@ -44,7 +44,7 @@ import localOperations from './collections/operations/local'; import localGlobalOperations from './globals/operations/local'; import { encrypt, decrypt } from './auth/crypto'; import { MockEmailHandler, BuildEmailResult, Message } from './email/types'; -import { PayloadRequest } from './express/types/payloadRequest'; +import { PayloadRequest } from './express/types'; require('isomorphic-fetch'); @@ -56,7 +56,9 @@ export class Payload { collections: Collection[] = []; - graphQL: GraphQL; + graphQL: { + resolvers: GraphQLResolvers + }; globals: Globals; diff --git a/src/init/bindRequestHandlers.ts b/src/init/bindRequestHandlers.ts index 380ac58936..b409bb4dff 100644 --- a/src/init/bindRequestHandlers.ts +++ b/src/init/bindRequestHandlers.ts @@ -1,4 +1,4 @@ -import access, { AccessRequestHandler } from '../auth/requestHandlers/access'; +import access from '../auth/requestHandlers/access'; import forgotPassword from '../auth/requestHandlers/forgotPassword'; import init from '../auth/requestHandlers/init'; import login from '../auth/requestHandlers/login'; @@ -10,11 +10,11 @@ import resetPassword from '../auth/requestHandlers/resetPassword'; import verifyEmail from '../auth/requestHandlers/verifyEmail'; import unlock from '../auth/requestHandlers/unlock'; -import create, { CreateRequestHandler } from '../collections/requestHandlers/create'; -import find, { FindRequestHandler } from '../collections/requestHandlers/find'; -import findByID, { FindByIDRequestHandler } from '../collections/requestHandlers/findByID'; -import update, { UpdateRequestHandler } from '../collections/requestHandlers/update'; -import deleteHandler, { DeleteRequestHandler } from '../collections/requestHandlers/delete'; +import create from '../collections/requestHandlers/create'; +import find from '../collections/requestHandlers/find'; +import findByID from '../collections/requestHandlers/findByID'; +import update from '../collections/requestHandlers/update'; +import deleteHandler from '../collections/requestHandlers/delete'; import findOne from '../globals/requestHandlers/findOne'; import globalUpdate from '../globals/requestHandlers/update'; @@ -22,14 +22,28 @@ import { Payload } from '../index'; export type RequestHandlers = { collections: { - create: CreateRequestHandler, - find: FindRequestHandler, - findByID: FindByIDRequestHandler, - update: UpdateRequestHandler, - delete: DeleteRequestHandler, + create: typeof create, + find: typeof find, + findByID: typeof findByID, + update: typeof update, + delete: typeof deleteHandler, auth: { - access: AccessRequestHandler, + access: typeof access, + forgotPassword: typeof forgotPassword, + init: typeof init, + login: typeof login, + logout: typeof logout, + me: typeof me, + refresh: typeof refresh + registerFirstUser: typeof registerFirstUser, + resetPassword: typeof resetPassword, + verifyEmail: typeof verifyEmail, + unlock: typeof unlock, } + }, + globals: { + findOne: typeof findOne, + update: typeof globalUpdate, } } diff --git a/src/localization/formatRefPathLocales.ts b/src/localization/formatRefPathLocales.ts index e0c2f96e5b..eeb6fb8154 100644 --- a/src/localization/formatRefPathLocales.ts +++ b/src/localization/formatRefPathLocales.ts @@ -1,4 +1,4 @@ -export default function formatRefPathLocales(schema, parentSchema, parentPath) { +export default function formatRefPathLocales(schema, parentSchema?: any, parentPath?: string): void { // Loop through all refPaths within schema schema.eachPath((pathname, schemaType) => { // If a dynamic refPath is found diff --git a/src/localization/plugin.ts b/src/localization/plugin.ts index 1998958290..40eba807f5 100644 --- a/src/localization/plugin.ts +++ b/src/localization/plugin.ts @@ -5,7 +5,7 @@ import mongoose from 'mongoose'; import sanitizeFallbackLocale from './sanitizeFallbackLocale'; import formatRefPathLocales from './formatRefPathLocales'; -export default function localizationPlugin(schema, options) { +export default function localizationPlugin(schema: any, options): void { if (!options || !options.locales || !Array.isArray(options.locales) || !options.locales.length) { throw new mongoose.Error('Required locales array is missing'); } @@ -160,4 +160,4 @@ export default function localizationPlugin(schema, options) { // Find any dynamic {{LOCALE}} in refPaths and modify schemas appropriately formatRefPathLocales(schema); -}; +} diff --git a/src/mongoose/buildSchema.ts b/src/mongoose/buildSchema.ts index b943e4fe2b..93a8c7dade 100644 --- a/src/mongoose/buildSchema.ts +++ b/src/mongoose/buildSchema.ts @@ -3,6 +3,8 @@ import { Schema, SchemaDefinition } from 'mongoose'; import { MissingFieldInputOptions } from '../errors'; import { ArrayField, Block, BlockField, Field, GroupField, RadioField, RelationshipField, RowField, SelectField, UploadField } from '../fields/config/types'; +type FieldSchemaGenerator = (field: Field, fields: SchemaDefinition) => SchemaDefinition; + const setBlockDiscriminators = (fields: Field[], schema: Schema) => { fields.forEach((field) => { const blockFieldType = field as BlockField; @@ -11,7 +13,7 @@ const setBlockDiscriminators = (fields: Field[], schema: Schema) => { let blockSchemaFields = {}; blockItem.fields.forEach((blockField) => { - const fieldSchema = fieldToSchemaMap[blockField.type]; + const fieldSchema: FieldSchemaGenerator = fieldToSchemaMap[blockField.type]; if (fieldSchema) { blockSchemaFields = fieldSchema(blockField, blockSchemaFields); } @@ -46,7 +48,7 @@ const buildSchema = (configFields: Field[], options = {}): Schema => { let fields = {}; configFields.forEach((field) => { - const fieldSchema = fieldToSchemaMap[field.type]; + const fieldSchema: FieldSchemaGenerator = fieldToSchemaMap[field.type]; if (fieldSchema) { fields = fieldSchema(field, fields); @@ -155,7 +157,7 @@ const fieldToSchemaMap = { const newFields = { ...fields }; field.fields.forEach((rowField: Field) => { - const fieldSchemaMap = fieldToSchemaMap[rowField.type]; + const fieldSchemaMap: FieldSchemaGenerator = fieldToSchemaMap[rowField.type]; if (fieldSchemaMap) { const fieldSchema = fieldSchemaMap(rowField, fields); diff --git a/src/types/index.ts b/src/types/index.ts index 92a2087042..1570162bc9 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,13 +1,3 @@ -import { Response } from 'express'; -import { AuthCollection, Collection } from '../collections/config/types'; -import { PayloadRequest } from '../express/types/payloadRequest'; -import { Field } from '../fields/config/types'; -import { Payload } from '../index'; - -export { PayloadCollectionConfig } from '../collections/config/types'; - -export { FieldHook } from '../fields/config/types'; - export type Where = { [key: string]: unknown } @@ -15,110 +5,6 @@ export type Where = { // eslint-disable-next-line @typescript-eslint/no-explicit-any export type Document = any; -export type CreateOptions = { - collection: string; - data: { - [key: string]: unknown - }; -}; - -export type FindOptions = { - collection: string; - where?: { [key: string]: unknown }; - depth?: number; - limit?: number; - sort?: string; -}; - -export type FindResponse = { - docs: Document[]; - totalDocs: number; - limit: number; - totalPages: number; - page: number; - pagingCounter: number; - hasPrevPage: boolean; - hasNextPage: boolean; - prevPage: number | null; - nextPage: number | null; -}; - -export type FindGlobalOptions = { - global: string; -}; -export type UpdateGlobalOptions = { - global: string; - data: { - [key: string]: unknown - }; -}; - -export type FindByIDOptions = { - collection: string; - id: string; -}; -export type UpdateOptions = { - collection: string; - id: string; - data: { - [key: string]: unknown - }; -}; - -export type DeleteOptions = { - collection: string; - id: string; -}; - -export type ForgotPasswordOptions = { - collection: string; - generateEmailHTML?: (token: string) => string; - expiration: Date; - data: { - [key: string]: unknown - }; -}; - -export interface OperationArguments { - collection: Collection; - data?: {[key: string]: unknown}; - originalDoc?: Document; - fullOriginalDoc?: {[key: string]: unknown}; - fullData?: {[key: string]: unknown}; - operation?: unknown; - hook?: string; - req?: PayloadRequest; - res?: Response; - id?: string; - overrideAccess?: boolean; - reduceLocales?: boolean; - showHiddenFields?: boolean; - currentDepth?: number; - depth?: number | string; - fields?: Field[]; - field?: Field; - payload?: Payload; - path?: string; - locale?: string; - fallbackLocale?: string; - accessPromises?: Promise[]; - hookPromises?: Promise[]; - relationshipPopulations?: any[]; - performFieldOperations?: Promise; - validationPromises?: any[]; - errors?: { message: any; field: string }[]; - newData?: {[key: string]: any}; - existingData?: {[key: string]: any}; - dataReference?: {[key: string]: any}; - index?: number | string; -} - -export type AuthOperationArguments = Omit & { - collection: AuthCollection; - disableEmail?: boolean; - expiration?: Date; -} - export type Operator = 'equals' | 'not_equals' | 'in' diff --git a/src/webpack/getWebpackDevConfig.ts b/src/webpack/getWebpackDevConfig.ts index 7e7255e48c..41adf90bb8 100644 --- a/src/webpack/getWebpackDevConfig.ts +++ b/src/webpack/getWebpackDevConfig.ts @@ -2,12 +2,12 @@ import HtmlWebpackPlugin from 'html-webpack-plugin'; import path from 'path'; import webpack, { Configuration } from 'webpack'; import babelConfig from '../babel.config'; -import { PayloadConfig } from '../config/types'; +import { Config } from '../config/types'; const mockModulePath = path.resolve(__dirname, './mocks/emptyModule.js'); const mockDotENVPath = path.resolve(__dirname, './mocks/dotENV.js'); -export default (config: PayloadConfig): Configuration => { +export default (config: Config): Configuration => { let webpackConfig: Configuration = { entry: { main: [ diff --git a/src/webpack/init.ts b/src/webpack/init.ts index 00926604f4..a1407a163a 100644 --- a/src/webpack/init.ts +++ b/src/webpack/init.ts @@ -3,11 +3,11 @@ import express, { Router } from 'express'; import webpackDevMiddleware from 'webpack-dev-middleware'; import webpackHotMiddleware from 'webpack-hot-middleware'; import getWebpackDevConfig from './getWebpackDevConfig'; -import { PayloadConfig } from '../config/types'; +import { Config } from '../config/types'; const router = express.Router(); -function initWebpack(config: PayloadConfig): Router { +function initWebpack(config: Config): Router { const webpackDevConfig = getWebpackDevConfig(config); const compiler = webpack(webpackDevConfig);