UNPKG

4.65 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 requiresTranslation,
57 errorOnMissingTranslations,
58 errorOnNamedArgumentMismatch,
59 stripEmptyTranslations,
60 wrapTranslationsWithNamespace,
61 } = this.configOptions;
62
63 const [translationTree, addonsWithTranslations] = buildTranslationTree(
64 this.project,
65 this.configOptions.inputPath,
66 this.treeGenerator
67 );
68
69 return new TranslationReducer([translationTree], {
70 fallbackLocale,
71 requiresTranslation,
72 errorOnMissingTranslations,
73 errorOnNamedArgumentMismatch,
74 stripEmptyTranslations,
75 wrapTranslationsWithNamespace,
76 verbose: !this.isSilent,
77 filename: options.filename,
78 outputPath: 'outputPath' in options ? options.outputPath : outputPath,
79 addonsWithTranslations,
80 log: (...args) => {
81 return this.logger.log(...args);
82 },
83 warn: (...args) => {
84 return this.logger.warn(...args);
85 },
86 });
87 },
88
89 treeForAddon(tree) {
90 let trees = [tree];
91
92 if (!this.configOptions.publicOnly) {
93 const translationTree = this.generateTranslationTree({
94 outputPath: '',
95 filename(key) {
96 return key;
97 },
98 });
99
100 const flattenedTranslationTree = new BroccoliMergeFiles([translationTree], {
101 outputFileName: 'translations.js',
102 merge: (entries) => {
103 const output = entries.map(([locale, translations]) => {
104 return [locale, JSON.parse(translations)];
105 });
106
107 return 'export default ' + stringify(output);
108 },
109 });
110
111 trees.push(flattenedTranslationTree);
112 }
113
114 return this._super.treeForAddon.call(this, mergeTrees(trees, { overwrite: true }));
115 },
116
117 treeForPublic() {
118 let trees = [];
119
120 if (this.configOptions.publicOnly) {
121 trees.push(this.generateTranslationTree());
122 }
123
124 return mergeTrees(trees, { overwrite: true });
125 },
126
127 readConfig(environment, project) {
128 // NOTE: For ember-cli >= 2.6.0-beta.3, project.configPath() returns absolute path
129 // while older ember-cli versions return path relative to project root
130 let configPath = path.dirname(project.configPath());
131 let config = path.join(configPath, 'ember-intl.js');
132
133 if (!path.isAbsolute(config)) {
134 config = path.join(project.root, config);
135 }
136
137 if (fs.existsSync(config)) {
138 return require(config)(environment);
139 }
140
141 return {};
142 },
143
144 createOptions(environment, project) {
145 const config = {
146 ...DEFAULT_CONFIG,
147 ...this.readConfig(environment, project),
148 };
149
150 if (typeof config.requiresTranslation !== 'function') {
151 this.logger.warn('Configured `requiresTranslation` is not a function. Using default implementation.');
152 config.requiresTranslation = DEFAULT_CONFIG.requiresTranslation;
153 }
154
155 OBSOLETE_OPTIONS.filter((option) => option in config).forEach((option) => {
156 this.logger.warn(`\`${option}\` is obsolete and can be removed from config/ember-intl.js.`);
157 });
158
159 return config;
160 },
161};