@omegagrid/localize 0.6.83 → 0.6.85

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.
@@ -1,4 +1,5 @@
1
1
  export type LocaleId = string;
2
+ export type MsgData = Record<string, string | number>;
2
3
  export type MsgOptions = {
3
4
  /** Unique message id */
4
5
  id?: string;
@@ -6,11 +7,14 @@ export type MsgOptions = {
6
7
  desc?: string;
7
8
  /** word separator */
8
9
  separator?: string;
10
+ /** replacable message data */
11
+ data?: MsgData;
9
12
  };
10
13
  export type LocalizeItem = {
11
14
  id: string;
12
15
  source: string;
13
16
  target: string;
17
+ translate?: (data: MsgData) => string;
14
18
  };
15
19
  export declare class LocaleChangeEvent extends Event {
16
20
  locale: string;
@@ -21,6 +25,7 @@ export declare function registerLocale(locale: LocaleId | LocaleId[], items: Loc
21
25
  export declare function getLocale(): string;
22
26
  export declare function hasLocale(locale: LocaleId): boolean;
23
27
  export declare function setLocale(locale: LocaleId): void;
28
+ export declare function createTranslateFunction(template: string): (data?: MsgData) => string;
24
29
  /**
25
30
  * Translate a message to the current locale
26
31
  * @param message source message
@@ -1 +1 @@
1
- {"version":3,"file":"localization.d.ts","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,MAAM,MAAM,UAAU,GAAG;IACrB,wBAAwB;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CACf,CAAA;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC3C,MAAM,EAAE,MAAM,CAAC;gBACH,MAAM,EAAE,MAAM;CAI1B;AAED,wBAAgB,eAAe,IAAI,MAAM,CAMxC;AAMD,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,QAEhF;AAED,wBAAgB,SAAS,WAExB;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,QAAQ,WAEzC;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAkBhD;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAC,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,MAAM,CAsB1E"}
1
+ {"version":3,"file":"localization.d.ts","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAC,MAAM,CAAC,CAAC;AAEpD,MAAM,MAAM,UAAU,GAAG;IACrB,wBAAwB;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;CACf,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAA;CACrC,CAAA;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC3C,MAAM,EAAE,MAAM,CAAC;gBACH,MAAM,EAAE,MAAM;CAI1B;AAED,wBAAgB,eAAe,IAAI,MAAM,CAMxC;AAOD,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,QAEhF;AAED,wBAAgB,SAAS,WAExB;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,QAAQ,WAEzC;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAkBhD;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,KAAK,MAAM,CA6BpF;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAC,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,MAAM,CAwC1E"}
@@ -41,6 +41,31 @@ export function setLocale(locale) {
41
41
  document.dispatchEvent(new LocaleChangeEvent(locale));
42
42
  }
43
43
  }
44
+ export function createTranslateFunction(template) {
45
+ const regex = /\{([^}]+)\}/g;
46
+ const matches = Array.from(template.matchAll(regex));
47
+ const placeholders = matches.map(match => ({
48
+ name: match[1],
49
+ start: match.index,
50
+ end: match.index + match[0].length
51
+ }));
52
+ return (data) => {
53
+ if (!data)
54
+ return template;
55
+ let result = '';
56
+ let lastIndex = 0;
57
+ for (const placeholder of placeholders) {
58
+ // Add text before placeholder
59
+ result += template.slice(lastIndex, placeholder.start);
60
+ // Add placeholder value
61
+ const value = data[placeholder.name];
62
+ result += value != null ? String(value) : '';
63
+ lastIndex = placeholder.end;
64
+ }
65
+ // Add remaining text after last placeholder
66
+ return result + template.slice(lastIndex);
67
+ };
68
+ }
44
69
  /**
45
70
  * Translate a message to the current locale
46
71
  * @param message source message
@@ -54,10 +79,27 @@ export function msg(message, options) {
54
79
  if (message == null || message === '')
55
80
  return '';
56
81
  const source = message.toLowerCase();
57
- if (!localeSourceMap || !localeSourceMap.has(currentLocale) || !localeSourceMap.get(currentLocale).has(source)) {
58
- return message;
82
+ let locale = localeSourceMap.get(currentLocale);
83
+ if (!locale) {
84
+ locale = new Map();
85
+ localeSourceMap.set(currentLocale, locale);
59
86
  }
60
- let target = localeSourceMap.get(currentLocale).get(source).target;
87
+ let localeItem = locale.get(source);
88
+ if (!localeItem) {
89
+ localeItem = {
90
+ id: options?.id ?? null,
91
+ source: source,
92
+ target: source
93
+ };
94
+ locale.set(source, localeItem);
95
+ }
96
+ // create translate function if not exists
97
+ if (options?.data && !localeItem.translate) {
98
+ localeItem.translate = createTranslateFunction(localeItem.target);
99
+ }
100
+ if (!localeItem)
101
+ return message;
102
+ let target = localeItem.translate ? localeItem.translate(options?.data) : localeItem.target;
61
103
  if (target == null || target === '')
62
104
  return '';
63
105
  // Capitalize the first letter if the source message first letter is capitalized
@@ -1 +1 @@
1
- {"version":3,"file":"localization.js","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"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","sourcesContent":["export type LocaleId = string;\n\nexport type MsgOptions = {\n /** Unique message id */\n id?: string;\n /** Description of this message */\n desc?: string;\n\t/** word separator */\n\tseparator?: string \n}\n\nexport type LocalizeItem = {\n\tid: string;\n\tsource: string;\n\ttarget: string;\n}\n\nexport class LocaleChangeEvent extends Event {\n\tlocale: string;\n\tconstructor(locale: string) {\n\t\tsuper('localechange');\n\t\tthis.locale = locale;\n\t}\n}\n\nexport function getSystemLocale(): string {\n\treturn typeof navigator !== 'undefined' ? (\n\t\tnavigator.languages && navigator.languages.length\n\t\t\t? navigator.languages[0]\n\t\t\t: navigator.language\n\t) : 'en';\n}\n\nconst locales = new Map<LocaleId, LocalizeItem[]>();\nconst localeSourceMap = new Map<LocaleId, Map<string, LocalizeItem>>();\nlet currentLocale: string = getSystemLocale();\n\nexport function registerLocale(locale: LocaleId|LocaleId[], items: LocalizeItem[]) {\n\t(Array.isArray(locale) ? locale : [locale]).forEach(l => locales.set(l, items));\n}\n\nexport function getLocale() {\n\treturn currentLocale;\n}\n\nexport function hasLocale(locale: LocaleId) {\n\treturn locales.has(locale);\n}\n\nexport function setLocale(locale: LocaleId): void {\n\tif (!locales.has(locale)) {\n\t\tlet newLocale = currentLocale;\n\t\tif (newLocale == null) {\n\t\t\tif (locales.has('en')) newLocale = 'en';\t\n\t\t\telse if (locales.size > 0) newLocale = locales.keys().next().value;\n\t\t}\n\t\t// log.getLogger().warn(`Locale ${locale} is not registered.${newLocale ? ` Switching to ${newLocale}.` : ''}`);\n\t}\n\n\tif (!localeSourceMap.has(locale)) localeSourceMap.set(locale, new Map());\n\tconst map = localeSourceMap.get(locale);\n\tlocales.get(locale)?.forEach(i => map.set(i.source, i));\n\n\tif (currentLocale !== locale) {\n\t\tcurrentLocale = locale;\n\t\tdocument.dispatchEvent(new LocaleChangeEvent(locale));\n\t}\n}\n\n/**\n * Translate a message to the current locale\n * @param message source message\n * @param options translation options\n * @returns \n */\nexport function msg(message: string|string[], options?: MsgOptions): string {\n\tif (Array.isArray(message)) {\n\t\treturn message.map(m => msg(m, options)).join(options?.separator ?? ' ');\n\t}\n\n\tif (message == null || message === '') return '';\n\t\n\tconst source = message.toLowerCase();\n\t\n\tif (!localeSourceMap || !localeSourceMap.has(currentLocale) || !localeSourceMap.get(currentLocale).has(source)) {\n\t\treturn message;\n\t}\n\n\tlet target = localeSourceMap.get(currentLocale).get(source).target;\n\tif (target == null || target === '') return '';\n\n\t// Capitalize the first letter if the source message first letter is capitalized\n\tif (message.length > 0 && message[0] === message[0].toUpperCase()) {\n\t\ttarget = target[0].toUpperCase() + target.slice(1);\n\t}\n\n\treturn target;\n}"]}
1
+ {"version":3,"file":"localization.js","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"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","sourcesContent":["export type LocaleId = string;\n\nexport type MsgData = Record<string, string|number>;\n\nexport type MsgOptions = {\n /** Unique message id */\n id?: string;\n /** Description of this message */\n desc?: string;\n\t/** word separator */\n\tseparator?: string;\n\t/** replacable message data */\n\tdata?: MsgData;\n}\n\nexport type LocalizeItem = {\n\tid: string;\n\tsource: string;\n\ttarget: string;\n\ttranslate?: (data: MsgData) => string\n}\n\nexport class LocaleChangeEvent extends Event {\n\tlocale: string;\n\tconstructor(locale: string) {\n\t\tsuper('localechange');\n\t\tthis.locale = locale;\n\t}\n}\n\nexport function getSystemLocale(): string {\n\treturn typeof navigator !== 'undefined' ? (\n\t\tnavigator.languages && navigator.languages.length\n\t\t\t? navigator.languages[0]\n\t\t\t: navigator.language\n\t) : 'en';\n}\n\nconst locales = new Map<LocaleId, LocalizeItem[]>();\nconst localeSourceMap = new Map<LocaleId, Map<string, LocalizeItem>>();\n\nlet currentLocale: string = getSystemLocale();\n\nexport function registerLocale(locale: LocaleId|LocaleId[], items: LocalizeItem[]) {\n\t(Array.isArray(locale) ? locale : [locale]).forEach(l => locales.set(l, items));\n}\n\nexport function getLocale() {\n\treturn currentLocale;\n}\n\nexport function hasLocale(locale: LocaleId) {\n\treturn locales.has(locale);\n}\n\nexport function setLocale(locale: LocaleId): void {\n\tif (!locales.has(locale)) {\n\t\tlet newLocale = currentLocale;\n\t\tif (newLocale == null) {\n\t\t\tif (locales.has('en')) newLocale = 'en';\t\n\t\t\telse if (locales.size > 0) newLocale = locales.keys().next().value;\n\t\t}\n\t\t// log.getLogger().warn(`Locale ${locale} is not registered.${newLocale ? ` Switching to ${newLocale}.` : ''}`);\n\t}\n\n\tif (!localeSourceMap.has(locale)) localeSourceMap.set(locale, new Map());\n\tconst map = localeSourceMap.get(locale);\n\tlocales.get(locale)?.forEach(i => map.set(i.source, i));\n\n\tif (currentLocale !== locale) {\n\t\tcurrentLocale = locale;\n\t\tdocument.dispatchEvent(new LocaleChangeEvent(locale));\n\t}\n}\n\nexport function createTranslateFunction(template: string): (data?: MsgData) => string {\n\tconst regex = /\\{([^}]+)\\}/g;\n\tconst matches = Array.from(template.matchAll(regex));\n\tconst placeholders = matches.map(match => ({\n\t\tname: match[1],\n\t\tstart: match.index!,\n\t\tend: match.index! + match[0].length\n\t}));\n\n\treturn (data?: MsgData): string => {\n\t\tif (!data) return template;\n\t\t\n\t\tlet result = '';\n\t\tlet lastIndex = 0;\n\t\t\n\t\tfor (const placeholder of placeholders) {\n\t\t\t// Add text before placeholder\n\t\t\tresult += template.slice(lastIndex, placeholder.start);\n\t\t\t\n\t\t\t// Add placeholder value\n\t\t\tconst value = data[placeholder.name];\n\t\t\tresult += value != null ? String(value) : '';\n\t\t\t\n\t\t\tlastIndex = placeholder.end;\n\t\t}\n\t\t\n\t\t// Add remaining text after last placeholder\n\t\treturn result + template.slice(lastIndex);\n\t};\n}\n\n/**\n * Translate a message to the current locale\n * @param message source message\n * @param options translation options\n * @returns \n */\nexport function msg(message: string|string[], options?: MsgOptions): string {\n\tif (Array.isArray(message)) {\n\t\treturn message.map(m => msg(m, options)).join(options?.separator ?? ' ');\n\t}\n\n\tif (message == null || message === '') return '';\n\t\n\tconst source = message.toLowerCase();\n\tlet locale = localeSourceMap.get(currentLocale);\n\tif (!locale) {\n\t\tlocale = new Map<string, LocalizeItem>();\n\t\tlocaleSourceMap.set(currentLocale, locale);\n\t}\n\n\tlet localeItem = locale.get(source);\n\tif (!localeItem) {\n\t\tlocaleItem = {\n\t\t\tid: options?.id ?? null,\n\t\t\tsource: source,\n\t\t\ttarget: source\n\t\t};\n\t\tlocale.set(source, localeItem);\n\t}\n\n\t// create translate function if not exists\t\t\n\tif (options?.data && !localeItem.translate) {\n\t\tlocaleItem.translate = createTranslateFunction(localeItem.target);\n\t}\n\n\tif (!localeItem) return message;\n\n\tlet target = localeItem.translate ? localeItem.translate(options?.data) : localeItem.target;\n\tif (target == null || target === '') return '';\n\n\t// Capitalize the first letter if the source message first letter is capitalized\n\tif (message.length > 0 && message[0] === message[0].toUpperCase()) {\n\t\ttarget = target[0].toUpperCase() + target.slice(1);\n\t}\n\n\treturn target;\n}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omegagrid/localize",
3
- "version": "0.6.83",
3
+ "version": "0.6.85",
4
4
  "license": "UNLICENSED",
5
5
  "description": "Localization",
6
6
  "main": "./dist/index.js",