"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const config_1 = require("@expo/config"); const chalk_1 = __importDefault(require("chalk")); const deep_diff_1 = __importDefault(require("deep-diff")); const fs_1 = __importDefault(require("fs")); const paths_1 = require("./paths"); // https://stackoverflow.com/a/51319962/4047926 function colorizeKeys(json) { if (typeof json !== 'string') { json = JSON.stringify(json, undefined, 2); } return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { if (/--pop/.test(match)) { // Bacon: If a key is prefixed with --pop it'll be colored red return chalk_1.default.red.bold(match.substring(0, match.length - 7) + '":'); } else if (/--push/.test(match)) { // Bacon: If a key is prefixed with --push it'll be colored green return chalk_1.default.green.bold(match.substring(0, match.length - 8) + '":'); } else if (/^"/.test(match)) { if (/:$/.test(match)) { return chalk_1.default.magenta(match); } else { return chalk_1.default.blueBright(match); } } else if (/true|false/.test(match)) { return chalk_1.default.cyanBright(match); } else if (/null/.test(match)) { return chalk_1.default.cyan(match); } return chalk_1.default.green(match); }); } function logHeader(title) { console.log(chalk_1.default.hidden('<details><summary>\n') + chalk_1.default.bgGreen.black(`[${title}]\n`) + chalk_1.default.hidden('</summary>\n')); } function logMdHelper(...messages) { console.log(chalk_1.default.hidden(...messages)); } function logFooter() { logMdHelper('</details>'); } // Log the main risky parts of webpack.config function logWebpackConfigComponents(webpackConfig) { logHeader('Webpack Info'); const { mode, resolve: { alias = {} } = {}, entry, devtool, context, devServer: { https, hot, contentBase } = {}, } = webpackConfig; // console.log('WEBPACK', JSON.stringify(webpackConfig, null, 2)); logMdHelper('```json'); console.log(colorizeKeys({ mode, devtool, entry, context, https, hot, contentBase, alias, })); logMdHelper('```'); logFooter(); } function logStaticsAsync(env) { return __awaiter(this, void 0, void 0, function* () { logHeader('Statics Info'); const paths = env.locations || (yield paths_1.getPathsAsync(env.projectRoot)); // Detect if the default template files aren't being used. const { template: statics = {} } = paths; const expectedLocation = 'webpack-config/web-default/'; for (const key of Object.keys(statics)) { const filePath = statics[key]; if (typeof filePath !== 'string') continue; const fileName = filePath.substring(filePath.lastIndexOf('/') + 1); let message = chalk_1.default.reset(`- **${key}**: `) + chalk_1.default.blue(`\`${fileName}\``) + ' : '; if (filePath.includes(expectedLocation)) { message += chalk_1.default.bgGreen.black(`\`${filePath}\``); } else { message += chalk_1.default.bgRed.black(`\`${filePath}\``); } console.log(message); } logFooter(); }); } function logEnvironment(_a) { var { config } = _a, env = __rest(_a, ["config"]); logHeader('Environment Info'); logMdHelper('```json'); console.log(colorizeKeys(env)); logMdHelper('```'); logFooter(); } function setDeepValue(pathComponents, object, value) { if (!pathComponents.length) { return; } const key = pathComponents.shift(); if (!key) return; if (!(key in object)) { if (pathComponents.length) object[key] = {}; else { if (value.kind === 'N') { object[key] = value.lhs; } else { if ('rhs' in value) object[`${key}--push`] = value.rhs; if ('lhs' in value) object[`${key}--pop`] = value.lhs; } } } setDeepValue(pathComponents, object[key], value); } function logAutoConfigValuesAsync(env) { return __awaiter(this, void 0, void 0, function* () { const locations = env.locations || (yield paths_1.getPathsAsync(env.projectRoot)); const { exp: config } = config_1.readConfigJson(env.projectRoot); const standardConfig = config_1.ensurePWAConfig({}, locations.absolute, { templateIcon: locations.template.get('icon.png'), }); const pwaConfig = config_1.ensurePWAConfig(config, locations.absolute, { templateIcon: locations.template.get('icon.png'), }); // @ts-ignore const nonStandard = deep_diff_1.default(standardConfig, pwaConfig); let obj = {}; for (const diff of nonStandard) { // console.log(chalk.bold(diff.path.join('/') + ': ') + chalk.bgRed(JSON.stringify(diff.rhs, null, 2))); // TODO: Bacon: add support for array updates: https://www.npmjs.com/package/deep-diff#differences if (diff.kind !== 'A') { setDeepValue(diff.path, obj, diff); } } logHeader('App.json'); logMdHelper('```json'); // TODO: Bacon: Diff block console.log(colorizeKeys(obj)); logMdHelper('```'); logFooter(); }); } function reportAsync(webpackConfig, env) { return __awaiter(this, void 0, void 0, function* () { console.log(chalk_1.default.bold('\n\nStart Copy\n\n')); logWebpackConfigComponents(webpackConfig); logEnvironment(env); yield logStaticsAsync(env); yield logAutoConfigValuesAsync(env); const locations = env.locations || (yield paths_1.getPathsAsync(env.projectRoot)); yield testBabelPreset(locations); console.log(chalk_1.default.bold('\nEnd Copy\n\n')); }); } exports.reportAsync = reportAsync; function testBabelPreset(locations) { return __awaiter(this, void 0, void 0, function* () { logHeader('Babel Preset'); const babelrc = locations.absolute('.babelrc'); const babelConfig = locations.absolute('babel.config.js'); const printPassed = (message, ...messages) => console.log(chalk_1.default.bgGreen.black(`- [✔︎ ${message}]`, ...messages)); const printWarning = (message, ...messages) => console.log(chalk_1.default.bgYellow.black(`- [${message}]`, ...messages)); const printFailed = (message, ...messages) => console.log(chalk_1.default.bgRed.black(`- [x ${message}]`, ...messages)); if (fs_1.default.existsSync(babelrc)) { printFailed('Using `.babelrc`', 'Please upgrade to Babel 7, and replace `.babelrc` with `babel.config.js`'); } else { printPassed('Not using .babelrc', 'Expo web runs best with Babel 7+'); } const printFailedToParse = (...messages) => printWarning(`Expo CLI cannot parse your babel.config.js at ${babelConfig}.`, ...messages); function testBabelConfig(config, isFunction) { const preferred = 'It should be returning an object with `{ "presets: ["babel-preset-expo"]" }`.'; if (!config) { if (isFunction) { printWarning('`babel.config.js` is exporting a function that evaluates to a null object', preferred); } else { printWarning('`babel.config.js` is exporting a `null` object', preferred); } return; } else if (!Array.isArray(config.presets)) { const missingKey = ' without the "presets" key'; if (isFunction) { printWarning('`babel.config.js` is exporting a function that evaluates to an object' + missingKey, preferred); } else { printWarning('`babel.config.js` is exporting an object' + missingKey, preferred); } return; } const isExpo = (preset) => preset === 'expo' || preset === 'babel-preset-expo'; const hasExpoPreset = (() => { for (const preset of config.presets) { if ((typeof preset === 'string' && isExpo(preset)) || (Array.isArray(preset) && isExpo(preset[0]))) { return true; } } return false; })(); if (hasExpoPreset) { printPassed('Using `babel-preset-expo`', 'Tree-shaking should work as expected.'); } else { printWarning('Not using `babel-preset-expo`', `This is highly recommended as it'll greatly improve tree-shaking in most cases.`, `\nRun \`yarn add babel-preset-expo\` and add it to the "presets" array of your \`babel.config.js\`.`); } } if (fs_1.default.existsSync(babelConfig)) { const configObjectOrFunction = require(require.resolve(babelConfig)); if (isFunction(configObjectOrFunction)) { try { const results = yield configObjectOrFunction({ cache() { } }); testBabelConfig(results, true); } catch (error) { printFailedToParse(`Is it exporting something other than an object or function?`, `If it's exporting a function ensure that function returns a valid object containing the "presets" key.`, `If it's exporting an object ensure it contains the "presets" key.`); } } else { testBabelConfig(configObjectOrFunction); } } logFooter(); }); } function isFunction(functionToCheck) { return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]'; } //# sourceMappingURL=Diagnosis.js.map