UNPKG

4.73 kBJavaScriptView Raw
1/* eslint-env node */
2
3/**
4 * Copyright 2015, Yahoo! Inc.
5 * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
6 */
7
8'use strict';
9
10const fs = require('fs');
11const path = require('path');
12const mergeTrees = require('broccoli-merge-trees');
13const { BroccoliMergeFiles } = require('broccoli-merge-files');
14const stringify = require('json-stable-stringify');
15const calculateCacheKeyForTree = require('calculate-cache-key-for-tree');
16
17const buildTranslationTree = require('./lib/broccoli/build-translation-tree');
18const TranslationReducer = require('./lib/broccoli/translation-reducer');
19const findEngine = require('./lib/utils/find-engine');
20const Logger = require('./lib/logger');
21const DEFAULT_CONFIG = require('./lib/default-config');
22
23const OBSOLETE_OPTIONS = ['locales', 'disablePolyfill', 'autoPolyfill'];
24
25module.exports = {
26 name: 'ember-intl',
27 logger: null,
28 configOptions: null,
29 isLocalizationFramework: true,
30
31 included(parent) {
32 this._super.included.apply(this, arguments);
33
34 this.app = this._findHost();
35 const options = this.app.options.intl || {};
36
37 this.logger = new Logger({
38 ui: this.ui,
39 silent: options.silent,
40 });
41
42 this.package = findEngine(parent) || this.project;
43 this.configOptions = this.createOptions(this.app.env, this.app.project);
44 },
45
46 cacheKeyForTree(treeType) {
47 const paths = this.package.paths || this.package.treePaths;
48
49 return calculateCacheKeyForTree(treeType, this, paths ? paths[treeType] : this.package.root);
50 },
51
52 generateTranslationTree(options = {}) {
53 const {
54 outputPath,
55 fallbackLocale,
56 includeLocales,
57 excludeLocales,
58 requiresTranslation,
59 errorOnMissingTranslations,
60 errorOnNamedArgumentMismatch,
61 stripEmptyTranslations,
62 wrapTranslationsWithNamespace,
63 } = this.configOptions;
64
65 const [translationTree, addonsWithTranslations] = buildTranslationTree(
66 this.project,
67 this.configOptions.inputPath,
68 this.treeGenerator
69 );
70
71 return new TranslationReducer([translationTree], {
72 fallbackLocale,
73 includeLocales,
74 excludeLocales,
75 requiresTranslation,
76 errorOnMissingTranslations,
77 errorOnNamedArgumentMismatch,
78 stripEmptyTranslations,
79 wrapTranslationsWithNamespace,
80 verbose: !this.isSilent,
81 filename: options.filename,
82 outputPath: 'outputPath' in options ? options.outputPath : outputPath,
83 addonsWithTranslations,
84 log: (...args) => {
85 return this.logger.log(...args);
86 },
87 warn: (...args) => {
88 return this.logger.warn(...args);
89 },
90 });
91 },
92
93 treeForAddon(tree) {
94 let trees = [tree];
95
96 if (!this.configOptions.publicOnly) {
97 const translationTree = this.generateTranslationTree({
98 outputPath: '',
99 filename(key) {
100 return key;
101 },
102 });
103
104 const flattenedTranslationTree = new BroccoliMergeFiles([translationTree], {
105 outputFileName: 'translations.js',
106 merge: (entries) => {
107 const output = entries.map(([locale, translations]) => {
108 return [locale, JSON.parse(translations)];
109 });
110
111 return 'export default ' + stringify(output);
112 },
113 });
114
115 trees.push(flattenedTranslationTree);
116 }
117
118 return this._super.treeForAddon.call(this, mergeTrees(trees, { overwrite: true }));
119 },
120
121 treeForPublic() {
122 let trees = [];
123
124 if (this.configOptions.publicOnly) {
125 trees.push(this.generateTranslationTree());
126 }
127
128 return mergeTrees(trees, { overwrite: true });
129 },
130
131 readConfig(environment, project) {
132 // NOTE: For ember-cli >= 2.6.0-beta.3, project.configPath() returns absolute path
133 // while older ember-cli versions return path relative to project root
134 let configPath = path.dirname(project.configPath());
135 let config = path.join(configPath, 'ember-intl.js');
136
137 if (!path.isAbsolute(config)) {
138 config = path.join(project.root, config);
139 }
140
141 if (fs.existsSync(config)) {
142 return require(config)(environment);
143 }
144
145 return {};
146 },
147
148 createOptions(environment, project) {
149 const config = {
150 ...DEFAULT_CONFIG,
151 ...this.readConfig(environment, project),
152 };
153
154 if (typeof config.requiresTranslation !== 'function') {
155 this.logger.warn('Configured `requiresTranslation` is not a function. Using default implementation.');
156 config.requiresTranslation = DEFAULT_CONFIG.requiresTranslation;
157 }
158
159 OBSOLETE_OPTIONS.filter((option) => option in config).forEach((option) => {
160 this.logger.warn(`\`${option}\` is obsolete and can be removed from config/ember-intl.js.`);
161 });
162
163 return config;
164 },
165};