@strapi/i18n 5.0.0-rc.23 → 5.0.0-rc.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -174,6 +174,350 @@ const getI18nLocaleArgPlugin = ({ nexus, typeRegistry }) => {
174
174
  }
175
175
  });
176
176
  };
177
+ const register = ({ strapi: strapi2 }) => {
178
+ extendContentTypes(strapi2);
179
+ addContentManagerLocaleMiddleware(strapi2);
180
+ };
181
+ const addContentManagerLocaleMiddleware = (strapi2) => {
182
+ strapi2.server.router.use("/content-manager/collection-types/:model", (ctx, next) => {
183
+ if (ctx.method === "POST" || ctx.method === "PUT") {
184
+ return validateLocaleCreation(ctx, next);
185
+ }
186
+ return next();
187
+ });
188
+ strapi2.server.router.use("/content-manager/single-types/:model", (ctx, next) => {
189
+ if (ctx.method === "POST" || ctx.method === "PUT") {
190
+ return validateLocaleCreation(ctx, next);
191
+ }
192
+ return next();
193
+ });
194
+ };
195
+ const extendContentTypes = (strapi2) => {
196
+ Object.values(strapi2.contentTypes).forEach((contentType) => {
197
+ const { attributes: attributes2 } = contentType;
198
+ _.set(attributes2, "locale", {
199
+ writable: true,
200
+ private: false,
201
+ configurable: false,
202
+ visible: false,
203
+ type: "string"
204
+ });
205
+ _.set(attributes2, "localizations", {
206
+ type: "relation",
207
+ relation: "oneToMany",
208
+ target: contentType.uid,
209
+ writable: false,
210
+ private: false,
211
+ configurable: false,
212
+ visible: false,
213
+ unstable_virtual: true,
214
+ joinColumn: {
215
+ name: "document_id",
216
+ referencedColumn: "document_id",
217
+ referencedTable: strapi2.db.metadata.identifiers.getTableName(contentType.collectionName),
218
+ // ensure the population will not include the results we already loaded
219
+ on({ results }) {
220
+ return {
221
+ id: {
222
+ $notIn: results.map((r) => r.id)
223
+ }
224
+ };
225
+ }
226
+ }
227
+ });
228
+ });
229
+ if (strapi2.plugin("graphql")) {
230
+ graphqlProvider({ strapi: strapi2 }).register();
231
+ }
232
+ };
233
+ const info = {
234
+ singularName: "locale",
235
+ pluralName: "locales",
236
+ collectionName: "locales",
237
+ displayName: "Locale",
238
+ description: ""
239
+ };
240
+ const options = {};
241
+ const pluginOptions = {
242
+ "content-manager": {
243
+ visible: false
244
+ },
245
+ "content-type-builder": {
246
+ visible: false
247
+ }
248
+ };
249
+ const attributes = {
250
+ name: {
251
+ type: "string",
252
+ min: 1,
253
+ max: 50,
254
+ configurable: false
255
+ },
256
+ code: {
257
+ type: "string",
258
+ unique: true,
259
+ configurable: false
260
+ }
261
+ };
262
+ const schema = {
263
+ info,
264
+ options,
265
+ pluginOptions,
266
+ attributes
267
+ };
268
+ const locale = {
269
+ schema
270
+ };
271
+ const contentTypes$1 = {
272
+ locale
273
+ };
274
+ const actions = [
275
+ {
276
+ section: "settings",
277
+ category: "Internationalization",
278
+ subCategory: "Locales",
279
+ pluginName: "i18n",
280
+ displayName: "Create",
281
+ uid: "locale.create"
282
+ },
283
+ {
284
+ section: "settings",
285
+ category: "Internationalization",
286
+ subCategory: "Locales",
287
+ pluginName: "i18n",
288
+ displayName: "Read",
289
+ uid: "locale.read",
290
+ aliases: [
291
+ { actionId: "plugin::content-manager.explorer.read", subjects: ["plugin::i18n.locale"] }
292
+ ]
293
+ },
294
+ {
295
+ section: "settings",
296
+ category: "Internationalization",
297
+ subCategory: "Locales",
298
+ pluginName: "i18n",
299
+ displayName: "Update",
300
+ uid: "locale.update"
301
+ },
302
+ {
303
+ section: "settings",
304
+ category: "Internationalization",
305
+ subCategory: "Locales",
306
+ pluginName: "i18n",
307
+ displayName: "Delete",
308
+ uid: "locale.delete"
309
+ }
310
+ ];
311
+ const addLocalesPropertyIfNeeded = ({ value: action }) => {
312
+ const {
313
+ section,
314
+ options: { applyToProperties }
315
+ } = action;
316
+ if (section !== "contentTypes") {
317
+ return;
318
+ }
319
+ if (isArray(applyToProperties) && applyToProperties.includes("locales")) {
320
+ return;
321
+ }
322
+ action.options.applyToProperties = isArray(applyToProperties) ? applyToProperties.concat("locales") : ["locales"];
323
+ };
324
+ const shouldApplyLocalesPropertyToSubject = ({ property, subject }) => {
325
+ if (property === "locales") {
326
+ const model = strapi.getModel(subject);
327
+ return getService("content-types").isLocalizedContentType(model);
328
+ }
329
+ return true;
330
+ };
331
+ const addAllLocalesToPermissions = async (permissions2) => {
332
+ const { actionProvider } = strapi.service("admin::permission");
333
+ const { find: findAllLocales } = getService("locales");
334
+ const allLocales = await findAllLocales();
335
+ const allLocalesCode = allLocales.map(prop("code"));
336
+ return Promise.all(
337
+ permissions2.map(async (permission) => {
338
+ const { action, subject } = permission;
339
+ const appliesToLocalesProperty = await actionProvider.appliesToProperty(
340
+ "locales",
341
+ action,
342
+ subject
343
+ );
344
+ if (!appliesToLocalesProperty) {
345
+ return permission;
346
+ }
347
+ const oldPermissionProperties = getOr({}, "properties", permission);
348
+ return { ...permission, properties: { ...oldPermissionProperties, locales: allLocalesCode } };
349
+ })
350
+ );
351
+ };
352
+ const syncSuperAdminPermissionsWithLocales = async () => {
353
+ const roleService = strapi.service("admin::role");
354
+ const permissionService = strapi.service("admin::permission");
355
+ const superAdminRole = await roleService.getSuperAdmin();
356
+ if (!superAdminRole) {
357
+ return;
358
+ }
359
+ const superAdminPermissions = await permissionService.findMany({
360
+ where: {
361
+ role: {
362
+ id: superAdminRole.id
363
+ }
364
+ }
365
+ });
366
+ const newSuperAdminPermissions = await addAllLocalesToPermissions(superAdminPermissions);
367
+ await roleService.assignPermissions(superAdminRole.id, newSuperAdminPermissions);
368
+ };
369
+ const registerI18nActions = async () => {
370
+ const { actionProvider } = strapi.service("admin::permission");
371
+ await actionProvider.registerMany(actions);
372
+ };
373
+ const registerI18nActionsHooks = () => {
374
+ const { actionProvider } = strapi.service("admin::permission");
375
+ const { hooks } = strapi.service("admin::role");
376
+ actionProvider.hooks.appliesPropertyToSubject.register(shouldApplyLocalesPropertyToSubject);
377
+ hooks.willResetSuperAdminPermissions.register(addAllLocalesToPermissions);
378
+ };
379
+ const updateActionsProperties = () => {
380
+ const { actionProvider } = strapi.service("admin::permission");
381
+ actionProvider.hooks.willRegister.register(addLocalesPropertyIfNeeded);
382
+ actionProvider.values().forEach((action) => addLocalesPropertyIfNeeded({ value: action }));
383
+ };
384
+ const i18nActionsService = {
385
+ actions,
386
+ registerI18nActions,
387
+ registerI18nActionsHooks,
388
+ updateActionsProperties,
389
+ syncSuperAdminPermissionsWithLocales
390
+ };
391
+ const localesPropertyHandler = async ({ action, section }) => {
392
+ const { actionProvider } = strapi.service("admin::permission");
393
+ const locales2 = await getService("locales").find();
394
+ if (isEmpty(locales2)) {
395
+ return;
396
+ }
397
+ for (const subject of section.subjects) {
398
+ const applies = await actionProvider.appliesToProperty("locales", action.actionId, subject.uid);
399
+ const hasLocalesProperty = subject.properties.find(
400
+ (property) => property.value === "locales"
401
+ );
402
+ if (applies && !hasLocalesProperty) {
403
+ subject.properties.push({
404
+ label: "Locales",
405
+ value: "locales",
406
+ children: locales2.map(({ name, code }) => ({ label: name || code, value: code }))
407
+ });
408
+ }
409
+ }
410
+ };
411
+ const registerLocalesPropertyHandler = () => {
412
+ const { sectionsBuilder } = strapi.service("admin::permission");
413
+ sectionsBuilder.addHandler("singleTypes", localesPropertyHandler);
414
+ sectionsBuilder.addHandler("collectionTypes", localesPropertyHandler);
415
+ };
416
+ const sectionsBuilderService = {
417
+ localesPropertyHandler,
418
+ registerLocalesPropertyHandler
419
+ };
420
+ const willRegisterPermission = (context) => {
421
+ const { permission, condition, user } = context;
422
+ const { subject, properties } = permission;
423
+ const isSuperAdmin = strapi.service("admin::role").hasSuperAdminRole(user);
424
+ if (isSuperAdmin) {
425
+ return;
426
+ }
427
+ const { locales: locales2 } = properties || {};
428
+ const { isLocalizedContentType: isLocalizedContentType2 } = getService("content-types");
429
+ if (!subject) {
430
+ return;
431
+ }
432
+ const ct = strapi.contentTypes[subject];
433
+ if (!isLocalizedContentType2(ct)) {
434
+ return;
435
+ }
436
+ if (locales2 === null) {
437
+ return;
438
+ }
439
+ condition.and({
440
+ locale: {
441
+ $in: locales2 || []
442
+ }
443
+ });
444
+ };
445
+ const registerI18nPermissionsHandlers = () => {
446
+ const { engine } = strapi.service("admin::permission");
447
+ engine.hooks["before-register.permission"].register(willRegisterPermission);
448
+ };
449
+ const engineService = {
450
+ willRegisterPermission,
451
+ registerI18nPermissionsHandlers
452
+ };
453
+ const permissions = () => ({
454
+ actions: i18nActionsService,
455
+ sectionsBuilder: sectionsBuilderService,
456
+ engine: engineService
457
+ });
458
+ const sendDidInitializeEvent = async () => {
459
+ const { isLocalizedContentType: isLocalizedContentType2 } = getService("content-types");
460
+ const numberOfContentTypes = reduce(
461
+ (sum, contentType) => isLocalizedContentType2(contentType) ? sum + 1 : sum,
462
+ 0
463
+ )(strapi.contentTypes);
464
+ await strapi.telemetry.send("didInitializeI18n", { groupProperties: { numberOfContentTypes } });
465
+ };
466
+ const sendDidUpdateI18nLocalesEvent = async () => {
467
+ const numberOfLocales = await getService("locales").count();
468
+ await strapi.telemetry.send("didUpdateI18nLocales", {
469
+ groupProperties: { numberOfLocales }
470
+ });
471
+ };
472
+ const metrics = () => ({
473
+ sendDidInitializeEvent,
474
+ sendDidUpdateI18nLocalesEvent
475
+ });
476
+ const syncNonLocalizedAttributes = async (sourceEntry, model) => {
477
+ const { copyNonLocalizedAttributes: copyNonLocalizedAttributes2 } = getService("content-types");
478
+ const nonLocalizedAttributes = copyNonLocalizedAttributes2(model, sourceEntry);
479
+ if (isEmpty(nonLocalizedAttributes)) {
480
+ return;
481
+ }
482
+ const uid = model.uid;
483
+ const documentId = sourceEntry.documentId;
484
+ const locale2 = sourceEntry.locale;
485
+ const status = sourceEntry?.publishedAt ? "published" : "draft";
486
+ const localeEntriesToUpdate = await strapi.db.query(uid).findMany({
487
+ where: {
488
+ documentId,
489
+ publishedAt: status === "published" ? { $ne: null } : null,
490
+ locale: { $ne: locale2 }
491
+ },
492
+ select: ["locale", "id"]
493
+ });
494
+ const entryData = await strapi.documents(uid).omitComponentData(nonLocalizedAttributes);
495
+ await async.map(localeEntriesToUpdate, async (entry) => {
496
+ const transformedData = await strapi.documents.utils.transformData(
497
+ cloneDeep(nonLocalizedAttributes),
498
+ {
499
+ uid,
500
+ status,
501
+ locale: entry.locale,
502
+ allowMissingId: true
503
+ }
504
+ );
505
+ const componentData = await strapi.documents(uid).updateComponents(entry, transformedData);
506
+ await strapi.db.query(uid).update({
507
+ where: {
508
+ documentId,
509
+ publishedAt: status === "published" ? { $ne: null } : null,
510
+ locale: { $eq: entry.locale }
511
+ },
512
+ // The data we send to the update function is the entry data merged with
513
+ // the updated component data
514
+ data: Object.assign(cloneDeep(entryData), componentData)
515
+ });
516
+ });
517
+ };
518
+ const localizations = () => ({
519
+ syncNonLocalizedAttributes
520
+ });
177
521
  const isoLocales = [
178
522
  {
179
523
  code: "af",
@@ -2565,440 +2909,42 @@ const isoLocales = [
2565
2909
  },
2566
2910
  {
2567
2911
  code: "yo-NG",
2568
- name: "Yoruba (Nigeria) (yo-NG)"
2569
- },
2570
- {
2571
- code: "dje",
2572
- name: "Zarma (dje)"
2573
- },
2574
- {
2575
- code: "dje-NE",
2576
- name: "Zarma (Niger) (dje-NE)"
2577
- },
2578
- {
2579
- code: "zu",
2580
- name: "Zulu (zu)"
2581
- },
2582
- {
2583
- code: "zu-ZA",
2584
- name: "Zulu (South Africa) (zu-ZA)"
2585
- }
2586
- ];
2587
- const getInitLocale = () => {
2588
- const envLocaleCode = process.env.STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE;
2589
- if (envLocaleCode) {
2590
- const matchingLocale = isoLocales.find(({ code }) => code === envLocaleCode);
2591
- if (!matchingLocale) {
2592
- throw new Error(
2593
- "Unknown locale code provided in the environment variable STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE"
2594
- );
2595
- }
2596
- return { ...matchingLocale };
2597
- }
2598
- return {
2599
- code: "en",
2600
- name: "English (en)"
2601
- };
2602
- };
2603
- const DEFAULT_LOCALE = getInitLocale();
2604
- const enableContentType = async ({ oldContentTypes, contentTypes: contentTypes2 }) => {
2605
- const { isLocalizedContentType: isLocalizedContentType2 } = getService("content-types");
2606
- const { getDefaultLocale: getDefaultLocale2 } = getService("locales");
2607
- if (!oldContentTypes) {
2608
- return;
2609
- }
2610
- for (const uid in contentTypes2) {
2611
- if (!oldContentTypes[uid]) {
2612
- continue;
2613
- }
2614
- const oldContentType = oldContentTypes[uid];
2615
- const contentType = contentTypes2[uid];
2616
- if (!isLocalizedContentType2(oldContentType) && isLocalizedContentType2(contentType)) {
2617
- const defaultLocale = await getDefaultLocale2() || DEFAULT_LOCALE.code;
2618
- await strapi.db.query(uid).updateMany({
2619
- where: { locale: null },
2620
- data: { locale: defaultLocale }
2621
- });
2622
- }
2623
- }
2624
- };
2625
- const disableContentType = async ({ oldContentTypes, contentTypes: contentTypes2 }) => {
2626
- const { isLocalizedContentType: isLocalizedContentType2 } = getService("content-types");
2627
- const { getDefaultLocale: getDefaultLocale2 } = getService("locales");
2628
- if (!oldContentTypes) {
2629
- return;
2630
- }
2631
- for (const uid in contentTypes2) {
2632
- if (!oldContentTypes[uid]) {
2633
- continue;
2634
- }
2635
- const oldContentType = oldContentTypes[uid];
2636
- const contentType = contentTypes2[uid];
2637
- if (isLocalizedContentType2(oldContentType) && !isLocalizedContentType2(contentType)) {
2638
- const defaultLocale = await getDefaultLocale2() || DEFAULT_LOCALE.code;
2639
- await Promise.all([
2640
- // Delete all entities that are not in the default locale
2641
- strapi.db.query(uid).deleteMany({
2642
- where: { locale: { $ne: defaultLocale } }
2643
- }),
2644
- // Set locale to null for the rest
2645
- strapi.db.query(uid).updateMany({
2646
- where: { locale: { $eq: defaultLocale } },
2647
- data: { locale: null }
2648
- })
2649
- ]);
2650
- }
2651
- }
2652
- };
2653
- const register = ({ strapi: strapi2 }) => {
2654
- extendContentTypes(strapi2);
2655
- addContentManagerLocaleMiddleware(strapi2);
2656
- addContentTypeSyncHooks(strapi2);
2657
- };
2658
- const addContentManagerLocaleMiddleware = (strapi2) => {
2659
- strapi2.server.router.use("/content-manager/collection-types/:model", (ctx, next) => {
2660
- if (ctx.method === "POST" || ctx.method === "PUT") {
2661
- return validateLocaleCreation(ctx, next);
2662
- }
2663
- return next();
2664
- });
2665
- strapi2.server.router.use("/content-manager/single-types/:model", (ctx, next) => {
2666
- if (ctx.method === "POST" || ctx.method === "PUT") {
2667
- return validateLocaleCreation(ctx, next);
2668
- }
2669
- return next();
2670
- });
2671
- };
2672
- const addContentTypeSyncHooks = (strapi2) => {
2673
- strapi2.hook("strapi::content-types.beforeSync").register(disableContentType);
2674
- strapi2.hook("strapi::content-types.afterSync").register(enableContentType);
2675
- };
2676
- const extendContentTypes = (strapi2) => {
2677
- Object.values(strapi2.contentTypes).forEach((contentType) => {
2678
- const { attributes: attributes2 } = contentType;
2679
- _.set(attributes2, "locale", {
2680
- writable: true,
2681
- private: false,
2682
- configurable: false,
2683
- visible: false,
2684
- type: "string"
2685
- });
2686
- _.set(attributes2, "localizations", {
2687
- type: "relation",
2688
- relation: "oneToMany",
2689
- target: contentType.uid,
2690
- writable: false,
2691
- private: false,
2692
- configurable: false,
2693
- visible: false,
2694
- unstable_virtual: true,
2695
- joinColumn: {
2696
- name: "document_id",
2697
- referencedColumn: "document_id",
2698
- referencedTable: strapi2.db.metadata.identifiers.getTableName(contentType.collectionName),
2699
- // ensure the population will not include the results we already loaded
2700
- on({ results }) {
2701
- return {
2702
- id: {
2703
- $notIn: results.map((r) => r.id)
2704
- }
2705
- };
2706
- }
2707
- }
2708
- });
2709
- });
2710
- if (strapi2.plugin("graphql")) {
2711
- graphqlProvider({ strapi: strapi2 }).register();
2712
- }
2713
- };
2714
- const info = {
2715
- singularName: "locale",
2716
- pluralName: "locales",
2717
- collectionName: "locales",
2718
- displayName: "Locale",
2719
- description: ""
2720
- };
2721
- const options = {};
2722
- const pluginOptions = {
2723
- "content-manager": {
2724
- visible: false
2725
- },
2726
- "content-type-builder": {
2727
- visible: false
2728
- }
2729
- };
2730
- const attributes = {
2731
- name: {
2732
- type: "string",
2733
- min: 1,
2734
- max: 50,
2735
- configurable: false
2736
- },
2737
- code: {
2738
- type: "string",
2739
- unique: true,
2740
- configurable: false
2741
- }
2742
- };
2743
- const schema = {
2744
- info,
2745
- options,
2746
- pluginOptions,
2747
- attributes
2748
- };
2749
- const locale = {
2750
- schema
2751
- };
2752
- const contentTypes$1 = {
2753
- locale
2754
- };
2755
- const actions = [
2912
+ name: "Yoruba (Nigeria) (yo-NG)"
2913
+ },
2756
2914
  {
2757
- section: "settings",
2758
- category: "Internationalization",
2759
- subCategory: "Locales",
2760
- pluginName: "i18n",
2761
- displayName: "Create",
2762
- uid: "locale.create"
2915
+ code: "dje",
2916
+ name: "Zarma (dje)"
2763
2917
  },
2764
2918
  {
2765
- section: "settings",
2766
- category: "Internationalization",
2767
- subCategory: "Locales",
2768
- pluginName: "i18n",
2769
- displayName: "Read",
2770
- uid: "locale.read",
2771
- aliases: [
2772
- { actionId: "plugin::content-manager.explorer.read", subjects: ["plugin::i18n.locale"] }
2773
- ]
2919
+ code: "dje-NE",
2920
+ name: "Zarma (Niger) (dje-NE)"
2774
2921
  },
2775
2922
  {
2776
- section: "settings",
2777
- category: "Internationalization",
2778
- subCategory: "Locales",
2779
- pluginName: "i18n",
2780
- displayName: "Update",
2781
- uid: "locale.update"
2923
+ code: "zu",
2924
+ name: "Zulu (zu)"
2782
2925
  },
2783
2926
  {
2784
- section: "settings",
2785
- category: "Internationalization",
2786
- subCategory: "Locales",
2787
- pluginName: "i18n",
2788
- displayName: "Delete",
2789
- uid: "locale.delete"
2927
+ code: "zu-ZA",
2928
+ name: "Zulu (South Africa) (zu-ZA)"
2790
2929
  }
2791
2930
  ];
