UNPKG

@artegoser/fluent

Version:

Better Fluent integration for JavaScript

147 lines 5.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Fluent = void 0; const bundle_1 = require("@fluent/bundle"); const langneg_1 = require("@fluent/langneg"); const read_file_1 = require("./read-file"); const logging_warning_handler_1 = require("./warnings/logging-warning-handler"); class Fluent { constructor(options = {}) { this.options = options; this.bundles = (new Set()); this.warningHandler = (options.warningHandler || new logging_warning_handler_1.LoggingWarningHandler()); } async addTranslation(options) { const locales = (Array.isArray(options.locales) ? options.locales : [options.locales]); const sources = await this.handleSources({ source: options.source, filePath: options.filePath, }); const bundle = this.createBundle({ locales, sources, bundleOptions: options.bundleOptions, }); this.bundles.add(bundle); if (!this.defaultBundle || options.isDefault) { this.defaultBundle = bundle; } } translate(localeOrLocales, path, context) { var _a; const locales = (Array.isArray(localeOrLocales) ? localeOrLocales : [localeOrLocales]); const bundles = this.matchBundles(locales); for (const bundle of bundles) { const [messageId, attributeName] = path.split('.', 2); const message = bundle.getMessage(messageId); if (!message) { this.warningHandler.handleWarning({ type: 'translate.bundle.missing-message', locales, path, matchedBundles: bundles, context, messageId, bundle, }); continue; } let pattern; if (attributeName) { pattern = (_a = message.attributes) === null || _a === void 0 ? void 0 : _a[attributeName]; if (!pattern) { this.warningHandler.handleWarning({ type: 'translate.message.missing-attribute', locales, path, matchedBundles: bundles, context, messageId, attributeName, bundle, }); continue; } } else { pattern = (message.value || ''); } return bundle.formatPattern(pattern, context); } this.warningHandler.handleWarning({ type: 'translate.missing-translation', locales, path, matchedBundles: bundles, context, }); return `{${path}}`; } withLocale(localeOrLocales) { return this.translate.bind(this, localeOrLocales); } async handleSources(options) { if (options.filePath && options.source) { throw new Error(`You should specify either "filePath" or "source" ` + `option, not both`); } if (options.source || options.source === '') { return (Array.isArray(options.source) ? options.source.map($source => String($source)) : [String(options.source)]); } else if (options.filePath) { const filePaths = Array.isArray(options.filePath) ? options.filePath : [options.filePath]; const sources = []; for (const filePath of filePaths) { sources.push(await (0, read_file_1.readFile)(filePath)); } return sources; } else { throw new Error(`You should specify "filePath" or "source" option`); } } createBundle(options) { const { locales, sources, bundleOptions = {}, } = options; const bundle = new bundle_1.FluentBundle(locales, bundleOptions); for (const source of sources) { const errors = bundle.addResource(new bundle_1.FluentResource(source), { allowOverrides: true, }); if ((errors === null || errors === void 0 ? void 0 : errors.length) > 0) { for (const error of errors) { console.error(error); } throw new Error(`Failed to parse Fluent resource, please check and ` + `correct the errors printed above`); } } return bundle; } matchBundles(locales) { const availableLocales = new Set(Array.from(this.bundles) .reduce(($locales, bundle) => [ ...$locales, ...bundle.locales ], [])); const matchedLocales = (0, langneg_1.negotiateLanguages)(locales, Array.from(availableLocales)); const matchedBundles = (matchedLocales .map(locale => (Array.from(this.bundles) .find(bundle => bundle.locales.includes(locale)))) .filter(Boolean)); if (this.defaultBundle) { matchedBundles.push(this.defaultBundle); } return new Set(matchedBundles); } } exports.Fluent = Fluent; //# sourceMappingURL=fluent.js.map