Compare commits
1 Commits
fix/join-h
...
feat/serve
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09d29a6ec9 |
37
.github/CODEOWNERS
vendored
Normal file
37
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# Order matters. The last matching pattern takes precedence.
|
||||
|
||||
### Package Exports
|
||||
|
||||
**/exports/ @denolfe @jmikrut @DanRibbens
|
||||
|
||||
### Packages
|
||||
|
||||
/packages/plugin-cloud*/src/ @denolfe @jmikrut @DanRibbens
|
||||
/packages/email-*/src/ @denolfe @jmikrut @DanRibbens
|
||||
/packages/live-preview*/src/ @jacobsfletch
|
||||
/packages/plugin-stripe/src/ @jacobsfletch
|
||||
/packages/plugin-multi-tenant/src/ @JarrodMFlesch
|
||||
/packages/richtext-*/src/ @AlessioGr
|
||||
/packages/next/src/ @jmikrut @jacobsfletch @AlessioGr @JarrodMFlesch
|
||||
/packages/ui/src/ @jmikrut @jacobsfletch @AlessioGr @JarrodMFlesch
|
||||
/packages/storage-*/src/ @denolfe @jmikrut @DanRibbens
|
||||
/packages/create-payload-app/src/ @denolfe @jmikrut @DanRibbens
|
||||
/packages/eslint-*/ @denolfe @jmikrut @DanRibbens @AlessioGr
|
||||
|
||||
### Templates
|
||||
|
||||
/templates/_data/ @denolfe @jmikrut @DanRibbens
|
||||
/templates/_template/ @denolfe @jmikrut @DanRibbens
|
||||
|
||||
### Build Files
|
||||
|
||||
**/tsconfig*.json @denolfe @jmikrut @DanRibbens @AlessioGr
|
||||
**/jest.config.js @denolfe @jmikrut @DanRibbens @AlessioGr
|
||||
|
||||
### Root
|
||||
|
||||
/package.json @denolfe @jmikrut @DanRibbens
|
||||
/tools/ @denolfe @jmikrut @DanRibbens
|
||||
/.husky/ @denolfe @jmikrut @DanRibbens
|
||||
/.vscode/ @denolfe @jmikrut @DanRibbens @AlessioGr
|
||||
/.github/ @denolfe @jmikrut @DanRibbens
|
||||
@@ -11,7 +11,7 @@ import { DefaultListView, HydrateAuthProvider, ListQueryProvider } from '@payloa
|
||||
import { RenderServerComponent } from '@payloadcms/ui/elements/RenderServerComponent'
|
||||
import { renderFilters, renderTable, upsertPreferences } from '@payloadcms/ui/rsc'
|
||||
import { formatAdminURL, mergeListSearchAndWhere } from '@payloadcms/ui/shared'
|
||||
import { notFound } from 'next/navigation.js'
|
||||
import { notFound, redirect } from 'next/navigation.js'
|
||||
import { isNumber } from 'payload/shared'
|
||||
import React, { Fragment } from 'react'
|
||||
|
||||
@@ -71,12 +71,13 @@ export const renderListView = async (
|
||||
}
|
||||
|
||||
const query = queryFromArgs || queryFromReq
|
||||
const limitFromQuery = isNumber(query?.limit) ? Number(query.limit) : undefined
|
||||
|
||||
const listPreferences = await upsertPreferences<ListPreferences>({
|
||||
key: `${collectionSlug}-list`,
|
||||
req,
|
||||
value: {
|
||||
limit: isNumber(query?.limit) ? Number(query.limit) : undefined,
|
||||
limit: limitFromQuery,
|
||||
sort: query?.sort as string,
|
||||
},
|
||||
})
|
||||
@@ -238,6 +239,19 @@ export const renderListView = async (
|
||||
}
|
||||
|
||||
export const ListView: React.FC<RenderListViewArgs> = async (args) => {
|
||||
const {
|
||||
initPageResult: { collectionConfig, req },
|
||||
} = args
|
||||
|
||||
if (!req.query?.limit) {
|
||||
return redirect(
|
||||
`${req.url}?${new URLSearchParams({
|
||||
...req.query,
|
||||
limit: String(collectionConfig.admin.pagination.defaultLimit),
|
||||
}).toString()}`,
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
const { List: RenderedList } = await renderListView({ ...args, enableRowSelections: true })
|
||||
return RenderedList
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
import type * as AWS from '@aws-sdk/client-s3'
|
||||
import type { CognitoUserSession } from 'amazon-cognito-identity-js'
|
||||
|
||||
import type { GetStorageClient } from './refreshSession.js'
|
||||
import { CognitoIdentityClient } from '@aws-sdk/client-cognito-identity'
|
||||
import * as AWS from '@aws-sdk/client-s3'
|
||||
import { fromCognitoIdentityPool } from '@aws-sdk/credential-providers'
|
||||
|
||||
import { refreshSession } from './refreshSession.js'
|
||||
import { authAsCognitoUser } from './authAsCognitoUser.js'
|
||||
|
||||
export let storageClient: AWS.S3 | null = null
|
||||
export let session: CognitoUserSession | null = null
|
||||
export let identityID: string
|
||||
export type GetStorageClient = () => Promise<{
|
||||
identityID: string
|
||||
storageClient: AWS.S3
|
||||
}>
|
||||
|
||||
let storageClient: AWS.S3 | null = null
|
||||
let session: CognitoUserSession | null = null
|
||||
let identityID: string
|
||||
|
||||
export const getStorageClient: GetStorageClient = async () => {
|
||||
if (storageClient && session?.isValid()) {
|
||||
@@ -17,8 +23,6 @@ export const getStorageClient: GetStorageClient = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
;({ identityID, session, storageClient } = await refreshSession())
|
||||
|
||||
if (!process.env.PAYLOAD_CLOUD_PROJECT_ID) {
|
||||
throw new Error('PAYLOAD_CLOUD_PROJECT_ID is required')
|
||||
}
|
||||
@@ -29,6 +33,34 @@ export const getStorageClient: GetStorageClient = async () => {
|
||||
throw new Error('PAYLOAD_CLOUD_COGNITO_IDENTITY_POOL_ID is required')
|
||||
}
|
||||
|
||||
session = await authAsCognitoUser(
|
||||
process.env.PAYLOAD_CLOUD_PROJECT_ID,
|
||||
process.env.PAYLOAD_CLOUD_COGNITO_PASSWORD,
|
||||
)
|
||||
|
||||
const cognitoIdentity = new CognitoIdentityClient({
|
||||
credentials: fromCognitoIdentityPool({
|
||||
clientConfig: {
|
||||
region: 'us-east-1',
|
||||
},
|
||||
identityPoolId: process.env.PAYLOAD_CLOUD_COGNITO_IDENTITY_POOL_ID,
|
||||
logins: {
|
||||
[`cognito-idp.us-east-1.amazonaws.com/${process.env.PAYLOAD_CLOUD_COGNITO_USER_POOL_ID}`]:
|
||||
session.getIdToken().getJwtToken(),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
const credentials = await cognitoIdentity.config.credentials()
|
||||
|
||||
// @ts-expect-error - Incorrect AWS types
|
||||
identityID = credentials.identityId
|
||||
|
||||
storageClient = new AWS.S3({
|
||||
credentials,
|
||||
region: process.env.PAYLOAD_CLOUD_BUCKET_REGION,
|
||||
})
|
||||
|
||||
return {
|
||||
identityID,
|
||||
storageClient,
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
import { CognitoIdentityClient } from '@aws-sdk/client-cognito-identity'
|
||||
import * as AWS from '@aws-sdk/client-s3'
|
||||
import { fromCognitoIdentityPool } from '@aws-sdk/credential-providers'
|
||||
|
||||
import { authAsCognitoUser } from './authAsCognitoUser.js'
|
||||
|
||||
export type GetStorageClient = () => Promise<{
|
||||
identityID: string
|
||||
storageClient: AWS.S3
|
||||
}>
|
||||
|
||||
export const refreshSession = async () => {
|
||||
const session = await authAsCognitoUser(
|
||||
process.env.PAYLOAD_CLOUD_PROJECT_ID || '',
|
||||
process.env.PAYLOAD_CLOUD_COGNITO_PASSWORD || '',
|
||||
)
|
||||
|
||||
const cognitoIdentity = new CognitoIdentityClient({
|
||||
credentials: fromCognitoIdentityPool({
|
||||
clientConfig: {
|
||||
region: 'us-east-1',
|
||||
},
|
||||
identityPoolId: process.env.PAYLOAD_CLOUD_COGNITO_IDENTITY_POOL_ID || '',
|
||||
logins: {
|
||||
[`cognito-idp.us-east-1.amazonaws.com/${process.env.PAYLOAD_CLOUD_COGNITO_USER_POOL_ID}`]:
|
||||
session.getIdToken().getJwtToken(),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
const credentials = await cognitoIdentity.config.credentials()
|
||||
|
||||
// @ts-expect-error - Incorrect AWS types
|
||||
const identityID = credentials.identityId
|
||||
|
||||
const storageClient = new AWS.S3({
|
||||
credentials,
|
||||
region: process.env.PAYLOAD_CLOUD_BUCKET_REGION,
|
||||
})
|
||||
|
||||
return {
|
||||
identityID,
|
||||
session,
|
||||
storageClient,
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ImportMap } from '../../bin/generateImportMap/index.js'
|
||||
import type { SanitizedConfig } from '../../config/types.js'
|
||||
import type { PaginatedDocs } from '../../database/types.js'
|
||||
import type { CollectionSlug, ColumnPreference } from '../../index.js'
|
||||
import type { CollectionSlug } from '../../index.js'
|
||||
import type { PayloadRequest, Sort, Where } from '../../types/index.js'
|
||||
|
||||
export type DefaultServerFunctionArgs = {
|
||||
@@ -50,7 +50,7 @@ export type ListQuery = {
|
||||
|
||||
export type BuildTableStateArgs = {
|
||||
collectionSlug: string | string[]
|
||||
columns?: ColumnPreference[]
|
||||
columns?: { accessor: string; active: boolean }[]
|
||||
docs?: PaginatedDocs['docs']
|
||||
enableRowSelections?: boolean
|
||||
parent?: {
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
// @ts-strict-ignore
|
||||
import type { AuthStrategyFunctionArgs, AuthStrategyResult } from './index.js'
|
||||
|
||||
export const executeAuthStrategies = async (
|
||||
args: AuthStrategyFunctionArgs,
|
||||
): Promise<AuthStrategyResult> => {
|
||||
if (!args.payload.authStrategies?.length) {
|
||||
return { user: null }
|
||||
}
|
||||
return args.payload.authStrategies.reduce(
|
||||
async (accumulatorPromise, strategy) => {
|
||||
const result: AuthStrategyResult = await accumulatorPromise
|
||||
if (!result.user) {
|
||||
// add the configured AuthStrategy `name` to the strategy function args
|
||||
args.strategyName = strategy.name
|
||||
|
||||
for (const strategy of args.payload.authStrategies) {
|
||||
// add the configured AuthStrategy `name` to the strategy function args
|
||||
args.strategyName = strategy.name
|
||||
|
||||
const result = await strategy.authenticate(args)
|
||||
if (result.user) {
|
||||
return strategy.authenticate(args)
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
return { user: null }
|
||||
},
|
||||
Promise.resolve({ user: null }),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -64,18 +64,18 @@ export const forgotPasswordOperation = async <TSlug extends CollectionSlug>(
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks?.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection?.config,
|
||||
context: args.req.context,
|
||||
operation: 'forgotPassword',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
await args.collection.config.hooks.beforeOperation.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection?.config,
|
||||
context: args.req.context,
|
||||
operation: 'forgotPassword',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}, Promise.resolve())
|
||||
|
||||
const {
|
||||
collection: { config: collectionConfig },
|
||||
@@ -190,11 +190,10 @@ export const forgotPasswordOperation = async <TSlug extends CollectionSlug>(
|
||||
// afterForgotPassword - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterForgotPassword?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterForgotPassword) {
|
||||
await hook({ args, collection: args.collection?.config, context: req.context })
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterForgotPassword.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
await hook({ args, collection: args.collection?.config, context: req.context })
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterOperation - Collection
|
||||
|
||||
@@ -51,18 +51,18 @@ export const loginOperation = async <TSlug extends CollectionSlug>(
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks?.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection?.config,
|
||||
context: args.req.context,
|
||||
operation: 'login',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
await args.collection.config.hooks.beforeOperation.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection?.config,
|
||||
context: args.req.context,
|
||||
operation: 'login',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}, Promise.resolve())
|
||||
|
||||
const {
|
||||
collection: { config: collectionConfig },
|
||||
@@ -227,17 +227,17 @@ export const loginOperation = async <TSlug extends CollectionSlug>(
|
||||
// beforeLogin - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.beforeLogin?.length) {
|
||||
for (const hook of collectionConfig.hooks.beforeLogin) {
|
||||
user =
|
||||
(await hook({
|
||||
collection: args.collection?.config,
|
||||
context: args.req.context,
|
||||
req: args.req,
|
||||
user,
|
||||
})) || user
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.beforeLogin.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
user =
|
||||
(await hook({
|
||||
collection: args.collection?.config,
|
||||
context: args.req.context,
|
||||
req: args.req,
|
||||
user,
|
||||
})) || user
|
||||
}, Promise.resolve())
|
||||
|
||||
const { exp, token } = await jwtSign({
|
||||
fieldsToSign,
|
||||
@@ -251,18 +251,18 @@ export const loginOperation = async <TSlug extends CollectionSlug>(
|
||||
// afterLogin - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterLogin?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterLogin) {
|
||||
user =
|
||||
(await hook({
|
||||
collection: args.collection?.config,
|
||||
context: args.req.context,
|
||||
req: args.req,
|
||||
token,
|
||||
user,
|
||||
})) || user
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterLogin.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
user =
|
||||
(await hook({
|
||||
collection: args.collection?.config,
|
||||
context: args.req.context,
|
||||
req: args.req,
|
||||
token,
|
||||
user,
|
||||
})) || user
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterRead - Fields
|
||||
@@ -286,17 +286,17 @@ export const loginOperation = async <TSlug extends CollectionSlug>(
|
||||
// afterRead - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterRead) {
|
||||
user =
|
||||
(await hook({
|
||||
collection: args.collection?.config,
|
||||
context: req.context,
|
||||
doc: user,
|
||||
req,
|
||||
})) || user
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
user =
|
||||
(await hook({
|
||||
collection: args.collection?.config,
|
||||
context: req.context,
|
||||
doc: user,
|
||||
req,
|
||||
})) || user
|
||||
}, Promise.resolve())
|
||||
|
||||
let result: { user: DataFromCollectionSlug<TSlug> } & Result = {
|
||||
exp,
|
||||
|
||||
@@ -25,16 +25,16 @@ export const logoutOperation = async (incomingArgs: Arguments): Promise<boolean>
|
||||
throw new APIError('Incorrect collection', httpStatus.FORBIDDEN)
|
||||
}
|
||||
|
||||
if (collectionConfig.hooks?.afterLogout?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterLogout) {
|
||||
args =
|
||||
(await hook({
|
||||
collection: args.collection?.config,
|
||||
context: req.context,
|
||||
req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterLogout.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
collection: args.collection?.config,
|
||||
context: req.context,
|
||||
req,
|
||||
})) || args
|
||||
}, Promise.resolve())
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -86,17 +86,17 @@ export const meOperation = async (args: Arguments): Promise<MeOperationResult> =
|
||||
// After Me - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collection.config.hooks?.afterMe?.length) {
|
||||
for (const hook of collection.config.hooks.afterMe) {
|
||||
result =
|
||||
(await hook({
|
||||
collection: collection?.config,
|
||||
context: req.context,
|
||||
req,
|
||||
response: result,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collection.config.hooks.afterMe.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: collection?.config,
|
||||
context: req.context,
|
||||
req,
|
||||
response: result,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -35,8 +35,10 @@ export const refreshOperation = async (incomingArgs: Arguments): Promise<Result>
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks?.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
await args.collection.config.hooks.beforeOperation.reduce(
|
||||
async (priorHook: BeforeOperationHook | Promise<void>, hook: BeforeOperationHook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
@@ -45,8 +47,9 @@ export const refreshOperation = async (incomingArgs: Arguments): Promise<Result>
|
||||
operation: 'refresh',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
},
|
||||
Promise.resolve(),
|
||||
)
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Refresh
|
||||
@@ -119,18 +122,18 @@ export const refreshOperation = async (incomingArgs: Arguments): Promise<Result>
|
||||
// After Refresh - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterRefresh?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterRefresh) {
|
||||
result =
|
||||
(await hook({
|
||||
collection: args.collection?.config,
|
||||
context: args.req.context,
|
||||
exp: result.exp,
|
||||
req: args.req,
|
||||
token: result.refreshedToken,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterRefresh.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: args.collection?.config,
|
||||
context: args.req.context,
|
||||
exp: result.exp,
|
||||
req: args.req,
|
||||
token: result.refreshedToken,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterOperation - Collection
|
||||
|
||||
@@ -91,17 +91,17 @@ export const resetPasswordOperation = async (args: Arguments): Promise<Result> =
|
||||
// beforeValidate - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.beforeValidate?.length) {
|
||||
for (const hook of collectionConfig.hooks.beforeValidate) {
|
||||
await hook({
|
||||
collection: args.collection?.config,
|
||||
context: req.context,
|
||||
data: user,
|
||||
operation: 'update',
|
||||
req,
|
||||
})
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.beforeValidate.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
await hook({
|
||||
collection: args.collection?.config,
|
||||
context: req.context,
|
||||
data: user,
|
||||
operation: 'update',
|
||||
req,
|
||||
})
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Update new password
|
||||
|
||||
@@ -44,9 +44,7 @@ const batchAndLoadDocs =
|
||||
*
|
||||
**/
|
||||
|
||||
const batchByFindArgs = {}
|
||||
|
||||
for (const key of keys) {
|
||||
const batchByFindArgs = keys.reduce((batches, key) => {
|
||||
const [
|
||||
transactionID,
|
||||
collection,
|
||||
@@ -79,16 +77,27 @@ const batchAndLoadDocs =
|
||||
const batchKey = JSON.stringify(batchKeyArray)
|
||||
|
||||
const idType = payload.collections?.[collection].customIDType || payload.db.defaultIDType
|
||||
const sanitizedID = idType === 'number' ? parseFloat(id) : id
|
||||
|
||||
let sanitizedID: number | string = id
|
||||
|
||||
if (idType === 'number') {
|
||||
sanitizedID = parseFloat(id)
|
||||
}
|
||||
|
||||
if (isValidID(sanitizedID, idType)) {
|
||||
batchByFindArgs[batchKey] = [...(batchByFindArgs[batchKey] || []), sanitizedID]
|
||||
return {
|
||||
...batches,
|
||||
[batchKey]: [...(batches[batchKey] || []), sanitizedID],
|
||||
}
|
||||
}
|
||||
}
|
||||
return batches
|
||||
}, {})
|
||||
|
||||
// Run find requests one after another, so as to not hang transactions
|
||||
|
||||
for (const [batchKey, ids] of Object.entries(batchByFindArgs)) {
|
||||
await Object.entries(batchByFindArgs).reduce(async (priorFind, [batchKey, ids]) => {
|
||||
await priorFind
|
||||
|
||||
const [
|
||||
transactionID,
|
||||
collection,
|
||||
@@ -128,7 +137,8 @@ const batchAndLoadDocs =
|
||||
|
||||
// For each returned doc, find index in original keys
|
||||
// Inject doc within docs array if index exists
|
||||
for (const doc of result.docs) {
|
||||
|
||||
result.docs.forEach((doc) => {
|
||||
const docKey = createDataloaderCacheKey({
|
||||
collectionSlug: collection,
|
||||
currentDepth,
|
||||
@@ -148,8 +158,8 @@ const batchAndLoadDocs =
|
||||
if (docsIndex > -1) {
|
||||
docs[docsIndex] = doc
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}, Promise.resolve())
|
||||
|
||||
// Return docs array,
|
||||
// which has now been injected with all fetched docs
|
||||
|
||||
@@ -28,18 +28,18 @@ export const countOperation = async <TSlug extends CollectionSlug>(
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks?.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'count',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
await args.collection.config.hooks.beforeOperation.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'count',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}, Promise.resolve())
|
||||
|
||||
const {
|
||||
collection: { config: collectionConfig },
|
||||
|
||||
@@ -28,18 +28,18 @@ export const countVersionsOperation = async <TSlug extends CollectionSlug>(
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'countVersions',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
await args.collection.config.hooks.beforeOperation.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'countVersions',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}, Promise.resolve())
|
||||
|
||||
const {
|
||||
collection: { config: collectionConfig },
|
||||
|
||||
@@ -78,8 +78,10 @@ export const createOperation = async <
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
await args.collection.config.hooks.beforeOperation.reduce(
|
||||
async (priorHook: BeforeOperationHook | Promise<void>, hook: BeforeOperationHook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
@@ -88,8 +90,9 @@ export const createOperation = async <
|
||||
operation: 'create',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
},
|
||||
Promise.resolve(),
|
||||
)
|
||||
|
||||
const {
|
||||
autosave = false,
|
||||
@@ -180,8 +183,10 @@ export const createOperation = async <
|
||||
// beforeValidate - Collections
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks.beforeValidate?.length) {
|
||||
for (const hook of collectionConfig.hooks.beforeValidate) {
|
||||
await collectionConfig.hooks.beforeValidate.reduce(
|
||||
async (priorHook: BeforeValidateHook | Promise<void>, hook: BeforeValidateHook) => {
|
||||
await priorHook
|
||||
|
||||
data =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
@@ -191,26 +196,27 @@ export const createOperation = async <
|
||||
originalDoc: duplicatedFromDoc,
|
||||
req,
|
||||
})) || data
|
||||
}
|
||||
}
|
||||
},
|
||||
Promise.resolve(),
|
||||
)
|
||||
|
||||
// /////////////////////////////////////
|
||||
// beforeChange - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.beforeChange?.length) {
|
||||
for (const hook of collectionConfig.hooks.beforeChange) {
|
||||
data =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
data,
|
||||
operation: 'create',
|
||||
originalDoc: duplicatedFromDoc,
|
||||
req,
|
||||
})) || data
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.beforeChange.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
data =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
data,
|
||||
operation: 'create',
|
||||
originalDoc: duplicatedFromDoc,
|
||||
req,
|
||||
})) || data
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// beforeChange - Fields
|
||||
@@ -326,17 +332,17 @@ export const createOperation = async <
|
||||
// afterRead - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterRead) {
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterChange - Fields
|
||||
@@ -357,8 +363,10 @@ export const createOperation = async <
|
||||
// afterChange - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterChange?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterChange) {
|
||||
await collectionConfig.hooks.afterChange.reduce(
|
||||
async (priorHook: AfterChangeHook | Promise<void>, hook: AfterChangeHook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
@@ -368,8 +376,9 @@ export const createOperation = async <
|
||||
previousDoc: {},
|
||||
req: args.req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
},
|
||||
Promise.resolve(),
|
||||
)
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterOperation - Collection
|
||||
|
||||
@@ -54,8 +54,10 @@ export const deleteOperation = async <
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks?.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
await args.collection.config.hooks.beforeOperation.reduce(
|
||||
async (priorHook: BeforeOperationHook | Promise<void>, hook: BeforeOperationHook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
@@ -64,8 +66,9 @@ export const deleteOperation = async <
|
||||
operation: 'delete',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
},
|
||||
Promise.resolve(),
|
||||
)
|
||||
|
||||
const {
|
||||
collection: { config: collectionConfig },
|
||||
@@ -144,16 +147,16 @@ export const deleteOperation = async <
|
||||
// beforeDelete - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.beforeDelete?.length) {
|
||||
for (const hook of collectionConfig.hooks.beforeDelete) {
|
||||
await hook({
|
||||
id,
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
req,
|
||||
})
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.beforeDelete.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
return hook({
|
||||
id,
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
req,
|
||||
})
|
||||
}, Promise.resolve())
|
||||
|
||||
await deleteAssociatedFiles({
|
||||
collectionConfig,
|
||||
@@ -226,34 +229,34 @@ export const deleteOperation = async <
|
||||
// afterRead - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterRead) {
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result || doc,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result || doc,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterDelete - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterDelete?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterDelete) {
|
||||
result =
|
||||
(await hook({
|
||||
id,
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterDelete.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
id,
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// 8. Return results
|
||||
|
||||
@@ -48,8 +48,10 @@ export const deleteByIDOperation = async <TSlug extends CollectionSlug, TSelect
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks?.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
await args.collection.config.hooks.beforeOperation.reduce(
|
||||
async (priorHook: BeforeOperationHook | Promise<void>, hook: BeforeOperationHook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
@@ -58,8 +60,9 @@ export const deleteByIDOperation = async <TSlug extends CollectionSlug, TSelect
|
||||
operation: 'delete',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
},
|
||||
Promise.resolve(),
|
||||
)
|
||||
|
||||
const {
|
||||
id,
|
||||
@@ -92,16 +95,16 @@ export const deleteByIDOperation = async <TSlug extends CollectionSlug, TSelect
|
||||
// beforeDelete - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.beforeDelete?.length) {
|
||||
for (const hook of collectionConfig.hooks.beforeDelete) {
|
||||
await hook({
|
||||
id,
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
req,
|
||||
})
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.beforeDelete.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
return hook({
|
||||
id,
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
req,
|
||||
})
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Retrieve document
|
||||
@@ -212,34 +215,34 @@ export const deleteByIDOperation = async <TSlug extends CollectionSlug, TSelect
|
||||
// afterRead - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterRead) {
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterDelete - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterDelete?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterDelete) {
|
||||
result =
|
||||
(await hook({
|
||||
id,
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterDelete.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
id,
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterOperation - Collection
|
||||
|
||||
@@ -63,18 +63,18 @@ export const findOperation = async <
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks?.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'read',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
await args.collection.config.hooks.beforeOperation.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'read',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}, Promise.resolve())
|
||||
|
||||
const {
|
||||
collection: { config: collectionConfig },
|
||||
@@ -257,7 +257,9 @@ export const findOperation = async <
|
||||
result.docs.map(async (doc) => {
|
||||
let docRef = doc
|
||||
|
||||
for (const hook of collectionConfig.hooks.beforeRead) {
|
||||
await collectionConfig.hooks.beforeRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
docRef =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
@@ -266,7 +268,7 @@ export const findOperation = async <
|
||||
query: fullWhere,
|
||||
req,
|
||||
})) || docRef
|
||||
}
|
||||
}, Promise.resolve())
|
||||
|
||||
return docRef
|
||||
}),
|
||||
@@ -308,7 +310,9 @@ export const findOperation = async <
|
||||
result.docs.map(async (doc) => {
|
||||
let docRef = doc
|
||||
|
||||
for (const hook of collectionConfig.hooks.afterRead) {
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
docRef =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
@@ -318,7 +322,7 @@ export const findOperation = async <
|
||||
query: fullWhere,
|
||||
req,
|
||||
})) || doc
|
||||
}
|
||||
}, Promise.resolve())
|
||||
|
||||
return docRef
|
||||
}),
|
||||
|
||||
@@ -54,18 +54,18 @@ export const findByIDOperation = async <
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks?.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'read',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
await args.collection.config.hooks.beforeOperation.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'read',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}, Promise.resolve())
|
||||
|
||||
const {
|
||||
id,
|
||||
@@ -221,18 +221,18 @@ export const findByIDOperation = async <
|
||||
// beforeRead - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.beforeRead?.length) {
|
||||
for (const hook of collectionConfig.hooks.beforeRead) {
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
query: findOneArgs.where,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.beforeRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
query: findOneArgs.where,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterRead - Fields
|
||||
@@ -259,18 +259,18 @@ export const findByIDOperation = async <
|
||||
// afterRead - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterRead) {
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
query: findOneArgs.where,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
query: findOneArgs.where,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterOperation - Collection
|
||||
|
||||
@@ -101,18 +101,18 @@ export const findVersionByIDOperation = async <TData extends TypeWithID = any>(
|
||||
// beforeRead - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.beforeRead?.length) {
|
||||
for (const hook of collectionConfig.hooks.beforeRead) {
|
||||
result.version =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result.version,
|
||||
query: fullWhere,
|
||||
req,
|
||||
})) || result.version
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.beforeRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result.version =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result.version,
|
||||
query: fullWhere,
|
||||
req,
|
||||
})) || result.version
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterRead - Fields
|
||||
@@ -139,18 +139,18 @@ export const findVersionByIDOperation = async <TData extends TypeWithID = any>(
|
||||
// afterRead - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterRead) {
|
||||
result.version =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result.version,
|
||||
query: fullWhere,
|
||||
req,
|
||||
})) || result.version
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result.version =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result.version,
|
||||
query: fullWhere,
|
||||
req,
|
||||
})) || result.version
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Return results
|
||||
|
||||
@@ -96,19 +96,18 @@ export const findVersionsOperation = async <TData extends TypeWithVersion<TData>
|
||||
if (!docRef.version) {
|
||||
;(docRef as any).version = {}
|
||||
}
|
||||
await collectionConfig.hooks.beforeRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
if (collectionConfig.hooks?.beforeRead?.length) {
|
||||
for (const hook of collectionConfig.hooks.beforeRead) {
|
||||
docRef.version =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: docRef.version,
|
||||
query: fullWhere,
|
||||
req,
|
||||
})) || docRef.version
|
||||
}
|
||||
}
|
||||
docRef.version =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: docRef.version,
|
||||
query: fullWhere,
|
||||
req,
|
||||
})) || docRef.version
|
||||
}, Promise.resolve())
|
||||
|
||||
return docRef
|
||||
}),
|
||||
@@ -148,7 +147,9 @@ export const findVersionsOperation = async <TData extends TypeWithVersion<TData>
|
||||
result.docs.map(async (doc) => {
|
||||
const docRef = doc
|
||||
|
||||
for (const hook of collectionConfig.hooks.afterRead) {
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
docRef.version =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
@@ -158,7 +159,7 @@ export const findVersionsOperation = async <TData extends TypeWithVersion<TData>
|
||||
query: fullWhere,
|
||||
req,
|
||||
})) || doc.version
|
||||
}
|
||||
}, Promise.resolve())
|
||||
|
||||
return docRef
|
||||
}),
|
||||
|
||||
@@ -165,17 +165,17 @@ export const restoreVersionOperation = async <TData extends TypeWithID = any>(
|
||||
// afterRead - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterRead) {
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterChange - Fields
|
||||
@@ -196,19 +196,19 @@ export const restoreVersionOperation = async <TData extends TypeWithID = any>(
|
||||
// afterChange - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterChange?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterChange) {
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
operation: 'update',
|
||||
previousDoc: prevDocWithLocales,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterChange.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
operation: 'update',
|
||||
previousDoc: prevDocWithLocales,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
return result
|
||||
} catch (error: unknown) {
|
||||
|
||||
@@ -62,18 +62,18 @@ export const updateOperation = async <
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks?.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'update',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
await args.collection.config.hooks.beforeOperation.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'update',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}, Promise.resolve())
|
||||
|
||||
const {
|
||||
collection: { config: collectionConfig },
|
||||
|
||||
@@ -64,18 +64,18 @@ export const updateByIDOperation = async <
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (args.collection.config.hooks?.beforeOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.beforeOperation) {
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'update',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}
|
||||
}
|
||||
await args.collection.config.hooks.beforeOperation.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
args =
|
||||
(await hook({
|
||||
args,
|
||||
collection: args.collection.config,
|
||||
context: args.req.context,
|
||||
operation: 'update',
|
||||
req: args.req,
|
||||
})) || args
|
||||
}, Promise.resolve())
|
||||
|
||||
if (args.publishSpecificLocale) {
|
||||
args.req.locale = args.publishSpecificLocale
|
||||
|
||||
@@ -171,19 +171,19 @@ export const updateDocument = async <
|
||||
// beforeValidate - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.beforeValidate?.length) {
|
||||
for (const hook of collectionConfig.hooks.beforeValidate) {
|
||||
data =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
data,
|
||||
operation: 'update',
|
||||
originalDoc,
|
||||
req,
|
||||
})) || data
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.beforeValidate.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
data =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
data,
|
||||
operation: 'update',
|
||||
originalDoc,
|
||||
req,
|
||||
})) || data
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Write files to local storage
|
||||
@@ -197,19 +197,19 @@ export const updateDocument = async <
|
||||
// beforeChange - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.beforeChange?.length) {
|
||||
for (const hook of collectionConfig.hooks.beforeChange) {
|
||||
data =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
data,
|
||||
operation: 'update',
|
||||
originalDoc,
|
||||
req,
|
||||
})) || data
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.beforeChange.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
data =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
data,
|
||||
operation: 'update',
|
||||
originalDoc,
|
||||
req,
|
||||
})) || data
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// beforeChange - Fields
|
||||
@@ -338,17 +338,17 @@ export const updateDocument = async <
|
||||
// afterRead - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterRead) {
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterChange - Fields
|
||||
@@ -369,19 +369,19 @@ export const updateDocument = async <
|
||||
// afterChange - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.hooks?.afterChange?.length) {
|
||||
for (const hook of collectionConfig.hooks.afterChange) {
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
operation: 'update',
|
||||
previousDoc: originalDoc,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await collectionConfig.hooks.afterChange.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
doc: result,
|
||||
operation: 'update',
|
||||
previousDoc: originalDoc,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
return result as TransformCollectionWithSelect<TSlug, TSelect>
|
||||
}
|
||||
|
||||
@@ -125,8 +125,10 @@ export const buildAfterOperation = async <
|
||||
|
||||
let newResult = result as OperationResult<TOperationGeneric, O>
|
||||
|
||||
if (args.collection.config.hooks?.afterOperation?.length) {
|
||||
for (const hook of args.collection.config.hooks.afterOperation) {
|
||||
await args.collection.config.hooks.afterOperation.reduce(
|
||||
async (priorHook, hook: AfterOperationHook<TOperationGeneric>) => {
|
||||
await priorHook
|
||||
|
||||
const hookResult = await hook({
|
||||
args,
|
||||
collection,
|
||||
@@ -138,8 +140,9 @@ export const buildAfterOperation = async <
|
||||
if (hookResult !== undefined) {
|
||||
newResult = hookResult as OperationResult<TOperationGeneric, O>
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Promise.resolve(),
|
||||
)
|
||||
|
||||
return newResult
|
||||
}
|
||||
|
||||
@@ -9,10 +9,11 @@ import { sanitizeConfig } from './sanitize.js'
|
||||
*/
|
||||
export async function buildConfig(config: Config): Promise<SanitizedConfig> {
|
||||
if (Array.isArray(config.plugins)) {
|
||||
let configAfterPlugins = config
|
||||
for (const plugin of config.plugins) {
|
||||
configAfterPlugins = await plugin(configAfterPlugins)
|
||||
}
|
||||
const configAfterPlugins = await config.plugins.reduce(async (acc, plugin) => {
|
||||
const configAfterPlugin = await acc
|
||||
return plugin(configAfterPlugin)
|
||||
}, Promise.resolve(config))
|
||||
|
||||
return await sanitizeConfig(configAfterPlugins)
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,10 @@ export const sanitizeConfig = async (incomingConfig: Config): Promise<SanitizedC
|
||||
}))
|
||||
} else {
|
||||
// is Locale[], so convert to string[] for localeCodes
|
||||
config.localization.localeCodes = config.localization.locales.map((locale) => locale.code)
|
||||
config.localization.localeCodes = config.localization.locales.reduce((locales, locale) => {
|
||||
locales.push(locale.code)
|
||||
return locales
|
||||
}, [] as string[])
|
||||
|
||||
config.localization.locales = (
|
||||
config.localization as LocalizationConfigWithLabels
|
||||
|
||||
@@ -133,17 +133,17 @@ export const findOneOperation = async <T extends Record<string, unknown>>(
|
||||
// Execute before global hook
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.hooks?.beforeRead?.length) {
|
||||
for (const hook of globalConfig.hooks.beforeRead) {
|
||||
doc =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc,
|
||||
global: globalConfig,
|
||||
req,
|
||||
})) || doc
|
||||
}
|
||||
}
|
||||
await globalConfig.hooks.beforeRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
doc =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc,
|
||||
global: globalConfig,
|
||||
req,
|
||||
})) || doc
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Execute globalType field if not selected
|
||||
@@ -182,17 +182,17 @@ export const findOneOperation = async <T extends Record<string, unknown>>(
|
||||
// Execute after global hook
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of globalConfig.hooks.afterRead) {
|
||||
doc =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc,
|
||||
global: globalConfig,
|
||||
req,
|
||||
})) || doc
|
||||
}
|
||||
}
|
||||
await globalConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
doc =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc,
|
||||
global: globalConfig,
|
||||
req,
|
||||
})) || doc
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Return results
|
||||
|
||||
@@ -102,17 +102,17 @@ export const findVersionByIDOperation = async <T extends TypeWithVersion<T> = an
|
||||
// beforeRead - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.hooks?.beforeRead?.length) {
|
||||
for (const hook of globalConfig.hooks.beforeRead) {
|
||||
result =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result.version,
|
||||
global: globalConfig,
|
||||
req,
|
||||
})) || result.version
|
||||
}
|
||||
}
|
||||
await globalConfig.hooks.beforeRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result.version,
|
||||
global: globalConfig,
|
||||
req,
|
||||
})) || result.version
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterRead - Fields
|
||||
@@ -139,18 +139,18 @@ export const findVersionByIDOperation = async <T extends TypeWithVersion<T> = an
|
||||
// afterRead - Global
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of globalConfig.hooks.afterRead) {
|
||||
result.version =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result.version,
|
||||
global: globalConfig,
|
||||
query: findGlobalVersionsArgs.where,
|
||||
req,
|
||||
})) || result.version
|
||||
}
|
||||
}
|
||||
await globalConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result.version =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result.version,
|
||||
global: globalConfig,
|
||||
query: findGlobalVersionsArgs.where,
|
||||
req,
|
||||
})) || result.version
|
||||
}, Promise.resolve())
|
||||
|
||||
return result
|
||||
} catch (error: unknown) {
|
||||
|
||||
@@ -126,12 +126,15 @@ export const findVersionsOperation = async <T extends TypeWithVersion<T>>(
|
||||
// afterRead - Global
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.hooks?.afterRead?.length) {
|
||||
result.docs = await Promise.all(
|
||||
result = {
|
||||
...result,
|
||||
docs: await Promise.all(
|
||||
result.docs.map(async (doc) => {
|
||||
const docRef = doc
|
||||
|
||||
for (const hook of globalConfig.hooks.afterRead) {
|
||||
await globalConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
docRef.version =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
@@ -141,11 +144,11 @@ export const findVersionsOperation = async <T extends TypeWithVersion<T>>(
|
||||
query: fullWhere,
|
||||
req,
|
||||
})) || doc.version
|
||||
}
|
||||
}, Promise.resolve())
|
||||
|
||||
return docRef
|
||||
}),
|
||||
)
|
||||
),
|
||||
}
|
||||
|
||||
// /////////////////////////////////////
|
||||
|
||||
@@ -143,17 +143,17 @@ export const restoreVersionOperation = async <T extends TypeWithVersion<T> = any
|
||||
// afterRead - Global
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of globalConfig.hooks.afterRead) {
|
||||
result =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result,
|
||||
global: globalConfig,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await globalConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result,
|
||||
global: globalConfig,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterChange - Fields
|
||||
@@ -174,18 +174,18 @@ export const restoreVersionOperation = async <T extends TypeWithVersion<T> = any
|
||||
// afterChange - Global
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.hooks?.afterChange?.length) {
|
||||
for (const hook of globalConfig.hooks.afterChange) {
|
||||
result =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result,
|
||||
global: globalConfig,
|
||||
previousDoc,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await globalConfig.hooks.afterChange.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result,
|
||||
global: globalConfig,
|
||||
previousDoc,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
if (shouldCommit) {
|
||||
await commitTransaction(req)
|
||||
|
||||
@@ -168,35 +168,35 @@ export const updateOperation = async <
|
||||
// beforeValidate - Global
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.hooks?.beforeValidate?.length) {
|
||||
for (const hook of globalConfig.hooks.beforeValidate) {
|
||||
data =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
data,
|
||||
global: globalConfig,
|
||||
originalDoc,
|
||||
req,
|
||||
})) || data
|
||||
}
|
||||
}
|
||||
await globalConfig.hooks.beforeValidate.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
data =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
data,
|
||||
global: globalConfig,
|
||||
originalDoc,
|
||||
req,
|
||||
})) || data
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// beforeChange - Global
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.hooks?.beforeChange?.length) {
|
||||
for (const hook of globalConfig.hooks.beforeChange) {
|
||||
data =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
data,
|
||||
global: globalConfig,
|
||||
originalDoc,
|
||||
req,
|
||||
})) || data
|
||||
}
|
||||
}
|
||||
await globalConfig.hooks.beforeChange.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
data =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
data,
|
||||
global: globalConfig,
|
||||
originalDoc,
|
||||
req,
|
||||
})) || data
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// beforeChange - Fields
|
||||
@@ -326,17 +326,17 @@ export const updateOperation = async <
|
||||
// afterRead - Global
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.hooks?.afterRead?.length) {
|
||||
for (const hook of globalConfig.hooks.afterRead) {
|
||||
result =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result,
|
||||
global: globalConfig,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await globalConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result,
|
||||
global: globalConfig,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterChange - Fields
|
||||
@@ -357,18 +357,18 @@ export const updateOperation = async <
|
||||
// afterChange - Global
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.hooks?.afterChange?.length) {
|
||||
for (const hook of globalConfig.hooks.afterChange) {
|
||||
result =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result,
|
||||
global: globalConfig,
|
||||
previousDoc: originalDoc,
|
||||
req,
|
||||
})) || result
|
||||
}
|
||||
}
|
||||
await globalConfig.hooks.afterChange.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
result =
|
||||
(await hook({
|
||||
context: req.context,
|
||||
doc: result,
|
||||
global: globalConfig,
|
||||
previousDoc: originalDoc,
|
||||
req,
|
||||
})) || result
|
||||
}, Promise.resolve())
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Return results
|
||||
|
||||
@@ -1374,7 +1374,6 @@ export { restoreVersionOperation as restoreVersionOperationGlobal } from './glob
|
||||
export { updateOperation as updateOperationGlobal } from './globals/operations/update.js'
|
||||
export type {
|
||||
CollapsedPreferences,
|
||||
ColumnPreference,
|
||||
DocumentPreferences,
|
||||
FieldsPreferences,
|
||||
InsideFieldsPreferences,
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* @todo remove this function and subsequent hooks in v4
|
||||
* They are used to transform the old shape of `columnPreferences` to new shape
|
||||
* i.e. ({ accessor: string, active: boolean })[] to ({ [accessor: string]: boolean })[]
|
||||
* In v4 can we use the new shape directly
|
||||
*/
|
||||
export const migrateColumns = (value: Record<string, any>) => {
|
||||
if (value && typeof value === 'object' && 'columns' in value && Array.isArray(value.columns)) {
|
||||
value.columns = value.columns.map((col) => {
|
||||
if ('accessor' in col) {
|
||||
return { [col.accessor]: col.active }
|
||||
}
|
||||
|
||||
return col
|
||||
})
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
import type { CollectionConfig } from '../collections/config/types.js'
|
||||
import type { Access, Config } from '../config/types.js'
|
||||
|
||||
import { migrateColumns } from './migrateColumns.js'
|
||||
import { deleteHandler } from './requestHandlers/delete.js'
|
||||
import { findByIDHandler } from './requestHandlers/findOne.js'
|
||||
import { updateHandler } from './requestHandlers/update.js'
|
||||
@@ -77,14 +76,6 @@ const getPreferencesCollection = (config: Config): CollectionConfig => ({
|
||||
{
|
||||
name: 'value',
|
||||
type: 'json',
|
||||
/**
|
||||
* @todo remove these hooks in v4
|
||||
* See `migrateColumns` for more information
|
||||
*/
|
||||
hooks: {
|
||||
afterRead: [({ value }) => migrateColumns(value)],
|
||||
beforeValidate: [({ value }) => migrateColumns(value)],
|
||||
},
|
||||
validate: (value) => {
|
||||
if (value) {
|
||||
try {
|
||||
|
||||
@@ -28,12 +28,8 @@ export type DocumentPreferences = {
|
||||
fields: FieldsPreferences
|
||||
}
|
||||
|
||||
export type ColumnPreference = {
|
||||
[key: string]: boolean
|
||||
}
|
||||
|
||||
export type ListPreferences = {
|
||||
columns?: ColumnPreference[]
|
||||
columns?: { accessor: string; active: boolean }[]
|
||||
limit?: number
|
||||
sort?: string
|
||||
}
|
||||
|
||||
@@ -1156,13 +1156,14 @@ export function configToJSONSchema(
|
||||
)
|
||||
: {}
|
||||
|
||||
const blocksDefinition: JSONSchema4 | undefined = {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {},
|
||||
required: [],
|
||||
}
|
||||
let blocksDefinition: JSONSchema4 | undefined = undefined
|
||||
if (config?.blocks?.length) {
|
||||
blocksDefinition = {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {},
|
||||
required: [],
|
||||
}
|
||||
for (const block of config.blocks) {
|
||||
const blockFieldSchemas = fieldsToJSONSchema(
|
||||
collectionIDFieldTypes,
|
||||
|
||||
@@ -4,9 +4,12 @@ import { useModal } from '@faceless-ui/modal'
|
||||
import React from 'react'
|
||||
|
||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||
import { ConfirmationModal } from '../../ConfirmationModal/index.js'
|
||||
import { Button } from '../../Button/index.js'
|
||||
import { FullscreenModal } from '../../FullscreenModal/index.js'
|
||||
import { useBulkUpload } from '../index.js'
|
||||
|
||||
export const discardBulkUploadModalSlug = 'bulk-upload--discard-without-saving'
|
||||
const baseClass = 'leave-without-saving'
|
||||
|
||||
export function DiscardWithoutSaving() {
|
||||
const { t } = useTranslation()
|
||||
@@ -23,14 +26,21 @@ export function DiscardWithoutSaving() {
|
||||
}, [closeModal, drawerSlug])
|
||||
|
||||
return (
|
||||
<ConfirmationModal
|
||||
body={t('general:changesNotSaved')}
|
||||
cancelLabel={t('general:stayOnThisPage')}
|
||||
confirmLabel={t('general:leaveAnyway')}
|
||||
heading={t('general:leaveWithoutSaving')}
|
||||
modalSlug={discardBulkUploadModalSlug}
|
||||
onCancel={onCancel}
|
||||
onConfirm={onConfirm}
|
||||
/>
|
||||
<FullscreenModal className={baseClass} slug={discardBulkUploadModalSlug}>
|
||||
<div className={`${baseClass}__wrapper`}>
|
||||
<div className={`${baseClass}__content`}>
|
||||
<h1>{t('general:leaveWithoutSaving')}</h1>
|
||||
<p>{t('general:changesNotSaved')}</p>
|
||||
</div>
|
||||
<div className={`${baseClass}__controls`}>
|
||||
<Button buttonStyle="secondary" onClick={onCancel} size="large">
|
||||
{t('general:stayOnThisPage')}
|
||||
</Button>
|
||||
<Button onClick={onConfirm} size="large">
|
||||
{t('general:leaveAnyway')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</FullscreenModal>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import type {
|
||||
CollectionSlug,
|
||||
Column,
|
||||
ColumnPreference,
|
||||
JoinFieldClient,
|
||||
ListQuery,
|
||||
PaginatedDocs,
|
||||
@@ -26,6 +25,7 @@ import { useServerFunctions } from '../../providers/ServerFunctions/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
import { hoistQueryParamsToAnd } from '../../utilities/mergeListSearchAndWhere.js'
|
||||
import { AnimateHeight } from '../AnimateHeight/index.js'
|
||||
import './index.scss'
|
||||
import { ColumnSelector } from '../ColumnSelector/index.js'
|
||||
import { useDocumentDrawer } from '../DocumentDrawer/index.js'
|
||||
import { Popup, PopupList } from '../Popup/index.js'
|
||||
@@ -33,7 +33,6 @@ import { RelationshipProvider } from '../Table/RelationshipProvider/index.js'
|
||||
import { TableColumnsProvider } from '../TableColumns/index.js'
|
||||
import { DrawerLink } from './cells/DrawerLink/index.js'
|
||||
import { RelationshipTablePagination } from './Pagination.js'
|
||||
import './index.scss'
|
||||
|
||||
const baseClass = 'relationship-table'
|
||||
|
||||
@@ -124,10 +123,11 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
|
||||
newQuery.where = hoistQueryParamsToAnd(newQuery.where, filterOptions)
|
||||
}
|
||||
|
||||
// map columns from string[] to ColumnPreference[]
|
||||
const defaultColumns: ColumnPreference[] = field.admin.defaultColumns
|
||||
// map columns from string[] to ListPreferences['columns']
|
||||
const defaultColumns = field.admin.defaultColumns
|
||||
? field.admin.defaultColumns.map((accessor) => ({
|
||||
[accessor]: true,
|
||||
accessor,
|
||||
active: true,
|
||||
}))
|
||||
: undefined
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ import type {
|
||||
ClientComponentProps,
|
||||
ClientField,
|
||||
Column,
|
||||
ColumnPreference,
|
||||
DefaultCellComponentProps,
|
||||
DefaultServerCellComponentProps,
|
||||
Field,
|
||||
ListPreferences,
|
||||
PaginatedDocs,
|
||||
Payload,
|
||||
SanitizedCollectionConfig,
|
||||
@@ -39,8 +39,8 @@ type Args = {
|
||||
beforeRows?: Column[]
|
||||
clientCollectionConfig: ClientCollectionConfig
|
||||
collectionConfig: SanitizedCollectionConfig
|
||||
columnPreferences: ColumnPreference[]
|
||||
columns?: ColumnPreference[]
|
||||
columnPreferences: ListPreferences['columns']
|
||||
columns?: ListPreferences['columns']
|
||||
customCellProps: DefaultCellComponentProps['customCellProps']
|
||||
docs: PaginatedDocs['docs']
|
||||
enableRowSelections: boolean
|
||||
@@ -99,10 +99,10 @@ export const buildColumnState = (args: Args): Column[] => {
|
||||
|
||||
const sortTo = columnPreferences || columns
|
||||
|
||||
const sortFieldMap = (fieldMap, sortTo: ColumnPreference[]) =>
|
||||
const sortFieldMap = (fieldMap, sortTo) =>
|
||||
fieldMap?.sort((a, b) => {
|
||||
const aIndex = sortTo.findIndex((column) => 'name' in a && a.name in column)
|
||||
const bIndex = sortTo.findIndex((column) => 'name' in b && b.name in column)
|
||||
const aIndex = sortTo.findIndex((column) => 'name' in a && column.accessor === a.name)
|
||||
const bIndex = sortTo.findIndex((column) => 'name' in b && column.accessor === b.name)
|
||||
|
||||
if (aIndex === -1 && bIndex === -1) {
|
||||
return 0
|
||||
@@ -136,12 +136,18 @@ export const buildColumnState = (args: Args): Column[] => {
|
||||
(f) => 'name' in field && 'name' in f && f.name === field.name,
|
||||
)
|
||||
|
||||
const columnPreference = columnPreferences?.find(
|
||||
(preference) => field && 'name' in field && preference.accessor === field.name,
|
||||
)
|
||||
|
||||
let active = false
|
||||
|
||||
if (columnPreferences) {
|
||||
active = 'name' in field && columnPreferences?.some((col) => col?.[field.name])
|
||||
if (columnPreference) {
|
||||
active = columnPreference.active
|
||||
} else if (columns && Array.isArray(columns) && columns.length > 0) {
|
||||
active = 'name' in field && columns.some((col) => col?.[field.name])
|
||||
active = columns.find(
|
||||
(column) => field && 'name' in field && column.accessor === field.name,
|
||||
)?.active
|
||||
} else if (activeColumnsIndices.length < 4) {
|
||||
active = true
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ import type { I18nClient } from '@payloadcms/translations'
|
||||
import type {
|
||||
ClientField,
|
||||
Column,
|
||||
ColumnPreference,
|
||||
DefaultCellComponentProps,
|
||||
DefaultServerCellComponentProps,
|
||||
Field,
|
||||
ListPreferences,
|
||||
PaginatedDocs,
|
||||
Payload,
|
||||
SanitizedCollectionConfig,
|
||||
@@ -36,8 +36,8 @@ import { filterFields } from './filterFields.js'
|
||||
|
||||
type Args = {
|
||||
beforeRows?: Column[]
|
||||
columnPreferences: ColumnPreference[]
|
||||
columns?: ColumnPreference[]
|
||||
columnPreferences: ListPreferences['columns']
|
||||
columns?: ListPreferences['columns']
|
||||
customCellProps: DefaultCellComponentProps['customCellProps']
|
||||
docs: PaginatedDocs['docs']
|
||||
enableRowSelections: boolean
|
||||
@@ -92,8 +92,8 @@ export const buildPolymorphicColumnState = (args: Args): Column[] => {
|
||||
|
||||
const sortFieldMap = (fieldMap, sortTo) =>
|
||||
fieldMap?.sort((a, b) => {
|
||||
const aIndex = sortTo.findIndex((column) => 'name' in a && a.name in column)
|
||||
const bIndex = sortTo.findIndex((column) => 'name' in b && b.name in column)
|
||||
const aIndex = sortTo.findIndex((column) => 'name' in a && column.accessor === a.name)
|
||||
const bIndex = sortTo.findIndex((column) => 'name' in b && column.accessor === b.name)
|
||||
|
||||
if (aIndex === -1 && bIndex === -1) {
|
||||
return 0
|
||||
@@ -127,12 +127,18 @@ export const buildPolymorphicColumnState = (args: Args): Column[] => {
|
||||
(f) => 'name' in field && 'name' in f && f.name === field.name,
|
||||
)
|
||||
|
||||
const columnPreference = columnPreferences?.find(
|
||||
(preference) => field && 'name' in field && preference.accessor === field.name,
|
||||
)
|
||||
|
||||
let active = false
|
||||
|
||||
if (columnPreferences) {
|
||||
active = 'name' in field && columnPreferences?.some((col) => col?.[field.name])
|
||||
if (columnPreference) {
|
||||
active = columnPreference.active
|
||||
} else if (columns && Array.isArray(columns) && columns.length > 0) {
|
||||
active = 'name' in field && columns.some((col) => col?.[field.name])
|
||||
active = columns.find(
|
||||
(column) => field && 'name' in field && column.accessor === field.name,
|
||||
)?.active
|
||||
} else if (activeColumnsIndices.length < 4) {
|
||||
active = true
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { ClientField, CollectionConfig, ColumnPreference, Field } from 'payload'
|
||||
import type { ClientField, CollectionConfig, Field, ListPreferences } from 'payload'
|
||||
|
||||
import { fieldAffectsData } from 'payload/shared'
|
||||
|
||||
const getRemainingColumns = <T extends ClientField[] | Field[]>(
|
||||
fields: T,
|
||||
useAsTitle: string,
|
||||
): ColumnPreference[] =>
|
||||
): ListPreferences['columns'] =>
|
||||
fields?.reduce((remaining, field) => {
|
||||
if (fieldAffectsData(field) && field.name === useAsTitle) {
|
||||
return remaining
|
||||
@@ -40,7 +40,7 @@ export const getInitialColumns = <T extends ClientField[] | Field[]>(
|
||||
fields: T,
|
||||
useAsTitle: CollectionConfig['admin']['useAsTitle'],
|
||||
defaultColumns: CollectionConfig['admin']['defaultColumns'],
|
||||
): ColumnPreference[] => {
|
||||
): ListPreferences['columns'] => {
|
||||
let initialColumns = []
|
||||
|
||||
if (Array.isArray(defaultColumns) && defaultColumns.length >= 1) {
|
||||
@@ -57,6 +57,7 @@ export const getInitialColumns = <T extends ClientField[] | Field[]>(
|
||||
}
|
||||
|
||||
return initialColumns.map((column) => ({
|
||||
[column]: true,
|
||||
accessor: column,
|
||||
active: true,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import type { Column, ColumnPreference, ListPreferences, SanitizedCollectionConfig } from 'payload'
|
||||
import type { Column, ListPreferences, SanitizedCollectionConfig } from 'payload'
|
||||
|
||||
import React, { createContext, useCallback, useContext, useEffect } from 'react'
|
||||
|
||||
@@ -39,10 +39,12 @@ type Props = {
|
||||
}
|
||||
|
||||
// strip out Heading, Label, and renderedCells properties, they cannot be sent to the server
|
||||
const formatColumnPreferences = (columns: Column[]): ColumnPreference[] =>
|
||||
columns.map(({ accessor, active }) => ({
|
||||
[accessor]: active,
|
||||
const sanitizeColumns = (columns: Column[]) => {
|
||||
return columns.map(({ accessor, active }) => ({
|
||||
accessor,
|
||||
active,
|
||||
}))
|
||||
}
|
||||
|
||||
export const TableColumnsProvider: React.FC<Props> = ({
|
||||
children,
|
||||
@@ -88,7 +90,7 @@ export const TableColumnsProvider: React.FC<Props> = ({
|
||||
|
||||
const result = await getTableState({
|
||||
collectionSlug,
|
||||
columns: formatColumnPreferences(withMovedColumn),
|
||||
columns: sanitizeColumns(withMovedColumn),
|
||||
docs,
|
||||
enableRowSelections,
|
||||
renderRowTypes,
|
||||
@@ -121,7 +123,7 @@ export const TableColumnsProvider: React.FC<Props> = ({
|
||||
|
||||
const { newColumnState, toggledColumns } = tableColumns.reduce<{
|
||||
newColumnState: Column[]
|
||||
toggledColumns: ColumnPreference[]
|
||||
toggledColumns: Pick<Column, 'accessor' | 'active'>[]
|
||||
}>(
|
||||
(acc, col) => {
|
||||
if (col.accessor === column) {
|
||||
@@ -131,12 +133,14 @@ export const TableColumnsProvider: React.FC<Props> = ({
|
||||
active: !col.active,
|
||||
})
|
||||
acc.toggledColumns.push({
|
||||
[col.accessor]: !col.active,
|
||||
accessor: col.accessor,
|
||||
active: !col.active,
|
||||
})
|
||||
} else {
|
||||
acc.newColumnState.push(col)
|
||||
acc.toggledColumns.push({
|
||||
[col.accessor]: col.active,
|
||||
accessor: col.accessor,
|
||||
active: col.active,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -178,8 +182,14 @@ export const TableColumnsProvider: React.FC<Props> = ({
|
||||
|
||||
const setActiveColumns = React.useCallback(
|
||||
async (activeColumnAccessors: string[]) => {
|
||||
const activeColumns: ColumnPreference[] = formatColumnPreferences(
|
||||
tableColumns.sort((first, second) => {
|
||||
const activeColumns: Pick<Column, 'accessor' | 'active'>[] = tableColumns
|
||||
.map((col) => {
|
||||
return {
|
||||
accessor: col.accessor,
|
||||
active: activeColumnAccessors.includes(col.accessor),
|
||||
}
|
||||
})
|
||||
.sort((first, second) => {
|
||||
const indexOfFirst = activeColumnAccessors.indexOf(first.accessor)
|
||||
const indexOfSecond = activeColumnAccessors.indexOf(second.accessor)
|
||||
|
||||
@@ -188,8 +198,7 @@ export const TableColumnsProvider: React.FC<Props> = ({
|
||||
}
|
||||
|
||||
return indexOfFirst > indexOfSecond ? 1 : -1
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
const { state: columnState, Table } = await getTableState({
|
||||
collectionSlug,
|
||||
@@ -230,7 +239,7 @@ export const TableColumnsProvider: React.FC<Props> = ({
|
||||
|
||||
if (collectionHasChanged || !listPreferences) {
|
||||
const currentPreferences = await getPreference<{
|
||||
columns: ColumnPreference[]
|
||||
columns: ListPreferences['columns']
|
||||
}>(preferenceKey)
|
||||
|
||||
prevCollection.current = defaultCollection
|
||||
|
||||
@@ -10,10 +10,10 @@ import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { FieldDescription } from '../FieldDescription/index.js'
|
||||
import { FieldError } from '../FieldError/index.js'
|
||||
import './index.scss'
|
||||
import { FieldLabel } from '../FieldLabel/index.js'
|
||||
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||
import { fieldBaseClass } from '../shared/index.js'
|
||||
import './index.scss'
|
||||
|
||||
const baseClass = 'json-field'
|
||||
|
||||
@@ -31,9 +31,10 @@ const JSONFieldComponent: JSONFieldClientComponent = (props) => {
|
||||
readOnly,
|
||||
validate,
|
||||
} = props
|
||||
|
||||
const [stringValue, setStringValue] = useState<string>()
|
||||
const [jsonError, setJsonError] = useState<string>()
|
||||
const inputChangeFromRef = React.useRef<'system' | 'user'>('system')
|
||||
const [editorKey, setEditorKey] = useState<string>('')
|
||||
const [hasLoadedValue, setHasLoadedValue] = useState(false)
|
||||
|
||||
const memoizedValidate = useCallback(
|
||||
(value, options) => {
|
||||
@@ -55,12 +56,6 @@ const JSONFieldComponent: JSONFieldClientComponent = (props) => {
|
||||
validate: memoizedValidate,
|
||||
})
|
||||
|
||||
const [initialStringValue, setInitialStringValue] = useState<string | undefined>(() =>
|
||||
(value || initialValue) !== undefined
|
||||
? JSON.stringify(value ?? initialValue, null, 2)
|
||||
: undefined,
|
||||
)
|
||||
|
||||
const handleMount = useCallback<OnMount>(
|
||||
(editor, monaco) => {
|
||||
if (!jsonSchema) {
|
||||
@@ -93,7 +88,7 @@ const JSONFieldComponent: JSONFieldClientComponent = (props) => {
|
||||
if (readOnly) {
|
||||
return
|
||||
}
|
||||
inputChangeFromRef.current = 'user'
|
||||
setStringValue(val)
|
||||
|
||||
try {
|
||||
setValue(val ? JSON.parse(val) : null)
|
||||
@@ -103,21 +98,20 @@ const JSONFieldComponent: JSONFieldClientComponent = (props) => {
|
||||
setJsonError(e)
|
||||
}
|
||||
},
|
||||
[readOnly, setValue],
|
||||
[readOnly, setValue, setStringValue],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (inputChangeFromRef.current === 'system') {
|
||||
setInitialStringValue(
|
||||
(value || initialValue) !== undefined
|
||||
? JSON.stringify(value ?? initialValue, null, 2)
|
||||
: undefined,
|
||||
)
|
||||
setEditorKey(new Date().toString())
|
||||
if (hasLoadedValue || value === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
inputChangeFromRef.current = 'system'
|
||||
}, [initialValue, value])
|
||||
setStringValue(
|
||||
value || initialValue ? JSON.stringify(value ? value : initialValue, null, 2) : '',
|
||||
)
|
||||
|
||||
setHasLoadedValue(true)
|
||||
}, [initialValue, value, hasLoadedValue])
|
||||
|
||||
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||
|
||||
@@ -148,16 +142,12 @@ const JSONFieldComponent: JSONFieldClientComponent = (props) => {
|
||||
{BeforeInput}
|
||||
<CodeEditor
|
||||
defaultLanguage="json"
|
||||
key={editorKey}
|
||||
maxHeight={maxHeight}
|
||||
onChange={handleChange}
|
||||
onMount={handleMount}
|
||||
options={editorOptions}
|
||||
readOnly={readOnly}
|
||||
value={initialStringValue}
|
||||
wrapperProps={{
|
||||
id: `field-${path?.replace(/\./g, '__')}`,
|
||||
}}
|
||||
value={stringValue}
|
||||
/>
|
||||
{AfterInput}
|
||||
</div>
|
||||
|
||||
@@ -102,11 +102,7 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
|
||||
setCurrentQuery(newQuery)
|
||||
},
|
||||
[
|
||||
currentQuery?.page,
|
||||
currentQuery?.limit,
|
||||
currentQuery?.search,
|
||||
currentQuery?.sort,
|
||||
currentQuery?.where,
|
||||
currentQuery,
|
||||
defaultLimit,
|
||||
defaultSort,
|
||||
modifySearchParams,
|
||||
@@ -173,8 +169,7 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
|
||||
|
||||
if (shouldUpdateQueryString) {
|
||||
setCurrentQuery(newQuery)
|
||||
// Do not use router.replace here to avoid re-rendering on initial load
|
||||
window.history.replaceState(null, '', `?${qs.stringify(newQuery)}`)
|
||||
router.replace(`${qs.stringify(newQuery, { addQueryPrefix: true })}`)
|
||||
}
|
||||
}
|
||||
}, [defaultSort, defaultLimit, router, modifySearchParams])
|
||||
|
||||
@@ -3,10 +3,9 @@ import type {
|
||||
ClientConfig,
|
||||
ClientField,
|
||||
CollectionConfig,
|
||||
Column,
|
||||
ColumnPreference,
|
||||
Field,
|
||||
ImportMap,
|
||||
ListPreferences,
|
||||
PaginatedDocs,
|
||||
Payload,
|
||||
SanitizedCollectionConfig,
|
||||
@@ -15,6 +14,9 @@ import type {
|
||||
import { getTranslation, type I18nClient } from '@payloadcms/translations'
|
||||
import { fieldAffectsData, fieldIsHiddenOrDisabled, flattenTopLevelFields } from 'payload/shared'
|
||||
|
||||
// eslint-disable-next-line payload/no-imports-from-exports-dir
|
||||
import type { Column } from '../exports/client/index.js'
|
||||
|
||||
import { RenderServerComponent } from '../elements/RenderServerComponent/index.js'
|
||||
import { buildColumnState } from '../elements/TableColumns/buildColumnState.js'
|
||||
import { buildPolymorphicColumnState } from '../elements/TableColumns/buildPolymorphicColumnState.js'
|
||||
@@ -69,8 +71,8 @@ export const renderTable = ({
|
||||
clientConfig?: ClientConfig
|
||||
collectionConfig?: SanitizedCollectionConfig
|
||||
collections?: string[]
|
||||
columnPreferences: ColumnPreference[]
|
||||
columns?: ColumnPreference[]
|
||||
columnPreferences: ListPreferences['columns']
|
||||
columns?: ListPreferences['columns']
|
||||
customCellProps?: Record<string, any>
|
||||
docs: PaginatedDocs['docs']
|
||||
drawerSlug?: string
|
||||
@@ -107,7 +109,7 @@ export const renderTable = ({
|
||||
const columns = columnsFromArgs
|
||||
? columnsFromArgs?.filter((column) =>
|
||||
flattenTopLevelFields(fields, true)?.some(
|
||||
(field) => 'name' in field && column[field.name],
|
||||
(field) => 'name' in field && field.name === column.accessor,
|
||||
),
|
||||
)
|
||||
: getInitialColumns(fields, useAsTitle, [])
|
||||
@@ -128,7 +130,7 @@ export const renderTable = ({
|
||||
const columns = columnsFromArgs
|
||||
? columnsFromArgs?.filter((column) =>
|
||||
flattenTopLevelFields(clientCollectionConfig.fields, true)?.some(
|
||||
(field) => 'name' in field && field.name in column,
|
||||
(field) => 'name' in field && field.name === column.accessor,
|
||||
),
|
||||
)
|
||||
: getInitialColumns(
|
||||
|
||||
@@ -151,7 +151,6 @@ export function DefaultListView(props: ListViewClientProps) {
|
||||
])
|
||||
}
|
||||
}, [setStepNav, labels, drawerDepth])
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<TableColumnsProvider
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { useField } from '@payloadcms/ui'
|
||||
|
||||
export function AfterField() {
|
||||
const { setValue } = useField({ path: 'customJSON' })
|
||||
|
||||
return (
|
||||
<button
|
||||
id="set-custom-json"
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
setValue({
|
||||
users: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'John Doe',
|
||||
email: 'john.doe@example.com',
|
||||
isActive: true,
|
||||
roles: ['admin', 'editor'],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Jane Smith',
|
||||
email: 'jane.smith@example.com',
|
||||
isActive: false,
|
||||
roles: ['viewer'],
|
||||
},
|
||||
],
|
||||
})
|
||||
}}
|
||||
style={{ marginTop: '5px', padding: '5px 10px' }}
|
||||
type="button"
|
||||
>
|
||||
Set Custom JSON
|
||||
</button>
|
||||
)
|
||||
}
|
||||
@@ -103,24 +103,4 @@ describe('JSON', () => {
|
||||
'"foo.with.periods": "bar"',
|
||||
)
|
||||
})
|
||||
|
||||
test('should update', async () => {
|
||||
const createdDoc = await payload.create({
|
||||
collection: 'json-fields',
|
||||
data: {
|
||||
customJSON: {
|
||||
default: 'value',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
await page.goto(url.edit(createdDoc.id))
|
||||
const jsonField = page.locator('.json-field #field-customJSON')
|
||||
await expect(jsonField).toContainText('"default": "value"')
|
||||
|
||||
const originalHeight = (await page.locator('#field-customJSON').boundingBox())?.height || 0
|
||||
await page.locator('#set-custom-json').click()
|
||||
const newHeight = (await page.locator('#field-customJSON').boundingBox())?.height || 0
|
||||
expect(newHeight).toBeGreaterThan(originalHeight)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -67,16 +67,6 @@ const JSON: CollectionConfig = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'customJSON',
|
||||
type: 'json',
|
||||
admin: {
|
||||
components: {
|
||||
afterInput: ['./collections/JSON/AfterField#AfterField'],
|
||||
},
|
||||
},
|
||||
label: 'Custom Json',
|
||||
},
|
||||
],
|
||||
versions: {
|
||||
maxPerDoc: 1,
|
||||
|
||||
@@ -170,7 +170,12 @@ describe('Text', () => {
|
||||
user: client.user,
|
||||
key: 'text-fields-list',
|
||||
value: {
|
||||
columns: [{ disableListColumnText: true }],
|
||||
columns: [
|
||||
{
|
||||
accessor: 'disableListColumnText',
|
||||
active: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -1474,15 +1474,6 @@ export interface JsonField {
|
||||
| boolean
|
||||
| null;
|
||||
};
|
||||
customJSON?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
@@ -3174,7 +3165,6 @@ export interface JsonFieldsSelect<T extends boolean = true> {
|
||||
| {
|
||||
jsonWithinGroup?: T;
|
||||
};
|
||||
customJSON?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
|
||||
@@ -1205,22 +1205,6 @@ describe('Joins Field', () => {
|
||||
expect(parent.children.docs[1]?.value.id).toBe(child_1.id)
|
||||
expect(parent.children.docs[1]?.relationTo).toBe('multiple-collections-1')
|
||||
|
||||
// Pagination across collections
|
||||
parent = await payload.findByID({
|
||||
collection: 'multiple-collections-parents',
|
||||
id: parent.id,
|
||||
depth: 1,
|
||||
joins: {
|
||||
children: {
|
||||
limit: 1,
|
||||
sort: 'title',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(parent.children.docs).toHaveLength(1)
|
||||
expect(parent.children?.hasNextPage).toBe(true)
|
||||
|
||||
// Sorting across collections
|
||||
parent = await payload.findByID({
|
||||
collection: 'multiple-collections-parents',
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@payload-config": ["./test/_community/config.ts"],
|
||||
"@payload-config": ["./test/fields-relationship/config.ts"],
|
||||
"@payloadcms/live-preview": ["./packages/live-preview/src"],
|
||||
"@payloadcms/live-preview-react": ["./packages/live-preview-react/src/index.ts"],
|
||||
"@payloadcms/live-preview-vue": ["./packages/live-preview-vue/src/index.ts"],
|
||||
|
||||
Reference in New Issue
Block a user