i18n: Upgrade translations from crowdin (a80a6511). (vpn-settings)
[ProtonMail-WebClient.git] / packages / pack / bin / protonPack.js
blob9d678a60d4dedad2c2aa33cfeed7fab5a45f33b6
1 #!/usr/bin/env node
2 const fs = require('fs').promises;
3 const execa = require('execa');
4 const path = require('path');
5 const { Command } = require('commander');
6 const portfinder = require('portfinder');
7 const chalk = require('chalk');
9 const program = new Command();
11 const { getConfigData, getApi, getConfigFile } = require('../lib/config');
13 const getPort = (basePort) => {
14 portfinder.basePort = basePort;
15 return portfinder.getPortPromise();
18 const writeConfig = async (configFile) => {
19 const configPath = path.resolve('./src/app/config.ts');
20 console.log(`writing file ${configPath}`);
22 await fs.mkdir(path.dirname(configPath), { recursive: true });
23 await fs.writeFile(configPath, configFile);
26 const addGlobalOptions = (program) => {
27 return program
28 .option('--appMode <appMode>', '')
29 .option('--analyze', '')
30 .option('--featureFlags <featureFlags>', '')
31 .option('--api <api>', '', (api) => getApi(api), getApi(''))
32 .option('--sso <sso>', '')
33 .option('--no-api-proxy', '')
34 .option('--webpackOnCaffeine', '', false)
35 .option('--logical', '', false)
36 .option(
37 '--publicPath <publicPath>',
38 '',
39 (publicPath) => {
40 if (publicPath && (!publicPath.startsWith('/') || !publicPath.endsWith('/'))) {
41 throw new Error('--publicPath must start and end with a forward slash');
43 return publicPath || '/';
45 '/'
49 const getWebpackArgs = (options, env, { appData, buildData }) => {
50 const envArgs = {
51 api: appData.api === '/api' ? undefined : appData.api,
52 sso: appData.sso,
53 appMode: options.appMode,
54 publicPath: options.publicPath === '/' ? undefined : options.publicPath,
55 featureFlags: options.featureFlags,
56 writeSri: options.sri ? undefined : options.sri,
57 warningLogs: options.warningLogs,
58 errorLogs: options.errorLogs,
59 overlayWarnings: options.overlayWarnings,
60 overlayErrors: options.overlayErrors,
61 overlayRuntimeErrors: options.overlayRuntimeErrors,
62 logical: Boolean(options.logical),
63 webpackOnCaffeine: Boolean(options.webpackOnCaffeine),
64 analyze: options.analyze,
65 ...buildData,
67 const extraWebpackArgs = env.args.join(' ');
68 const webpackEnvArgs = Object.entries(envArgs)
69 .filter(([, value]) => value !== undefined && value !== '')
70 .reduce((acc, [key, value]) => {
71 if (typeof value === 'boolean') {
72 if (value) {
73 return `${acc} --env ${key}`;
74 } else {
75 return acc;
79 return `${acc} --env ${key}=${value.replace(/ /g, '\\ ')}`;
80 }, '');
82 return `${webpackEnvArgs} ${extraWebpackArgs}`;
85 const commandWithLog = (...args) => {
86 console.log(chalk.cyan(args[0]), `\n`);
87 return execa.command(...args);
90 addGlobalOptions(program.command('build').description('create an optimized production build'))
91 .option('--no-sri', 'disable sri')
92 .action(async (options, env) => {
93 console.log(chalk.magenta('Creating a production build...\n'));
95 const configData = getConfigData(options);
96 await writeConfig(getConfigFile(configData));
98 const webpackArgs = getWebpackArgs(options, env, configData);
99 const outputPath = path.resolve('./dist');
100 await commandWithLog(`rm -rf ${outputPath}`);
101 await commandWithLog(
102 `${require.resolve('webpack-cli/bin/cli.js')} --progress --output-path=${outputPath} ${webpackArgs}`,
104 stdio: 'inherit',
107 await commandWithLog(`${path.resolve(__dirname, `../scripts/validate.sh`)} ${outputPath}`, {
108 stdio: 'inherit',
110 const dotFiles = await Promise.all(
111 ['.htaccess', '.well-known'].map(async (file) => {
112 try {
113 await fs.access(`${outputPath}/${file}`);
114 return file;
115 } catch {}
118 await commandWithLog(`tar -czvf ../webapp-bundle.tar.gz * ${dotFiles.filter(Boolean).join(' ')} 2> /dev/null`, {
119 stdio: 'inherit',
120 cwd: outputPath,
121 shell: true,
125 addGlobalOptions(program.command('dev-server').description('run locally'))
126 .option('--port <port>', '')
127 .option('--warning-logs', 'emit typescript and eslint warnings')
128 .option('--no-error-logs', 'do not emit typescript and eslint errors')
129 .option('--overlay-warnings', 'show a full screen overlay when there are compiler warnings')
130 .option('--overlay-runtime-errors', 'show a full screen overlay when there are runtime errors')
131 .option('--overlay-errors', 'show a full screen overlay when there are compiler errors')
132 .action(async (options, env) => {
133 console.log(chalk.magenta('Starting development server...\n'));
135 const configData = getConfigData(options);
136 await writeConfig(getConfigFile(configData));
138 const port = await getPort(options.port || 8080);
140 const webpackArgs = getWebpackArgs(options, env, configData);
141 await commandWithLog(
142 `${require.resolve('webpack-cli/bin/cli.js')} serve --progress --port=${port} ${webpackArgs}`,
144 stdio: 'inherit',
149 addGlobalOptions(program.command('config').description('write config'))
150 .option('--version <version>', 'override the default (based on the tag) version number')
151 .action(async (options) => {
152 await writeConfig(getConfigFile(getConfigData(options)));
155 program.parse(process.argv);