diff --git a/docs/admin/preferences.mdx b/docs/admin/preferences.mdx index 38ae631836..4343acde60 100644 --- a/docs/admin/preferences.mdx +++ b/docs/admin/preferences.mdx @@ -30,17 +30,17 @@ This API is used significantly for internal operations of the Admin panel, as me ### Database -Payload automatically creates an internally used `_preferences` collection that stores user preferences. Each document in the `_preferences` collection contains the following shape: +Payload automatically creates an internally used `payload-preferences` collection that stores user preferences. Each document in the `payload-preferences` collection contains the following shape: -| Key | Value | -| -------------------- | -------------| -| `id` | A unique ID for each preference stored. | -| `key` | A unique `key` that corresponds to the preference. | -| `user` | The ID of the `user` that is storing its preference. | -| `userCollection` | The `slug` of the collection that the `user` is logged in as. | -| `value` | The value of the preference. Can be any data shape that you need. | -| `createdAt` | A timestamp of when the preference was created. | -| `updatedAt` | A timestamp set to the last time the preference was updated. +| Key | Value | +|-------------------|-------------------------------------------------------------------| +| `id` | A unique ID for each preference stored. | +| `key` | A unique `key` that corresponds to the preference. | +| `user.value` | The ID of the `user` that is storing its preference. | +| `user.relationTo` | The `slug` of the collection that the `user` is logged in as. | +| `value` | The value of the preference. Can be any data shape that you need. | +| `createdAt` | A timestamp of when the preference was created. | +| `updatedAt` | A timestamp set to the last time the preference was updated. | ### APIs diff --git a/docs/rest-api/overview.mdx b/docs/rest-api/overview.mdx index 92e072b7a8..fcdcfda6fa 100644 --- a/docs/rest-api/overview.mdx +++ b/docs/rest-api/overview.mdx @@ -479,7 +479,7 @@ In addition to the dynamically generated endpoints above Payload also has REST e { operation: "Get Preference", method: "GET", - path: "/api/_preferences/{key}", + path: "/api/payload-preferences/{key}", description: "Get a preference by key", example: { slug: "getPreference", @@ -501,7 +501,7 @@ In addition to the dynamically generated endpoints above Payload also has REST e { operation: "Create Preference", method: "POST", - path: "/api/_preferences/{key}", + path: "/api/payload-preferences/{key}", description: "Create or update a preference by key", example: { slug: "createPreference", @@ -525,7 +525,7 @@ In addition to the dynamically generated endpoints above Payload also has REST e { operation: "Delete Preference", method: "DELETE", - path: "/api/_preferences/{key}", + path: "/api/payload-preferences/{key}", description: "Delete a preference by key", example: { slug: "deletePreference", diff --git a/src/admin/components/utilities/Preferences/index.tsx b/src/admin/components/utilities/Preferences/index.tsx index 633d29b20a..90d457e8bb 100644 --- a/src/admin/components/utilities/Preferences/index.tsx +++ b/src/admin/components/utilities/Preferences/index.tsx @@ -40,7 +40,7 @@ export const PreferencesProvider: React.FC<{children?: React.ReactNode}> = ({ ch if (typeof prefs[key] !== 'undefined') return prefs[key]; const promise = new Promise((resolve: (value: T) => void) => { (async () => { - const request = await requests.get(`${serverURL}${api}/_preferences/${key}`, { + const request = await requests.get(`${serverURL}${api}/payload-preferences/${key}`, { headers: { 'Accept-Language': i18n.language, }, @@ -60,7 +60,7 @@ export const PreferencesProvider: React.FC<{children?: React.ReactNode}> = ({ ch const setPreference = useCallback(async (key: string, value: unknown): Promise => { preferencesRef.current[key] = value; - await requests.post(`${serverURL}${api}/_preferences/${key}`, requestOptions(value, i18n.language)); + await requests.post(`${serverURL}${api}/payload-preferences/${key}`, requestOptions(value, i18n.language)); }, [api, i18n.language, serverURL]); contextRef.current.getPreference = getPreference; diff --git a/src/auth/strategies/apiKey.ts b/src/auth/strategies/apiKey.ts index b2e1a0fe12..1f8848cd16 100644 --- a/src/auth/strategies/apiKey.ts +++ b/src/auth/strategies/apiKey.ts @@ -3,8 +3,9 @@ import crypto from 'crypto'; import { PayloadRequest } from '../../express/types'; import { Payload } from '../../payload'; import find from '../../collections/operations/find'; +import { SanitizedCollectionConfig } from '../../collections/config/types'; -export default (payload: Payload, { Model, config }): PassportAPIKey => { +export default (payload: Payload, config: SanitizedCollectionConfig): PassportAPIKey => { const { secret } = payload; const opts = { header: 'Authorization', @@ -40,7 +41,6 @@ export default (payload: Payload, { Model, config }): PassportAPIKey => { const userQuery = await find({ where, collection: { - Model, config, }, req: req as PayloadRequest, diff --git a/src/collections/initHTTP.ts b/src/collections/initHTTP.ts index 8a3206ce11..1576422695 100644 --- a/src/collections/initHTTP.ts +++ b/src/collections/initHTTP.ts @@ -17,16 +17,16 @@ export default function initCollectionsHTTP(ctx: Payload): void { router.all('*', bindCollectionMiddleware(ctx.collections[formattedCollection.slug])); if (collection.auth) { - const AuthCollection = ctx.collections[formattedCollection.slug]; + const { config } = ctx.collections[formattedCollection.slug]; if (collection.auth.useAPIKey) { - passport.use(`${AuthCollection.config.slug}-api-key`, apiKeyStrategy(ctx, AuthCollection)); + passport.use(`${config.slug}-api-key`, apiKeyStrategy(ctx, config)); } if (Array.isArray(collection.auth.strategies)) { collection.auth.strategies.forEach(({ name, strategy }, index) => { const passportStrategy = typeof strategy === 'object' ? strategy : strategy(ctx); - passport.use(`${AuthCollection.config.slug}-${name ?? index}`, passportStrategy); + passport.use(`${config.slug}-${name ?? index}`, passportStrategy); }); } } diff --git a/src/collections/operations/create.ts b/src/collections/operations/create.ts index 101f3299db..4f6da4e703 100644 --- a/src/collections/operations/create.ts +++ b/src/collections/operations/create.ts @@ -203,7 +203,7 @@ async function create( doc: resultWithLocales, payload: req.payload, password: data.password as string, - }) + }); } else { try { doc = await Model.create(resultWithLocales); diff --git a/src/collections/operations/delete.ts b/src/collections/operations/delete.ts index df59362260..26fec5fee9 100644 --- a/src/collections/operations/delete.ts +++ b/src/collections/operations/delete.ts @@ -2,7 +2,6 @@ import { Config as GeneratedTypes } from 'payload/generated-types'; import httpStatus from 'http-status'; import { AccessResult } from '../../config/types'; import { PayloadRequest } from '../../express/types'; -import sanitizeInternalFields from '../../utilities/sanitizeInternalFields'; import { APIError } from '../../errors'; import executeAccess from '../../auth/executeAccess'; import { BeforeOperationHook, Collection } from '../config/types'; @@ -10,6 +9,7 @@ import { Where } from '../../types'; import { afterRead } from '../../fields/hooks/afterRead'; import { deleteCollectionVersions } from '../../versions/deleteCollectionVersions'; import { deleteAssociatedFiles } from '../../uploads/deleteAssociatedFiles'; +import { deleteUserPreferences } from '../../preferences/deleteUserPreferences'; import { validateQueryPaths } from '../../database/queryValidation/validateQueryPaths'; import { combineQueries } from '../../database/combineQueries'; @@ -60,7 +60,6 @@ async function deleteOperation id) }, - userCollection: collectionConfig.slug, - }); - } - preferences.Model.deleteMany({ key: { in: docs.map(({ id }) => `collection-${collectionConfig.slug}-${id}`) } }); + deleteUserPreferences({ + payload, + collectionConfig, + ids: docs.map(({ id }) => id), + }); return { docs: awaitedDocs.filter(Boolean), diff --git a/src/collections/operations/deleteByID.ts b/src/collections/operations/deleteByID.ts index d5d2137972..6e6196831f 100644 --- a/src/collections/operations/deleteByID.ts +++ b/src/collections/operations/deleteByID.ts @@ -10,6 +10,7 @@ import { afterRead } from '../../fields/hooks/afterRead'; import { deleteCollectionVersions } from '../../versions/deleteCollectionVersions'; import { deleteAssociatedFiles } from '../../uploads/deleteAssociatedFiles'; import { combineQueries } from '../../database/combineQueries'; +import { deleteUserPreferences } from '../../preferences/deleteUserPreferences'; export type Arguments = { depth?: number @@ -49,7 +50,6 @@ async function deleteByID(inc payload, payload: { config, - preferences, }, }, overrideAccess, @@ -113,10 +113,11 @@ async function deleteByID(inc // Delete Preferences // ///////////////////////////////////// - if (collectionConfig.auth) { - await preferences.Model.deleteMany({ user: id, userCollection: collectionConfig.slug }); - } - await preferences.Model.deleteMany({ key: `collection-${collectionConfig.slug}-${id}` }); + deleteUserPreferences({ + payload, + collectionConfig, + ids: [id], + }); // ///////////////////////////////////// // Delete versions diff --git a/src/config/sanitize.ts b/src/config/sanitize.ts index ef054e8eac..8ce67e8198 100644 --- a/src/config/sanitize.ts +++ b/src/config/sanitize.ts @@ -7,6 +7,7 @@ import { InvalidConfiguration } from '../errors'; import sanitizeGlobals from '../globals/config/sanitize'; import checkDuplicateCollections from '../utilities/checkDuplicateCollections'; import { defaults } from './defaults'; +import getPreferencesCollection from '../preferences/preferencesCollection'; const sanitizeConfig = (config: Config): SanitizedConfig => { const sanitizedConfig = merge(defaults, config, { @@ -26,6 +27,8 @@ const sanitizeConfig = (config: Config): SanitizedConfig => { throw new InvalidConfiguration(`${sanitizedConfig.admin.user} is not a valid admin user collection`); } + sanitizedConfig.collections.push(getPreferencesCollection(sanitizedConfig)); + sanitizedConfig.collections = sanitizedConfig.collections.map((collection) => sanitizeCollection(sanitizedConfig, collection)); checkDuplicateCollections(sanitizedConfig.collections); diff --git a/src/graphql/registerSchema.ts b/src/graphql/registerSchema.ts index bfd68cfce3..361b00597d 100644 --- a/src/graphql/registerSchema.ts +++ b/src/graphql/registerSchema.ts @@ -7,7 +7,6 @@ import buildLocaleInputType from './schema/buildLocaleInputType'; import buildFallbackLocaleInputType from './schema/buildFallbackLocaleInputType'; import initCollections from '../collections/graphql/init'; import initGlobals from '../globals/graphql/init'; -import initPreferences from '../preferences/graphql/init'; import buildPoliciesType from './schema/buildPoliciesType'; import accessResolver from '../auth/graphql/resolvers/access'; @@ -37,7 +36,6 @@ export default function registerGraphQLSchema(payload: Payload): void { initCollections(payload); initGlobals(payload); - initPreferences(payload); payload.Query.fields.Access = { type: buildPoliciesType(payload), diff --git a/src/initHTTP.ts b/src/initHTTP.ts index 0872e01aaf..0117b1b580 100644 --- a/src/initHTTP.ts +++ b/src/initHTTP.ts @@ -8,7 +8,6 @@ import initAdmin from './express/admin'; import initAuth from './auth/init'; import access from './auth/requestHandlers/access'; import initCollectionsHTTP from './collections/initHTTP'; -import initPreferences from './preferences/init'; import initGlobalsHTTP from './globals/initHTTP'; import initGraphQLPlayground from './graphql/initPlayground'; import initStatic from './express/static'; @@ -49,7 +48,6 @@ export const initHTTP = async (options: InitOptions): Promise => { } initAdmin(payload); - initPreferences(payload); payload.router.get('/access', access); diff --git a/src/payload.ts b/src/payload.ts index de8bed6c94..d8f0918f65 100644 --- a/src/payload.ts +++ b/src/payload.ts @@ -19,7 +19,6 @@ import localOperations from './collections/operations/local'; import localGlobalOperations from './globals/operations/local'; import { decrypt, encrypt } from './auth/crypto'; import { BuildEmailResult } from './email/types'; -import { Preferences } from './preferences/types'; import { Options as CreateOptions } from './collections/operations/local/create'; import { Options as FindOptions } from './collections/operations/local/find'; @@ -57,7 +56,6 @@ import sendEmail from './email/sendEmail'; import { serverInit as serverInitTelemetry } from './utilities/telemetry/events/serverInit'; import Logger from './utilities/logger'; -import PreferencesModel from './preferences/model'; import findConfig from './config/find'; import { defaults as emailDefaults } from './email/defaults'; @@ -80,8 +78,6 @@ export class BasePayload { [slug: string]: CollectionModel; } = {}; - preferences: Preferences; - globals: Globals; logger: pino.Logger; @@ -239,7 +235,6 @@ export class BasePayload { if (this.db.init) { await this.db?.init({ payload: this, config: this.config }); } - this.preferences = { Model: PreferencesModel }; serverInitTelemetry(this); diff --git a/src/preferences/deleteUserPreferences.ts b/src/preferences/deleteUserPreferences.ts new file mode 100644 index 0000000000..5c35d97367 --- /dev/null +++ b/src/preferences/deleteUserPreferences.ts @@ -0,0 +1,20 @@ +import type { Payload } from '../index'; +import type { SanitizedCollectionConfig } from '../collections/config/types'; + +type Args = { + payload: Payload + /** + * User IDs to delete + */ + ids: (string|number)[] + collectionConfig: SanitizedCollectionConfig +} +export const deleteUserPreferences = ({ payload, ids, collectionConfig }: Args) => { + if (collectionConfig.auth) { + payload.collections['payload-preferences'].Model.deleteMany({ + user: { in: ids }, + userCollection: collectionConfig.slug, + }); + } + payload.collections['payload-preferences'].Model.deleteMany({ key: { in: ids.map((id) => `collection-${collectionConfig.slug}-${id}`) } }); +}; diff --git a/src/preferences/graphql/init.ts b/src/preferences/graphql/init.ts deleted file mode 100644 index 071e553980..0000000000 --- a/src/preferences/graphql/init.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable no-param-reassign */ -import { GraphQLJSON } from 'graphql-type-json'; -import { - GraphQLNonNull, - GraphQLObjectType, - GraphQLString, -} from 'graphql'; -import { DateTimeResolver } from 'graphql-scalars'; -import findOne from '../operations/findOne'; -import update from '../operations/update'; -import deleteOperation from '../operations/delete'; -import { Payload } from '../../payload'; - -function initCollectionsGraphQL(payload: Payload): void { - const valueType = GraphQLJSON; - - const preferenceType = new GraphQLObjectType({ - name: 'Preference', - fields: { - key: { - type: new GraphQLNonNull(GraphQLString), - }, - value: { type: valueType }, - createdAt: { type: new GraphQLNonNull(DateTimeResolver) }, - updatedAt: { type: new GraphQLNonNull(DateTimeResolver) }, - }, - }); - - payload.Query.fields.Preference = { - type: preferenceType, - args: { - key: { type: GraphQLString }, - }, - resolve: (_, { key }, context) => { - const { user } = context.req; - return findOne({ key, user, req: context.req }); - }, - }; - - payload.Mutation.fields.updatePreference = { - type: preferenceType, - args: { - key: { type: new GraphQLNonNull(GraphQLString) }, - value: { type: valueType }, - }, - resolve: (_, { key, value }, context) => { - const { user } = context.req; - return update({ key, user, req: context.req, value }); - }, - }; - - payload.Mutation.fields.deletePreference = { - type: preferenceType, - args: { - key: { type: new GraphQLNonNull(GraphQLString) }, - }, - resolve: (_, { key }, context) => { - const { user } = context.req; - return deleteOperation({ key, user, req: context.req }); - }, - }; -} - -export default initCollectionsGraphQL; diff --git a/src/preferences/init.ts b/src/preferences/init.ts deleted file mode 100644 index 022390fc1d..0000000000 --- a/src/preferences/init.ts +++ /dev/null @@ -1,18 +0,0 @@ -import express from 'express'; -import findOne from './requestHandlers/findOne'; -import update from './requestHandlers/update'; -import deleteHandler from './requestHandlers/delete'; -import { Payload } from '../payload'; - -export default function initPreferences(ctx: Payload): void { - if (!ctx.local) { - const router = express.Router(); - router - .route('/_preferences/:key') - .get(findOne) - .post(update) - .delete(deleteHandler); - - ctx.router.use(router); - } -} diff --git a/src/preferences/model.ts b/src/preferences/model.ts deleted file mode 100644 index a9b2280099..0000000000 --- a/src/preferences/model.ts +++ /dev/null @@ -1,15 +0,0 @@ -import mongoose, { Schema } from 'mongoose'; -import { Preference } from './types'; - -const Model = mongoose.model('_preferences', new Schema({ - user: { - type: Schema.Types.ObjectId, - refPath: 'userCollection', - }, - userCollection: String, - key: String, - value: Schema.Types.Mixed, -}, { timestamps: true }) - .index({ user: 1, key: 1, userCollection: 1 }, { unique: true })); - -export default Model; diff --git a/src/preferences/operations/delete.ts b/src/preferences/operations/delete.ts index 231cd4aee5..719e972f68 100644 --- a/src/preferences/operations/delete.ts +++ b/src/preferences/operations/delete.ts @@ -1,19 +1,16 @@ import executeAccess from '../../auth/executeAccess'; import defaultAccess from '../../auth/defaultAccess'; -import { Document } from '../../types'; +import { Document, Where } from '../../types'; import UnauthorizedError from '../../errors/UnathorizedError'; import { PreferenceRequest } from '../types'; +import NotFound from '../../errors/NotFound'; async function deleteOperation(args: PreferenceRequest): Promise { const { overrideAccess, req, req: { - payload: { - preferences: { - Model, - }, - }, + payload, }, user, key, @@ -27,15 +24,25 @@ async function deleteOperation(args: PreferenceRequest): Promise { await executeAccess({ req }, defaultAccess); } - const filter = { - key, - user: user.id, - userCollection: user.collection, + const where: Where = { + and: [ + { key: { equals: key } }, + { 'user.value': { equals: user.id } }, + { 'user.relationTo': { equals: user.collection } }, + ], }; - const result = await Model.findOneAndDelete(filter); + const result = await payload.delete({ + collection: 'payload-preferences', + where, + depth: 0, + user, + }); - return result; + if (result.docs.length === 1) { + return result.docs[0]; + } + throw new NotFound(); } export default deleteOperation; diff --git a/src/preferences/operations/findOne.ts b/src/preferences/operations/findOne.ts index b1461309aa..3f2573b73d 100644 --- a/src/preferences/operations/findOne.ts +++ b/src/preferences/operations/findOne.ts @@ -1,40 +1,34 @@ -import { Preference, PreferenceRequest } from '../types'; -import executeAccess from '../../auth/executeAccess'; -import defaultAccess from '../../auth/defaultAccess'; -import UnauthorizedError from '../../errors/UnathorizedError'; +import { Config as GeneratedTypes } from 'payload/generated-types'; +import { PreferenceRequest } from '../types'; +import { Where } from '../../types'; -async function findOne(args: PreferenceRequest): Promise { +async function findOne(args: PreferenceRequest): Promise { const { - overrideAccess, - req, req: { - payload: { - preferences: { Model }, - }, + payload, }, user, key, } = args; - if (!user) { - throw new UnauthorizedError(req.t); - } - - if (!overrideAccess) { - await executeAccess({ req }, defaultAccess); - } - - const filter = { - key, - user: user.id, - userCollection: user.collection, + const where: Where = { + and: [ + { key: { equals: key } }, + { 'user.value': { equals: user.id } }, + { 'user.relationTo': { equals: user.collection } }, + ], }; - const doc = await Model.findOne(filter); + const { docs } = await payload.find({ + collection: 'payload-preferences', + where, + depth: 0, + user, + }); - if (!doc) return null; + if (docs.length === 0) return null; - return doc; + return docs[0]; } export default findOne; diff --git a/src/preferences/operations/update.ts b/src/preferences/operations/update.ts index 5359fe2af2..1483e6ddcc 100644 --- a/src/preferences/operations/update.ts +++ b/src/preferences/operations/update.ts @@ -1,4 +1,4 @@ -import { Preference, PreferenceUpdateRequest } from '../types'; +import { PreferenceUpdateRequest } from '../types'; import defaultAccess from '../../auth/defaultAccess'; import executeAccess from '../../auth/executeAccess'; import UnauthorizedError from '../../errors/UnathorizedError'; @@ -9,16 +9,27 @@ async function update(args: PreferenceUpdateRequest) { user, req, req: { - payload: { - preferences: { - Model, - }, - }, + payload, }, key, value, } = args; + const collection = 'payload-preferences'; + + const filter = { + key, + user: { + value: user.id, + relationTo: user.collection, + }, + }; + + const preference = { + ...filter, + value, + }; + if (!user) { throw new UnauthorizedError(req.t); } @@ -27,10 +38,16 @@ async function update(args: PreferenceUpdateRequest) { await executeAccess({ req }, defaultAccess); } - const filter = { user: user.id, key, userCollection: user.collection }; - const preference: Preference = { ...filter, value }; - await Model.updateOne(filter, { ...preference }, { upsert: true }); - + const { Model } = payload.collections[collection]; + const updateResult = await Model.updateOne(filter, preference); + if (updateResult.modifiedCount === 0) { + // TODO: workaround to prevent race-conditions 500 errors from violating unique constraints + try { + await Model.create(preference); + } catch (err: unknown) { + await Model.updateOne(filter, preference); + } + } return preference; } diff --git a/src/preferences/preferencesCollection.ts b/src/preferences/preferencesCollection.ts new file mode 100644 index 0000000000..f987d90b1d --- /dev/null +++ b/src/preferences/preferencesCollection.ts @@ -0,0 +1,84 @@ +import { CollectionConfig } from '../collections/config/types'; +import { Access, Config } from '../config/types'; +import findOne from './requestHandlers/findOne'; +import update from './requestHandlers/update'; +import deleteHandler from './requestHandlers/delete'; + +const preferenceAccess: Access = ({ req }) => ({ + 'user.value': { + equals: req?.user?.id, + }, +}); + +const getPreferencesCollection = (config: Config): CollectionConfig => ({ + slug: 'payload-preferences', + admin: { + hidden: true, + }, + access: { + read: preferenceAccess, + delete: preferenceAccess, + }, + fields: [ + { + name: 'user', + type: 'relationship', + relationTo: config.collections + .filter((collectionConfig) => collectionConfig.auth) + .map((collectionConfig) => collectionConfig.slug), + required: true, + hooks: { + beforeValidate: [ + (({ req }) => { + if (!req?.user) { + return null; + } + return { + value: req?.user.id, + relationTo: req?.user.collection, + }; + }), + ], + }, + }, + { + name: 'key', + type: 'text', + }, + { + name: 'value', + type: 'json', + }, + ], + indexes: [ + { + fields: { + 'user.value': 1, + 'user.relationTo': 1, + key: 1, + }, + options: { + unique: true, + }, + }, + ], + endpoints: [ + { + method: 'get', + path: '/:key', + handler: findOne, + }, + { + method: 'delete', + path: '/:key', + handler: deleteHandler, + }, + { + method: 'post', + path: '/:key', + handler: update, + }, + ], +}); + +export default getPreferencesCollection; diff --git a/src/preferences/requestHandlers/delete.ts b/src/preferences/requestHandlers/delete.ts index aee7f56f8b..10bb8e2b6f 100644 --- a/src/preferences/requestHandlers/delete.ts +++ b/src/preferences/requestHandlers/delete.ts @@ -4,7 +4,7 @@ import { PayloadRequest } from '../../express/types'; import formatSuccessResponse from '../../express/responses/formatSuccess'; import deleteOperation from '../operations/delete'; -export default async function deleteHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise | void> { +export default async function deleteHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise | void> { try { await deleteOperation({ req, diff --git a/src/preferences/requestHandlers/findOne.ts b/src/preferences/requestHandlers/findOne.ts index 8ae683e50b..a14e450b5e 100644 --- a/src/preferences/requestHandlers/findOne.ts +++ b/src/preferences/requestHandlers/findOne.ts @@ -1,10 +1,10 @@ import { NextFunction, Response } from 'express'; import httpStatus from 'http-status'; +import { Config as GeneratedTypes } from 'payload/generated-types'; import { PayloadRequest } from '../../express/types'; -import { Preference } from '../types'; import findOne from '../operations/findOne'; -export default async function findOneHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise | void> { +export default async function findOneHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise | void> { try { const result = await findOne({ req, diff --git a/src/preferences/requestHandlers/update.ts b/src/preferences/requestHandlers/update.ts index 3fb75eece9..abd24f7215 100644 --- a/src/preferences/requestHandlers/update.ts +++ b/src/preferences/requestHandlers/update.ts @@ -1,13 +1,11 @@ import { NextFunction, Response } from 'express'; import httpStatus from 'http-status'; +import { Config as GeneratedTypes } from 'payload/generated-types'; import { PayloadRequest } from '../../express/types'; import formatSuccessResponse from '../../express/responses/formatSuccess'; import update from '../operations/update'; -export type UpdatePreferenceResult = Promise | void>; -export type UpdatePreferenceResponse = (req: PayloadRequest, res: Response, next: NextFunction) => UpdatePreferenceResult; - -export default async function updateHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise | void> { +export default async function updateHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise | void> { try { const doc = await update({ req, diff --git a/src/preferences/types.ts b/src/preferences/types.ts index d4a52dfc69..45caa7b781 100644 --- a/src/preferences/types.ts +++ b/src/preferences/types.ts @@ -1,20 +1,6 @@ -import { Model } from 'mongoose'; import { User } from '../auth'; import { PayloadRequest } from '../express/types'; -export type Preference = { - user: string; - userCollection: string; - key: string; - value: { [key: string]: unknown } | unknown; - createdAt?: Date; - updatedAt?: Date; -}; - -export type Preferences = { - Model: Model -} - export type PreferenceRequest = { overrideAccess?: boolean; req: PayloadRequest;