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