UNPKG

@zendesk/zcli-themes

Version:

zcli theme commands live here

110 lines (109 loc) 5.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const core_1 = require("@oclif/core"); const path = require("path"); const fs = require("fs"); const express = require("express"); const http = require("http"); const https = require("https"); const WebSocket = require("ws"); const morgan = require("morgan"); const chalk = require("chalk"); const cors = require("cors"); const chokidar = require("chokidar"); const preview_1 = require("../../lib/preview"); const getManifest_1 = require("../../lib/getManifest"); const getVariables_1 = require("../../lib/getVariables"); const getAssets_1 = require("../../lib/getAssets"); const zass_1 = require("../../lib/zass"); const logMiddleware = morgan((tokens, req, res) => `${chalk.green(tokens.method(req, res))} ${tokens.url(req, res)} ${chalk.bold(tokens.status(req, res))}`); class Preview extends core_1.Command { async run() { const { flags, argv: [themeDirectory] } = await this.parse(Preview); const themePath = path.resolve(themeDirectory); const { logs: tailLogs, bind: host, port, 'https-cert': httpsCert, 'https-key': httpsKey } = flags; let httpsServerOptions = null; if (httpsCert && httpsKey) { httpsServerOptions = { key: fs.readFileSync(httpsKey), cert: fs.readFileSync(httpsCert) }; } const baseUrl = await (0, preview_1.default)(themePath, flags); const app = express(); const server = httpsServerOptions === null ? http.createServer(app) : https.createServer(httpsServerOptions, app); const wss = new WebSocket.Server({ server, path: '/livereload' }); app.use(cors()); tailLogs && app.use(logMiddleware); app.use('/guide/assets', express.static(`${themePath}/assets`)); app.use('/guide/settings', express.static(`${themePath}/settings`)); app.get('/guide/script.js', (req, res) => { const script = path.resolve(`${themePath}/script.js`); const source = fs.readFileSync(script, 'utf8'); res.header('Content-Type', 'text/javascript'); res.send(source); }); app.get('/guide/style.css', (req, res) => { const style = path.resolve(`${themePath}/style.css`); const source = fs.readFileSync(style, 'utf8'); const manifest = (0, getManifest_1.default)(themePath); const variables = (0, getVariables_1.default)(themePath, manifest.settings, flags); const assets = (0, getAssets_1.default)(themePath, flags); const compiled = (0, zass_1.default)(source, variables, assets); res.header('Content-Type', 'text/css'); res.send(compiled); }); server.listen(port, host, async () => { this.log(chalk.bold.green('Ready', chalk.blueBright(`${baseUrl}/hc/admin/local_preview/start`, '🚀'))); this.log(`You can exit preview mode in the UI or by visiting ${baseUrl}/hc/admin/local_preview/stop`); tailLogs && this.log(chalk.bold('Tailing logs')); }); const monitoredPaths = [ `${themePath}/assets`, `${themePath}/settings`, `${themePath}/templates`, `${themePath}/manifest.json`, `${themePath}/script.js`, `${themePath}/style.css` ]; const watcher = chokidar.watch(monitoredPaths).on('change', async (path) => { this.log(chalk.bold('Change'), path); try { await (0, preview_1.default)(themePath, flags); wss.clients.forEach((client) => { if (client.readyState === WebSocket.OPEN) { client.send('reload'); } }); } catch (e) { this.error(e, { exit: false }); } }); return { close: () => { // Stop watching file changes before terminating the server watcher.close(); server.close(); wss.close(); } }; } } exports.default = Preview; Preview.description = 'preview a theme in development mode'; Preview.flags = { bind: core_1.Flags.string({ default: 'localhost', description: 'Bind theme server to a specific host' }), port: core_1.Flags.integer({ default: 4567, description: 'Port for the http server to use' }), logs: core_1.Flags.boolean({ default: false, description: 'Tail logs' }), livereload: core_1.Flags.boolean({ default: true, description: 'Enable or disable live-reloading the preview when a change is made', allowNo: true }), 'https-cert': core_1.Flags.file({ description: 'Certificate used to start the server in HTTPS mode' }), 'https-key': core_1.Flags.file({ description: 'Key used to start the server in HTTPS mode' }) }; Preview.args = [ { name: 'themeDirectory', required: true, default: '.' } ]; Preview.examples = [ '$ zcli themes:preview ./copenhagen_theme' ]; Preview.strict = false;