diff --git a/.changeset/eleven-cars-try.md b/.changeset/eleven-cars-try.md new file mode 100644 index 000000000..5ef6c1174 --- /dev/null +++ b/.changeset/eleven-cars-try.md @@ -0,0 +1,5 @@ +--- +'@cloudflare/next-on-pages': patch +--- + +Parses cli arguments with the `zodcli` package diff --git a/package-lock.json b/package-lock.json index 48a9c7298..97cfd04d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,9 @@ "astring": "^1.8.4", "chokidar": "^3.5.3", "cookie": "^0.5.0", - "esbuild": "^0.15.3" + "esbuild": "^0.15.3", + "zod": "^3.21.4", + "zodcli": "^0.0.4" }, "bin": { "next-on-pages": "bin/index.js" @@ -6630,9 +6632,9 @@ } }, "node_modules/typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7103,6 +7105,25 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", + "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zodcli": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/zodcli/-/zodcli-0.0.4.tgz", + "integrity": "sha512-+WdBcf7Z19ueKI/w9SbxRXGyPnn5Fg/hc2nvOL3YKwcnhL2dvp58MvZwScvJS/Zqt4ePwSOLajboFG6su8BM8w==", + "dependencies": { + "typescript": "^4.9.5" + }, + "peerDependencies": { + "zod": "^3.21.4" + } } }, "dependencies": { @@ -11887,9 +11908,9 @@ } }, "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==" }, "unbox-primitive": { "version": "1.0.2", @@ -12218,6 +12239,19 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", "dev": true + }, + "zod": { + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", + "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==" + }, + "zodcli": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/zodcli/-/zodcli-0.0.4.tgz", + "integrity": "sha512-+WdBcf7Z19ueKI/w9SbxRXGyPnn5Fg/hc2nvOL3YKwcnhL2dvp58MvZwScvJS/Zqt4ePwSOLajboFG6su8BM8w==", + "requires": { + "typescript": "^4.9.5" + } } } } diff --git a/package.json b/package.json index bd8874e90..ca6c0e8ff 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "eslint src", "types-check": "tsc --noEmit", "build": "npx esbuild --bundle --platform=node ./src/index.ts --external:esbuild --external:chokidar --outfile=./dist/index.js", + "build:watch": "npm run build -- --watch", "prepare": "npm run build", "publish": "npm run build && npx changeset publish", "changeset": "npx changeset", @@ -24,7 +25,9 @@ "astring": "^1.8.4", "chokidar": "^3.5.3", "cookie": "^0.5.0", - "esbuild": "^0.15.3" + "esbuild": "^0.15.3", + "zod": "^3.21.4", + "zodcli": "^0.0.4" }, "peerDependencies": { "vercel": "^28.0.2" diff --git a/src/cli.ts b/src/cli.ts index 96f18f31e..db8c21c6c 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,34 +1,50 @@ import dedent from 'dedent-tabs'; - -export type CliOptions = { - help: boolean; - watch: boolean; - skipBuild: boolean; - experimentalMinify: boolean; - version: boolean; -}; +import { z } from 'zod'; +import { argumentParser } from 'zodcli'; + +// A helper type to handle command line flags. Defaults to false +const flag = z + .union([ + z.literal('true').transform(() => true), + z.literal('false').transform(() => false), + z.null().transform(() => true), + ]) + .default('false'); + +const cliOptions = z + .object({ + help: flag, + watch: flag, + skipBuild: flag, + experimentalMinify: flag, + version: flag, + }) + .strict(); + +export type CliOptions = z.infer; /** * parses the options provided to the CLI * - * TODO: this should replaced by yargs or similar - * * @returns the provided options */ -export function getCliOptions(): CliOptions { - return { - help: process.argv.includes('--help'), - watch: process.argv.includes('--watch'), - skipBuild: process.argv.includes('--skip-build'), - experimentalMinify: process.argv.includes('--experimental-minify'), - version: process.argv.includes('--version'), - }; +export function parseCliArgs() { + return argumentParser({ + options: cliOptions, + aliases: { + h: 'help', + v: 'version', + s: 'skipBuild', + e: 'experimentalMinify', + w: 'watch', + }, + }).parse(process.argv.slice(2)); } /** * Prints the help message that users get when they provide the help option * - * TODO: we should use yargs or similar and get this autogenerated instead + * Note: this should soon be available by zodcli and not be needed anymore */ export function printCliHelpMessage(): void { cliLog(` @@ -36,16 +52,16 @@ export function printCliHelpMessage(): void { Options: - --help: Shows this help message + --help, -h: Shows this help message - --version: Shows the version of the package + --version, -v: Shows the version of the package - --skip-build: Doesn't run 'vercel build' automatically + --skip-build, -s: Doesn't run 'vercel build' automatically - --experimental-minify: Attempts to minify the functions of a project (by de-duping webpack chunks) + --experimental-minify, -m: Attempts to minify the functions of a project (by de-duping webpack chunks) - --watch: Automatically rebuilds when the project is edited + --watch, -w: Automatically rebuilds when the project is edited GitHub: https://github.com/cloudflare/next-on-pages diff --git a/src/index.ts b/src/index.ts index 6abe23e24..344ea67b9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,16 +1,17 @@ import { watch } from 'chokidar'; import pLimit from 'p-limit'; -import { cliLog, CliOptions, getCliOptions, printCliHelpMessage } from './cli'; +import { cliLog, CliOptions, parseCliArgs, printCliHelpMessage } from './cli'; import { buildApplication } from './buildApplication'; import { nextOnPagesVersion } from './utils'; const limit = pLimit(1); -const cliOptions = getCliOptions(); -runNextOnPages(cliOptions); +runNextOnPages(); -function runNextOnPages(options: CliOptions): void { - if (options.version) { +function runNextOnPages(): void { + const args = parseCliArgs(); + + if (args.version) { // eslint-disable-next-line no-console -- for the version lets simply print it plainly console.log(nextOnPagesVersion); return; @@ -18,13 +19,17 @@ function runNextOnPages(options: CliOptions): void { cliLog(`@cloudflare/next-on-pages CLI v.${nextOnPagesVersion}`); - if (options.help) { + if (args.help) { printCliHelpMessage(); return; } - if (options.watch) { - setWatchMode(() => runBuild(options)); + // Run the build once + runBuild(args); + + // If the watch flag is set, run in watch mode + if (args.watch) { + setWatchMode(() => runBuild(args)); } }