@dialpad/i18n 1.22.3 → 1.24.0

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.
Files changed (46) hide show
  1. package/bin/force-pull-translations.js +2 -0
  2. package/bin/pull-translations.js +2 -0
  3. package/bin/should-pull.js +2 -0
  4. package/bin/translate-dialpadistan.js +2 -0
  5. package/bin/translation-screenshots-check.js +2 -0
  6. package/bin/upload-translation-service.js +2 -0
  7. package/dist/i18n.cjs +883 -878
  8. package/dist/i18n.cjs.map +1 -1
  9. package/dist/i18n.js +883 -878
  10. package/dist/i18n.js.map +1 -1
  11. package/dist/types/index.d.ts +2 -4
  12. package/dist/types/index.js +1 -2
  13. package/{README.md → docs/README.md} +280 -84
  14. package/index.ts +18 -5
  15. package/package.json +50 -26
  16. package/.eslintignore +0 -1
  17. package/.eslintrc.cjs +0 -12
  18. package/.prettierignore +0 -3
  19. package/.rush/temp/chunked-rush-logs/i18n.build.chunks.jsonl +0 -22
  20. package/.rush/temp/chunked-rush-logs/i18n.format.chunks.jsonl +0 -19
  21. package/.rush/temp/chunked-rush-logs/i18n.lint.chunks.jsonl +0 -2
  22. package/.rush/temp/package-deps_build.json +0 -24
  23. package/.rush/temp/package-deps_format.json +0 -24
  24. package/.rush/temp/package-deps_lint.json +0 -24
  25. package/.rush/temp/shrinkwrap-deps.json +0 -12
  26. package/CHANGELOG.json +0 -63
  27. package/CHANGELOG.md +0 -30
  28. package/base-tsconfig.json +0 -19
  29. package/dialpad-i18n-1.22.2.tgz +0 -0
  30. package/dist/types/src/locale-manager.d.ts +0 -53
  31. package/dist/types/src/locale-manager.js +0 -146
  32. package/eslint-tsconfig.json +0 -5
  33. package/index.html +0 -11
  34. package/rush-logs/i18n.build.error.log +0 -0
  35. package/rush-logs/i18n.build.log +0 -22
  36. package/rush-logs/i18n.format.error.log +0 -0
  37. package/rush-logs/i18n.format.log +0 -19
  38. package/rush-logs/i18n.lint.error.log +0 -0
  39. package/rush-logs/i18n.lint.log +0 -2
  40. package/src/__test__/locale-manager.find.test.ts +0 -78
  41. package/src/__test__/locale-manager.formatters.test.ts +0 -139
  42. package/src/__test__/locale-manager.multiple.test.ts +0 -349
  43. package/src/__test__/locale-manager.test.ts +0 -511
  44. package/src/locale-manager.ts +0 -198
  45. package/tsconfig.json +0 -10
  46. package/vite.config.ts +0 -39
