Skip to content

Commit 98a1d12

Browse files
committed
Include locales in companion manifest
1 parent aa8d9e6 commit 98a1d12

2 files changed

Lines changed: 77 additions & 40 deletions

File tree

src/__snapshots__/componentManifest.test.ts.snap

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ Object {
8080
"companion": Object {
8181
"main": "companion/index.js",
8282
},
83+
"i18n": Object {
84+
"en-us": Object {
85+
"name": "My App",
86+
},
87+
"fr-fr": Object {
88+
"name": "Mon application",
89+
},
90+
},
8391
"manifestVersion": 2,
8492
"name": "My App",
8593
"requestedPermissions": Array [],
@@ -107,6 +115,14 @@ Object {
107115
"main": "companion/index.js",
108116
},
109117
"developerProfileId": "f00df00d-f00d-f00d-f00d-f00df00df00d",
118+
"i18n": Object {
119+
"en-us": Object {
120+
"name": "My App",
121+
},
122+
"fr-fr": Object {
123+
"name": "Mon application",
124+
},
125+
},
110126
"manifestVersion": 2,
111127
"name": "My App",
112128
"requestedPermissions": Array [],
@@ -122,6 +138,14 @@ Object {
122138
"companion": Object {
123139
"main": "companion/index.js",
124140
},
141+
"i18n": Object {
142+
"en-us": Object {
143+
"name": "My App",
144+
},
145+
"fr-fr": Object {
146+
"name": "Mon application",
147+
},
148+
},
125149
"manifestVersion": 2,
126150
"name": "My App",
127151
"requestedPermissions": Array [],
@@ -224,9 +248,9 @@ Object {
224248
}
225249
`;
226250

227-
exports[`when there is a device entry point present when there are compiled language files ensures the default language en-US is the first key in the i18n object 1`] = `"{\\"appManifestVersion\\":1,\\"main\\":\\"device/index.js\\",\\"svgMain\\":\\"resources/index.view\\",\\"svgWidgets\\":\\"resources/widget.defs\\",\\"appType\\":\\"clockface\\",\\"apiVersion\\":\\"7.0.0\\",\\"buildId\\":\\"0x0f75775f470c1585\\",\\"bundleDate\\":\\"2018-06-27T00:00:00.000Z\\",\\"uuid\\":\\"b4ae822e-eca9-4fcb-8747-217f2a1f53a1\\",\\"name\\":\\"My App\\",\\"requestedPermissions\\":[],\\"supports\\":{\\"screenSize\\":{\\"w\\":300,\\"h\\":300}},\\"i18n\\":{\\"en-us\\":{\\"name\\":\\"My App\\",\\"resources\\":\\"lang/english\\"},\\"fr-fr\\":{\\"name\\":\\"Mon application\\"},\\"es-es\\":{\\"resources\\":\\"spanish/language\\"}}}"`;
251+
exports[`when there is a device entry point present when there are compiled language files ensures the default language en-US is the first key in the i18n object 1`] = `"{\\"appManifestVersion\\":1,\\"main\\":\\"device/index.js\\",\\"svgMain\\":\\"resources/index.view\\",\\"svgWidgets\\":\\"resources/widget.defs\\",\\"appType\\":\\"clockface\\",\\"apiVersion\\":\\"7.0.0\\",\\"buildId\\":\\"0x0f75775f470c1585\\",\\"bundleDate\\":\\"2018-06-27T00:00:00.000Z\\",\\"uuid\\":\\"b4ae822e-eca9-4fcb-8747-217f2a1f53a1\\",\\"name\\":\\"My App\\",\\"requestedPermissions\\":[],\\"i18n\\":{\\"en-us\\":{\\"name\\":\\"My App\\",\\"resources\\":\\"lang/english\\"},\\"fr-fr\\":{\\"name\\":\\"Mon application\\"},\\"es-es\\":{\\"resources\\":\\"spanish/language\\"}},\\"supports\\":{\\"screenSize\\":{\\"w\\":300,\\"h\\":300}}}"`;
228252

229-
exports[`when there is a device entry point present when there are compiled language files ensures the default language es-ES is the first key in the i18n object 1`] = `"{\\"appManifestVersion\\":1,\\"main\\":\\"device/index.js\\",\\"svgMain\\":\\"resources/index.view\\",\\"svgWidgets\\":\\"resources/widget.defs\\",\\"appType\\":\\"clockface\\",\\"apiVersion\\":\\"7.0.0\\",\\"buildId\\":\\"0x0f75775f470c1585\\",\\"bundleDate\\":\\"2018-06-27T00:00:00.000Z\\",\\"uuid\\":\\"b4ae822e-eca9-4fcb-8747-217f2a1f53a1\\",\\"name\\":\\"My App\\",\\"requestedPermissions\\":[],\\"supports\\":{\\"screenSize\\":{\\"w\\":300,\\"h\\":300}},\\"i18n\\":{\\"es-es\\":{\\"resources\\":\\"spanish/language\\"},\\"en-us\\":{\\"name\\":\\"My App\\",\\"resources\\":\\"lang/english\\"},\\"fr-fr\\":{\\"name\\":\\"Mon application\\"}}}"`;
253+
exports[`when there is a device entry point present when there are compiled language files ensures the default language es-ES is the first key in the i18n object 1`] = `"{\\"appManifestVersion\\":1,\\"main\\":\\"device/index.js\\",\\"svgMain\\":\\"resources/index.view\\",\\"svgWidgets\\":\\"resources/widget.defs\\",\\"appType\\":\\"clockface\\",\\"apiVersion\\":\\"7.0.0\\",\\"buildId\\":\\"0x0f75775f470c1585\\",\\"bundleDate\\":\\"2018-06-27T00:00:00.000Z\\",\\"uuid\\":\\"b4ae822e-eca9-4fcb-8747-217f2a1f53a1\\",\\"name\\":\\"My App\\",\\"requestedPermissions\\":[],\\"i18n\\":{\\"es-es\\":{\\"resources\\":\\"spanish/language\\"},\\"en-us\\":{\\"name\\":\\"My App\\",\\"resources\\":\\"lang/english\\"},\\"fr-fr\\":{\\"name\\":\\"Mon application\\"}},\\"supports\\":{\\"screenSize\\":{\\"w\\":300,\\"h\\":300}}}"`;
230254

231255
exports[`when there is a device entry point present when there are compiled language files sets the i18n[lang].resources key for language files that pass through 1`] = `
232256
Object {

src/componentManifest.ts

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,36 @@ const manifestPath = 'manifest.json';
1717
/**
1818
* Descriptor for localized resources.
1919
*/
20-
interface Locales {
20+
interface Locale {
21+
/**
22+
* Localized name of the app.
23+
*
24+
* On device, this field is capped at 30 bytes (not including the null
25+
* char).
26+
*/
27+
name?: string;
28+
}
29+
30+
interface DeviceLocale extends Locale {
31+
/**
32+
* Path to the resources file for the locale, relative to the manifest file.
33+
*
34+
* This file is generated from the corresponding '.po' file using an
35+
* internal, more compact format. On device, this field is capped at
36+
* 256 bytes (not including the null char).
37+
* @example 'l/en-US'
38+
*/
39+
resources?: string;
40+
}
41+
42+
interface Locales<LocaleType = Locale> {
2143
/**
2244
* Lower case locale name.
2345
*
2446
* On device, this field is capped at 20 bytes (not including the null char).
2547
* @example 'en-us'
2648
*/
27-
[locale: string]: {
28-
/**
29-
* Localized name of the app.
30-
*
31-
* On device, this field is capped at 30 bytes (not including the null
32-
* char).
33-
*/
34-
name?: string;
35-
36-
/**
37-
* Path to the resources file for the locale, relative to the manifest file.
38-
*
39-
* This file is generated from the corresponding '.po' file using an
40-
* internal, more compact format. On device, this field is capped at
41-
* 256 bytes (not including the null char).
42-
* @example 'l/en-US'
43-
*/
44-
resources?: string;
45-
};
49+
[locale: string]: LocaleType;
4650
}
4751

4852
interface ComponentManifest {
@@ -88,6 +92,14 @@ interface ComponentManifest {
8892
* On device, this field is capped at 36 bytes (not including the null char).
8993
*/
9094
uuid: string;
95+
96+
/**
97+
* List of localized resources.
98+
*
99+
* On device, when this field is read, the value of the `i18n` field is
100+
* capped to 1024 bytes (not including the null char).
101+
*/
102+
i18n: Locales;
91103
}
92104

93105
interface DeviceManifest extends ComponentManifest {
@@ -116,7 +128,7 @@ interface DeviceManifest extends ComponentManifest {
116128
* On device, when this field is read, the value of the `i18n` field is
117129
* capped to 1024 bytes (not including the null char).
118130
*/
119-
i18n: Locales;
131+
i18n: Locales<DeviceLocale>;
120132

121133
/**
122134
* Path to the app icon file.
@@ -185,13 +197,30 @@ function makeCommonManifest({
185197
buildId: string;
186198
apiVersion: string;
187199
}): ComponentManifest {
200+
// Ensure the default language is the first listed in the manifest
201+
const locales: Locales<DeviceLocale> = projectConfig.i18n;
202+
const {
203+
[projectConfig.defaultLanguage]: defaultLanguage,
204+
...otherLocales
205+
} = locales;
206+
188207
return {
189208
apiVersion,
190209
buildId,
191210
bundleDate: new Date().toISOString(),
192211
uuid: projectConfig.appUUID,
193212
name: projectConfig.appDisplayName,
194213
requestedPermissions: projectConfig.requestedPermissions,
214+
// FW is case sensitive for locales, it insists on everything being lowercase
215+
// Doing this too early means the casing won't match the developers defaultLanguage
216+
// setting, so do it as late as possible
217+
i18n: lodash.mapKeys(
218+
{
219+
[projectConfig.defaultLanguage]: defaultLanguage,
220+
...otherLocales,
221+
},
222+
(_, locale) => locale.toLowerCase(),
223+
),
195224
};
196225
}
197226

@@ -204,7 +233,7 @@ export function makeDeviceManifest({
204233
buildId: string;
205234
targetDevice: string;
206235
}) {
207-
const locales: Locales = projectConfig.i18n;
236+
const locales: Locales<DeviceLocale> = projectConfig.i18n;
208237
let entryPoint: string | undefined;
209238

210239
return new Transform({
@@ -243,12 +272,6 @@ export function makeDeviceManifest({
243272
},
244273

245274
flush(done) {
246-
// Ensure the default language is the first listed in the manifest
247-
const {
248-
[projectConfig.defaultLanguage]: defaultLanguage,
249-
...otherLocales
250-
} = locales;
251-
252275
if (!entryPoint) {
253276
return done(
254277
new PluginError(
@@ -273,16 +296,6 @@ export function makeDeviceManifest({
273296
apiVersion: deviceApi,
274297
}),
275298
...(supports && { supports }),
276-
// FW is case sensitive for locales, it insists on everything being lowercase
277-
// Doing this too early means the casing won't match the developers defaultLanguage
278-
// setting, so do it as late as possible
279-
i18n: lodash.mapKeys(
280-
{
281-
[projectConfig.defaultLanguage]: defaultLanguage,
282-
...otherLocales,
283-
},
284-
(_, locale) => locale.toLowerCase(),
285-
),
286299
...(projectConfig.appType !== AppType.CLOCKFACE && {
287300
iconFile: projectConfig.iconFile,
288301
wipeColor: projectConfig.wipeColor,

0 commit comments

Comments
 (0)