chore: stubs out global versions queries

This commit is contained in:
James
2023-06-12 21:38:10 -04:00
parent f74ff8f6bf
commit 05ed6d9721
12 changed files with 234 additions and 97 deletions

7
.vscode/launch.json vendored
View File

@@ -18,5 +18,12 @@
"type": "node-terminal",
"cwd": "${workspaceFolder}"
},
{
"command": "yarn run dev versions",
"name": "Run Dev Versions",
"request": "launch",
"type": "node-terminal",
"cwd": "${workspaceFolder}"
},
]
}

View File

@@ -57,6 +57,7 @@ async function deleteOperation<TSlug extends keyof GeneratedTypes['collections']
req: {
t,
payload,
locale,
payload: {
config,
preferences,
@@ -87,17 +88,13 @@ async function deleteOperation<TSlug extends keyof GeneratedTypes['collections']
overrideAccess,
});
const query = await Model.buildQuery({
where: combineQueries(where, accessResult),
payload,
locale: req.locale,
});
const fullWhere = combineQueries(where, accessResult);
// /////////////////////////////////////
// Retrieve documents
// /////////////////////////////////////
const docs = await Model.find(query, {}, { lean: true });
const { docs } = await payload.db.find<GeneratedTypes['collections'][TSlug]>({ payload, locale, where: fullWhere, collection: collectionConfig });
const errors = [];
@@ -105,12 +102,6 @@ async function deleteOperation<TSlug extends keyof GeneratedTypes['collections']
const promises = docs.map(async (doc) => {
let result;
// custom id type reset
doc.id = doc._id;
doc = JSON.stringify(doc);
doc = JSON.parse(doc);
doc = sanitizeInternalFields(doc);
const { id } = doc;
try {

View File

@@ -31,6 +31,7 @@ async function findVersionByID<T extends TypeWithVersion<T> = any>(args: Argumen
req: {
t,
payload,
locale,
},
disableErrors,
currentDepth,
@@ -42,8 +43,6 @@ async function findVersionByID<T extends TypeWithVersion<T> = any>(args: Argumen
throw new APIError('Missing ID of version.', httpStatus.BAD_REQUEST);
}
const VersionsModel = (payload.versions[collectionConfig.slug]) as CollectionModel;
// /////////////////////////////////////
// Access
// /////////////////////////////////////
@@ -55,19 +54,22 @@ async function findVersionByID<T extends TypeWithVersion<T> = any>(args: Argumen
const hasWhereAccess = typeof accessResults === 'object';
const query = await VersionsModel.buildQuery({
where: combineQueries({ _id: { equals: id } }, accessResults),
payload,
locale: req.locale,
});
const fullWhere = combineQueries({ _id: { equals: id } }, accessResults);
// /////////////////////////////////////
// Find by ID
// /////////////////////////////////////
if (!query.$and[0]._id) throw new NotFound(t);
const versionsQuery = await payload.db.findVersions<T>({
payload,
locale,
collection: collectionConfig,
limit: 1,
pagination: false,
where: fullWhere,
});
let result = await VersionsModel.findOne(query, {}).lean();
const result = versionsQuery.docs[0];
if (!result) {
if (!disableErrors) {
@@ -78,11 +80,6 @@ async function findVersionByID<T extends TypeWithVersion<T> = any>(args: Argumen
return null;
}
// Clone the result - it may have come back memoized
result = JSON.parse(JSON.stringify(result));
result = sanitizeInternalFields(result);
// /////////////////////////////////////
// beforeRead - Collection
// /////////////////////////////////////
@@ -92,7 +89,7 @@ async function findVersionByID<T extends TypeWithVersion<T> = any>(args: Argumen
result.version = await hook({
req,
query,
query: fullWhere,
doc: result.version,
}) || result.version;
}, Promise.resolve());
@@ -120,7 +117,7 @@ async function findVersionByID<T extends TypeWithVersion<T> = any>(args: Argumen
result.version = await hook({
req,
query,
query: fullWhere,
doc: result.version,
}) || result.version;
}, Promise.resolve());

View File

@@ -2,8 +2,7 @@ import { Where } from '../../types';
import { PayloadRequest } from '../../express/types';
import executeAccess from '../../auth/executeAccess';
import sanitizeInternalFields from '../../utilities/sanitizeInternalFields';
import { Collection, CollectionModel } from '../config/types';
import flattenWhereToOperators from '../../database/flattenWhereToOperators';
import { Collection } from '../config/types';
import { buildSortParam } from '../../mongoose/queries/buildSortParam';
import { PaginatedDocs } from '../../mongoose/types';
import { TypeWithVersion } from '../../versions/types';
@@ -44,20 +43,10 @@ async function findVersions<T extends TypeWithVersion<T>>(
showHiddenFields,
} = args;
const VersionsModel = payload.versions[collectionConfig.slug] as CollectionModel;
// /////////////////////////////////////
// Access
// /////////////////////////////////////
let useEstimatedCount = false;
if (where) {
const constraints = flattenWhereToOperators(where);
useEstimatedCount = constraints.some((prop) => Object.keys(prop).some((key) => key === 'near'));
}
let accessResults;
if (!overrideAccess) {
@@ -74,11 +63,7 @@ async function findVersions<T extends TypeWithVersion<T>>(
overrideAccess,
});
const query = await VersionsModel.buildQuery({
where: combineQueries(where, accessResults),
payload,
locale,
});
const fullWhere = combineQueries(where, accessResults);
// /////////////////////////////////////
// Find
@@ -92,15 +77,15 @@ async function findVersions<T extends TypeWithVersion<T>>(
locale,
});
const paginatedDocs = await VersionsModel.paginate(query, {
const paginatedDocs = await payload.db.findVersions<T>({
payload,
where: fullWhere,
page: page || 1,
limit: limit ?? 10,
sort: {
[sortProperty]: sortOrder,
},
lean: true,
leanWithId: true,
useEstimatedCount,
collection: collectionConfig,
sortProperty,
sortOrder,
locale,
});
// /////////////////////////////////////
@@ -110,13 +95,11 @@ async function findVersions<T extends TypeWithVersion<T>>(
let result = {
...paginatedDocs,
docs: await Promise.all(paginatedDocs.docs.map(async (doc) => {
const docString = JSON.stringify(doc);
const docRef = JSON.parse(docString);
const docRef = doc;
await collectionConfig.hooks.beforeRead.reduce(async (priorHook, hook) => {
await priorHook;
docRef.version = await hook({ req, query, doc: docRef.version }) || docRef.version;
docRef.version = await hook({ req, query: fullWhere, doc: docRef.version }) || docRef.version;
}, Promise.resolve());
return docRef;
@@ -155,7 +138,7 @@ async function findVersions<T extends TypeWithVersion<T>>(
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
await priorHook;
docRef.version = await hook({ req, query, doc: doc.version, findMany: true }) || doc.version;
docRef.version = await hook({ req, query: fullWhere, doc: doc.version, findMany: true }) || doc.version;
}, Promise.resolve());
return docRef;

View File

@@ -27,6 +27,7 @@ import {
import { SanitizedCollectionConfig } from '../collections/config/types';
import { Payload } from '../payload';
import { Document, Where } from '../types';
import { SanitizedGlobalConfig } from '../globals/config/types';
export interface DatabaseAdapter {
/**
@@ -111,6 +112,8 @@ export interface DatabaseAdapter {
// operations
find: <T>(args: FindArgs) => Promise<PaginatedDocs<T>>
findVersions: <T>(args: FindVersionArgs) => Promise<PaginatedDocs<T>>
findGlobalVersions: <T>(args: FindGlobalVersionArgs) => Promise<PaginatedDocs<T>>
findOne: FindOne
create: Create
update: Update
@@ -136,6 +139,36 @@ export type FindArgs = {
collection: SanitizedCollectionConfig
where?: Where
page?: number
skip?: number
versions?: boolean
limit?: number
pagination?: boolean
sortProperty?: string
sortOrder?: string
locale?: string
}
export type FindVersionArgs = {
payload: Payload
collection: SanitizedCollectionConfig
where?: Where
page?: number
skip?: number
versions?: boolean
limit?: number
pagination?: boolean
sortProperty?: string
sortOrder?: string
locale?: string
}
export type FindGlobalVersionArgs = {
payload: Payload
global: SanitizedGlobalConfig
where?: Where
page?: number
skip?: number
versions?: boolean
limit?: number
pagination?: boolean
sortProperty?: string

View File

@@ -3,7 +3,6 @@ import { PayloadRequest } from '../../express/types';
import executeAccess from '../../auth/executeAccess';
import sanitizeInternalFields from '../../utilities/sanitizeInternalFields';
import { PaginatedDocs } from '../../mongoose/types';
import flattenWhereToOperators from '../../database/flattenWhereToOperators';
import { buildSortParam } from '../../mongoose/queries/buildSortParam';
import { SanitizedGlobalConfig } from '../config/types';
import { afterRead } from '../../fields/hooks/afterRead';
@@ -42,20 +41,12 @@ async function findVersions<T extends TypeWithVersion<T>>(
showHiddenFields,
} = args;
const VersionsModel = payload.versions[globalConfig.slug];
const versionFields = buildVersionGlobalFields(globalConfig);
// /////////////////////////////////////
// Access
// /////////////////////////////////////
let useEstimatedCount = false;
if (where) {
const constraints = flattenWhereToOperators(where);
useEstimatedCount = constraints.some((prop) => Object.keys(prop).some((key) => key === 'near'));
}
const accessResults = !overrideAccess ? await executeAccess({ req }, globalConfig.access.readVersions) : true;
await validateQueryPaths({
@@ -66,12 +57,7 @@ async function findVersions<T extends TypeWithVersion<T>>(
overrideAccess,
});
const query = await VersionsModel.buildQuery({
where: combineQueries(where, accessResults),
payload,
locale,
globalSlug: globalConfig.slug,
});
const fullWhere = combineQueries(where, accessResults);
// /////////////////////////////////////
// Find
@@ -85,15 +71,15 @@ async function findVersions<T extends TypeWithVersion<T>>(
locale,
});
const paginatedDocs = await VersionsModel.paginate(query, {
const paginatedDocs = await payload.db.findGlobalVersions<T>({
payload,
where: fullWhere,
page: page || 1,
limit: limit ?? 10,
sort: {
[sortProperty]: sortOrder,
},
lean: true,
leanWithId: true,
useEstimatedCount,
sortProperty,
sortOrder,
global: globalConfig,
locale,
});
// /////////////////////////////////////
@@ -128,7 +114,7 @@ async function findVersions<T extends TypeWithVersion<T>>(
await globalConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
await priorHook;
docRef.version = await hook({ req, query, doc: doc.version, findMany: true }) || doc.version;
docRef.version = await hook({ req, query: fullWhere, doc: doc.version, findMany: true }) || doc.version;
}, Promise.resolve());
return docRef;

View File

@@ -33,7 +33,6 @@ export async function find<T = unknown>(
leanWithId: true,
useEstimatedCount,
pagination,
useCustomCountFn: pagination ? undefined : () => Promise.resolve(1),
options: {
// limit must also be set here, it's ignored when pagination is false
limit,

View File

@@ -0,0 +1,55 @@
import type { MongooseAdapter } from '.';
import { PaginatedDocs } from './types';
import { FindGlobalVersionArgs } from '../database/types';
import sanitizeInternalFields from '../utilities/sanitizeInternalFields';
import flattenWhereToOperators from '../database/flattenWhereToOperators';
export async function findGlobalVersions<T = unknown>(
this: MongooseAdapter,
{ payload, global, where, page, limit, sortProperty, sortOrder, locale, pagination, skip }: FindGlobalVersionArgs,
): Promise<PaginatedDocs<T>> {
const Model = this.versions[global.slug];
let useEstimatedCount = false;
if (where) {
const constraints = flattenWhereToOperators(where);
useEstimatedCount = constraints.some((prop) => Object.keys(prop).some((key) => key === 'near'));
}
const query = await Model.buildQuery({
payload,
locale,
where,
globalSlug: global.slug,
});
const paginationOptions = {
page,
sort: {
[sortProperty]: sortOrder,
},
limit,
lean: true,
leanWithId: true,
pagination,
offset: skip,
useEstimatedCount,
options: {
// limit must also be set here, it's ignored when pagination is false
limit,
skip,
},
};
const result = await Model.paginate(query, paginationOptions);
return {
...result,
docs: result.docs.map((doc) => {
const sanitizedDoc = JSON.parse(JSON.stringify(doc));
sanitizedDoc.id = sanitizedDoc._id;
return sanitizeInternalFields(sanitizedDoc);
}),
};
}

View File

@@ -0,0 +1,54 @@
import type { MongooseAdapter } from '.';
import { PaginatedDocs } from './types';
import { FindVersionArgs } from '../database/types';
import sanitizeInternalFields from '../utilities/sanitizeInternalFields';
import flattenWhereToOperators from '../database/flattenWhereToOperators';
export async function findVersions<T = unknown>(
this: MongooseAdapter,
{ payload, collection, where, page, limit, sortProperty, sortOrder, locale, pagination, skip }: FindVersionArgs,
): Promise<PaginatedDocs<T>> {
const Model = this.versions[collection.slug];
let useEstimatedCount = false;
if (where) {
const constraints = flattenWhereToOperators(where);
useEstimatedCount = constraints.some((prop) => Object.keys(prop).some((key) => key === 'near'));
}
const query = await Model.buildQuery({
payload,
locale,
where,
});
const paginationOptions = {
page,
sort: {
[sortProperty]: sortOrder,
},
limit,
lean: true,
leanWithId: true,
pagination,
offset: skip,
useEstimatedCount,
options: {
// limit must also be set here, it's ignored when pagination is false
limit,
skip,
},
};
const result = await Model.paginate(query, paginationOptions);
return {
...result,
docs: result.docs.map((doc) => {
const sanitizedDoc = JSON.parse(JSON.stringify(doc));
sanitizedDoc.id = sanitizedDoc._id;
return sanitizeInternalFields(sanitizedDoc);
}),
};
}

View File

@@ -7,6 +7,8 @@ import { CollectionModel } from '../collections/config/types';
import { queryDrafts } from './queryDrafts';
import { GlobalModel } from '../globals/config/types';
import { find } from './find';
import { findVersions } from './findVersions';
import { findGlobalVersions } from './findGlobalVersions';
export interface Args {
/** The URL to connect to MongoDB */
@@ -50,5 +52,7 @@ export function mongooseAdapter({ url, connectOptions }: Args): MongooseAdapter
commitTransaction: async () => true,
queryDrafts,
find,
findVersions,
findGlobalVersions,
};
}

View File

@@ -1,13 +1,15 @@
import { FilterQuery } from 'mongoose';
import { Payload } from '../payload';
import { CollectionModel } from '../collections/config/types';
import { CollectionModel, SanitizedCollectionConfig } from '../collections/config/types';
import { Where } from '../types';
import { SanitizedGlobalConfig } from '../globals/config/types';
type Args = {
payload: Payload
Model: CollectionModel
max: number
slug: string
entityType: 'global' | 'collection'
collection?: SanitizedCollectionConfig
global?: SanitizedGlobalConfig
id?: string | number
}
@@ -15,25 +17,54 @@ export const enforceMaxVersions = async ({
payload,
Model,
max,
slug,
entityType,
collection,
global,
id,
}: Args): Promise<void> => {
const entityType = collection ? 'collection' : 'global';
const slug = collection ? collection.slug : global?.slug;
try {
const query: { parent?: string | number } = {};
const where: Where = {};
let oldestAllowedDoc;
if (entityType === 'collection') query.parent = id;
if (collection) {
where.parent = {
equals: id,
};
const oldestAllowedDoc = await Model.find(query).limit(1).skip(max).sort({ updatedAt: -1 });
const query = await payload.db.findVersions({
payload,
where,
collection,
skip: max,
sortProperty: 'updatedAt',
sortOrder: 'desc',
pagination: false,
});
if (oldestAllowedDoc?.[0]?.updatedAt) {
[oldestAllowedDoc] = query.docs;
} else if (global) {
const query = await payload.db.findGlobalVersions({
payload,
where,
global,
skip: max,
sortProperty: 'updatedAt',
sortOrder: 'desc',
});
[oldestAllowedDoc] = query.docs;
}
if (oldestAllowedDoc?.updatedAt) {
const deleteQuery: FilterQuery<unknown> = {
updatedAt: {
$lte: oldestAllowedDoc[0].updatedAt,
$lte: oldestAllowedDoc.updatedAt,
},
};
if (entityType === 'collection') deleteQuery.parent = id;
if (collection) deleteQuery.parent = id;
await Model.deleteMany(deleteQuery);
}

View File

@@ -28,16 +28,13 @@ export const saveVersion = async ({
}: Args): Promise<TypeWithID> => {
let result;
let entityConfig;
let entityType: 'global' | 'collection';
if (collection) {
entityConfig = collection;
entityType = 'collection';
}
if (global) {
entityConfig = global;
entityType = 'global';
}
const VersionModel = payload.versions[entityConfig.slug];
@@ -104,8 +101,8 @@ export const saveVersion = async ({
id,
payload,
Model: VersionModel,
slug: entityConfig.slug,
entityType,
collection,
global,
max,
});
}