chore: api handler adjustments
This commit is contained in:
@@ -5,7 +5,7 @@ import { isNumber } from 'payload/utilities'
|
||||
import { generatePayloadCookie } from '../../utilities/cookies'
|
||||
|
||||
export const login = async ({ req }: { req: PayloadRequest }): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
|
||||
const result = await loginOperation({
|
||||
|
||||
@@ -5,7 +5,7 @@ import { generatePayloadCookie } from '../../utilities/cookies'
|
||||
import { PayloadRequest } from 'payload/types'
|
||||
|
||||
export const resetPassword = async ({ req }: { req: PayloadRequest }): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
|
||||
const result = await resetPasswordOperation({
|
||||
|
||||
@@ -6,7 +6,7 @@ import { isNumber } from 'payload/utilities'
|
||||
import { createOperation } from 'payload/operations'
|
||||
|
||||
export const create = async ({ req }: { req: PayloadRequest }): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const autosave = searchParams.get('autosave') === 'true'
|
||||
const draft = searchParams.get('draft') === 'true'
|
||||
const depth = searchParams.get('depth')
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getTranslation } from '@payloadcms/translations'
|
||||
import { deleteOperation } from 'payload/operations'
|
||||
|
||||
export const deleteDoc = async ({ req }: { req: PayloadRequest }): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
const where = searchParams.get('where')
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ export const deleteByID = async ({
|
||||
req: PayloadRequest
|
||||
id: string
|
||||
}): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
const doc = await deleteByIDOperation({
|
||||
id,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { isNumber } from 'payload/utilities'
|
||||
import { findOperation } from 'payload/operations'
|
||||
|
||||
export const find = async ({ req }: { req: PayloadRequest }): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
|
||||
const depth = searchParams.get('depth')
|
||||
const limit = searchParams.get('limit')
|
||||
|
||||
@@ -11,7 +11,7 @@ export const findByID = async ({
|
||||
req: PayloadRequest
|
||||
id: string
|
||||
}): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
|
||||
const result = await findByIDOperation({
|
||||
|
||||
@@ -11,7 +11,7 @@ export const findVersionByID = async ({
|
||||
req: PayloadRequest
|
||||
id: string
|
||||
}): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
|
||||
const result = await findVersionByIDOperation({
|
||||
|
||||
@@ -11,7 +11,7 @@ export const findVersions = async ({
|
||||
req: PayloadRequest
|
||||
id: string
|
||||
}): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const page = searchParams.get('page')
|
||||
const depth = searchParams.get('depth')
|
||||
const limit = searchParams.get('limit')
|
||||
|
||||
@@ -11,7 +11,7 @@ export const restoreVersion = async ({
|
||||
req: PayloadRequest
|
||||
id: string
|
||||
}): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
|
||||
const result = await restoreVersionOperation({
|
||||
|
||||
@@ -7,7 +7,7 @@ import { updateOperation } from 'payload/operations'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
|
||||
export const update = async ({ req }: { req: PayloadRequest }): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
const where = searchParams.get('where')
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ export const updateByID = async ({
|
||||
req: PayloadRequest
|
||||
id: string
|
||||
}): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
const autosave = searchParams.get('autosave') === 'true'
|
||||
const draft = searchParams.get('draft') === 'true'
|
||||
|
||||
@@ -12,7 +12,7 @@ export const findOne = async ({
|
||||
req: PayloadRequest
|
||||
globalConfig: SanitizedGlobalConfig
|
||||
}): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
|
||||
const result = await findOneOperation({
|
||||
|
||||
@@ -14,7 +14,7 @@ export const findVersionByID = async ({
|
||||
globalConfig: SanitizedGlobalConfig
|
||||
id: string
|
||||
}): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
|
||||
const result = await findVersionByIDOperationGlobal({
|
||||
|
||||
@@ -12,7 +12,7 @@ export const findVersions = async ({
|
||||
req: PayloadRequest
|
||||
globalConfig: SanitizedGlobalConfig
|
||||
}): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const page = searchParams.get('page')
|
||||
const limit = searchParams.get('limit')
|
||||
const depth = searchParams.get('depth')
|
||||
|
||||
@@ -14,7 +14,7 @@ export const restoreVersion = async ({
|
||||
globalConfig: SanitizedGlobalConfig
|
||||
id: string
|
||||
}): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
|
||||
const doc = await restoreVersionOperationGlobal({
|
||||
|
||||
@@ -12,7 +12,7 @@ export const update = async ({
|
||||
req: PayloadRequest
|
||||
globalConfig: SanitizedGlobalConfig
|
||||
}): Promise<Response> => {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const depth = searchParams.get('depth')
|
||||
const draft = searchParams.get('draft') === 'true'
|
||||
const autosave = searchParams.get('autosave') === 'true'
|
||||
|
||||
@@ -92,17 +92,15 @@ const endpoints = {
|
||||
const handleCustomEndpoints = ({
|
||||
entitySlug,
|
||||
endpoints,
|
||||
originalRequest,
|
||||
payloadRequest,
|
||||
}: {
|
||||
entitySlug?: string
|
||||
endpoints: Endpoint[]
|
||||
originalRequest: Request
|
||||
payloadRequest: PayloadRequest
|
||||
}): Promise<Response> => {
|
||||
}): Promise<Response> | Response => {
|
||||
if (endpoints && endpoints.length > 0) {
|
||||
let handlerParams = {}
|
||||
const { pathname } = new URL(payloadRequest.url)
|
||||
const { pathname } = payloadRequest
|
||||
const pathPrefix =
|
||||
payloadRequest.payload.config.routes.api + (entitySlug ? `/${entitySlug}` : '')
|
||||
|
||||
@@ -121,8 +119,8 @@ const handleCustomEndpoints = ({
|
||||
|
||||
if (customEndpoint) {
|
||||
return customEndpoint.handler({
|
||||
req: customEndpoint.root && originalRequest ? originalRequest : payloadRequest,
|
||||
params: handlerParams,
|
||||
req: payloadRequest,
|
||||
routeParams: handlerParams,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -134,7 +132,6 @@ export const GET = async (
|
||||
request: Request,
|
||||
{ params: { slug } }: { params: { slug: string[] } },
|
||||
) => {
|
||||
const originalRequest = request.clone()
|
||||
const [slug1, slug2, slug3, slug4] = slug
|
||||
|
||||
try {
|
||||
@@ -150,7 +147,6 @@ export const GET = async (
|
||||
const customEndpointResponse = await handleCustomEndpoints({
|
||||
entitySlug: slug1,
|
||||
payloadRequest: req,
|
||||
originalRequest,
|
||||
endpoints: req.collection.config?.endpoints || [],
|
||||
})
|
||||
if (customEndpointResponse) return customEndpointResponse
|
||||
@@ -186,7 +182,6 @@ export const GET = async (
|
||||
const customEndpointResponse = await handleCustomEndpoints({
|
||||
entitySlug: `${slug1}/${slug2}`,
|
||||
payloadRequest: req,
|
||||
originalRequest,
|
||||
endpoints: globalConfig?.endpoints || [],
|
||||
})
|
||||
if (customEndpointResponse) return customEndpointResponse
|
||||
@@ -210,7 +205,6 @@ export const GET = async (
|
||||
// root routes
|
||||
const customEndpointResponse = await handleCustomEndpoints({
|
||||
payloadRequest: req,
|
||||
originalRequest,
|
||||
endpoints: req.payload.config.endpoints,
|
||||
})
|
||||
if (customEndpointResponse) return customEndpointResponse
|
||||
@@ -230,7 +224,6 @@ export const POST = async (
|
||||
request: Request,
|
||||
{ params: { slug } }: { params: { slug: string[] } },
|
||||
) => {
|
||||
const originalRequest = request.clone()
|
||||
const [slug1, slug2, slug3, slug4] = slug
|
||||
|
||||
try {
|
||||
@@ -240,7 +233,6 @@ export const POST = async (
|
||||
const customEndpointResponse = await handleCustomEndpoints({
|
||||
entitySlug: slug1,
|
||||
payloadRequest: req,
|
||||
originalRequest,
|
||||
endpoints: req.collection.config?.endpoints || [],
|
||||
})
|
||||
if (customEndpointResponse) return customEndpointResponse
|
||||
@@ -276,7 +268,6 @@ export const POST = async (
|
||||
const customEndpointResponse = await handleCustomEndpoints({
|
||||
entitySlug: `${slug1}/${slug2}`,
|
||||
payloadRequest: req,
|
||||
originalRequest,
|
||||
endpoints: globalConfig?.endpoints || [],
|
||||
})
|
||||
if (customEndpointResponse) return customEndpointResponse
|
||||
@@ -299,7 +290,6 @@ export const POST = async (
|
||||
// root routes
|
||||
const customEndpointResponse = await handleCustomEndpoints({
|
||||
payloadRequest: req,
|
||||
originalRequest,
|
||||
endpoints: req.payload.config.endpoints,
|
||||
})
|
||||
if (customEndpointResponse) return customEndpointResponse
|
||||
@@ -313,7 +303,6 @@ export const DELETE = async (
|
||||
request: Request,
|
||||
{ params: { slug } }: { params: { slug: string[] } },
|
||||
) => {
|
||||
const originalRequest = request.clone()
|
||||
const [slug1, slug2] = slug
|
||||
|
||||
try {
|
||||
@@ -329,7 +318,6 @@ export const DELETE = async (
|
||||
const customEndpointResponse = await handleCustomEndpoints({
|
||||
entitySlug: slug1,
|
||||
payloadRequest: req,
|
||||
originalRequest,
|
||||
endpoints: req.collection.config?.endpoints || [],
|
||||
})
|
||||
if (customEndpointResponse) return customEndpointResponse
|
||||
@@ -348,7 +336,6 @@ export const DELETE = async (
|
||||
// root routes
|
||||
const customEndpointResponse = await handleCustomEndpoints({
|
||||
payloadRequest: req,
|
||||
originalRequest,
|
||||
endpoints: req.payload.config.endpoints,
|
||||
})
|
||||
if (customEndpointResponse) return customEndpointResponse
|
||||
@@ -362,7 +349,6 @@ export const PATCH = async (
|
||||
request: Request,
|
||||
{ params: { slug } }: { params: { slug: string[] } },
|
||||
) => {
|
||||
const originalRequest = request.clone()
|
||||
const [slug1, slug2] = slug
|
||||
|
||||
try {
|
||||
@@ -378,7 +364,6 @@ export const PATCH = async (
|
||||
const customEndpointResponse = await handleCustomEndpoints({
|
||||
entitySlug: slug1,
|
||||
payloadRequest: req,
|
||||
originalRequest,
|
||||
endpoints: req.collection.config?.endpoints || [],
|
||||
})
|
||||
if (customEndpointResponse) return customEndpointResponse
|
||||
@@ -397,7 +382,6 @@ export const PATCH = async (
|
||||
// root routes
|
||||
const customEndpointResponse = await handleCustomEndpoints({
|
||||
payloadRequest: req,
|
||||
originalRequest,
|
||||
endpoints: req.payload.config.endpoints,
|
||||
})
|
||||
if (customEndpointResponse) return customEndpointResponse
|
||||
|
||||
@@ -82,6 +82,8 @@ export const createPayloadRequest = async ({
|
||||
transactionID: undefined,
|
||||
payloadDataLoader: undefined,
|
||||
payloadUploadSizes: {},
|
||||
searchParams,
|
||||
pathname,
|
||||
}
|
||||
|
||||
const req: PayloadRequest = Object.assign(request, customRequest)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import type { NextFunction, Response } from 'express'
|
||||
|
||||
import { URL } from 'url'
|
||||
|
||||
import type { SanitizedCollectionConfig } from '../collections/config/types'
|
||||
import type { PayloadRequest } from '../types'
|
||||
import type { Where } from '../types'
|
||||
@@ -17,7 +15,7 @@ const getExecuteStaticAccess =
|
||||
}
|
||||
|
||||
try {
|
||||
const { pathname } = new URL(req.url)
|
||||
const { pathname } = req
|
||||
if (pathname) {
|
||||
const accessResult = await executeAccess({ req }, config.access.read)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import jwt from 'jsonwebtoken'
|
||||
import { URL } from 'url'
|
||||
|
||||
import type { Collection } from '../../collections/config/types'
|
||||
import type { PayloadRequest } from '../../types'
|
||||
@@ -28,8 +27,8 @@ export const meOperation = async ({
|
||||
}
|
||||
|
||||
if (req.user) {
|
||||
const parsedURL = new URL(req.url)
|
||||
const isGraphQL = parsedURL.pathname === `/api${req.payload.config.routes.graphQL}`
|
||||
const { pathname } = req
|
||||
const isGraphQL = pathname === `/api${req.payload.config.routes.graphQL}`
|
||||
|
||||
const user = (await req.payload.findByID({
|
||||
id: req.user.id,
|
||||
|
||||
@@ -435,7 +435,7 @@ export interface SanitizedCollectionConfig
|
||||
'auth' | 'endpoints' | 'fields' | 'upload' | 'versions'
|
||||
> {
|
||||
auth: Auth
|
||||
endpoints: Omit<Endpoint, 'root'>[] | false
|
||||
endpoints: Endpoint[] | false
|
||||
fields: Field[]
|
||||
upload: Upload
|
||||
versions: SanitizedCollectionVersions
|
||||
|
||||
@@ -197,13 +197,15 @@ export type Access<T = any, U = any> = (
|
||||
) => AccessResult | Promise<AccessResult>
|
||||
|
||||
/** Equivalent to express middleware, but with an enhanced request object */
|
||||
export type PayloadHandler<T = PayloadRequest | Request> = ({
|
||||
params,
|
||||
export type PayloadHandler = ({
|
||||
req,
|
||||
routeParams,
|
||||
}: {
|
||||
params: Record<string, unknown>
|
||||
req: T
|
||||
}) => Promise<Response>
|
||||
req: PayloadRequest
|
||||
routeParams: {
|
||||
[key: string]: string
|
||||
}
|
||||
}) => Promise<Response> | Response
|
||||
|
||||
/**
|
||||
* Docs: https://payloadcms.com/docs/rest-api/overview#custom-endpoints
|
||||
@@ -211,7 +213,12 @@ export type PayloadHandler<T = PayloadRequest | Request> = ({
|
||||
export type Endpoint = {
|
||||
/** Extension point to add your custom data. */
|
||||
custom?: Record<string, any>
|
||||
handler: PayloadHandler<PayloadRequest>
|
||||
/**
|
||||
* Middleware that will be called when the path/method matches
|
||||
*
|
||||
* Compatible with Web Request/Response Model
|
||||
*/
|
||||
handler: PayloadHandler
|
||||
/** HTTP method (or "all") */
|
||||
method: 'connect' | 'delete' | 'get' | 'head' | 'options' | 'patch' | 'post' | 'put'
|
||||
/**
|
||||
@@ -220,34 +227,14 @@ export type Endpoint = {
|
||||
* Compatible with the Express router
|
||||
*/
|
||||
path: string
|
||||
} & (
|
||||
| {
|
||||
/**
|
||||
* Middleware that will be called when the path/method matches
|
||||
*
|
||||
* Compatible with Express middleware
|
||||
*/
|
||||
handler: PayloadHandler<PayloadRequest>
|
||||
/**
|
||||
* Set to `true` to disable the Payload middleware for this endpoint
|
||||
* @default false
|
||||
*/
|
||||
root?: false | undefined
|
||||
}
|
||||
| {
|
||||
/**
|
||||
* Middleware that will be called when the path/method matches
|
||||
*
|
||||
* Compatible with Express middleware
|
||||
*/
|
||||
handler: PayloadHandler<Request>
|
||||
/**
|
||||
* Set to `true` to disable the Payload middleware for this endpoint
|
||||
* @default false
|
||||
*/
|
||||
root: true
|
||||
}
|
||||
)
|
||||
/**
|
||||
* @deprecated in 3.0
|
||||
*
|
||||
* Please add "root" routes under the /api folder in the Payload Project.
|
||||
* https://nextjs.org/docs/app/api-reference/file-conventions/route
|
||||
*/
|
||||
root: never
|
||||
}
|
||||
|
||||
export type AdminViewConfig = {
|
||||
Component: AdminViewComponent
|
||||
|
||||
@@ -199,7 +199,7 @@ export type GlobalConfig = {
|
||||
|
||||
export interface SanitizedGlobalConfig
|
||||
extends Omit<DeepRequired<GlobalConfig>, 'endpoints' | 'fields' | 'versions'> {
|
||||
endpoints: Omit<Endpoint, 'root'>[] | false
|
||||
endpoints: Endpoint[] | false
|
||||
fields: Field[]
|
||||
versions: SanitizedGlobalVersions
|
||||
}
|
||||
|
||||
@@ -48,6 +48,13 @@ export type CustomPayloadRequest<U = any> = {
|
||||
* Only available for localized collections
|
||||
*/
|
||||
locale?: string
|
||||
/**
|
||||
* The URL path of the request
|
||||
*/
|
||||
pathname: null | string
|
||||
/**
|
||||
* The payload object
|
||||
*/
|
||||
payload: typeof payload
|
||||
/**
|
||||
* The context in which the request is being made
|
||||
@@ -57,6 +64,10 @@ export type CustomPayloadRequest<U = any> = {
|
||||
payloadDataLoader?: DataLoader<string, TypeWithID>
|
||||
/** Resized versions of the image that was uploaded during this request */
|
||||
payloadUploadSizes?: Record<string, Buffer>
|
||||
/**
|
||||
* The search parameters from the request URL
|
||||
*/
|
||||
searchParams: URLSearchParams
|
||||
/** Translate function - duplicate of i18n.t */
|
||||
t: TFunction
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,6 @@ import mkdirp from 'mkdirp'
|
||||
import path from 'path'
|
||||
import sanitize from 'sanitize-filename'
|
||||
import sharp from 'sharp'
|
||||
import { URL } from 'url'
|
||||
|
||||
import type { Collection } from '../collections/config/types'
|
||||
import type { SanitizedConfig } from '../config/types'
|
||||
@@ -54,7 +53,7 @@ export const generateFileData = async <T>({
|
||||
|
||||
let file = req.file
|
||||
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const uploadEdits = searchParams.get('uploadEdits') || {}
|
||||
|
||||
const { disableLocalStorage, formatOptions, imageSizes, resizeOptions, staticDir, trimOptions } =
|
||||
|
||||
@@ -55,6 +55,8 @@ export const createLocalReq: CreateLocalReq = (
|
||||
req.user = user || req?.user || null
|
||||
req.collection = collection ? payload.collections?.[collection] : null
|
||||
req.payloadDataLoader = req?.payloadDataLoader || getDataLoader(req)
|
||||
req.searchParams = req?.searchParams || new URLSearchParams()
|
||||
req.pathname = req?.pathname || null
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export async function getFilePrefix({
|
||||
req: PayloadRequest
|
||||
}): Promise<string> {
|
||||
const imageSizes = (collection?.upload as IncomingUploadType)?.imageSizes || []
|
||||
const { searchParams } = new URL(req.url)
|
||||
const { searchParams } = req
|
||||
const filename = searchParams.get('filename')
|
||||
|
||||
const files = await req.payload.find({
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
'use client'
|
||||
import { Modal, useModal } from '@faceless-ui/modal'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import type { Props, TogglerProps } from './types'
|
||||
|
||||
import { Gutter } from '../Gutter'
|
||||
import { EditDepthContext, useEditDepth } from '../../providers/EditDepth'
|
||||
import { X } from '../../icons/X'
|
||||
import { useTranslation } from '../..'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
@@ -51,7 +51,7 @@ export const Drawer: React.FC<Props> = ({
|
||||
slug,
|
||||
title,
|
||||
}) => {
|
||||
const { t } = useTranslation('general')
|
||||
const { t } = useTranslation()
|
||||
const { closeModal, modalState } = useModal()
|
||||
const drawerDepth = useEditDepth()
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
@@ -84,7 +84,7 @@ export const Drawer: React.FC<Props> = ({
|
||||
>
|
||||
{(!drawerDepth || drawerDepth === 1) && <div className={`${baseClass}__blur-bg`} />}
|
||||
<button
|
||||
aria-label={t('close')}
|
||||
aria-label={t('general:close')}
|
||||
className={`${baseClass}__close`}
|
||||
id={`close-drawer__${slug}`}
|
||||
onClick={() => closeModal(slug)}
|
||||
@@ -104,7 +104,7 @@ export const Drawer: React.FC<Props> = ({
|
||||
i.e. changing to a `div` element will fix the animation issue but will break accessibility
|
||||
*/}
|
||||
<button
|
||||
aria-label={t('close')}
|
||||
aria-label={t('general:close')}
|
||||
className={`${baseClass}__header__close`}
|
||||
id={`close-drawer__${slug}`}
|
||||
onClick={() => closeModal(slug)}
|
||||
|
||||
Reference in New Issue
Block a user