/* eslint-disable no-param-reassign */ import Path from "path"; import Fs from "fs"; import subappUtil from "subapp-util"; import { logger } from "./logger"; import { PROD_DIR } from "./constants"; /** * Figure out the mode app is setup. * * 1. src/client, src/server => lib * 2. src/{subapp-directories}, src/server => lib * 3. which react lib is being used (default react) * * And then setup the env APP_SRC_DIR so in dev mode code in src is executed * with run time compiler like @babel/register, but in prod mode transpiled * code in lib will be executed. * * @param {*} prodDir - directory to save data of the app mode * @param {*} reactLib - UI framework (react) * * @returns app mode data */ export function makeAppMode(prodDir = PROD_DIR, reactLib = "react") { const client = "client"; const server = "server"; let srcDir = ""; let libDir = ""; const savedFile = Path.join(prodDir, ".app-mode.json"); const version = 1; const loadSavedAppMode = () => { const savedFileFP = Path.resolve(savedFile); const subApps = subappUtil.scanSubAppsFromDir("src"); const hasSubApps = Object.keys(subApps).length > 0; // // app still has src directory in production mode so we know // app is definitely in the src/lib dir structure setup // if ( hasSubApps || Fs.existsSync(Path.resolve("src", client)) || Fs.existsSync(Path.resolve("src", server)) ) { srcDir = "src"; libDir = "lib"; return hasSubApps ? { subApps, hasSubApps } : {}; } else if (Fs.existsSync(savedFileFP)) { const saved = JSON.parse(Fs.readFileSync(savedFileFP, "utf-8")); if (saved.version === version) { return saved; } logger.warn(`${savedFile} version ${saved.version} not match ${version} - ignoring.`); } return {}; }; const saved = loadSavedAppMode(); reactLib = reactLib || "react"; const posixify = s => s.replace(/\\/g, "/"); const envKey = "APP_SRC_DIR"; return { reactLib, savedFile, envKey, setEnv: dir => { if (dir) { dir = posixify(dir); if (!dir.endsWith("/")) { dir += "/"; } process.env[envKey] = dir; } else { delete process.env[envKey]; } }, getEnv: () => { return process.env[envKey]; }, hasEnv: () => { return !!process.env[envKey]; }, client, server, src: { dir: srcDir, client: posixify(Path.join(srcDir, client)), server: posixify(Path.join(srcDir, server)) }, lib: { dir: libDir, client: posixify(Path.join(libDir, client)), server: posixify(Path.join(libDir, server)) }, ...saved, version }; }