UNPKG

zem

Version:

Create, test and publish Zeplin extensions with no build configuration

129 lines (109 loc) 4.15 kB
#!/usr/bin/env node import fs from "fs-extra"; import path from "node:path"; import { fileURLToPath } from "node:url"; import chalk from "chalk"; import updateNotifier from "update-notifier"; import { Command } from "commander"; import { resolveBuildPath } from "./utils/paths.js"; import build from "./commands/build.js"; import start from "./commands/start.js"; import exec from "./commands/exec.js"; import publish from "./commands/publish/index.js"; import create from "./commands/create.js"; import test from "./commands/test.js"; import execWebpackConfig from "./config/webpack.exec.mjs"; import prodWebpackConfig from "./config/webpack.prod.mjs"; import devWebpackConfig from "./config/webpack.dev.mjs"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const { name, version } = fs.readJsonSync(`${__dirname}/../package.json`) const seconds = 60; const minutes = 60; const hours = 24; const days = 5; const updateCheckInterval = days * hours * minutes * seconds; function beforeCommand() { const notifier = updateNotifier({ pkg: { name, version }, shouldNotifyInNpmScript: true, updateCheckInterval }); notifier.notify(); } const program = new Command(name).version(version); const TEST_ARGS_INDEX = 3; program .command("create <dir>") .description("Create empty Zeplin extension at directory.") .option("-y --yes", "Create extension without prompt for configuration") .action((extensionDir, { yes }) => { const root = path.resolve(process.cwd(), extensionDir); return create({ root, disablePrompt: yes }); }); program .command("build") .description("Create build, targeting production environment.") .option("-d --dev", "Target development environment") .action(async options => { await build(options.dev ? devWebpackConfig : prodWebpackConfig); }); program .command("clean") .description("Clean build directory.") .action(() => { fs.removeSync(resolveBuildPath()); }); program .command("start") .description("Start local server, serving the extension.") .option("-h --host <host>", "Host name (Default: \"127.0.0.1\")") .option("-p --port <port>", "Port (Default: 7070)") .option("-a --allowed-hosts <allowed-hosts>", "Allowed hosts, comma-separated (e.g., localhost,127.0.0.1,example.com,*.example.com) (Default: \"all\")") .action(async command => { await start(command.host, command.port, command.allowedHosts); }); program .command("exec [function-name]") .description("Execute extension function with sample data.") .option("--no-build", "Use existing build.") .option("--defaults <default-options>", `Set default extension option values (e.g, flag=false,prefix=\\"pre\\")`) .action((fnName, options) => { let defaultOptions; if (options.defaults) { defaultOptions = {}; options.defaults.split(",").forEach(keyValue => { const [key, value] = keyValue.split("="); defaultOptions[key] = JSON.parse(value); }); } exec(execWebpackConfig, fnName, defaultOptions, options.build); }); program .command("publish") .description(`Publish extension, submitting it for review to be listed on ${chalk.underline("https://extensions.zeplin.io.")}`) .option("--path <build-path>", `Path for the extension build to be published`) .option("--verbose", "Enables verbose logs") .action(async ({ path: buildPath, verbose }) => { try { await publish({ buildPath, verbose }); } catch (_) { process.exitCode = 1; } }); program .command("test") .description(`Test via jest`) .allowUnknownOption() .action(async () => { const testSuccess = await test(process.argv.slice(TEST_ARGS_INDEX)); if (!testSuccess) { console.log("Tests failed."); process.exitCode = 1; } }); program.on("command:*", () => { program.outputHelp(); }); beforeCommand(); program.parse(process.argv);