UNPKG

5.9 kBJavaScriptView Raw
1#!/usr/bin/env node
2// @noflow
3
4/* eslint-disable no-console */
5const fs = require("fs-extra");
6const path = require("path");
7const chalk = require("chalk");
8const yargs = require("yargs");
9const R = require("ramda");
10
11const collectKeys = require("./scripts/collectKeys");
12const fetchBrandConfig = require("./scripts/fetchBrandConfig");
13const fetchSpreadsheet = require("./scripts/fetchSpreadsheet");
14const { getTranslations, getTranslationsGranular } = require("./scripts/getTranslations");
15const missingKeys = require("./scripts/missingKeys");
16const { mapLanguages, mapLanguagesGran } = require("./scripts/mapLanguages");
17
18const command = process.argv[2];
19
20const OUT = path.join(process.cwd(), "data");
21const TKEYS = path.join(OUT, "tkeys.json");
22
23function log(what) {
24 console.log(`${chalk.bold.green(">")} ${what}`);
25}
26
27function error(what) {
28 console.log(`${chalk.bold.red(">")} ${what}`);
29}
30
31// Unstable, not in JS spec
32const sortKeys = obj =>
33 Object.keys(obj)
34 .sort()
35 .reduce((acc, key) => ({ ...acc, [key]: obj[key] }), {});
36
37const resolve = glob => path.join(process.cwd(), glob);
38
39const commands = {
40 keys: "keys",
41 "keys-check": "keys-check",
42 translations: "translations",
43 fetch: "fetch",
44};
45
46const commandOptionsMap = {
47 keys: {
48 "--no-nitro": "nitro",
49 },
50};
51
52log(chalk.bold.green("NITRO"));
53if (!commands[command]) {
54 log("Available commands:");
55 log(` ${chalk.underline.bold("keys")} [...globs] - collects translation keys`);
56 log(` ${chalk.underline("...globs")} - where to collect keys from`);
57 log("");
58 log(` ${chalk.underline.bold("keys-check")} - checks missing translations`);
59 log("");
60 log(` ${chalk.underline.bold("translations")} [--path] - fetches translations`);
61 log(` ${chalk.underline("--path")} (optional) - where to take translations from`);
62 log("");
63 log(` ${chalk.underline.bold("fetch")} - fetches production data`);
64 log("");
65 log("See CLI docs for details at https://github.com/kiwicom/nitrolib");
66}
67
68function keys(globs, shouldExcludeNitroTranslations) {
69 const ours = shouldExcludeNitroTranslations
70 ? []
71 : JSON.parse(fs.readFileSync(path.join(__dirname, "../tkeys.json")));
72
73 const collected = collectKeys(globs.map(resolve));
74
75 const data = sortKeys(R.merge(ours, collected));
76 fs.outputJsonSync(path.join(OUT, "tkeys.json"), data, {
77 spaces: 2,
78 });
79
80 log(
81 `DONE! Collected ${Object.keys(data).length} keys, out of which ${
82 Object.keys(collected).length
83 } are your own.`,
84 );
85}
86
87function keysCheck() {
88 const TFILES = path.join(OUT, "translationsFiles.json");
89 if (!fs.existsSync(TFILES)) {
90 error(
91 "Key checking requires the 'data/translationsFiles.json' file. Run 'nitro translations'.",
92 );
93 process.exit(1);
94 return;
95 }
96
97 if (!fs.existsSync(TKEYS)) {
98 error(
99 "'fetch' requires collecting translation keys to a 'data/tkeys.json' file! This can be done using the 'nitro keys <globs>' command.",
100 );
101 process.exit(1);
102 return;
103 }
104
105 const missing = missingKeys(OUT, TKEYS, TFILES);
106 if (missing.length > 0) {
107 missing.forEach(error);
108 process.exit(1);
109 }
110
111 log("All good.");
112}
113
114const TRANSLATIONS_NEEDS = [
115 path.join(OUT, "brands.json"),
116 path.join(OUT, "languages.json"),
117 path.join(OUT, "countries.json"),
118 path.join(OUT, "tkeys.json"),
119];
120
121const TRANSLATION_GRANS = [
122 path.join(OUT, "brands"),
123 path.join(OUT, "languages"),
124 path.join(OUT, "countries"),
125 path.join(OUT, "tkeys.json"),
126];
127
128function translations(tFile, granular) {
129 if (tFile && !fs.existsSync(tFile)) {
130 error(`Translations not found at '${tFile}'`);
131 process.exit(1);
132 return;
133 }
134 if (!tFile) {
135 try {
136 // eslint-disable-next-line no-unused-vars
137 const kiwiTranslations = require("@kiwicom/translations");
138 } catch (err) {
139 error(`'@kiwicom/translations' is not installed and you don't provide path param!`);
140 process.exit(1);
141 return;
142 }
143 }
144
145 const good = granular
146 ? TRANSLATION_GRANS.reduce((ok, need) => {
147 if (!fs.existsSync(need)) {
148 error(
149 `Task 'translations' requires running the 'keys' and 'fetch' commands first! Missing file: ${need}`,
150 );
151 return false;
152 }
153 return ok;
154 }, true)
155 : TRANSLATIONS_NEEDS.reduce((ok, need) => {
156 if (!fs.existsSync(need)) {
157 error(
158 `Task 'translations' requires running the 'keys' and 'fetch' commands first! Missing file: ${need}`,
159 );
160 return false;
161 }
162 return ok;
163 }, true);
164
165 if (!good) {
166 process.exit(1);
167 return;
168 }
169
170 if (granular) {
171 getTranslationsGranular(TKEYS, tFile)
172 .then(mapLanguagesGran)
173 .then(() => {
174 log("DONE!");
175 })
176 .catch(err => {
177 log(chalk.bold.red("ERROR"));
178 error(err);
179 });
180 } else {
181 getTranslations(TKEYS, tFile)
182 .then(mapLanguages)
183 .then(() => {
184 log("DONE!");
185 })
186 .catch(err => {
187 log(chalk.bold.red("ERROR"));
188 error(err);
189 });
190 }
191}
192
193function fetch(granular) {
194 Promise.all([fetchSpreadsheet(granular), fetchBrandConfig(granular)])
195 .then(() => {
196 log("DONE!");
197 })
198 .catch(err => {
199 log(chalk.bold.red("ERROR"));
200 error(err);
201 });
202}
203
204if (command === commands.keys) {
205 const globs = process.argv.slice(3).filter(a => !commandOptionsMap.keys[a]);
206 // yargs casts options starting with --no- into a `false` flag. --no-nitro -> nitro: false
207 const shouldExcludeNitroTranslations = commandOptionsMap.keys["--no-nitro"] in yargs.argv;
208
209 keys(globs, shouldExcludeNitroTranslations);
210}
211
212if (command === commands["keys-check"]) {
213 keysCheck();
214}
215
216if (command === commands.translations) {
217 translations(yargs.argv.path, yargs.argv.granular);
218}
219
220if (command === commands.fetch) {
221 fetch(yargs.argv.granular);
222}