diff --git a/package-lock.json b/package-lock.json index 45fb8d17..e899f2c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,7 +65,6 @@ "eslint-plugin-unicorn": "^56.0.1", "express": "^4.21.2", "fast-plist": "^0.1.3", - "get-stdin": "^9.0.0", "globals": "^15.14.0", "globby": "^14.0.2", "image-size": "^1.2.0", @@ -8651,19 +8650,6 @@ "node": ">=8.0.0" } }, - "node_modules/get-stdin": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", - "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", diff --git a/package.json b/package.json index 37856ff5..1875a41e 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,6 @@ "eslint-plugin-unicorn": "^56.0.1", "express": "^4.21.2", "fast-plist": "^0.1.3", - "get-stdin": "^9.0.0", "globals": "^15.14.0", "globby": "^14.0.2", "image-size": "^1.2.0", diff --git a/src/file.ts b/src/file.ts index a50b54b3..21787964 100644 --- a/src/file.ts +++ b/src/file.ts @@ -1,44 +1,14 @@ /* eslint-disable @typescript-eslint/no-namespace */ import fs from 'node:fs' import path from 'node:path' -import { setTimeout as setTimeoutPromise } from 'node:timers/promises' import * as url from 'node:url' -import chalk from 'chalk' -import _getStdin from 'get-stdin' import { globby, Options as GlobbyOptions } from 'globby' -import { info } from './cli' import { debug } from './utils/debug' +import { getStdin } from './utils/stdin' import { generateTmpName } from './utils/tmp' export const markdownExtensions = ['md', 'mdown', 'markdown', 'markdn'] -const STDIN_NOTICE_DELAY = 3000 - -const getStdin = async () => { - const delayedNoticeController = new AbortController() - - setTimeoutPromise(STDIN_NOTICE_DELAY, null, { - ref: false, - signal: delayedNoticeController.signal, - }) - .then(() => { - info( - `Currently waiting data from stdin stream. Conversion will start after finished reading. (Pass ${chalk.yellow`--no-stdin`} option if it was not intended)` - ) - }) - .catch(() => { - // No ops - }) - - debug('Reading stdin stream...') - const buf = await _getStdin.buffer() - - debug('Read from stdin: %d bytes', buf.length) - delayedNoticeController.abort() - - return buf -} - interface GenerateTmpFileInterfaceOptions { extension?: `.${string}` } diff --git a/src/utils/stdin.ts b/src/utils/stdin.ts new file mode 100644 index 00000000..d22d4e0f --- /dev/null +++ b/src/utils/stdin.ts @@ -0,0 +1,34 @@ +import streamConsumers from 'node:stream/consumers' +import { setTimeout as setTimeoutPromise } from 'node:timers/promises' +import chalk from 'chalk' +import { info } from '../cli' +import { debug } from './debug' + +const STDIN_NOTICE_DELAY = 3000 + +export const getStdin = async (): Promise => { + if (process.stdin.isTTY) return Buffer.alloc(0) + + const delayedNoticeController = new AbortController() + + setTimeoutPromise(STDIN_NOTICE_DELAY, null, { + ref: false, + signal: delayedNoticeController.signal, + }) + .then(() => { + info( + `Currently waiting data from stdin stream. Conversion will start after finished reading. (Pass ${chalk.yellow`--no-stdin`} option if it was not intended)` + ) + }) + .catch(() => { + // No ops + }) + + debug('Reading stdin stream...') + const buf = await streamConsumers.buffer(process.stdin) + + debug('Read from stdin: %d bytes', buf.length) + delayedNoticeController.abort() + + return buf +} diff --git a/test/__mocks__/get-stdin.ts b/test/__mocks__/get-stdin.ts deleted file mode 100644 index 7adc1e46..00000000 --- a/test/__mocks__/get-stdin.ts +++ /dev/null @@ -1,5 +0,0 @@ -const getStdin = Object.assign(async () => '', { - buffer: async () => Buffer.from(''), -}) - -export default getStdin diff --git a/test/index.ts b/test/index.ts index 3f15c9c2..ac3171d2 100644 --- a/test/index.ts +++ b/test/index.ts @@ -1,7 +1,7 @@ import path from 'node:path' -import getStdin from 'get-stdin' import api, { CLIError } from '../src/index' import * as marpCli from '../src/marp-cli' +import * as stdin from '../src/utils/stdin' afterEach(() => { jest.clearAllMocks() @@ -27,7 +27,7 @@ describe('Marp CLI API interface', () => { it('does not read input from stdin if called API', async () => { jest.spyOn(console, 'log').mockImplementation() - const stdinBuffer = jest.spyOn(getStdin, 'buffer') + const stdinBuffer = jest.spyOn(stdin, 'getStdin') await marpCli.cliInterface([]) expect(stdinBuffer).toHaveBeenCalled() diff --git a/test/marp-cli.ts b/test/marp-cli.ts index 8ec7e0ca..917a6fe0 100644 --- a/test/marp-cli.ts +++ b/test/marp-cli.ts @@ -4,7 +4,6 @@ import path from 'node:path' import { version as coreVersion } from '@marp-team/marp-core/package.json' import { version as marpitVersion } from '@marp-team/marpit/package.json' import * as cosmiconfigExplorer from 'cosmiconfig/dist/Explorer' // eslint-disable-line import-x/namespace -import getStdin from 'get-stdin' import stripAnsi from 'strip-ansi' import { version as cliVersion } from '../package.json' import { defaultFinders } from '../src/browser/finder' @@ -22,6 +21,7 @@ import { Preview } from '../src/preview' import { Server } from '../src/server' import { ThemeSet } from '../src/theme' import * as container from '../src/utils/container' +import * as stdin from '../src/utils/stdin' import * as version from '../src/version' import { Watcher } from '../src/watcher' @@ -1752,9 +1752,7 @@ describe('Marp CLI', () => { cliInfo = jest.spyOn(cli, 'info').mockImplementation() stdout = jest.spyOn(process.stdout, 'write').mockImplementation() - jest - .spyOn(getStdin, 'buffer') - .mockResolvedValue(Buffer.from('# markdown')) + jest.spyOn(stdin, 'getStdin').mockResolvedValue(Buffer.from('# markdown')) // reset cached stdin buffer ;(File as any).stdinBuffer = undefined