lighthouse 13.6.0-dev.20261027 → 13.6.0-dev.20261028
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/core/config/config-helpers.js +9 -0
- package/core/config/config-plugin.d.ts +7 -0
- package/core/config/config-plugin.js +49 -0
- package/core/config/config.js +9 -0
- package/core/config/filters.js +1 -0
- package/core/index.d.ts +2 -0
- package/core/index.js +2 -0
- package/core/lib/i18n/i18n.d.ts +2 -0
- package/core/lib/i18n/i18n.js +8 -2
- package/package.json +1 -1
- package/shared/localization/format.js +4 -1
- package/types/config.d.ts +6 -1
|
@@ -349,6 +349,11 @@ async function mergePlugins(config, configDir, flags) {
|
|
|
349
349
|
const flagPlugins = flags?.plugins || [];
|
|
350
350
|
const pluginNames = new Set([...configPlugins, ...flagPlugins]);
|
|
351
351
|
|
|
352
|
+
const configLocales = config.locales;
|
|
353
|
+
if (configLocales) {
|
|
354
|
+
delete config.locales;
|
|
355
|
+
}
|
|
356
|
+
|
|
352
357
|
for (const pluginName of pluginNames) {
|
|
353
358
|
validation.assertValidPluginName(config, pluginName);
|
|
354
359
|
|
|
@@ -362,6 +367,10 @@ async function mergePlugins(config, configDir, flags) {
|
|
|
362
367
|
config = mergeConfigFragment(config, pluginJson);
|
|
363
368
|
}
|
|
364
369
|
|
|
370
|
+
if (configLocales) {
|
|
371
|
+
config.locales = mergeConfigFragment(config.locales, configLocales);
|
|
372
|
+
}
|
|
373
|
+
|
|
365
374
|
return config;
|
|
366
375
|
}
|
|
367
376
|
|
|
@@ -34,6 +34,13 @@ declare class ConfigPlugin {
|
|
|
34
34
|
* @return {Record<string, LH.Config.GroupJson>|undefined}
|
|
35
35
|
*/
|
|
36
36
|
static _parseGroups(groupsJson: unknown, pluginName: string): Record<string, LH.Config.GroupJson> | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Extract and validate locales JSON added by the plugin.
|
|
39
|
+
* @param {unknown} localesJson
|
|
40
|
+
* @param {string} pluginName
|
|
41
|
+
* @return {NonNullable<LH.Config['locales']>|undefined}
|
|
42
|
+
*/
|
|
43
|
+
static _parseLocales(localesJson: unknown, pluginName: string): NonNullable<LH.Config["locales"]> | undefined;
|
|
37
44
|
/**
|
|
38
45
|
* Extracts and validates a config from the provided plugin input, throwing
|
|
39
46
|
* if it deviates from the expected object shape.
|
|
@@ -215,6 +215,53 @@ class ConfigPlugin {
|
|
|
215
215
|
return parsedGroupsJson;
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Extract and validate locales JSON added by the plugin.
|
|
220
|
+
* @param {unknown} localesJson
|
|
221
|
+
* @param {string} pluginName
|
|
222
|
+
* @return {NonNullable<LH.Config['locales']>|undefined}
|
|
223
|
+
*/
|
|
224
|
+
static _parseLocales(localesJson, pluginName) {
|
|
225
|
+
if (localesJson === undefined) {
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (!isObjectOfUnknownProperties(localesJson)) {
|
|
230
|
+
throw new Error(`${pluginName} locales json is not defined as an object.`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** @type {NonNullable<LH.Config['locales']>} */
|
|
234
|
+
const parsedLocalesJson = {};
|
|
235
|
+
for (const [locale, localeMessagesJson] of Object.entries(localesJson)) {
|
|
236
|
+
if (!isObjectOfUnknownProperties(localeMessagesJson)) {
|
|
237
|
+
throw new Error(`${pluginName} has a locale (${locale}) not defined as an object.`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** @type {Record<string, {message: string}>} */
|
|
241
|
+
const parsedMessages = {};
|
|
242
|
+
for (const [icuMessageId, messageEntry] of Object.entries(localeMessagesJson)) {
|
|
243
|
+
if (!isObjectOfUnknownProperties(messageEntry)) {
|
|
244
|
+
throw new Error(
|
|
245
|
+
`${pluginName} has a locale message (${icuMessageId}) not defined as an object.`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const {message, ...invalidRest} = messageEntry;
|
|
250
|
+
assertNoExcessProperties(invalidRest, pluginName, 'locale message');
|
|
251
|
+
|
|
252
|
+
if (typeof message !== 'string') {
|
|
253
|
+
throw new Error(`${pluginName} has an invalid locale message (${icuMessageId}).`);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
parsedMessages[icuMessageId] = {message};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
parsedLocalesJson[/** @type {LH.Locale} */ (locale)] = parsedMessages;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return parsedLocalesJson;
|
|
263
|
+
}
|
|
264
|
+
|
|
218
265
|
/**
|
|
219
266
|
* Extracts and validates a config from the provided plugin input, throwing
|
|
220
267
|
* if it deviates from the expected object shape.
|
|
@@ -233,6 +280,7 @@ class ConfigPlugin {
|
|
|
233
280
|
audits: pluginAuditsJson,
|
|
234
281
|
category: pluginCategoryJson,
|
|
235
282
|
groups: pluginGroupsJson,
|
|
283
|
+
locales: pluginLocalesJson,
|
|
236
284
|
...invalidRest
|
|
237
285
|
} = pluginJson;
|
|
238
286
|
|
|
@@ -244,6 +292,7 @@ class ConfigPlugin {
|
|
|
244
292
|
[pluginName]: ConfigPlugin._parseCategory(pluginCategoryJson, pluginName),
|
|
245
293
|
},
|
|
246
294
|
groups: ConfigPlugin._parseGroups(pluginGroupsJson, pluginName),
|
|
295
|
+
locales: ConfigPlugin._parseLocales(pluginLocalesJson, pluginName),
|
|
247
296
|
};
|
|
248
297
|
}
|
|
249
298
|
}
|
package/core/config/config.js
CHANGED
|
@@ -163,6 +163,7 @@ async function resolveArtifactsToDefns(artifacts, configDir) {
|
|
|
163
163
|
id: artifactJson.id,
|
|
164
164
|
gatherer,
|
|
165
165
|
dependencies: resolveArtifactDependencies(artifactJson, gatherer, artifactDefnsBySymbol),
|
|
166
|
+
alwaysGather: artifactJson.alwaysGather,
|
|
166
167
|
};
|
|
167
168
|
|
|
168
169
|
const symbol = artifact.gatherer.instance.meta.symbol;
|
|
@@ -229,6 +230,14 @@ async function initializeConfig(gatherMode, config, flags = {}) {
|
|
|
229
230
|
configWorkingCopy = resolveExtensions(configWorkingCopy);
|
|
230
231
|
configWorkingCopy = await mergePlugins(configWorkingCopy, configDir, flags);
|
|
231
232
|
|
|
233
|
+
if (configWorkingCopy.locales) {
|
|
234
|
+
for (const [locale, lhlMessages] of Object.entries(configWorkingCopy.locales)) {
|
|
235
|
+
if (lhlMessages) {
|
|
236
|
+
format.registerLocaleData(/** @type {LH.Locale} */ (locale), lhlMessages);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
232
241
|
const settings = resolveSettings(configWorkingCopy.settings || {}, flags);
|
|
233
242
|
overrideSettingsForGatherMode(settings, gatherMode);
|
|
234
243
|
overrideThrottlingWindows(settings);
|
package/core/config/filters.js
CHANGED
|
@@ -69,6 +69,7 @@ function filterArtifactsByAvailableAudits(artifacts, audits) {
|
|
|
69
69
|
/** @type {Set<string>} */
|
|
70
70
|
const artifactIdsToKeep = new Set([
|
|
71
71
|
...filterResistantArtifactIds,
|
|
72
|
+
...artifacts.filter(artifact => artifact.alwaysGather).map(artifact => artifact.id),
|
|
72
73
|
...audits.flatMap(audit => audit.implementation.meta.requiredArtifacts),
|
|
73
74
|
]);
|
|
74
75
|
|
package/core/index.d.ts
CHANGED
|
@@ -68,6 +68,8 @@ export function auditFlowArtifacts(flowArtifacts: LH.UserFlow.FlowArtifacts, con
|
|
|
68
68
|
}>;
|
|
69
69
|
export function getAuditList(): string[];
|
|
70
70
|
export const traceCategories: string[];
|
|
71
|
+
import * as i18n from './lib/i18n/i18n.js';
|
|
71
72
|
import * as LH from '../types/lh.js';
|
|
72
73
|
import { UserFlow } from './user-flow.js';
|
|
74
|
+
export { i18n };
|
|
73
75
|
//# sourceMappingURL=index.d.ts.map
|
package/core/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import {ReportGenerator} from '../report/generator/report-generator.js';
|
|
|
11
11
|
import {startTimespanGather} from './gather/timespan-runner.js';
|
|
12
12
|
import {snapshotGather} from './gather/snapshot-runner.js';
|
|
13
13
|
import {navigationGather} from './gather/navigation-runner.js';
|
|
14
|
+
import * as i18n from './lib/i18n/i18n.js';
|
|
14
15
|
import * as LH from '../types/lh.js';
|
|
15
16
|
|
|
16
17
|
/*
|
|
@@ -131,4 +132,5 @@ export {
|
|
|
131
132
|
auditFlowArtifacts,
|
|
132
133
|
getAuditList,
|
|
133
134
|
traceCategories,
|
|
135
|
+
i18n,
|
|
134
136
|
};
|
package/core/lib/i18n/i18n.d.ts
CHANGED
|
@@ -77,4 +77,6 @@ export function createIcuMessageFn(filename: string, fileStrings?: Record<string
|
|
|
77
77
|
* @return {value is string|LH.IcuMessage}
|
|
78
78
|
*/
|
|
79
79
|
export function isStringOrIcuMessage(value: unknown): value is string | LH.IcuMessage;
|
|
80
|
+
import { registerLocaleData } from '../../../shared/localization/format.js';
|
|
81
|
+
export { registerLocaleData };
|
|
80
82
|
//# sourceMappingURL=i18n.d.ts.map
|
package/core/lib/i18n/i18n.js
CHANGED
|
@@ -9,9 +9,14 @@ import url from 'url';
|
|
|
9
9
|
|
|
10
10
|
import log from 'lighthouse-logger';
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
getAvailableLocales,
|
|
14
|
+
isIcuMessage,
|
|
15
|
+
formatMessage,
|
|
16
|
+
registerLocaleData,
|
|
17
|
+
DEFAULT_LOCALE,
|
|
18
|
+
} from '../../../shared/localization/format.js';
|
|
13
19
|
import {LH_ROOT} from '../../../shared/root.js';
|
|
14
|
-
import {isIcuMessage, formatMessage, DEFAULT_LOCALE} from '../../../shared/localization/format.js';
|
|
15
20
|
|
|
16
21
|
const UIStrings = {
|
|
17
22
|
/** Used to show the duration in milliseconds that something lasted. The `{timeInMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 63 ms) */
|
|
@@ -232,4 +237,5 @@ export {
|
|
|
232
237
|
lookupLocale,
|
|
233
238
|
createIcuMessageFn,
|
|
234
239
|
isStringOrIcuMessage,
|
|
240
|
+
registerLocaleData,
|
|
235
241
|
};
|
package/package.json
CHANGED
|
@@ -466,7 +466,10 @@ function getAvailableLocales() {
|
|
|
466
466
|
* @param {import('./locales').LhlMessages} lhlMessages
|
|
467
467
|
*/
|
|
468
468
|
function registerLocaleData(locale, lhlMessages) {
|
|
469
|
-
LOCALE_MESSAGES[locale] =
|
|
469
|
+
LOCALE_MESSAGES[locale] = {
|
|
470
|
+
...LOCALE_MESSAGES[locale],
|
|
471
|
+
...lhlMessages,
|
|
472
|
+
};
|
|
470
473
|
}
|
|
471
474
|
|
|
472
475
|
/**
|
package/types/config.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import {Audit} from '../core/audits/audit.js';
|
|
9
|
-
import {SharedFlagsSettings, ConfigSettings} from './lhr/settings.js';
|
|
9
|
+
import {SharedFlagsSettings, ConfigSettings, Locale} from './lhr/settings.js';
|
|
10
10
|
import Gatherer from './gatherer.js';
|
|
11
11
|
import {IcuMessage} from './lhr/i18n.js';
|
|
12
12
|
import Result from './lhr/lhr.js';
|
|
@@ -26,6 +26,7 @@ interface Config {
|
|
|
26
26
|
categories?: Record<string, Config.CategoryJson> | null;
|
|
27
27
|
groups?: Record<string, Config.GroupJson> | null;
|
|
28
28
|
plugins?: Array<string>;
|
|
29
|
+
locales?: Partial<Record<Locale, Record<string, {message: string}>>> | null;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
declare namespace Config {
|
|
@@ -43,6 +44,7 @@ declare namespace Config {
|
|
|
43
44
|
interface ArtifactJson {
|
|
44
45
|
id: string;
|
|
45
46
|
gatherer: GathererJson;
|
|
47
|
+
alwaysGather?: boolean;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
type GathererJson = {
|
|
@@ -94,6 +96,7 @@ declare namespace Config {
|
|
|
94
96
|
dependencies?: TDependencies extends Gatherer.DefaultDependenciesKey ?
|
|
95
97
|
undefined :
|
|
96
98
|
Record<Exclude<TDependencies, Gatherer.DefaultDependenciesKey>, {id: string}>;
|
|
99
|
+
alwaysGather?: boolean;
|
|
97
100
|
}
|
|
98
101
|
|
|
99
102
|
type ArtifactDefnExpander<TDependencies extends Gatherer.DependencyKey> =
|
|
@@ -136,6 +139,8 @@ declare namespace Config {
|
|
|
136
139
|
category: Config.Category;
|
|
137
140
|
/** Optionally provide more groups in addition to those specified by the base config. */
|
|
138
141
|
groups?: Record<string, Config.GroupJson>;
|
|
142
|
+
/** Optionally provide locale messages for translating plugin strings. */
|
|
143
|
+
locales?: Partial<Record<Locale, Record<string, {message: string}>>>;
|
|
139
144
|
}
|
|
140
145
|
|
|
141
146
|
type Merge = {
|