@hua-labs/i18n-core 2.1.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.mjs CHANGED
@@ -1,3 +1,3 @@
1
- export { Translator, serverTranslate, ssrTranslate } from './chunk-EZL5TNH5.mjs';
1
+ export { Translator, serverTranslate, ssrTranslate } from './chunk-4IYWT7MS.mjs';
2
2
  //# sourceMappingURL=server.mjs.map
3
3
  //# sourceMappingURL=server.mjs.map
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@hua-labs/i18n-core",
3
- "version": "2.1.0",
3
+ "version": "2.2.1",
4
4
  "description": "HUA Labs - Core i18n functionality with SSR/CSR support and state management integration",
5
- "main": "./dist/index.mjs",
5
+ "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
7
7
  "types": "./dist/index.d.ts",
8
8
  "files": [
@@ -11,13 +11,16 @@
11
11
  ],
12
12
  "exports": {
13
13
  ".": {
14
+ "react-native": "./dist/index.mjs",
14
15
  "types": "./dist/index.d.ts",
15
16
  "import": "./dist/index.mjs",
17
+ "require": "./dist/index.cjs",
16
18
  "default": "./dist/index.mjs"
17
19
  },
18
20
  "./server": {
19
21
  "types": "./dist/server.d.ts",
20
22
  "import": "./dist/server.mjs",
23
+ "require": "./dist/server.cjs",
21
24
  "default": "./dist/server.mjs"
22
25
  }
23
26
  },
@@ -28,16 +31,16 @@
28
31
  "devDependencies": {
29
32
  "@testing-library/jest-dom": "^6.6.3",
30
33
  "@testing-library/react": "^16.3.0",
31
- "@types/node": "^25.3.0",
32
- "@types/react": "^19.2.14",
33
- "@vitejs/plugin-react": "^5.1.4",
34
- "eslint": "^10.0.1",
35
- "jsdom": "^28.1.0",
36
- "react": "^19.2.4",
37
- "react-dom": "^19.2.4",
34
+ "@types/node": "^25.9.3",
35
+ "@types/react": "^19.2.17",
36
+ "@vitejs/plugin-react": "^5.2.0",
37
+ "eslint": "^10.5.0",
38
+ "jsdom": "^29.1.1",
39
+ "react": "^19.2.7",
40
+ "react-dom": "^19.2.7",
38
41
  "tsup": "^8.5.1",
39
42
  "typescript": "^5.9.3",
40
- "vitest": "^4.0.18"
43
+ "vitest": "^4.1.8"
41
44
  },
