lays operation type pattern

This commit is contained in:
James
2020-12-26 16:25:58 -05:00
parent 569ce08174
commit cf32ee460c
50 changed files with 201 additions and 209 deletions

View File

@@ -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 {

View File

@@ -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<Permissions> {
type Arguments = {
req: PayloadRequest
}
async function accessOperation(args: Arguments): Promise<Permissions> {
const { config } = this;
const {

View File

@@ -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<string | null> {
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<string | null> {
const { config, sendEmail: email } = this;
if (!Object.prototype.hasOwnProperty.call(incomingArgs.data, 'email')) {

View File

@@ -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<Result> {
const {
collection: collectionSlug,
data,

View File

@@ -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<Result> {
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;

View File

@@ -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<LoginResponse> {
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<Result> {
const { config, operations, secret } = this;
let args = incomingArgs;

View File

@@ -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';

View File

@@ -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();

View File

@@ -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;

View File

@@ -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<any> {
try {

View File

@@ -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<any> {
try {

View File

@@ -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<any> {
try {

View File

@@ -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 {

View File

@@ -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<any> {
try {

View File

@@ -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<any> {
try {

View File

@@ -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<any> {
try {

View File

@@ -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<any> {
try {

View File

@@ -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<any> {
try {

View File

@@ -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<any> {
try {

View File

@@ -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';

View File

@@ -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> | string
type GenerateVerifyEmailSubject = (args: { req: PayloadRequest, token: string, user: any}) => Promise<string> | string
type GenerateForgotPasswordEmailHTML = (args?: { req?: PayloadRequest, token?: string, user?: string}) => Promise<string> | string
type GenerateForgotPasswordEmailHTML = (args?: { req?: PayloadRequest, token?: string, user?: unknown}) => Promise<string> | string
type GenerateForgotPasswordEmailSubject = (args?: { req?: PayloadRequest, token?: string, user?: any }) => Promise<string> | string
export interface IncomingAuthType {

View File

@@ -1,4 +1,4 @@
import { PayloadRequest } from '../../express/types/payloadRequest';
import { PayloadRequest } from '../../express/types';
export const defaults = {
access: {

View File

@@ -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';

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -42,6 +42,7 @@ export const defaults = {
rateLimit: {
window: 15 * 60 * 100, // 15min default,
max: 500,
skip: undefined,
},
express: {
json: {},

View File

@@ -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<DeepRequired<PayloadConfig>, 'collections'> & {
collections: CollectionConfig[]
globals: GlobalConfig[]
}

View File

@@ -2,7 +2,7 @@ import httpStatus from 'http-status';
import APIError from './APIError';
class ValidationError extends APIError {
constructor(results: any[]) {
constructor(results: Record<string, unknown>) {
super(`Bad request with ${results.length} errors`, httpStatus.BAD_REQUEST, results);
}
}

View File

@@ -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<Response<ErrorResponse> | void>
export type ErrorHandler = (err: APIError, req: PayloadRequest, res: Response, next: NextFunction) => Promise<Response<ErrorResponse> | 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<void> => {
const errorHandler = (config: Config, logger: Logger) => async (err: APIError, req: PayloadRequest, res: Response, next: NextFunction): Promise<Response<ErrorResponse> | void> => {
let response = formatErrorResponse(err);
let status = err.status || httpStatus.INTERNAL_SERVER_ERROR;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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';

View File

@@ -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<any> | null => {
const buildModel = (config: Config): mongoose.PaginateModel<any> | null => {
if (config.globals && config.globals.length > 0) {
const globalsSchema = new mongoose.Schema({}, { discriminatorKey: 'globalType', timestamps: true });

View File

@@ -31,5 +31,5 @@ export type GlobalConfig = DeepRequired<PayloadGlobalConfig>
export type Globals = {
Model: GlobalModel
config: GlobalConfig
config: GlobalConfig[]
}

View File

@@ -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';

View File

@@ -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';

View File

@@ -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: {

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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,
}
}

View File

@@ -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

View File

@@ -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);
};
}

View File

@@ -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);

View File

@@ -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<void>[];
hookPromises?: Promise<void>[];
relationshipPopulations?: any[];
performFieldOperations?: Promise<Document>;
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<OperationArguments, 'collection'> & {
collection: AuthCollection;
disableEmail?: boolean;
expiration?: Date;
}
export type Operator = 'equals'
| 'not_equals'
| 'in'

View File

@@ -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: [

View File

@@ -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);