UNPKG

@digipolis/start-ui

Version:
234 lines (206 loc) 6.62 kB
import path from 'path'; import replace from 'replace-in-file'; import brandings from '../../config/brandings.config.js'; import { mapBranding } from '../../utils/branding.js'; import { copyFolderRecursiveSync } from '../../utils/copy.js'; import { deleteFolderSync, deleteFileSync } from '../../utils/delete.js'; import { execPromise } from '../../utils/exec.js'; import { updateLog, errorLog } from '../../utils/log.js'; import { mapRouting, getRoutingReplaceOptions, getLoginReplaceOptions, getLoginRoutingReplaceOptions, } from './routing.js'; import frontEndConfig from '../../config/front-end.config.js'; const options = [ { param: '-b, --branding <branding>', description: 'Branding (Antwerp)', validation: /^(Antwerp)$/i, fallback: 'Antwerp', }, { param: '-F, --no-flexboxgrid', description: "Don't use the Flexbox grid", }, { param: '-R, --no-routing', description: "Don't add basic routing", }, ]; const questions = [ { type: 'list', name: 'branding', message: 'Which branding do you want to use?', choices: Object.keys(brandings), filter: mapBranding, }, { type: 'confirm', name: 'flexboxgrid', message: 'Do you want to use the Flexbox grid?', default: true, }, { type: 'confirm', name: 'routing', message: 'Do you want to add basic routing?', default: true, }, ]; function getQuestions() { return questions; } function getOptions() { return options; } /** * Run the create-react-app command. * Install NPM dependencies. */ async function installReact(config) { updateLog('Installing React...'); try { await execPromise('npx', ['create-react-app', 'frontend']); if (config.backend) { deleteFolderSync('frontend/.git'); } } catch (e) { errorLog(e); } } /** * Go into frontend folder and install Antwerp UI related stuff: * - Antwerp UI (React). * - Core Branding and optionally one of the other brandings. * - Node SASS, so you don't have to rely on CSS only. */ async function installAntwerpUI(config) { updateLog('Installing Antwerp UI...'); try { if (config.routing) { await execPromise('npm', ['install', '--save', 'react-router-dom'], { cwd: path.resolve('frontend') }); } await execPromise('npm', ['install', '--save-dev', 'sass'], { cwd: path.resolve('frontend') }); await execPromise('npm', ['install', '--save', '@acpaas-ui/react-components'].concat(config.branding.npm).concat(config.routing.npm), { cwd: path.resolve('frontend'), }); } catch (e) { errorLog(e); } } /** * Adjust the generated `index.html` file to include: * - Core Branding. * - Flexbox grid. * Merge our ready-made files with the files created by Create React App. */ async function createStarterTemplate(config) { updateLog('Creating starter template...'); const IndexHtmlReplaceOptions = { files: `${__frontenddir}/public/index.html`, from: [/Starter app/g, 'https://cdn.antwerpen.be/core_branding_scss/x.x.x/main.min.css'], to: [config.name, `https://cdn.antwerpen.be/${config.branding.cdn}/${config.branding.version}/main.min.css`], }; const AppJsReplaceOptions = { files: `${__frontenddir}/src/App.js`, from: [/Starter app/g], to: [config.name], }; const AppJsNextReplaceOptions = { files: `${__frontenddir}/src/App.js`, from: ['logoAlt="{{BRANDING_NAME}} logo." logoSrc="https://cdn.antwerpen.be/{{BRANDING_TYPE}}_branding_scss/{{BRANDING_VERSION}}/assets/images/{{BRANDING_LOGO}}'], to: [`logoAlt="${config.branding.key} logo." logoSrc="https://cdn.antwerpen.be/${config.branding.type}_branding_scss/${config.branding.version}/assets/images/${config.branding.logo}`], }; if (config.branding.type !== 'core') { IndexHtmlReplaceOptions.from.push( /safari-pinned-tab.svg" color="#cf0039"/g, /msapplication-TileColor" content="#cf0039"/g, /theme-color" content="#cf0039"/g, ); IndexHtmlReplaceOptions.to.push( 'safari-pinned-tab.svg" color="#347ea6"', 'msapplication-TileColor" content="#5fb1d6"', 'theme-color" content="#ffffff"', ); } // Flexboxgrid if (config.flexboxgrid) { IndexHtmlReplaceOptions.from.push(/main.min.css">/g); IndexHtmlReplaceOptions.to.push(`main.min.css"> ${frontEndConfig.flexbox.link}`); } try { deleteFolderSync('frontend/public'); await copyFolderRecursiveSync(`${__basedir}/generators/react/files/public`, __frontenddir); await copyFolderRecursiveSync(`${__basedir}/generators/react/files/src`, __frontenddir); await replace({ files: `${__frontenddir}/src/App.scss`, from: [/styles\/quarks';/], to: [ `/styles/quarks'; ${config.branding.scss.join('\n')}`, ], }); await replace(IndexHtmlReplaceOptions); await replace(AppJsReplaceOptions); if (config.routing.add) { const replaceOptions = getRoutingReplaceOptions(); const keys = Object.keys(replaceOptions); await Promise.all(keys.map((key) => { const option = replaceOptions[key]; return replace(option); })); } else { deleteFolderSync('frontend/src/components/About'); } if (config.auth) { if (config.routing.add) { const replaceOptions = getLoginRoutingReplaceOptions(); const keys = Object.keys(replaceOptions); await Promise.all(keys.map((key) => { const option = replaceOptions[key]; return replace(option); })); } else { const replaceOptions = getLoginReplaceOptions(); const keys = Object.keys(replaceOptions); await Promise.all(keys.map((key) => { const option = replaceOptions[key]; return replace(option); })); } } else { deleteFileSync('frontend/src/setupProxy.js'); deleteFolderSync('frontend/src/components/Login'); } await replace(AppJsNextReplaceOptions); } catch (e) { errorLog(e); } } async function prepareConfiguration(config) { return { ...config, routing: mapRouting(config), branding: await config.branding, }; } async function start(config) { updateLog('Preparing...'); const configuration = await prepareConfiguration(config); try { deleteFolderSync('frontend'); await installReact(configuration); await installAntwerpUI(configuration); await createStarterTemplate(configuration); updateLog('Done with front-end setup', 'cyan'); } catch (e) { errorLog(e); } } export default { getOptions, getQuestions, start, prepareConfiguration, };