From c9a07718c251d5edff226f25e8d4485aca6fd91a Mon Sep 17 00:00:00 2001 From: Eemeli Aro Date: Sat, 24 Feb 2024 23:46:53 +0200 Subject: [PATCH] Package CLI code as ES module to allow import() --- bin.mjs | 11 ++++++++ config/jest.config.js | 6 ++++- config/rollup.node-config.mjs | 48 ++++++++++++++++------------------- package.json | 2 +- src/cli.ts | 18 +++---------- tests/cli.ts | 6 ++--- 6 files changed, 45 insertions(+), 46 deletions(-) create mode 100755 bin.mjs diff --git a/bin.mjs b/bin.mjs new file mode 100755 index 00000000..7504ae13 --- /dev/null +++ b/bin.mjs @@ -0,0 +1,11 @@ +#!/usr/bin/env node + +import { UserError, cli, help } from './dist/cli.mjs' + +cli(process.stdin, error => { + if (error instanceof UserError) { + if (error.code === UserError.ARGS) console.error(`${help}\n`) + console.error(error.message) + process.exitCode = error.code + } else if (error) throw error +}) diff --git a/config/jest.config.js b/config/jest.config.js index 12ad785b..39b16c48 100644 --- a/config/jest.config.js +++ b/config/jest.config.js @@ -12,10 +12,14 @@ switch (process.env.npm_lifecycle_event) { console.log('Testing build output from dist/') moduleNameMapper = { '^yaml$': '/dist/index.js', - '^yaml/cli$': '/dist/cli.js', + '^yaml/cli$': '/dist/cli.mjs', '^yaml/util$': '/dist/util.js', '^../src/test-events$': '/dist/test-events.js' } + transform['[/\\\\]dist[/\\\\].*\\.mjs$'] = [ + 'babel-jest', + { configFile: './config/babel.config.js' } + ] break case 'test': diff --git a/config/rollup.node-config.mjs b/config/rollup.node-config.mjs index c6877cb6..e42dbc73 100644 --- a/config/rollup.node-config.mjs +++ b/config/rollup.node-config.mjs @@ -1,30 +1,26 @@ import { chmod, stat } from 'node:fs/promises' import typescript from '@rollup/plugin-typescript' -export default { - input: { - cli: 'src/cli.ts', - index: 'src/index.ts', - 'test-events': 'src/test-events.ts', - util: 'src/util.ts' +export default [ + { + input: { + index: 'src/index.ts', + 'test-events': 'src/test-events.ts', + util: 'src/util.ts' + }, + output: { + dir: 'dist', + format: 'cjs', + esModule: false, + preserveModules: true + }, + plugins: [typescript()], + treeshake: { moduleSideEffects: false, propertyReadSideEffects: false } }, - output: { - dir: 'dist', - format: 'cjs', - esModule: false, - preserveModules: true - }, - external: ['node:path', 'node:util'], - plugins: [ - typescript(), - { - async writeBundle() { - // chmod a+x dist/cli.js - const file = 'dist/cli.js' - const prev = await stat(file) - await chmod(file, prev.mode | 0o111) - } - } - ], - treeshake: { moduleSideEffects: false, propertyReadSideEffects: false } -} + { + input: 'src/cli.ts', + output: { file: 'dist/cli.mjs' }, + external: () => true, + plugins: [typescript()] + } +] diff --git a/package.json b/package.json index 5dbcca69..5209d73a 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ ], "type": "commonjs", "main": "./dist/index.js", - "bin": "./dist/cli.js", + "bin": "./bin.mjs", "browser": { "./dist/index.js": "./browser/index.js", "./dist/util.js": "./browser/dist/util.js", diff --git a/src/cli.ts b/src/cli.ts index 66901e65..a05ede81 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,5 +1,3 @@ -#!/usr/bin/env node - import { resolve } from 'node:path' import { parseArgs } from 'node:util' @@ -12,7 +10,7 @@ import { type Document } from './doc/Document.js' import { prettifyError } from './errors.js' import { visit, type visitor } from './visit.js' -const help = `\ +export const help = `\ yaml: A command-line YAML processor and inspector Reads stdin and writes output to stdout and errors & warnings to stderr. @@ -34,7 +32,7 @@ Additional options for bare "yaml" command: --visit, -v Apply a visitor to each document (requires a path to import) --yaml 1.1 Set the YAML version. (default: 1.2)` -class UserError extends Error { +export class UserError extends Error { static ARGS = 2 static SINGLE = 3 code: number @@ -44,17 +42,7 @@ class UserError extends Error { } } -/* istanbul ignore if */ -if (require.main === module) - // eslint-disable-next-line @typescript-eslint/no-floating-promises - main(process.stdin, error => { - if (error instanceof UserError) { - console.error(`${help}\n\n${error.message}`) - process.exitCode = error.code - } else if (error) throw error - }) - -export async function main( +export async function cli( stdin: NodeJS.ReadableStream, done: (error?: Error) => void, argv?: string[] diff --git a/tests/cli.ts b/tests/cli.ts index f0fdc9d9..f0da5172 100644 --- a/tests/cli.ts +++ b/tests/cli.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-floating-promises */ import { Readable } from 'node:stream' -import { main } from 'yaml/cli' +import { cli } from 'yaml/cli' const [major] = process.versions.node.split('.') const skip = Number(major) < 20 @@ -31,7 +31,7 @@ const skip = Number(major) < 20 test(name, done => { stdout.length = 0 stderr.length = 0 - main( + cli( Readable.from([input]), error => { try { @@ -56,7 +56,7 @@ const skip = Number(major) < 20 test(name, done => { stderr.length = 0 let doned = false - main( + cli( Readable.from([input]), error => { if (doned) return