Compare commits
23 Commits
db-postgre
...
feat/db-op
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9677872b5 | ||
|
|
358e979c9e | ||
|
|
b691c6c9a7 | ||
|
|
0c4547b890 | ||
|
|
83a060b3f7 | ||
|
|
e20248489a | ||
|
|
9f788b192d | ||
|
|
ab7845d5bc | ||
|
|
9a9ff781bf | ||
|
|
118287097f | ||
|
|
6b48734375 | ||
|
|
087a30df86 | ||
|
|
7baf43aa0f | ||
|
|
d9cbd446ff | ||
|
|
7da131a93e | ||
|
|
f5575049f7 | ||
|
|
9b11a75ef8 | ||
|
|
f3b809193d | ||
|
|
25d83c3d06 | ||
|
|
b693de557b | ||
|
|
7beb4db796 | ||
|
|
e2d4a2a59f | ||
|
|
a5444d0e7c |
@@ -78,6 +78,8 @@ To configure Collection database operations in your Payload application, your Co
|
||||
|
||||
The override methods receive arguments useful for augmenting operations such as Field data, the collection slug, and the req.
|
||||
|
||||
Relations and Migrations are not supported at this time on collections with custom database operations.
|
||||
|
||||
Here is an example:
|
||||
```ts
|
||||
import type { CollectionConfig } from 'payload/types'
|
||||
@@ -172,3 +174,47 @@ export const Collection: CollectionConfig => {
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Global Operations
|
||||
|
||||
You can also configure database operations on globals.
|
||||
|
||||
Like collection operations, the override methods receive arguments useful for augmenting operations such as the global slug, and the req.
|
||||
|
||||
Relations and Migrations are not supported at this time on globals with custom database operations.
|
||||
|
||||
Here is an example:
|
||||
```ts
|
||||
import type { CollectionConfig } from 'payload/types'
|
||||
|
||||
export const Collection: CollectionConfig => {
|
||||
return {
|
||||
globals: [
|
||||
{
|
||||
slug: 'global-db-operations',
|
||||
db: {
|
||||
createGlobal: () => {
|
||||
// ...
|
||||
},
|
||||
updateGlobal: () => {
|
||||
// ...
|
||||
},
|
||||
findGlobal: () => {
|
||||
// ...
|
||||
},
|
||||
findGlobalVersions: () => {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
@@ -2,6 +2,7 @@
|
||||
import type { PaginateOptions } from 'mongoose'
|
||||
import type { Init } from 'payload/database'
|
||||
import type { SanitizedCollectionConfig } from 'payload/types'
|
||||
import type { SanitizedGlobalConfig } from 'payload/types'
|
||||
|
||||
import mongoose from 'mongoose'
|
||||
import mongooseAggregatePaginate from 'mongoose-aggregate-paginate-v2'
|
||||
@@ -19,6 +20,9 @@ import { getDBName } from './utilities/getDBName'
|
||||
|
||||
export const init: Init = async function init(this: MongooseAdapter) {
|
||||
this.payload.config.collections.forEach((collection: SanitizedCollectionConfig) => {
|
||||
// Skip collections that have an .init() method
|
||||
if ('function' === typeof collection?.db?.init) return
|
||||
|
||||
const schema = buildCollectionSchema(collection, this)
|
||||
|
||||
if (collection.versions) {
|
||||
@@ -74,7 +78,10 @@ export const init: Init = async function init(this: MongooseAdapter) {
|
||||
const model = buildGlobalModel(this)
|
||||
this.globals = model
|
||||
|
||||
this.payload.config.globals.forEach((global) => {
|
||||
this.payload.config.globals.forEach((global: SanitizedGlobalConfig) => {
|
||||
// Skip globals that have an .init() method
|
||||
if ('function' === typeof global?.db?.init) return
|
||||
|
||||
if (global.versions) {
|
||||
const versionModelName = getDBName({ config: global, versions: true })
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import type { Init } from 'payload/database'
|
||||
import type { SanitizedCollectionConfig } from 'payload/types'
|
||||
import type { SanitizedGlobalConfig } from 'payload/types'
|
||||
|
||||
import { pgEnum, pgSchema, pgTable } from 'drizzle-orm/pg-core'
|
||||
import { buildVersionCollectionFields, buildVersionGlobalFields } from 'payload/versions'
|
||||
@@ -25,6 +26,9 @@ export const init: Init = async function init(this: PostgresAdapter) {
|
||||
}
|
||||
|
||||
this.payload.config.collections.forEach((collection: SanitizedCollectionConfig) => {
|
||||
// Skip collections that have an .init() method
|
||||
if ('function' === typeof collection?.db?.init) return
|
||||
|
||||
const tableName = createTableName({
|
||||
adapter: this,
|
||||
config: collection,
|
||||
@@ -67,7 +71,10 @@ export const init: Init = async function init(this: PostgresAdapter) {
|
||||
}
|
||||
})
|
||||
|
||||
this.payload.config.globals.forEach((global) => {
|
||||
this.payload.config.globals.forEach((global: SanitizedGlobalConfig) => {
|
||||
// Skip globals that have an .init() method
|
||||
if ('function' === typeof global?.db?.init) return
|
||||
|
||||
const tableName = createTableName({ adapter: this, config: global })
|
||||
|
||||
buildTable({
|
||||
|
||||
@@ -49,11 +49,21 @@ const getExecuteStaticAccess =
|
||||
})
|
||||
}
|
||||
|
||||
const doc = await req.payload.db.findOne({
|
||||
let doc: Record<string, unknown> | undefined
|
||||
|
||||
if (config?.db?.findOne) {
|
||||
doc = await config.db.findOne({
|
||||
collection: config.slug,
|
||||
req,
|
||||
where: queryToBuild,
|
||||
})
|
||||
} else {
|
||||
doc = await req.payload.db.findOne({
|
||||
collection: config.slug,
|
||||
req,
|
||||
where: queryToBuild,
|
||||
})
|
||||
}
|
||||
|
||||
if (!doc) {
|
||||
throw new Forbidden(req.t)
|
||||
|
||||
@@ -79,11 +79,18 @@ async function forgotPassword(incomingArgs: Arguments): Promise<null | string> {
|
||||
throw new APIError('Missing email.')
|
||||
}
|
||||
|
||||
let user = await payload.db.findOne<UserDoc>({
|
||||
const userDbArgs = {
|
||||
collection: collectionConfig.slug,
|
||||
req,
|
||||
where: { email: { equals: data.email.toLowerCase() } },
|
||||
})
|
||||
}
|
||||
|
||||
let user: UserDoc
|
||||
if (collectionConfig?.db?.findOne) {
|
||||
user = await collectionConfig.db.findOne<UserDoc>(userDbArgs)
|
||||
} else {
|
||||
user = await payload.db.findOne<UserDoc>(userDbArgs)
|
||||
}
|
||||
|
||||
if (!user) return null
|
||||
|
||||
|
||||
@@ -3,10 +3,20 @@ import type { PayloadRequest } from '../../express/types'
|
||||
async function init(args: { collection: string; req: PayloadRequest }): Promise<boolean> {
|
||||
const { collection: slug, req } = args
|
||||
|
||||
const doc = await req.payload.db.findOne({
|
||||
const collectionConfig = req.payload.config.collections[slug]
|
||||
|
||||
let doc: Record<string, unknown> | undefined
|
||||
if (collectionConfig?.db?.findOne) {
|
||||
doc = await collectionConfig.db.findOne({
|
||||
collection: slug,
|
||||
req,
|
||||
})
|
||||
} else {
|
||||
doc = await req.payload.db.findOne({
|
||||
collection: slug,
|
||||
req,
|
||||
})
|
||||
}
|
||||
|
||||
return !!doc
|
||||
}
|
||||
|
||||
@@ -95,11 +95,18 @@ async function login<TSlug extends keyof GeneratedTypes['collections']>(
|
||||
|
||||
const email = unsanitizedEmail ? unsanitizedEmail.toLowerCase().trim() : null
|
||||
|
||||
let user = await payload.db.findOne<any>({
|
||||
const userDbArgs = {
|
||||
collection: collectionConfig.slug,
|
||||
req,
|
||||
where: { email: { equals: email.toLowerCase() } },
|
||||
})
|
||||
}
|
||||
|
||||
let user: any
|
||||
if (collectionConfig?.db?.findOne) {
|
||||
user = await collectionConfig.db.findOne(userDbArgs)
|
||||
} else {
|
||||
user = await req.payload.db.findOne<any>(userDbArgs)
|
||||
}
|
||||
|
||||
if (!user || (args.collection.config.auth.verify && user._verified === false)) {
|
||||
throw new AuthenticationError(req.t)
|
||||
|
||||
@@ -32,8 +32,8 @@ async function registerFirstUser<TSlug extends keyof GeneratedTypes['collections
|
||||
collection: {
|
||||
config,
|
||||
config: {
|
||||
auth: { verify },
|
||||
slug,
|
||||
auth: { verify },
|
||||
},
|
||||
},
|
||||
data,
|
||||
@@ -44,10 +44,18 @@ async function registerFirstUser<TSlug extends keyof GeneratedTypes['collections
|
||||
try {
|
||||
const shouldCommit = await initTransaction(req)
|
||||
|
||||
const doc = await payload.db.findOne({
|
||||
let doc
|
||||
if (config?.db?.findOne) {
|
||||
doc = await config.db.findOne({
|
||||
collection: config.slug,
|
||||
req,
|
||||
})
|
||||
} else {
|
||||
doc = await payload.db.findOne({
|
||||
collection: config.slug,
|
||||
req,
|
||||
})
|
||||
}
|
||||
|
||||
if (doc) throw new Forbidden(req.t)
|
||||
|
||||
|
||||
@@ -58,14 +58,21 @@ async function resetPassword(args: Arguments): Promise<Result> {
|
||||
// Reset Password
|
||||
// /////////////////////////////////////
|
||||
|
||||
const user = await payload.db.findOne<any>({
|
||||
const userDbArgs = {
|
||||
collection: collectionConfig.slug,
|
||||
req,
|
||||
where: {
|
||||
resetPasswordExpiration: { greater_than: new Date() },
|
||||
resetPasswordToken: { equals: data.token },
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
let user: any
|
||||
if (collectionConfig?.db?.findOne) {
|
||||
user = await collectionConfig.db.findOne<any>(userDbArgs)
|
||||
} else {
|
||||
user = await payload.db.findOne<any>(userDbArgs)
|
||||
}
|
||||
|
||||
if (!user) throw new APIError('Token is either invalid or has expired.')
|
||||
|
||||
@@ -81,12 +88,18 @@ async function resetPassword(args: Arguments): Promise<Result> {
|
||||
user._verified = true
|
||||
}
|
||||
|
||||
const doc = await payload.db.updateOne({
|
||||
const updateDbArgs = {
|
||||
id: user.id,
|
||||
collection: collectionConfig.slug,
|
||||
data: user,
|
||||
req,
|
||||
})
|
||||
}
|
||||
let doc: any
|
||||
if (collectionConfig?.db?.updateOne) {
|
||||
doc = await collectionConfig.db.updateOne(updateDbArgs)
|
||||
} else {
|
||||
doc = await payload.db.updateOne(updateDbArgs)
|
||||
}
|
||||
|
||||
await authenticateLocalStrategy({ doc, password: data.password })
|
||||
|
||||
|
||||
@@ -52,12 +52,19 @@ async function unlock(args: Args): Promise<boolean> {
|
||||
throw new APIError('Missing email.')
|
||||
}
|
||||
|
||||
const user = await req.payload.db.findOne({
|
||||
const userDbArgs = {
|
||||
collection: collectionConfig.slug,
|
||||
locale,
|
||||
req,
|
||||
where: { email: { equals: data.email.toLowerCase() } },
|
||||
})
|
||||
}
|
||||
|
||||
let user: any
|
||||
if (collectionConfig?.db?.findOne) {
|
||||
user = await collectionConfig.db.findOne<any>(userDbArgs)
|
||||
} else {
|
||||
user = await req.payload.db.findOne<any>(userDbArgs)
|
||||
}
|
||||
|
||||
let result
|
||||
|
||||
|
||||
@@ -23,19 +23,25 @@ async function verifyEmail(args: Args): Promise<boolean> {
|
||||
try {
|
||||
const shouldCommit = await initTransaction(req)
|
||||
|
||||
const user = await req.payload.db.findOne<any>({
|
||||
const userDbArgs = {
|
||||
collection: collection.config.slug,
|
||||
req,
|
||||
where: {
|
||||
_verificationToken: { equals: token },
|
||||
},
|
||||
})
|
||||
}
|
||||
let user: any
|
||||
if (collection.config?.db?.findOne) {
|
||||
user = await collection.config.db.findOne<any>(userDbArgs)
|
||||
} else {
|
||||
user = await req.payload.db.findOne<any>(userDbArgs)
|
||||
}
|
||||
|
||||
if (!user) throw new APIError('Verification token is invalid.', httpStatus.BAD_REQUEST)
|
||||
if (user && user._verified === true)
|
||||
throw new APIError('This account has already been activated.', httpStatus.ACCEPTED)
|
||||
|
||||
await req.payload.db.updateOne({
|
||||
const updateDbArgs = {
|
||||
id: user.id,
|
||||
collection: collection.config.slug,
|
||||
data: {
|
||||
@@ -44,7 +50,13 @@ async function verifyEmail(args: Args): Promise<boolean> {
|
||||
_verified: true,
|
||||
},
|
||||
req,
|
||||
})
|
||||
}
|
||||
|
||||
if (collection.config?.db?.updateOne) {
|
||||
await collection.config.db.updateOne(updateDbArgs)
|
||||
} else {
|
||||
await req.payload.db.updateOne(updateDbArgs)
|
||||
}
|
||||
|
||||
if (shouldCommit) await commitTransaction(req)
|
||||
|
||||
|
||||
@@ -387,9 +387,30 @@ export type CollectionConfig = {
|
||||
/**
|
||||
* Add a custom database adapter to this collection.
|
||||
*/
|
||||
db?: Pick<
|
||||
db?:
|
||||
| DatabaseAdapter
|
||||
| Pick<
|
||||
DatabaseAdapter,
|
||||
'create' | 'deleteMany' | 'deleteOne' | 'find' | 'findOne' | 'updateOne'
|
||||
| 'connect'
|
||||
| 'count'
|
||||
| 'create'
|
||||
| 'createGlobal'
|
||||
| 'createGlobalVersion'
|
||||
| 'createVersion'
|
||||
| 'deleteMany'
|
||||
| 'deleteOne'
|
||||
| 'deleteVersions'
|
||||
| 'find'
|
||||
| 'findGlobal'
|
||||
| 'findGlobalVersions'
|
||||
| 'findOne'
|
||||
| 'findVersions'
|
||||
| 'init'
|
||||
| 'queryDrafts'
|
||||
| 'updateGlobal'
|
||||
| 'updateGlobalVersion'
|
||||
| 'updateOne'
|
||||
| 'updateVersion'
|
||||
>
|
||||
/**
|
||||
* Used to override the default naming of the database table or collection with your using a function or string
|
||||
|
||||
@@ -80,11 +80,16 @@ async function count<T extends TypeWithID & Record<string, unknown>>(
|
||||
where,
|
||||
})
|
||||
|
||||
result = await payload.db.count({
|
||||
const countDbArgs = {
|
||||
collection: collectionConfig.slug,
|
||||
req,
|
||||
where: fullWhere,
|
||||
})
|
||||
}
|
||||
if (collectionConfig?.db?.count) {
|
||||
result = await collectionConfig.db.count(countDbArgs)
|
||||
} else {
|
||||
result = await payload.db.count(countDbArgs)
|
||||
}
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterOperation - Collection
|
||||
|
||||
@@ -124,7 +124,7 @@ async function find<T extends TypeWithID & Record<string, unknown>>(
|
||||
where: fullWhere,
|
||||
})
|
||||
|
||||
result = await payload.db.queryDrafts<T>({
|
||||
const queryDraftArgs = {
|
||||
collection: collectionConfig.slug,
|
||||
limit: sanitizedLimit,
|
||||
locale,
|
||||
@@ -133,7 +133,12 @@ async function find<T extends TypeWithID & Record<string, unknown>>(
|
||||
req,
|
||||
sort: getQueryDraftsSort(sort),
|
||||
where: fullWhere,
|
||||
})
|
||||
}
|
||||
if (collectionConfig?.db?.queryDrafts) {
|
||||
result = await collectionConfig.db.queryDrafts<T>(queryDraftArgs)
|
||||
} else {
|
||||
result = await payload.db.queryDrafts<T>(queryDraftArgs)
|
||||
}
|
||||
} else {
|
||||
await validateQueryPaths({
|
||||
collectionConfig,
|
||||
|
||||
@@ -65,14 +65,21 @@ async function findVersionByID<T extends TypeWithID = any>(
|
||||
// Find by ID
|
||||
// /////////////////////////////////////
|
||||
|
||||
const versionsQuery = await payload.db.findVersions<T>({
|
||||
const findVersionsDbArgs = {
|
||||
collection: collectionConfig.slug,
|
||||
limit: 1,
|
||||
locale,
|
||||
pagination: false,
|
||||
req,
|
||||
where: fullWhere,
|
||||
})
|
||||
}
|
||||
|
||||
let versionsQuery
|
||||
if (collectionConfig?.db?.findVersions) {
|
||||
versionsQuery = await collectionConfig.db.findVersions<T>(findVersionsDbArgs)
|
||||
} else {
|
||||
versionsQuery = await payload.db.findVersions<T>(findVersionsDbArgs)
|
||||
}
|
||||
|
||||
const result = versionsQuery.docs[0]
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ async function findVersions<T extends TypeWithVersion<T>>(
|
||||
// Find
|
||||
// /////////////////////////////////////
|
||||
|
||||
const paginatedDocs = await payload.db.findVersions<T>({
|
||||
const findVersionsDbArgs = {
|
||||
collection: collectionConfig.slug,
|
||||
limit: limit ?? 10,
|
||||
locale,
|
||||
@@ -82,7 +82,14 @@ async function findVersions<T extends TypeWithVersion<T>>(
|
||||
req,
|
||||
sort,
|
||||
where: fullWhere,
|
||||
})
|
||||
}
|
||||
let paginatedDocs
|
||||
|
||||
if (collectionConfig?.db?.findVersions) {
|
||||
paginatedDocs = await collectionConfig.db.findVersions<T>(findVersionsDbArgs)
|
||||
} else {
|
||||
paginatedDocs = await payload.db.findVersions<T>(findVersionsDbArgs)
|
||||
}
|
||||
|
||||
// /////////////////////////////////////
|
||||
// beforeRead - Collection
|
||||
|
||||
@@ -49,13 +49,21 @@ async function restoreVersion<T extends TypeWithID = any>(args: Arguments): Prom
|
||||
// Retrieve original raw version
|
||||
// /////////////////////////////////////
|
||||
|
||||
const { docs: versionDocs } = await req.payload.db.findVersions({
|
||||
const findVersionDbArgs = {
|
||||
collection: collectionConfig.slug,
|
||||
limit: 1,
|
||||
locale,
|
||||
req,
|
||||
where: { id: { equals: id } },
|
||||
})
|
||||
}
|
||||
|
||||
let queryResult: any
|
||||
if (collectionConfig?.db?.findVersions) {
|
||||
queryResult = await collectionConfig.db.findVersions(findVersionDbArgs)
|
||||
} else {
|
||||
queryResult = await req.payload.db.findVersions(findVersionDbArgs)
|
||||
}
|
||||
const versionDocs = queryResult.docs
|
||||
|
||||
const [rawVersion] = versionDocs
|
||||
|
||||
@@ -132,7 +140,7 @@ async function restoreVersion<T extends TypeWithID = any>(args: Arguments): Prom
|
||||
|
||||
delete prevVersion.id
|
||||
|
||||
await payload.db.createVersion({
|
||||
const createVersionDbArgs = {
|
||||
autosave: false,
|
||||
collectionSlug: collectionConfig.slug,
|
||||
createdAt: prevVersion.createdAt,
|
||||
@@ -140,7 +148,12 @@ async function restoreVersion<T extends TypeWithID = any>(args: Arguments): Prom
|
||||
req,
|
||||
updatedAt: new Date().toISOString(),
|
||||
versionData: rawVersion.version,
|
||||
})
|
||||
}
|
||||
if (collectionConfig?.db?.createVersion) {
|
||||
await collectionConfig.db.createVersion(createVersionDbArgs)
|
||||
} else {
|
||||
await payload.db.createVersion(createVersionDbArgs)
|
||||
}
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterRead - Fields
|
||||
|
||||
@@ -128,12 +128,22 @@ async function update<TSlug extends keyof GeneratedTypes['collections']>(
|
||||
where: versionsWhere,
|
||||
})
|
||||
|
||||
const query = await payload.db.queryDrafts<GeneratedTypes['collections'][TSlug]>({
|
||||
const queryDraftsDbArgs = {
|
||||
collection: collectionConfig.slug,
|
||||
locale,
|
||||
req,
|
||||
where: versionsWhere,
|
||||
})
|
||||
}
|
||||
let query: any
|
||||
if (collection.config?.db?.queryDrafts) {
|
||||
query =
|
||||
await collection.config.db.queryDrafts<GeneratedTypes['collections'][TSlug]>(
|
||||
queryDraftsDbArgs,
|
||||
)
|
||||
} else {
|
||||
query =
|
||||
await payload.db.queryDrafts<GeneratedTypes['collections'][TSlug]>(queryDraftsDbArgs)
|
||||
}
|
||||
|
||||
docs = query.docs
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { GraphQLNonNull, GraphQLObjectType } from 'graphql'
|
||||
import type { DeepRequired } from 'ts-essentials'
|
||||
|
||||
import type { DatabaseAdapter } from '../../'
|
||||
import type {
|
||||
CustomPreviewButtonProps,
|
||||
CustomPublishButtonType,
|
||||
@@ -170,6 +171,34 @@ export type GlobalConfig = {
|
||||
admin?: GlobalAdminOptions
|
||||
/** Extension point to add your custom data. */
|
||||
custom?: Record<string, any>
|
||||
/**
|
||||
* Add a custom database adapter to this global.
|
||||
*/
|
||||
db?:
|
||||
| DatabaseAdapter
|
||||
| Pick<
|
||||
DatabaseAdapter,
|
||||
| 'connect'
|
||||
| 'count'
|
||||
| 'create'
|
||||
| 'createGlobal'
|
||||
| 'createGlobalVersion'
|
||||
| 'createVersion'
|
||||
| 'deleteMany'
|
||||
| 'deleteOne'
|
||||
| 'deleteVersions'
|
||||
| 'find'
|
||||
| 'findGlobal'
|
||||
| 'findGlobalVersions'
|
||||
| 'findOne'
|
||||
| 'findVersions'
|
||||
| 'init'
|
||||
| 'queryDrafts'
|
||||
| 'updateGlobal'
|
||||
| 'updateGlobalVersion'
|
||||
| 'updateOne'
|
||||
| 'updateVersion'
|
||||
>
|
||||
/**
|
||||
* Customize the SQL table name
|
||||
*/
|
||||
|
||||
@@ -50,12 +50,18 @@ async function findOne<T extends Record<string, unknown>>(args: Args): Promise<T
|
||||
// Perform database operation
|
||||
// /////////////////////////////////////
|
||||
|
||||
let doc = await req.payload.db.findGlobal({
|
||||
const findGlobalArgs = {
|
||||
slug,
|
||||
locale,
|
||||
req,
|
||||
where: overrideAccess ? undefined : (accessResult as Where),
|
||||
})
|
||||
}
|
||||
let doc
|
||||
if (globalConfig?.db?.findGlobal) {
|
||||
doc = await globalConfig.db.findGlobal(findGlobalArgs)
|
||||
} else {
|
||||
doc = await req.payload.db.findGlobal(findGlobalArgs)
|
||||
}
|
||||
if (!doc) {
|
||||
doc = {}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,13 @@ async function findVersionByID<T extends TypeWithVersion<T> = any>(args: Argumen
|
||||
|
||||
if (!findGlobalVersionsArgs.where.and[0].id) throw new NotFound(t)
|
||||
|
||||
const { docs: results } = await payload.db.findGlobalVersions(findGlobalVersionsArgs)
|
||||
let globalVersions: any
|
||||
if (globalConfig?.db?.findGlobalVersions) {
|
||||
globalVersions = await globalConfig.db.findGlobalVersions(findGlobalVersionsArgs)
|
||||
} else {
|
||||
globalVersions = await payload.db.findGlobalVersions(findGlobalVersionsArgs)
|
||||
}
|
||||
const results = globalVersions.docs
|
||||
if (!results || results?.length === 0) {
|
||||
if (!disableErrors) {
|
||||
if (!hasWhereAccess) throw new NotFound(t)
|
||||
|
||||
@@ -69,7 +69,7 @@ async function findVersions<T extends TypeWithVersion<T>>(
|
||||
// Find
|
||||
// /////////////////////////////////////
|
||||
|
||||
const paginatedDocs = await payload.db.findGlobalVersions<T>({
|
||||
const paginatedDocsArgs = {
|
||||
global: globalConfig.slug,
|
||||
limit: limit ?? 10,
|
||||
locale,
|
||||
@@ -77,7 +77,13 @@ async function findVersions<T extends TypeWithVersion<T>>(
|
||||
req,
|
||||
sort,
|
||||
where: fullWhere,
|
||||
})
|
||||
}
|
||||
let paginatedDocs: any
|
||||
if (globalConfig?.db?.findGlobalVersions) {
|
||||
paginatedDocs = await globalConfig.db.findGlobalVersions<T>(paginatedDocsArgs)
|
||||
} else {
|
||||
paginatedDocs = await payload.db.findGlobalVersions<T>(paginatedDocsArgs)
|
||||
}
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterRead - Fields
|
||||
|
||||
@@ -45,12 +45,19 @@ async function restoreVersion<T extends TypeWithVersion<T> = any>(args: Argument
|
||||
// Retrieve original raw version
|
||||
// /////////////////////////////////////
|
||||
|
||||
const { docs: versionDocs } = await payload.db.findGlobalVersions<any>({
|
||||
const findGlobalDbArgs = {
|
||||
global: globalConfig.slug,
|
||||
limit: 1,
|
||||
req,
|
||||
where: { id: { equals: id } },
|
||||
})
|
||||
}
|
||||
let findGlobalResult: any
|
||||
if (globalConfig?.db?.findGlobalVersions) {
|
||||
findGlobalResult = await globalConfig.db.findGlobalVersions<any>(findGlobalDbArgs)
|
||||
} else {
|
||||
findGlobalResult = await payload.db.findGlobalVersions<any>(findGlobalDbArgs)
|
||||
}
|
||||
const versionDocs = findGlobalResult.docs
|
||||
|
||||
if (!versionDocs || versionDocs.length === 0) {
|
||||
throw new NotFound(t)
|
||||
@@ -75,25 +82,38 @@ async function restoreVersion<T extends TypeWithVersion<T> = any>(args: Argument
|
||||
// Update global
|
||||
// /////////////////////////////////////
|
||||
|
||||
const global = await payload.db.findGlobal({
|
||||
let global: any
|
||||
if (globalConfig?.db?.findGlobal) {
|
||||
global = await globalConfig.db.findGlobal({
|
||||
slug: globalConfig.slug,
|
||||
req,
|
||||
})
|
||||
|
||||
let result = rawVersion.version
|
||||
|
||||
if (global) {
|
||||
result = await payload.db.updateGlobal({
|
||||
slug: globalConfig.slug,
|
||||
data: result,
|
||||
req,
|
||||
})
|
||||
} else {
|
||||
result = await payload.db.createGlobal({
|
||||
global = await payload.db.findGlobal({
|
||||
slug: globalConfig.slug,
|
||||
req,
|
||||
})
|
||||
}
|
||||
|
||||
let result = rawVersion.version
|
||||
|
||||
const globalDbArgs = {
|
||||
slug: globalConfig.slug,
|
||||
data: result,
|
||||
req,
|
||||
})
|
||||
}
|
||||
if (global) {
|
||||
if (globalConfig?.db?.updateGlobal) {
|
||||
result = await globalConfig.db.updateGlobal(globalDbArgs)
|
||||
} else {
|
||||
result = await payload.db.updateGlobal(globalDbArgs)
|
||||
}
|
||||
} else {
|
||||
if (globalConfig?.db?.createGlobal) {
|
||||
result = await globalConfig.db.createGlobal(globalDbArgs)
|
||||
} else {
|
||||
result = await payload.db.createGlobal(globalDbArgs)
|
||||
}
|
||||
}
|
||||
|
||||
// /////////////////////////////////////
|
||||
|
||||
@@ -44,7 +44,11 @@ async function update<TSlug extends keyof GeneratedTypes['globals']>(
|
||||
} = args
|
||||
|
||||
try {
|
||||
const shouldCommit = await initTransaction(req)
|
||||
const isCustomGlobalDb = Boolean(
|
||||
globalConfig?.db?.updateGlobal || globalConfig?.db?.createGlobal,
|
||||
)
|
||||
|
||||
const shouldCommit = !isCustomGlobalDb && (await initTransaction(req))
|
||||
|
||||
let { data } = args
|
||||
|
||||
@@ -177,18 +181,23 @@ async function update<TSlug extends keyof GeneratedTypes['globals']>(
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (!shouldSaveDraft) {
|
||||
const globalDbArgs = {
|
||||
slug,
|
||||
data: result,
|
||||
req,
|
||||
}
|
||||
if (globalExists) {
|
||||
result = await payload.db.updateGlobal({
|
||||
slug,
|
||||
data: result,
|
||||
req,
|
||||
})
|
||||
if (globalConfig?.db?.updateGlobal) {
|
||||
result = await globalConfig.db.updateGlobal(globalDbArgs)
|
||||
} else {
|
||||
result = await payload.db.createGlobal({
|
||||
slug,
|
||||
data: result,
|
||||
req,
|
||||
})
|
||||
result = await payload.db.updateGlobal(globalDbArgs)
|
||||
}
|
||||
} else {
|
||||
if (globalConfig?.db?.createGlobal) {
|
||||
result = await globalConfig.db.createGlobal(globalDbArgs)
|
||||
} else {
|
||||
result = await payload.db.createGlobal(globalDbArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -352,13 +352,34 @@ export class BasePayload<TGeneratedTypes extends GeneratedTypes> {
|
||||
this.config = await loadConfig(this.logger)
|
||||
}
|
||||
|
||||
const globalDbConnections = {}
|
||||
const globalDbInitializations = {}
|
||||
const collectionDbConnections = {}
|
||||
const collectionDbInitializations = {}
|
||||
this.globals = {
|
||||
config: this.config.globals,
|
||||
}
|
||||
|
||||
this.config.globals.forEach((global) => {
|
||||
if ('function' === typeof global.db?.connect) {
|
||||
globalDbConnections[global.slug] = global.db.connect
|
||||
}
|
||||
if ('function' === typeof global.db?.init) {
|
||||
globalDbInitializations[global.slug] = global.db.init
|
||||
}
|
||||
})
|
||||
|
||||
this.config.collections.forEach((collection) => {
|
||||
this.collections[collection.slug] = {
|
||||
config: collection,
|
||||
}
|
||||
|
||||
if ('function' === typeof collection.db?.connect) {
|
||||
collectionDbConnections[collection.slug] = collection.db.connect
|
||||
}
|
||||
if ('function' === typeof collection.db?.init) {
|
||||
collectionDbInitializations[collection.slug] = collection.db.init
|
||||
}
|
||||
})
|
||||
|
||||
this.db = this.config.db({ payload: this })
|
||||
@@ -368,8 +389,22 @@ export class BasePayload<TGeneratedTypes extends GeneratedTypes> {
|
||||
await this.db.init(this)
|
||||
}
|
||||
|
||||
Object.keys(globalDbInitializations).forEach(async (slug) => {
|
||||
await globalDbInitializations[slug](this)
|
||||
})
|
||||
Object.keys(collectionDbInitializations).forEach(async (slug) => {
|
||||
await collectionDbInitializations[slug](this)
|
||||
})
|
||||
|
||||
if (!options.disableDBConnect && this.db.connect) {
|
||||
await this.db.connect(this)
|
||||
|
||||
Object.keys(globalDbConnections).forEach(async (slug) => {
|
||||
await globalDbConnections[slug](this)
|
||||
})
|
||||
Object.keys(collectionDbConnections).forEach(async (slug) => {
|
||||
await collectionDbConnections[slug](this)
|
||||
})
|
||||
}
|
||||
|
||||
this.logger.info('Starting Payload...')
|
||||
|
||||
@@ -13,7 +13,7 @@ type Args = {
|
||||
}
|
||||
export const deleteUserPreferences = async ({ collectionConfig, ids, payload, req }: Args) => {
|
||||
if (collectionConfig.auth) {
|
||||
await payload.db.deleteMany({
|
||||
const deleteManyAuthDbArgs = {
|
||||
collection: 'payload-preferences',
|
||||
req,
|
||||
where: {
|
||||
@@ -26,13 +26,24 @@ export const deleteUserPreferences = async ({ collectionConfig, ids, payload, re
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
}
|
||||
await payload.db.deleteMany({
|
||||
if (collectionConfig?.db?.deleteMany) {
|
||||
await collectionConfig.db.deleteMany(deleteManyAuthDbArgs)
|
||||
} else {
|
||||
await payload.db.deleteMany(deleteManyAuthDbArgs)
|
||||
}
|
||||
}
|
||||
|
||||
const deleteManyDbArgs = {
|
||||
collection: 'payload-preferences',
|
||||
req,
|
||||
where: {
|
||||
key: { in: ids.map((id) => `collection-${collectionConfig.slug}-${id}`) },
|
||||
},
|
||||
})
|
||||
}
|
||||
if (collectionConfig?.db?.deleteMany) {
|
||||
await collectionConfig.db.deleteMany(deleteManyDbArgs)
|
||||
} else {
|
||||
await payload.db.deleteMany(deleteManyDbArgs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ type Args = {
|
||||
}
|
||||
|
||||
const docWithFilenameExists = async ({ collectionSlug, filename, req }: Args): Promise<boolean> => {
|
||||
const doc = await req.payload.db.findOne({
|
||||
const collectionConfig = req.payload.config.collections[collectionSlug]
|
||||
const dbArgs = {
|
||||
collection: collectionSlug,
|
||||
req,
|
||||
where: {
|
||||
@@ -16,7 +17,13 @@ const docWithFilenameExists = async ({ collectionSlug, filename, req }: Args): P
|
||||
equals: filename,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
let doc: any
|
||||
if (collectionConfig?.db?.findOne) {
|
||||
doc = await collectionConfig.db.findOne(dbArgs)
|
||||
} else {
|
||||
doc = await req.payload.db.findOne(dbArgs)
|
||||
}
|
||||
if (doc) return true
|
||||
|
||||
return false
|
||||
|
||||
@@ -8,9 +8,9 @@ type Args = {
|
||||
slug: string
|
||||
}
|
||||
|
||||
export const deleteCollectionVersions = async ({ id, payload, req, slug }: Args): Promise<void> => {
|
||||
export const deleteCollectionVersions = async ({ id, slug, payload, req }: Args): Promise<void> => {
|
||||
try {
|
||||
await payload.db.deleteVersions({
|
||||
const dbArgs = {
|
||||
collection: slug,
|
||||
req,
|
||||
where: {
|
||||
@@ -18,7 +18,13 @@ export const deleteCollectionVersions = async ({ id, payload, req, slug }: Args)
|
||||
equals: id,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
const collectionConfig = payload.config.collections[slug]
|
||||
if (collectionConfig?.db?.deleteVersions) {
|
||||
await collectionConfig.db.deleteVersions(dbArgs)
|
||||
} else {
|
||||
await payload.db.deleteVersions(dbArgs)
|
||||
}
|
||||
} catch (err) {
|
||||
payload.logger.error(
|
||||
`There was an error removing versions for the deleted ${slug} document with ID ${id}.`,
|
||||
|
||||
@@ -72,10 +72,18 @@ const replaceWithDraftIfAvailable = async <T extends TypeWithID>({
|
||||
|
||||
let versionDocs
|
||||
if (entityType === 'global') {
|
||||
if (entity?.db?.findGlobalVersions) {
|
||||
versionDocs = (await entity.db.findGlobalVersions<T>(findVersionsArgs)).docs
|
||||
} else {
|
||||
versionDocs = (await req.payload.db.findGlobalVersions<T>(findVersionsArgs)).docs
|
||||
}
|
||||
} else {
|
||||
if (entity?.db?.findVersions) {
|
||||
versionDocs = (await entity.db.findVersions<T>(findVersionsArgs)).docs
|
||||
} else {
|
||||
versionDocs = (await req.payload.db.findVersions<T>(findVersionsArgs)).docs
|
||||
}
|
||||
}
|
||||
|
||||
let draft = versionDocs[0]
|
||||
|
||||
|
||||
@@ -33,24 +33,36 @@ export const enforceMaxVersions = async ({
|
||||
equals: id,
|
||||
}
|
||||
|
||||
const query = await payload.db.findVersions({
|
||||
const findVersionsDbArgs = {
|
||||
collection: collection.slug,
|
||||
pagination: false,
|
||||
req,
|
||||
skip: max,
|
||||
sort: '-updatedAt',
|
||||
where,
|
||||
})
|
||||
}
|
||||
let query: any
|
||||
if (collection?.db?.findVersions) {
|
||||
query = await collection.db.findVersions(findVersionsDbArgs)
|
||||
} else {
|
||||
query = await payload.db.findVersions(findVersionsDbArgs)
|
||||
}
|
||||
|
||||
;[oldestAllowedDoc] = query.docs
|
||||
} else if (global) {
|
||||
const query = await payload.db.findGlobalVersions({
|
||||
const findGlobalVersionsDbArgs = {
|
||||
global: global.slug,
|
||||
req,
|
||||
skip: max,
|
||||
sort: '-updatedAt',
|
||||
where,
|
||||
})
|
||||
}
|
||||
let query: any
|
||||
if (global?.db?.findGlobalVersions) {
|
||||
query = await global.db.findGlobalVersions(findGlobalVersionsDbArgs)
|
||||
} else {
|
||||
query = await payload.db.findGlobalVersions(findGlobalVersionsDbArgs)
|
||||
}
|
||||
|
||||
;[oldestAllowedDoc] = query.docs
|
||||
}
|
||||
@@ -68,11 +80,17 @@ export const enforceMaxVersions = async ({
|
||||
}
|
||||
}
|
||||
|
||||
await payload.db.deleteVersions({
|
||||
const deleteDbArgs = {
|
||||
collection: collection?.slug,
|
||||
req,
|
||||
where: deleteQuery,
|
||||
})
|
||||
}
|
||||
|
||||
if (collection?.db?.deleteVersions) {
|
||||
await collection.db.deleteVersions(deleteDbArgs)
|
||||
} else {
|
||||
await payload.db.deleteVersions(deleteDbArgs)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
payload.logger.error(
|
||||
|
||||
@@ -26,14 +26,21 @@ export const getLatestCollectionVersion = async <T extends TypeWithID = any>({
|
||||
const hasConfigDb = Object.keys(config?.db ? config?.db : {}).length > 0
|
||||
|
||||
if (config.versions?.drafts && !hasConfigDb) {
|
||||
const { docs } = await payload.db.findVersions<T>({
|
||||
const findVersionsDbArgs = {
|
||||
collection: config.slug,
|
||||
limit: 1,
|
||||
pagination: false,
|
||||
req,
|
||||
sort: '-updatedAt',
|
||||
where: { parent: { equals: id } },
|
||||
})
|
||||
}
|
||||
let result: any
|
||||
if (config?.db?.findVersions) {
|
||||
result = await config.db.findVersions<T>(findVersionsDbArgs)
|
||||
} else {
|
||||
result = await payload.db.findVersions<T>(findVersionsDbArgs)
|
||||
}
|
||||
const docs = result.docs
|
||||
;[latestVersion] = docs
|
||||
}
|
||||
|
||||
|
||||
@@ -14,34 +14,45 @@ type Args = {
|
||||
}
|
||||
|
||||
export const getLatestGlobalVersion = async ({
|
||||
slug,
|
||||
config,
|
||||
locale,
|
||||
payload,
|
||||
req,
|
||||
slug,
|
||||
where,
|
||||
}: Args): Promise<{ global: Document; globalExists: boolean }> => {
|
||||
let latestVersion
|
||||
|
||||
const globalConfig = payload.config.globals?.find((cfg) => cfg.slug === slug)
|
||||
|
||||
if (config.versions?.drafts) {
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
latestVersion = (
|
||||
await payload.db.findGlobalVersions({
|
||||
const findVersionsDbArgs = {
|
||||
global: slug,
|
||||
limit: 1,
|
||||
locale,
|
||||
req,
|
||||
sort: '-updatedAt',
|
||||
})
|
||||
).docs[0]
|
||||
}
|
||||
|
||||
const global = await payload.db.findGlobal({
|
||||
if (globalConfig?.db?.findGlobalVersions) {
|
||||
latestVersion = (await globalConfig.db.findGlobalVersions(findVersionsDbArgs)).docs[0]
|
||||
} else {
|
||||
latestVersion = (await payload.db.findGlobalVersions(findVersionsDbArgs)).docs[0]
|
||||
}
|
||||
}
|
||||
|
||||
const findGlobalArgs = {
|
||||
slug,
|
||||
locale,
|
||||
req,
|
||||
slug,
|
||||
where,
|
||||
})
|
||||
}
|
||||
let global
|
||||
if (globalConfig?.db?.findGlobal) {
|
||||
global = await globalConfig.db.findGlobal(findGlobalArgs)
|
||||
} else {
|
||||
global = await payload.db.findGlobal(findGlobalArgs)
|
||||
}
|
||||
const globalExists = Boolean(global)
|
||||
|
||||
if (!latestVersion || (docHasTimestamps(global) && latestVersion.updatedAt < global.updatedAt)) {
|
||||
|
||||
@@ -44,7 +44,7 @@ export const saveVersion = async ({
|
||||
sort: '-updatedAt',
|
||||
}
|
||||
if (collection) {
|
||||
;({ docs } = await payload.db.findVersions({
|
||||
const findVersionsDbArgs = {
|
||||
...findVersionArgs,
|
||||
collection: collection.slug,
|
||||
req,
|
||||
@@ -53,13 +53,24 @@ export const saveVersion = async ({
|
||||
equals: id,
|
||||
},
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
if (collection?.db?.findVersions) {
|
||||
;({ docs } = await collection.db.findVersions(findVersionsDbArgs))
|
||||
} else {
|
||||
;({ docs } = await payload.db.findGlobalVersions({
|
||||
;({ docs } = await payload.db.findVersions(findVersionsDbArgs))
|
||||
}
|
||||
} else {
|
||||
const findGlobalVersionsDbArgs = {
|
||||
...findVersionArgs,
|
||||
global: global.slug,
|
||||
req,
|
||||
}))
|
||||
}
|
||||
if (global?.db?.findGlobalVersions) {
|
||||
;({ docs } = await global.db.findGlobalVersions(findGlobalVersionsDbArgs))
|
||||
} else {
|
||||
;({ docs } = await payload.db.findGlobalVersions(findGlobalVersionsDbArgs))
|
||||
}
|
||||
}
|
||||
const [latestVersion] = docs
|
||||
|
||||
@@ -80,24 +91,34 @@ export const saveVersion = async ({
|
||||
}
|
||||
|
||||
if (collection) {
|
||||
result = await payload.db.updateVersion({
|
||||
const updateVersionDbArgs = {
|
||||
...updateVersionArgs,
|
||||
collection: collection.slug,
|
||||
req,
|
||||
})
|
||||
}
|
||||
if (collection?.db?.updateVersion) {
|
||||
result = await collection.db.updateVersion(updateVersionDbArgs)
|
||||
} else {
|
||||
result = await payload.db.updateGlobalVersion({
|
||||
result = await payload.db.updateVersion(updateVersionDbArgs)
|
||||
}
|
||||
} else {
|
||||
const updateGlobalVersionDbArgs = {
|
||||
...updateVersionArgs,
|
||||
global: global.slug,
|
||||
req,
|
||||
})
|
||||
}
|
||||
if (global?.db?.updateGlobalVersion) {
|
||||
result = await global.db.updateGlobalVersion(updateGlobalVersionDbArgs)
|
||||
} else {
|
||||
result = await payload.db.updateGlobalVersion(updateGlobalVersionDbArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (createNewVersion) {
|
||||
if (collection) {
|
||||
result = await payload.db.createVersion({
|
||||
const createVersionDbArgs = {
|
||||
autosave: Boolean(autosave),
|
||||
collectionSlug: collection.slug,
|
||||
createdAt: doc?.createdAt ? new Date(doc.createdAt).toISOString() : now,
|
||||
@@ -105,11 +126,16 @@ export const saveVersion = async ({
|
||||
req,
|
||||
updatedAt: draft ? now : new Date(doc.updatedAt).toISOString(),
|
||||
versionData,
|
||||
})
|
||||
}
|
||||
if (collection?.db?.createVersion) {
|
||||
result = await collection.db.createVersion(createVersionDbArgs)
|
||||
} else {
|
||||
result = await payload.db.createVersion(createVersionDbArgs)
|
||||
}
|
||||
}
|
||||
|
||||
if (global) {
|
||||
result = await payload.db.createGlobalVersion({
|
||||
const createGlobalVersionDbArgs = {
|
||||
autosave: Boolean(autosave),
|
||||
createdAt: doc?.createdAt ? new Date(doc.createdAt).toISOString() : now,
|
||||
globalSlug: global.slug,
|
||||
@@ -117,7 +143,12 @@ export const saveVersion = async ({
|
||||
req,
|
||||
updatedAt: draft ? now : new Date(doc.updatedAt).toISOString(),
|
||||
versionData,
|
||||
})
|
||||
}
|
||||
if (global?.db?.createGlobalVersion) {
|
||||
result = await global.db.createGlobalVersion(createGlobalVersionDbArgs)
|
||||
} else {
|
||||
result = await payload.db.createGlobalVersion(createGlobalVersionDbArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
@@ -4,35 +4,64 @@ import { buildConfigWithDefaults } from '../buildConfigWithDefaults'
|
||||
import { devUser } from '../credentials'
|
||||
|
||||
export const doc = {
|
||||
id: -1,
|
||||
id: 'abc123',
|
||||
name: 'Collection 1',
|
||||
customData: true,
|
||||
}
|
||||
export const doc2 = {
|
||||
id: 'abc456',
|
||||
name: 'Collection 2',
|
||||
customData: true,
|
||||
}
|
||||
export const docs = [doc]
|
||||
export const docs2 = [doc2]
|
||||
|
||||
const collectionWithDb = (collectionSlug: string): CollectionConfig => {
|
||||
export let isInit = false
|
||||
export const updateIsInit = (val: boolean) => {
|
||||
isInit = val
|
||||
return isInit
|
||||
}
|
||||
|
||||
export let isConnected = false
|
||||
export const updateIsConnect = (val: boolean) => {
|
||||
isConnected = val
|
||||
return isConnected
|
||||
}
|
||||
|
||||
export const collectionSlug = 'collection-db'
|
||||
export const collectionSlugRelated = 'collection-related-db'
|
||||
const collectionWithDb = (slug: string, relatedCollection: string): CollectionConfig => {
|
||||
return {
|
||||
slug: collectionSlug,
|
||||
slug,
|
||||
db: {
|
||||
init: async () => {
|
||||
updateIsInit(true)
|
||||
return Promise.resolve()
|
||||
},
|
||||
connect: async () => {
|
||||
updateIsConnect(true)
|
||||
return Promise.resolve()
|
||||
},
|
||||
// @ts-expect-error
|
||||
create: () => {
|
||||
return doc
|
||||
return slug === collectionSlug ? doc : doc2
|
||||
},
|
||||
// @ts-expect-error
|
||||
deleteOne: () => {
|
||||
return docs
|
||||
return slug === collectionSlug ? doc : doc2
|
||||
},
|
||||
// Only used in deleteUserPreferences on user collections
|
||||
// @ts-expect-error
|
||||
deleteMany: () => {
|
||||
return docs
|
||||
// Only used in deleteUserPreferences on user collections
|
||||
return slug === collectionSlug ? doc : doc2
|
||||
},
|
||||
// @ts-expect-error
|
||||
find: () => {
|
||||
return { docs }
|
||||
return { docs: slug === collectionSlug ? docs : docs2 }
|
||||
},
|
||||
// @ts-expect-error
|
||||
findOne: () => {
|
||||
return doc
|
||||
return slug === collectionSlug ? doc : doc2
|
||||
},
|
||||
// @ts-expect-error
|
||||
updateOne: () => {
|
||||
@@ -44,14 +73,21 @@ const collectionWithDb = (collectionSlug: string): CollectionConfig => {
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'otherCollection',
|
||||
type: 'relationship',
|
||||
relationTo: [relatedCollection],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
export const collectionSlug = 'collection-db'
|
||||
export default buildConfigWithDefaults({
|
||||
// @ts-expect-error
|
||||
collections: [collectionWithDb(collectionSlug)],
|
||||
collections: [
|
||||
collectionWithDb(collectionSlug, collectionSlugRelated),
|
||||
collectionWithDb(collectionSlugRelated, collectionSlug),
|
||||
],
|
||||
graphQL: {
|
||||
schemaOutputFile: './test/collections-db/schema.graphql',
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import payload from '../../packages/payload/src'
|
||||
import { devUser } from '../credentials'
|
||||
import { initPayloadTest } from '../helpers/configHelpers'
|
||||
import { collectionSlug } from './config'
|
||||
import { collectionSlug, isConnected, isInit } from './config'
|
||||
import { doc } from './config'
|
||||
|
||||
require('isomorphic-fetch')
|
||||
@@ -42,9 +42,17 @@ describe('Collection Database Operations', () => {
|
||||
})
|
||||
|
||||
// --__--__--__--__--__--__--__--__--__
|
||||
// Local API
|
||||
// Custom Collection DB Operations
|
||||
// --__--__--__--__--__--__--__--__--__
|
||||
|
||||
it('collection DB Init', () => {
|
||||
expect(isInit).toEqual(true)
|
||||
})
|
||||
|
||||
it('collection DB Connect', () => {
|
||||
expect(isConnected).toEqual(true)
|
||||
})
|
||||
|
||||
it('collection DB Create', async () => {
|
||||
const result = await payload.create({
|
||||
collection: collectionSlug,
|
||||
@@ -107,4 +115,21 @@ describe('Collection Database Operations', () => {
|
||||
expect(result.docs[0].customData).toEqual(doc.customData)
|
||||
expect(result.errors).toHaveLength(0)
|
||||
})
|
||||
|
||||
it.todo('support Relationships in Collection DB Operations')
|
||||
it.skip('collection Relationship', async () => {
|
||||
const result = await payload.create({
|
||||
collection: collectionSlug,
|
||||
data: {
|
||||
id: doc.id,
|
||||
otherCollection: {
|
||||
id: doc.id,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(result.id).toEqual(doc.id)
|
||||
expect(result.customData).toEqual(doc.customData)
|
||||
expect(result.related.id).toEqual(doc.id)
|
||||
})
|
||||
})
|
||||
|
||||
101
test/collections-db/payload-types.ts
Normal file
101
test/collections-db/payload-types.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* This file was automatically generated by Payload.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,
|
||||
* and re-run `payload generate:types` to regenerate this file.
|
||||
*/
|
||||
|
||||
export interface Config {
|
||||
collections: {
|
||||
'collection-db': CollectionDb
|
||||
'collection-related-db': CollectionRelatedDb
|
||||
users: User
|
||||
'payload-preferences': PayloadPreference
|
||||
'payload-migrations': PayloadMigration
|
||||
}
|
||||
globals: {}
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "collection-db".
|
||||
*/
|
||||
export interface CollectionDb {
|
||||
id: string
|
||||
name?: string | null
|
||||
otherCollection?: {
|
||||
relationTo: 'collection-related-db'
|
||||
value: string | CollectionRelatedDb
|
||||
} | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "collection-related-db".
|
||||
*/
|
||||
export interface CollectionRelatedDb {
|
||||
id: string
|
||||
name?: string | null
|
||||
otherCollection?: {
|
||||
relationTo: 'collection-db'
|
||||
value: string | CollectionDb
|
||||
} | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users".
|
||||
*/
|
||||
export interface User {
|
||||
id: string
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
email: string
|
||||
resetPasswordToken?: string | null
|
||||
resetPasswordExpiration?: string | null
|
||||
salt?: string | null
|
||||
hash?: string | null
|
||||
loginAttempts?: number | null
|
||||
lockUntil?: string | null
|
||||
password: string | null
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences".
|
||||
*/
|
||||
export interface PayloadPreference {
|
||||
id: string
|
||||
user: {
|
||||
relationTo: 'users'
|
||||
value: string | User
|
||||
}
|
||||
key?: string | null
|
||||
value?:
|
||||
| {
|
||||
[k: string]: unknown
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-migrations".
|
||||
*/
|
||||
export interface PayloadMigration {
|
||||
id: string
|
||||
name?: string | null
|
||||
batch?: number | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
declare module 'payload' {
|
||||
export interface GeneratedTypes extends Config {}
|
||||
}
|
||||
78
test/globals-db/config.ts
Normal file
78
test/globals-db/config.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults'
|
||||
import { devUser } from '../credentials'
|
||||
|
||||
export const doc = {
|
||||
id: -1,
|
||||
customData: true,
|
||||
}
|
||||
export const docs = [doc]
|
||||
|
||||
export const globalSlug = 'global-db'
|
||||
|
||||
let noGlobal = false
|
||||
export const updateNoGlobal = (val: boolean) => {
|
||||
noGlobal = val
|
||||
return noGlobal
|
||||
}
|
||||
|
||||
export let isInit = false
|
||||
export const updateIsInit = (val: boolean) => {
|
||||
isInit = val
|
||||
return isInit
|
||||
}
|
||||
|
||||
export let isConnected = false
|
||||
export const updateIsConnect = (val: boolean) => {
|
||||
isConnected = val
|
||||
return isConnected
|
||||
}
|
||||
export default buildConfigWithDefaults({
|
||||
globals: [
|
||||
{
|
||||
slug: globalSlug,
|
||||
db: {
|
||||
init: async () => {
|
||||
updateIsInit(true)
|
||||
return Promise.resolve()
|
||||
},
|
||||
connect: async () => {
|
||||
updateIsConnect(true)
|
||||
return Promise.resolve()
|
||||
},
|
||||
// @ts-expect-error
|
||||
createGlobal: ({ slug, data, req }) => {
|
||||
return { ...doc, created: true }
|
||||
},
|
||||
// @ts-expect-error
|
||||
updateGlobal: ({ slug, data, req }) => {
|
||||
return { ...doc, updated: true }
|
||||
},
|
||||
// @ts-expect-error
|
||||
findGlobal: () => {
|
||||
if (noGlobal) return false
|
||||
return doc
|
||||
},
|
||||
// @ts-expect-error
|
||||
findGlobalVersions: () => {
|
||||
return { docs }
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
onInit: async (payload) => {
|
||||
await payload.create({
|
||||
collection: 'users',
|
||||
data: {
|
||||
email: devUser.email,
|
||||
password: devUser.password,
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
103
test/globals-db/int.spec.ts
Normal file
103
test/globals-db/int.spec.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import payload from '../../packages/payload/src'
|
||||
import { devUser } from '../credentials'
|
||||
import { initPayloadTest } from '../helpers/configHelpers'
|
||||
import { globalSlug, isConnected, isInit, updateNoGlobal } from './config'
|
||||
import { doc } from './config'
|
||||
|
||||
require('isomorphic-fetch')
|
||||
|
||||
let apiUrl
|
||||
let jwt
|
||||
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
const { email, password } = devUser
|
||||
|
||||
describe('Global Database Operations', () => {
|
||||
// --__--__--__--__--__--__--__--__--__
|
||||
// Boilerplate test setup/teardown
|
||||
// --__--__--__--__--__--__--__--__--__
|
||||
beforeAll(async () => {
|
||||
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } })
|
||||
apiUrl = `${serverURL}/api`
|
||||
|
||||
const response = await fetch(`${apiUrl}/users/login`, {
|
||||
body: JSON.stringify({
|
||||
email,
|
||||
password,
|
||||
}),
|
||||
headers,
|
||||
method: 'POST',
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
jwt = data.token
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
if (typeof payload.db.destroy === 'function') {
|
||||
await payload.db.destroy(payload)
|
||||
}
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
updateNoGlobal(false)
|
||||
})
|
||||
|
||||
// --__--__--__--__--__--__--__--__--__
|
||||
// Custom Global DB Operations
|
||||
// --__--__--__--__--__--__--__--__--__
|
||||
|
||||
it('global DB Init', () => {
|
||||
expect(isInit).toEqual(true)
|
||||
})
|
||||
|
||||
it('global DB Connect', () => {
|
||||
expect(isConnected).toEqual(true)
|
||||
})
|
||||
|
||||
it('global DB Create', async () => {
|
||||
updateNoGlobal(true)
|
||||
const result = await payload.updateGlobal({
|
||||
slug: globalSlug,
|
||||
data: {
|
||||
id: doc.id,
|
||||
},
|
||||
})
|
||||
expect(result.id).toEqual(doc.id)
|
||||
expect(result.customData).toEqual(doc.customData)
|
||||
})
|
||||
|
||||
it('global DB Update', async () => {
|
||||
const result = await payload.updateGlobal({
|
||||
slug: globalSlug,
|
||||
data: {
|
||||
id: doc.id,
|
||||
},
|
||||
})
|
||||
|
||||
expect(result.id).toEqual(doc.id)
|
||||
expect(result.customData).toEqual(doc.customData)
|
||||
expect(result.updated).toEqual(true)
|
||||
})
|
||||
|
||||
it('global DB Find', async () => {
|
||||
const result = await payload.findGlobal({
|
||||
slug: globalSlug,
|
||||
})
|
||||
|
||||
expect(result.id).toEqual(doc.id)
|
||||
expect(result.customData).toEqual(doc.customData)
|
||||
})
|
||||
|
||||
it('global DB find versions', async () => {
|
||||
const result = await payload.findGlobalVersions({
|
||||
slug: globalSlug,
|
||||
})
|
||||
|
||||
expect(result.docs[0].id).toEqual(doc.id)
|
||||
// @ts-expect-error
|
||||
expect(result.docs[0].customData).toEqual(doc.customData)
|
||||
})
|
||||
})
|
||||
83
test/globals-db/payload-types.ts
Normal file
83
test/globals-db/payload-types.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* This file was automatically generated by Payload.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,
|
||||
* and re-run `payload generate:types` to regenerate this file.
|
||||
*/
|
||||
|
||||
export interface Config {
|
||||
collections: {
|
||||
users: User
|
||||
'payload-preferences': PayloadPreference
|
||||
'payload-migrations': PayloadMigration
|
||||
}
|
||||
globals: {
|
||||
'global-db': GlobalDb
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users".
|
||||
*/
|
||||
export interface User {
|
||||
id: string
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
email: string
|
||||
resetPasswordToken?: string | null
|
||||
resetPasswordExpiration?: string | null
|
||||
salt?: string | null
|
||||
hash?: string | null
|
||||
loginAttempts?: number | null
|
||||
lockUntil?: string | null
|
||||
password: string | null
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences".
|
||||
*/
|
||||
export interface PayloadPreference {
|
||||
id: string
|
||||
user: {
|
||||
relationTo: 'users'
|
||||
value: string | User
|
||||
}
|
||||
key?: string | null
|
||||
value?:
|
||||
| {
|
||||
[k: string]: unknown
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-migrations".
|
||||
*/
|
||||
export interface PayloadMigration {
|
||||
id: string
|
||||
name?: string | null
|
||||
batch?: number | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "global-db".
|
||||
*/
|
||||
export interface GlobalDb {
|
||||
id: string
|
||||
name?: string | null
|
||||
updatedAt?: string | null
|
||||
createdAt?: string | null
|
||||
}
|
||||
|
||||
declare module 'payload' {
|
||||
export interface GeneratedTypes extends Config {}
|
||||
}
|
||||
Reference in New Issue
Block a user