fix: respect draft: true when querying docs for the join field (#11763)
Previously, if you were querying a collection that has a join field with `draft: true`, and the join field's collection also has `versions.drafts: true` our db adapter would still query the original SQL table / mongodb collection instead of the versions one which isn't quite right since we respect `draft: true` when populating relationships
This commit is contained in:
@@ -18,6 +18,7 @@ export const find: Find = async function find(
|
|||||||
this: MongooseAdapter,
|
this: MongooseAdapter,
|
||||||
{
|
{
|
||||||
collection: collectionSlug,
|
collection: collectionSlug,
|
||||||
|
draftsEnabled,
|
||||||
joins = {},
|
joins = {},
|
||||||
limit = 0,
|
limit = 0,
|
||||||
locale,
|
locale,
|
||||||
@@ -128,6 +129,7 @@ export const find: Find = async function find(
|
|||||||
adapter: this,
|
adapter: this,
|
||||||
collection: collectionSlug,
|
collection: collectionSlug,
|
||||||
collectionConfig,
|
collectionConfig,
|
||||||
|
draftsEnabled,
|
||||||
joins,
|
joins,
|
||||||
locale,
|
locale,
|
||||||
query,
|
query,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { transform } from './utilities/transform.js'
|
|||||||
|
|
||||||
export const findOne: FindOne = async function findOne(
|
export const findOne: FindOne = async function findOne(
|
||||||
this: MongooseAdapter,
|
this: MongooseAdapter,
|
||||||
{ collection: collectionSlug, joins, locale, req, select, where = {} },
|
{ collection: collectionSlug, draftsEnabled, joins, locale, req, select, where = {} },
|
||||||
) {
|
) {
|
||||||
const { collectionConfig, Model } = getCollection({ adapter: this, collectionSlug })
|
const { collectionConfig, Model } = getCollection({ adapter: this, collectionSlug })
|
||||||
|
|
||||||
@@ -42,6 +42,7 @@ export const findOne: FindOne = async function findOne(
|
|||||||
adapter: this,
|
adapter: this,
|
||||||
collection: collectionSlug,
|
collection: collectionSlug,
|
||||||
collectionConfig,
|
collectionConfig,
|
||||||
|
draftsEnabled,
|
||||||
joins,
|
joins,
|
||||||
locale,
|
locale,
|
||||||
projection,
|
projection,
|
||||||
|
|||||||
@@ -2,14 +2,19 @@ import type { PipelineStage } from 'mongoose'
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
APIError,
|
APIError,
|
||||||
|
appendVersionToQueryKey,
|
||||||
|
buildVersionCollectionFields,
|
||||||
type CollectionSlug,
|
type CollectionSlug,
|
||||||
|
combineQueries,
|
||||||
type FlattenedField,
|
type FlattenedField,
|
||||||
|
getQueryDraftsSort,
|
||||||
type JoinQuery,
|
type JoinQuery,
|
||||||
type SanitizedCollectionConfig,
|
type SanitizedCollectionConfig,
|
||||||
} from 'payload'
|
} from 'payload'
|
||||||
import { fieldShouldBeLocalized } from 'payload/shared'
|
import { fieldShouldBeLocalized } from 'payload/shared'
|
||||||
|
|
||||||
import type { MongooseAdapter } from '../index.js'
|
import type { MongooseAdapter } from '../index.js'
|
||||||
|
import type { CollectionModel } from '../types.js'
|
||||||
|
|
||||||
import { buildQuery } from '../queries/buildQuery.js'
|
import { buildQuery } from '../queries/buildQuery.js'
|
||||||
import { buildSortParam } from '../queries/buildSortParam.js'
|
import { buildSortParam } from '../queries/buildSortParam.js'
|
||||||
@@ -19,6 +24,7 @@ type BuildJoinAggregationArgs = {
|
|||||||
adapter: MongooseAdapter
|
adapter: MongooseAdapter
|
||||||
collection: CollectionSlug
|
collection: CollectionSlug
|
||||||
collectionConfig: SanitizedCollectionConfig
|
collectionConfig: SanitizedCollectionConfig
|
||||||
|
draftsEnabled?: boolean
|
||||||
joins?: JoinQuery
|
joins?: JoinQuery
|
||||||
locale?: string
|
locale?: string
|
||||||
projection?: Record<string, true>
|
projection?: Record<string, true>
|
||||||
@@ -32,6 +38,7 @@ export const buildJoinAggregation = async ({
|
|||||||
adapter,
|
adapter,
|
||||||
collection,
|
collection,
|
||||||
collectionConfig,
|
collectionConfig,
|
||||||
|
draftsEnabled,
|
||||||
joins,
|
joins,
|
||||||
locale,
|
locale,
|
||||||
projection,
|
projection,
|
||||||
@@ -262,10 +269,27 @@ export const buildJoinAggregation = async ({
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const { collectionConfig, Model: JoinModel } = getCollection({
|
const collectionConfig = adapter.payload.collections[join.field.collection as string]?.config
|
||||||
adapter,
|
|
||||||
collectionSlug: join.field.collection as string,
|
if (!collectionConfig) {
|
||||||
})
|
throw new APIError(
|
||||||
|
`Collection config for ${join.field.collection.toString()} was not found`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let JoinModel: CollectionModel | undefined
|
||||||
|
|
||||||
|
const useDrafts = (draftsEnabled || versions) && Boolean(collectionConfig.versions.drafts)
|
||||||
|
|
||||||
|
if (useDrafts) {
|
||||||
|
JoinModel = adapter.versions[collectionConfig.slug]
|
||||||
|
} else {
|
||||||
|
JoinModel = adapter.collections[collectionConfig.slug]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!JoinModel) {
|
||||||
|
throw new APIError(`Join Model was not found for ${collectionConfig.slug}`)
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
count,
|
count,
|
||||||
@@ -279,12 +303,16 @@ export const buildJoinAggregation = async ({
|
|||||||
throw new Error('Unreachable')
|
throw new Error('Unreachable')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fields = useDrafts
|
||||||
|
? buildVersionCollectionFields(adapter.payload.config, collectionConfig, true)
|
||||||
|
: collectionConfig.flattenedFields
|
||||||
|
|
||||||
const sort = buildSortParam({
|
const sort = buildSortParam({
|
||||||
adapter,
|
adapter,
|
||||||
config: adapter.payload.config,
|
config: adapter.payload.config,
|
||||||
fields: collectionConfig.flattenedFields,
|
fields,
|
||||||
locale,
|
locale,
|
||||||
sort: sortJoin,
|
sort: useDrafts ? getQueryDraftsSort({ collectionConfig, sort: sortJoin }) : sortJoin,
|
||||||
timestamps: true,
|
timestamps: true,
|
||||||
})
|
})
|
||||||
const sortProperty = Object.keys(sort)[0]!
|
const sortProperty = Object.keys(sort)[0]!
|
||||||
@@ -293,7 +321,13 @@ export const buildJoinAggregation = async ({
|
|||||||
const $match = await JoinModel.buildQuery({
|
const $match = await JoinModel.buildQuery({
|
||||||
locale,
|
locale,
|
||||||
payload: adapter.payload,
|
payload: adapter.payload,
|
||||||
where: whereJoin,
|
where: useDrafts
|
||||||
|
? combineQueries(appendVersionToQueryKey(whereJoin), {
|
||||||
|
latest: {
|
||||||
|
equals: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
: whereJoin,
|
||||||
})
|
})
|
||||||
|
|
||||||
const pipeline: Exclude<PipelineStage, PipelineStage.Merge | PipelineStage.Out>[] = [
|
const pipeline: Exclude<PipelineStage, PipelineStage.Merge | PipelineStage.Out>[] = [
|
||||||
@@ -345,6 +379,12 @@ export const buildJoinAggregation = async ({
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let foreignFieldPrefix = ''
|
||||||
|
|
||||||
|
if (useDrafts) {
|
||||||
|
foreignFieldPrefix = 'version.'
|
||||||
|
}
|
||||||
|
|
||||||
if (adapter.payload.config.localization && locale === 'all') {
|
if (adapter.payload.config.localization && locale === 'all') {
|
||||||
adapter.payload.config.localization.localeCodes.forEach((code) => {
|
adapter.payload.config.localization.localeCodes.forEach((code) => {
|
||||||
const as = `${versions ? `version.${join.joinPath}` : join.joinPath}${code}`
|
const as = `${versions ? `version.${join.joinPath}` : join.joinPath}${code}`
|
||||||
@@ -353,7 +393,7 @@ export const buildJoinAggregation = async ({
|
|||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
as: `${as}.docs`,
|
as: `${as}.docs`,
|
||||||
foreignField: `${join.field.on}${code}${polymorphicSuffix}`,
|
foreignField: `${foreignFieldPrefix}${join.field.on}${code}${polymorphicSuffix}`,
|
||||||
from: JoinModel.collection.name,
|
from: JoinModel.collection.name,
|
||||||
localField: versions ? 'parent' : '_id',
|
localField: versions ? 'parent' : '_id',
|
||||||
pipeline,
|
pipeline,
|
||||||
@@ -364,7 +404,7 @@ export const buildJoinAggregation = async ({
|
|||||||
[`${as}.docs`]: {
|
[`${as}.docs`]: {
|
||||||
$map: {
|
$map: {
|
||||||
as: 'doc',
|
as: 'doc',
|
||||||
in: '$$doc._id',
|
in: useDrafts ? `$$doc.parent` : '$$doc._id',
|
||||||
input: `$${as}.docs`,
|
input: `$${as}.docs`,
|
||||||
},
|
},
|
||||||
}, // Slicing the docs to match the limit
|
}, // Slicing the docs to match the limit
|
||||||
@@ -387,7 +427,10 @@ export const buildJoinAggregation = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (count) {
|
if (count) {
|
||||||
addTotalDocsAggregation(as, `${join.field.on}${code}${polymorphicSuffix}`)
|
addTotalDocsAggregation(
|
||||||
|
as,
|
||||||
|
`${foreignFieldPrefix}${join.field.on}${code}${polymorphicSuffix}`,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -414,7 +457,7 @@ export const buildJoinAggregation = async ({
|
|||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
as: `${as}.docs`,
|
as: `${as}.docs`,
|
||||||
foreignField,
|
foreignField: `${foreignFieldPrefix}${foreignField}`,
|
||||||
from: JoinModel.collection.name,
|
from: JoinModel.collection.name,
|
||||||
localField: versions ? 'parent' : '_id',
|
localField: versions ? 'parent' : '_id',
|
||||||
pipeline,
|
pipeline,
|
||||||
@@ -425,7 +468,7 @@ export const buildJoinAggregation = async ({
|
|||||||
[`${as}.docs`]: {
|
[`${as}.docs`]: {
|
||||||
$map: {
|
$map: {
|
||||||
as: 'doc',
|
as: 'doc',
|
||||||
in: '$$doc._id',
|
in: useDrafts ? `$$doc.parent` : '$$doc._id',
|
||||||
input: `$${as}.docs`,
|
input: `$${as}.docs`,
|
||||||
},
|
},
|
||||||
}, // Slicing the docs to match the limit
|
}, // Slicing the docs to match the limit
|
||||||
@@ -437,7 +480,7 @@ export const buildJoinAggregation = async ({
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (count) {
|
if (count) {
|
||||||
addTotalDocsAggregation(as, foreignField)
|
addTotalDocsAggregation(as, `${foreignFieldPrefix}${foreignField}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (limitJoin > 0) {
|
if (limitJoin > 0) {
|
||||||
|
|||||||
@@ -8,7 +8,19 @@ import { findMany } from './find/findMany.js'
|
|||||||
|
|
||||||
export const find: Find = async function find(
|
export const find: Find = async function find(
|
||||||
this: DrizzleAdapter,
|
this: DrizzleAdapter,
|
||||||
{ collection, joins, limit, locale, page = 1, pagination, req, select, sort: sortArg, where },
|
{
|
||||||
|
collection,
|
||||||
|
draftsEnabled,
|
||||||
|
joins,
|
||||||
|
limit,
|
||||||
|
locale,
|
||||||
|
page = 1,
|
||||||
|
pagination,
|
||||||
|
req,
|
||||||
|
select,
|
||||||
|
sort: sortArg,
|
||||||
|
where,
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
|
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
|
||||||
const sort = sortArg !== undefined && sortArg !== null ? sortArg : collectionConfig.defaultSort
|
const sort = sortArg !== undefined && sortArg !== null ? sortArg : collectionConfig.defaultSort
|
||||||
@@ -18,6 +30,7 @@ export const find: Find = async function find(
|
|||||||
return findMany({
|
return findMany({
|
||||||
adapter: this,
|
adapter: this,
|
||||||
collectionSlug: collectionConfig.slug,
|
collectionSlug: collectionConfig.slug,
|
||||||
|
draftsEnabled,
|
||||||
fields: collectionConfig.flattenedFields,
|
fields: collectionConfig.flattenedFields,
|
||||||
joins,
|
joins,
|
||||||
limit,
|
limit,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ type BuildFindQueryArgs = {
|
|||||||
adapter: DrizzleAdapter
|
adapter: DrizzleAdapter
|
||||||
collectionSlug?: string
|
collectionSlug?: string
|
||||||
depth: number
|
depth: number
|
||||||
|
draftsEnabled?: boolean
|
||||||
fields: FlattenedField[]
|
fields: FlattenedField[]
|
||||||
joinQuery?: JoinQuery
|
joinQuery?: JoinQuery
|
||||||
/**
|
/**
|
||||||
@@ -35,6 +36,7 @@ export const buildFindManyArgs = ({
|
|||||||
adapter,
|
adapter,
|
||||||
collectionSlug,
|
collectionSlug,
|
||||||
depth,
|
depth,
|
||||||
|
draftsEnabled,
|
||||||
fields,
|
fields,
|
||||||
joinQuery,
|
joinQuery,
|
||||||
joins = [],
|
joins = [],
|
||||||
@@ -80,6 +82,7 @@ export const buildFindManyArgs = ({
|
|||||||
currentArgs: result,
|
currentArgs: result,
|
||||||
currentTableName: tableName,
|
currentTableName: tableName,
|
||||||
depth,
|
depth,
|
||||||
|
draftsEnabled,
|
||||||
fields,
|
fields,
|
||||||
joinQuery,
|
joinQuery,
|
||||||
joins,
|
joins,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ type Args = {
|
|||||||
export const findMany = async function find({
|
export const findMany = async function find({
|
||||||
adapter,
|
adapter,
|
||||||
collectionSlug,
|
collectionSlug,
|
||||||
|
draftsEnabled,
|
||||||
fields,
|
fields,
|
||||||
joins: joinQuery,
|
joins: joinQuery,
|
||||||
limit: limitArg,
|
limit: limitArg,
|
||||||
@@ -74,6 +75,7 @@ export const findMany = async function find({
|
|||||||
adapter,
|
adapter,
|
||||||
collectionSlug,
|
collectionSlug,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
|
draftsEnabled,
|
||||||
fields,
|
fields,
|
||||||
joinQuery,
|
joinQuery,
|
||||||
joins,
|
joins,
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
import type { LibSQLDatabase } from 'drizzle-orm/libsql'
|
import type { LibSQLDatabase } from 'drizzle-orm/libsql'
|
||||||
import type { SQLiteSelectBase } from 'drizzle-orm/sqlite-core'
|
import type { SQLiteSelectBase } from 'drizzle-orm/sqlite-core'
|
||||||
import type { FlattenedField, JoinQuery, SelectMode, SelectType, Where } from 'payload'
|
|
||||||
|
|
||||||
import { and, asc, count, desc, eq, or, sql } from 'drizzle-orm'
|
import { and, asc, count, desc, eq, or, sql } from 'drizzle-orm'
|
||||||
|
import {
|
||||||
|
appendVersionToQueryKey,
|
||||||
|
buildVersionCollectionFields,
|
||||||
|
combineQueries,
|
||||||
|
type FlattenedField,
|
||||||
|
getQueryDraftsSort,
|
||||||
|
type JoinQuery,
|
||||||
|
type SelectMode,
|
||||||
|
type SelectType,
|
||||||
|
type Where,
|
||||||
|
} from 'payload'
|
||||||
import { fieldIsVirtual, fieldShouldBeLocalized } from 'payload/shared'
|
import { fieldIsVirtual, fieldShouldBeLocalized } from 'payload/shared'
|
||||||
import toSnakeCase from 'to-snake-case'
|
import toSnakeCase from 'to-snake-case'
|
||||||
|
|
||||||
@@ -61,6 +71,7 @@ type TraverseFieldArgs = {
|
|||||||
currentArgs: Result
|
currentArgs: Result
|
||||||
currentTableName: string
|
currentTableName: string
|
||||||
depth?: number
|
depth?: number
|
||||||
|
draftsEnabled?: boolean
|
||||||
fields: FlattenedField[]
|
fields: FlattenedField[]
|
||||||
joinQuery: JoinQuery
|
joinQuery: JoinQuery
|
||||||
joins?: BuildQueryJoinAliases
|
joins?: BuildQueryJoinAliases
|
||||||
@@ -88,6 +99,7 @@ export const traverseFields = ({
|
|||||||
currentArgs,
|
currentArgs,
|
||||||
currentTableName,
|
currentTableName,
|
||||||
depth,
|
depth,
|
||||||
|
draftsEnabled,
|
||||||
fields,
|
fields,
|
||||||
joinQuery = {},
|
joinQuery = {},
|
||||||
joins,
|
joins,
|
||||||
@@ -193,6 +205,7 @@ export const traverseFields = ({
|
|||||||
currentArgs: withArray,
|
currentArgs: withArray,
|
||||||
currentTableName: arrayTableName,
|
currentTableName: arrayTableName,
|
||||||
depth,
|
depth,
|
||||||
|
draftsEnabled,
|
||||||
fields: field.flattenedFields,
|
fields: field.flattenedFields,
|
||||||
joinQuery,
|
joinQuery,
|
||||||
locale,
|
locale,
|
||||||
@@ -304,6 +317,7 @@ export const traverseFields = ({
|
|||||||
currentArgs: withBlock,
|
currentArgs: withBlock,
|
||||||
currentTableName: tableName,
|
currentTableName: tableName,
|
||||||
depth,
|
depth,
|
||||||
|
draftsEnabled,
|
||||||
fields: block.flattenedFields,
|
fields: block.flattenedFields,
|
||||||
joinQuery,
|
joinQuery,
|
||||||
locale,
|
locale,
|
||||||
@@ -345,6 +359,7 @@ export const traverseFields = ({
|
|||||||
currentArgs,
|
currentArgs,
|
||||||
currentTableName,
|
currentTableName,
|
||||||
depth,
|
depth,
|
||||||
|
draftsEnabled,
|
||||||
fields: field.flattenedFields,
|
fields: field.flattenedFields,
|
||||||
joinQuery,
|
joinQuery,
|
||||||
joins,
|
joins,
|
||||||
@@ -511,9 +526,23 @@ export const traverseFields = ({
|
|||||||
.from(sql`${currentQuery.as(subQueryAlias)}`)
|
.from(sql`${currentQuery.as(subQueryAlias)}`)
|
||||||
.where(sqlWhere)}`.as(columnName)
|
.where(sqlWhere)}`.as(columnName)
|
||||||
} else {
|
} else {
|
||||||
const fields = adapter.payload.collections[field.collection].config.flattenedFields
|
const useDrafts =
|
||||||
|
(versions || draftsEnabled) &&
|
||||||
|
Boolean(adapter.payload.collections[field.collection].config.versions.drafts)
|
||||||
|
|
||||||
const joinCollectionTableName = adapter.tableNameMap.get(toSnakeCase(field.collection))
|
const fields = useDrafts
|
||||||
|
? buildVersionCollectionFields(
|
||||||
|
adapter.payload.config,
|
||||||
|
adapter.payload.collections[field.collection].config,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
: adapter.payload.collections[field.collection].config.flattenedFields
|
||||||
|
|
||||||
|
const joinCollectionTableName = adapter.tableNameMap.get(
|
||||||
|
useDrafts
|
||||||
|
? `_${toSnakeCase(field.collection)}${adapter.versionsSuffix}`
|
||||||
|
: toSnakeCase(field.collection),
|
||||||
|
)
|
||||||
|
|
||||||
const joins: BuildQueryJoinAliases = []
|
const joins: BuildQueryJoinAliases = []
|
||||||
|
|
||||||
@@ -546,6 +575,12 @@ export const traverseFields = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useDrafts) {
|
||||||
|
joinQueryWhere = combineQueries(appendVersionToQueryKey(joinQueryWhere), {
|
||||||
|
latest: { equals: true },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const columnName = `${path.replaceAll('.', '_')}${field.name}`
|
const columnName = `${path.replaceAll('.', '_')}${field.name}`
|
||||||
|
|
||||||
const subQueryAlias = `${columnName}_alias`
|
const subQueryAlias = `${columnName}_alias`
|
||||||
@@ -567,7 +602,12 @@ export const traverseFields = ({
|
|||||||
locale,
|
locale,
|
||||||
parentIsLocalized,
|
parentIsLocalized,
|
||||||
selectLocale: true,
|
selectLocale: true,
|
||||||
sort,
|
sort: useDrafts
|
||||||
|
? getQueryDraftsSort({
|
||||||
|
collectionConfig: adapter.payload.collections[field.collection].config,
|
||||||
|
sort,
|
||||||
|
})
|
||||||
|
: sort,
|
||||||
tableName: joinCollectionTableName,
|
tableName: joinCollectionTableName,
|
||||||
where: joinQueryWhere,
|
where: joinQueryWhere,
|
||||||
})
|
})
|
||||||
@@ -610,6 +650,10 @@ export const traverseFields = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useDrafts) {
|
||||||
|
selectFields.parent = newAliasTable.parent
|
||||||
|
}
|
||||||
|
|
||||||
const subQuery = chainMethods({
|
const subQuery = chainMethods({
|
||||||
methods: chainedMethods,
|
methods: chainedMethods,
|
||||||
query: db
|
query: db
|
||||||
@@ -636,7 +680,7 @@ export const traverseFields = ({
|
|||||||
currentArgs.extras[columnName] = sql`${db
|
currentArgs.extras[columnName] = sql`${db
|
||||||
.select({
|
.select({
|
||||||
result: jsonAggBuildObject(adapter, {
|
result: jsonAggBuildObject(adapter, {
|
||||||
id: sql.raw(`"${subQueryAlias}".id`),
|
id: sql.raw(`"${subQueryAlias}".${useDrafts ? 'parent_id' : 'id'}`),
|
||||||
...(selectFields._locale && {
|
...(selectFields._locale && {
|
||||||
locale: sql.raw(`"${subQueryAlias}".${selectFields._locale.name}`),
|
locale: sql.raw(`"${subQueryAlias}".${selectFields._locale.name}`),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { findMany } from './find/findMany.js'
|
|||||||
|
|
||||||
export async function findOne<T extends TypeWithID>(
|
export async function findOne<T extends TypeWithID>(
|
||||||
this: DrizzleAdapter,
|
this: DrizzleAdapter,
|
||||||
{ collection, joins, locale, req, select, where }: FindOneArgs,
|
{ collection, draftsEnabled, joins, locale, req, select, where }: FindOneArgs,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
|
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@ export async function findOne<T extends TypeWithID>(
|
|||||||
const { docs } = await findMany({
|
const { docs } = await findMany({
|
||||||
adapter: this,
|
adapter: this,
|
||||||
collectionSlug: collection,
|
collectionSlug: collection,
|
||||||
|
draftsEnabled,
|
||||||
fields: collectionConfig.flattenedFields,
|
fields: collectionConfig.flattenedFields,
|
||||||
joins,
|
joins,
|
||||||
limit: 1,
|
limit: 1,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { FlattenedBlock, FlattenedField, JoinQuery, SanitizedConfig } from 'payload'
|
import type { FlattenedBlock, FlattenedField, JoinQuery, SanitizedConfig } from 'payload'
|
||||||
|
|
||||||
import { fieldIsVirtual, fieldShouldBeLocalized } from 'payload/shared'
|
import { fieldIsVirtual, fieldShouldBeLocalized } from 'payload/shared'
|
||||||
import toSnakeCase from 'to-snake-case'
|
|
||||||
|
|
||||||
import type { DrizzleAdapter } from '../../types.js'
|
import type { DrizzleAdapter } from '../../types.js'
|
||||||
import type { BlocksMap } from '../../utilities/createBlocksMap.js'
|
import type { BlocksMap } from '../../utilities/createBlocksMap.js'
|
||||||
|
|||||||
@@ -23,15 +23,15 @@ export const metadata = {
|
|||||||
export const RootLayout = async ({
|
export const RootLayout = async ({
|
||||||
children,
|
children,
|
||||||
config: configPromise,
|
config: configPromise,
|
||||||
|
htmlProps = {},
|
||||||
importMap,
|
importMap,
|
||||||
serverFunction,
|
serverFunction,
|
||||||
htmlProps = {},
|
|
||||||
}: {
|
}: {
|
||||||
readonly children: React.ReactNode
|
readonly children: React.ReactNode
|
||||||
readonly config: Promise<SanitizedConfig>
|
readonly config: Promise<SanitizedConfig>
|
||||||
|
readonly htmlProps?: React.HtmlHTMLAttributes<HTMLHtmlElement>
|
||||||
readonly importMap: ImportMap
|
readonly importMap: ImportMap
|
||||||
readonly serverFunction: ServerFunctionClient
|
readonly serverFunction: ServerFunctionClient
|
||||||
readonly htmlProps?: React.HtmlHTMLAttributes<HTMLHtmlElement>
|
|
||||||
}) => {
|
}) => {
|
||||||
checkDependencies()
|
checkDependencies()
|
||||||
|
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ export const findOperation = async <
|
|||||||
|
|
||||||
result = await payload.db.find<DataFromCollectionSlug<TSlug>>({
|
result = await payload.db.find<DataFromCollectionSlug<TSlug>>({
|
||||||
collection: collectionConfig.slug,
|
collection: collectionConfig.slug,
|
||||||
|
draftsEnabled,
|
||||||
joins: req.payloadAPI === 'GraphQL' ? false : sanitizedJoins,
|
joins: req.payloadAPI === 'GraphQL' ? false : sanitizedJoins,
|
||||||
limit: sanitizedLimit,
|
limit: sanitizedLimit,
|
||||||
locale,
|
locale,
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ export const findByIDOperation = async <
|
|||||||
|
|
||||||
const findOneArgs: FindOneArgs = {
|
const findOneArgs: FindOneArgs = {
|
||||||
collection: collectionConfig.slug,
|
collection: collectionConfig.slug,
|
||||||
|
draftsEnabled: draftEnabled,
|
||||||
joins: req.payloadAPI === 'GraphQL' ? false : sanitizedJoins,
|
joins: req.payloadAPI === 'GraphQL' ? false : sanitizedJoins,
|
||||||
locale,
|
locale,
|
||||||
req: {
|
req: {
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ export type QueryDrafts = <T = TypeWithID>(args: QueryDraftsArgs) => Promise<Pag
|
|||||||
|
|
||||||
export type FindOneArgs = {
|
export type FindOneArgs = {
|
||||||
collection: CollectionSlug
|
collection: CollectionSlug
|
||||||
|
draftsEnabled?: boolean
|
||||||
joins?: JoinQuery
|
joins?: JoinQuery
|
||||||
locale?: string
|
locale?: string
|
||||||
req?: Partial<PayloadRequest>
|
req?: Partial<PayloadRequest>
|
||||||
@@ -217,6 +218,7 @@ export type FindOne = <T extends TypeWithID>(args: FindOneArgs) => Promise<null
|
|||||||
|
|
||||||
export type FindArgs = {
|
export type FindArgs = {
|
||||||
collection: CollectionSlug
|
collection: CollectionSlug
|
||||||
|
draftsEnabled?: boolean
|
||||||
joins?: JoinQuery
|
joins?: JoinQuery
|
||||||
/** Setting limit to 1 is equal to the previous Model.findOne(). Setting limit to 0 disables the limit */
|
/** Setting limit to 1 is equal to the previous Model.findOne(). Setting limit to 0 disables the limit */
|
||||||
limit?: number
|
limit?: number
|
||||||
|
|||||||
@@ -1008,12 +1008,10 @@ export type {
|
|||||||
User,
|
User,
|
||||||
VerifyConfig,
|
VerifyConfig,
|
||||||
} from './auth/types.js'
|
} from './auth/types.js'
|
||||||
|
|
||||||
export { generateImportMap } from './bin/generateImportMap/index.js'
|
export { generateImportMap } from './bin/generateImportMap/index.js'
|
||||||
|
|
||||||
export type { ImportMap } from './bin/generateImportMap/index.js'
|
export type { ImportMap } from './bin/generateImportMap/index.js'
|
||||||
export { genImportMapIterateFields } from './bin/generateImportMap/iterateFields.js'
|
export { genImportMapIterateFields } from './bin/generateImportMap/iterateFields.js'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
type ClientCollectionConfig,
|
type ClientCollectionConfig,
|
||||||
createClientCollectionConfig,
|
createClientCollectionConfig,
|
||||||
@@ -1060,6 +1058,7 @@ export type {
|
|||||||
} from './collections/config/types.js'
|
} from './collections/config/types.js'
|
||||||
|
|
||||||
export type { CompoundIndex } from './collections/config/types.js'
|
export type { CompoundIndex } from './collections/config/types.js'
|
||||||
|
|
||||||
export type { SanitizedCompoundIndex } from './collections/config/types.js'
|
export type { SanitizedCompoundIndex } from './collections/config/types.js'
|
||||||
export { createDataloaderCacheKey, getDataLoader } from './collections/dataloader.js'
|
export { createDataloaderCacheKey, getDataLoader } from './collections/dataloader.js'
|
||||||
export { countOperation } from './collections/operations/count.js'
|
export { countOperation } from './collections/operations/count.js'
|
||||||
@@ -1084,6 +1083,7 @@ export {
|
|||||||
serverOnlyConfigProperties,
|
serverOnlyConfigProperties,
|
||||||
type UnsanitizedClientConfig,
|
type UnsanitizedClientConfig,
|
||||||
} from './config/client.js'
|
} from './config/client.js'
|
||||||
|
|
||||||
export { defaults } from './config/defaults.js'
|
export { defaults } from './config/defaults.js'
|
||||||
export { sanitizeConfig } from './config/sanitize.js'
|
export { sanitizeConfig } from './config/sanitize.js'
|
||||||
export type * from './config/types.js'
|
export type * from './config/types.js'
|
||||||
@@ -1313,6 +1313,7 @@ export type {
|
|||||||
} from './fields/config/types.js'
|
} from './fields/config/types.js'
|
||||||
|
|
||||||
export { getDefaultValue } from './fields/getDefaultValue.js'
|
export { getDefaultValue } from './fields/getDefaultValue.js'
|
||||||
|
|
||||||
export { traverseFields as afterChangeTraverseFields } from './fields/hooks/afterChange/traverseFields.js'
|
export { traverseFields as afterChangeTraverseFields } from './fields/hooks/afterChange/traverseFields.js'
|
||||||
export { promise as afterReadPromise } from './fields/hooks/afterRead/promise.js'
|
export { promise as afterReadPromise } from './fields/hooks/afterRead/promise.js'
|
||||||
export { traverseFields as afterReadTraverseFields } from './fields/hooks/afterRead/traverseFields.js'
|
export { traverseFields as afterReadTraverseFields } from './fields/hooks/afterRead/traverseFields.js'
|
||||||
@@ -1352,7 +1353,6 @@ export type {
|
|||||||
UploadFieldValidation,
|
UploadFieldValidation,
|
||||||
UsernameFieldValidation,
|
UsernameFieldValidation,
|
||||||
} from './fields/validations.js'
|
} from './fields/validations.js'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
type ClientGlobalConfig,
|
type ClientGlobalConfig,
|
||||||
createClientGlobalConfig,
|
createClientGlobalConfig,
|
||||||
@@ -1374,6 +1374,7 @@ export type {
|
|||||||
} from './globals/config/types.js'
|
} from './globals/config/types.js'
|
||||||
|
|
||||||
export { docAccessOperation as docAccessOperationGlobal } from './globals/operations/docAccess.js'
|
export { docAccessOperation as docAccessOperationGlobal } from './globals/operations/docAccess.js'
|
||||||
|
|
||||||
export { findOneOperation } from './globals/operations/findOne.js'
|
export { findOneOperation } from './globals/operations/findOne.js'
|
||||||
export { findVersionByIDOperation as findVersionByIDOperationGlobal } from './globals/operations/findVersionByID.js'
|
export { findVersionByIDOperation as findVersionByIDOperationGlobal } from './globals/operations/findVersionByID.js'
|
||||||
export { findVersionsOperation as findVersionsOperationGlobal } from './globals/operations/findVersions.js'
|
export { findVersionsOperation as findVersionsOperationGlobal } from './globals/operations/findVersions.js'
|
||||||
@@ -1423,6 +1424,7 @@ export { getFileByPath } from './uploads/getFileByPath.js'
|
|||||||
export type * from './uploads/types.js'
|
export type * from './uploads/types.js'
|
||||||
|
|
||||||
export { addDataAndFileToRequest } from './utilities/addDataAndFileToRequest.js'
|
export { addDataAndFileToRequest } from './utilities/addDataAndFileToRequest.js'
|
||||||
|
|
||||||
export { addLocalesToRequestFromData, sanitizeLocales } from './utilities/addLocalesToRequest.js'
|
export { addLocalesToRequestFromData, sanitizeLocales } from './utilities/addLocalesToRequest.js'
|
||||||
export { commitTransaction } from './utilities/commitTransaction.js'
|
export { commitTransaction } from './utilities/commitTransaction.js'
|
||||||
export {
|
export {
|
||||||
@@ -1490,6 +1492,8 @@ export { buildVersionGlobalFields } from './versions/buildGlobalFields.js'
|
|||||||
export { buildVersionCompoundIndexes } from './versions/buildVersionCompoundIndexes.js'
|
export { buildVersionCompoundIndexes } from './versions/buildVersionCompoundIndexes.js'
|
||||||
export { versionDefaults } from './versions/defaults.js'
|
export { versionDefaults } from './versions/defaults.js'
|
||||||
export { deleteCollectionVersions } from './versions/deleteCollectionVersions.js'
|
export { deleteCollectionVersions } from './versions/deleteCollectionVersions.js'
|
||||||
|
export { appendVersionToQueryKey } from './versions/drafts/appendVersionToQueryKey.js'
|
||||||
|
export { getQueryDraftsSort } from './versions/drafts/getQueryDraftsSort.js'
|
||||||
export { enforceMaxVersions } from './versions/enforceMaxVersions.js'
|
export { enforceMaxVersions } from './versions/enforceMaxVersions.js'
|
||||||
export { getLatestCollectionVersion } from './versions/getLatestCollectionVersion.js'
|
export { getLatestCollectionVersion } from './versions/getLatestCollectionVersion.js'
|
||||||
export { getLatestGlobalVersion } from './versions/getLatestGlobalVersion.js'
|
export { getLatestGlobalVersion } from './versions/getLatestGlobalVersion.js'
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import type { PayloadRequest, SelectType, Where } from '../../types/index.js'
|
|||||||
import { hasWhereAccessResult } from '../../auth/index.js'
|
import { hasWhereAccessResult } from '../../auth/index.js'
|
||||||
import { combineQueries } from '../../database/combineQueries.js'
|
import { combineQueries } from '../../database/combineQueries.js'
|
||||||
import { docHasTimestamps } from '../../types/index.js'
|
import { docHasTimestamps } from '../../types/index.js'
|
||||||
import { deepCopyObjectSimple } from '../../utilities/deepCopyObject.js'
|
|
||||||
import sanitizeInternalFields from '../../utilities/sanitizeInternalFields.js'
|
import sanitizeInternalFields from '../../utilities/sanitizeInternalFields.js'
|
||||||
import { appendVersionToQueryKey } from './appendVersionToQueryKey.js'
|
import { appendVersionToQueryKey } from './appendVersionToQueryKey.js'
|
||||||
import { getQueryDraftsSelect } from './getQueryDraftsSelect.js'
|
import { getQueryDraftsSelect } from './getQueryDraftsSelect.js'
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ export function UploadInput(props: UploadInputProps) {
|
|||||||
const populateDocs = React.useCallback<PopulateDocs>(
|
const populateDocs = React.useCallback<PopulateDocs>(
|
||||||
async (ids, relatedCollectionSlug) => {
|
async (ids, relatedCollectionSlug) => {
|
||||||
if (!ids.length) {
|
if (!ids.length) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const query: {
|
const query: {
|
||||||
|
|||||||
@@ -606,6 +606,27 @@ describe('Joins Field', () => {
|
|||||||
expect(res.docs[0].relatedVersions.docs[0].id).toBe(version.id)
|
expect(res.docs[0].relatedVersions.docs[0].id).toBe(version.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should populate joins with hasMany when on both sides documents are in draft', async () => {
|
||||||
|
const category = await payload.create({
|
||||||
|
collection: 'categories-versions',
|
||||||
|
data: { _status: 'draft' },
|
||||||
|
draft: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const version = await payload.create({
|
||||||
|
collection: 'versions',
|
||||||
|
data: { _status: 'draft', categoryVersion: category.id },
|
||||||
|
draft: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = await payload.find({
|
||||||
|
collection: 'categories-versions',
|
||||||
|
draft: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(res.docs[0].relatedVersions.docs[0].id).toBe(version.id)
|
||||||
|
})
|
||||||
|
|
||||||
it('should populate joins when versions on both sides draft true payload.db.queryDrafts', async () => {
|
it('should populate joins when versions on both sides draft true payload.db.queryDrafts', async () => {
|
||||||
const category = await payload.create({ collection: 'categories-versions', data: {} })
|
const category = await payload.create({ collection: 'categories-versions', data: {} })
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user