@hua-labs/i18n-core 2.2.0 → 2.2.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/dist/server.cjs CHANGED
@@ -1,9 +1,17 @@
1
1
  'use strict';
2
2
 
3
3
  // src/types/index.ts
4
- var PLURAL_CATEGORIES = /* @__PURE__ */ new Set(["zero", "one", "two", "few", "many", "other"]);
4
+ var PLURAL_CATEGORIES = /* @__PURE__ */ new Set([
5
+ "zero",
6
+ "one",
7
+ "two",
8
+ "few",
9
+ "many",
10
+ "other"
11
+ ]);
5
12
  function isPluralValue(value) {
6
- if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
13
+ if (typeof value !== "object" || value === null || Array.isArray(value))
14
+ return false;
7
15
  const obj = value;
8
16
  const keys = Object.keys(obj);
9
17
  return keys.length > 0 && keys.every((k) => PLURAL_CATEGORIES.has(k)) && Object.values(obj).every((v) => typeof v === "string") && typeof obj.other === "string";
@@ -68,7 +76,9 @@ var Translator = class {
68
76
  this.currentLang = config.defaultLanguage;
69
77
  if (config.initialTranslations) {
70
78
  this.allTranslations = config.initialTranslations;
71
- for (const [language, namespaces] of Object.entries(config.initialTranslations)) {
79
+ for (const [language, namespaces] of Object.entries(
80
+ config.initialTranslations
81
+ )) {
72
82
  for (const namespace of Object.keys(namespaces)) {
73
83
  this.loadedNamespaces.add(`${language}:${namespace}`);
74
84
  }
@@ -166,9 +176,15 @@ var Translator = class {
166
176
  }
167
177
  }
168
178
  if (this.config.debug) {
169
- console.log("\u{1F30D} [TRANSLATOR] Initializing translator with languages:", languages);
179
+ console.log(
180
+ "\u{1F30D} [TRANSLATOR] Initializing translator with languages:",
181
+ languages
182
+ );
170
183
  console.log("\u{1F4CD} [TRANSLATOR] Current language:", this.currentLang);
171
- console.log("\u{1F4E6} [TRANSLATOR] Config namespaces:", this.config.namespaces);
184
+ console.log(
185
+ "\u{1F4E6} [TRANSLATOR] Config namespaces:",
186
+ this.config.namespaces
187
+ );
172
188
  }
173
189
  for (const language of languages) {
174
190
  if (this.config.debug) {
@@ -181,12 +197,23 @@ var Translator = class {
181
197
  const cacheKey = `${language}:${namespace}`;
182
198
  if (skipNamespaces.has(cacheKey)) {
183
199
  if (this.config.debug) {
184
- console.log("\u23ED\uFE0F [TRANSLATOR] Skipping", namespace, "for", language, "(already loaded from SSR)");
200
+ console.log(
201
+ "\u23ED\uFE0F [TRANSLATOR] Skipping",
202
+ namespace,
203
+ "for",
204
+ language,
205
+ "(already loaded from SSR)"
206
+ );
185
207
  }
186
208
  continue;
187
209
  }
188
210
  if (this.config.debug) {
189
- console.log("Loading namespace:", namespace, "for language:", language);
211
+ console.log(
212
+ "Loading namespace:",
213
+ namespace,
214
+ "for language:",
215
+ language
216
+ );
190
217
  }
191
218
  try {
192
219
  const data = await this.safeLoadTranslations(language, namespace);
@@ -206,7 +233,10 @@ var Translator = class {
206
233
  if (isRecoverableError(translationError)) {
207
234
  if (language !== this.config.fallbackLanguage) {
208
235
  try {
209
- const fallbackData = await this.safeLoadTranslations(this.config.fallbackLanguage || "en", namespace);
236
+ const fallbackData = await this.safeLoadTranslations(
237
+ this.config.fallbackLanguage || "en",
238
+ namespace
239
+ );
210
240
  this.allTranslations[language][namespace] = fallbackData;
211
241
  this.loadedNamespaces.add(`${language}:${namespace}`);
212
242
  if (this.config.debug) {
@@ -244,7 +274,9 @@ var Translator = class {
244
274
  this.logError(this.initializationError);
245
275
  this.isInitialized = true;
246
276
  if (this.config.debug) {
247
- console.warn("Translator initialized with errors, using fallback translations");
277
+ console.warn(
278
+ "Translator initialized with errors, using fallback translations"
279
+ );
248
280
  }
249
281
  }
250
282
  }
@@ -259,7 +291,10 @@ var Translator = class {
259
291
  const result = this.findInNamespace(namespace, actualKey, targetLang);
260
292
  if (result) {
261
293
  if (this.config.debug) {
262
- console.log(`\u2705 [TRANSLATOR] Found fallback translation from initialTranslations:`, result);
294
+ console.log(
295
+ `\u2705 [TRANSLATOR] Found fallback translation from initialTranslations:`,
296
+ result
297
+ );
263
298
  }
264
299
  return result;
265
300
  }
@@ -323,10 +358,17 @@ var Translator = class {
323
358
  }
324
359
  if (!this.isInitialized) {
325
360
  const raw = this.translateBeforeInitialized(key, targetLang);
361
+ if ((!raw || raw === key) && params && typeof params === "object" && "defaultValue" in params && typeof params.defaultValue === "string") {
362
+ return this.interpolate(params.defaultValue, params);
363
+ }
326
364
  return params ? this.interpolate(raw, params) : raw;
327
365
  }
328
366
  const { namespace, key: actualKey } = this.parseKey(key);
329
- let result = this.findInNamespace(namespace, actualKey, targetLang);
367
+ let result = this.findInNamespace(
368
+ namespace,
369
+ actualKey,
370
+ targetLang
371
+ );
330
372
  if (result) {
331
373
  this.cacheStats.hits++;
332
374
  return params ? this.interpolate(result, params) : result;
@@ -340,6 +382,9 @@ var Translator = class {
340
382
  return params ? this.interpolate(result, params) : result;
341
383
  }
342
384
  this.cacheStats.misses++;
385
+ if (params && typeof params === "object" && "defaultValue" in params && typeof params.defaultValue === "string") {
386
+ return this.interpolate(params.defaultValue, params);
387
+ }
343
388
  if (this.config.debug) {
344
389
  const missing = this.config.missingKeyHandler?.(key, targetLang, namespace) || key;
345
390
  return params ? this.interpolate(missing, params) : missing;
@@ -356,11 +401,16 @@ var Translator = class {
356
401
  if (!this.loadedNamespaces.has(cacheKey) && !this.loadingPromises.has(cacheKey)) {
357
402
  this.loadTranslationData(language, namespace).catch((error) => {
358
403
  if (this.config.debug) {
359
- console.warn(`\u26A0\uFE0F [TRANSLATOR] Auto-load failed for ${language}/${namespace}:`, error);
404
+ console.warn(
405
+ `\u26A0\uFE0F [TRANSLATOR] Auto-load failed for ${language}/${namespace}:`,
406
+ error
407
+ );
360
408
  }
361
409
  });
362
410
  if (this.config.debug) {
363
- console.warn(`\u274C [TRANSLATOR] No translations found for ${language}/${namespace}, attempting auto-load...`);
411
+ console.warn(
412
+ `\u274C [TRANSLATOR] No translations found for ${language}/${namespace}, attempting auto-load...`
413
+ );
364
414
  }
365
415
  }
366
416
  return "";
@@ -380,7 +430,9 @@ var Translator = class {
380
430
  return nestedValue[Math.floor(Math.random() * nestedValue.length)];
381
431
  }
382
432
  if (this.config.debug) {
383
- console.warn(`\u274C [TRANSLATOR] No match found for key: ${key} in ${language}/${namespace}`);
433
+ console.warn(
434
+ `\u274C [TRANSLATOR] No match found for key: ${key} in ${language}/${namespace}`
435
+ );
384
436
  }
385
437
  return "";
386
438
  }
@@ -446,7 +498,10 @@ var Translator = class {
446
498
  if (actualKey in fallbackTranslations) {
447
499
  return fallbackTranslations[actualKey];
448
500
  }
449
- const fallbackNestedValue = this.getNestedValue(fallbackTranslations, actualKey);
501
+ const fallbackNestedValue = this.getNestedValue(
502
+ fallbackTranslations,
503
+ actualKey
504
+ );
450
505
  if (fallbackNestedValue !== void 0) {
451
506
  return fallbackNestedValue;
452
507
  }
@@ -492,7 +547,9 @@ var Translator = class {
492
547
  const raw = this.getRawValue(key, targetLang);
493
548
  const mergedParams = { count, ...params };
494
549
  if (isPluralValue(raw)) {
495
- const category = this.getPluralRules(targetLang).select(count);
550
+ const category = this.getPluralRules(targetLang).select(
551
+ count
552
+ );
496
553
  const text = raw[category] ?? raw.other;
497
554
  return this.interpolate(text, mergedParams);
498
555
  }
@@ -535,7 +592,9 @@ var Translator = class {
535
592
  });
536
593
  }
537
594
  if (this.config.debug) {
538
- console.log(`\u{1F310} [TRANSLATOR] Language changed: ${previousLanguage} -> ${language}`);
595
+ console.log(
596
+ `\u{1F310} [TRANSLATOR] Language changed: ${previousLanguage} -> ${language}`
597
+ );
539
598
  }
540
599
  }
541
600
  /**
@@ -647,7 +706,11 @@ var Translator = class {
647
706
  */
648
707
  logError(error) {
649
708
  if (this.config.errorHandler) {
650
- this.config.errorHandler(error, error.language || "", error.namespace || "");
709
+ this.config.errorHandler(
710
+ error,
711
+ error.language || "",
712
+ error.namespace || ""
713
+ );
651
714
  }
652
715
  }
653
716
  /**
@@ -670,7 +733,9 @@ var Translator = class {
670
733
  if (attempt === maxRetries) {
671
734
  break;
672
735
  }
673
- await new Promise((resolve) => setTimeout(resolve, Math.pow(2, attempt) * 1e3));
736
+ await new Promise(
737
+ (resolve) => setTimeout(resolve, Math.pow(2, attempt) * 1e3)
738
+ );
674
739
  }
675
740
  }
676
741
  throw lastError;
@@ -680,21 +745,29 @@ var Translator = class {
680
745
  */
681
746
  async safeLoadTranslations(language, namespace) {
682
747
  if (this.config.debug) {
683
- console.log(`\u{1F4E5} [TRANSLATOR] safeLoadTranslations called:`, { language, namespace });
748
+ console.log(`\u{1F4E5} [TRANSLATOR] safeLoadTranslations called:`, {
749
+ language,
750
+ namespace
751
+ });
684
752
  }
685
753
  const loadOperation = async () => {
686
754
  if (!this.config.loadTranslations) {
687
755
  throw new Error("No translation loader configured");
688
756
  }
689
757
  if (this.config.debug) {
690
- console.log(`\u{1F504} [TRANSLATOR] Calling loadTranslations for:`, { language, namespace });
758
+ console.log(`\u{1F504} [TRANSLATOR] Calling loadTranslations for:`, {
759
+ language,
760
+ namespace
761
+ });
691
762
  }
692
763
  const data = await this.config.loadTranslations(language, namespace);
693
764
  if (this.config.debug) {
694
765
  console.log(`\u{1F4E6} [TRANSLATOR] loadTranslations returned:`, data);
695
766
  }
696
767
  if (!isTranslationNamespace(data)) {
697
- throw new Error(`Invalid translation data for ${language}:${namespace}`);
768
+ throw new Error(
769
+ `Invalid translation data for ${language}:${namespace}`
770
+ );
698
771
  }
699
772
  return data;
700
773
  };
@@ -707,7 +780,10 @@ var Translator = class {
707
780
  language,
708
781
  namespace
709
782
  );
710
- return this.retryOperation(loadOperation, translationError, { language, namespace });
783
+ return this.retryOperation(loadOperation, translationError, {
784
+ language,
785
+ namespace
786
+ });
711
787
  }
712
788
  }
713
789
  /**
@@ -744,35 +820,30 @@ var Translator = class {
744
820
  if (!this.isInitialized) {
745
821
  await this.initialize();
746
822
  }
747
- const translated = this.translate(key);
748
- if (!params) {
749
- return translated;
750
- }
751
- return this.interpolate(translated, params);
823
+ return this.translate(key, params);
752
824
  }
753
825
  /**
754
826
  * 동기 번역 (고급 기능)
755
827
  */
756
828
  translateSync(key, params) {
757
829
  if (!this.isInitialized) {
830
+ if (params && typeof params === "object" && "defaultValue" in params && typeof params.defaultValue === "string") {
831
+ return this.interpolate(params.defaultValue, params);
832
+ }
758
833
  if (this.config.debug) {
759
834
  console.warn("Translator not initialized for sync translation");
760
835
  }
761
836
  const { namespace } = this.parseKey(key);
762
837
  return this.config.missingKeyHandler?.(key, this.currentLang, namespace) || key;
763
838
  }
764
- const translated = this.translate(key);
765
- if (!params) {
766
- return translated;
767
- }
768
- return this.interpolate(translated, params);
839
+ return this.translate(key, params);
769
840
  }
770
841
  /**
771
842
  * 키 파싱 (네임스페이스:키 형식)
772
- *
843
+ *
773
844
  * - 콜론(:)만 네임스페이스 구분자로 사용
774
845
  * - 점(.)은 키 이름의 일부로 취급 (중첩 객체 접근용)
775
- *
846
+ *
776
847
  * @example
777
848
  * parseKey("home:hero.badge") → { namespace: "home", key: "hero.badge" }
778
849
  * parseKey("hero.badge") → { namespace: "common", key: "hero.badge" }
@@ -781,7 +852,10 @@ var Translator = class {
781
852
  parseKey(key) {
782
853
  const colonIndex = key.indexOf(":");
783
854
  if (colonIndex !== -1) {
784
- return { namespace: key.substring(0, colonIndex), key: key.substring(colonIndex + 1) };
855
+ return {
856
+ namespace: key.substring(0, colonIndex),
857
+ key: key.substring(colonIndex + 1)
858
+ };
785
859
  }
786
860
  return { namespace: "common", key };
787
861
  }
@@ -820,7 +894,9 @@ var Translator = class {
820
894
  this.loadedNamespaces.add(cacheKey);
821
895
  this.setCacheEntry(cacheKey, data);
822
896
  if (this.config.debug) {
823
- console.log(`\u2705 [TRANSLATOR] Auto-loaded and saved ${language}/${namespace}`);
897
+ console.log(
898
+ `\u2705 [TRANSLATOR] Auto-loaded and saved ${language}/${namespace}`
899
+ );
824
900
  }
825
901
  this.notifyTranslationLoaded(language, namespace);
826
902
  return data;
@@ -838,7 +914,9 @@ var Translator = class {
838
914
  try {
839
915
  const data = await this.config.loadTranslations(language, namespace);
840
916
  if (!isTranslationNamespace(data)) {
841
- throw new Error(`Invalid translation data for ${language}:${namespace}`);
917
+ throw new Error(
918
+ `Invalid translation data for ${language}:${namespace}`
919
+ );
842
920
  }
843
921
  return data;
844
922
  } catch (error) {
@@ -861,12 +939,20 @@ function ssrTranslate({
861
939
  missingKeyHandler = (key2) => key2
862
940
  }) {
863
941
  const { namespace, key: actualKey } = parseKey(key);
864
- let result = ssrFindInNamespace(translations, namespace, actualKey, language);
942
+ let result = ssrFindInNamespace(
943
+ translations,
944
+ namespace,
945
+ actualKey,
946
+ language);
865
947
  if (result) {
866
948
  return result;
867
949
  }
868
950
  if (language !== fallbackLanguage) {
869
- result = ssrFindInNamespace(translations, namespace, actualKey, fallbackLanguage);
951
+ result = ssrFindInNamespace(
952
+ translations,
953
+ namespace,
954
+ actualKey,
955
+ fallbackLanguage);
870
956
  if (result) {
871
957
  return result;
872
958
  }
@@ -905,7 +991,10 @@ function isStringValue(value) {
905
991
  function parseKey(key) {
906
992
  const colonIndex = key.indexOf(":");
907
993
  if (colonIndex !== -1) {
908
- return { namespace: key.substring(0, colonIndex), key: key.substring(colonIndex + 1) };
994
+ return {
995
+ namespace: key.substring(0, colonIndex),
996
+ key: key.substring(colonIndex + 1)
997
+ };
909
998
  }
910
999
  return { namespace: "common", key };
911
1000
  }
@@ -927,7 +1016,11 @@ function serverTranslate({
927
1016
  return cached;
928
1017
  }
929
1018
  }
930
- const result = findInTranslations(translations, key, language, fallbackLanguage);
1019
+ const result = findInTranslations(
1020
+ translations,
1021
+ key,
1022
+ language,
1023
+ fallbackLanguage);
931
1024
  if (cache && result) {
932
1025
  const cacheKey = `${language}:${key}`;
933
1026
  cache.set(cacheKey, result);
@@ -943,7 +1036,12 @@ function findInTranslations(translations, key, language, fallbackLanguage, missi
943
1036
  return result;
944
1037
  }
945
1038
  if (language !== fallbackLanguage) {
946
- result = findInNamespace(translations, namespace, actualKey, fallbackLanguage);
1039
+ result = findInNamespace(
1040
+ translations,
1041
+ namespace,
1042
+ actualKey,
1043
+ fallbackLanguage
1044
+ );
947
1045
  if (result) {
948
1046
  return result;
949
1047
  }