2792
- const addLocalesPropertyIfNeeded = ({ value: action }) => {
2793
- const {
2794
- section,
2795
- options: { applyToProperties }
2796
- } = action;
2797
- if (section !== "contentTypes") {
2798
- return;
2799
- }
2800
- if (isArray(applyToProperties) && applyToProperties.includes("locales")) {
2801
- return;
2802
- }
2803
- action.options.applyToProperties = isArray(applyToProperties) ? applyToProperties.concat("locales") : ["locales"];
2804
- };
2805
- const shouldApplyLocalesPropertyToSubject = ({ property, subject }) => {
2806
- if (property === "locales") {
2807
- const model = strapi.getModel(subject);
2808
- return getService("content-types").isLocalizedContentType(model);
2809
- }
2810
- return true;
2811
- };
2812
- const addAllLocalesToPermissions = async (permissions2) => {
2813
- const { actionProvider } = strapi.service("admin::permission");
2814
- const { find: findAllLocales } = getService("locales");
2815
- const allLocales = await findAllLocales();
2816
- const allLocalesCode = allLocales.map(prop("code"));
2817
- return Promise.all(
2818
- permissions2.map(async (permission) => {
2819
- const { action, subject } = permission;
2820
- const appliesToLocalesProperty = await actionProvider.appliesToProperty(
2821
- "locales",
2822
- action,
2823
- subject
2931
+ const getInitLocale = () => {
2932
+ const envLocaleCode = process.env.STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE;
2933
+ if (envLocaleCode) {
2934
+ const matchingLocale = isoLocales.find(({ code }) => code === envLocaleCode);
2935
+ if (!matchingLocale) {
2936
+ throw new Error(
2937
+ "Unknown locale code provided in the environment variable STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE"
2824
2938
  );
2825
- if (!appliesToLocalesProperty) {
2826
- return permission;
2827
- }
2828
- const oldPermissionProperties = getOr({}, "properties", permission);
2829
- return { ...permission, properties: { ...oldPermissionProperties, locales: allLocalesCode } };
2830
- })
2831
- );
2832
- };
2833
- const syncSuperAdminPermissionsWithLocales = async () => {
2834
- const roleService = strapi.service("admin::role");
2835
- const permissionService = strapi.service("admin::permission");
2836
- const superAdminRole = await roleService.getSuperAdmin();
2837
- if (!superAdminRole) {
2838
- return;
2839
- }
2840
- const superAdminPermissions = await permissionService.findMany({
2841
- where: {
2842
- role: {
2843
- id: superAdminRole.id
2844
- }
2845
- }
2846
- });
2847
- const newSuperAdminPermissions = await addAllLocalesToPermissions(superAdminPermissions);
2848
- await roleService.assignPermissions(superAdminRole.id, newSuperAdminPermissions);
2849
- };
2850
- const registerI18nActions = async () => {
2851
- const { actionProvider } = strapi.service("admin::permission");
2852
- await actionProvider.registerMany(actions);
2853
- };
2854
- const registerI18nActionsHooks = () => {
2855
- const { actionProvider } = strapi.service("admin::permission");
2856
- const { hooks } = strapi.service("admin::role");
2857
- actionProvider.hooks.appliesPropertyToSubject.register(shouldApplyLocalesPropertyToSubject);
2858
- hooks.willResetSuperAdminPermissions.register(addAllLocalesToPermissions);
2859
- };
2860
- const updateActionsProperties = () => {
2861
- const { actionProvider } = strapi.service("admin::permission");
2862
- actionProvider.hooks.willRegister.register(addLocalesPropertyIfNeeded);
2863
- actionProvider.values().forEach((action) => addLocalesPropertyIfNeeded({ value: action }));
2864
- };
2865
- const i18nActionsService = {
2866
- actions,
2867
- registerI18nActions,
2868
- registerI18nActionsHooks,
2869
- updateActionsProperties,
2870
- syncSuperAdminPermissionsWithLocales
2871
- };
2872
- const localesPropertyHandler = async ({ action, section }) => {
2873
- const { actionProvider } = strapi.service("admin::permission");
2874
- const locales2 = await getService("locales").find();
2875
- if (isEmpty(locales2)) {
2876
- return;
2877
- }
2878
- for (const subject of section.subjects) {
2879
- const applies = await actionProvider.appliesToProperty("locales", action.actionId, subject.uid);
2880
- const hasLocalesProperty = subject.properties.find(
2881
- (property) => property.value === "locales"
2882
- );
2883
- if (applies && !hasLocalesProperty) {
2884
- subject.properties.push({
2885
- label: "Locales",
2886
- value: "locales",
2887
- children: locales2.map(({ name, code }) => ({ label: name || code, value: code }))
2888
- });
2889
- }
2890
- }
2891
- };
2892
- const registerLocalesPropertyHandler = () => {
2893
- const { sectionsBuilder } = strapi.service("admin::permission");
2894
- sectionsBuilder.addHandler("singleTypes", localesPropertyHandler);
2895
- sectionsBuilder.addHandler("collectionTypes", localesPropertyHandler);
2896
- };
2897
- const sectionsBuilderService = {
2898
- localesPropertyHandler,
2899
- registerLocalesPropertyHandler
2900
- };
2901
- const willRegisterPermission = (context) => {
2902
- const { permission, condition, user } = context;
2903
- const { subject, properties } = permission;
2904
- const isSuperAdmin = strapi.service("admin::role").hasSuperAdminRole(user);
2905
- if (isSuperAdmin) {
2906
- return;
2907
- }
2908
- const { locales: locales2 } = properties || {};
2909
- const { isLocalizedContentType: isLocalizedContentType2 } = getService("content-types");
2910
- if (!subject) {
2911
- return;
2912
- }
2913
- const ct = strapi.contentTypes[subject];
2914
- if (!isLocalizedContentType2(ct)) {
2915
- return;
2916
- }
2917
- if (locales2 === null) {
2918
- return;
2919
- }
2920
- condition.and({
2921
- locale: {
2922
- $in: locales2 || []
2923
2939
  }
2924
- });
2925
- };
2926
- const registerI18nPermissionsHandlers = () => {
2927
- const { engine } = strapi.service("admin::permission");
2928
- engine.hooks["before-register.permission"].register(willRegisterPermission);
2929
- };
2930
- const engineService = {
2931
- willRegisterPermission,
2932
- registerI18nPermissionsHandlers
2933
- };
2934
- const permissions = () => ({
2935
- actions: i18nActionsService,
2936
- sectionsBuilder: sectionsBuilderService,
2937
- engine: engineService
2938
- });
2939
- const sendDidInitializeEvent = async () => {
2940
- const { isLocalizedContentType: isLocalizedContentType2 } = getService("content-types");
2941
- const numberOfContentTypes = reduce(
2942
- (sum, contentType) => isLocalizedContentType2(contentType) ? sum + 1 : sum,
2943
- 0
2944
- )(strapi.contentTypes);
2945
- await strapi.telemetry.send("didInitializeI18n", { groupProperties: { numberOfContentTypes } });
2946
- };
2947
- const sendDidUpdateI18nLocalesEvent = async () => {
2948
- const numberOfLocales = await getService("locales").count();
2949
- await strapi.telemetry.send("didUpdateI18nLocales", {
2950
- groupProperties: { numberOfLocales }
2951
- });
2952
- };
2953
- const metrics = () => ({
2954
- sendDidInitializeEvent,
2955
- sendDidUpdateI18nLocalesEvent
2956
- });
2957
- const syncNonLocalizedAttributes = async (sourceEntry, model) => {
2958
- const { copyNonLocalizedAttributes: copyNonLocalizedAttributes2 } = getService("content-types");
2959
- const nonLocalizedAttributes = copyNonLocalizedAttributes2(model, sourceEntry);
2960
- if (isEmpty(nonLocalizedAttributes)) {
2961
- return;
2940
+ return { ...matchingLocale };
2962
2941
  }
2963
- const uid = model.uid;
2964
- const documentId = sourceEntry.documentId;
2965
- const locale2 = sourceEntry.locale;
2966
- const status = sourceEntry?.publishedAt ? "published" : "draft";
2967
- const localeEntriesToUpdate = await strapi.db.query(uid).findMany({
2968
- where: {
2969
- documentId,
2970
- publishedAt: status === "published" ? { $ne: null } : null,
2971
- locale: { $ne: locale2 }
2972
- },
2973
- select: ["locale", "id"]
2974
- });
2975
- const entryData = await strapi.documents(uid).omitComponentData(nonLocalizedAttributes);
2976
- await async.map(localeEntriesToUpdate, async (entry) => {
2977
- const transformedData = await strapi.documents.utils.transformData(
2978
- cloneDeep(nonLocalizedAttributes),
2979
- {
2980
- uid,
2981
- status,
2982
- locale: entry.locale,
2983
- allowMissingId: true
2984
- }
2985
- );
2986
- const componentData = await strapi.documents(uid).updateComponents(entry, transformedData);
2987
- await strapi.db.query(uid).update({
2988
- where: {
2989
- documentId,
2990
- publishedAt: status === "published" ? { $ne: null } : null,
2991
- locale: { $eq: entry.locale }
2992
- },
2993
- // The data we send to the update function is the entry data merged with
2994
- // the updated component data
2995
- data: Object.assign(cloneDeep(entryData), componentData)
2996
- });
2997
- });
2942
+ return {
2943
+ code: "en",
2944
+ name: "English (en)"
2945
+ };
2998
2946
  };
2999
- const localizations = () => ({
3000
- syncNonLocalizedAttributes
3001
- });
2947
+ const DEFAULT_LOCALE = getInitLocale();
3002
2948
  const find = (params = {}) => strapi.db.query("plugin::i18n.locale").findMany({ where: params });
3003
2949
  const findById = (id) => strapi.db.query("plugin::i18n.locale").findOne({ where: { id } });
3004
2950
  const findByCode = (code) => strapi.db.query("plugin::i18n.locale").findOne({ where: { code } });