diff --git a/packages/core/strapi/lib/Strapi.js b/packages/core/strapi/lib/Strapi.js index cf80f0329a..cc334fb786 100644 --- a/packages/core/strapi/lib/Strapi.js +++ b/packages/core/strapi/lib/Strapi.js @@ -345,15 +345,16 @@ class Strapi { // Init core store + await this.runLifecyclesFunctions(LIFECYCLES.REGISTER); + + // TODO: i18N must have added the new fileds before we init the DB + const contentTypes = [ // todo: move corestore and webhook to real models instead of content types to avoid adding extra attributes coreStoreModel, webhookModel, - ...Object.values(strapi.models), + ...Object.values(strapi.contentTypes), ...Object.values(strapi.components), - ...Object.values(strapi.admin.models), - ...Object.values(strapi.plugins).flatMap(plugin => Object.values(plugin.models)), - ...Object.values(strapi.api).flatMap(api => Object.values(api.models)), ]; // TODO: create in RootProvider @@ -364,9 +365,6 @@ class Strapi { await this.db.schema.sync(); - await this.runLifecyclesFunctions(LIFECYCLES.REGISTER); - // await this.db.initialize(); - this.store = createCoreStore({ environment: this.config.environment, db: this.db, diff --git a/packages/plugins/i18n/config/functions/register.js b/packages/plugins/i18n/config/functions/register.js index 08e42d08c1..c7f00b44fb 100644 --- a/packages/plugins/i18n/config/functions/register.js +++ b/packages/plugins/i18n/config/functions/register.js @@ -23,8 +23,10 @@ module.exports = () => { private: false, configurable: false, visible: false, - collection: modelName, - populate: ['_id', 'id', 'locale', PUBLISHED_AT_ATTRIBUTE], + type: 'relation', + relation: 'oneToMany', + target: contentType.uid, + // populate: ['_id', 'id', 'locale', PUBLISHED_AT_ATTRIBUTE], }); _.set(attributes, 'locale', { diff --git a/packages/plugins/i18n/config/policies/validateLocaleCreation.js b/packages/plugins/i18n/config/policies/validateLocaleCreation.js index 2ea19b57bf..11dc773a1b 100644 --- a/packages/plugins/i18n/config/policies/validateLocaleCreation.js +++ b/packages/plugins/i18n/config/policies/validateLocaleCreation.js @@ -37,10 +37,10 @@ const validateLocaleCreation = async (ctx, next) => { if (modelDef.kind === 'singleType') { const entity = await strapi.entityService.find(modelDef.uid, { - params: { _locale: entityLocale }, + params: { locale: entityLocale }, }); - ctx.request.query._locale = body.locale; + ctx.request.query.locale = body.locale; // updating if (entity) { diff --git a/packages/plugins/i18n/controllers/content-types.js b/packages/plugins/i18n/controllers/content-types.js index efdfd488b1..1a15d9d31f 100644 --- a/packages/plugins/i18n/controllers/content-types.js +++ b/packages/plugins/i18n/controllers/content-types.js @@ -33,16 +33,22 @@ module.exports = { let params = modelDef.kind === 'singleType' ? {} : { id }; - const entity = await strapi.query(model).findOne(params); + const entity = await strapi + .query(model) + .findOne({ where: params, populate: ['localizations'] }); if (!entity) { return ctx.notFound(); } - const permissions = await strapi.admin.services.permission.find({ - action_in: [READ_ACTION, CREATE_ACTION], - subject: model, - role_in: user.roles.map(prop('id')), + const permissions = await strapi.admin.services.permission.findMany({ + where: { + action: [READ_ACTION, CREATE_ACTION], + subject: model, + role: { + id: user.roles.map(prop('id')), + }, + }, }); const localePermissions = permissions diff --git a/packages/plugins/i18n/services/__tests__/entity-service-decorator.test.js b/packages/plugins/i18n/services/__tests__/entity-service-decorator.test.js index a749cc9fb5..53aec17c81 100644 --- a/packages/plugins/i18n/services/__tests__/entity-service-decorator.test.js +++ b/packages/plugins/i18n/services/__tests__/entity-service-decorator.test.js @@ -152,7 +152,7 @@ describe('Entity service decorator', () => { const input = { params: { - _locale: 'fr', + locale: 'fr', }, populate: ['test'], }; diff --git a/packages/plugins/i18n/services/content-types.js b/packages/plugins/i18n/services/content-types.js index e0cb87803a..d933f0fd52 100644 --- a/packages/plugins/i18n/services/content-types.js +++ b/packages/plugins/i18n/services/content-types.js @@ -54,9 +54,11 @@ const getAndValidateRelatedEntity = async (relatedEntityId, model, locale) => { let relatedEntity; if (kind === 'singleType') { - relatedEntity = await strapi.query(model).findOne({}); + relatedEntity = await strapi.query(model).findOne({ populate: ['localizations'] }); } else if (relatedEntityId) { - relatedEntity = await strapi.query(model).findOne({ id: relatedEntityId }); + relatedEntity = await strapi + .query(model) + .findOne({ where: { id: relatedEntityId }, populate: ['localizations'] }); } if (relatedEntityId && !relatedEntity) { diff --git a/packages/plugins/i18n/services/core-api.js b/packages/plugins/i18n/services/core-api.js index ab6dbbdc43..c6eb6e5775 100644 --- a/packages/plugins/i18n/services/core-api.js +++ b/packages/plugins/i18n/services/core-api.js @@ -142,7 +142,7 @@ const createLocalizationHandler = contentType => { if (isSingleType(contentType)) { return async function(ctx) { - const entry = await strapi.query(contentType.uid).findOne(); + const entry = await strapi.query(contentType.uid).findOne({ populate: ['localizations'] }); if (!entry) { throw strapi.errors.notFound('baseEntryId.invalid'); @@ -155,7 +155,9 @@ const createLocalizationHandler = contentType => { return async function(ctx) { const { id: baseEntryId } = ctx.params; - const entry = await strapi.query(contentType.uid).findOne({ id: baseEntryId }); + const entry = await strapi + .query(contentType.uid) + .findOne({ where: { id: baseEntryId }, populate: ['localizations'] }); if (!entry) { throw strapi.errors.notFound('baseEntryId.invalid'); diff --git a/packages/plugins/i18n/services/entity-service-decorator.js b/packages/plugins/i18n/services/entity-service-decorator.js index eade307677..75b6d5bcc5 100644 --- a/packages/plugins/i18n/services/entity-service-decorator.js +++ b/packages/plugins/i18n/services/entity-service-decorator.js @@ -5,20 +5,19 @@ const { getService } = require('../utils'); const { syncLocalizations, syncNonLocalizedAttributes } = require('./localizations'); -const LOCALE_QUERY_FILTER = '_locale'; +const LOCALE_QUERY_FILTER = 'locale'; const SINGLE_ENTRY_ACTIONS = ['findOne', 'update', 'delete']; const BULK_ACTIONS = ['delete']; const paramsContain = (key, params) => { return ( - has(key, params) || - has(key, params._where) || - (isArray(params._where) && params._where.some(clause => has(key, clause))) + has(key, params.filters) || + (isArray(params.filters) && params.filters.some(clause => has(key, clause))) ); }; /** - * Adds default locale or replaces _locale by locale in query params + * Adds default locale or replaces locale by locale in query params * @param {object} params - query params */ // TODO: fix @@ -32,12 +31,14 @@ const wrapParams = async (params = {}, ctx = {}) => { return { ...omit(LOCALE_QUERY_FILTER, params), - locale: params[LOCALE_QUERY_FILTER], + filters: { + $and: [params.filters || {}, { locale: params[LOCALE_QUERY_FILTER] }], + }, }; } const entityDefinedById = paramsContain('id', params) && SINGLE_ENTRY_ACTIONS.includes(action); - const entitiesDefinedByIds = paramsContain('id_in', params) && BULK_ACTIONS.includes(action); + const entitiesDefinedByIds = paramsContain('id.$in', params) && BULK_ACTIONS.includes(action); if (entityDefinedById || entitiesDefinedByIds) { return params; @@ -47,7 +48,9 @@ const wrapParams = async (params = {}, ctx = {}) => { return { ...params, - locale: await getDefaultLocale(), + filters: { + $and: [params.filters || {}, { locale: await getDefaultLocale() }], + }, }; }; diff --git a/packages/plugins/i18n/services/localizations.js b/packages/plugins/i18n/services/localizations.js index 3ff294e997..0f770df7e7 100644 --- a/packages/plugins/i18n/services/localizations.js +++ b/packages/plugins/i18n/services/localizations.js @@ -29,7 +29,7 @@ const syncLocalizations = async (entry, { model }) => { const updateLocalization = id => { const localizations = newLocalizations.filter(localizationId => localizationId !== id); - return strapi.query(model.uid).update({ id }, { localizations }); + return strapi.query(model.uid).update({ where: { id }, data: { localizations } }); }; await Promise.all(entry.localizations.map(({ id }) => updateLocalization(id))); @@ -52,7 +52,9 @@ const syncNonLocalizedAttributes = async (entry, { model }) => { return; } - const updateLocalization = id => strapi.query(model.uid).update({ id }, nonLocalizedAttributes); + const updateLocalization = id => { + return strapi.query(model.uid).update({ where: { id }, data: nonLocalizedAttributes }); + }; await Promise.all(entry.localizations.map(({ id }) => updateLocalization(id))); } diff --git a/packages/plugins/i18n/services/permissions/actions.js b/packages/plugins/i18n/services/permissions/actions.js index a3569e2d31..f05a6a2b72 100644 --- a/packages/plugins/i18n/services/permissions/actions.js +++ b/packages/plugins/i18n/services/permissions/actions.js @@ -82,9 +82,12 @@ const syncSuperAdminPermissionsWithLocales = async () => { return; } - // TODO: fix - const superAdminPermissions = await permissionService.findUserPermissions({ - roles: [superAdminRole], + const superAdminPermissions = await permissionService.findMany({ + where: { + role: { + id: superAdminRole.id, + }, + }, }); const newSuperAdminPermissions = await addAllLocalesToPermissions(superAdminPermissions); diff --git a/packages/plugins/i18n/tests/content-manager/list-relation.test.e2e.js b/packages/plugins/i18n/tests/content-manager/list-relation.test.e2e.js index 2e2c3e1fa5..da835f65a5 100644 --- a/packages/plugins/i18n/tests/content-manager/list-relation.test.e2e.js +++ b/packages/plugins/i18n/tests/content-manager/list-relation.test.e2e.js @@ -111,7 +111,7 @@ describe('i18n - Relation-list route', () => { const res = await rq({ method: 'POST', url: '/content-manager/relations/application::shop.shop/products', - qs: { _locale: 'it' }, + qs: { locale: 'it' }, }); expect(res.body).toHaveLength(1); diff --git a/packages/plugins/i18n/tests/graphql.test.e2e.js b/packages/plugins/i18n/tests/graphql.test.e2e.js index f04fa59a77..610bffb248 100644 --- a/packages/plugins/i18n/tests/graphql.test.e2e.js +++ b/packages/plugins/i18n/tests/graphql.test.e2e.js @@ -51,7 +51,7 @@ describe('Test Graphql API create localization', () => { afterAll(async () => { await strapi.query('plugins::i18n.locale').delete({ where: { id: localeId } }); - await strapi.query('recipes').deleteMany(); + await strapi.query('application::recipes.recipes').deleteMany(); await strapi.destroy(); await builder.cleanup(); }); diff --git a/packages/plugins/i18n/tests/locales.test.e2e.js b/packages/plugins/i18n/tests/locales.test.e2e.js index 8d6fdfa948..5fd71cb77b 100644 --- a/packages/plugins/i18n/tests/locales.test.e2e.js +++ b/packages/plugins/i18n/tests/locales.test.e2e.js @@ -365,7 +365,7 @@ describe('CRUD locales', () => { } = await rq({ url: '/content-manager/collection-types/application::product.product', method: 'GET', - qs: { _locale: 'fr-FR' }, + qs: { locale: 'fr-FR' }, }); expect(createdProducts).toHaveLength(1); @@ -381,7 +381,7 @@ describe('CRUD locales', () => { } = await rq({ url: '/content-manager/collection-types/application::product.product', method: 'GET', - qs: { _locale: 'fr-FR' }, + qs: { locale: 'fr-FR' }, }); expect(frenchProducts).toHaveLength(0); @@ -390,7 +390,7 @@ describe('CRUD locales', () => { } = await rq({ url: '/content-manager/collection-types/application::product.product', method: 'GET', - qs: { _locale: 'en' }, + qs: { locale: 'en' }, }); expect(englishProducts).toHaveLength(1);