42
45
  "peerDependencies": {
43
46
  "react": ">=19.0.0"
@@ -59,12 +62,12 @@
59
62
  "license": "MIT",
60
63
  "repository": {
61
64
  "type": "git",
62
- "url": "https://github.com/HUA-Labs/HUA-Labs-public.git"
65
+ "url": "https://github.com/HUA-Labs/hua-packages.git"
63
66
  },
64
67
  "bugs": {
65
- "url": "https://github.com/HUA-Labs/HUA-Labs-public/issues"
68
+ "url": "https://github.com/HUA-Labs/hua-packages/issues"
66
69
  },
67
- "homepage": "https://github.com/HUA-Labs/HUA-Labs-public#readme",
70
+ "homepage": "https://github.com/HUA-Labs/hua-packages#readme",
68
71
  "publishConfig": {
69
72
  "access": "public",
70
73
  "provenance": true
@@ -0,0 +1,149 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { Translator } from "../core/translator";
3
+ import { I18nConfig } from "../types";
4
+
5
+ function createConfig(overrides?: Partial<I18nConfig>): I18nConfig {
6
+ return {
7
+ defaultLanguage: "ko",
8
+ fallbackLanguage: "en",
9
+ supportedLanguages: [
10
+ { code: "ko", name: "Korean", nativeName: "한국어" },
11
+ { code: "en", name: "English", nativeName: "English" },
12
+ ],
13
+ namespaces: ["common"],
14
+ loadTranslations: vi
15
+ .fn()
16
+ .mockImplementation(async (lang: string, ns: string) => {
17
+ if (lang === "ko" && ns === "common") {
18
+ return { greeting: "안녕하세요", welcome: "{name}님 환영합니다" };
19
+ }
20
+ if (lang === "en" && ns === "common") {
21
+ return { greeting: "Hello", welcome: "Welcome {name}" };
22
+ }
23
+ return {};
24
+ }),
25
+ ...overrides,
26
+ };
27
+ }
28
+
29
+ describe("defaultValue support", () => {
30
+ let translator: Translator;
31
+
32
+ beforeEach(() => {
33
+ vi.useFakeTimers();
34
+ });
35
+
36
+ afterEach(() => {
37
+ vi.useRealTimers();
38
+ });
39
+
40
+ describe("Translator.translate()", () => {
41
+ beforeEach(async () => {
42
+ translator = new Translator(createConfig());
43
+ await translator.initialize();
44
+ vi.advanceTimersByTime(100);
45
+ });
46
+
47
+ it("returns translation when key exists (ignores defaultValue)", () => {
48
+ const result = translator.translate("common:greeting", {
49
+ defaultValue: "Fallback",
50
+ });
51
+ expect(result).toBe("안녕하세요");
52
+ });
53
+
54
+ it("returns defaultValue when key is missing", () => {
55
+ const result = translator.translate("common:nonexistent", {
56
+ defaultValue: "Fallback text",
57
+ });
58
+ expect(result).toBe("Fallback text");
59
+ });
60
+
61
+ it("interpolates variables in defaultValue", () => {
62
+ const result = translator.translate("common:missing", {
63
+ defaultValue: "Hello {{name}}",
64
+ name: "World",
65
+ });
66
+ expect(result).toBe("Hello World");
67
+ });
68
+
69
+ it("returns empty string when key is missing and no defaultValue (production)", () => {
70
+ const result = translator.translate("common:nonexistent");
71
+ expect(result).toBe("");
72
+ });
73
+
74
+ it("returns defaultValue before initialization", () => {
75
+ const fresh = new Translator(createConfig());
76
+ // Not initialized — should still return defaultValue
77
+ const result = fresh.translate("common:missing", {
78
+ defaultValue: "Hello {{name}}",
79
+ name: "World",
80
+ });
81
+ expect(result).toBe("Hello World");
82
+ });
83
+
84
+ it("returns key when missing and debug mode (no defaultValue)", () => {
85
+ const debugTranslator = new Translator(createConfig({ debug: true }));
86
+ // Use initialTranslations to bypass async init
87
+ const config = createConfig({
88
+ debug: true,
89
+ initialTranslations: { ko: { common: {} }, en: { common: {} } },
90
+ });
91
+ const t = new Translator(config);
92
+ const result = t.translate("common:nonexistent");
93
+ expect(result).toBe("common:nonexistent");
94
+ });
95
+ });
96
+
97
+ describe("Translator.translateAsync()", () => {
98
+ beforeEach(async () => {
99
+ translator = new Translator(createConfig());
100
+ await translator.initialize();
101
+ vi.advanceTimersByTime(100);
102
+ });
103
+
104
+ it("returns defaultValue when key is missing", async () => {
105
+ const result = await translator.translateAsync("common:missing", {
106
+ defaultValue: "Async fallback",
107
+ });
108
+ expect(result).toBe("Async fallback");
109
+ });
110
+
111
+ it("returns translation when key exists", async () => {
112
+ const result = await translator.translateAsync("common:greeting", {
113
+ defaultValue: "Fallback",
114
+ });
115
+ expect(result).toBe("안녕하세요");
116
+ });
117
+ });
118
+
119
+ describe("Translator.translateSync()", () => {
120
+ beforeEach(async () => {
121
+ translator = new Translator(createConfig());
122
+ await translator.initialize();
123
+ vi.advanceTimersByTime(100);
124
+ });
125
+
126
+ it("returns defaultValue when key is missing", () => {
127
+ const result = translator.translateSync("common:missing", {
128
+ defaultValue: "Sync fallback",
129
+ });
130
+ expect(result).toBe("Sync fallback");
131
+ });
132
+
133
+ it("returns translation when key exists", () => {
134
+ const result = translator.translateSync("common:greeting", {
135
+ defaultValue: "Fallback",
136
+ });
137
+ expect(result).toBe("안녕하세요");
138
+ });
139
+
140
+ it("returns defaultValue even before initialization", () => {
141
+ const fresh = new Translator(createConfig());
142
+ // Not initialized — should still return defaultValue
143
+ const result = fresh.translateSync("common:missing", {
144
+ defaultValue: "Before init",
145
+ });
146
+ expect(result).toBe("Before init");
147
+ });
148
+ });
149
+ });
@@ -189,10 +189,12 @@ export const reportMissingKey = (key: string, options: {
189
189
  component: options.component
190
190
  };
191
191
 
192
- // 커스텀 이벤트 발생
193
- window.dispatchEvent(new CustomEvent('i18n:missing-key', {
194
- detail: missingKey
195
- }));
192
+ // 커스텀 이벤트 발생 (브라우저 환경에서만)
193
+ if (typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') {
194
+ window.dispatchEvent(new CustomEvent('i18n:missing-key', {
195
+ detail: missingKey
196
+ }));
197
+ }
196
198
 
197
199
  // 콘솔에도 로그
198
200
  if (process.env.NODE_ENV === 'development') console.warn(`Missing translation key: ${key}`, {