diff --git a/src/collections/operations/create.js b/src/collections/operations/create.js index dc10a42347..21af95385b 100644 --- a/src/collections/operations/create.js +++ b/src/collections/operations/create.js @@ -179,6 +179,7 @@ async function create(args) { req, depth, overrideAccess, + reduceLocales: true, }); // ///////////////////////////////////// diff --git a/src/collections/operations/find.js b/src/collections/operations/find.js index 3201ac8827..c59b0b4ba9 100644 --- a/src/collections/operations/find.js +++ b/src/collections/operations/find.js @@ -13,7 +13,6 @@ async function find(args) { req, req: { locale, - fallbackLocale, }, overrideAccess, } = args; @@ -75,7 +74,8 @@ async function find(args) { page: page || 1, limit: limit || 10, sort, - collation: sort ? { locale: 'en' } : {}, // case-insensitive sort in MongoDB + lean: true, + leanWithId: true, }; let result = await Model.paginate(query, optionsToExecute); @@ -89,11 +89,8 @@ async function find(args) { docs: await Promise.all(result.docs.map(async (doc) => { let docRef = doc; - if (locale && doc.setLocale) { - doc.setLocale(locale, fallbackLocale); - } - - docRef = doc.toJSON({ virtuals: true }); + if (docRef._id) delete docRef._id; + if (docRef.__v) delete docRef.__v; await collectionConfig.hooks.beforeRead.reduce(async (priorHook, hook) => { await priorHook; @@ -121,6 +118,7 @@ async function find(args) { hook: 'afterRead', operation: 'read', overrideAccess, + reduceLocales: true, }, find, ))), @@ -149,9 +147,6 @@ async function find(args) { // 6. Return results // ///////////////////////////////////// - result = JSON.stringify(result); - result = JSON.parse(result); - return result; } diff --git a/src/collections/operations/findByID.js b/src/collections/operations/findByID.js index e5e71c5838..de1cd47c76 100644 --- a/src/collections/operations/findByID.js +++ b/src/collections/operations/findByID.js @@ -13,7 +13,6 @@ async function findByID(args) { req, req: { locale, - fallbackLocale, }, disableErrors, currentDepth, @@ -51,7 +50,7 @@ async function findByID(args) { if (!query.$and[0]._id) throw new NotFound(); - let result = await Model.findOne(query, {}); + let result = await Model.findOne(query, {}).lean(); if (!result) { if (!disableErrors) { @@ -62,11 +61,12 @@ async function findByID(args) { return null; } - if (locale && result.setLocale) { - result.setLocale(locale, fallbackLocale); + if (result._id) { + result.id = result._id; + delete result._id; } - result = result.toJSON({ virtuals: true }); + if (result.__v) delete result.__v; // ///////////////////////////////////// // 3. Execute beforeRead collection hook @@ -95,6 +95,7 @@ async function findByID(args) { operation: 'read', currentDepth, overrideAccess, + reduceLocales: true, }); @@ -116,9 +117,6 @@ async function findByID(args) { // 6. Return results // ///////////////////////////////////// - result = JSON.stringify(result); - result = JSON.parse(result); - return result; } diff --git a/src/collections/operations/update.js b/src/collections/operations/update.js index b8852f6b32..54d01d3252 100644 --- a/src/collections/operations/update.js +++ b/src/collections/operations/update.js @@ -222,6 +222,7 @@ async function update(args) { id, depth, overrideAccess, + reduceLocales: true, }); // ///////////////////////////////////// diff --git a/src/fields/performFieldOperations.js b/src/fields/performFieldOperations.js index 57005881a4..1a56caccae 100644 --- a/src/fields/performFieldOperations.js +++ b/src/fields/performFieldOperations.js @@ -1,6 +1,7 @@ const { isValidObjectId } = require('mongoose'); const { ValidationError } = require('../errors'); const executeAccess = require('../auth/executeAccess'); +const sanitizeFallbackLocale = require('../localization/sanitizeFallbackLocale'); async function performFieldOperations(entityConfig, args) { const { @@ -12,10 +13,14 @@ async function performFieldOperations(entityConfig, args) { id, req: { payloadAPI, + locale, }, overrideAccess, + reduceLocales, } = args; + const fallbackLocale = sanitizeFallbackLocale(req.fallbackLocale); + const recursivePerformFieldOperations = performFieldOperations.bind(this); let depth = 0; @@ -275,6 +280,13 @@ async function performFieldOperations(entityConfig, args) { fields.forEach((field) => { const dataCopy = data; + if (reduceLocales && field.name && field.localized && locale !== 'all' && typeof data[field.name] === 'object') { + let localizedValue = data[field.name][locale]; + if (typeof localizedValue === 'undefined' && fallbackLocale) localizedValue = data[field.name][fallbackLocale]; + if (typeof localizedValue === 'undefined') localizedValue = null; + dataCopy[field.name] = localizedValue; + } + if (field.type === 'upload') { if (data[field.name] === '') dataCopy[field.name] = null; } diff --git a/src/globals/operations/findOne.js b/src/globals/operations/findOne.js index d58a6b87e3..78151e0aea 100644 --- a/src/globals/operations/findOne.js +++ b/src/globals/operations/findOne.js @@ -6,10 +6,6 @@ async function findOne(args) { const { globalConfig, req, - req: { - locale, - fallbackLocale, - }, slug, depth, } = args; @@ -30,19 +26,12 @@ async function findOne(args) { // 3. Perform database operation // ///////////////////////////////////// - let doc = await Model.findOne({ globalType: slug }); + let doc = await Model.findOne({ globalType: slug }).lean(); if (!doc) { doc = {}; - } else { - if (locale && doc.setLocale) { - doc.setLocale(locale, fallbackLocale); - } - - doc = doc.toJSON({ virtuals: true }); } - // ///////////////////////////////////// // 4. Execute field-level hooks and access // ///////////////////////////////////// @@ -53,6 +42,7 @@ async function findOne(args) { operation: 'read', req, depth, + reduceLocales: true, }); // ///////////////////////////////////// @@ -72,9 +62,6 @@ async function findOne(args) { // 6. Return results // ///////////////////////////////////// - doc = JSON.stringify(doc); - doc = JSON.parse(doc); - return doc; } diff --git a/src/graphql/schema/buildFallbackLocaleInputType.js b/src/graphql/schema/buildFallbackLocaleInputType.js index 76f1a57abd..692edd254b 100644 --- a/src/graphql/schema/buildFallbackLocaleInputType.js +++ b/src/graphql/schema/buildFallbackLocaleInputType.js @@ -1,15 +1,13 @@ const { GraphQLEnumType } = require('graphql'); -const buildFallbackLocaleInputType = (localization) => { - return new GraphQLEnumType({ - name: 'FallbackLocaleInputType', - values: [...localization.locales, 'none'].reduce((values, locale) => ({ - ...values, - [locale]: { - value: locale, - }, - }), {}), - }); -}; +const buildFallbackLocaleInputType = (localization) => new GraphQLEnumType({ + name: 'FallbackLocaleInputType', + values: [...localization.locales, 'none'].reduce((values, locale) => ({ + ...values, + [locale]: { + value: locale, + }, + }), {}), +}); module.exports = buildFallbackLocaleInputType; diff --git a/src/localization/middleware.js b/src/localization/middleware.js index 03acf81b4b..1aa807a5d9 100644 --- a/src/localization/middleware.js +++ b/src/localization/middleware.js @@ -21,11 +21,11 @@ module.exports = function localizationMiddleware(localization) { if (requestedFallbackLocale === 'none') requestedFallbackLocale = 'null'; if (requestedLocale === '*' || requestedLocale === 'all') requestedLocale = 'all'; - if (validLocales.find(locale => locale === requestedLocale)) { + if (validLocales.find((locale) => locale === requestedLocale)) { req.locale = requestedLocale; } - if (validFallbackLocales.find(locale => locale === requestedFallbackLocale)) { + if (validFallbackLocales.find((locale) => locale === requestedFallbackLocale)) { req.fallbackLocale = requestedFallbackLocale; } }