@adminforth/i18n 1.0.23-next.0 → 1.0.23-next.1

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
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.23] - next
9
+
10
+ ### Improved
11
+
12
+ - Better instructions for LLM pluralization Slavik messages
13
+
14
+ ### Added
15
+ - support for pluralization in Backend `tr` function
16
+
8
17
  ## [1.0.22]
9
18
 
10
19
  ### Fixed
@@ -32,6 +32,7 @@
32
32
  import Select from '@/afcl/Select.vue';
33
33
  import 'flag-icon-css/css/flag-icons.min.css';
34
34
  import { setLang, getCountryCodeFromLangCode, getLocalLang } from './langCommon';
35
+ import { useCoreStore } from '@/stores/core';
35
36
 
36
37
  import { computed, ref, onMounted, watch } from 'vue';
37
38
  import { useI18n } from 'vue-i18n';
@@ -42,9 +43,11 @@ const { setLocaleMessage, locale } = useI18n();
42
43
  const props = defineProps(['meta', 'resource']);
43
44
 
44
45
  const selectedLanguage = ref('');
46
+ const coreStore = useCoreStore();
45
47
 
46
- watch(() => selectedLanguage.value, (newVal) => {
47
- setLang({ setLocaleMessage, locale }, props.meta.pluginInstanceId, newVal);
48
+ watch(() => selectedLanguage.value, async (newVal) => {
49
+ await setLang({ setLocaleMessage, locale }, props.meta.pluginInstanceId, newVal);
50
+ coreStore.getPublicConfig();
48
51
  });
49
52
 
50
53
 
@@ -32,6 +32,7 @@
32
32
  import Select from '@/afcl/Select.vue';
33
33
  import 'flag-icon-css/css/flag-icons.min.css';
34
34
  import { setLang, getCountryCodeFromLangCode, getLocalLang } from './langCommon';
35
+ import { useCoreStore } from '@/stores/core';
35
36
 
36
37
  import { computed, ref, onMounted, watch } from 'vue';
37
38
  import { useI18n } from 'vue-i18n';
@@ -42,9 +43,11 @@ const { setLocaleMessage, locale } = useI18n();
42
43
  const props = defineProps(['meta', 'resource']);
43
44
 
44
45
  const selectedLanguage = ref('');
46
+ const coreStore = useCoreStore();
45
47
 
46
- watch(() => selectedLanguage.value, (newVal) => {
47
- setLang({ setLocaleMessage, locale }, props.meta.pluginInstanceId, newVal);
48
+ watch(() => selectedLanguage.value, async (newVal) => {
49
+ await setLang({ setLocaleMessage, locale }, props.meta.pluginInstanceId, newVal);
50
+ coreStore.getPublicConfig();
48
51
  });
49
52
 
50
53
 
package/dist/index.js CHANGED
@@ -380,7 +380,7 @@ export default class I18nPlugin extends AdminForthPlugin {
380
380
  const requestSlavicPlurals = Object.keys(SLAVIC_PLURAL_EXAMPLES).includes(lang) && plurals;
381
381
  const prompt = `
382
382
  I need to translate strings in JSON to ${lang} (${langName}) language from English for my web app.
383
- ${requestSlavicPlurals ? `You should provide 4 translations (in format zero | singular | 2-4 | 5+) e.g. ${SLAVIC_PLURAL_EXAMPLES[lang]}` : ''}
383
+ ${requestSlavicPlurals ? `You should provide 4 slavic forms (in format "zero count | singular count | 2-4 | 5+") e.g. "apple | apples" should become "${SLAVIC_PLURAL_EXAMPLES[lang]}"` : ''}
384
384
  Keep keys, as is, write translation into values! Here are the strings:
385
385
 
386
386
  \`\`\`json
@@ -474,8 +474,10 @@ ${JSON.stringify(strings.reduce((acc, s) => {
474
474
  totalTranslated = totalTranslated.concat(noPluralKeys, pluralKeys);
475
475
  })));
476
476
  yield Promise.all(Object.entries(updateStrings).map((_c) => __awaiter(this, [_c], void 0, function* ([_, { updates, strId }]) {
477
+ // get old full record
478
+ const oldRecord = yield this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(this.primaryKeyFieldName, strId)]);
477
479
  // because this will translate all languages, we can set completedLangs to all languages
478
- const futureCompletedFieldValue = yield this.computeCompletedFieldValue(updates);
480
+ const futureCompletedFieldValue = yield this.computeCompletedFieldValue(Object.assign(Object.assign({}, oldRecord), updates));
479
481
  yield this.adminforth.resource(this.resourceConfig.resourceId).update(strId, Object.assign(Object.assign({}, updates), { [this.options.completedFieldName]: futureCompletedFieldValue }));
480
482
  })));
481
483
  for (const lang of langsInvolved) {
@@ -565,7 +567,7 @@ ${JSON.stringify(strings.reduce((acc, s) => {
565
567
  }
566
568
  // in this plugin we will use plugin to fill the database with missing language messages
567
569
  this.tryProcessAndWatch(adminforth);
568
- adminforth.tr = (msg, category, lang, params) => __awaiter(this, void 0, void 0, function* () {
570
+ adminforth.tr = (msg, category, lang, params, pluralizationNumber) => __awaiter(this, void 0, void 0, function* () {
569
571
  if (!msg) {
570
572
  return msg;
571
573
  }
@@ -612,6 +614,10 @@ ${JSON.stringify(strings.reduce((acc, s) => {
612
614
  // cache so even if key does not exist, we will not hit database
613
615
  yield this.cache.set(cacheKey, result);
614
616
  }
617
+ // if msg has '|' in it, then we need to aplly pluralization
618
+ if (msg.includes('|')) {
619
+ result = this.applyPluralization(result, pluralizationNumber, lang);
620
+ }
615
621
  if (params) {
616
622
  for (const [key, value] of Object.entries(params)) {
617
623
  result = result.replace(`{${key}}`, value);
@@ -620,6 +626,32 @@ ${JSON.stringify(strings.reduce((acc, s) => {
620
626
  return result;
621
627
  });
622
628
  }
629
+ applyPluralization(str, number, lang) {
630
+ const choices = str.split('|');
631
+ const choicesLength = choices.length;
632
+ if (choicesLength > 2) {
633
+ // this is slavic pluralization
634
+ return choices[this.slavicPluralRule(number, choicesLength)];
635
+ }
636
+ else {
637
+ return number === 1 ? choices[0] : choices[1];
638
+ }
639
+ }
640
+ // taken from here https://vue-i18n.intlify.dev/guide/essentials/pluralization.html#custom-pluralization
641
+ slavicPluralRule(choice, choicesLength) {
642
+ if (choice === 0) {
643
+ return 0;
644
+ }
645
+ const teen = choice > 10 && choice < 20;
646
+ const endsWithOne = choice % 10 === 1;
647
+ if (!teen && endsWithOne) {
648
+ return 1;
649
+ }
650
+ if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
651
+ return 2;
652
+ }
653
+ return choicesLength < 4 ? 2 : 3;
654
+ }
623
655
  instanceUniqueRepresentation(pluginOptions) {
624
656
  // optional method to return unique string representation of plugin instance.
625
657
  // Needed if plugin can have multiple instances on one resource
package/index.ts CHANGED
@@ -429,7 +429,7 @@ export default class I18nPlugin extends AdminForthPlugin {
429
429
 
430
430
  const prompt = `
431
431
  I need to translate strings in JSON to ${lang} (${langName}) language from English for my web app.
432
- ${requestSlavicPlurals ? `You should provide 4 translations (in format zero | singular | 2-4 | 5+) e.g. ${SLAVIC_PLURAL_EXAMPLES[lang]}` : ''}
432
+ ${requestSlavicPlurals ? `You should provide 4 slavic forms (in format "zero count | singular count | 2-4 | 5+") e.g. "apple | apples" should become "${SLAVIC_PLURAL_EXAMPLES[lang]}"` : ''}
433
433
  Keep keys, as is, write translation into values! Here are the strings:
434
434
 
435
435
  \`\`\`json
@@ -449,6 +449,7 @@ JSON.stringify(strings.reduce((acc: object, s: { en_string: string }): object =>
449
449
  300,
450
450
  );
451
451
 
452
+
452
453
  if (resp.error) {
453
454
  throw new AiTranslateError(resp.error);
454
455
  }
@@ -568,8 +569,11 @@ JSON.stringify(strings.reduce((acc: object, s: { en_string: string }): object =>
568
569
  await Promise.all(
569
570
  Object.entries(updateStrings).map(
570
571
  async ([_, { updates, strId }]: [string, { updates: any, category: string, strId: string }]) => {
572
+ // get old full record
573
+ const oldRecord = await this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(this.primaryKeyFieldName, strId)]);
574
+
571
575
  // because this will translate all languages, we can set completedLangs to all languages
572
- const futureCompletedFieldValue = await this.computeCompletedFieldValue(updates);
576
+ const futureCompletedFieldValue = await this.computeCompletedFieldValue({ ...oldRecord, ...updates });
573
577
 
574
578
  await this.adminforth.resource(this.resourceConfig.resourceId).update(strId, {
575
579
  ...updates,
@@ -675,7 +679,7 @@ JSON.stringify(strings.reduce((acc: object, s: { en_string: string }): object =>
675
679
  // in this plugin we will use plugin to fill the database with missing language messages
676
680
  this.tryProcessAndWatch(adminforth);
677
681
 
678
- adminforth.tr = async (msg: string | null | undefined, category: string, lang: string, params): Promise<string> => {
682
+ adminforth.tr = async (msg: string | null | undefined, category: string, lang: string, params, pluralizationNumber: number): Promise<string> => {
679
683
  if (!msg) {
680
684
  return msg;
681
685
  }
@@ -726,6 +730,11 @@ JSON.stringify(strings.reduce((acc: object, s: { en_string: string }): object =>
726
730
  // cache so even if key does not exist, we will not hit database
727
731
  await this.cache.set(cacheKey, result);
728
732
  }
733
+ // if msg has '|' in it, then we need to aplly pluralization
734
+ if (msg.includes('|')) {
735
+ result = this.applyPluralization(result, pluralizationNumber, lang);
736
+ }
737
+
729
738
  if (params) {
730
739
  for (const [key, value] of Object.entries(params)) {
731
740
  result = result.replace(`{${key}}`, value);
@@ -735,6 +744,36 @@ JSON.stringify(strings.reduce((acc: object, s: { en_string: string }): object =>
735
744
  }
736
745
  }
737
746
 
747
+ applyPluralization(str: string, number: number, lang: string): string {
748
+ const choices = str.split('|');
749
+ const choicesLength = choices.length;
750
+
751
+ if (choicesLength > 2) {
752
+ // this is slavic pluralization
753
+ return choices[this.slavicPluralRule(number, choicesLength)];
754
+ } else {
755
+ return number === 1 ? choices[0] : choices[1];
756
+ }
757
+ }
758
+
759
+ // taken from here https://vue-i18n.intlify.dev/guide/essentials/pluralization.html#custom-pluralization
760
+ slavicPluralRule(choice, choicesLength) {
761
+ if (choice === 0) {
762
+ return 0
763
+ }
764
+
765
+ const teen = choice > 10 && choice < 20
766
+ const endsWithOne = choice % 10 === 1
767
+
768
+ if (!teen && endsWithOne) {
769
+ return 1
770
+ }
771
+ if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
772
+ return 2
773
+ }
774
+
775
+ return choicesLength < 4 ? 2 : 3
776
+ }
738
777
  instanceUniqueRepresentation(pluginOptions: any) : string {
739
778
  // optional method to return unique string representation of plugin instance.
740
779
  // Needed if plugin can have multiple instances on one resource
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/i18n",
3
- "version": "1.0.23-next.0",
3
+ "version": "1.0.23-next.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",