@artegoser/fluent
Version:
Better Fluent integration for JavaScript
147 lines • 5.62 kB
JavaScript
;
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