@lwrjs/label-module-provider 0.11.0-alpha.9 → 0.11.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.
@@ -28,6 +28,7 @@ __export(exports, {
28
28
  });
29
29
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
30
30
  var import_utils = __toModule(require("./utils.cjs"));
31
+ var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
31
32
  var DEFAULT_DIR = [
32
33
  {
33
34
  dir: "$rootDir/src/labels",
@@ -35,13 +36,18 @@ var DEFAULT_DIR = [
35
36
  }
36
37
  ];
37
38
  var LabelModuleProvider = class {
38
- constructor({provideDefault = false, labelDirs = DEFAULT_DIR}, {config, runtimeEnvironment: {defaultLocale, lwrVersion}}) {
39
+ constructor({provideDefault = false, labelDirs = DEFAULT_DIR}, {config, runtimeEnvironment: {lwrVersion}}) {
39
40
  this.name = "label-module-provider";
40
41
  this.labelDirs = [];
41
42
  this.labelJsonCache = new Map();
42
43
  this.version = lwrVersion;
43
- this.defaultLocale = defaultLocale;
44
+ this.defaultLocale = config.i18n.defaultLocale;
44
45
  this.provideDefault = provideDefault;
46
+ this.i18n = config.i18n;
47
+ this.useI18nFallbacks = !!this.i18n.locales.find((f) => f.fallback);
48
+ if (!this.useI18nFallbacks && labelDirs.length > 1) {
49
+ import_diagnostics.logger.warn(`[label-module-provider] You are using the label provider with a deprecated fallback strategy. Please migrate to the new i18n app-level configuration.`);
50
+ }
45
51
  const {rootDir, contentDir, layoutsDir} = config;
46
52
  labelDirs.forEach((config2) => {
47
53
  const normalizedDir = (0, import_shared_utils.normalizeResourcePath)(config2.dir, {
@@ -56,29 +62,40 @@ var LabelModuleProvider = class {
56
62
  });
57
63
  });
58
64
  }
59
- async getLabelInfo(specifier, locale) {
65
+ async getLabelInfo(specifier, initialLocale) {
60
66
  const labelInfo = (0, import_utils.parseSpecifier)(this.labelDirs, specifier);
61
67
  if (!labelInfo) {
62
68
  return void 0;
63
69
  }
70
+ let rawValue;
71
+ if (this.useI18nFallbacks) {
72
+ rawValue = await (0, import_shared_utils.walkLocaleFallbacks)(initialLocale, this.i18n, async (locale) => {
73
+ return this.getLabelInfoForLocale(labelInfo, locale, false);
74
+ });
75
+ } else {
76
+ rawValue = this.getLabelInfoForLocale(labelInfo, initialLocale, true);
77
+ }
78
+ const {labelReference} = labelInfo;
79
+ const labelValue = !rawValue && this.provideDefault ? labelReference : rawValue;
80
+ return labelValue ? {...labelInfo, labelValue} : void 0;
81
+ }
82
+ getLabelInfoForLocale(labelInfo, locale, legacyFallbacks) {
64
83
  const {dir, labelReference} = labelInfo;
65
84
  const cacheKey = `${dir}|${locale}`;
66
85
  let labelJson = {};
67
86
  if (this.labelJsonCache.has(cacheKey)) {
68
87
  labelJson = this.labelJsonCache.get(cacheKey);
69
88
  } else {
70
- let fsLabels = (0, import_utils.getLabels)(dir, locale);
71
- if (!fsLabels && locale !== this.defaultLocale) {
72
- fsLabels = (0, import_utils.getLabels)(dir, this.defaultLocale);
89
+ let fsLabels = (0, import_utils.getLabels)(dir, locale, legacyFallbacks);
90
+ if (legacyFallbacks && !fsLabels && locale !== this.defaultLocale) {
91
+ fsLabels = (0, import_utils.getLabels)(dir, this.defaultLocale, legacyFallbacks);
73
92
  }
74
93
  labelJson = fsLabels || labelJson;
75
94
  this.labelJsonCache.set(cacheKey, labelJson);
76
95
  }
77
96
  const [namespace, labelName] = labelReference.split(".");
78
97
  const namespacedLabels = labelJson[namespace] || {};
79
- const rawValue = namespacedLabels[labelName] || labelJson[labelReference];
80
- const labelValue = !rawValue && this.provideDefault ? labelReference : rawValue;
81
- return labelValue ? {...labelInfo, labelValue} : void 0;
98
+ return namespacedLabels[labelName] || labelJson[labelReference];
82
99
  }
83
100
  async getModuleEntry({specifier}, runtimeParams = {}) {
84
101
  const locale = runtimeParams.locale && runtimeParams.locale !== "*" ? runtimeParams.locale : this.defaultLocale;
@@ -33,6 +33,7 @@ var import_fs = __toModule(require("fs"));
33
33
  var import_path = __toModule(require("path"));
34
34
  var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
35
35
  var import_validation = __toModule(require("./validation.cjs"));
36
+ var import_diagnostics2 = __toModule(require("@lwrjs/diagnostics"));
36
37
  function isValidLocaleFormat(locale) {
37
38
  return /^[A-Za-z]{2}([_-][A-Za-z]{2})?$/.test(locale);
38
39
  }
@@ -46,13 +47,13 @@ function parseSpecifier(allDirs, specifier) {
46
47
  const fileType = (file ? (0, import_path.extname)(file) : ".js").substr(1);
47
48
  return {labelReference, fileType, ...dirConfig};
48
49
  }
49
- function getLabels(labelDir, locale) {
50
+ function getLabels(labelDir, locale, legacyFallbacks) {
50
51
  const localePath = `${labelDir}/${locale}.json`;
51
52
  try {
52
53
  if ((0, import_fs.existsSync)(localePath)) {
53
54
  return (0, import_validation.validateAndParse)(localePath);
54
55
  }
55
- if (locale.length > 2) {
56
+ if (legacyFallbacks && locale.length > 2) {
56
57
  const lang = locale.substr(0, 2);
57
58
  const country = locale.substr(3);
58
59
  const altLocale = locale[2] === "-" ? `${lang}_${country}` : `${lang}-${country}`;
@@ -72,7 +73,7 @@ function getLabels(labelDir, locale) {
72
73
  description: import_diagnostics.descriptions.UNRESOLVABLE.LABEL_MODULE(localePath, e.message)
73
74
  }, import_diagnostics.LwrUnresolvableError);
74
75
  }
75
- console.error(diagnosticError);
76
+ import_diagnostics2.logger.error(diagnosticError);
76
77
  }
77
78
  return void 0;
78
79
  }
@@ -1,4 +1,4 @@
1
- import type { AbstractModuleId, ModuleCompiled, ModuleEntry, ModuleProvider, ProviderContext, RuntimeParams } from '@lwrjs/types';
1
+ import type { AbstractModuleId, I18NConfig, ModuleCompiled, ModuleEntry, ModuleProvider, ProviderContext, RuntimeParams } from '@lwrjs/types';
2
2
  import { LabelDirConfig, LabelProviderOptions } from './utils.js';
3
3
  export default class LabelModuleProvider implements ModuleProvider {
4
4
  name: string;
@@ -6,9 +6,12 @@ export default class LabelModuleProvider implements ModuleProvider {
6
6
  defaultLocale: string;
7
7
  provideDefault: boolean;
8
8
  labelDirs: LabelDirConfig[];
9
+ i18n: I18NConfig;
10
+ useI18nFallbacks: boolean;
9
11
  private labelJsonCache;
10
- constructor({ provideDefault, labelDirs }: LabelProviderOptions, { config, runtimeEnvironment: { defaultLocale, lwrVersion } }: ProviderContext);
12
+ constructor({ provideDefault, labelDirs }: LabelProviderOptions, { config, runtimeEnvironment: { lwrVersion } }: ProviderContext);
11
13
  private getLabelInfo;
14
+ private getLabelInfoForLocale;
12
15
  getModuleEntry({ specifier }: AbstractModuleId, runtimeParams?: RuntimeParams): Promise<ModuleEntry | undefined>;
13
16
  getModule({ specifier, namespace, name }: AbstractModuleId, runtimeParams?: RuntimeParams): Promise<ModuleCompiled | undefined>;
14
17
  }
package/build/es/index.js CHANGED
@@ -1,5 +1,6 @@
1
- import { hashContent, normalizeResourcePath } from '@lwrjs/shared-utils';
2
- import { getLabels, generateModule, isValidLocaleFormat, parseSpecifier, } from './utils.js';
1
+ import { hashContent, normalizeResourcePath, walkLocaleFallbacks } from '@lwrjs/shared-utils';
2
+ import { generateModule, isValidLocaleFormat, parseSpecifier, getLabels, } from './utils.js';
3
+ import { logger } from '@lwrjs/diagnostics';
3
4
  const DEFAULT_DIR = [
4
5
  {
5
6
  dir: '$rootDir/src/labels',
@@ -7,13 +8,18 @@ const DEFAULT_DIR = [
7
8
  },
8
9
  ];
9
10
  export default class LabelModuleProvider {
10
- constructor({ provideDefault = false, labelDirs = DEFAULT_DIR }, { config, runtimeEnvironment: { defaultLocale, lwrVersion } }) {
11
+ constructor({ provideDefault = false, labelDirs = DEFAULT_DIR }, { config, runtimeEnvironment: { lwrVersion } }) {
11
12
  this.name = 'label-module-provider';
12
13
  this.labelDirs = [];
13
14
  this.labelJsonCache = new Map(); // TODO: file watcher
14
15
  this.version = lwrVersion;
15
- this.defaultLocale = defaultLocale;
16
+ this.defaultLocale = config.i18n.defaultLocale;
16
17
  this.provideDefault = provideDefault;
18
+ this.i18n = config.i18n;
19
+ this.useI18nFallbacks = !!this.i18n.locales.find((f) => f.fallback);
20
+ if (!this.useI18nFallbacks && labelDirs.length > 1) {
21
+ logger.warn(`[label-module-provider] You are using the label provider with a deprecated fallback strategy. Please migrate to the new i18n app-level configuration.`);
22
+ }
17
23
  // normalize the label directories
18
24
  const { rootDir, contentDir, layoutsDir } = config;
19
25
  labelDirs.forEach((config) => {
@@ -30,13 +36,30 @@ export default class LabelModuleProvider {
30
36
  });
31
37
  });
32
38
  }
33
- async getLabelInfo(specifier, locale) {
39
+ async getLabelInfo(specifier, initialLocale) {
34
40
  // Check if this provider handles given specifier package/prefix
35
41
  // Modules handled by this provider have specifiers in this form: "{package}/{labelReference}"
36
42
  const labelInfo = parseSpecifier(this.labelDirs, specifier);
37
43
  if (!labelInfo) {
38
44
  return undefined;
39
45
  }
46
+ // If the app has defined any fallbacks in the config. Assume this is the fallback precedence we should follow.
47
+ let rawValue;
48
+ if (this.useI18nFallbacks) {
49
+ rawValue = await walkLocaleFallbacks(initialLocale, this.i18n, async (locale) => {
50
+ return this.getLabelInfoForLocale(labelInfo, locale, false);
51
+ });
52
+ }
53
+ // Other wise use the default fallbacks for backward compatibility
54
+ else {
55
+ rawValue = this.getLabelInfoForLocale(labelInfo, initialLocale, true);
56
+ }
57
+ // If provideDefault is on, and the label is missing, return the label reference/key
58
+ const { labelReference } = labelInfo;
59
+ const labelValue = !rawValue && this.provideDefault ? labelReference : rawValue;
60
+ return labelValue ? { ...labelInfo, labelValue: labelValue } : undefined;
61
+ }
62
+ getLabelInfoForLocale(labelInfo, locale, legacyFallbacks) {
40
63
  const { dir, labelReference } = labelInfo;
41
64
  // Fetch the label JSON from the cache or file system
42
65
  const cacheKey = `${dir}|${locale}`;
@@ -47,10 +70,10 @@ export default class LabelModuleProvider {
47
70
  }
48
71
  else {
49
72
  // Cache miss, read from fs
50
- let fsLabels = getLabels(dir, locale);
73
+ let fsLabels = getLabels(dir, locale, legacyFallbacks);
51
74
  // Fallback to default locale
52
- if (!fsLabels && locale !== this.defaultLocale) {
53
- fsLabels = getLabels(dir, this.defaultLocale);
75
+ if (legacyFallbacks && !fsLabels && locale !== this.defaultLocale) {
76
+ fsLabels = getLabels(dir, this.defaultLocale, legacyFallbacks);
54
77
  }
55
78
  // Set cache
56
79
  labelJson = fsLabels || labelJson;
@@ -61,9 +84,7 @@ export default class LabelModuleProvider {
61
84
  // If provideDefault is on, and the label is missing, return the label reference/key
62
85
  const [namespace, labelName] = labelReference.split('.');
63
86
  const namespacedLabels = (labelJson[namespace] || {});
64
- const rawValue = namespacedLabels[labelName] || labelJson[labelReference]; // nested or flat structure
65
- const labelValue = !rawValue && this.provideDefault ? labelReference : rawValue;
66
- return labelValue ? { ...labelInfo, labelValue: labelValue } : undefined;
87
+ return namespacedLabels[labelName] || labelJson[labelReference]; // nested or flat structure
67
88
  }
68
89
  async getModuleEntry({ specifier }, runtimeParams = {}) {
69
90
  const locale = (runtimeParams.locale && runtimeParams.locale !== '*' ? runtimeParams.locale : this.defaultLocale);
@@ -6,14 +6,14 @@ export interface LabelProviderOptions {
6
6
  provideDefault: boolean;
7
7
  labelDirs: LabelDirConfig[];
8
8
  }
9
- interface LabelKeyInfo extends LabelDirConfig {
9
+ export interface LabelKeyInfo extends LabelDirConfig {
10
10
  labelReference: string;
11
11
  fileType: string;
12
12
  }
13
13
  export interface LabelInfo extends LabelKeyInfo {
14
14
  labelValue: string;
15
15
  }
16
- type LabelEntry = {
16
+ export type LabelEntry = {
17
17
  [key: string]: string;
18
18
  };
19
19
  export type LabelMap = {
@@ -45,8 +45,9 @@ export declare function parseSpecifier(allDirs: LabelDirConfig[], specifier: str
45
45
  *
46
46
  * @param labelDir - The directory which contains the label JSON files
47
47
  * @param locale - The locale to retrieve
48
+ * @param legacyFallbacks - Use the legacy fallback logic
48
49
  */
49
- export declare function getLabels(labelDir: string, locale: string): LabelMap | undefined;
50
+ export declare function getLabels(labelDir: string, locale: string, legacyFallbacks: boolean): LabelMap | undefined;
50
51
  /**
51
52
  * Generate a module string which fulfills a label request
52
53
  *
@@ -54,5 +55,4 @@ export declare function getLabels(labelDir: string, locale: string): LabelMap |
54
55
  * @param fileType - The module file type: html, css or js
55
56
  */
56
57
  export declare function generateModule(label: string): string;
57
- export {};
58
58
  //# sourceMappingURL=utils.d.ts.map
package/build/es/utils.js CHANGED
@@ -2,6 +2,7 @@ import { existsSync } from 'fs';
2
2
  import { extname } from 'path';
3
3
  import { createSingleDiagnosticError, descriptions, LwrUnresolvableError } from '@lwrjs/diagnostics';
4
4
  import { validateAndParse } from './validation.js';
5
+ import { logger } from '@lwrjs/diagnostics';
5
6
  /**
6
7
  * Validate a locale string against these rules:
7
8
  * - first 2 characters are a language code
@@ -42,8 +43,9 @@ export function parseSpecifier(allDirs, specifier) {
42
43
  *
43
44
  * @param labelDir - The directory which contains the label JSON files
44
45
  * @param locale - The locale to retrieve
46
+ * @param legacyFallbacks - Use the legacy fallback logic
45
47
  */
46
- export function getLabels(labelDir, locale) {
48
+ export function getLabels(labelDir, locale, legacyFallbacks) {
47
49
  // Check for locale JSON file (eg: en_US.json)
48
50
  const localePath = `${labelDir}/${locale}.json`;
49
51
  try {
@@ -51,7 +53,7 @@ export function getLabels(labelDir, locale) {
51
53
  return validateAndParse(localePath);
52
54
  }
53
55
  // If the locale contains a country code, try some fallbacks
54
- if (locale.length > 2) {
56
+ if (legacyFallbacks && locale.length > 2) {
55
57
  const lang = locale.substr(0, 2);
56
58
  const country = locale.substr(3);
57
59
  // Check for a different language/country separator (_ vs -)
@@ -74,7 +76,7 @@ export function getLabels(labelDir, locale) {
74
76
  description: descriptions.UNRESOLVABLE.LABEL_MODULE(localePath, e.message),
75
77
  }, LwrUnresolvableError);
76
78
  }
77
- console.error(diagnosticError);
79
+ logger.error(diagnosticError);
78
80
  }
79
81
  return undefined;
80
82
  }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.11.0-alpha.9",
7
+ "version": "0.11.1",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -30,15 +30,15 @@
30
30
  "build/**/*.d.ts"
31
31
  ],
32
32
  "dependencies": {
33
- "@lwrjs/diagnostics": "0.11.0-alpha.9",
34
- "@lwrjs/shared-utils": "0.11.0-alpha.9",
33
+ "@lwrjs/diagnostics": "0.11.1",
34
+ "@lwrjs/shared-utils": "0.11.1",
35
35
  "ajv": "6.12.6"
36
36
  },
37
37
  "devDependencies": {
38
- "@lwrjs/types": "0.11.0-alpha.9"
38
+ "@lwrjs/types": "0.11.1"
39
39
  },
40
40
  "engines": {
41
41
  "node": ">=16.0.0"
42
42
  },
43
- "gitHead": "bc50e3f828be56ebdd2f8206cafe8158ab722470"
43
+ "gitHead": "b7c40fdcd86635dd4e368c0a2e91c5d3374c0fcf"
44
44
  }