@vocab/phrase 1.1.0 → 1.2.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.
- package/README.md +66 -5
- package/dist/declarations/src/csv.d.ts +10 -0
- package/dist/declarations/src/phrase-api.d.ts +5 -3
- package/dist/declarations/src/push-translations.d.ts +2 -1
- package/dist/vocab-phrase.cjs.dev.js +113 -28
- package/dist/vocab-phrase.cjs.prod.js +113 -28
- package/dist/vocab-phrase.esm.js +113 -28
- package/package.json +8 -4
- package/CHANGELOG.md +0 -145
- package/src/file.ts +0 -4
- package/src/index.ts +0 -2
- package/src/logger.ts +0 -9
- package/src/phrase-api.ts +0 -181
- package/src/pull-translations.test.ts +0 -214
- package/src/pull-translations.ts +0 -114
- package/src/push-translations.test.ts +0 -168
- package/src/push-translations.ts +0 -67
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { pull } from './pull-translations';
|
|
3
|
-
import { pullAllTranslations } from './phrase-api';
|
|
4
|
-
import { writeFile } from './file';
|
|
5
|
-
import { GeneratedLanguageTarget, LanguageTarget } from '@vocab/types';
|
|
6
|
-
|
|
7
|
-
jest.mock('./file', () => ({
|
|
8
|
-
writeFile: jest.fn(() => Promise.resolve),
|
|
9
|
-
mkdir: jest.fn(() => Promise.resolve),
|
|
10
|
-
}));
|
|
11
|
-
|
|
12
|
-
jest.mock('./phrase-api', () => ({
|
|
13
|
-
ensureBranch: jest.fn(() => Promise.resolve()),
|
|
14
|
-
pullAllTranslations: jest.fn(() => Promise.resolve({ en: {}, fr: {} })),
|
|
15
|
-
}));
|
|
16
|
-
|
|
17
|
-
const devLanguage = 'en';
|
|
18
|
-
|
|
19
|
-
function runPhrase(options: {
|
|
20
|
-
languages: LanguageTarget[];
|
|
21
|
-
generatedLanguages: GeneratedLanguageTarget[];
|
|
22
|
-
}) {
|
|
23
|
-
return pull(
|
|
24
|
-
{ branch: 'tester' },
|
|
25
|
-
{
|
|
26
|
-
...options,
|
|
27
|
-
devLanguage,
|
|
28
|
-
projectRoot: path.resolve(__dirname, '..', '..', '..', 'fixtures/phrase'),
|
|
29
|
-
},
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
describe('pull translations', () => {
|
|
34
|
-
describe('when pulling translations for languages that already have translations', () => {
|
|
35
|
-
beforeEach(() => {
|
|
36
|
-
jest.mocked(pullAllTranslations).mockClear();
|
|
37
|
-
jest.mocked(writeFile).mockClear();
|
|
38
|
-
jest.mocked(pullAllTranslations).mockImplementation(() =>
|
|
39
|
-
Promise.resolve({
|
|
40
|
-
en: {
|
|
41
|
-
'hello.mytranslations': {
|
|
42
|
-
message: 'Hi there',
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
fr: {
|
|
46
|
-
'hello.mytranslations': {
|
|
47
|
-
message: 'merci',
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
}),
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const options = {
|
|
55
|
-
languages: [{ name: 'en' }, { name: 'fr' }],
|
|
56
|
-
generatedLanguages: [
|
|
57
|
-
{
|
|
58
|
-
name: 'generatedLanguage',
|
|
59
|
-
extends: 'en',
|
|
60
|
-
generator: {
|
|
61
|
-
transformMessage: (message: string) => `[${message}]`,
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
it('should resolve', async () => {
|
|
68
|
-
await expect(runPhrase(options)).resolves.toBeUndefined();
|
|
69
|
-
|
|
70
|
-
expect(jest.mocked(writeFile)).toHaveBeenCalledTimes(2);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should update keys', async () => {
|
|
74
|
-
await expect(runPhrase(options)).resolves.toBeUndefined();
|
|
75
|
-
|
|
76
|
-
expect(
|
|
77
|
-
jest
|
|
78
|
-
.mocked(writeFile)
|
|
79
|
-
.mock.calls.map(([_filePath, contents]) =>
|
|
80
|
-
JSON.parse(contents as string),
|
|
81
|
-
),
|
|
82
|
-
).toMatchInlineSnapshot(`
|
|
83
|
-
[
|
|
84
|
-
{
|
|
85
|
-
"hello": {
|
|
86
|
-
"message": "Hi there",
|
|
87
|
-
},
|
|
88
|
-
"world": {
|
|
89
|
-
"message": "world",
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"hello": {
|
|
94
|
-
"message": "merci",
|
|
95
|
-
},
|
|
96
|
-
"world": {
|
|
97
|
-
"message": "monde",
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
]
|
|
101
|
-
`);
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
describe('when pulling translations and some languages do not have any translations', () => {
|
|
106
|
-
beforeEach(() => {
|
|
107
|
-
jest.mocked(pullAllTranslations).mockClear();
|
|
108
|
-
jest.mocked(writeFile).mockClear();
|
|
109
|
-
jest.mocked(pullAllTranslations).mockImplementation(() =>
|
|
110
|
-
Promise.resolve({
|
|
111
|
-
en: {
|
|
112
|
-
'hello.mytranslations': {
|
|
113
|
-
message: 'Hi there',
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
fr: {
|
|
117
|
-
'hello.mytranslations': {
|
|
118
|
-
message: 'merci',
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
}),
|
|
122
|
-
);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
const options = {
|
|
126
|
-
languages: [{ name: 'en' }, { name: 'fr' }, { name: 'ja' }],
|
|
127
|
-
generatedLanguages: [
|
|
128
|
-
{
|
|
129
|
-
name: 'generatedLanguage',
|
|
130
|
-
extends: 'en',
|
|
131
|
-
generator: {
|
|
132
|
-
transformMessage: (message: string) => `[${message}]`,
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
it('should resolve', async () => {
|
|
139
|
-
await expect(runPhrase(options)).resolves.toBeUndefined();
|
|
140
|
-
|
|
141
|
-
expect(jest.mocked(writeFile)).toHaveBeenCalledTimes(2);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it('should update keys', async () => {
|
|
145
|
-
await expect(runPhrase(options)).resolves.toBeUndefined();
|
|
146
|
-
|
|
147
|
-
expect(
|
|
148
|
-
jest
|
|
149
|
-
.mocked(writeFile)
|
|
150
|
-
.mock.calls.map(([_filePath, contents]) =>
|
|
151
|
-
JSON.parse(contents as string),
|
|
152
|
-
),
|
|
153
|
-
).toMatchInlineSnapshot(`
|
|
154
|
-
[
|
|
155
|
-
{
|
|
156
|
-
"hello": {
|
|
157
|
-
"message": "Hi there",
|
|
158
|
-
},
|
|
159
|
-
"world": {
|
|
160
|
-
"message": "world",
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
"hello": {
|
|
165
|
-
"message": "merci",
|
|
166
|
-
},
|
|
167
|
-
"world": {
|
|
168
|
-
"message": "monde",
|
|
169
|
-
},
|
|
170
|
-
},
|
|
171
|
-
]
|
|
172
|
-
`);
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
describe('when pulling translations and the project has not configured translations for the dev language', () => {
|
|
177
|
-
beforeEach(() => {
|
|
178
|
-
jest.mocked(pullAllTranslations).mockClear();
|
|
179
|
-
jest.mocked(writeFile).mockClear();
|
|
180
|
-
jest.mocked(pullAllTranslations).mockImplementation(() =>
|
|
181
|
-
Promise.resolve({
|
|
182
|
-
fr: {
|
|
183
|
-
'hello.mytranslations': {
|
|
184
|
-
message: 'merci',
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
}),
|
|
188
|
-
);
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
const options = {
|
|
192
|
-
languages: [{ name: 'en' }, { name: 'fr' }],
|
|
193
|
-
generatedLanguages: [
|
|
194
|
-
{
|
|
195
|
-
name: 'generatedLanguage',
|
|
196
|
-
extends: 'en',
|
|
197
|
-
generator: {
|
|
198
|
-
transformMessage: (message: string) => `[${message}]`,
|
|
199
|
-
},
|
|
200
|
-
},
|
|
201
|
-
],
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
it('should throw an error', async () => {
|
|
205
|
-
await expect(runPhrase(options)).rejects.toThrow(
|
|
206
|
-
new Error(
|
|
207
|
-
`Phrase did not return any translations for the configured development language "en".\nPlease ensure this language is present in your Phrase project's configuration.`,
|
|
208
|
-
),
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
expect(jest.mocked(writeFile)).toHaveBeenCalledTimes(0);
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
});
|
package/src/pull-translations.ts
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { writeFile, mkdir } from './file';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
loadAllTranslations,
|
|
6
|
-
getAltLanguageFilePath,
|
|
7
|
-
getAltLanguages,
|
|
8
|
-
getUniqueKey,
|
|
9
|
-
} from '@vocab/core';
|
|
10
|
-
import type { UserConfig } from '@vocab/types';
|
|
11
|
-
|
|
12
|
-
import { pullAllTranslations, ensureBranch } from './phrase-api';
|
|
13
|
-
import { trace } from './logger';
|
|
14
|
-
|
|
15
|
-
interface PullOptions {
|
|
16
|
-
branch?: string;
|
|
17
|
-
deleteUnusedKeys?: boolean;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export async function pull(
|
|
21
|
-
{ branch = 'local-development' }: PullOptions,
|
|
22
|
-
config: UserConfig,
|
|
23
|
-
) {
|
|
24
|
-
trace(`Pulling translations from branch ${branch}`);
|
|
25
|
-
await ensureBranch(branch);
|
|
26
|
-
const alternativeLanguages = getAltLanguages(config);
|
|
27
|
-
const allPhraseTranslations = await pullAllTranslations(branch);
|
|
28
|
-
trace(
|
|
29
|
-
`Pulling translations from Phrase for languages ${
|
|
30
|
-
config.devLanguage
|
|
31
|
-
} and ${alternativeLanguages.join(', ')}`,
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
const phraseLanguages = Object.keys(allPhraseTranslations);
|
|
35
|
-
trace(
|
|
36
|
-
`Found Phrase translations for languages ${phraseLanguages.join(', ')}`,
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
if (!phraseLanguages.includes(config.devLanguage)) {
|
|
40
|
-
throw new Error(
|
|
41
|
-
`Phrase did not return any translations for the configured development language "${config.devLanguage}".\nPlease ensure this language is present in your Phrase project's configuration.`,
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const allVocabTranslations = await loadAllTranslations(
|
|
46
|
-
{ fallbacks: 'none', includeNodeModules: false },
|
|
47
|
-
config,
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
for (const loadedTranslation of allVocabTranslations) {
|
|
51
|
-
const devTranslations = loadedTranslation.languages[config.devLanguage];
|
|
52
|
-
|
|
53
|
-
if (!devTranslations) {
|
|
54
|
-
throw new Error('No dev language translations loaded');
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const defaultValues = { ...devTranslations };
|
|
58
|
-
const localKeys = Object.keys(defaultValues);
|
|
59
|
-
|
|
60
|
-
for (const key of localKeys) {
|
|
61
|
-
defaultValues[key] = {
|
|
62
|
-
...defaultValues[key],
|
|
63
|
-
...allPhraseTranslations[config.devLanguage][
|
|
64
|
-
getUniqueKey(key, loadedTranslation.namespace)
|
|
65
|
-
],
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
await writeFile(
|
|
69
|
-
loadedTranslation.filePath,
|
|
70
|
-
`${JSON.stringify(defaultValues, null, 2)}\n`,
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
for (const alternativeLanguage of alternativeLanguages) {
|
|
74
|
-
if (alternativeLanguage in allPhraseTranslations) {
|
|
75
|
-
const altTranslations = {
|
|
76
|
-
...loadedTranslation.languages[alternativeLanguage],
|
|
77
|
-
};
|
|
78
|
-
const phraseAltTranslations =
|
|
79
|
-
allPhraseTranslations[alternativeLanguage];
|
|
80
|
-
|
|
81
|
-
for (const key of localKeys) {
|
|
82
|
-
const phraseKey = getUniqueKey(key, loadedTranslation.namespace);
|
|
83
|
-
const phraseTranslationMessage =
|
|
84
|
-
phraseAltTranslations[phraseKey]?.message;
|
|
85
|
-
|
|
86
|
-
if (!phraseTranslationMessage) {
|
|
87
|
-
trace(
|
|
88
|
-
`Missing translation. No translation for key ${key} in phrase as ${phraseKey} in language ${alternativeLanguage}.`,
|
|
89
|
-
);
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
altTranslations[key] = {
|
|
94
|
-
...altTranslations[key],
|
|
95
|
-
message: phraseTranslationMessage,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const altTranslationFilePath = getAltLanguageFilePath(
|
|
100
|
-
loadedTranslation.filePath,
|
|
101
|
-
alternativeLanguage,
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
await mkdir(path.dirname(altTranslationFilePath), {
|
|
105
|
-
recursive: true,
|
|
106
|
-
});
|
|
107
|
-
await writeFile(
|
|
108
|
-
altTranslationFilePath,
|
|
109
|
-
`${JSON.stringify(altTranslations, null, 2)}\n`,
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { push } from './push-translations';
|
|
3
|
-
import { pushTranslationsByLocale, deleteUnusedKeys } from './phrase-api';
|
|
4
|
-
import { writeFile } from './file';
|
|
5
|
-
|
|
6
|
-
jest.mock('./file', () => ({
|
|
7
|
-
writeFile: jest.fn(() => Promise.resolve),
|
|
8
|
-
mkdir: jest.fn(() => Promise.resolve),
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
jest.mock('./phrase-api', () => ({
|
|
12
|
-
ensureBranch: jest.fn(() => Promise.resolve()),
|
|
13
|
-
pushTranslationsByLocale: jest.fn(() => Promise.resolve({ en: {}, fr: {} })),
|
|
14
|
-
deleteUnusedKeys: jest.fn(() => Promise.resolve()),
|
|
15
|
-
}));
|
|
16
|
-
|
|
17
|
-
const uploadId = '1234';
|
|
18
|
-
|
|
19
|
-
function runPhrase(config: { deleteUnusedKeys: boolean }) {
|
|
20
|
-
return push(
|
|
21
|
-
{ branch: 'tester', deleteUnusedKeys: config.deleteUnusedKeys },
|
|
22
|
-
{
|
|
23
|
-
devLanguage: 'en',
|
|
24
|
-
languages: [{ name: 'en' }, { name: 'fr' }],
|
|
25
|
-
generatedLanguages: [
|
|
26
|
-
{
|
|
27
|
-
name: 'generatedLanguage',
|
|
28
|
-
extends: 'en',
|
|
29
|
-
generator: {
|
|
30
|
-
transformMessage: (message: string) => `[${message}]`,
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
projectRoot: path.resolve(__dirname, '..', '..', '..', 'fixtures/phrase'),
|
|
35
|
-
},
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
describe('push', () => {
|
|
40
|
-
describe('when deleteUnusedKeys is false', () => {
|
|
41
|
-
const config = { deleteUnusedKeys: false };
|
|
42
|
-
|
|
43
|
-
beforeEach(() => {
|
|
44
|
-
jest.mocked(pushTranslationsByLocale).mockClear();
|
|
45
|
-
jest.mocked(writeFile).mockClear();
|
|
46
|
-
jest.mocked(deleteUnusedKeys).mockClear();
|
|
47
|
-
|
|
48
|
-
jest
|
|
49
|
-
.mocked(pushTranslationsByLocale)
|
|
50
|
-
.mockImplementation(() => Promise.resolve({ uploadId }));
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should resolve', async () => {
|
|
54
|
-
await expect(runPhrase(config)).resolves.toBeUndefined();
|
|
55
|
-
|
|
56
|
-
expect(jest.mocked(pushTranslationsByLocale)).toHaveBeenCalledTimes(2);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('should update keys', async () => {
|
|
60
|
-
await expect(runPhrase(config)).resolves.toBeUndefined();
|
|
61
|
-
|
|
62
|
-
expect(jest.mocked(pushTranslationsByLocale)).toHaveBeenCalledWith(
|
|
63
|
-
{
|
|
64
|
-
'hello.mytranslations': {
|
|
65
|
-
message: 'Hello',
|
|
66
|
-
},
|
|
67
|
-
'world.mytranslations': {
|
|
68
|
-
message: 'world',
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
'en',
|
|
72
|
-
'tester',
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
expect(jest.mocked(pushTranslationsByLocale)).toHaveBeenCalledWith(
|
|
76
|
-
{
|
|
77
|
-
'hello.mytranslations': {
|
|
78
|
-
message: 'Bonjour',
|
|
79
|
-
},
|
|
80
|
-
'world.mytranslations': {
|
|
81
|
-
message: 'monde',
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
'fr',
|
|
85
|
-
'tester',
|
|
86
|
-
);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it('should not delete unused keys', () => {
|
|
90
|
-
expect(deleteUnusedKeys).not.toHaveBeenCalled();
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
describe('when deleteUnusedKeys is true', () => {
|
|
95
|
-
const config = { deleteUnusedKeys: true };
|
|
96
|
-
|
|
97
|
-
beforeEach(() => {
|
|
98
|
-
jest.mocked(pushTranslationsByLocale).mockClear();
|
|
99
|
-
jest.mocked(writeFile).mockClear();
|
|
100
|
-
jest.mocked(deleteUnusedKeys).mockClear();
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
describe('and the upload succeeds', () => {
|
|
104
|
-
beforeEach(() => {
|
|
105
|
-
jest
|
|
106
|
-
.mocked(pushTranslationsByLocale)
|
|
107
|
-
.mockImplementation(() => Promise.resolve({ uploadId }));
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('should resolve', async () => {
|
|
111
|
-
await expect(runPhrase(config)).resolves.toBeUndefined();
|
|
112
|
-
|
|
113
|
-
expect(jest.mocked(pushTranslationsByLocale)).toHaveBeenCalledTimes(2);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it('should update keys', async () => {
|
|
117
|
-
await expect(runPhrase(config)).resolves.toBeUndefined();
|
|
118
|
-
|
|
119
|
-
expect(jest.mocked(pushTranslationsByLocale)).toHaveBeenCalledWith(
|
|
120
|
-
{
|
|
121
|
-
'hello.mytranslations': {
|
|
122
|
-
message: 'Hello',
|
|
123
|
-
},
|
|
124
|
-
'world.mytranslations': {
|
|
125
|
-
message: 'world',
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
'en',
|
|
129
|
-
'tester',
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
expect(jest.mocked(pushTranslationsByLocale)).toHaveBeenCalledWith(
|
|
133
|
-
{
|
|
134
|
-
'hello.mytranslations': {
|
|
135
|
-
message: 'Bonjour',
|
|
136
|
-
},
|
|
137
|
-
'world.mytranslations': {
|
|
138
|
-
message: 'monde',
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
'fr',
|
|
142
|
-
'tester',
|
|
143
|
-
);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('should delete unused keys', async () => {
|
|
147
|
-
await expect(runPhrase(config)).resolves.toBeUndefined();
|
|
148
|
-
|
|
149
|
-
expect(deleteUnusedKeys).toHaveBeenCalledWith(uploadId, 'en', 'tester');
|
|
150
|
-
expect(deleteUnusedKeys).toHaveBeenCalledWith(uploadId, 'fr', 'tester');
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
describe('and the upload fails', () => {
|
|
155
|
-
beforeEach(() => {
|
|
156
|
-
jest
|
|
157
|
-
.mocked(pushTranslationsByLocale)
|
|
158
|
-
.mockImplementation(() => Promise.reject('Upload failed'));
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it('should not delete unused keys', async () => {
|
|
162
|
-
await expect(runPhrase(config)).rejects.toBe('Upload failed');
|
|
163
|
-
|
|
164
|
-
expect(deleteUnusedKeys).not.toHaveBeenCalled();
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
});
|
package/src/push-translations.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { TranslationsByLanguage } from './../../types/src/index';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
ensureBranch,
|
|
5
|
-
pushTranslationsByLocale,
|
|
6
|
-
deleteUnusedKeys as phraseDeleteUnusedKeys,
|
|
7
|
-
} from './phrase-api';
|
|
8
|
-
import { trace } from './logger';
|
|
9
|
-
import { loadAllTranslations, getUniqueKey } from '@vocab/core';
|
|
10
|
-
import { UserConfig } from '@vocab/types';
|
|
11
|
-
|
|
12
|
-
interface PushOptions {
|
|
13
|
-
branch: string;
|
|
14
|
-
deleteUnusedKeys?: boolean;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Uploading to the Phrase API for each language. Adding a unique namespace to each key using file path they key came from
|
|
19
|
-
*/
|
|
20
|
-
export async function push(
|
|
21
|
-
{ branch, deleteUnusedKeys }: PushOptions,
|
|
22
|
-
config: UserConfig,
|
|
23
|
-
) {
|
|
24
|
-
const allLanguageTranslations = await loadAllTranslations(
|
|
25
|
-
{ fallbacks: 'none', includeNodeModules: false },
|
|
26
|
-
config,
|
|
27
|
-
);
|
|
28
|
-
trace(`Pushing translations to branch ${branch}`);
|
|
29
|
-
const allLanguages = config.languages.map((v) => v.name);
|
|
30
|
-
await ensureBranch(branch);
|
|
31
|
-
|
|
32
|
-
trace(
|
|
33
|
-
`Pushing translations to phrase for languages ${allLanguages.join(', ')}`,
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
const phraseTranslations: TranslationsByLanguage = {};
|
|
37
|
-
|
|
38
|
-
for (const loadedTranslation of allLanguageTranslations) {
|
|
39
|
-
for (const language of allLanguages) {
|
|
40
|
-
const localTranslations = loadedTranslation.languages[language];
|
|
41
|
-
if (!localTranslations) {
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
if (!phraseTranslations[language]) {
|
|
45
|
-
phraseTranslations[language] = {};
|
|
46
|
-
}
|
|
47
|
-
for (const localKey of Object.keys(localTranslations)) {
|
|
48
|
-
const phraseKey = getUniqueKey(localKey, loadedTranslation.namespace);
|
|
49
|
-
phraseTranslations[language][phraseKey] = localTranslations[localKey];
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
for (const language of allLanguages) {
|
|
55
|
-
if (phraseTranslations[language]) {
|
|
56
|
-
const { uploadId } = await pushTranslationsByLocale(
|
|
57
|
-
phraseTranslations[language],
|
|
58
|
-
language,
|
|
59
|
-
branch,
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
if (deleteUnusedKeys) {
|
|
63
|
-
await phraseDeleteUnusedKeys(uploadId, language, branch);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|