npm package diff
Package: @forge/cli-shared
Versions: 5.5.0-next.8-experimental-c7a7d36 - 5.5.0-next.11
File: package/out/service/i18n-resource-bundling-service.js
Index: package/out/service/i18n-resource-bundling-service.js
===================================================================
--- package/out/service/i18n-resource-bundling-service.js
+++ package/out/service/i18n-resource-bundling-service.js
@@ -0,0 +1,97 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.I18nResourceBundlingService = exports.listFilesInI18nResourceBundle = exports.EMPTY_I18N_RESOURCE_BUNDLE = void 0;
+const tslib_1 = require("tslib");
+const tmp_1 = tslib_1.__importDefault(require("tmp"));
+const fs_1 = require("fs");
+const path_1 = require("path");
+const i18n_1 = require("@forge/i18n");
+exports.EMPTY_I18N_RESOURCE_BUNDLE = { exists: false };
+const listFilesInI18nResourceBundle = (i18nResourceBundle) => {
+ if (!i18nResourceBundle.exists) {
+ return [];
+ }
+ return (0, fs_1.readdirSync)(i18nResourceBundle.path).map((fileName) => [fileName, (0, path_1.join)(i18nResourceBundle.path, fileName)]);
+};
+exports.listFilesInI18nResourceBundle = listFilesInI18nResourceBundle;
+class I18nResourceBundlingService {
+ async copyLocaleFilesToBundleDir(bundleDirPath, i18nConfig) {
+ const providedLocaleFilePaths = i18nConfig.resources.map((resource) => [resource.key, (0, path_1.resolve)(resource.path)]);
+ await Promise.all(providedLocaleFilePaths.map(async ([key, providedPath]) => {
+ const dest = (0, path_1.join)(bundleDirPath, `${key}.json`);
+ await fs_1.promises.copyFile(providedPath, dest);
+ }));
+ }
+ async createI18nInfoFile(bundleDirPath, i18nConfig, modules) {
+ const i18nKeys = (0, i18n_1.extractI18nKeysFromModules)(modules);
+ const translationLookup = await this.loadTranslationLookup(i18nConfig);
+ const i18nInfo = this.createI18nInfo(i18nConfig, i18nKeys, translationLookup);
+ const i18nInfoFilePath = (0, path_1.join)(bundleDirPath, i18n_1.I18N_INFO_FILE_NAME);
+ await fs_1.promises.writeFile(i18nInfoFilePath, JSON.stringify(i18nInfo));
+ }
+ createI18nInfo(i18nConfig, i18nKeys, translationLookup) {
+ const translations = {};
+ const localeKeys = Object.keys(translationLookup).sort();
+ i18nKeys.forEach((i18nKey) => {
+ const i18nInfoEntry = localeKeys.reduce((entry, locale) => {
+ const translationValue = (0, i18n_1.getTranslationValue)(translationLookup, i18nKey, locale);
+ if (translationValue) {
+ entry[locale] = translationValue;
+ }
+ return entry;
+ }, {});
+ translations[i18nKey] = i18nInfoEntry;
+ });
+ const defaultLocale = i18nConfig.fallback.default;
+ if (i18nKeys.some((key) => !translations[key][defaultLocale])) {
+ throw new Error(`Default locale '${defaultLocale}' is missing translations for some keys`);
+ }
+ return {
+ translations,
+ config: {
+ locales: localeKeys,
+ fallback: i18nConfig.fallback
+ }
+ };
+ }
+ async loadTranslationLookup(i18nConfig) {
+ const providedLocaleFilePaths = i18nConfig.resources.map((resource) => [
+ resource.key,
+ (0, path_1.resolve)(resource.path)
+ ]);
+ const results = await Promise.all(providedLocaleFilePaths.map(async ([key, providedPath]) => {
+ const file = await fs_1.promises.readFile(providedPath);
+ return [key, JSON.parse(file.toString())];
+ }));
+ return Object.fromEntries(results);
+ }
+ async bundle(modules, i18nConfig) {
+ if (!modules || !i18nConfig) {
+ return exports.EMPTY_I18N_RESOURCE_BUNDLE;
+ }
+ const bundleDirPath = tmp_1.default.dirSync().name;
+ await this.copyLocaleFilesToBundleDir(bundleDirPath, i18nConfig);
+ await this.createI18nInfoFile(bundleDirPath, i18nConfig, modules);
+ return { exists: true, path: bundleDirPath };
+ }
+ createFileAccessor(i18nConfig) {
+ const i18nInfoFileKey = i18n_1.I18N_INFO_FILE_NAME.split('.')[0];
+ return async (resourceKey) => {
+ if (resourceKey === i18nInfoFileKey) {
+ return Buffer.from(JSON.stringify({
+ translations: {},
+ config: {
+ locales: i18nConfig.resources.map((resource) => resource.key),
+ fallback: i18nConfig.fallback
+ }
+ }));
+ }
+ const i18nResource = i18nConfig.resources.find((resource) => resource.key === resourceKey);
+ if (!i18nResource || !(await fs_1.promises.stat((0, path_1.resolve)(i18nResource.path))).isFile()) {
+ return null;
+ }
+ return fs_1.promises.readFile((0, path_1.resolve)(i18nResource.path));
+ };
+ }
+}
+exports.I18nResourceBundlingService = I18nResourceBundlingService;