@@ -1,139 +0,0 @@
1
- import { LocaleManager } from '../locale-manager';
2
- import { RawBundleSource } from '@dialpad/i18n-services/bundle-source';
3
- import { describe, it, expect } from 'vitest';
4
-
5
- function mockVueApp(): any {
6
- return { use: () => {}, provide: () => {}, component: () => {} };
7
- }
8
-
9
- describe('Fluent Formatters', () => {
10
- it('formats a message successfully', async () => {
11
- const bundleSource = new RawBundleSource({
12
- resources: await RawBundleSource.dynamicResources([
13
- ['en-US', 'x', 'existing-key = Hello, world!'],
14
- ]),
15
- });
16
-
17
- const manager = new LocaleManager({
18
- bundleSource,
19
- preferredLocale: 'en-US',
20
- warmUp: true,
21
- fallbackLocale: 'en-US',
22
- namespaces: ['x'],
23
- });
24
-
25
- await manager.change({ namespaces: ['x'] });
26
-
27
- const app = mockVueApp();
28
- manager.install(app);
29
- await manager.ready;
30
-
31
- expect(manager.fluentFormat('existing-key')).toEqual('Hello, world!');
32
- });
33
-
34
- it('returns the key instead of missing if not found **for both this locale and the fallback locale', async () => {
35
- const bundleSource = new RawBundleSource({
36
- resources: await RawBundleSource.dynamicResources([
37
- ['en-US', 'x', 'existing-key = Hello, world!'],
38
- ]),
39
- });
40
-
41
- const manager = new LocaleManager({
42
- bundleSource,
43
- preferredLocale: 'en-US',
44
- warmUp: true,
45
- fallbackLocale: 'en-US',
46
- namespaces: ['x'],
47
- });
48
-
49
- await manager.change({ namespaces: ['x'] });
50
-
51
- const app = mockVueApp();
52
- manager.install(app);
53
- await manager.ready;
54
-
55
- expect(manager.fluentFormat('missing-key')).toEqual('missing-key');
56
- });
57
-
58
- it('uses fallbackBundle when key is not found', async () => {
59
- const bundleSource = new RawBundleSource({
60
- resources: await RawBundleSource.dynamicResources([
61
- ['es-ES', 'x', 'existing-key = Hola, mundo!'],
62
- [
63
- 'en-US',
64
- 'x',
65
- 'existing-key = Hello, world!\nfallback-key = Fallback message',
66
- ],
67
- ]),
68
- });
69
-
70
- const manager = new LocaleManager({
71
- bundleSource,
72
- preferredLocale: 'es-ES',
73
- warmUp: true,
74
- fallbackLocale: 'en-US',
75
- namespaces: ['x'],
76
- });
77
-
78
- await manager.change({ namespaces: ['x'] });
79
-
80
- const app = mockVueApp();
81
- manager.install(app);
82
- await manager.ready;
83
-
84
- expect(manager.fluentFormat('fallback-key')).toEqual('Fallback message');
85
- });
86
-
87
- it('formats attributes correctly', async () => {
88
- const bundleSource = new RawBundleSource({
89
- resources: await RawBundleSource.dynamicResources([
90
- [
91
- 'en-US',
92
- 'x',
93
- 'existing-key = stuff\n.attr1 = Value 1\n.attr2 = Value 2',
94
- ],
95
- ]),
96
- });
97
-
98
- const manager = new LocaleManager({
99
- bundleSource,
100
- preferredLocale: 'en-US',
101
- warmUp: true,
102
- fallbackLocale: 'en-US',
103
- namespaces: ['x'],
104
- });
105
-
106
- await manager.change({ namespaces: ['x'] });
107
-
108
- const app = mockVueApp();
109
- manager.install(app);
110
- await manager.ready;
111
-
112
- const attributes = manager.fluentFormatAttrs('existing-key');
113
- expect(attributes).toEqual({ attr1: 'Value 1', attr2: 'Value 2' });
114
- });
115
-
116
- it('returns an empty object when attributes are not found', async () => {
117
- const bundleSource = new RawBundleSource({
118
- resources: await RawBundleSource.dynamicResources([
119
- ['en-US', 'x', 'no-attributes = stuff'],
120
- ]),
121
- });
122
-
123
- const manager = new LocaleManager({
124
- bundleSource,
125
- preferredLocale: 'en-US',
126
- warmUp: true,
127
- fallbackLocale: 'en-US',
128
- namespaces: ['x'],
129
- });
130
-
131
- await manager.change({ namespaces: ['x'] });
132
-
133
- const app = mockVueApp();
134
- manager.install(app);
135
- await manager.ready;
136
-
137
- expect(manager.fluentFormatAttrs('no-attributes')).toEqual({});
138
- });
139
- });
@@ -1,349 +0,0 @@
1
- import { RawBundleSource } from '@dialpad/i18n-services/bundle-source';
2
- import type { LocaleManagerParams } from '@dialpad/i18n-services/locale-manager';
3
- import { MemoryStorageWrapper } from '@dialpad/i18n-services/storage';
4
-
5
- import { expect, describe, it, beforeEach, vi } from 'vitest';
6
- import { INJECTION_KEY_PREFIX, LocaleManager } from '../locale-manager';
7
- import type { App } from 'vue';
8
-
9
- const EN_US = 'en-US';
10
- const ES_LA = 'es-LA';
11
-
12
- function createTestBundleSources() {
13
- const PowerdialerBundle = new RawBundleSource({
14
- resources: [
15
- [
16
- EN_US,
17
- 'app-core',
18
- `PAGE_TITLE_CAMPAIGNS = Campaigns
19
- LEAD_PHONE_NUM_LABEL = Phone Number
20
- CREATE_LEAD_BUTTON = Create Lead`,
21
- ],
22
- [
23
- ES_LA,
24
- 'app-core',
25
- `PAGE_TITLE_CAMPAIGNS = Campañas
26
- LEAD_PHONE_NUM_LABEL = Número de Teléfono
27
- CREATE_LEAD_BUTTON = Crear Cliente Potencial`,
28
- ],
29
- ],
30
- });
31
-
32
- // Admin bundle source
33
- const adminBundle = new RawBundleSource({
34
- resources: [
35
- [
36
- EN_US,
37
- 'admin-test',
38
- `ADMIN_DASHBOARD = Admin Dashboard
39
- ADMIN_USERS = Manage Users
40
- ADMIN_REPORTS = Admin Reports
41
- BUTTON_SAVE = Admin Save
42
- test-admin-only = This key ONLY exists in admin bundle
43
-
44
- # Same key as Powerdialer but different value
45
- PAGE_TITLE_CAMPAIGNS = Admin Campaigns View`,
46
- ],
47
- [
48
- ES_LA,
49
- 'admin-test',
50
- `ADMIN_DASHBOARD = Panel de Administración
51
- ADMIN_USERS = Gestionar Usuarios
52
- ADMIN_REPORTS = Reportes de Admin
53
- BUTTON_SAVE = Guardar Admin
54
- test-admin-only = Esta clave SOLO existe en el bundle de admin
55
-
56
- # Same key as Powerdialer but different value
57
- PAGE_TITLE_CAMPAIGNS = Vista de Campañas Admin`,
58
- ],
59
- ],
60
- });
61
-
62
- return { PowerdialerBundle, adminBundle };
63
- }
64
-
65
- function createTestManager(
66
- bundleSource: RawBundleSource,
67
- namespaces: string[],
68
- props?: Partial<LocaleManagerParams>,
69
- ): LocaleManager {
70
- return new LocaleManager({
71
- bundleSource,
72
- namespaces,
73
- warmUp: false,
74
- fallbackLocale: EN_US,
75
- preferredLocale: EN_US,
76
- storageWrapper: new MemoryStorageWrapper(),
77
- ...props,
78
- });
79
- }
80
-
81
- function mockVueApp(): App {
82
- return {
83
- _context: { provides: {} },
84
- use: vi.fn(),
85
- provide: vi.fn(),
86
- component: vi.fn(),
87
- } as unknown as App;
88
- }
89
-
90
- describe('LocaleManager - Multiple Instances', () => {
91
- let powerdialerManager: LocaleManager;
92
- let adminManager: LocaleManager;
93
- let mockApp: App;
94
-
95
- beforeEach(async () => {
96
- const { PowerdialerBundle, adminBundle } = createTestBundleSources();
97
-
98
- powerdialerManager = createTestManager(PowerdialerBundle, ['app-core']);
99
- adminManager = createTestManager(adminBundle, ['admin-test']);
100
-
101
- mockApp = mockVueApp();
102
-
103
- // Warm up both managers with proper initialization
104
- powerdialerManager.updateLocaleSettings({
105
- namespaces: ['app-core'],
106
- preferredLocale: EN_US,
107
- });
108
- adminManager.updateLocaleSettings({
109
- namespaces: ['admin-test'],
110
- preferredLocale: EN_US,
111
- });
112
-
113
- // Install managers to Vue app (required for fluentFormat to work)
114
- powerdialerManager.install(mockApp);
115
- adminManager.install(mockApp);
116
-
117
- // Wait for both managers to be ready
118
- await powerdialerManager.ready;
119
- await adminManager.ready;
120
- });
121
-
122
- describe('Bundle Key Isolation', () => {
123
- it('should allow each manager to access only its own namespace keys', async () => {
124
- // Powerdialer manager should access app-core keys
125
- expect(powerdialerManager.fluentFormat('PAGE_TITLE_CAMPAIGNS')).toBe(
126
- 'Campaigns',
127
- );
128
- expect(powerdialerManager.fluentFormat('LEAD_PHONE_NUM_LABEL')).toBe(
129
- 'Phone Number',
130
- );
131
- expect(powerdialerManager.fluentFormat('CREATE_LEAD_BUTTON')).toBe(
132
- 'Create Lead',
133
- );
134
-
135
- // Admin manager should access admin-test keys
136
- expect(adminManager.fluentFormat('ADMIN_DASHBOARD')).toBe(
137
- 'Admin Dashboard',
138
- );
139
- expect(adminManager.fluentFormat('test-admin-only')).toBe(
140
- 'This key ONLY exists in admin bundle',
141
- );
142
- expect(adminManager.fluentFormat('PAGE_TITLE_CAMPAIGNS')).toBe(
143
- 'Admin Campaigns View',
144
- );
145
- });
146
-
147
- it('should return raw keys for non-existent keys in each namespace', () => {
148
- // Powerdialer manager should not access admin-only keys
149
- expect(powerdialerManager.fluentFormat('ADMIN_DASHBOARD')).toBe(
150
- 'ADMIN_DASHBOARD',
151
- );
152
- expect(powerdialerManager.fluentFormat('test-admin-only')).toBe(
153
- 'test-admin-only',
154
- );
155
-
156
- // Admin manager should not access Powerdialer-only keys
157
- expect(adminManager.fluentFormat('LEAD_PHONE_NUM_LABEL')).toBe(
158
- 'LEAD_PHONE_NUM_LABEL',
159
- );
160
- expect(adminManager.fluentFormat('CREATE_LEAD_BUTTON')).toBe(
161
- 'CREATE_LEAD_BUTTON',
162
- );
163
- });
164
- });
165
-
166
- describe('Cross-contamination Prevention', () => {
167
- it("should prevent managers from accessing each other's namespaces", () => {
168
- // Same key name, different values based on namespace
169
- const PowerdialerCampaigns = powerdialerManager.fluentFormat(
170
- 'PAGE_TITLE_CAMPAIGNS',
171
- );
172
- const adminCampaigns = adminManager.fluentFormat('PAGE_TITLE_CAMPAIGNS');
173
-
174
- expect(PowerdialerCampaigns).toBe('Campaigns');
175
- expect(adminCampaigns).toBe('Admin Campaigns View');
176
- expect(PowerdialerCampaigns).not.toBe(adminCampaigns);
177
- });
178
-
179
- it('should maintain namespace isolation even with similar key names', () => {
180
- // Admin has BUTTON_SAVE, Powerdialer doesn't
181
- expect(adminManager.fluentFormat('BUTTON_SAVE')).toBe('Admin Save');
182
- expect(powerdialerManager.fluentFormat('BUTTON_SAVE')).toBe(
183
- 'BUTTON_SAVE',
184
- ); // Raw key returned
185
-
186
- // Powerdialer has CREATE_LEAD_BUTTON, Admin doesn't
187
- expect(powerdialerManager.fluentFormat('CREATE_LEAD_BUTTON')).toBe(
188
- 'Create Lead',
189
- );
190
- expect(adminManager.fluentFormat('CREATE_LEAD_BUTTON')).toBe(
191
- 'CREATE_LEAD_BUTTON',
192
- ); // Raw key returned
193
- });
194
- });
195
-
196
- describe('Language Switching', () => {
197
- it('should switch language for individual managers independently', async () => {
198
- // Set up injection keys for both managers (like the working test)
199
- const provides = mockApp._context.provides as Record<
200
- string,
201
- LocaleManager
202
- >;
203
- provides[`${INJECTION_KEY_PREFIX}.app-core`] = powerdialerManager;
204
- provides[`${INJECTION_KEY_PREFIX}.admin-test`] = adminManager;
205
-
206
- // Switch Powerdialer to Spanish using change() method with namespace
207
- powerdialerManager.changeLocale({ preferredLocale: ES_LA }, 'app-core');
208
- await powerdialerManager.ready;
209
-
210
- // Powerdialer should show Spanish
211
- expect(powerdialerManager.fluentFormat('PAGE_TITLE_CAMPAIGNS')).toBe(
212
- 'Campañas',
213
- );
214
- expect(powerdialerManager.fluentFormat('LEAD_PHONE_NUM_LABEL')).toBe(
215
- 'Número de Teléfono',
216
- );
217
-
218
- // Admin should still show English
219
- expect(adminManager.fluentFormat('PAGE_TITLE_CAMPAIGNS')).toBe(
220
- 'Admin Campaigns View',
221
- );
222
- expect(adminManager.fluentFormat('ADMIN_DASHBOARD')).toBe(
223
- 'Admin Dashboard',
224
- );
225
- });
226
-
227
- it('should switch language for all managers when using changeLocale globally', async () => {
228
- // Set up injection keys for both managers
229
- const provides = mockApp._context.provides as Record<
230
- string,
231
- LocaleManager
232
- >;
233
- provides[`${INJECTION_KEY_PREFIX}.app-core`] = powerdialerManager;
234
- provides[`${INJECTION_KEY_PREFIX}.admin-test`] = adminManager;
235
-
236
- // Switch all managers to Spanish
237
- powerdialerManager.changeLocale({ preferredLocale: ES_LA });
238
-
239
- // Wait for both managers to be ready
240
- await powerdialerManager.ready;
241
- await adminManager.ready;
242
-
243
- // Both managers should show Spanish
244
- expect(powerdialerManager.fluentFormat('PAGE_TITLE_CAMPAIGNS')).toBe(
245
- 'Campañas',
246
- );
247
- expect(adminManager.fluentFormat('PAGE_TITLE_CAMPAIGNS')).toBe(
248
- 'Vista de Campañas Admin',
249
- );
250
- expect(adminManager.fluentFormat('ADMIN_DASHBOARD')).toBe(
251
- 'Panel de Administración',
252
- );
253
- });
254
-
255
- it('should maintain namespace isolation during language switching', async () => {
256
- // Switch both to Spanish
257
- const provides = mockApp._context.provides as Record<
258
- string,
259
- LocaleManager
260
- >;
261
- provides[`${INJECTION_KEY_PREFIX}.app-core`] = powerdialerManager;
262
- provides[`${INJECTION_KEY_PREFIX}.admin-test`] = adminManager;
263
-
264
- powerdialerManager.changeLocale({ preferredLocale: ES_LA });
265
- await powerdialerManager.ready;
266
- await adminManager.ready;
267
-
268
- // Each manager should access only its own Spanish translations
269
- expect(powerdialerManager.fluentFormat('PAGE_TITLE_CAMPAIGNS')).toBe(
270
- 'Campañas',
271
- );
272
- expect(adminManager.fluentFormat('PAGE_TITLE_CAMPAIGNS')).toBe(
273
- 'Vista de Campañas Admin',
274
- );
275
-
276
- // Admin-only keys should still be isolated
277
- expect(adminManager.fluentFormat('test-admin-only')).toBe(
278
- 'Esta clave SOLO existe en el bundle de admin',
279
- );
280
- expect(powerdialerManager.fluentFormat('test-admin-only')).toBe(
281
- 'test-admin-only',
282
- ); // Raw key
283
- });
284
- });
285
-
286
- describe('Manager Independence', () => {
287
- it('should allow managers to have different preferred locales simultaneously', async () => {
288
- // Set up injection keys for both managers
289
- const provides = mockApp._context.provides as Record<
290
- string,
291
- LocaleManager
292
- >;
293
- provides[`${INJECTION_KEY_PREFIX}.app-core`] = powerdialerManager;
294
- provides[`${INJECTION_KEY_PREFIX}.admin-test`] = adminManager;
295
-
296
- // Set Powerdialer to Spanish using change() method with namespace
297
- powerdialerManager.changeLocale({ preferredLocale: ES_LA }, 'app-core');
298
- await powerdialerManager.ready;
299
-
300
- // Keep Admin in English (no change)
301
-
302
- // Verify different locales
303
- expect(powerdialerManager.currentLocaleProp.value).toBe(ES_LA);
304
- expect(adminManager.currentLocaleProp.value).toBe(EN_US);
305
-
306
- // Verify translations reflect different locales
307
- expect(powerdialerManager.fluentFormat('PAGE_TITLE_CAMPAIGNS')).toBe(
308
- 'Campañas',
309
- );
310
- expect(adminManager.fluentFormat('PAGE_TITLE_CAMPAIGNS')).toBe(
311
- 'Admin Campaigns View',
312
- );
313
- });
314
-
315
- it("should not interfere with each other's bundle loading", async () => {
316
- // Force reload bundles for one manager
317
- powerdialerManager.changeLocale({ useCache: false });
318
- await powerdialerManager.ready;
319
-
320
- // Other manager should still work normally
321
- expect(adminManager.fluentFormat('ADMIN_DASHBOARD')).toBe(
322
- 'Admin Dashboard',
323
- );
324
- expect(powerdialerManager.fluentFormat('PAGE_TITLE_CAMPAIGNS')).toBe(
325
- 'Campaigns',
326
- );
327
- });
328
- });
329
-
330
- describe('Error Handling', () => {
331
- it('should handle missing translations gracefully in each manager', () => {
332
- // Non-existent keys should return raw key strings
333
- expect(powerdialerManager.fluentFormat('NON_EXISTENT_KEY')).toBe(
334
- 'NON_EXISTENT_KEY',
335
- );
336
- expect(adminManager.fluentFormat('ANOTHER_MISSING_KEY')).toBe(
337
- 'ANOTHER_MISSING_KEY',
338
- );
339
- });
340
-
341
- it('should not crash when one manager has bundle issues', () => {
342
- // This test ensures that if one manager has problems, others continue working
343
- expect(() => {
344
- powerdialerManager.fluentFormat('PAGE_TITLE_CAMPAIGNS');
345
- adminManager.fluentFormat('ADMIN_DASHBOARD');
346
- }).not.toThrow();
347
- });
348
- });
349
- });