@adminforth/i18n 1.0.21-next.0 β†’ 1.0.21

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.
package/Changelog.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [1.0.21] - next
9
9
 
10
+ ### Fixed
11
+ - improve cache reset when editing messages manually
12
+
13
+ ### Added
14
+ - Translating external app" feature by using feedCategoryTranslations
15
+
10
16
  ## [1.0.20]
11
17
 
12
18
  ### Fixed
package/dist/index.js CHANGED
@@ -215,7 +215,6 @@ export default class I18N extends AdminForthPlugin {
215
215
  }));
216
216
  // add hook on edit of any translation
217
217
  resourceConfig.hooks.edit.afterSave.push((_d) => __awaiter(this, [_d], void 0, function* ({ updates, oldRecord }) {
218
- console.log('πŸͺ²edit.afterSave', JSON.stringify(updates, null, 2), '-----', JSON.stringify(oldRecord, null, 2));
219
218
  if (oldRecord) {
220
219
  // find lang which changed
221
220
  let langsChanged = [];
@@ -223,10 +222,14 @@ export default class I18N extends AdminForthPlugin {
223
222
  if (lang === 'en') {
224
223
  continue;
225
224
  }
225
+ if (updates[this.trFieldNames[lang]] !== undefined) {
226
+ langsChanged.push(lang);
227
+ }
226
228
  }
227
229
  // clear frontend cache for all langsChanged
228
230
  for (const lang of langsChanged) {
229
- this.cache.clear(`${this.resourceConfig.resourceId}:frontend:${lang}`);
231
+ this.cache.clear(`${this.resourceConfig.resourceId}:${oldRecord[this.options.categoryFieldName]}:${lang}`);
232
+ this.cache.clear(`${this.resourceConfig.resourceId}:${oldRecord[this.options.categoryFieldName]}:${lang}:${oldRecord[this.enFieldName]}`);
230
233
  }
231
234
  this.updateUntranslatedMenuBadge();
232
235
  }
@@ -236,7 +239,8 @@ export default class I18N extends AdminForthPlugin {
236
239
  // add hook on delete of any translation to reset cache
237
240
  resourceConfig.hooks.delete.afterSave.push((_e) => __awaiter(this, [_e], void 0, function* ({ record }) {
238
241
  for (const lang of this.options.supportedLanguages) {
239
- this.cache.clear(`${this.resourceConfig.resourceId}:frontend:${lang}`);
242
+ // if frontend, clear frontend cache
243
+ this.cache.clear(`${this.resourceConfig.resourceId}:${record[this.options.categoryFieldName]}:${lang}`);
240
244
  this.cache.clear(`${this.resourceConfig.resourceId}:${record[this.options.categoryFieldName]}:${lang}:${record[this.enFieldName]}`);
241
245
  }
242
246
  this.updateUntranslatedMenuBadge();
@@ -497,33 +501,13 @@ ${JSON.stringify(strings.reduce((acc, s) => {
497
501
  return;
498
502
  }
499
503
  // loop over missingKeys[i].path and add them to database if not exists
500
- const missingKeysDeduplicated = messages.missingKeys.reduce((acc, missingKey) => {
501
- if (!acc.find((a) => a.path === missingKey.path)) {
502
- acc.push(missingKey);
503
- }
504
- return acc;
505
- }, []);
506
- yield Promise.all(missingKeysDeduplicated.map((missingKey) => __awaiter(this, void 0, void 0, function* () {
507
- const key = missingKey.path;
508
- const file = missingKey.file;
509
- const category = 'frontend';
510
- const exists = yield adminforth.resource(this.resourceConfig.resourceId).count(Filters.EQ(this.enFieldName, key));
511
- if (exists) {
512
- return;
513
- }
514
- if (!key) {
515
- throw new Error(`Faced an empty key in Fronted messages, file ${file}`);
516
- }
517
- const record = Object.assign({ [this.enFieldName]: key, [this.options.categoryFieldName]: category }, (this.options.sourceFieldName ? { [this.options.sourceFieldName]: file } : {}));
518
- try {
519
- yield adminforth.resource(this.resourceConfig.resourceId).create(record);
520
- }
521
- catch (e) {
522
- console.error('πŸ› Error creating record', e);
523
- }
524
- })));
525
- // updateBadge
526
- this.updateUntranslatedMenuBadge();
504
+ const messagesForFeed = messages.missingKeys.map((mk) => {
505
+ return {
506
+ en_string: mk.path,
507
+ source: mk.file,
508
+ };
509
+ });
510
+ yield this.feedCategoryTranslations(messagesForFeed, 'frontend');
527
511
  });
528
512
  }
529
513
  tryProcessAndWatch(adminforth) {
@@ -641,6 +625,54 @@ ${JSON.stringify(strings.reduce((acc, s) => {
641
625
  // Needed if plugin can have multiple instances on one resource
642
626
  return `single`;
643
627
  }
628
+ getCategoryTranslations(category, lang) {
629
+ return __awaiter(this, void 0, void 0, function* () {
630
+ const resource = this.adminforth.resource(this.resourceConfig.resourceId);
631
+ const cacheKey = `${this.resourceConfig.resourceId}:${category}:${lang}`;
632
+ const cached = yield this.cache.get(cacheKey);
633
+ if (cached) {
634
+ return cached;
635
+ }
636
+ const translations = {};
637
+ const allTranslations = yield resource.list([Filters.EQ(this.options.categoryFieldName, category)]);
638
+ for (const tr of allTranslations) {
639
+ translations[tr[this.enFieldName]] = tr[this.trFieldNames[lang]];
640
+ }
641
+ yield this.cache.set(cacheKey, translations);
642
+ return translations;
643
+ });
644
+ }
645
+ feedCategoryTranslations(messages, category) {
646
+ return __awaiter(this, void 0, void 0, function* () {
647
+ const adminforth = this.adminforth;
648
+ const missingKeysDeduplicated = messages.reduce((acc, missingKey) => {
649
+ if (!acc.find((a) => a.en_string === missingKey.en_string)) {
650
+ acc.push(missingKey);
651
+ }
652
+ return acc;
653
+ }, []);
654
+ yield Promise.all(missingKeysDeduplicated.map((missingKey) => __awaiter(this, void 0, void 0, function* () {
655
+ const key = missingKey.en_string;
656
+ const source = missingKey.source;
657
+ const exists = yield adminforth.resource(this.resourceConfig.resourceId).count(Filters.EQ(this.enFieldName, key));
658
+ if (exists) {
659
+ return;
660
+ }
661
+ if (!key) {
662
+ console.error(`Faced an empty key in feeding ${category} messages, source ${source}`);
663
+ }
664
+ const record = Object.assign({ [this.enFieldName]: key, [this.options.categoryFieldName]: category }, (this.options.sourceFieldName ? { [this.options.sourceFieldName]: source } : {}));
665
+ try {
666
+ yield adminforth.resource(this.resourceConfig.resourceId).create(record);
667
+ }
668
+ catch (e) {
669
+ console.error('πŸ› Error creating record', e);
670
+ }
671
+ })));
672
+ // updateBadge
673
+ this.updateUntranslatedMenuBadge();
674
+ });
675
+ }
644
676
  setupEndpoints(server) {
645
677
  server.endpoint({
646
678
  method: 'GET',
@@ -649,18 +681,7 @@ ${JSON.stringify(strings.reduce((acc, s) => {
649
681
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ query }) {
650
682
  const lang = query.lang;
651
683
  // form map of translations
652
- const resource = this.adminforth.resource(this.resourceConfig.resourceId);
653
- const cacheKey = `${this.resourceConfig.resourceId}:frontend:${lang}`;
654
- const cached = yield this.cache.get(cacheKey);
655
- if (cached) {
656
- return cached;
657
- }
658
- const translations = {};
659
- const allTranslations = yield resource.list([Filters.EQ(this.options.categoryFieldName, 'frontend')]);
660
- for (const tr of allTranslations) {
661
- translations[tr[this.enFieldName]] = tr[this.trFieldNames[lang]];
662
- }
663
- yield this.cache.set(cacheKey, translations);
684
+ const translations = yield this.getCategoryTranslations('frontend', lang);
664
685
  return translations;
665
686
  })
666
687
  });
package/index.ts CHANGED
@@ -244,7 +244,6 @@ export default class I18N extends AdminForthPlugin {
244
244
 
245
245
  // add hook on edit of any translation
246
246
  resourceConfig.hooks.edit.afterSave.push(async ({ updates, oldRecord }: { updates: any, oldRecord?: any }): Promise<{ ok: boolean, error?: string }> => {
247
- console.log('πŸͺ²edit.afterSave', JSON.stringify(updates, null, 2),'-----', JSON.stringify(oldRecord, null, 2));
248
247
  if (oldRecord) {
249
248
  // find lang which changed
250
249
  let langsChanged: LanguageCode[] = [];
@@ -252,26 +251,27 @@ export default class I18N extends AdminForthPlugin {
252
251
  if (lang === 'en') {
253
252
  continue;
254
253
  }
254
+ if (updates[this.trFieldNames[lang]] !== undefined) {
255
+ langsChanged.push(lang);
256
+ }
255
257
  }
256
-
258
+
257
259
  // clear frontend cache for all langsChanged
258
260
  for (const lang of langsChanged) {
259
- this.cache.clear(`${this.resourceConfig.resourceId}:frontend:${lang}`);
261
+ this.cache.clear(`${this.resourceConfig.resourceId}:${oldRecord[this.options.categoryFieldName]}:${lang}`);
262
+ this.cache.clear(`${this.resourceConfig.resourceId}:${oldRecord[this.options.categoryFieldName]}:${lang}:${oldRecord[this.enFieldName]}`);
260
263
  }
261
-
262
264
  this.updateUntranslatedMenuBadge();
263
-
264
265
  }
265
266
  // clear frontend cache for all lan
266
-
267
-
268
267
  return { ok: true };
269
268
  });
270
269
 
271
270
  // add hook on delete of any translation to reset cache
272
271
  resourceConfig.hooks.delete.afterSave.push(async ({ record }: { record: any }): Promise<{ ok: boolean, error?: string }> => {
273
272
  for (const lang of this.options.supportedLanguages) {
274
- this.cache.clear(`${this.resourceConfig.resourceId}:frontend:${lang}`);
273
+ // if frontend, clear frontend cache
274
+ this.cache.clear(`${this.resourceConfig.resourceId}:${record[this.options.categoryFieldName]}:${lang}`);
275
275
  this.cache.clear(`${this.resourceConfig.resourceId}:${record[this.options.categoryFieldName]}:${lang}:${record[this.enFieldName]}`);
276
276
  }
277
277
  this.updateUntranslatedMenuBadge();
@@ -603,39 +603,16 @@ JSON.stringify(strings.reduce((acc: object, s: { en_string: string }): object =>
603
603
  return;
604
604
  }
605
605
  // loop over missingKeys[i].path and add them to database if not exists
606
-
607
- const missingKeysDeduplicated = messages.missingKeys.reduce((acc: any[], missingKey: any) => {
608
- if (!acc.find((a) => a.path === missingKey.path)) {
609
- acc.push(missingKey);
610
- }
611
- return acc;
612
- }, []);
613
-
614
- await Promise.all(missingKeysDeduplicated.map(async (missingKey: any) => {
615
- const key = missingKey.path;
616
- const file = missingKey.file;
617
- const category = 'frontend';
618
- const exists = await adminforth.resource(this.resourceConfig.resourceId).count(Filters.EQ(this.enFieldName, key));
619
- if (exists) {
620
- return;
621
- }
622
- if (!key) {
623
- throw new Error(`Faced an empty key in Fronted messages, file ${file}`);
624
- }
625
- const record = {
626
- [this.enFieldName]: key,
627
- [this.options.categoryFieldName]: category,
628
- ...(this.options.sourceFieldName ? { [this.options.sourceFieldName]: file } : {}),
606
+ const messagesForFeed = messages.missingKeys.map((mk) => {
607
+ return {
608
+ en_string: mk.path,
609
+ source: mk.file,
629
610
  };
630
- try {
631
- await adminforth.resource(this.resourceConfig.resourceId).create(record);
632
- } catch (e) {
633
- console.error('πŸ› Error creating record', e);
634
- }
635
- }));
611
+ });
636
612
 
637
- // updateBadge
638
- this.updateUntranslatedMenuBadge()
613
+ await this.feedCategoryTranslations(messagesForFeed, 'frontend')
614
+
615
+
639
616
  }
640
617
 
641
618
 
@@ -764,6 +741,60 @@ JSON.stringify(strings.reduce((acc: object, s: { en_string: string }): object =>
764
741
  return `single`;
765
742
  }
766
743
 
744
+ async getCategoryTranslations(category: string, lang: string): Promise<Record<string, string>> {
745
+ const resource = this.adminforth.resource(this.resourceConfig.resourceId);
746
+ const cacheKey = `${this.resourceConfig.resourceId}:${category}:${lang}`;
747
+ const cached = await this.cache.get(cacheKey);
748
+ if (cached) {
749
+ return cached;
750
+ }
751
+ const translations = {};
752
+ const allTranslations = await resource.list([Filters.EQ(this.options.categoryFieldName, category)]);
753
+ for (const tr of allTranslations) {
754
+ translations[tr[this.enFieldName]] = tr[this.trFieldNames[lang]];
755
+ }
756
+ await this.cache.set(cacheKey, translations);
757
+ return translations;
758
+ }
759
+
760
+ async feedCategoryTranslations(messages: {
761
+ en_string: string;
762
+ source: string;
763
+ }[], category: string): Promise<void> {
764
+ const adminforth = this.adminforth;
765
+ const missingKeysDeduplicated = messages.reduce((acc: any[], missingKey: any) => {
766
+ if (!acc.find((a) => a.en_string === missingKey.en_string)) {
767
+ acc.push(missingKey);
768
+ }
769
+ return acc;
770
+ }, []);
771
+
772
+ await Promise.all(missingKeysDeduplicated.map(async (missingKey: any) => {
773
+ const key = missingKey.en_string;
774
+ const source = missingKey.source;
775
+ const exists = await adminforth.resource(this.resourceConfig.resourceId).count(Filters.EQ(this.enFieldName, key));
776
+ if (exists) {
777
+ return;
778
+ }
779
+ if (!key) {
780
+ console.error(`Faced an empty key in feeding ${category} messages, source ${source}`);
781
+ }
782
+ const record = {
783
+ [this.enFieldName]: key,
784
+ [this.options.categoryFieldName]: category,
785
+ ...(this.options.sourceFieldName ? { [this.options.sourceFieldName]: source } : {}),
786
+ };
787
+ try {
788
+ await adminforth.resource(this.resourceConfig.resourceId).create(record);
789
+ } catch (e) {
790
+ console.error('πŸ› Error creating record', e);
791
+ }
792
+ }));
793
+
794
+ // updateBadge
795
+ this.updateUntranslatedMenuBadge();
796
+ }
797
+
767
798
 
768
799
  setupEndpoints(server: IHttpServer) {
769
800
  server.endpoint({
@@ -774,18 +805,7 @@ JSON.stringify(strings.reduce((acc: object, s: { en_string: string }): object =>
774
805
  const lang = query.lang;
775
806
 
776
807
  // form map of translations
777
- const resource = this.adminforth.resource(this.resourceConfig.resourceId);
778
- const cacheKey = `${this.resourceConfig.resourceId}:frontend:${lang}`;
779
- const cached = await this.cache.get(cacheKey);
780
- if (cached) {
781
- return cached;
782
- }
783
- const translations = {};
784
- const allTranslations = await resource.list([Filters.EQ(this.options.categoryFieldName, 'frontend')]);
785
- for (const tr of allTranslations) {
786
- translations[tr[this.enFieldName]] = tr[this.trFieldNames[lang]];
787
- }
788
- await this.cache.set(cacheKey, translations);
808
+ const translations = await this.getCategoryTranslations('frontend', lang);
789
809
  return translations;
790
810
 
791
811
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/i18n",
3
- "version": "1.0.21-next.0",
3
+ "version": "1.0.21",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",