chore: adds feature flag to config

This commit is contained in:
Jarrod Flesch
2023-08-31 21:16:50 -04:00
parent e500b46576
commit 33561a8ea2
6 changed files with 114 additions and 3 deletions

View File

@@ -56,4 +56,7 @@ export const defaults: Config = {
localization: false,
telemetry: true,
custom: {},
database: {
queryDrafts_2_0: false,
},
};

View File

@@ -178,4 +178,7 @@ export default joi.object({
onInit: joi.func(),
debug: joi.boolean(),
custom: joi.object().pattern(joi.string(), joi.any()),
database: joi.object().keys({
queryDrafts_2_0: joi.boolean(),
}),
});

View File

@@ -555,6 +555,15 @@ export type Config = {
onInit?: (payload: Payload) => Promise<void> | void;
/** Extension point to add your custom data. */
custom?: Record<string, any>;
/** database specific configurations */
database?: {
/**
* Enable the v2.0 drafts query improvement, before 2.0.
*
* You must run the migration script for this feature to function properly.
*/
queryDrafts_2_0?: boolean;
};
};
export type SanitizedConfig = Omit<

View File

@@ -40,7 +40,6 @@ export const buildVersionCollectionFields = (collection: SanitizedCollectionConf
});
}
// TODO: behind feature flag
if (collection?.versions?.drafts) {
fields.push({
name: 'latest',

View File

@@ -32,7 +32,6 @@ export const buildVersionGlobalFields = (global: SanitizedGlobalConfig): Field[]
});
}
// TODO: behind feature flag
if (global?.versions?.drafts) {
fields.push({
name: 'latest',

View File

@@ -5,6 +5,15 @@ import { Payload } from '../../payload';
import { PaginatedDocs } from '../../mongoose/types';
import { Collection, CollectionModel, TypeWithID } from '../../collections/config/types';
import { combineQueries } from '../../database/combineQueries';
import { hasWhereAccessResult } from '../../auth';
import { appendVersionToQueryKey } from './appendVersionToQueryKey';
type AggregateVersion<T> = {
_id: string
version: T
updatedAt: string
createdAt: string
}
type Args = {
accessResult: AccessResult
@@ -16,7 +25,96 @@ type Args = {
where: Where
}
export const queryDrafts = async <T extends TypeWithID>({
export const queryDrafts = async <T extends TypeWithID>(args: Args): Promise<PaginatedDocs<T>> => {
if (args.payload.config?.database?.queryDrafts_2_0) {
return queryDraftsV2(args);
}
return queryDraftsV1(args);
};
const queryDraftsV1 = async <T extends TypeWithID>({
accessResult,
collection,
req,
overrideAccess,
payload,
paginationOptions,
where: incomingWhere,
}: Args): Promise<PaginatedDocs<T>> => {
const VersionModel = payload.versions[collection.config.slug] as CollectionModel;
const where = appendVersionToQueryKey(incomingWhere || {});
let versionAccessResult;
if (hasWhereAccessResult(accessResult)) {
versionAccessResult = appendVersionToQueryKey(accessResult);
}
const versionQuery = await VersionModel.buildQuery({
where,
access: versionAccessResult,
req,
overrideAccess,
});
const aggregate = VersionModel.aggregate<AggregateVersion<T>>([
// Sort so that newest are first
{ $sort: { updatedAt: -1 } },
// Group by parent ID, and take the first of each
{
$group: {
_id: '$parent',
version: { $first: '$version' },
updatedAt: { $first: '$updatedAt' },
createdAt: { $first: '$createdAt' },
},
},
// Filter based on incoming query
{ $match: versionQuery },
], {
allowDiskUse: true,
});
let result;
if (paginationOptions) {
const aggregatePaginateOptions = {
...paginationOptions,
useFacet: payload.mongoOptions?.useFacet,
sort: Object.entries(paginationOptions.sort)
.reduce((sort, [incomingSortKey, order]) => {
let key = incomingSortKey;
if (!['createdAt', 'updatedAt', '_id'].includes(incomingSortKey)) {
key = `version.${incomingSortKey}`;
}
return {
...sort,
[key]: order === 'asc' ? 1 : -1,
};
}, {}),
};
result = await VersionModel.aggregatePaginate(aggregate, aggregatePaginateOptions);
} else {
result = aggregate.exec();
}
return {
...result,
docs: result.docs.map((doc) => ({
_id: doc._id,
...doc.version,
updatedAt: doc.updatedAt,
createdAt: doc.createdAt,
})),
};
};
const queryDraftsV2 = async <T extends TypeWithID>({
accessResult,
collection,
req,