routie dev init since i didn't adhere to any proper guidance up until now

This commit is contained in:
2026-04-29 22:27:29 -06:00
commit e1dabb71e2
15301 changed files with 3562618 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
# Enforce Unix newlines
* text=auto eol=lf
+1
View File
@@ -0,0 +1 @@
github: ['bcomnes', 'voxpelli']
+17
View File
@@ -0,0 +1,17 @@
# Basic dependabot.yml file with
# minimum configuration for two package managers
version: 2
updates:
# Enable version updates for npm
- package-ecosystem: "npm"
# Look for `package.json` and `lock` files in the `root` directory
directory: "/"
# Check the npm registry for updates every day (weekdays)
schedule:
interval: "daily"
# Enable updates to github actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
+43
View File
@@ -0,0 +1,43 @@
name: "CodeQL"
on:
push:
branches:
- master
- "!dependabot/**"
pull_request:
branches:
- master
- "!dependabot/**"
schedule:
- cron: "0 0 * * 0"
workflow_dispatch:
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Clone repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: "javascript"
queries: +security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:javascript"
+42
View File
@@ -0,0 +1,42 @@
name: npm-bump
on:
workflow_dispatch:
inputs:
newversion:
description: 'npm version {major,minor,patch}'
required: true
env:
FORCE_COLOR: 1
concurrency: # prevent concurrent releases
group: npm-bump
cancel-in-progress: true
jobs:
version_and_release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# fetch full history so things like auto-changelog work properly
fetch-depth: 0
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version-file: package.json
# setting a registry enables the NODE_AUTH_TOKEN env variable where we can set an npm token. REQUIRED
registry-url: 'https://registry.npmjs.org'
- run: npm i
- run: npm test
- run: git status # getting odd dirty repo errors during version debug info
- run: git diff
- name: npm version && npm publish
uses: bcomnes/npm-bump@v2.2.1
with:
git_email: bcomnes@gmail.com
git_username: ${{ github.actor }}
newversion: ${{ github.event.inputs.newversion }}
github_token: ${{ secrets.GITHUB_TOKEN }} # built in actions token. Passed tp gh-release if in use.
npm_token: ${{ secrets.NPM_TOKEN }} # user set secret token generated at npm
+60
View File
@@ -0,0 +1,60 @@
name: tests
on:
push:
branches:
- master
tags:
- '*'
pull_request:
branches:
- master
env:
FORCE_COLOR: 2
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version-file: package.json
- run: npm i
- run: npm run check
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: ['20', 'lts/*', '23']
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm i
- run: npm run test-mocha
- uses: codecov/codecov-action@v5
if: ${{ github.event_name == 'pull_request' }}
with:
flags: ${{ matrix.os }}-${{ matrix.node }}
automerge:
needs: [lint, test]
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: write
steps:
- uses: fastify/github-action-merge-dependabot@v3
if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'pull_request' && contains(github.head_ref, 'dependabot/github_actions') }}
with:
github-token: ${{ secrets.github_token }}
+5
View File
@@ -0,0 +1,5 @@
{
"$schema": "https://unpkg.com/knip@5/schema.json",
"entry": ["lib/index.js", "bin/*/*.js", "test-workspace/tasks/*.js"],
"ignoreDependencies": ["yarn"]
}
+825
View File
@@ -0,0 +1,825 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
## [v8.0.4](https://github.com/bcomnes/npm-run-all2/compare/v8.0.4-beta.0...v8.0.4)
### Commits
- Merge pull request #182 from bcomnes/beta [`afcc18a`](https://github.com/bcomnes/npm-run-all2/commit/afcc18a7c68805ae1678871b31cd5103691a4bce)
## [v8.0.4-beta.0](https://github.com/bcomnes/npm-run-all2/compare/v8.0.3...v8.0.4-beta.0) - 2025-05-20
### Merged
- add tests for double stars [`#179`](https://github.com/bcomnes/npm-run-all2/pull/179)
### Commits
- Merge pull request #180 from bcomnes/simplify-lifecycles [`fb6721a`](https://github.com/bcomnes/npm-run-all2/commit/fb6721a1d537f0db9bb87645f158a573343c717a)
- fix new test [`3c0d2b2`](https://github.com/bcomnes/npm-run-all2/commit/3c0d2b29e32c07f2a943d5c9451843a57664fcc8)
- Improve npm lifecycles [`530288e`](https://github.com/bcomnes/npm-run-all2/commit/530288e7d2985dbb7dcc8f6f6347c0c761d3b4af)
## [v8.0.3](https://github.com/bcomnes/npm-run-all2/compare/v8.0.2...v8.0.3) - 2025-05-20
### Commits
- Merge pull request #175 from bcomnes/revert-pico [`75bb00e`](https://github.com/bcomnes/npm-run-all2/commit/75bb00e0a13d96cb4f873fd2967ea3ebeaffd815)
- Revert "replace minimatch with picomatch" [`5d93a54`](https://github.com/bcomnes/npm-run-all2/commit/5d93a5485a5749b2b171c24f4e6e9fe0d64299f6)
## [v8.0.2](https://github.com/bcomnes/npm-run-all2/compare/v8.0.1...v8.0.2) - 2025-05-16
### Commits
- Merge pull request #172 from beeequeue/picomatch [`4f42923`](https://github.com/bcomnes/npm-run-all2/commit/4f42923e1fdea84fc97796e774a5550e8f78f092)
- replace minimatch with picomatch [`74201f5`](https://github.com/bcomnes/npm-run-all2/commit/74201f5f7238d9a2c9d5e7b889db8748687fd4f9)
- add type field [`e8f046a`](https://github.com/bcomnes/npm-run-all2/commit/e8f046af4d4c14b61449695c7eb58f6a385ab2b6)
## [v8.0.1](https://github.com/bcomnes/npm-run-all2/compare/v8.0.0...v8.0.1) - 2025-05-02
### Commits
- Merge pull request #159 from bcomnes/dependabot/npm_and_yarn/minimatch-10.0.1 [`54af3ab`](https://github.com/bcomnes/npm-run-all2/commit/54af3abd3d9fe5c32d21c8bac8a5ef12b7b448aa)
- Upgrade: Bump minimatch from 9.0.5 to 10.0.1 [`f50ddf4`](https://github.com/bcomnes/npm-run-all2/commit/f50ddf48a0622d5473a7f9480069ebec8c5acd45)
- Merge pull request #170 from bcomnes/fix-engine-range [`e43e670`](https://github.com/bcomnes/npm-run-all2/commit/e43e6705fedfa87b8d80200f9d55ceb943ad77c7)
## [v8.0.0](https://github.com/bcomnes/npm-run-all2/compare/v7.0.2...v8.0.0) - 2025-05-02
### Commits
- **Breaking change:** Raise engine floor to >= Node 20 [`b1b12f8`](https://github.com/bcomnes/npm-run-all2/commit/b1b12f858291a7b3d73b20b28ca134407d927166)
- Merge pull request #169 from bcomnes/node-20-or-greater [`bb27458`](https://github.com/bcomnes/npm-run-all2/commit/bb274582dadbaaeeb2c3a2c54b4171660fb92399)
## [v7.0.2](https://github.com/bcomnes/npm-run-all2/compare/v7.0.1...v7.0.2) - 2024-12-16
### Merged
- Upgrade: Bump neostandard from 0.11.9 to 0.12.0 [`#164`](https://github.com/bcomnes/npm-run-all2/pull/164)
- Upgrade: Bump codecov/codecov-action from 4 to 5 [`#161`](https://github.com/bcomnes/npm-run-all2/pull/161)
### Commits
- Raise cross-spawn version floor to ^7.0.6 [`45a9e19`](https://github.com/bcomnes/npm-run-all2/commit/45a9e191b75e0b76433409808b6219d1f4dffe83)
- Merge pull request #163 from bcomnes/dependabot/npm_and_yarn/mocha-11.0.1 [`285967a`](https://github.com/bcomnes/npm-run-all2/commit/285967a3fc5076d8c22ecb14823eb6fc274dd835)
- Upgrade: Bump mocha from 10.8.2 to 11.0.1 [`5d1aea5`](https://github.com/bcomnes/npm-run-all2/commit/5d1aea58f17abd201515f737c06bbe8044d05d21)
## [v7.0.1](https://github.com/bcomnes/npm-run-all2/compare/v7.0.0...v7.0.1) - 2024-10-23
### Commits
- Revert engine range bump back to Node 18 [`b2e849b`](https://github.com/bcomnes/npm-run-all2/commit/b2e849bf8d31135751dd7458724344dd1bca120e)
## [v7.0.0](https://github.com/bcomnes/npm-run-all2/compare/v6.2.6...v7.0.0) - 2024-10-21
### Merged
- Prevent a throw when looking up undefined results [`#158`](https://github.com/bcomnes/npm-run-all2/pull/158)
### Commits
- **Breaking change:** Bump node engines ^18.17.0 || >=20.5.0 [`49b95f0`](https://github.com/bcomnes/npm-run-all2/commit/49b95f0c4905504a94d1a7ce87fbb7e77ab60df5)
- Merge pull request #156 from bcomnes/rm-rf-rimraf [`c661ffc`](https://github.com/bcomnes/npm-run-all2/commit/c661ffc942e09a68b1a553190d3a550dc0f6a39c)
- Remove rimraf [`c77e085`](https://github.com/bcomnes/npm-run-all2/commit/c77e0856c65115b32788c3e9a1e441ba69fbd430)
## [v6.2.6](https://github.com/bcomnes/npm-run-all2/compare/v6.2.4...v6.2.6) - 2024-10-21
### Commits
- Prevent a throw when looking up undefined results [`d928f9a`](https://github.com/bcomnes/npm-run-all2/commit/d928f9ad59c00a20797c90d35b62ef0aecf0c364)
## [v6.2.4](https://github.com/bcomnes/npm-run-all2/compare/v6.2.3...v6.2.4) - 2024-10-18
### Merged
- Switch to JS-based `which` command [`#154`](https://github.com/bcomnes/npm-run-all2/pull/154)
### Fixed
- Switch to JS-based `which` command [`#153`](https://github.com/bcomnes/npm-run-all2/issues/153)
## [v6.2.3](https://github.com/bcomnes/npm-run-all2/compare/v6.2.2...v6.2.3) - 2024-09-13
### Commits
- Merge pull request #151 from bcomnes/fix-pnpm-agian [`c43fa2b`](https://github.com/bcomnes/npm-run-all2/commit/c43fa2b677442c710a29654a333b15c8de4f00ab)
- Avoid passing config fields as flags for pnpm [`dc2d7da`](https://github.com/bcomnes/npm-run-all2/commit/dc2d7da61cf0898d0bc2b25747e588325e06b9a9)
## [v6.2.2](https://github.com/bcomnes/npm-run-all2/compare/v6.2.1...v6.2.2) - 2024-07-04
### Commits
- Revert "Compatibility: npm, yarn and pnpm run scripts" [`fc35f0d`](https://github.com/bcomnes/npm-run-all2/commit/fc35f0dc4f78afc1c631fa94b6ac85ba0fb0e7b1)
## [v6.2.1](https://github.com/bcomnes/npm-run-all2/compare/v6.2.0...v6.2.1) - 2024-07-03
### Merged
- Compatibility: npm, yarn and pnpm run scripts [`#143`](https://github.com/bcomnes/npm-run-all2/pull/143)
- Use neostandard + add more static code analysis [`#142`](https://github.com/bcomnes/npm-run-all2/pull/142)
- Upgrade: Bump c8 from 9.1.0 to 10.0.0 [`#141`](https://github.com/bcomnes/npm-run-all2/pull/141)
- Upgrade: Bump p-queue from 7.4.1 to 8.0.1 [`#138`](https://github.com/bcomnes/npm-run-all2/pull/138)
## [v6.2.0](https://github.com/bcomnes/npm-run-all2/compare/v6.1.2...v6.2.0) - 2024-05-17
### Merged
- Placeholder that unfolds into multiple tasks [`#134`](https://github.com/bcomnes/npm-run-all2/pull/134)
- 📝 add compatibility note for pnpm. [`#136`](https://github.com/bcomnes/npm-run-all2/pull/136)
- Upgrade: Bump codecov/codecov-action from 3 to 4 [`#131`](https://github.com/bcomnes/npm-run-all2/pull/131)
## [v6.1.2](https://github.com/bcomnes/npm-run-all2/compare/v6.1.1...v6.1.2) - 2024-01-31
### Merged
- feat: move to read-package-json-fast [`#130`](https://github.com/bcomnes/npm-run-all2/pull/130)
- Upgrade: Bump c8 from 8.0.1 to 9.0.0 [`#127`](https://github.com/bcomnes/npm-run-all2/pull/127)
- Upgrade: Bump github/codeql-action from 2 to 3 [`#126`](https://github.com/bcomnes/npm-run-all2/pull/126)
- Upgrade: Bump actions/setup-node from 3 to 4 [`#123`](https://github.com/bcomnes/npm-run-all2/pull/123)
### Commits
- Publish the whole project [`3dde20c`](https://github.com/bcomnes/npm-run-all2/commit/3dde20c1c8fa973045773e03f4fc121360fdbed4)
- Utilize CJS require for 'read-package-json-fast' [`605ca15`](https://github.com/bcomnes/npm-run-all2/commit/605ca15d9adee3ce14da6fcaa98cb14d9c03795c)
- Update FUNDING.yml [`c838ee9`](https://github.com/bcomnes/npm-run-all2/commit/c838ee9eea06e545d1a7f25592f7beb8468f1afd)
## [v6.1.1](https://github.com/bcomnes/npm-run-all2/compare/v6.1.0...v6.1.1) - 2023-10-04
### Commits
- Add an npm-run-all2 bin alias [`e6dc017`](https://github.com/bcomnes/npm-run-all2/commit/e6dc0175006a9a703c1256949f8424922043a33a)
- Fix npx on node 16 [`cfbd974`](https://github.com/bcomnes/npm-run-all2/commit/cfbd974a5990e8d549ae8bf7bfb632424ff4990b)
## [v6.1.0](https://github.com/bcomnes/npm-run-all2/compare/v6.0.6...v6.1.0) - 2023-10-04
### Merged
- Upgrade: Bump actions/checkout from 3 to 4 [`#119`](https://github.com/bcomnes/npm-run-all2/pull/119)
### Commits
- Lets avoid spawn.sync [`a3ee6cd`](https://github.com/bcomnes/npm-run-all2/commit/a3ee6cd9e051471bfd7b1b4d153aa260fc9b6634)
- Add support for pnpm (#117) [`3df3708`](https://github.com/bcomnes/npm-run-all2/commit/3df37084ab1ae55f873fcbb449ad0d7df8bc328f)
## [v6.0.6](https://github.com/bcomnes/npm-run-all2/compare/v6.0.5...v6.0.6) - 2023-07-04
### Merged
- Update all esm only packages [`#114`](https://github.com/bcomnes/npm-run-all2/pull/114)
- Upgrade: Bump c8 from 7.14.0 to 8.0.0 [`#111`](https://github.com/bcomnes/npm-run-all2/pull/111)
- Delete .nycrc [`#109`](https://github.com/bcomnes/npm-run-all2/pull/109)
- Update CodeQL workflow [`#110`](https://github.com/bcomnes/npm-run-all2/pull/110)
### Commits
- Lint fix and a few hand fixes [`2c81236`](https://github.com/bcomnes/npm-run-all2/commit/2c8123694b73084f37b68eb6719632024331d2e9)
- Fix tests [`79e2c97`](https://github.com/bcomnes/npm-run-all2/commit/79e2c97c5b32c46d5cf64ce37b3b78cf4035498e)
- Update p-queue and ansi-styles [`10b075c`](https://github.com/bcomnes/npm-run-all2/commit/10b075c849153822e9abc1447222d186a1cd6136)
## [v6.0.5](https://github.com/bcomnes/npm-run-all2/compare/v6.0.4...v6.0.5) - 2023-04-03
### Merged
- Upgrade: Bump bcomnes/npm-bump from 2.1.0 to 2.2.1 [`#104`](https://github.com/bcomnes/npm-run-all2/pull/104)
- Upgrade: Bump minimatch from 6.2.0 to 7.0.0 [`#103`](https://github.com/bcomnes/npm-run-all2/pull/103)
- Upgrade: Bump minimatch from 5.1.4 to 6.0.4 [`#102`](https://github.com/bcomnes/npm-run-all2/pull/102)
- Upgrade: Bump fs-extra from 10.1.0 to 11.1.0 [`#98`](https://github.com/bcomnes/npm-run-all2/pull/98)
### Commits
- Merge pull request #105 from bcomnes/dependabot/npm_and_yarn/minimatch-8.0.2 [`cbf78c8`](https://github.com/bcomnes/npm-run-all2/commit/cbf78c8155365db9ec06cb8054bc821e057d06e2)
- Upgrade: Bump minimatch from 7.4.4 to 8.0.2 [`c90d02b`](https://github.com/bcomnes/npm-run-all2/commit/c90d02b02df6dd33cbab01caac44b9729e012bb9)
- Merge pull request #101 from bcomnes/dependabot/npm_and_yarn/rimraf-4.0.4 [`d0d46a2`](https://github.com/bcomnes/npm-run-all2/commit/d0d46a2b0aa87a3c0c79b78a013415e7902c8324)
## [v6.0.4](https://github.com/bcomnes/npm-run-all2/compare/v6.0.3...v6.0.4) - 2022-11-09
### Merged
- When running through npx, use the npm that should be next to it. [`#96`](https://github.com/bcomnes/npm-run-all2/pull/96)
## [v6.0.3](https://github.com/bcomnes/npm-run-all2/compare/v6.0.2...v6.0.3) - 2022-11-09
### Merged
- Upgrade: Bump jsdoc from 3.6.11 to 4.0.0 [`#95`](https://github.com/bcomnes/npm-run-all2/pull/95)
- Upgrade: Bump bcomnes/npm-bump from 2.0.2 to 2.1.0 [`#92`](https://github.com/bcomnes/npm-run-all2/pull/92)
- docs: update minimum supported Node version [`#90`](https://github.com/bcomnes/npm-run-all2/pull/90)
### Commits
- Merge pull request #94 from MarmadileManteater/runjs-being-called-instead-of-npm-run [`da913f9`](https://github.com/bcomnes/npm-run-all2/commit/da913f9481543907457bd2298ad17192a4420874)
- Use NPM_CLI_JS over npm_execpath [`0224167`](https://github.com/bcomnes/npm-run-all2/commit/022416740f0d9cf8eae2f2e4ca4de8d09a6b67d8)
- Add a proper check for yarn [`bb41ef6`](https://github.com/bcomnes/npm-run-all2/commit/bb41ef6fd85a803a4a22e8382f67ea9e3e235b7d)
## [v6.0.2](https://github.com/bcomnes/npm-run-all2/compare/v6.0.1...v6.0.2) - 2022-08-16
### Merged
- Update package shell quote [`#89`](https://github.com/bcomnes/npm-run-all2/pull/89)
## [v6.0.1](https://github.com/bcomnes/npm-run-all2/compare/v6.0.0...v6.0.1) - 2022-06-14
### Commits
- Lower bound node engine to ^14.18.0 || >=16.0.0 [`fc2957f`](https://github.com/bcomnes/npm-run-all2/commit/fc2957f4814848b55bc29b0a0a1def8bfadda18b)
## [v6.0.0](https://github.com/bcomnes/npm-run-all2/compare/v5.0.2...v6.0.0) - 2022-06-11
### Merged
- Move support to node 16 and npm 8 [`#85`](https://github.com/bcomnes/npm-run-all2/pull/85)
- Upgrade: Bump pidtree from 0.5.0 to 0.6.0 [`#84`](https://github.com/bcomnes/npm-run-all2/pull/84)
- Upgrade: Bump mocha from 9.2.2 to 10.0.0 [`#83`](https://github.com/bcomnes/npm-run-all2/pull/83)
- Upgrade: Bump github/codeql-action from 1 to 2 [`#82`](https://github.com/bcomnes/npm-run-all2/pull/82)
- Upgrade: Bump fastify/github-action-merge-dependabot from 3.0.2 to 3.1 [`#78`](https://github.com/bcomnes/npm-run-all2/pull/78)
- Upgrade: Bump codecov/codecov-action from 2 to 3 [`#77`](https://github.com/bcomnes/npm-run-all2/pull/77)
- Upgrade: Bump actions/setup-node from 2 to 3 [`#75`](https://github.com/bcomnes/npm-run-all2/pull/75)
- Upgrade: Bump actions/checkout from 2 to 3 [`#76`](https://github.com/bcomnes/npm-run-all2/pull/76)
- Upgrade: Bump minimatch from 4.2.1 to 5.0.0 [`#74`](https://github.com/bcomnes/npm-run-all2/pull/74)
- Upgrade: Bump minimatch from 3.1.1 to 4.1.1 [`#73`](https://github.com/bcomnes/npm-run-all2/pull/73)
- Upgrade: Bump fastify/github-action-merge-dependabot from 2.7.1 to 3.0.2 [`#72`](https://github.com/bcomnes/npm-run-all2/pull/72)
- Upgrade: Bump fastify/github-action-merge-dependabot from 2.7.0 to 2.7.1 [`#71`](https://github.com/bcomnes/npm-run-all2/pull/71)
- Upgrade: Bump fastify/github-action-merge-dependabot from 2.6.0 to 2.7.0 [`#70`](https://github.com/bcomnes/npm-run-all2/pull/70)
- Upgrade: Bump fastify/github-action-merge-dependabot from 2.5.0 to 2.6.0 [`#69`](https://github.com/bcomnes/npm-run-all2/pull/69)
- Simplify npm scripts [`#64`](https://github.com/bcomnes/npm-run-all2/pull/64)
- Update CI config [`#62`](https://github.com/bcomnes/npm-run-all2/pull/62)
- Add CodeQL workflow [`#65`](https://github.com/bcomnes/npm-run-all2/pull/65)
- Switch to c8 for coverage [`#66`](https://github.com/bcomnes/npm-run-all2/pull/66)
- tests: switch to assert's strict mode [`#67`](https://github.com/bcomnes/npm-run-all2/pull/67)
- Enforce LF in the repo. [`#61`](https://github.com/bcomnes/npm-run-all2/pull/61)
- Upgrade: Bump actions/setup-node from 2.4.0 to 2.4.1 [`#59`](https://github.com/bcomnes/npm-run-all2/pull/59)
- Upgrade: Bump fastify/github-action-merge-dependabot from 2.4.0 to 2.5.0 [`#58`](https://github.com/bcomnes/npm-run-all2/pull/58)
- Upgrade: Bump codecov/codecov-action from 2.0.2 to 2.1.0 [`#57`](https://github.com/bcomnes/npm-run-all2/pull/57)
- Upgrade: Bump fastify/github-action-merge-dependabot from 2.2.0 to 2.4.0 [`#54`](https://github.com/bcomnes/npm-run-all2/pull/54)
- Upgrade: Bump actions/setup-node from 2.3.2 to 2.4.0 [`#53`](https://github.com/bcomnes/npm-run-all2/pull/53)
- Upgrade: Bump actions/setup-node from 2.3.1 to 2.3.2 [`#52`](https://github.com/bcomnes/npm-run-all2/pull/52)
- Upgrade: Bump actions/setup-node from 2.3.0 to 2.3.1 [`#51`](https://github.com/bcomnes/npm-run-all2/pull/51)
- Upgrade: Bump codecov/codecov-action from 2.0.1 to 2.0.2 [`#50`](https://github.com/bcomnes/npm-run-all2/pull/50)
- Upgrade: Bump actions/setup-node from 2.2.0 to 2.3.0 [`#49`](https://github.com/bcomnes/npm-run-all2/pull/49)
- Upgrade: Bump codecov/codecov-action from 1.5.2 to 2.0.1 [`#48`](https://github.com/bcomnes/npm-run-all2/pull/48)
- Upgrade: Bump fastify/github-action-merge-dependabot from 2.1.1 to 2.2.0 [`#47`](https://github.com/bcomnes/npm-run-all2/pull/47)
- Upgrade: Bump actions/setup-node from 2.1.5 to 2.2.0 [`#46`](https://github.com/bcomnes/npm-run-all2/pull/46)
- Upgrade: Bump codecov/codecov-action from 1.5.0 to 1.5.2 [`#44`](https://github.com/bcomnes/npm-run-all2/pull/44)
- Upgrade: Bump mocha from 8.4.0 to 9.0.0 [`#43`](https://github.com/bcomnes/npm-run-all2/pull/43)
- Upgrade: Bump fastify/github-action-merge-dependabot from 2.1.0 to 2.1.1 [`#42`](https://github.com/bcomnes/npm-run-all2/pull/42)
- Upgrade: Bump fastify/github-action-merge-dependabot from 2.0.0 to 2.1.0 [`#41`](https://github.com/bcomnes/npm-run-all2/pull/41)
- Upgrade: Bump gh-release from 5.0.2 to 6.0.0 [`#40`](https://github.com/bcomnes/npm-run-all2/pull/40)
- Upgrade: Bump codecov/codecov-action from 1 to 1.5.0 [`#39`](https://github.com/bcomnes/npm-run-all2/pull/39)
- Upgrade: Bump fs-extra from 9.1.0 to 10.0.0 [`#38`](https://github.com/bcomnes/npm-run-all2/pull/38)
- Upgrade: Bump fastify/github-action-merge-dependabot from v1.2.1 to v2.0.0 [`#33`](https://github.com/bcomnes/npm-run-all2/pull/33)
- Upgrade: Bump fastify/github-action-merge-dependabot [`#32`](https://github.com/bcomnes/npm-run-all2/pull/32)
- Upgrade: Bump fastify/github-action-merge-dependabot from v1.1.1 to v1.2.0 [`#31`](https://github.com/bcomnes/npm-run-all2/pull/31)
- Upgrade: Bump actions/setup-node from v2.1.4 to v2.1.5 [`#30`](https://github.com/bcomnes/npm-run-all2/pull/30)
- Upgrade: Bump gh-release from 4.0.4 to 5.0.0 [`#29`](https://github.com/bcomnes/npm-run-all2/pull/29)
- Upgrade: Bump actions/setup-node from v2.1.3 to v2.1.4 [`#28`](https://github.com/bcomnes/npm-run-all2/pull/28)
- Upgrade: Bump actions/setup-node from v2.1.2 to v2.1.3 [`#27`](https://github.com/bcomnes/npm-run-all2/pull/27)
### Fixed
- Disable override tests on > npm 7 [`#79`](https://github.com/bcomnes/npm-run-all2/issues/79)
### Commits
- **Breaking change:** Bump engines to node 16 and npm 8 [`7d19dd4`](https://github.com/bcomnes/npm-run-all2/commit/7d19dd47ee70286878f380934d18823310355471)
- Add auto merge [`e598066`](https://github.com/bcomnes/npm-run-all2/commit/e598066fea7478e0fce14b4f09d64fdf37b0420f)
- Update test.yml [`96260d6`](https://github.com/bcomnes/npm-run-all2/commit/96260d6c088ce0aa2bd367ff0736d653f5b0b1f1)
## [v5.0.2](https://github.com/bcomnes/npm-run-all2/compare/v5.0.1...v5.0.2) - 2020-12-08
### Merged
- Upgrade: Bump ansi-styles from 4.3.0 to 5.0.0 [`#26`](https://github.com/bcomnes/npm-run-all2/pull/26)
- Upgrade: Bump actions/checkout from v2.3.3 to v2.3.4 [`#25`](https://github.com/bcomnes/npm-run-all2/pull/25)
## [v5.0.1](https://github.com/bcomnes/npm-run-all2/compare/v5.0.0...v5.0.1) - 2020-10-24
### Commits
- Fix repo field to a valid format [`00b88f8`](https://github.com/bcomnes/npm-run-all2/commit/00b88f8a399d45cb104a33357cf56015ab92a1c0)
- Remove duplicate repo field [`a2d11ff`](https://github.com/bcomnes/npm-run-all2/commit/a2d11ff3f234812ba660be32f3a9a0aa45a510f6)
- Update FUNDING.yml [`648a541`](https://github.com/bcomnes/npm-run-all2/commit/648a5418725b4330571e08e9e1300756c98edd76)
## [v5.0.0](https://github.com/bcomnes/npm-run-all2/compare/v4.1.5...v5.0.0) - 2020-10-04
### Merged
- report codecov [`#21`](https://github.com/bcomnes/npm-run-all2/pull/21)
- Use built in string.padEnd [`#22`](https://github.com/bcomnes/npm-run-all2/pull/22)
- Upgrade: Bump fs-extra from 7.0.1 to 9.0.1 [`#17`](https://github.com/bcomnes/npm-run-all2/pull/17)
- remove @types/node [`#20`](https://github.com/bcomnes/npm-run-all2/pull/20)
- Upgrade: Bump @types/node from 4.9.4 to 14.11.2 [`#18`](https://github.com/bcomnes/npm-run-all2/pull/18)
- remove dependency on chalk [`#19`](https://github.com/bcomnes/npm-run-all2/pull/19)
- Upgrade: Bump eslint-config-mysticatea from 12.0.0 to 13.0.2 [`#11`](https://github.com/bcomnes/npm-run-all2/pull/11)
- Upgrade: Bump rimraf from 2.7.1 to 3.0.2 [`#10`](https://github.com/bcomnes/npm-run-all2/pull/10)
- Upgrade: Bump ansi-styles from 3.2.1 to 4.2.1 [`#12`](https://github.com/bcomnes/npm-run-all2/pull/12)
- Upgrade: Bump cross-spawn from 6.0.5 to 7.0.3 [`#9`](https://github.com/bcomnes/npm-run-all2/pull/9)
- Enable windows testing [`#15`](https://github.com/bcomnes/npm-run-all2/pull/15)
- Upgrade: Bump babel-preset-power-assert from 2.0.0 to 3.0.0 [`#3`](https://github.com/bcomnes/npm-run-all2/pull/3)
- more renaming [`#13`](https://github.com/bcomnes/npm-run-all2/pull/13)
- Upgrade: Bump p-queue from 2.4.2 to 6.6.1 [`#4`](https://github.com/bcomnes/npm-run-all2/pull/4)
- Upgrade: Bump nyc from 11.9.0 to 15.1.0 [`#7`](https://github.com/bcomnes/npm-run-all2/pull/7)
- Upgrade: Bump pidtree from 0.3.1 to 0.5.0 [`#5`](https://github.com/bcomnes/npm-run-all2/pull/5)
- Upgrade: Bump read-pkg from 3.0.0 to 5.2.0 [`#6`](https://github.com/bcomnes/npm-run-all2/pull/6)
- Upgrade: Bump mocha from 5.2.0 to 8.1.3 [`#8`](https://github.com/bcomnes/npm-run-all2/pull/8)
- Upgrade: Bump actions/setup-node from v2.1.1 to v2.1.2 [`#1`](https://github.com/bcomnes/npm-run-all2/pull/1)
- Upgrade: Bump actions/checkout from v2.3.2 to v2.3.3 [`#2`](https://github.com/bcomnes/npm-run-all2/pull/2)
- 🐛 fix signal handling [`#171`](https://github.com/bcomnes/npm-run-all2/pull/171)
### Commits
- fix lint [`acce8f7`](https://github.com/bcomnes/npm-run-all2/commit/acce8f78b0a4ac656020c14ab946d57639e22764)
- ⚒ switch to actions and use dependabot [`13696f8`](https://github.com/bcomnes/npm-run-all2/commit/13696f8aef475fb66346a8b219c9f07d026d2513)
- Fix lint [`87b3e01`](https://github.com/bcomnes/npm-run-all2/commit/87b3e01c1405bb92c39a1aecdf957805bcc184c0)
## [v4.1.5](https://github.com/bcomnes/npm-run-all2/compare/v4.1.4...v4.1.5) - 2018-11-24
### Commits
- 🐛 use pidtree [`1b41ac5`](https://github.com/bcomnes/npm-run-all2/commit/1b41ac569987c96e224f940ff59f9699322c7824)
- ⬆️ update dependencies [`7ec542e`](https://github.com/bcomnes/npm-run-all2/commit/7ec542e95ceb922b9abe593270d9b6f8e0df4bc5)
- 🔖 4.1.5 [`df15118`](https://github.com/bcomnes/npm-run-all2/commit/df1511851a2b5e8a406e4a2622829b360f671afc)
## [v4.1.4](https://github.com/bcomnes/npm-run-all2/compare/v4.1.3...v4.1.4) - 2018-11-24
### Commits
- 🔥 remove ps-tree [`57d72eb`](https://github.com/bcomnes/npm-run-all2/commit/57d72eb98c2ce108f07d2a2cf1b44d57f08ec3ca)
- 🔖 4.1.4 [`a79fbac`](https://github.com/bcomnes/npm-run-all2/commit/a79fbacda181ec8a240d8bf8d34f9303da3c1fd1)
- remove test in version script temporary [`d97929c`](https://github.com/bcomnes/npm-run-all2/commit/d97929cdd73c615e053202c2a5068eb0cf1af08e)
## [v4.1.3](https://github.com/bcomnes/npm-run-all2/compare/v4.1.2...v4.1.3) - 2018-05-07
### Merged
- Fix: unexpected behavior of leading bang [`#124`](https://github.com/bcomnes/npm-run-all2/pull/124)
- Docs: typo fix in README.md: is/are [`#120`](https://github.com/bcomnes/npm-run-all2/pull/120)
- Fix: colorize tasks names sequentially instead of by hash [`#115`](https://github.com/bcomnes/npm-run-all2/pull/115)
### Commits
- Chore: trivial fix [`21c0269`](https://github.com/bcomnes/npm-run-all2/commit/21c02697e59748c0d2ac55b5244bd0ca10ecbfcc)
- Chore: upgrade dependencies [`61bad5c`](https://github.com/bcomnes/npm-run-all2/commit/61bad5c72678f35f8dd1dcd68eb20b688795ffd5)
## [v4.1.2](https://github.com/bcomnes/npm-run-all2/compare/v4.1.1...v4.1.2) - 2017-11-07
### Fixed
- Fix: `--aggregate-output` cannot handle large data (fixes #111)(#112) [`#111`](https://github.com/bcomnes/npm-run-all2/issues/111)
### Commits
- Chore: fix tests [`43a6b16`](https://github.com/bcomnes/npm-run-all2/commit/43a6b1683374e3dd314733ec5559908abfcc6cd1)
- Fix: fix for latest yarn [`dfb9dcb`](https://github.com/bcomnes/npm-run-all2/commit/dfb9dcb40dc0d309480e28dbdaac24878e4c32c6)
- Fix: missing --aggregate-output in npm-run-all [`693261b`](https://github.com/bcomnes/npm-run-all2/commit/693261b6169071b61b443eec5ad6d04525394500)
## [v4.1.1](https://github.com/bcomnes/npm-run-all2/compare/v4.1.0...v4.1.1) - 2017-08-28
### Merged
- Fix: Use ansi-style directly instead of chalk.styles [`#108`](https://github.com/bcomnes/npm-run-all2/pull/108)
### Commits
- Chore: configure appveyor to run on only Node 8. [`ac9358a`](https://github.com/bcomnes/npm-run-all2/commit/ac9358a669611cedb7eb7201e770d60886347ca5)
## [v4.1.0](https://github.com/bcomnes/npm-run-all2/compare/v4.0.2...v4.1.0) - 2017-08-26
### Merged
- Docs: add note about Yarn compatibility [`#103`](https://github.com/bcomnes/npm-run-all2/pull/103)
- Add Node.js 8.x to Travis CI [`#101`](https://github.com/bcomnes/npm-run-all2/pull/101)
- Include docs in published npm package. [`#95`](https://github.com/bcomnes/npm-run-all2/pull/95)
### Fixed
- Fix: MaxListenersExceededWarning (fixes #105) [`#105`](https://github.com/bcomnes/npm-run-all2/issues/105)
- New: add `--aggregate-output` option (fixes #36)(#104) [`#36`](https://github.com/bcomnes/npm-run-all2/issues/36)
### Commits
- Chore: use async/await in tests [`64f6479`](https://github.com/bcomnes/npm-run-all2/commit/64f647988007d36b16c96a700c6c06fdb8175066)
- Docs: update docs [`8c8bec0`](https://github.com/bcomnes/npm-run-all2/commit/8c8bec0701586c2a0169ef5f601683e61837e901)
- Chore: tweak CI settings [`8c6debf`](https://github.com/bcomnes/npm-run-all2/commit/8c6debfc5b8eac43f21bdc9e2a3d163927e59749)
## [v4.0.2](https://github.com/bcomnes/npm-run-all2/compare/v4.0.1...v4.0.2) - 2017-02-23
### Fixed
- Fix: it threw for --race even if --parallel exists (fixes #88) [`#88`](https://github.com/bcomnes/npm-run-all2/issues/88)
## [v4.0.1](https://github.com/bcomnes/npm-run-all2/compare/v4.0.0...v4.0.1) - 2017-01-17
### Merged
- Simplify repository config [`#82`](https://github.com/bcomnes/npm-run-all2/pull/82)
- Fix Case Sensitive NPM_EXECPATH [`#84`](https://github.com/bcomnes/npm-run-all2/pull/84)
- Fixed: typo in `help` CLI command. [`#83`](https://github.com/bcomnes/npm-run-all2/pull/83)
### Commits
- NPM_EXECPATH -> npm_execpath, this variable is case sensitive [`bb9e627`](https://github.com/bcomnes/npm-run-all2/commit/bb9e627406fd98933e237358c731ea74b5fd1634)
- Docs: update README.md [`6beda60`](https://github.com/bcomnes/npm-run-all2/commit/6beda6057d5bdda5da7ba370597468fb618c9ab3)
- Chore: switch to codecov [`378c54b`](https://github.com/bcomnes/npm-run-all2/commit/378c54b549edc7e9bb26f0c2f86f83a28cddad50)
## [v4.0.0](https://github.com/bcomnes/npm-run-all2/compare/v3.1.2...v4.0.0) - 2017-01-01
### Merged
- Change labels to be displayed in individual colors for each task [`#75`](https://github.com/bcomnes/npm-run-all2/pull/75)
### Fixed
- Merge pull request #75 from nulltask/feature/colorize (fixes #73) [`#73`](https://github.com/bcomnes/npm-run-all2/issues/73)
### Commits
- Chore: upgrade eslint and eslint-config [`3f933c3`](https://github.com/bcomnes/npm-run-all2/commit/3f933c326567da1ba1530fbb5d9047fc31d325c9)
- New: --max-parallel option [`02e9767`](https://github.com/bcomnes/npm-run-all2/commit/02e97675e3852aefd758d40fef366dc3be5b7aad)
- Breaking: use NPM_EXECPATH to run tasks [`12b2b87`](https://github.com/bcomnes/npm-run-all2/commit/12b2b87cf473e4b11e27da64b4c27d9f2db8d7e6)
## [v3.1.2](https://github.com/bcomnes/npm-run-all2/compare/v3.1.1...v3.1.2) - 2016-12-01
### Fixed
- Fix: remove useless `if` for old tests (fixes #67) [`#67`](https://github.com/bcomnes/npm-run-all2/issues/67)
- Fix: --version command was wrong (fixes #70) [`#70`](https://github.com/bcomnes/npm-run-all2/issues/70)
### Commits
- Chore: improve tests [`4b26037`](https://github.com/bcomnes/npm-run-all2/commit/4b260379beeb8757a79e94e3f4e678008bf1bd6f)
- Chore: update travis.yml with dot reporter. [`413a7d5`](https://github.com/bcomnes/npm-run-all2/commit/413a7d52fd4d12121ddba265e4af4c6b56fdc4dd)
- Chore: add @types/node [`76c7f3d`](https://github.com/bcomnes/npm-run-all2/commit/76c7f3d989dd0d8ae331e7b1fddcd5c374895335)
## [v3.1.1](https://github.com/bcomnes/npm-run-all2/compare/v3.1.0...v3.1.1) - 2016-10-15
### Merged
- fix: use run command instead of run-script [`#66`](https://github.com/bcomnes/npm-run-all2/pull/66)
- docs: add hint about forcing chalk coloring [`#65`](https://github.com/bcomnes/npm-run-all2/pull/65)
## [v3.1.0](https://github.com/bcomnes/npm-run-all2/compare/v3.0.0...v3.1.0) - 2016-09-01
### Fixed
- New: add supporting `$npm_config_xxx` (fixes #60) [`#60`](https://github.com/bcomnes/npm-run-all2/issues/60)
### Commits
- Merge pull request #61 from mysticatea/issue60 [`6a3697d`](https://github.com/bcomnes/npm-run-all2/commit/6a3697dcea11a9a461660f097662bdf131209dbd)
- Chore: rename tests: env-check/overwriting → package-config [`a32ca2f`](https://github.com/bcomnes/npm-run-all2/commit/a32ca2f1f4749424b2947f6daa12a723b0604721)
## [v3.0.0](https://github.com/bcomnes/npm-run-all2/compare/v2.3.0...v3.0.0) - 2016-08-17
### Merged
- Added appveyor support for modern node versions [`#57`](https://github.com/bcomnes/npm-run-all2/pull/57)
### Fixed
- Breaking: supports default values for argument placeholders (fixes #54) [`#54`](https://github.com/bcomnes/npm-run-all2/issues/54)
### Commits
- Chore: improve --race tests [`58c5df8`](https://github.com/bcomnes/npm-run-all2/commit/58c5df875908d5641e39ac2ac762dc063fdbcd94)
- Chore: try to improve tests for --race [`2e5663a`](https://github.com/bcomnes/npm-run-all2/commit/2e5663ac62739a602ab4703bfd7690c223117f6b)
- Docs: update README.md [`1e2b299`](https://github.com/bcomnes/npm-run-all2/commit/1e2b29973e854fb766d38bfab4f49c8079373605)
## [v2.3.0](https://github.com/bcomnes/npm-run-all2/compare/v2.2.2...v2.3.0) - 2016-06-28
### Fixed
- New: race option (fixes #42) [`#42`](https://github.com/bcomnes/npm-run-all2/issues/42)
### Commits
- Chore: upgrade my ESLint config. [`b740e19`](https://github.com/bcomnes/npm-run-all2/commit/b740e193c856e6f77bc8ecaeb3082dffb2fca3cf)
## [v2.2.2](https://github.com/bcomnes/npm-run-all2/compare/v2.2.1...v2.2.2) - 2016-06-23
### Commits
- Upgrade: shell-quote 1.6.1 [`e7ef8cf`](https://github.com/bcomnes/npm-run-all2/commit/e7ef8cffef04fb393c7bc51d9f82c3aed3fdefa0)
## [v2.2.1](https://github.com/bcomnes/npm-run-all2/compare/v2.2.0...v2.2.1) - 2016-06-23
### Commits
- Upgrade: minimatch 3.0.2 [`5dc5056`](https://github.com/bcomnes/npm-run-all2/commit/5dc5056210bda994f8ba857857a04f6dbf737cf5)
## [v2.2.0](https://github.com/bcomnes/npm-run-all2/compare/v2.1.2...v2.2.0) - 2016-06-18
### Merged
- Docs: ESLint use `--color` not `--colors` [`#47`](https://github.com/bcomnes/npm-run-all2/pull/47)
### Fixed
- New: add a feature to pass arguments on to each task. (fixes #44) [`#44`](https://github.com/bcomnes/npm-run-all2/issues/44)
### Commits
- Fix: add tests for argument-passthrough [`e18ce01`](https://github.com/bcomnes/npm-run-all2/commit/e18ce01e77efef3e57e8467d29e086a037c40d76)
- Docs: add documents about argument placeholders. [`c9f69b4`](https://github.com/bcomnes/npm-run-all2/commit/c9f69b429c1b718f9e1c72c7dbcceb82b021f0cf)
- Fix: refactor and change Node API for argument-passthrough [`49c9e67`](https://github.com/bcomnes/npm-run-all2/commit/49c9e67daf48ddbc87c9de8efba1254fd6752ed4)
## [v2.1.2](https://github.com/bcomnes/npm-run-all2/compare/v2.1.1...v2.1.2) - 2016-06-13
### Commits
- Upgrade: cross-spawn 4.0.0 [`16603c3`](https://github.com/bcomnes/npm-run-all2/commit/16603c3db0747c063ba58f9b0d68206ef0cbc469)
## [v2.1.1](https://github.com/bcomnes/npm-run-all2/compare/v2.1.0...v2.1.1) - 2016-05-19
### Fixed
- Upgrade: `cross-spawn-async` to `cross-spawn` (fixes #40) [`#40`](https://github.com/bcomnes/npm-run-all2/issues/40)
## [v2.1.0](https://github.com/bcomnes/npm-run-all2/compare/v2.0.0...v2.1.0) - 2016-05-13
### Commits
- Update: `results` of Node API [`f4ef9f7`](https://github.com/bcomnes/npm-run-all2/commit/f4ef9f7bef8c443eb04a5289f7d08795fed45faf)
- Fix: invalid jsdoc comments. [`32daa0e`](https://github.com/bcomnes/npm-run-all2/commit/32daa0ec98c85e8326a9608fc5c404cb70bb47f8)
- Fix: results of aborted tasks on linux [`4a1bd16`](https://github.com/bcomnes/npm-run-all2/commit/4a1bd169e760c84a614a871351745ab13e37630f)
## [v2.0.0](https://github.com/bcomnes/npm-run-all2/compare/v1.8.0...v2.0.0) - 2016-05-11
### Merged
- Build: Add Node 6 to Travis CI [`#39`](https://github.com/bcomnes/npm-run-all2/pull/39)
### Commits
- Update: add tests for shorthand commands. [`4496065`](https://github.com/bcomnes/npm-run-all2/commit/4496065f16bf13c22a78f8f1b49d1e606f75af2e)
- Add `run-s` and `run-p` commands [`40554ef`](https://github.com/bcomnes/npm-run-all2/commit/40554ef517781856169c70adc574f7719252e3ee)
- Chore: Stop a use of ES6 modules. And upgrade eslint. [`2f26fa5`](https://github.com/bcomnes/npm-run-all2/commit/2f26fa5e21e07a74a1a5e56c224dff1ed361c63a)
## [v1.8.0](https://github.com/bcomnes/npm-run-all2/compare/v1.7.0...v1.8.0) - 2016-04-24
### Fixed
- New: `--print-name` option (fixes #35) [`#35`](https://github.com/bcomnes/npm-run-all2/issues/35)
- New: `--print-label` option (fixes #23) [`#23`](https://github.com/bcomnes/npm-run-all2/issues/23)
## [v1.7.0](https://github.com/bcomnes/npm-run-all2/compare/v1.6.0...v1.7.0) - 2016-03-30
### Fixed
- Update: `--continue-on-error` option (fixes #34) [`#34`](https://github.com/bcomnes/npm-run-all2/issues/34)
## [v1.6.0](https://github.com/bcomnes/npm-run-all2/compare/v1.5.3...v1.6.0) - 2016-03-20
### Merged
- added --serial option as a synonym for sequential [`#31`](https://github.com/bcomnes/npm-run-all2/pull/31)
### Fixed
- added --serial option as a synonym for sequential [`#30`](https://github.com/bcomnes/npm-run-all2/issues/30)
### Commits
- Docs: fix help text within 80 columns. [`b1e6c5a`](https://github.com/bcomnes/npm-run-all2/commit/b1e6c5a1a487e3054fb24f564a8bab9b02b5348a)
## [v1.5.3](https://github.com/bcomnes/npm-run-all2/compare/v1.5.2...v1.5.3) - 2016-03-13
### Fixed
- Fix: Add a workaround for Git Bash for Windows (fixes #24) [`#24`](https://github.com/bcomnes/npm-run-all2/issues/24)
### Commits
- Build: Update appveyor.yml [`6585c66`](https://github.com/bcomnes/npm-run-all2/commit/6585c664827de1c2bbedc7b4519c2454d0072e2a)
## [v1.5.2](https://github.com/bcomnes/npm-run-all2/compare/v1.5.1...v1.5.2) - 2016-03-08
### Fixed
- Fix: using `cross-spawn-async` for spaced paths (fixes #26, fixes #27) [`#26`](https://github.com/bcomnes/npm-run-all2/issues/26) [`#27`](https://github.com/bcomnes/npm-run-all2/issues/27)
### Commits
- Add: appveyor and badge to readme [`b1ac307`](https://github.com/bcomnes/npm-run-all2/commit/b1ac30763a622ada39847c328f078f5ea685bdae)
- Fix: AppVeyor settings [`b1f1eb1`](https://github.com/bcomnes/npm-run-all2/commit/b1f1eb1cd35fc4d36c1edc3aacd57a9d24503c38)
- Fix: trivial change. [`aa2dd2b`](https://github.com/bcomnes/npm-run-all2/commit/aa2dd2b55b0a2d8cdcf2c680ded0709d1e545952)
## [v1.5.1](https://github.com/bcomnes/npm-run-all2/compare/v1.5.0...v1.5.1) - 2016-01-28
### Fixed
- Fix: came to report unmatched pattern error (fixes #19) [`#19`](https://github.com/bcomnes/npm-run-all2/issues/19)
### Commits
- Docs: trivial [`8f7736d`](https://github.com/bcomnes/npm-run-all2/commit/8f7736d7d096bf7a6396dd6c544be128b4b490ce)
- Upgrade: eslint-plugin-node@0.6.0 [`a497241`](https://github.com/bcomnes/npm-run-all2/commit/a49724146ea3853d915c7fbc4c8e5a4d84f839e1)
## [v1.5.0](https://github.com/bcomnes/npm-run-all2/compare/v1.4.0...v1.5.0) - 2016-01-17
### Commits
- Update: Add `silent` option [`87aedbf`](https://github.com/bcomnes/npm-run-all2/commit/87aedbf187f2e554e9d6654c9475f4c93cd0ba91)
- Fix: switch to babel-runtime [`bbad6e8`](https://github.com/bcomnes/npm-run-all2/commit/bbad6e80fef44efb9bcf77aa57299eb19069059e)
- Pin eslint-config [`92e48ea`](https://github.com/bcomnes/npm-run-all2/commit/92e48ea0ad2901e72813703252c166ff4a4f6e2b)
## [v1.4.0](https://github.com/bcomnes/npm-run-all2/compare/v1.3.4...v1.4.0) - 2015-12-08
### Fixed
- Add transfaring config overwritten to nested calls (fixes #13) [`#13`](https://github.com/bcomnes/npm-run-all2/issues/13)
### Commits
- trivial [`baea559`](https://github.com/bcomnes/npm-run-all2/commit/baea559cb07228f327c964775ab7672838f51712)
## [v1.3.4](https://github.com/bcomnes/npm-run-all2/compare/v1.3.3...v1.3.4) - 2015-12-06
### Merged
- Small typo + grammar fixes [`#16`](https://github.com/bcomnes/npm-run-all2/pull/16)
### Commits
- Fix: Add `import "babel-polyfill"` for node v0.10 (refs #17) [`9253ce9`](https://github.com/bcomnes/npm-run-all2/commit/9253ce9365284ef0aa6e8089aead67bc7a8be2b2)
## [v1.3.3](https://github.com/bcomnes/npm-run-all2/compare/v1.3.2...v1.3.3) - 2015-12-02
### Fixed
- Add notes about the behavior of non-zero-exit (fixes #15) [`#15`](https://github.com/bcomnes/npm-run-all2/issues/15)
### Commits
- Upgrade Babel. [`1fa5e5b`](https://github.com/bcomnes/npm-run-all2/commit/1fa5e5bdb14621eb36a26c8568b5ab3ef1cb060b)
- Fix for babel and eslint [`f72af44`](https://github.com/bcomnes/npm-run-all2/commit/f72af44a253e4e123bfb94cc54d8f3f237ef7c22)
- Modify ESLint's config. [`2b24221`](https://github.com/bcomnes/npm-run-all2/commit/2b24221807bce843a30d6b13c01c4687a7e97ad3)
## [v1.3.2](https://github.com/bcomnes/npm-run-all2/compare/v1.3.0...v1.3.2) - 2015-11-23
### Fixed
- Fix: use `ps-tree` to kill processes (fixes #14) [`#14`](https://github.com/bcomnes/npm-run-all2/issues/14)
### Commits
- Added esdoc-importpath-plugin [`611a956`](https://github.com/bcomnes/npm-run-all2/commit/611a9561fab73be7b17ac5bb1f3fd8f107f75c70)
## [v1.3.0](https://github.com/bcomnes/npm-run-all2/compare/v1.2.13...v1.3.0) - 2015-11-18
### Commits
- Refactoring! [`8004ce4`](https://github.com/bcomnes/npm-run-all2/commit/8004ce4f3039fe6e8d67c0b291ddf688d55176c2)
- Added `--:=` style options. [`08aa833`](https://github.com/bcomnes/npm-run-all2/commit/08aa833b5750b1fd8b4cde7463ef68c17297a0bf)
- Added postversion hook [`700b620`](https://github.com/bcomnes/npm-run-all2/commit/700b6203b20b8c72137d008c99e062cb7432eb67)
## [v1.2.13](https://github.com/bcomnes/npm-run-all2/compare/v1.2.12...v1.2.13) - 2015-11-05
### Fixed
- Fix: should not remove duplicate tasks (fixes #12) [`#12`](https://github.com/bcomnes/npm-run-all2/issues/12)
### Commits
- Upgrade: dependencies [`daad55f`](https://github.com/bcomnes/npm-run-all2/commit/daad55f95417243aa169313c145c7ee4dad2709c)
- Build: Add tests for Node.js 5 [`eabd8cf`](https://github.com/bcomnes/npm-run-all2/commit/eabd8cf5efaae9f188735735f2b46aac70afbd3d)
## [v1.2.12](https://github.com/bcomnes/npm-run-all2/compare/v1.2.10...v1.2.12) - 2015-10-18
### Commits
- Fix: added a support for built-in tasks [`b287965`](https://github.com/bcomnes/npm-run-all2/commit/b28796539082aa1d78f6777dcee9a94acf7b0594)
- Update eslint and config [`57c917c`](https://github.com/bcomnes/npm-run-all2/commit/57c917c865261314c9022d4628f7535990804eb0)
- Update .eslintrc [`97fdd8b`](https://github.com/bcomnes/npm-run-all2/commit/97fdd8b60365fb88de06bf1a15c425d11e056588)
## [v1.2.10](https://github.com/bcomnes/npm-run-all2/compare/v1.2.9...v1.2.10) - 2015-09-07
### Commits
- Remove aborting with SIGINT since stdin is inherited. [`84bff03`](https://github.com/bcomnes/npm-run-all2/commit/84bff0345933f6505c40a8cd56b9cf5460ae4664)
## [v1.2.9](https://github.com/bcomnes/npm-run-all2/compare/v1.2.8...v1.2.9) - 2015-09-07
### Commits
- Add missing .eslintrc for tests [`8c38912`](https://github.com/bcomnes/npm-run-all2/commit/8c3891277b17ec8d33f1b831b547fa8ad2595449)
- Update dependencies. [`53200d3`](https://github.com/bcomnes/npm-run-all2/commit/53200d3f2ab3638dfb26bbc9f3cb5831348c2310)
- Fix: a problem around using stdin in tasks (refs #9) [`f502903`](https://github.com/bcomnes/npm-run-all2/commit/f5029038b9b514ab6516ae650309bd0742a24095)
## [v1.2.8](https://github.com/bcomnes/npm-run-all2/compare/v1.2.7...v1.2.8) - 2015-08-26
## [v1.2.7](https://github.com/bcomnes/npm-run-all2/compare/v1.2.6...v1.2.7) - 2015-08-26
### Commits
- Update dependencies. [`2520765`](https://github.com/bcomnes/npm-run-all2/commit/2520765fe06032ef00654becbf6eccc13dc4d19a)
- Fix: Use inherit option (fixes: #8) [`736dee0`](https://github.com/bcomnes/npm-run-all2/commit/736dee0023630f8b9ce7b72e6ec79af49b35821d)
- Fix: ignores killed tasks. [`76d87cb`](https://github.com/bcomnes/npm-run-all2/commit/76d87cb25909fe5c1c518b943b32b50098bf8596)
## [v1.2.6](https://github.com/bcomnes/npm-run-all2/compare/v1.2.5...v1.2.6) - 2015-06-20
### Commits
- Kill all tasks when one of tasks exited with errors. [`87e7864`](https://github.com/bcomnes/npm-run-all2/commit/87e7864f92236218651db836b07334736dd43395)
- Update dependencies [`cf60bdf`](https://github.com/bcomnes/npm-run-all2/commit/cf60bdf09f7f04e65a4d928d2f100601f2c1bf8b)
## [v1.2.5](https://github.com/bcomnes/npm-run-all2/compare/v1.2.4...v1.2.5) - 2015-05-15
### Commits
- Update dependencies. [`448317e`](https://github.com/bcomnes/npm-run-all2/commit/448317e365d01db40950f131907773f4d4a433ef)
- Update dependencies. [`b2e2fe0`](https://github.com/bcomnes/npm-run-all2/commit/b2e2fe0b8f9c841b03743727425639efbf808915)
## [v1.2.4](https://github.com/bcomnes/npm-run-all2/compare/v1.2.3...v1.2.4) - 2015-04-26
### Commits
- Update deps and slim down npm-scripts. [`cd5c8ed`](https://github.com/bcomnes/npm-run-all2/commit/cd5c8ed1c77b8eb6651508c890486fb77b91fdc5)
## [v1.2.3](https://github.com/bcomnes/npm-run-all2/compare/v1.2.2...v1.2.3) - 2015-04-19
### Commits
- code coverage [`87a8aeb`](https://github.com/bcomnes/npm-run-all2/commit/87a8aeb865088a8012ff478855c1f650929e2381)
- Trivial fix. [`9a60535`](https://github.com/bcomnes/npm-run-all2/commit/9a60535aa21462e46962a2ef53718dd9b6ba5be5)
- Minor edits to help text [`4e8f4bd`](https://github.com/bcomnes/npm-run-all2/commit/4e8f4bd3e23ad502128bbf3ae02e8816a70fa168)
## [v1.2.2](https://github.com/bcomnes/npm-run-all2/compare/v1.2.1...v1.2.2) - 2015-04-15
### Commits
- Restore to use myself [`d41265c`](https://github.com/bcomnes/npm-run-all2/commit/d41265ceab1e1640f4ff79bbe77af691fdf4b484)
## [v1.2.1](https://github.com/bcomnes/npm-run-all2/compare/v1.2.0...v1.2.1) - 2015-04-15
### Commits
- Fix an wrong behavior [`fa42f77`](https://github.com/bcomnes/npm-run-all2/commit/fa42f772ddce0e7787231d773e9a117dfdff3612)
## [v1.2.0](https://github.com/bcomnes/npm-run-all2/compare/v1.1.3...v1.2.0) - 2015-04-15
### Commits
- New feature: glob-like task names. [`aabe1f9`](https://github.com/bcomnes/npm-run-all2/commit/aabe1f9e2f221f4592135b3a0dc9e45788175f27)
- readme improvements [`ebea491`](https://github.com/bcomnes/npm-run-all2/commit/ebea49105a89b4472bebb9b4567ce294cc391b05)
- Add about pattern-matching to README.md [`864c94f`](https://github.com/bcomnes/npm-run-all2/commit/864c94f45903e1b8f66e5d3d629bda3c577a89a3)
## [v1.1.3](https://github.com/bcomnes/npm-run-all2/compare/v1.1.2...v1.1.3) - 2015-04-12
### Commits
- Update dependencies. [`936a621`](https://github.com/bcomnes/npm-run-all2/commit/936a6210f8d60d74f3c84c77c73dd2f5696929f5)
- Adjust timing paramters... [`c362db1`](https://github.com/bcomnes/npm-run-all2/commit/c362db1a0b25784d14e6b174552f0ff25fb6cdf3)
- Fix settings for travis ci. [`c7e016a`](https://github.com/bcomnes/npm-run-all2/commit/c7e016a5010c1e57fe66b40ea4bd7eff70695fa1)
## [v1.1.2](https://github.com/bcomnes/npm-run-all2/compare/v1.1.1...v1.1.2) - 2015-04-05
### Commits
- Update dependencies. [`8a8ff02`](https://github.com/bcomnes/npm-run-all2/commit/8a8ff02aaab41dc83758a9606762634a748621e3)
## [v1.1.1](https://github.com/bcomnes/npm-run-all2/compare/v1.1.0...v1.1.1) - 2015-03-31
### Commits
- Update version of "npm-run-all" in my package.json [`db4c554`](https://github.com/bcomnes/npm-run-all2/commit/db4c5540ce97d3ce9710babf01e19614a9b46143)
## [v1.1.0](https://github.com/bcomnes/npm-run-all2/compare/v1.0.3...v1.1.0) - 2015-03-31
### Commits
- New feature: mixied running. [`0b04869`](https://github.com/bcomnes/npm-run-all2/commit/0b0486934b397349edce10246cf3f8e38acb9505)
## [v1.0.3](https://github.com/bcomnes/npm-run-all2/compare/v1.0.2...v1.0.3) - 2015-03-30
### Commits
- Update README.md [`2c19468`](https://github.com/bcomnes/npm-run-all2/commit/2c1946861fb8c2b424c9badd78896c42bbe3eab6)
- Trivial fix package.json [`4f6020c`](https://github.com/bcomnes/npm-run-all2/commit/4f6020ccb82a8362ec8839ade08ebe79bc7479f9)
- Update dependencies, and trivial update scripts. [`541e581`](https://github.com/bcomnes/npm-run-all2/commit/541e581ae2c6b8fe1541f137b203031fd83a7c9a)
## [v1.0.2](https://github.com/bcomnes/npm-run-all2/compare/v1.0.1...v1.0.2) - 2015-03-24
### Commits
- Add missing option stdin [`b6a8cae`](https://github.com/bcomnes/npm-run-all2/commit/b6a8cae59881dd3a7bf20a4c05a2ecfc0ac83524)
- Update README.md [`3c9f6e2`](https://github.com/bcomnes/npm-run-all2/commit/3c9f6e21c646dfee65902608777a34afa74c1f5b)
- Fix lint errors in test. [`9bcc9af`](https://github.com/bcomnes/npm-run-all2/commit/9bcc9af577e6a7ffb53476dc86ab10bf703b15e0)
## [v1.0.1](https://github.com/bcomnes/npm-run-all2/compare/v1.0.0...v1.0.1) - 2015-03-24
### Commits
- Use myself [`2e6ca4f`](https://github.com/bcomnes/npm-run-all2/commit/2e6ca4f190fc6d87c958d4bc2cf5e7f2e08f6787)
- Add badges [`2bab2a6`](https://github.com/bcomnes/npm-run-all2/commit/2bab2a6524abdb31119da4b243f3449b34ea7c59)
## v1.0.0 - 2015-03-24
### Commits
- Add the first version. [`b77f1a5`](https://github.com/bcomnes/npm-run-all2/commit/b77f1a5d51d62a1301c803ab95ef887c97906c48)
- Refactor [`9555a9d`](https://github.com/bcomnes/npm-run-all2/commit/9555a9dc7b9b0d7921b8f73be13a2734199f30b2)
- Create README.md [`98eca08`](https://github.com/bcomnes/npm-run-all2/commit/98eca08dc86b4ee1292cb02c05d206301964ce86)
+22
View File
@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 Toru Nagashima
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+94
View File
@@ -0,0 +1,94 @@
| index | [npm-run-all] | [run-s] | [run-p] | [Node API] |
|-------|---------------|---------|---------|------------|
# npm-run-all2
[![npm version](https://img.shields.io/npm/v/npm-run-all2.svg)](https://www.npmjs.com/package/npm-run-all2)
[![Downloads/month](https://img.shields.io/npm/dm/npm-run-all2.svg)](http://www.npmtrends.com/npm-run-all2)
[![tests](https://github.com/bcomnes/npm-run-all2/workflows/tests/badge.svg)](https://github.com/bcomnes/npm-run-all2/actions)
[![Coverage Status](https://codecov.io/gh/bcomnes/npm-run-all2/branch/master/graph/badge.svg)](https://codecov.io/gh/bcomnes/npm-run-all2)
[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard)
A CLI tool to run multiple npm-scripts in parallel or sequential.
## npm-run-all2 why?
**A maintenance fork of npm-run-all.** npm-run-all2 is a fork of npm-run-all with dependabot updates, release automation enabled and some troublesome babel stuff removed to further reduce maintenance burden. Hopefully this labor can upstream some day when mysticatea returns, but until then, welcome aboard!
## ⤴️ Motivation
- **Simplify.** The official `npm run-script` command cannot run multiple scripts, so if we want to run multiple scripts, it's redundant a bit. Let's shorten it by glob-like patterns.<br>
Before: `npm run clean && npm run build:css && npm run build:js && npm run build:html`<br>
After: `npm-run-all clean build:*`
- **Cross platform.** We sometimes use `&` to run multiple command in parallel, but `cmd.exe` (`npm run-script` uses it by default) does not support the `&`. Half of Node.js users are using it on Windows, so the use of `&` might block contributions. `npm-run-all --parallel` works well on Windows as well.
## 💿 Installation
```bash
$ npm install npm-run-all2 --save-dev
# or
$ yarn add npm-run-all2 --dev
```
- It requires `Node@>=14`. It may work on older versions of Node, but no guarantees are given.
## 📖 Usage
### CLI Commands
This `npm-run-all` package provides 3 CLI commands.
- [npm-run-all]
- [run-s]
- [run-p]
The main command is [npm-run-all].
We can make complex plans with [npm-run-all] command.
Both [run-s] and [run-p] are shorthand commands.
[run-s] is for sequential, [run-p] is for parallel.
We can make simple plans with those commands.
#### Yarn / pnpm Compatibility
`npm-run-all` is compatible with both Yarn and pnpm. If a script is invoked using either package manager, `npm-run-all` will correctly utilize it to execute the plan's child scripts.
### Node API
This `npm-run-all` package provides Node API.
- [Node API]
## 📰 Changelog
- https://github.com/bcomnes/npm-run-all2/releases
## 🍻 Contributing
Welcome♡
### Bug Reports or Feature Requests
Please use GitHub Issues.
### Correct Documents
Please use GitHub Pull Requests.
I'm not familiar with English, so I especially thank you for documents' corrections.
### Implementing
Please use GitHub Pull Requests.
There are some npm-scripts to help developments.
- **npm test** - Run tests and collect coverage.
- **npm run clean** - Delete temporary files.
- **npm run lint** - Run ESLint.
- **npm run watch** - Run tests (not collect coverage) on every file change.
[npm-run-all]: docs/npm-run-all.md
[run-s]: docs/run-s.md
[run-p]: docs/run-p.md
[Node API]: docs/node-api.md
+48
View File
@@ -0,0 +1,48 @@
/**
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
module.exports = function bootstrap (name) {
const argv = process.argv.slice(2)
switch (argv[0]) {
case undefined:
case '-h':
case '--help':
return require(`../${name}/help`)(process.stdout)
case '-v':
case '--version':
return require('./version')(process.stdout)
default:
// https://github.com/mysticatea/npm-run-all/issues/105
// Avoid MaxListenersExceededWarnings.
process.stdout.setMaxListeners(0)
process.stderr.setMaxListeners(0)
process.stdin.setMaxListeners(0)
// Main
return require(`../${name}/main`)(
argv,
process.stdout,
process.stderr
).then(
() => {
// I'm not sure why, but maybe the process never exits
// on Git Bash (MINGW64)
process.exit(0)
},
() => {
process.exit(1)
}
)
}
}
+243
View File
@@ -0,0 +1,243 @@
/**
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Helpers
// ------------------------------------------------------------------------------
const OVERWRITE_OPTION = /^--([^:]+?):([^=]+?)(?:=(.+))?$/
const CONFIG_OPTION = /^--([^=]+?)(?:=(.+))$/
const PACKAGE_CONFIG_PATTERN = /^npm_package_config_(.+)$/
const CONCAT_OPTIONS = /^-[clnprs]+$/
/**
* Overwrites a specified package config.
*
* @param {object} config - A config object to be overwritten.
* @param {string} packageName - A package name to overwrite.
* @param {string} variable - A variable name to overwrite.
* @param {string} value - A new value to overwrite.
* @returns {void}
*/
function overwriteConfig (config, packageName, variable, value) {
const scope = config[packageName] || (config[packageName] = {})
scope[variable] = value
}
/**
* Creates a package config object.
* This checks `process.env` and creates the default value.
*
* @returns {object} Created config object.
*/
function createPackageConfig () {
const retv = {}
const packageName = process.env.npm_package_name
if (!packageName) {
return retv
}
for (const key of Object.keys(process.env)) {
const m = PACKAGE_CONFIG_PATTERN.exec(key)
if (m != null) {
overwriteConfig(retv, packageName, m[1], process.env[key])
}
}
return retv
}
/**
* Adds a new group into a given list.
*
* @param {object[]} groups - A group list to add.
* @param {object} initialValues - A key-value map for the default of new value.
* @returns {void}
*/
function addGroup (groups, initialValues) {
groups.push(Object.assign(
{ parallel: false, patterns: [] },
initialValues || {}
))
}
/**
* ArgumentSet is values of parsed CLI arguments.
* This class provides the getter to get the last group.
*/
class ArgumentSet {
/**
* @param {object} initialValues - A key-value map for the default of new value.
* @param {object} options - A key-value map for the options.
*/
constructor (initialValues, options) {
this.config = {}
this.continueOnError = false
this.groups = []
this.maxParallel = 0
this.npmPath = null
this.packageConfig = createPackageConfig()
this.printLabel = false
this.printName = false
this.race = false
this.rest = []
this.silent = process.env.npm_config_loglevel === 'silent'
this.singleMode = Boolean(options && options.singleMode)
addGroup(this.groups, initialValues)
}
/**
* Gets the last group.
*/
get lastGroup () {
return this.groups[this.groups.length - 1]
}
/**
* Gets "parallel" flag.
*/
get parallel () {
return this.groups.some(g => g.parallel)
}
}
/**
* Parses CLI arguments.
*
* @param {ArgumentSet} set - The parsed CLI arguments.
* @param {string[]} args - CLI arguments.
* @returns {ArgumentSet} set itself.
*/
function parseCLIArgsCore (set, args) {
LOOP: // eslint-disable-line no-labels
for (let i = 0; i < args.length; ++i) {
const arg = args[i]
switch (arg) {
case '--':
set.rest = args.slice(1 + i)
break LOOP // eslint-disable-line no-labels
case '--color':
case '--no-color':
// do nothing.
break
case '-c':
case '--continue-on-error':
set.continueOnError = true
break
case '-l':
case '--print-label':
set.printLabel = true
break
case '-n':
case '--print-name':
set.printName = true
break
case '-r':
case '--race':
set.race = true
break
case '--silent':
set.silent = true
break
case '--max-parallel':
set.maxParallel = parseInt(args[++i], 10)
if (!Number.isFinite(set.maxParallel) || set.maxParallel <= 0) {
throw new Error(`Invalid Option: --max-parallel ${args[i]}`)
}
break
case '-s':
case '--sequential':
case '--serial':
if (set.singleMode && arg === '-s') {
set.silent = true
break
}
if (set.singleMode) {
throw new Error(`Invalid Option: ${arg}`)
}
addGroup(set.groups)
break
case '--aggregate-output':
set.aggregateOutput = true
break
case '-p':
case '--parallel':
if (set.singleMode) {
throw new Error(`Invalid Option: ${arg}`)
}
addGroup(set.groups, { parallel: true })
break
case '--npm-path':
set.npmPath = args[++i] || null
break
default: {
let matched = null
if ((matched = OVERWRITE_OPTION.exec(arg))) {
overwriteConfig(
set.packageConfig,
matched[1],
matched[2],
matched[3] || args[++i]
)
} else if ((matched = CONFIG_OPTION.exec(arg))) {
set.config[matched[1]] = matched[2]
} else if (CONCAT_OPTIONS.test(arg)) {
parseCLIArgsCore(
set,
arg.slice(1).split('').map(c => `-${c}`)
)
} else if (arg[0] === '-') {
throw new Error(`Invalid Option: ${arg}`)
} else {
set.lastGroup.patterns.push(arg)
}
break
}
}
}
if (!set.parallel && set.aggregateOutput) {
throw new Error('Invalid Option: --aggregate-output (without parallel)')
}
if (!set.parallel && set.race) {
const race = args.indexOf('--race') !== -1 ? '--race' : '-r'
throw new Error(`Invalid Option: ${race} (without parallel)`)
}
if (!set.parallel && set.maxParallel !== 0) {
throw new Error('Invalid Option: --max-parallel (without parallel)')
}
return set
}
/**
* Parses CLI arguments.
*
* @param {string[]} args - CLI arguments.
* @param {object} initialValues - A key-value map for the default of new value.
* @param {object} options - A key-value map for the options.
* @param {boolean} options.singleMode - The flag to be single group mode.
* @returns {ArgumentSet} The parsed CLI arguments.
*/
module.exports = function parseCLIArgs (args, initialValues, options) {
return parseCLIArgsCore(new ArgumentSet(initialValues, options), args)
}
+25
View File
@@ -0,0 +1,25 @@
/**
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Print a version text.
*
* @param {stream.Writable} output - A writable stream to print.
* @returns {Promise} Always a fulfilled promise.
* @private
*/
module.exports = function printVersion (output) {
const version = require('../../package.json').version
output.write(`v${version}\n`)
return Promise.resolve(null)
}
+71
View File
@@ -0,0 +1,71 @@
/**
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Print a help text.
*
* @param {stream.Writable} output - A writable stream to print.
* @returns {Promise} Always a fulfilled promise.
* @private
*/
module.exports = function printHelp (output) {
output.write(`
Usage:
$ npm-run-all [--help | -h | --version | -v]
$ npm-run-all [tasks] [OPTIONS]
Run given npm-scripts in parallel or sequential.
<tasks> : A list of npm-scripts' names and Glob-like patterns.
Options:
--aggregate-output - - - Avoid interleaving output by delaying printing of
each command's output until it has finished.
-c, --continue-on-error - Set the flag to continue executing
other/subsequent tasks even if a task threw an
error. 'npm-run-all' itself will exit with
non-zero code if one or more tasks threw error(s)
--max-parallel <number> - Set the maximum number of parallelism. Default is
unlimited.
--npm-path <string> - - - Set the path to npm. Default is the value of
environment variable npm_execpath.
If the variable is not defined, then it's "npm".
In this case, the "npm" command must be found in
environment variable PATH.
-l, --print-label - - - - Set the flag to print the task name as a prefix
on each line of output. Tools in tasks may stop
coloring their output if this option was given.
-n, --print-name - - - - Set the flag to print the task name before
running each task.
-p, --parallel <tasks> - Run a group of tasks in parallel.
e.g. 'npm-run-all -p foo bar' is similar to
'npm run foo & npm run bar'.
-r, --race - - - - - - - Set the flag to kill all tasks when a task
finished with zero. This option is valid only
with 'parallel' option.
-s, --sequential <tasks> - Run a group of tasks sequentially.
--serial <tasks> e.g. 'npm-run-all -s foo bar' is similar to
'npm run foo && npm run bar'.
'--serial' is a synonym of '--sequential'.
--silent - - - - - - - - Set 'silent' to the log level of npm.
Examples:
$ npm-run-all --serial clean lint build:**
$ npm-run-all --parallel watch:**
$ npm-run-all clean lint --parallel "build:** -- --watch"
$ npm-run-all -l -p start-server start-browser start-electron
See Also:
https://github.com/mysticatea/npm-run-all#readme
`)
return Promise.resolve(null)
}
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env node
/**
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Main
// ------------------------------------------------------------------------------
require('../common/bootstrap')('npm-run-all')
+74
View File
@@ -0,0 +1,74 @@
/**
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const runAll = require('../../lib')
const parseCLIArgs = require('../common/parse-cli-args')
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Parses arguments, then run specified npm-scripts.
*
* @param {string[]} args - Arguments to parse.
* @param {stream.Writable} stdout - A writable stream to print logs.
* @param {stream.Writable} stderr - A writable stream to print errors.
* @returns {Promise} A promise which comes to be fulfilled when all npm-scripts are completed.
* @private
*/
module.exports = function npmRunAll (args, stdout, stderr) {
try {
const stdin = process.stdin
const argv = parseCLIArgs(args)
const promise = argv.groups.reduce(
(prev, group) => {
if (group.patterns.length === 0) {
return prev
}
return prev.then(() => runAll(
group.patterns,
{
stdout,
stderr,
stdin,
parallel: group.parallel,
maxParallel: group.parallel ? argv.maxParallel : 1,
continueOnError: argv.continueOnError,
printLabel: argv.printLabel,
printName: argv.printName,
config: argv.config,
packageConfig: argv.packageConfig,
silent: argv.silent,
arguments: argv.rest,
race: group.parallel && argv.race,
npmPath: argv.npmPath,
aggregateOutput: group.parallel && argv.aggregateOutput,
}
))
},
Promise.resolve(null)
)
if (!argv.silent) {
promise.catch(err => {
console.error('ERROR:', err.message)
})
}
return promise
} catch (err) {
console.error('ERROR:', err.message)
return Promise.reject(err)
}
}
+66
View File
@@ -0,0 +1,66 @@
/**
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Print a help text.
*
* @param {stream.Writable} output - A writable stream to print.
* @returns {Promise} Always a fulfilled promise.
* @private
*/
module.exports = function printHelp (output) {
output.write(`
Usage:
$ run-p [--help | -h | --version | -v]
$ run-p [OPTIONS] <tasks>
Run given npm-scripts in parallel.
<tasks> : A list of npm-scripts' names and Glob-like patterns.
Options:
--aggregate-output - - - Avoid interleaving output by delaying printing of
each command's output until it has finished.
-c, --continue-on-error - Set the flag to continue executing other tasks
even if a task threw an error. 'run-p' itself
will exit with non-zero code if one or more tasks
threw error(s).
--max-parallel <number> - Set the maximum number of parallelism. Default is
unlimited.
--npm-path <string> - - - Set the path to npm. Default is the value of
environment variable npm_execpath.
If the variable is not defined, then it's "npm."
In this case, the "npm" command must be found in
environment variable PATH.
-l, --print-label - - - - Set the flag to print the task name as a prefix
on each line of output. Tools in tasks may stop
coloring their output if this option was given.
-n, --print-name - - - - Set the flag to print the task name before
running each task.
-r, --race - - - - - - - Set the flag to kill all tasks when a task
finished with zero.
-s, --silent - - - - - - Set 'silent' to the log level of npm.
Shorthand aliases can be combined.
For example, '-clns' equals to '-c -l -n -s'.
Examples:
$ run-p watch:**
$ run-p --print-label "build:** -- --watch"
$ run-p -sl "build:** -- --watch"
$ run-p start-server start-browser start-electron
See Also:
https://github.com/mysticatea/npm-run-all#readme
`)
return Promise.resolve(null)
}
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env node
/**
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Main
// ------------------------------------------------------------------------------
require('../common/bootstrap')('run-p')
+71
View File
@@ -0,0 +1,71 @@
/**
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const runAll = require('../../lib')
const parseCLIArgs = require('../common/parse-cli-args')
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Parses arguments, then run specified npm-scripts.
*
* @param {string[]} args - Arguments to parse.
* @param {stream.Writable} stdout - A writable stream to print logs.
* @param {stream.Writable} stderr - A writable stream to print errors.
* @returns {Promise} A promise which comes to be fulfilled when all npm-scripts are completed.
* @private
*/
module.exports = function npmRunAll (args, stdout, stderr) {
try {
const stdin = process.stdin
const argv = parseCLIArgs(args, { parallel: true }, { singleMode: true })
const group = argv.lastGroup
if (group.patterns.length === 0) {
return Promise.resolve(null)
}
const promise = runAll(
group.patterns,
{
stdout,
stderr,
stdin,
parallel: group.parallel,
maxParallel: argv.maxParallel,
continueOnError: argv.continueOnError,
printLabel: argv.printLabel,
printName: argv.printName,
config: argv.config,
packageConfig: argv.packageConfig,
silent: argv.silent,
arguments: argv.rest,
race: argv.race,
npmPath: argv.npmPath,
aggregateOutput: argv.aggregateOutput,
}
)
if (!argv.silent) {
promise.catch(err => {
console.error('ERROR:', err.message)
})
}
return promise
} catch (err) {
console.error('ERROR:', err.message)
return Promise.reject(err)
}
}
+60
View File
@@ -0,0 +1,60 @@
/**
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Print a help text.
*
* @param {stream.Writable} output - A writable stream to print.
* @returns {Promise} Always a fulfilled promise.
* @private
*/
module.exports = function printHelp (output) {
output.write(`
Usage:
$ run-s [--help | -h | --version | -v]
$ run-s [OPTIONS] <tasks>
Run given npm-scripts sequentially.
<tasks> : A list of npm-scripts' names and Glob-like patterns.
Options:
-c, --continue-on-error - Set the flag to continue executing subsequent
tasks even if a task threw an error. 'run-s'
itself will exit with non-zero code if one or
more tasks threw error(s).
--npm-path <string> - - - Set the path to npm. Default is the value of
environment variable npm_execpath.
If the variable is not defined, then it's "npm."
In this case, the "npm" command must be found in
environment variable PATH.
-l, --print-label - - - - Set the flag to print the task name as a prefix
on each line of output. Tools in tasks may stop
coloring their output if this option was given.
-n, --print-name - - - - Set the flag to print the task name before
running each task.
-s, --silent - - - - - - Set 'silent' to the log level of npm.
Shorthand aliases can be combined.
For example, '-clns' equals to '-c -l -n -s'.
Examples:
$ run-s build:**
$ run-s lint clean build:**
$ run-s --silent --print-name lint clean build:**
$ run-s -sn lint clean build:**
See Also:
https://github.com/mysticatea/npm-run-all#readme
`)
return Promise.resolve(null)
}
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env node
/**
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Main
// ------------------------------------------------------------------------------
require('../common/bootstrap')('run-s')
+68
View File
@@ -0,0 +1,68 @@
/**
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const runAll = require('../../lib')
const parseCLIArgs = require('../common/parse-cli-args')
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Parses arguments, then run specified npm-scripts.
*
* @param {string[]} args - Arguments to parse.
* @param {stream.Writable} stdout - A writable stream to print logs.
* @param {stream.Writable} stderr - A writable stream to print errors.
* @returns {Promise} A promise which comes to be fulfilled when all npm-scripts are completed.
* @private
*/
module.exports = function npmRunAll (args, stdout, stderr) {
try {
const stdin = process.stdin
const argv = parseCLIArgs(args, { parallel: false }, { singleMode: true })
const group = argv.lastGroup
if (group.patterns.length === 0) {
return Promise.resolve(null)
}
const promise = runAll(
group.patterns,
{
stdout,
stderr,
stdin,
parallel: group.parallel,
continueOnError: argv.continueOnError,
printLabel: argv.printLabel,
printName: argv.printName,
config: argv.config,
packageConfig: argv.packageConfig,
silent: argv.silent,
arguments: argv.rest,
npmPath: argv.npmPath,
}
)
if (!argv.silent) {
promise.catch(err => {
console.error('ERROR:', err.message)
})
}
return promise
} catch (err) {
console.error('ERROR:', err.message)
return Promise.reject(err)
}
}
+117
View File
@@ -0,0 +1,117 @@
| [index](../README.md) | [npm-run-all](npm-run-all.md) | [run-s](run-s.md) | [run-p](run-p.md) | Node API |
|-----------------------|-------------------------------|-------------------|-------------------|----------|
# Node API
A Node module to run given npm-scripts in parallel or sequential.
```js
const runAll = require("npm-run-all");
runAll(["clean", "lint", "build:*"], {parallel: false})
.then(() => {
console.log("done!");
})
.catch(err => {
console.log("failed!");
});
runAll(["build:* -- --watch"], {parallel: true})
.then(() => {
console.log("done!");
})
.catch(err => {
console.log("failed!");
});
```
## runAll
```
let promise = runAll(patterns, options);
```
Run npm-scripts.
- **patterns** `string|string[]` -- Glob-like patterns for script names.
- **options** `object`
- **options.aggregateOutput** `boolean` --
The flag to avoid interleaving output by delaying printing of each command's output until it has finished.
This option is valid only with `options.parallel` option.
Default is `false`.
- **options.arguments** `string[]` --
An argument list to replace argument placeholders (such as `{1}`, `{2}`). If pattern text has `{1}`, it's replaced by `options.arguments[0]`.
Default is an empty array.
- **options.continueOnError** `boolean` --
The flag to continue executing other/subsequent scripts even if a script threw an error.
Returned `Promise` object will be rejected if one or more scripts threw error(s).
Default is `false`.
- **options.parallel** `boolean` --
The flag to run scripts in parallel.
Default is `false`.
- **options.maxParallel** `number` --
The maximum number of parallelism.
This option is valid only with `options.parallel` option.
Default is `Number.POSITIVE_INFINITY`.
- **options.npmPath** `string` --
The path to npm.
Default is `process.env.npm_execpath` or `"npm"`.
- **options.packageConfig** `object|null` --
The map-like object to overwrite package configs.
Keys are package names.
Every value is a map-like object (Pairs of variable name and value).
e.g. `{"npm-run-all": {"test": 777, "test2": 333}}`
Default is `null`.
- **options.printLabel** `boolean` --
Set the flag to print the task name as a prefix on each line of output.
Tools in scripts may stop coloring their output if this option is given.
Default is `false`.
- **options.printName** `boolean` --
Set the flag to print the task name before running each task.
Default is `false`.
- **options.race** `boolean` --
Set the flag to kill all npm-scripts when a npm-script finished with zero.
This option is valid only with `options.parallel` option.
Default is `false`.
- **options.silent** `boolean` --
The flag to set `silent` to the log level of npm.
Default is `false`.
- **options.stdin** `stream.Readable|null` --
The readable stream to send to the stdin of npm-scripts.
Default is nothing.
Set `process.stdin` in order to send from stdin.
- **options.stdout** `stream.Writable|null` --
The writable stream to receive from the stdout of npm-scripts.
Default is nothing.
Set `process.stdout` in order to print to stdout.
- **options.stderr** `stream.Writable|null` --
The writable stream to receive from the stderr of npm-scripts
Default is nothing.
Set `process.stderr` in order to print to stderr.
- **options.taskList** `string[]|null` --
The string array of all script names.
If this is `null`, it reads from `package.json` in the current directory.
Default is `null`.
`runAll` returns a promise that will becomes *fulfilled* when all scripts are completed.
The promise will become *rejected* when any of the scripts exit with a non-zero code.
The promise gives `results` to the fulfilled handler.
`results` is an array of objects which have 2 properties: `name` and `code`.
The `name` property is the name of a npm-script.
The `code` property is the exit code of the npm-script. If the npm-script was not executed, the `code` property is `undefined`.
```js
runAll(["clean", "lint", "build"])
.then(results => {
console.log(`${results[0].name}: ${results[0].code}`); // clean: 0
console.log(`${results[1].name}: ${results[1].code}`); // lint: 0
console.log(`${results[2].name}: ${results[2].code}`); // build: 0
});
```
## About MaxListenersExceededWarning
- If you use `options.stdin`, `options.stdout`, or `options.stderr` in parallel mode, please configure max listeners by [emitter.setMaxListeners(n)](https://nodejs.org/api/events.html#events_emitter_setmaxlisteners_n) properly.
- If you don't use those options and `process.stdXXX.isTTY` is `false`, please configure max listeners of the `process.stdXXX` properly. In that case, `npm-run-all` uses piping to connect to child processes.<br>
On the other hand, if `process.stdXXX.isTTY` is `true`, `npm-run-all` uses `inherit` option, so the configuration is unnecessary.
+198
View File
@@ -0,0 +1,198 @@
| [index](../README.md) | npm-run-all | [run-s](run-s.md) | [run-p](run-p.md) | [Node API](node-api.md) |
|-----------------------|-------------|-------------------|-------------------|-------------------------|
# `npm-run-all` command
```
Usage:
$ npm-run-all [--help | -h | --version | -v]
$ npm-run-all [tasks] [OPTIONS]
Run given npm-scripts in parallel or sequential.
<tasks> : A list of npm-scripts' names and Glob-like patterns.
Options:
--aggregate-output - - - Avoid interleaving output by delaying printing of
each command's output until it has finished.
-c, --continue-on-error - Set the flag to continue executing
other/subsequent tasks even if a task threw an
error. 'npm-run-all' itself will exit with
non-zero code if one or more tasks threw error(s)
--max-parallel <number> - Set the maximum number of parallelism. Default is
unlimited.
--npm-path <string> - - - Set the path to npm. Default is the value of
environment variable npm_execpath.
If the variable is not defined, then it's "npm."
In this case, the "npm" command must be found in
environment variable PATH.
-l, --print-label - - - - Set the flag to print the task name as a prefix
on each line of output. Tools in tasks may stop
coloring their output if this option was given.
-n, --print-name - - - - Set the flag to print the task name before
running each task.
-p, --parallel <tasks> - Run a group of tasks in parallel.
e.g. 'npm-run-all -p foo bar' is similar to
'npm run foo & npm run bar'.
-r, --race - - - - - - - Set the flag to kill all tasks when a task
finished with zero. This option is valid only
with 'parallel' option.
-s, --sequential <tasks> - Run a group of tasks sequentially.
--serial <tasks> e.g. 'npm-run-all -s foo bar' is similar to
'npm run foo && npm run bar'.
'--serial' is a synonym of '--sequential'.
--silent - - - - - - - - Set 'silent' to the log level of npm.
Examples:
$ npm-run-all --serial clean lint build:**
$ npm-run-all --parallel watch:**
$ npm-run-all clean lint --parallel "build:** -- --watch"
$ npm-run-all -l -p start-server start-browser start-electron
```
### npm-scripts
It's `"scripts"` field of `package.json`.
For example:
```json
{
"scripts": {
"clean": "rm -rf dist",
"lint": "eslint src",
"build": "babel src -o lib"
}
}
```
We can run a script with `npm run` command.
On the other hand, this `npm-run-all` command runs multiple scripts in parallel or sequential.
### Run scripts sequentially
```
$ npm-run-all clean lint build
```
This is same as `npm run clean && npm run lint && npm run build`.
**Note:** If a script exited with non zero code, the following scripts are not run.
If `--continue-on-error` option is given, this behavior will be disabled.
### Run scripts in parallel
```
$ npm-run-all --parallel lint build
```
This is similar to `npm run lint & npm run build`.
**Note1:** If a script exited with a non-zero code, the other scripts and those descendant processes are killed with `SIGTERM` (On Windows, with `taskkill.exe /F /T`).
If `--continue-on-error` option is given, this behavior will be disabled.
**Note2:** `&` operator does not work on Windows' `cmd.exe`. But `npm-run-all --parallel` works fine there.
### Run a mix of sequential and parallel scripts
```
$ npm-run-all clean lint --parallel watch:html watch:js
```
1. First, this runs `clean` and `lint` sequentially / serially.
2. Next, runs `watch:html` and `watch:js` in parallel.
```
$ npm-run-all a b --parallel c d --sequential e f --parallel g h i
```
or
```
$ npm-run-all a b --parallel c d --serial e f --parallel g h i
```
1. First, runs `a` and `b` sequentially / serially.
2. Second, runs `c` and `d` in parallel.
3. Third, runs `e` and `f` sequentially / serially.
4. Lastly, runs `g`, `h`, and `i` in parallel.
### Glob-like pattern matching for script names
We can use [glob]-like patterns to specify npm-scripts.
The difference is one -- the separator is `:` instead of `/`.
```
$ npm-run-all --parallel watch:*
```
In this case, runs sub scripts of `watch`. For example: `watch:html`, `watch:js`.
But, doesn't run sub-sub scripts. For example: `watch:js:index`.
```
$ npm-run-all --parallel watch:**
```
If we use a globstar `**`, runs both sub scripts and sub-sub scripts.
`npm-run-all` reads the actual npm-script list from `package.json` in the current directory, then filters the scripts by glob-like patterns, then runs those.
### Run with arguments
We can enclose a script name or a pattern in quotes to use arguments.
The following 2 commands are similar.
```
$ npm-run-all --parallel "build:* -- --watch"
$ npm run build:aaa -- --watch & npm run build:bbb -- --watch
```
When we use a pattern, arguments are forwarded to every matched script.
### Argument placeholders
We can use placeholders to give the arguments preceded by `--` to scripts.
```
$ npm-run-all build "start-server -- --port {1}" -- 8080
```
This is useful to pass through arguments from `npm run` command.
```json
{
"scripts": {
"start": "npm-run-all build \"start-server -- --port {1}\" --"
}
}
```
```
$ npm run start 8080
> example@0.0.0 start /path/to/package.json
> npm-run-all build "start-server -- --port {1}" -- "8080"
```
There are the following placeholders:
- `{1}`, `{2}`, ... -- An argument. `{1}` is the 1st argument. `{2}` is the 2nd.
- `{@}` -- All arguments.
- `{*}` -- All arguments as combined.
- `{%}` -- Repeats the command for every argument. (There's no equivalent shell parameter and does not support suffixes)
Support for following suffixes:
- `{1-=foo}` -- defaults to `'foo'` here when the 1st argument is missing
- `{1:=foo}` -- defaults to `'foo'` here and in all following `{1}` when the 1st argument is missing
Those are similar to [Shell Parameters](http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameters). But please note arguments are enclosed by double quotes automatically (similar to npm).
### Known Limitations
- If `--print-label` option is given, some tools in scripts might stop coloring their output.
Because some coloring library (e.g. [chalk]) will stop coloring if `process.stdout` is not a TTY.
`npm-run-all` changes the `process.stdout` of child processes to a pipe in order to add labels to the head of each line if `--print-label` option is given.<br>
For example, [eslint] stops coloring under `npm-run-all --print-label`. But [eslint] has `--color` option to force coloring, we can use it. For anything [chalk] based you can set the environment variable `FORCE_COLOR=1` to produce colored output anyway.
[glob]: https://www.npmjs.com/package/glob#glob-primer
[chalk]: https://www.npmjs.com/package/chalk
[eslint]: https://www.npmjs.com/package/eslint
+162
View File
@@ -0,0 +1,162 @@
| [index](../README.md) | [npm-run-all](npm-run-all.md) | [run-s](run-s.md) | run-p | [Node API](node-api.md) |
|-----------------------|-------------------------------|-------------------|-------|-------------------------|
# `run-p` command
A CLI command to run given npm-scripts in parallel.
This command is the shorthand of `npm-run-all -p`.
```
Usage:
$ run-p [--help | -h | --version | -v]
$ run-p [OPTIONS] <tasks>
Run given npm-scripts in parallel.
<tasks> : A list of npm-scripts' names and Glob-like patterns.
Options:
--aggregate-output - - - Avoid interleaving output by delaying printing of
each command's output until it has finished.
-c, --continue-on-error - Set the flag to continue executing other tasks
even if a task threw an error. 'run-p' itself
will exit with non-zero code if one or more tasks
threw error(s).
--max-parallel <number> - Set the maximum number of parallelism. Default is
unlimited.
--npm-path <string> - - - Set the path to npm. Default is the value of
environment variable npm_execpath.
If the variable is not defined, then it's "npm."
In this case, the "npm" command must be found in
environment variable PATH.
-l, --print-label - - - - Set the flag to print the task name as a prefix
on each line of output. Tools in tasks may stop
coloring their output if this option was given.
-n, --print-name - - - - Set the flag to print the task name before
running each task.
-r, --race - - - - - - - Set the flag to kill all tasks when a task
finished with zero.
-s, --silent - - - - - - Set 'silent' to the log level of npm.
Shorthand aliases can be combined.
For example, '-clns' equals to '-c -l -n -s'.
Examples:
$ run-p watch:**
$ run-p --print-label "build:** -- --watch"
$ run-p -l "build:** -- --watch"
$ run-p start-server start-browser start-electron
```
### npm-scripts
It's `"scripts"` field of `package.json`.
For example:
```json
{
"scripts": {
"clean": "rm -rf dist",
"lint": "eslint src",
"build": "babel src -o lib"
}
}
```
We can run a script with `npm run` command.
On the other hand, this `run-p` command runs multiple scripts in parallel.
The following 2 commands are similar.
The `run-p` command is shorter and **available on Windows**.
```
$ run-p lint build
$ npm run lint & npm run build
```
**Note1:** If a script exited with a non-zero code, the other scripts and those descendant processes are killed with `SIGTERM` (On Windows, with `taskkill.exe /F /T`).
If `--continue-on-error` option is given, this behavior will be disabled.
**Note2:** `&` operator does not work on Windows' `cmd.exe`. But `run-p` works fine there.
### Glob-like pattern matching for script names
We can use [glob]-like patterns to specify npm-scripts.
The difference is one -- the separator is `:` instead of `/`.
```
$ run-p watch:*
```
In this case, runs sub scripts of `watch`. For example: `watch:html`, `watch:js`.
But, doesn't run sub-sub scripts. For example: `watch:js:index`.
```
$ run-p watch:**
```
If we use a globstar `**`, runs both sub scripts and sub-sub scripts.
`run-p` reads the actual npm-script list from `package.json` in the current directory, then filters the scripts by glob-like patterns, then runs those.
### Run with arguments
We can enclose a script name or a pattern in quotes to use arguments.
The following 2 commands are similar.
```
$ run-p "build:* -- --watch"
$ npm run build:aaa -- --watch & npm run build:bbb -- --watch
```
When we use a pattern, arguments are forwarded to every matched script.
### Argument placeholders
We can use placeholders to give the arguments preceded by `--` to scripts.
```
$ run-p "start-server -- --port {1}" -- 8080
```
This is useful to pass through arguments from `npm run` command.
```json
{
"scripts": {
"start": "run-p \"start-server -- --port {1}\" --"
}
}
```
```
$ npm run start 8080
> example@0.0.0 start /path/to/package.json
> run-p "start-server -- --port {1}" -- "8080"
```
There are the following placeholders:
- `{1}`, `{2}`, ... -- An argument. `{1}` is the 1st argument. `{2}` is the 2nd.
- `{@}` -- All arguments.
- `{*}` -- All arguments as combined.
- `{%}` -- Repeats the command for every argument. (There's no equivalent shell parameter and does not support suffixes)
Support for following suffixes:
- `{1-=foo}` -- defaults to `'foo'` here when the 1st argument is missing
- `{1:=foo}` -- defaults to `'foo'` here and in all following `{1}` when the 1st argument is missing
Those are similar to [Shell Parameters](http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameters). But please note arguments are enclosed by double quotes automatically (similar to npm).
### Known Limitations
- If `--print-label` option is given, some tools in scripts might stop coloring their output.
Because some coloring library (e.g. [chalk]) will stop coloring if `process.stdout` is not a TTY.
`run-p` changes the `process.stdout` of child processes to a pipe in order to add labels to the head of each line if `--print-label` option is given.<br>
For example, [eslint] stops coloring under `run-p --print-label`. But [eslint] has `--color` option to force coloring, we can use it.
[glob]: https://www.npmjs.com/package/glob#glob-primer
[chalk]: https://www.npmjs.com/package/chalk
[eslint]: https://www.npmjs.com/package/eslint
+153
View File
@@ -0,0 +1,153 @@
| [index](../README.md) | [npm-run-all](npm-run-all.md) | run-s | [run-p](run-p.md) | [Node API](node-api.md) |
|-----------------------|-------------------------------|-------|-------------------|-------------------------|
# `run-s` command
A CLI command to run given npm-scripts sequentially.
This command is the shorthand of `npm-run-all -s`.
```
Usage:
$ run-s [--help | -h | --version | -v]
$ run-s [OPTIONS] <tasks>
Run given npm-scripts sequentially.
<tasks> : A list of npm-scripts' names and Glob-like patterns.
Options:
-c, --continue-on-error - Set the flag to continue executing subsequent
tasks even if a task threw an error. 'run-s'
itself will exit with non-zero code if one or
more tasks threw error(s).
--npm-path <string> - - - Set the path to npm. Default is the value of
environment variable npm_execpath.
If the variable is not defined, then it's "npm."
In this case, the "npm" command must be found in
environment variable PATH.
-l, --print-label - - - - Set the flag to print the task name as a prefix
on each line of output. Tools in tasks may stop
coloring their output if this option was given.
-n, --print-name - - - - Set the flag to print the task name before
running each task.
-s, --silent - - - - - - Set 'silent' to the log level of npm.
Shorthand aliases can be combined.
For example, '-clns' equals to '-c -l -n -s'.
Examples:
$ run-s build:**
$ run-s lint clean build:**
$ run-s --silent --print-name lint clean build:**
$ run-s -sn lint clean build:**
```
### npm-scripts
It's `"scripts"` field of `package.json`.
For example:
```json
{
"scripts": {
"clean": "rm -rf dist",
"lint": "eslint src",
"build": "babel src -o lib"
}
}
```
We can run a script with `npm run` command.
On the other hand, this `run-s` command runs multiple scripts sequentially.
The following 2 commands are the same.
The `run-s` command is shorter.
```
$ run-s clean lint build
$ npm run clean && npm run lint && npm run build
```
**Note:** If a script exited with a non-zero code, the following scripts are not run.
### Glob-like pattern matching for script names
We can use [glob]-like patterns to specify npm-scripts.
The difference is one -- the separator is `:` instead of `/`.
```
$ run-s build:*
```
In this case, runs sub scripts of `build`. For example: `build:html`, `build:js`.
But, doesn't run sub-sub scripts. For example: `build:js:index`.
```
$ run-s build:**
```
If we use a globstar `**`, runs both sub scripts and sub-sub scripts.
`run-s` reads the actual npm-script list from `package.json` in the current directory, then filters the scripts by glob-like patterns, then runs those.
### Run with arguments
We can enclose a script name or a pattern in quotes to use arguments.
The following 2 commands are the same.
```
$ run-s start:server "delay 3000" start:client
$ npm run start:server && npm run delay 3000 && npm run start:client
```
When we use a pattern, arguments are forwarded to every matched script.
### Argument placeholders
We can use placeholders to give the arguments preceded by `--` to scripts.
```
$ run-s build "start-server -- --port {1}" -- 8080
```
This is useful to pass through arguments from `npm run` command.
```json
{
"scripts": {
"start": "run-s build \"start-server -- --port {1}\" --"
}
}
```
```
$ npm run start 8080
> example@0.0.0 start /path/to/package.json
> run-s build "start-server -- --port {1}" -- "8080"
```
There are the following placeholders:
- `{1}`, `{2}`, ... -- An argument. `{1}` is the 1st argument. `{2}` is the 2nd.
- `{@}` -- All arguments.
- `{*}` -- All arguments as combined.
- `{%}` -- Repeats the command for every argument. (There's no equivalent shell parameter and does not support suffixes)
Support for following suffixes:
- `{1-=foo}` -- defaults to `'foo'` here when the 1st argument is missing
- `{1:=foo}` -- defaults to `'foo'` here and in all following `{1}` when the 1st argument is missing
Those are similar to [Shell Parameters](http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameters). But please note arguments are enclosed by double quotes automatically (similar to npm).
### Known Limitations
- If `--print-label` option is given, some tools in scripts might stop coloring their output.
Because some coloring library (e.g. [chalk]) will stop coloring if `process.stdout` is not a TTY.
`run-s` changes the `process.stdout` of child processes to a pipe in order to add labels to the head of each line if `--print-label` option is given.<br>
For example, [eslint] stops coloring under `run-s --print-label`. But [eslint] has `--color` option to force coloring, we can use it.
[glob]: https://www.npmjs.com/package/glob#glob-primer
[chalk]: https://www.npmjs.com/package/chalk
[eslint]: https://www.npmjs.com/package/eslint
+9
View File
@@ -0,0 +1,9 @@
'use strict'
module.exports = [
...require('neostandard')({
env: ['mocha'],
ignores: require('neostandard').resolveIgnoresFromGitignore(),
ts: true,
}),
]
+10
View File
@@ -0,0 +1,10 @@
{
"source": {
"include": ["lib", "README.md"]
},
"opts": {
"destination": "jsdoc",
"encoding": "utf8",
"recurse": true
}
}
+42
View File
@@ -0,0 +1,42 @@
/**
* @module create-header
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Creates the header text for a given task.
*
* @param {string} nameAndArgs - A task name and arguments.
* @param {object} packageInfo - A package.json's information.
* @param {object} packageInfo.body - A package.json's JSON object.
* @param {string} packageInfo.path - A package.json's file path.
* @param {boolean} isTTY - The flag to color the header.
* @returns {string} The header of a given task.
*/
module.exports = function createHeader (nameAndArgs, packageInfo, isTTY, ansiStyles) {
if (!packageInfo) {
return `\n> ${nameAndArgs}\n\n`
}
const index = nameAndArgs.indexOf(' ')
const name = (index === -1) ? nameAndArgs : nameAndArgs.slice(0, index)
const args = (index === -1) ? '' : nameAndArgs.slice(index + 1)
const packageName = packageInfo.body.name
const packageVersion = packageInfo.body.version
const scriptBody = packageInfo.body.scripts[name]
const packagePath = packageInfo.path
const color = isTTY ? ansiStyles.gray : { open: '', close: '' }
return `
${color.open}> ${packageName}@${packageVersion} ${name} ${packagePath}${color.close}
${color.open}> ${scriptBody} ${args}${color.close}
`
}
@@ -0,0 +1,91 @@
/**
* @module create-prefix-transform-stream
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const stream = require('stream')
// ------------------------------------------------------------------------------
// Helpers
// ------------------------------------------------------------------------------
const ALL_BR = /\n/g
/**
* The transform stream to insert a specific prefix.
*
* Several streams can exist for the same output stream.
* This stream will insert the prefix if the last output came from other instance.
* To do that, this stream is using a shared state object.
*
* @private
*/
class PrefixTransform extends stream.Transform {
/**
* @param {string} prefix - A prefix text to be inserted.
* @param {object} state - A state object.
* @param {string} state.lastPrefix - The last prefix which is printed.
* @param {boolean} state.lastIsLinebreak -The flag to check whether the last output is a line break or not.
*/
constructor (prefix, state) {
super()
this.prefix = prefix
this.state = state
}
/**
* Transforms the output chunk.
*
* @param {string|Buffer} chunk - A chunk to be transformed.
* @param {string} _encoding - The encoding of the chunk.
* @param {function} callback - A callback function that is called when done.
* @returns {void}
*/
_transform (chunk, _encoding, callback) {
const prefix = this.prefix
const nPrefix = `\n${prefix}`
const state = this.state
const firstPrefix =
state.lastIsLinebreak
? prefix
: (state.lastPrefix !== prefix)
? '\n'
: ''
const prefixed = `${firstPrefix}${chunk}`.replace(ALL_BR, nPrefix)
const index = prefixed.indexOf(prefix, Math.max(0, prefixed.length - prefix.length))
state.lastPrefix = prefix
state.lastIsLinebreak = (index !== -1)
callback(null, (index !== -1) ? prefixed.slice(0, index) : prefixed)
}
}
// ------------------------------------------------------------------------------
// Public API
// ------------------------------------------------------------------------------
/**
* Create a transform stream to insert the specific prefix.
*
* Several streams can exist for the same output stream.
* This stream will insert the prefix if the last output came from other instance.
* To do that, this stream is using a shared state object.
*
* @param {string} prefix - A prefix text to be inserted.
* @param {object} state - A state object.
* @param {string} state.lastPrefix - The last prefix which is printed.
* @param {boolean} state.lastIsLinebreak -The flag to check whether the last output is a line break or not.
* @returns {stream.Transform} The created transform stream.
*/
module.exports = function createPrefixTransform (prefix, state) {
return new PrefixTransform(prefix, state)
}
+306
View File
@@ -0,0 +1,306 @@
/**
* @module index
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const shellQuote = require('shell-quote')
const matchTasks = require('./match-tasks')
const readPackageJson = require('./read-package-json')
const runTasks = require('./run-tasks')
// ------------------------------------------------------------------------------
// Helpers
// ------------------------------------------------------------------------------
const ARGS_PATTERN = /\{(!)?([*@%]|\d+)([^}]+)?}/g
const ARGS_UNPACK_PATTERN = /\{(!)?([%])([^}]+)?}/g
/**
* Converts a given value to an array.
*
* @param {string|string[]|null|undefined} x - A value to convert.
* @returns {string[]} An array.
*/
function toArray (x) {
if (x == null) {
return []
}
return Array.isArray(x) ? x : [x]
}
/**
* Replaces argument placeholders (such as `{1}`) by arguments.
*
* @param {string[]} patterns - Patterns to replace.
* @param {string[]} args - Arguments to replace.
* @returns {string[]} replaced
*/
function applyArguments (patterns, args) {
const defaults = Object.create(null)
const unfoldedPatterns = patterns
.flatMap(pattern => {
const match = ARGS_UNPACK_PATTERN.exec(pattern)
if (match && match[2] === '%') {
const result = []
for (let i = 0, length = args.length; i < length; i++) {
const argPosition = i + 1
result.push(pattern.replace(ARGS_UNPACK_PATTERN, (whole, indirectionMark, id, options) => {
if (indirectionMark != null || options != null || id !== '%') {
throw Error(`Invalid Placeholder: ${whole}`)
}
return `{${argPosition}}`
}))
}
return result
}
return pattern
})
return unfoldedPatterns.map(pattern => pattern.replace(ARGS_PATTERN, (whole, indirectionMark, id, options) => {
if (indirectionMark != null) {
throw Error(`Invalid Placeholder: ${whole}`)
}
if (id === '@') {
return shellQuote.quote(args)
}
if (id === '*') {
return shellQuote.quote([args.join(' ')])
}
const position = parseInt(id, 10)
if (position >= 1 && position <= args.length) {
return shellQuote.quote([args[position - 1]])
}
// Address default values
if (options != null) {
const prefix = options.slice(0, 2)
if (prefix === ':=') {
defaults[id] = shellQuote.quote([options.slice(2)])
return defaults[id]
}
if (prefix === ':-') {
return shellQuote.quote([options.slice(2)])
}
throw Error(`Invalid Placeholder: ${whole}`)
}
if (defaults[id] != null) {
return defaults[id]
}
return ''
}))
}
/**
* Parse patterns.
* In parsing process, it replaces argument placeholders (such as `{1}`) by arguments.
*
* @param {string|string[]} patternOrPatterns - Patterns to run.
* A pattern is a npm-script name or a Glob-like pattern.
* @param {string[]} args - Arguments to replace placeholders.
* @returns {string[]} Parsed patterns.
*/
function parsePatterns (patternOrPatterns, args) {
const patterns = toArray(patternOrPatterns)
const hasPlaceholder = patterns.some(pattern => ARGS_PATTERN.test(pattern))
return hasPlaceholder ? applyArguments(patterns, args) : patterns
}
/**
* Converts a given config object to an `--:=` style option array.
*
* @param {object|null} config -
* A map-like object to overwrite package configs.
* Keys are package names.
* Every value is a map-like object (Pairs of variable name and value).
* @returns {string[]} `--:=` style options.
*/
function toOverwriteOptions (config) {
const options = []
for (const packageName of Object.keys(config)) {
const packageConfig = config[packageName]
for (const variableName of Object.keys(packageConfig)) {
const value = packageConfig[variableName]
options.push(`--${packageName}:${variableName}=${value}`)
}
}
return options
}
/**
* Converts a given config object to an `--a=b` style option array.
*
* @param {object|null} config -
* A map-like object to set configs.
* @returns {string[]} `--a=b` style options.
*/
function toConfigOptions (config) {
return Object.keys(config).map(key => `--${key}=${config[key]}`)
}
/**
* Gets the maximum length.
*
* @param {number} length - The current maximum length.
* @param {string} name - A name.
* @returns {number} The maximum length.
*/
function maxLength (length, name) {
return Math.max(name.length, length)
}
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Runs npm-scripts which are matched with given patterns.
*
* @param {string|string[]} patternOrPatterns - Patterns to run.
* A pattern is a npm-script name or a Glob-like pattern.
* @param {object|undefined} [options] Optional.
* @param {boolean} options.parallel -
* If this is `true`, run scripts in parallel.
* Otherwise, run scripts in sequencial.
* Default is `false`.
* @param {stream.Readable|null} options.stdin -
* A readable stream to send messages to stdin of child process.
* If this is `null`, ignores it.
* If this is `process.stdin`, inherits it.
* Otherwise, makes a pipe.
* Default is `null`.
* @param {stream.Writable|null} options.stdout -
* A writable stream to receive messages from stdout of child process.
* If this is `null`, cannot send.
* If this is `process.stdout`, inherits it.
* Otherwise, makes a pipe.
* Default is `null`.
* @param {stream.Writable|null} options.stderr -
* A writable stream to receive messages from stderr of child process.
* If this is `null`, cannot send.
* If this is `process.stderr`, inherits it.
* Otherwise, makes a pipe.
* Default is `null`.
* @param {string[]} options.taskList -
* Actual name list of npm-scripts.
* This function search npm-script names in this list.
* If this is `null`, this function reads `package.json` of current directly.
* @param {object|null} options.packageConfig -
* A map-like object to overwrite package configs.
* Keys are package names.
* Every value is a map-like object (Pairs of variable name and value).
* e.g. `{"npm-run-all": {"test": 777}}`
* Default is `null`.
* @param {boolean} options.silent -
* The flag to set `silent` to the log level of npm.
* Default is `false`.
* @param {boolean} options.continueOnError -
* The flag to ignore errors.
* Default is `false`.
* @param {boolean} options.printLabel -
* The flag to print task names at the head of each line.
* Default is `false`.
* @param {boolean} options.printName -
* The flag to print task names before running each task.
* Default is `false`.
* @param {number} options.maxParallel -
* The maximum number of parallelism.
* Default is unlimited.
* @param {string} options.npmPath -
* The path to npm.
* Default is `process.env.npm_execpath`.
* @returns {Promise}
* A promise object which becomes fullfilled when all npm-scripts are completed.
*/
module.exports = function npmRunAll (patternOrPatterns, options) {
const stdin = (options && options.stdin) || null
const stdout = (options && options.stdout) || null
const stderr = (options && options.stderr) || null
const taskList = (options && options.taskList) || null
const config = (options && options.config) || null
const packageConfig = (options && options.packageConfig) || null
const args = (options && options.arguments) || []
const parallel = Boolean(options && options.parallel)
const silent = Boolean(options && options.silent)
const continueOnError = Boolean(options && options.continueOnError)
const printLabel = Boolean(options && options.printLabel)
const printName = Boolean(options && options.printName)
const race = Boolean(options && options.race)
const maxParallel = parallel ? ((options && options.maxParallel) || 0) : 1
const aggregateOutput = Boolean(options && options.aggregateOutput)
const npmPath = options && options.npmPath
try {
const patterns = parsePatterns(patternOrPatterns, args)
if (patterns.length === 0) {
return Promise.resolve(null)
}
if (taskList != null && Array.isArray(taskList) === false) {
throw new Error('Invalid options.taskList')
}
if (typeof maxParallel !== 'number' || !(maxParallel >= 0)) {
throw new Error('Invalid options.maxParallel')
}
if (!parallel && aggregateOutput) {
throw new Error('Invalid options.aggregateOutput; It requires options.parallel')
}
if (!parallel && race) {
throw new Error('Invalid options.race; It requires options.parallel')
}
const prefixOptions = [].concat(
silent ? ['--silent'] : [],
packageConfig ? toOverwriteOptions(packageConfig) : [],
config ? toConfigOptions(config) : []
)
return Promise.resolve()
.then(() => {
if (taskList != null) {
return { taskList, packageInfo: null }
}
return readPackageJson()
})
.then(x => {
const tasks = matchTasks(x.taskList, patterns)
const labelWidth = tasks.reduce(maxLength, 0)
return runTasks(tasks, {
stdin,
stdout,
stderr,
prefixOptions,
continueOnError,
labelState: {
enabled: printLabel,
width: labelWidth,
lastPrefix: null,
lastIsLinebreak: true,
},
printName,
packageInfo: x.packageInfo,
race,
maxParallel,
npmPath,
aggregateOutput,
})
})
} catch (err) {
return Promise.reject(new Error(err.message))
}
}
+130
View File
@@ -0,0 +1,130 @@
/**
* @module match-tasks
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const picomatch = require('picomatch')
// ------------------------------------------------------------------------------
// Helpers
// ------------------------------------------------------------------------------
const COLON_OR_SLASH = /[:/]/g
const CONVERT_MAP = { ':': '/', '/': ':' }
/**
* Swaps ":" and "/", in order to use ":" as the separator in picomatch.
*
* @param {string} s - A text to swap.
* @returns {string} The text which was swapped.
*/
function swapColonAndSlash (s) {
return s.replace(COLON_OR_SLASH, (matched) => CONVERT_MAP[matched])
}
/**
* Creates a filter from user-specified pattern text.
*
* The task name is the part until the first space.
* The rest part is the arguments for this task.
*
* @param {string} pattern - A pattern to create filter.
* @returns {{match: function, task: string, args: string}} The filter object of the pattern.
*/
function createFilter (pattern) {
const trimmed = pattern.trim()
const spacePos = trimmed.indexOf(' ')
const task = spacePos < 0 ? trimmed : trimmed.slice(0, spacePos)
const args = spacePos < 0 ? '' : trimmed.slice(spacePos)
const match = picomatch(swapColonAndSlash(task), {
nonegate: true,
strictSlashes: true,
})
return { match, task, args }
}
/**
* The set to remove overlapped task.
*/
class TaskSet {
/**
* Creates a instance.
*/
constructor () {
this.result = []
this.sourceMap = Object.create(null)
}
/**
* Adds a command (a pattern) into this set if it's not overlapped.
* "Overlapped" is meaning that the command was added from a different source.
*
* @param {string} command - A pattern text to add.
* @param {string} source - A task name to check.
* @returns {void}
*/
add (command, source) {
const sourceList = this.sourceMap[command] || (this.sourceMap[command] = [])
if (sourceList.length === 0 || sourceList.indexOf(source) !== -1) {
this.result.push(command)
}
sourceList.push(source)
}
}
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Enumerates tasks which matches with given patterns.
*
* @param {string[]} taskList - A list of actual task names.
* @param {string[]} patterns - Pattern texts to match.
* @returns {string[]} Tasks which matches with the patterns.
* @private
*/
module.exports = function matchTasks (taskList, patterns) {
const filters = patterns.map(createFilter)
const candidates = taskList.map(swapColonAndSlash)
const taskSet = new TaskSet()
const unknownSet = Object.create(null)
// Take tasks while keep the order of patterns.
for (const filter of filters) {
let found = false
for (const candidate of candidates) {
if (filter.match(candidate)) {
found = true
taskSet.add(
swapColonAndSlash(candidate) + filter.args,
filter.task
)
}
}
// Built-in tasks should be allowed.
if (!found && (filter.task === 'restart' || filter.task === 'env')) {
taskSet.add(filter.task + filter.args, filter.task)
found = true
}
if (!found) {
unknownSet[filter.task] = true
}
}
const unknownTasks = Object.keys(unknownSet)
if (unknownTasks.length > 0) {
throw new Error(`Task not found: "${unknownTasks.join('", ')}"`)
}
return taskSet.result
}
+47
View File
@@ -0,0 +1,47 @@
/**
* @module npm-run-all-error
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Error object with some additional info.
*/
module.exports = class NpmRunAllError extends Error {
/**
* Constructor.
*
* @param {{name: string, code: number}} causeResult -
* The result item of the npm-script which causes an error.
* @param {Array.<{name: string, code: (number|undefined)}>} allResults -
* All result items of npm-scripts.
*/
constructor (causeResult, allResults) {
super(`"${causeResult.task}" exited with ${causeResult.code}.`)
/**
* The name of a npm-script which exited with a non-zero code.
* @type {string}
*/
this.name = causeResult.name
/**
* The code of a npm-script which exited with a non-zero code.
* This can be `undefined`.
* @type {number}
*/
this.code = causeResult.code
/**
* All result items of npm-scripts.
* @type {Array.<{name: string, code: (number|undefined)}>}
*/
this.results = allResults
}
}
+32
View File
@@ -0,0 +1,32 @@
/**
* @module read-package-json
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
const readPackage = require('read-package-json-fast')
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const joinPath = require('path').join
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Reads the package.json in the current directory.
*
* @returns {object} package.json's information.
*/
module.exports = function readPackageJson () {
const path = joinPath(process.cwd(), 'package.json')
return readPackage(path).then(body => ({
taskList: Object.keys(body.scripts || {}),
packageInfo: { path, body },
}))
}
+251
View File
@@ -0,0 +1,251 @@
/**
* @module run-task
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const fs = require('fs')
const path = require('path')
const ansiStylesPromise = import('ansi-styles')
const parseArgs = require('shell-quote').parse
const which = require('which')
const createHeader = require('./create-header')
const createPrefixTransform = require('./create-prefix-transform-stream')
const spawn = require('./spawn')
// ------------------------------------------------------------------------------
// Helpers
// ------------------------------------------------------------------------------
const colors = ['cyan', 'green', 'magenta', 'yellow', 'red']
let colorIndex = 0
const taskNamesToColors = new Map()
/**
* Select a color from given task name.
*
* @param {string} taskName - The task name.
* @returns {function} A colorize function that provided by `chalk`
*/
function selectColor (taskName) {
let color = taskNamesToColors.get(taskName)
if (!color) {
color = colors[colorIndex]
colorIndex = (colorIndex + 1) % colors.length
taskNamesToColors.set(taskName, color)
}
return color
}
/**
* Wraps stdout/stderr with a transform stream to add the task name as prefix.
*
* @param {string} taskName - The task name.
* @param {stream.Writable} source - An output stream to be wrapped.
* @param {object} labelState - An label state for the transform stream.
* @returns {stream.Writable} `source` or the created wrapped stream.
*/
function wrapLabeling (taskName, source, labelState, ansiStyles) {
if (source == null || !labelState.enabled) {
return source
}
const label = taskName.padEnd(labelState.width)
const color = source.isTTY ? ansiStyles[selectColor(taskName)] : { open: '', close: '' }
const prefix = `${color.open}[${label}]${color.close} `
const stream = createPrefixTransform(prefix, labelState)
stream.pipe(source)
return stream
}
/**
* Converts a given stream to an option for `child_process.spawn`.
*
* @param {stream.Readable|stream.Writable|null} stream - An original stream to convert.
* @param {process.stdin|process.stdout|process.stderr} std - A standard stream for this option.
* @returns {string|stream.Readable|stream.Writable} An option for `child_process.spawn`.
*/
function detectStreamKind (stream, std) {
return (
stream == null
? 'ignore' // `|| !std.isTTY` is needed for the workaround of https://github.com/nodejs/node/issues/5620
: stream !== std || !std.isTTY
? 'pipe'
: stream
)
}
/**
* Ensure the output of shell-quote's `parse()` is acceptable input to npm-cli.
*
* The `parse()` method of shell-quote sometimes returns special objects in its
* output array, e.g. if it thinks some elements should be globbed. But npm-cli
* only accepts strings and will throw an error otherwise.
*
* See https://github.com/substack/node-shell-quote#parsecmd-env
*
* @param {object|string} arg - Item in the output of shell-quote's `parse()`.
* @returns {string} A valid argument for npm-cli.
*/
function cleanTaskArg (arg) {
return arg.pattern || arg.op || arg
}
// ------------------------------------------------------------------------------
// Interface
// ------------------------------------------------------------------------------
/**
* Run a npm-script of a given name.
* The return value is a promise which has an extra method: `abort()`.
* The `abort()` kills the child process to run the npm-script.
*
* @param {string} task - A npm-script name to run.
* @param {object} options - An option object.
* @param {stream.Readable|null} options.stdin -
* A readable stream to send messages to stdin of child process.
* If this is `null`, ignores it.
* If this is `process.stdin`, inherits it.
* Otherwise, makes a pipe.
* @param {stream.Writable|null} options.stdout -
* A writable stream to receive messages from stdout of child process.
* If this is `null`, cannot send.
* If this is `process.stdout`, inherits it.
* Otherwise, makes a pipe.
* @param {stream.Writable|null} options.stderr -
* A writable stream to receive messages from stderr of child process.
* If this is `null`, cannot send.
* If this is `process.stderr`, inherits it.
* Otherwise, makes a pipe.
* @param {string[]} options.prefixOptions -
* An array of options which are inserted before the task name.
* @param {object} options.labelState - A state object for printing labels.
* @param {boolean} options.printName - The flag to print task names before running each task.
* @param {object} options.packageInfo - A package.json's information.
* @param {object} options.packageInfo.body - A package.json's JSON object.
* @param {string} options.packageInfo.path - A package.json's file path.
* @returns {Promise}
* A promise object which becomes fullfilled when the npm-script is completed.
* This promise object has an extra method: `abort()`.
* @private
*/
module.exports = function runTask (task, options) {
let cp = null
async function asyncRunTask () {
const { default: ansiStyles } = await ansiStylesPromise
const stdin = options.stdin
const stdout = wrapLabeling(task, options.stdout, options.labelState, ansiStyles)
const stderr = wrapLabeling(task, options.stderr, options.labelState, ansiStyles)
const stdinKind = detectStreamKind(stdin, process.stdin)
const stdoutKind = detectStreamKind(stdout, process.stdout)
const stderrKind = detectStreamKind(stderr, process.stderr)
const spawnOptions = { stdio: [stdinKind, stdoutKind, stderrKind] }
// Print task name.
if (options.printName && stdout != null) {
stdout.write(createHeader(
task,
options.packageInfo,
options.stdout.isTTY,
ansiStyles
))
}
// Execute.
let npmPath = options.npmPath
if (!npmPath && process.env.npm_execpath) {
const basename = path.basename(process.env.npm_execpath)
let newBasename = basename
if (basename.startsWith('npx')) {
newBasename = basename.replace('npx', 'npm')
} else if (basename.startsWith('pnpx')) {
newBasename = basename.replace('pnpx', 'pnpm')
}
npmPath = newBasename !== basename
? path.join(path.dirname(process.env.npm_execpath), newBasename)
: process.env.npm_execpath
}
const npmPathIsJs = typeof npmPath === 'string' && /\.(c|m)?js/.test(path.extname(npmPath))
let execPath = (npmPathIsJs ? process.execPath : npmPath || 'npm')
if (!npmPath && !process.env.npm_execpath) {
// When a script is being run via pnpm, npmPath and npm_execpath will be null or undefined
// Attempt to figure out whether we're running via pnpm
const projectRoot = path.dirname(options.packageInfo.path)
const hasPnpmLockfile = fs.existsSync(path.join(projectRoot, 'pnpm-lock.yaml'))
const whichPnpmResults = await which('pnpm', { nothrow: true })
const pnpmFound = whichPnpmResults?.status
const pnpmWhichOutput = whichPnpmResults?.output
if (hasPnpmLockfile && __dirname.split(path.delimiter).includes('.pnpm') && pnpmFound) {
execPath = pnpmWhichOutput
}
}
const isYarn = process.env.npm_config_user_agent && process.env.npm_config_user_agent.startsWith('yarn')
const isPnpm = Boolean(process.env.PNPM_SCRIPT_SRC_DIR)
const isNpm = !isYarn && !isPnpm
const spawnArgs = ['run']
if (npmPathIsJs) {
spawnArgs.unshift(npmPath)
}
if (isNpm) {
Array.prototype.push.apply(spawnArgs, options.prefixOptions)
} else if (options.prefixOptions.indexOf('--silent') !== -1) {
spawnArgs.push('--silent')
}
Array.prototype.push.apply(spawnArgs, parseArgs(task).map(cleanTaskArg))
cp = spawn(execPath, spawnArgs, spawnOptions)
// Piping stdio.
if (stdinKind === 'pipe') {
stdin.pipe(cp.stdin)
}
if (stdoutKind === 'pipe') {
cp.stdout.pipe(stdout, { end: false })
}
if (stderrKind === 'pipe') {
cp.stderr.pipe(stderr, { end: false })
}
return new Promise((resolve, reject) => {
// Register
cp.on('error', (err) => {
cp = null
reject(err)
})
cp.on('close', (code, signal) => {
cp = null
resolve({ task, code, signal })
})
})
}
const promise = asyncRunTask()
promise.abort = function abort () {
if (cp != null) {
cp.kill()
cp = null
}
}
return promise
}
+217
View File
@@ -0,0 +1,217 @@
/**
* @module run-tasks-in-parallel
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const MemoryStream = require('memorystream')
const NpmRunAllError = require('./npm-run-all-error')
const runTask = require('./run-task')
// ------------------------------------------------------------------------------
// Helpers
// ------------------------------------------------------------------------------
/**
* Remove the given value from the array.
* @template T
* @param {T[]} array - The array to remove.
* @param {T} x - The item to be removed.
* @returns {void}
*/
function remove (array, x) {
const index = array.indexOf(x)
if (index !== -1) {
array.splice(index, 1)
}
}
const signals = {
SIGABRT: 6,
SIGALRM: 14,
SIGBUS: 10,
SIGCHLD: 20,
SIGCONT: 19,
SIGFPE: 8,
SIGHUP: 1,
SIGILL: 4,
SIGINT: 2,
SIGKILL: 9,
SIGPIPE: 13,
SIGQUIT: 3,
SIGSEGV: 11,
SIGSTOP: 17,
SIGTERM: 15,
SIGTRAP: 5,
SIGTSTP: 18,
SIGTTIN: 21,
SIGTTOU: 22,
SIGUSR1: 30,
SIGUSR2: 31,
}
/**
* Converts a signal name to a number.
* @param {string} signal - the signal name to convert into a number
* @returns {number} - the return code for the signal
*/
function convert (signal) {
return signals[signal] || 0
}
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Run npm-scripts of given names in parallel.
*
* If a npm-script exited with a non-zero code, this aborts other all npm-scripts.
*
* @param {string} tasks - A list of npm-script name to run in parallel.
* @param {object} options - An option object.
* @returns {Promise} A promise object which becomes fullfilled when all npm-scripts are completed.
* @private
*/
module.exports = function runTasks (tasks, options) {
return new Promise((resolve, reject) => {
if (tasks.length === 0) {
resolve([])
return
}
const results = tasks.map(task => ({ name: task, code: undefined }))
const queue = tasks.map((task, index) => ({ name: task, index }))
const promises = []
let error = null
let aborted = false
/**
* Done.
* @returns {void}
*/
function done () {
if (error == null) {
resolve(results)
} else {
reject(error)
}
}
/**
* Aborts all tasks.
* @returns {void}
*/
function abort () {
if (aborted) {
return
}
aborted = true
if (promises.length === 0) {
done()
} else {
for (const p of promises) {
p.abort()
}
Promise.all(promises).then(done, reject)
}
}
/**
* Runs a next task.
* @returns {void}
*/
function next () {
if (aborted) {
return
}
if (queue.length === 0) {
if (promises.length === 0) {
done()
}
return
}
const originalOutputStream = options.stdout
const optionsClone = Object.assign({}, options)
const writer = new MemoryStream(null, {
readable: false,
})
if (options.aggregateOutput) {
optionsClone.stdout = writer
}
const task = queue.shift()
const promise = runTask(task.name, optionsClone)
promises.push(promise)
promise.then(
(result) => {
remove(promises, promise)
if (aborted) {
return
}
if (options.aggregateOutput) {
originalOutputStream.write(writer.toString())
}
// Check if the task failed as a result of a signal, and
// amend the exit code as a result.
if (result.code === null && result.signal !== null) {
// An exit caused by a signal must return a status code
// of 128 plus the value of the signal code.
// Ref: https://nodejs.org/api/process.html#process_exit_codes
result.code = 128 + convert(result.signal)
}
// Save the result.
results[task.index].code = result.code
// Aborts all tasks if it's an error.
if (result.code) {
error = new NpmRunAllError(result, results)
if (!options.continueOnError) {
abort()
return
}
}
// Aborts all tasks if options.race is true.
if (options.race && !result.code) {
abort()
return
}
// Call the next task.
next()
},
(thisError) => {
remove(promises, promise)
if (!options.continueOnError || options.race) {
error = thisError
abort()
return
}
next()
}
)
}
const max = options.maxParallel
const end = (typeof max === 'number' && max > 0)
? Math.min(tasks.length, max)
: tasks.length
for (let i = 0; i < end; ++i) {
next()
}
})
}
+63
View File
@@ -0,0 +1,63 @@
/**
* @module spawn-posix
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const crossSpawn = require('cross-spawn')
const getDescendentProcessInfo = require('pidtree')
// ------------------------------------------------------------------------------
// Helpers
// ------------------------------------------------------------------------------
/**
* Kills the new process and its sub processes.
* @this ChildProcess
* @returns {void}
*/
function kill () {
getDescendentProcessInfo(this.pid, { root: true }, (err, pids) => {
if (err) {
return
}
for (const pid of pids) {
try {
process.kill(pid)
} catch (_err) {
// ignore.
}
}
})
}
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Launches a new process with the given command.
* This is almost same as `child_process.spawn`.
*
* This returns a `ChildProcess` instance.
* `kill` method of the instance kills the new process and its sub processes.
*
* @param {string} command - The command to run.
* @param {string[]} args - List of string arguments.
* @param {object} options - Options.
* @returns {ChildProcess} A ChildProcess instance of new process.
* @private
*/
module.exports = function spawn (command, args, options) {
const child = crossSpawn(command, args, options)
child.kill = kill
return child
}
+50
View File
@@ -0,0 +1,50 @@
/**
* @module spawn-win32
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const crossSpawn = require('cross-spawn')
// ------------------------------------------------------------------------------
// Helpers
// ------------------------------------------------------------------------------
/**
* Kills the new process and its sub processes forcibly.
* @this ChildProcess
* @returns {void}
*/
function kill () {
crossSpawn('taskkill', ['/F', '/T', '/PID', this.pid])
}
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Launches a new process with the given command.
* This is almost same as `child_process.spawn`.
*
* This returns a `ChildProcess` instance.
* `kill` method of the instance kills the new process and its sub processes forcibly.
*
* @param {string} command - The command to run.
* @param {string[]} args - List of string arguments.
* @param {object} options - Options.
* @returns {ChildProcess} A ChildProcess instance of new process.
* @private
*/
module.exports = function spawn (command, args, options) {
const child = crossSpawn(command, args, options)
child.kill = kill
return child
}
+18
View File
@@ -0,0 +1,18 @@
/**
* @module spawn
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
// ------------------------------------------------------------------------------
// Public Interface
// ------------------------------------------------------------------------------
/**
* Launches a new process with the given command.
* This is {@link ./spawn-posix.js:spawn} or {@link ./spawn-win32.js:spawn}
* @private
*/
module.exports = process.platform === 'win32' ? require('./spawn-win32') : require('./spawn-posix')
+1
View File
@@ -0,0 +1 @@
../which/bin/which.js
+236
View File
@@ -0,0 +1,236 @@
export type CSPair = { // eslint-disable-line @typescript-eslint/naming-convention
/**
The ANSI terminal control sequence for starting this style.
*/
readonly open: string;
/**
The ANSI terminal control sequence for ending this style.
*/
readonly close: string;
};
export type ColorBase = {
/**
The ANSI terminal control sequence for ending this color.
*/
readonly close: string;
ansi(code: number): string;
ansi256(code: number): string;
ansi16m(red: number, green: number, blue: number): string;
};
export type Modifier = {
/**
Resets the current color chain.
*/
readonly reset: CSPair;
/**
Make text bold.
*/
readonly bold: CSPair;
/**
Emitting only a small amount of light.
*/
readonly dim: CSPair;
/**
Make text italic. (Not widely supported)
*/
readonly italic: CSPair;
/**
Make text underline. (Not widely supported)
*/
readonly underline: CSPair;
/**
Make text overline.
Supported on VTE-based terminals, the GNOME terminal, mintty, and Git Bash.
*/
readonly overline: CSPair;
/**
Inverse background and foreground colors.
*/
readonly inverse: CSPair;
/**
Prints the text, but makes it invisible.
*/
readonly hidden: CSPair;
/**
Puts a horizontal line through the center of the text. (Not widely supported)
*/
readonly strikethrough: CSPair;
};
export type ForegroundColor = {
readonly black: CSPair;
readonly red: CSPair;
readonly green: CSPair;
readonly yellow: CSPair;
readonly blue: CSPair;
readonly cyan: CSPair;
readonly magenta: CSPair;
readonly white: CSPair;
/**
Alias for `blackBright`.
*/
readonly gray: CSPair;
/**
Alias for `blackBright`.
*/
readonly grey: CSPair;
readonly blackBright: CSPair;
readonly redBright: CSPair;
readonly greenBright: CSPair;
readonly yellowBright: CSPair;
readonly blueBright: CSPair;
readonly cyanBright: CSPair;
readonly magentaBright: CSPair;
readonly whiteBright: CSPair;
};
export type BackgroundColor = {
readonly bgBlack: CSPair;
readonly bgRed: CSPair;
readonly bgGreen: CSPair;
readonly bgYellow: CSPair;
readonly bgBlue: CSPair;
readonly bgCyan: CSPair;
readonly bgMagenta: CSPair;
readonly bgWhite: CSPair;
/**
Alias for `bgBlackBright`.
*/
readonly bgGray: CSPair;
/**
Alias for `bgBlackBright`.
*/
readonly bgGrey: CSPair;
readonly bgBlackBright: CSPair;
readonly bgRedBright: CSPair;
readonly bgGreenBright: CSPair;
readonly bgYellowBright: CSPair;
readonly bgBlueBright: CSPair;
readonly bgCyanBright: CSPair;
readonly bgMagentaBright: CSPair;
readonly bgWhiteBright: CSPair;
};
export type ConvertColor = {
/**
Convert from the RGB color space to the ANSI 256 color space.
@param red - (`0...255`)
@param green - (`0...255`)
@param blue - (`0...255`)
*/
rgbToAnsi256(red: number, green: number, blue: number): number;
/**
Convert from the RGB HEX color space to the RGB color space.
@param hex - A hexadecimal string containing RGB data.
*/
hexToRgb(hex: string): [red: number, green: number, blue: number];
/**
Convert from the RGB HEX color space to the ANSI 256 color space.
@param hex - A hexadecimal string containing RGB data.
*/
hexToAnsi256(hex: string): number;
/**
Convert from the ANSI 256 color space to the ANSI 16 color space.
@param code - A number representing the ANSI 256 color.
*/
ansi256ToAnsi(code: number): number;
/**
Convert from the RGB color space to the ANSI 16 color space.
@param red - (`0...255`)
@param green - (`0...255`)
@param blue - (`0...255`)
*/
rgbToAnsi(red: number, green: number, blue: number): number;
/**
Convert from the RGB HEX color space to the ANSI 16 color space.
@param hex - A hexadecimal string containing RGB data.
*/
hexToAnsi(hex: string): number;
};
/**
Basic modifier names.
*/
export type ModifierName = keyof Modifier;
/**
Basic foreground color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type ForegroundColorName = keyof ForegroundColor;
/**
Basic background color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type BackgroundColorName = keyof BackgroundColor;
/**
Basic color names. The combination of foreground and background color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type ColorName = ForegroundColorName | BackgroundColorName;
/**
Basic modifier names.
*/
export const modifierNames: readonly ModifierName[];
/**
Basic foreground color names.
*/
export const foregroundColorNames: readonly ForegroundColorName[];
/**
Basic background color names.
*/
export const backgroundColorNames: readonly BackgroundColorName[];
/*
Basic color names. The combination of foreground and background color names.
*/
export const colorNames: readonly ColorName[];
declare const ansiStyles: {
readonly modifier: Modifier;
readonly color: ColorBase & ForegroundColor;
readonly bgColor: ColorBase & BackgroundColor;
readonly codes: ReadonlyMap<number, number>;
} & ForegroundColor & BackgroundColor & Modifier & ConvertColor;
export default ansiStyles;
+223
View File
@@ -0,0 +1,223 @@
const ANSI_BACKGROUND_OFFSET = 10;
const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`;
const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`;
const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`;
const styles = {
modifier: {
reset: [0, 0],
// 21 isn't widely supported and 22 does the same thing
bold: [1, 22],
dim: [2, 22],
italic: [3, 23],
underline: [4, 24],
overline: [53, 55],
inverse: [7, 27],
hidden: [8, 28],
strikethrough: [9, 29],
},
color: {
black: [30, 39],
red: [31, 39],
green: [32, 39],
yellow: [33, 39],
blue: [34, 39],
magenta: [35, 39],
cyan: [36, 39],
white: [37, 39],
// Bright color
blackBright: [90, 39],
gray: [90, 39], // Alias of `blackBright`
grey: [90, 39], // Alias of `blackBright`
redBright: [91, 39],
greenBright: [92, 39],
yellowBright: [93, 39],
blueBright: [94, 39],
magentaBright: [95, 39],
cyanBright: [96, 39],
whiteBright: [97, 39],
},
bgColor: {
bgBlack: [40, 49],
bgRed: [41, 49],
bgGreen: [42, 49],
bgYellow: [43, 49],
bgBlue: [44, 49],
bgMagenta: [45, 49],
bgCyan: [46, 49],
bgWhite: [47, 49],
// Bright color
bgBlackBright: [100, 49],
bgGray: [100, 49], // Alias of `bgBlackBright`
bgGrey: [100, 49], // Alias of `bgBlackBright`
bgRedBright: [101, 49],
bgGreenBright: [102, 49],
bgYellowBright: [103, 49],
bgBlueBright: [104, 49],
bgMagentaBright: [105, 49],
bgCyanBright: [106, 49],
bgWhiteBright: [107, 49],
},
};
export const modifierNames = Object.keys(styles.modifier);
export const foregroundColorNames = Object.keys(styles.color);
export const backgroundColorNames = Object.keys(styles.bgColor);
export const colorNames = [...foregroundColorNames, ...backgroundColorNames];
function assembleStyles() {
const codes = new Map();
for (const [groupName, group] of Object.entries(styles)) {
for (const [styleName, style] of Object.entries(group)) {
styles[styleName] = {
open: `\u001B[${style[0]}m`,
close: `\u001B[${style[1]}m`,
};
group[styleName] = styles[styleName];
codes.set(style[0], style[1]);
}
Object.defineProperty(styles, groupName, {
value: group,
enumerable: false,
});
}
Object.defineProperty(styles, 'codes', {
value: codes,
enumerable: false,
});
styles.color.close = '\u001B[39m';
styles.bgColor.close = '\u001B[49m';
styles.color.ansi = wrapAnsi16();
styles.color.ansi256 = wrapAnsi256();
styles.color.ansi16m = wrapAnsi16m();
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js
Object.defineProperties(styles, {
rgbToAnsi256: {
value(red, green, blue) {
// We use the extended greyscale palette here, with the exception of
// black and white. normal palette only has 4 greyscale shades.
if (red === green && green === blue) {
if (red < 8) {
return 16;
}
if (red > 248) {
return 231;
}
return Math.round(((red - 8) / 247) * 24) + 232;
}
return 16
+ (36 * Math.round(red / 255 * 5))
+ (6 * Math.round(green / 255 * 5))
+ Math.round(blue / 255 * 5);
},
enumerable: false,
},
hexToRgb: {
value(hex) {
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
if (!matches) {
return [0, 0, 0];
}
let [colorString] = matches;
if (colorString.length === 3) {
colorString = [...colorString].map(character => character + character).join('');
}
const integer = Number.parseInt(colorString, 16);
return [
/* eslint-disable no-bitwise */
(integer >> 16) & 0xFF,
(integer >> 8) & 0xFF,
integer & 0xFF,
/* eslint-enable no-bitwise */
];
},
enumerable: false,
},
hexToAnsi256: {
value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
enumerable: false,
},
ansi256ToAnsi: {
value(code) {
if (code < 8) {
return 30 + code;
}
if (code < 16) {
return 90 + (code - 8);
}
let red;
let green;
let blue;
if (code >= 232) {
red = (((code - 232) * 10) + 8) / 255;
green = red;
blue = red;
} else {
code -= 16;
const remainder = code % 36;
red = Math.floor(code / 36) / 5;
green = Math.floor(remainder / 6) / 5;
blue = (remainder % 6) / 5;
}
const value = Math.max(red, green, blue) * 2;
if (value === 0) {
return 30;
}
// eslint-disable-next-line no-bitwise
let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));
if (value === 2) {
result += 60;
}
return result;
},
enumerable: false,
},
rgbToAnsi: {
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
enumerable: false,
},
hexToAnsi: {
value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
enumerable: false,
},
});
return styles;
}
const ansiStyles = assembleStyles();
export default ansiStyles;
+9
View File
@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,54 @@
{
"name": "ansi-styles",
"version": "6.2.3",
"description": "ANSI escape codes for styling strings in the terminal",
"license": "MIT",
"repository": "chalk/ansi-styles",
"funding": "https://github.com/chalk/ansi-styles?sponsor=1",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=12"
},
"scripts": {
"test": "xo && ava && tsd",
"screenshot": "svg-term --command='node screenshot' --out=screenshot.svg --padding=3 --width=55 --height=3 --at=1000 --no-cursor"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"devDependencies": {
"ava": "^6.1.3",
"svg-term-cli": "^2.1.1",
"tsd": "^0.31.1",
"xo": "^0.58.0"
}
}
+173
View File
@@ -0,0 +1,173 @@
# ansi-styles
> [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal
You probably want the higher-level [chalk](https://github.com/chalk/chalk) module for styling your strings.
![](screenshot.png)
## Install
```sh
npm install ansi-styles
```
## Usage
```js
import styles from 'ansi-styles';
console.log(`${styles.green.open}Hello world!${styles.green.close}`);
// Color conversion between 256/truecolor
// NOTE: When converting from truecolor to 256 colors, the original color
// may be degraded to fit the new color palette. This means terminals
// that do not support 16 million colors will best-match the
// original color.
console.log(`${styles.color.ansi(styles.rgbToAnsi(199, 20, 250))}Hello World${styles.color.close}`)
console.log(`${styles.color.ansi256(styles.rgbToAnsi256(199, 20, 250))}Hello World${styles.color.close}`)
console.log(`${styles.color.ansi16m(...styles.hexToRgb('#abcdef'))}Hello World${styles.color.close}`)
```
## API
### `open` and `close`
Each style has an `open` and `close` property.
### `modifierNames`, `foregroundColorNames`, `backgroundColorNames`, and `colorNames`
All supported style strings are exposed as an array of strings for convenience. `colorNames` is the combination of `foregroundColorNames` and `backgroundColorNames`.
This can be useful if you need to validate input:
```js
import {modifierNames, foregroundColorNames} from 'ansi-styles';
console.log(modifierNames.includes('bold'));
//=> true
console.log(foregroundColorNames.includes('pink'));
//=> false
```
## Styles
### Modifiers
- `reset`
- `bold`
- `dim`
- `italic` *(Not widely supported)*
- `underline`
- `overline` *Supported on VTE-based terminals, the GNOME terminal, mintty, and Git Bash.*
- `inverse`
- `hidden`
- `strikethrough` *(Not widely supported)*
### Colors
- `black`
- `red`
- `green`
- `yellow`
- `blue`
- `magenta`
- `cyan`
- `white`
- `blackBright` (alias: `gray`, `grey`)
- `redBright`
- `greenBright`
- `yellowBright`
- `blueBright`
- `magentaBright`
- `cyanBright`
- `whiteBright`
### Background colors
- `bgBlack`
- `bgRed`
- `bgGreen`
- `bgYellow`
- `bgBlue`
- `bgMagenta`
- `bgCyan`
- `bgWhite`
- `bgBlackBright` (alias: `bgGray`, `bgGrey`)
- `bgRedBright`
- `bgGreenBright`
- `bgYellowBright`
- `bgBlueBright`
- `bgMagentaBright`
- `bgCyanBright`
- `bgWhiteBright`
## Advanced usage
By default, you get a map of styles, but the styles are also available as groups. They are non-enumerable so they don't show up unless you access them explicitly. This makes it easier to expose only a subset in a higher-level module.
- `styles.modifier`
- `styles.color`
- `styles.bgColor`
###### Example
```js
import styles from 'ansi-styles';
console.log(styles.color.green.open);
```
Raw escape codes (i.e. without the CSI escape prefix `\u001B[` and render mode postfix `m`) are available under `styles.codes`, which returns a `Map` with the open codes as keys and close codes as values.
###### Example
```js
import styles from 'ansi-styles';
console.log(styles.codes.get(36));
//=> 39
```
## 16 / 256 / 16 million (TrueColor) support
`ansi-styles` allows converting between various color formats and ANSI escapes, with support for 16, 256 and [16 million colors](https://gist.github.com/XVilka/8346728).
The following color spaces are supported:
- `rgb`
- `hex`
- `ansi256`
- `ansi`
To use these, call the associated conversion function with the intended output, for example:
```js
import styles from 'ansi-styles';
styles.color.ansi(styles.rgbToAnsi(100, 200, 15)); // RGB to 16 color ansi foreground code
styles.bgColor.ansi(styles.hexToAnsi('#C0FFEE')); // HEX to 16 color ansi foreground code
styles.color.ansi256(styles.rgbToAnsi256(100, 200, 15)); // RGB to 256 color ansi foreground code
styles.bgColor.ansi256(styles.hexToAnsi256('#C0FFEE')); // HEX to 256 color ansi foreground code
styles.color.ansi16m(100, 200, 15); // RGB to 16 million color foreground code
styles.bgColor.ansi16m(...styles.hexToRgb('#C0FFEE')); // Hex (RGB) to 16 million color foreground code
```
## Related
- [ansi-escapes](https://github.com/sindresorhus/ansi-escapes) - ANSI escape codes for manipulating the terminal
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)
## For enterprise
Available as part of the Tidelift Subscription.
The maintainers of `ansi-styles` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-ansi-styles?utm_source=npm-ansi-styles&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
+55
View File
@@ -0,0 +1,55 @@
# Blue Oak Model License
Version 1.0.0
## Purpose
This license gives everyone as much permission to work with
this software as possible, while protecting contributors
from liability.
## Acceptance
In order to receive this license, you must agree to its
rules. The rules of this license are both obligations
under that agreement and conditions to your license.
You must not do anything with this software that triggers
a rule that you cannot or will not follow.
## Copyright
Each contributor licenses you to do everything with this
software that would otherwise infringe that contributor's
copyright in it.
## Notices
You must ensure that everyone who gets a copy of
any part of this software from you, with or without
changes, also gets the text of this license or a link to
<https://blueoakcouncil.org/license/1.0.0>.
## Excuse
If anyone notifies you in writing that you have not
complied with [Notices](#notices), you can keep your
license by taking all practical steps to comply within 30
days after the notice. If you do not do so, your license
ends immediately.
## Patent
Each contributor licenses you to do everything with this
software that would otherwise infringe any patent claims
they can license or become able to license.
## Reliability
No contributor can revoke this license.
## No Liability
***As far as the law allows, this software comes as is,
without any warranty or condition, and no contributor
will be liable to anyone for any damages related to this
software or this license, under any kind of legal claim.***
+80
View File
@@ -0,0 +1,80 @@
# isexe
Minimal module to check if a file is executable, and a normal file.
Uses `fs.stat` and tests against the `PATHEXT` environment variable on
Windows.
## USAGE
```js
// default export is a minified version that doesn't need to
// load more than one file. Load the 'isexe/raw' export if
// you want the non-minified version for some reason.
import { isexe, sync } from 'isexe'
// or require() works too
// const { isexe } = require('isexe')
isexe('some-file-name').then(
isExe => {
if (isExe) {
console.error('this thing can be run')
} else {
console.error('cannot be run')
}
},
err => {
console.error('probably file doesnt exist or something')
},
)
// same thing but synchronous, throws errors
isExe = sync('some-file-name')
// treat errors as just "not executable"
const isExe = await isexe('maybe-missing-file', { ignoreErrors: true })
const isExe = sync('maybe-missing-file', { ignoreErrors: true })
```
## API
### `isexe(path, [options]) => Promise<boolean>`
Check if the path is executable.
Will raise whatever errors may be raised by `fs.stat`, unless
`options.ignoreErrors` is set to true.
### `sync(path, [options]) => boolean`
Same as `isexe` but returns the value and throws any errors raised.
## Platform Specific Implementations
If for some reason you want to use the implementation for a
specific platform, you can do that.
```js
import { win32, posix } from 'isexe'
win32.isexe(...)
win32.sync(...)
// etc
// or:
import { isexe, sync } from 'isexe/posix'
```
The default exported implementation will be chosen based on
`process.platform`.
### Options
```ts
import type IsexeOptions from 'isexe'
```
- `ignoreErrors` Treat all errors as "no, this is not
executable", but don't raise them.
- `uid` Number to use as the user id on posix
- `gid` Number to use as the group id on posix
- `pathExt` List of path extensions to use instead of `PATHEXT`
environment variable on Windows.
@@ -0,0 +1,14 @@
import * as posix from './posix.js';
import * as win32 from './win32.js';
export * from './options.js';
export { win32, posix };
/**
* Determine whether a path is executable on the current platform.
*/
export declare const isexe: (path: string, options?: import("./options.js").IsexeOptions) => Promise<boolean>;
/**
* Synchronously determine whether a path is executable on the
* current platform.
*/
export declare const sync: (path: string, options?: import("./options.js").IsexeOptions) => boolean;
//# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;AAKvB;;GAEG;AACH,eAAO,MAAM,KAAK,mFAAa,CAAA;AAC/B;;;GAGG;AACH,eAAO,MAAM,IAAI,0EAAY,CAAA"}
@@ -0,0 +1,56 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sync = exports.isexe = exports.posix = exports.win32 = void 0;
const posix = __importStar(require("./posix.js"));
exports.posix = posix;
const win32 = __importStar(require("./win32.js"));
exports.win32 = win32;
__exportStar(require("./options.js"), exports);
const platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform;
const impl = platform === 'win32' ? win32 : posix;
/**
* Determine whether a path is executable on the current platform.
*/
exports.isexe = impl.isexe;
/**
* Synchronously determine whether a path is executable on the
* current platform.
*/
exports.sync = impl.sync;
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAAmC;AAGnB,sBAAK;AAFrB,kDAAmC;AAE1B,sBAAK;AADd,+CAA4B;AAG5B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,QAAQ,CAAA;AACtE,MAAM,IAAI,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAA;AAEjD;;GAEG;AACU,QAAA,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;AAC/B;;;GAGG;AACU,QAAA,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA","sourcesContent":["import * as posix from './posix.js'\nimport * as win32 from './win32.js'\nexport * from './options.js'\nexport { win32, posix }\n\nconst platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform\nconst impl = platform === 'win32' ? win32 : posix\n\n/**\n * Determine whether a path is executable on the current platform.\n */\nexport const isexe = impl.isexe\n/**\n * Synchronously determine whether a path is executable on the\n * current platform.\n */\nexport const sync = impl.sync\n"]}
@@ -0,0 +1,2 @@
"use strict";var a=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var _=a(i=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0});i.sync=i.isexe=void 0;var M=require("node:fs"),x=require("node:fs/promises"),q=async(t,e={})=>{let{ignoreErrors:r=!1}=e;try{return d(await(0,x.stat)(t),e)}catch(s){let n=s;if(r||n.code==="EACCES")return!1;throw n}};i.isexe=q;var m=(t,e={})=>{let{ignoreErrors:r=!1}=e;try{return d((0,M.statSync)(t),e)}catch(s){let n=s;if(r||n.code==="EACCES")return!1;throw n}};i.sync=m;var d=(t,e)=>t.isFile()&&A(t,e),A=(t,e)=>{let r=e.uid??process.getuid?.(),s=e.groups??process.getgroups?.()??[],n=e.gid??process.getgid?.()??s[0];if(r===void 0||n===void 0)throw new Error("cannot get uid or gid");let u=new Set([n,...s]),c=t.mode,S=t.uid,P=t.gid,f=parseInt("100",8),l=parseInt("010",8),j=parseInt("001",8),C=f|l;return!!(c&j||c&l&&u.has(P)||c&f&&S===r||c&C&&r===0)}});var g=a(o=>{"use strict";Object.defineProperty(o,"__esModule",{value:!0});o.sync=o.isexe=void 0;var T=require("node:fs"),I=require("node:fs/promises"),D=require("node:path"),F=async(t,e={})=>{let{ignoreErrors:r=!1}=e;try{return y(await(0,I.stat)(t),t,e)}catch(s){let n=s;if(r||n.code==="EACCES")return!1;throw n}};o.isexe=F;var L=(t,e={})=>{let{ignoreErrors:r=!1}=e;try{return y((0,T.statSync)(t),t,e)}catch(s){let n=s;if(r||n.code==="EACCES")return!1;throw n}};o.sync=L;var B=(t,e)=>{let{pathExt:r=process.env.PATHEXT||""}=e,s=r.split(D.delimiter);if(s.indexOf("")!==-1)return!0;for(let n of s){let u=n.toLowerCase(),c=t.substring(t.length-u.length).toLowerCase();if(u&&c===u)return!0}return!1},y=(t,e,r)=>t.isFile()&&B(e,r)});var p=a(h=>{"use strict";Object.defineProperty(h,"__esModule",{value:!0})});var v=exports&&exports.__createBinding||(Object.create?(function(t,e,r,s){s===void 0&&(s=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,s,n)}):(function(t,e,r,s){s===void 0&&(s=r),t[s]=e[r]})),G=exports&&exports.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),w=exports&&exports.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(r){var s=[];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(s[s.length]=n);return s},t(e)};return function(e){if(e&&e.__esModule)return e;var r={};if(e!=null)for(var s=t(e),n=0;n<s.length;n++)s[n]!=="default"&&v(r,e,s[n]);return G(r,e),r}})(),X=exports&&exports.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&v(e,t,r)};Object.defineProperty(exports,"__esModule",{value:!0});exports.sync=exports.isexe=exports.posix=exports.win32=void 0;var E=w(_());exports.posix=E;var O=w(g());exports.win32=O;X(p(),exports);var H=process.env._ISEXE_TEST_PLATFORM_||process.platform,b=H==="win32"?O:E;exports.isexe=b.isexe;exports.sync=b.sync;
//# sourceMappingURL=index.min.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/posix.ts", "../../src/win32.ts", "options.js", "../../src/index.ts"],
"sourcesContent": ["/**\n * This is the Posix implementation of isexe, which uses the file\n * mode and uid/gid values.\n *\n * @module\n */\n\nimport { Stats, statSync } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { IsexeOptions } from './options.js'\n\n/**\n * Determine whether a path is executable according to the mode and\n * current (or specified) user and group IDs.\n */\nexport const isexe = async (\n path: string,\n options: IsexeOptions = {},\n): Promise<boolean> => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(await stat(path), options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\n/**\n * Synchronously determine whether a path is executable according to\n * the mode and current (or specified) user and group IDs.\n */\nexport const sync = (\n path: string,\n options: IsexeOptions = {},\n): boolean => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(statSync(path), options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\nconst checkStat = (stat: Stats, options: IsexeOptions) =>\n stat.isFile() && checkMode(stat, options)\n\nconst checkMode = (stat: Stats, options: IsexeOptions) => {\n const myUid = options.uid ?? process.getuid?.()\n const myGroups = options.groups ?? process.getgroups?.() ?? []\n const myGid = options.gid ?? process.getgid?.() ?? myGroups[0]\n if (myUid === undefined || myGid === undefined) {\n throw new Error('cannot get uid or gid')\n }\n\n const groups = new Set([myGid, ...myGroups])\n\n const mod = stat.mode\n const uid = stat.uid\n const gid = stat.gid\n\n const u = parseInt('100', 8)\n const g = parseInt('010', 8)\n const o = parseInt('001', 8)\n const ug = u | g\n\n return !!(\n mod & o ||\n (mod & g && groups.has(gid)) ||\n (mod & u && uid === myUid) ||\n (mod & ug && myUid === 0)\n )\n}\n", "/**\n * This is the Windows implementation of isexe, which uses the file\n * extension and PATHEXT setting.\n *\n * @module\n */\n\nimport { Stats, statSync } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { IsexeOptions } from './options.js'\nimport { delimiter } from 'node:path'\n\n/**\n * Determine whether a path is executable based on the file extension\n * and PATHEXT environment variable (or specified pathExt option)\n */\nexport const isexe = async (\n path: string,\n options: IsexeOptions = {},\n): Promise<boolean> => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(await stat(path), path, options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\n/**\n * Synchronously determine whether a path is executable based on the file\n * extension and PATHEXT environment variable (or specified pathExt option)\n */\nexport const sync = (\n path: string,\n options: IsexeOptions = {},\n): boolean => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(statSync(path), path, options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\nconst checkPathExt = (path: string, options: IsexeOptions) => {\n const { pathExt = process.env.PATHEXT || '' } = options\n const peSplit = pathExt.split(delimiter)\n if (peSplit.indexOf('') !== -1) {\n return true\n }\n\n for (const pes of peSplit) {\n const p = pes.toLowerCase()\n const ext = path.substring(path.length - p.length).toLowerCase()\n\n if (p && ext === p) {\n return true\n }\n }\n return false\n}\n\nconst checkStat = (stat: Stats, path: string, options: IsexeOptions) =>\n stat.isFile() && checkPathExt(path, options)\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=options.js.map", "import * as posix from './posix.js'\nimport * as win32 from './win32.js'\nexport * from './options.js'\nexport { win32, posix }\n\nconst platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform\nconst impl = platform === 'win32' ? win32 : posix\n\n/**\n * Determine whether a path is executable on the current platform.\n */\nexport const isexe = impl.isexe\n/**\n * Synchronously determine whether a path is executable on the\n * current platform.\n */\nexport const sync = impl.sync\n"],
"mappings": "2KAOA,IAAAA,EAAA,QAAA,SAAA,EACAC,EAAA,QAAA,kBAAA,EAOaC,EAAQ,MACnBC,EACAC,EAAwB,CAAA,IACJ,CACpB,GAAM,CAAE,aAAAC,EAAe,EAAK,EAAKD,EACjC,GAAI,CACF,OAAOE,EAAU,QAAML,EAAA,MAAKE,CAAI,EAAGC,CAAO,CAC5C,OAASG,EAAG,CACV,IAAMC,EAAKD,EACX,GAAIF,GAAgBG,EAAG,OAAS,SAAU,MAAO,GACjD,MAAMA,CACR,CACF,EAZaC,EAAA,MAAKP,EAkBX,IAAMQ,EAAO,CAClBP,EACAC,EAAwB,CAAA,IACb,CACX,GAAM,CAAE,aAAAC,EAAe,EAAK,EAAKD,EACjC,GAAI,CACF,OAAOE,KAAUN,EAAA,UAASG,CAAI,EAAGC,CAAO,CAC1C,OAASG,EAAG,CACV,IAAMC,EAAKD,EACX,GAAIF,GAAgBG,EAAG,OAAS,SAAU,MAAO,GACjD,MAAMA,CACR,CACF,EAZaC,EAAA,KAAIC,EAcjB,IAAMJ,EAAY,CAACK,EAAaP,IAC9BO,EAAK,OAAM,GAAMC,EAAUD,EAAMP,CAAO,EAEpCQ,EAAY,CAACD,EAAaP,IAAyB,CACvD,IAAMS,EAAQT,EAAQ,KAAO,QAAQ,SAAQ,EACvCU,EAAWV,EAAQ,QAAU,QAAQ,YAAW,GAAM,CAAA,EACtDW,EAAQX,EAAQ,KAAO,QAAQ,SAAQ,GAAMU,EAAS,CAAC,EAC7D,GAAID,IAAU,QAAaE,IAAU,OACnC,MAAM,IAAI,MAAM,uBAAuB,EAGzC,IAAMC,EAAS,IAAI,IAAI,CAACD,EAAO,GAAGD,CAAQ,CAAC,EAErCG,EAAMN,EAAK,KACXO,EAAMP,EAAK,IACXQ,EAAMR,EAAK,IAEXS,EAAI,SAAS,MAAO,CAAC,EACrBC,EAAI,SAAS,MAAO,CAAC,EACrBC,EAAI,SAAS,MAAO,CAAC,EACrBC,EAAKH,EAAIC,EAEf,MAAO,CAAC,EACNJ,EAAMK,GACLL,EAAMI,GAAKL,EAAO,IAAIG,CAAG,GACzBF,EAAMG,GAAKF,IAAQL,GACnBI,EAAMM,GAAMV,IAAU,EAE3B,oGCpEA,IAAAW,EAAA,QAAA,SAAA,EACAC,EAAA,QAAA,kBAAA,EAEAC,EAAA,QAAA,WAAA,EAMaC,EAAQ,MACnBC,EACAC,EAAwB,CAAA,IACJ,CACpB,GAAM,CAAE,aAAAC,EAAe,EAAK,EAAKD,EACjC,GAAI,CACF,OAAOE,EAAU,QAAMN,EAAA,MAAKG,CAAI,EAAGA,EAAMC,CAAO,CAClD,OAASG,EAAG,CACV,IAAMC,EAAKD,EACX,GAAIF,GAAgBG,EAAG,OAAS,SAAU,MAAO,GACjD,MAAMA,CACR,CACF,EAZaC,EAAA,MAAKP,EAkBX,IAAMQ,EAAO,CAClBP,EACAC,EAAwB,CAAA,IACb,CACX,GAAM,CAAE,aAAAC,EAAe,EAAK,EAAKD,EACjC,GAAI,CACF,OAAOE,KAAUP,EAAA,UAASI,CAAI,EAAGA,EAAMC,CAAO,CAChD,OAASG,EAAG,CACV,IAAMC,EAAKD,EACX,GAAIF,GAAgBG,EAAG,OAAS,SAAU,MAAO,GACjD,MAAMA,CACR,CACF,EAZaC,EAAA,KAAIC,EAcjB,IAAMC,EAAe,CAACR,EAAcC,IAAyB,CAC3D,GAAM,CAAE,QAAAQ,EAAU,QAAQ,IAAI,SAAW,EAAE,EAAKR,EAC1CS,EAAUD,EAAQ,MAAMX,EAAA,SAAS,EACvC,GAAIY,EAAQ,QAAQ,EAAE,IAAM,GAC1B,MAAO,GAGT,QAAWC,KAAOD,EAAS,CACzB,IAAME,EAAID,EAAI,YAAW,EACnBE,EAAMb,EAAK,UAAUA,EAAK,OAASY,EAAE,MAAM,EAAE,YAAW,EAE9D,GAAIA,GAAKC,IAAQD,EACf,MAAO,EAEX,CACA,MAAO,EACT,EAEMT,EAAY,CAACW,EAAad,EAAcC,IAC5Ca,EAAK,OAAM,GAAMN,EAAaR,EAAMC,CAAO,ICnE7C,IAAAc,EAAAC,EAAAC,GAAA,cACA,OAAO,eAAeA,EAAS,aAAc,CAAE,MAAO,EAAK,CAAC,ykCCD5D,IAAAC,EAAAC,EAAA,GAAA,EAGgB,QAAA,MAAAD,EAFhB,IAAAE,EAAAD,EAAA,GAAA,EAES,QAAA,MAAAC,EADTC,EAAA,IAAA,OAAA,EAGA,IAAMC,EAAW,QAAQ,IAAI,uBAAyB,QAAQ,SACxDC,EAAOD,IAAa,QAAUF,EAAQF,EAK/B,QAAA,MAAQK,EAAK,MAKb,QAAA,KAAOA,EAAK",
"names": ["node_fs_1", "promises_1", "isexe", "path", "options", "ignoreErrors", "checkStat", "e", "er", "exports", "sync", "stat", "checkMode", "myUid", "myGroups", "myGid", "groups", "mod", "uid", "gid", "u", "g", "o", "ug", "node_fs_1", "promises_1", "node_path_1", "isexe", "path", "options", "ignoreErrors", "checkStat", "e", "er", "exports", "sync", "checkPathExt", "pathExt", "peSplit", "pes", "p", "ext", "stat", "require_options", "__commonJSMin", "exports", "posix", "__importStar", "win32", "__exportStar", "platform", "impl"]
}
@@ -0,0 +1,32 @@
export interface IsexeOptions {
/**
* Ignore errors arising from attempting to get file access status
* Note that EACCES is always ignored, because that just means
* it's not executable. If this is not set, then attempting to check
* the executable-ness of a nonexistent file will raise ENOENT, for
* example.
*/
ignoreErrors?: boolean;
/**
* effective uid when checking executable mode flags on posix
* Defaults to process.getuid()
*/
uid?: number;
/**
* effective gid when checking executable mode flags on posix
* Defaults to process.getgid()
*/
gid?: number;
/**
* effective group ID list to use when checking executable mode flags
* on posix
* Defaults to process.getgroups()
*/
groups?: number[];
/**
* The ;-delimited path extension list for win32 implementation.
* Defaults to process.env.PATHEXT
*/
pathExt?: string;
}
//# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB"}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/options.ts"],"names":[],"mappings":"","sourcesContent":["export interface IsexeOptions {\n /**\n * Ignore errors arising from attempting to get file access status\n * Note that EACCES is always ignored, because that just means\n * it's not executable. If this is not set, then attempting to check\n * the executable-ness of a nonexistent file will raise ENOENT, for\n * example.\n */\n ignoreErrors?: boolean\n\n /**\n * effective uid when checking executable mode flags on posix\n * Defaults to process.getuid()\n */\n uid?: number\n\n /**\n * effective gid when checking executable mode flags on posix\n * Defaults to process.getgid()\n */\n gid?: number\n\n /**\n * effective group ID list to use when checking executable mode flags\n * on posix\n * Defaults to process.getgroups()\n */\n groups?: number[]\n\n /**\n * The ;-delimited path extension list for win32 implementation.\n * Defaults to process.env.PATHEXT\n */\n pathExt?: string\n}\n"]}
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
@@ -0,0 +1,18 @@
/**
* This is the Posix implementation of isexe, which uses the file
* mode and uid/gid values.
*
* @module
*/
import { IsexeOptions } from './options.js';
/**
* Determine whether a path is executable according to the mode and
* current (or specified) user and group IDs.
*/
export declare const isexe: (path: string, options?: IsexeOptions) => Promise<boolean>;
/**
* Synchronously determine whether a path is executable according to
* the mode and current (or specified) user and group IDs.
*/
export declare const sync: (path: string, options?: IsexeOptions) => boolean;
//# sourceMappingURL=posix.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"posix.d.ts","sourceRoot":"","sources":["../../src/posix.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE3C;;;GAGG;AACH,eAAO,MAAM,KAAK,GAChB,MAAM,MAAM,EACZ,UAAS,YAAiB,KACzB,OAAO,CAAC,OAAO,CASjB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,GACf,MAAM,MAAM,EACZ,UAAS,YAAiB,KACzB,OASF,CAAA"}
@@ -0,0 +1,67 @@
"use strict";
/**
* This is the Posix implementation of isexe, which uses the file
* mode and uid/gid values.
*
* @module
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.sync = exports.isexe = void 0;
const node_fs_1 = require("node:fs");
const promises_1 = require("node:fs/promises");
/**
* Determine whether a path is executable according to the mode and
* current (or specified) user and group IDs.
*/
const isexe = async (path, options = {}) => {
const { ignoreErrors = false } = options;
try {
return checkStat(await (0, promises_1.stat)(path), options);
}
catch (e) {
const er = e;
if (ignoreErrors || er.code === 'EACCES')
return false;
throw er;
}
};
exports.isexe = isexe;
/**
* Synchronously determine whether a path is executable according to
* the mode and current (or specified) user and group IDs.
*/
const sync = (path, options = {}) => {
const { ignoreErrors = false } = options;
try {
return checkStat((0, node_fs_1.statSync)(path), options);
}
catch (e) {
const er = e;
if (ignoreErrors || er.code === 'EACCES')
return false;
throw er;
}
};
exports.sync = sync;
const checkStat = (stat, options) => stat.isFile() && checkMode(stat, options);
const checkMode = (stat, options) => {
const myUid = options.uid ?? process.getuid?.();
const myGroups = options.groups ?? process.getgroups?.() ?? [];
const myGid = options.gid ?? process.getgid?.() ?? myGroups[0];
if (myUid === undefined || myGid === undefined) {
throw new Error('cannot get uid or gid');
}
const groups = new Set([myGid, ...myGroups]);
const mod = stat.mode;
const uid = stat.uid;
const gid = stat.gid;
const u = parseInt('100', 8);
const g = parseInt('010', 8);
const o = parseInt('001', 8);
const ug = u | g;
return !!(mod & o ||
(mod & g && groups.has(gid)) ||
(mod & u && uid === myUid) ||
(mod & ug && myUid === 0));
};
//# sourceMappingURL=posix.js.map
@@ -0,0 +1 @@
{"version":3,"file":"posix.js","sourceRoot":"","sources":["../../src/posix.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,qCAAyC;AACzC,+CAAuC;AAGvC;;;GAGG;AACI,MAAM,KAAK,GAAG,KAAK,EACxB,IAAY,EACZ,UAAwB,EAAE,EACR,EAAE;IACpB,MAAM,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IACxC,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;IAC7C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAZY,QAAA,KAAK,SAYjB;AAED;;;GAGG;AACI,MAAM,IAAI,GAAG,CAClB,IAAY,EACZ,UAAwB,EAAE,EACjB,EAAE;IACX,MAAM,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IACxC,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,IAAA,kBAAQ,EAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;IAC3C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAZY,QAAA,IAAI,QAYhB;AAED,MAAM,SAAS,GAAG,CAAC,IAAW,EAAE,OAAqB,EAAE,EAAE,CACvD,IAAI,CAAC,MAAM,EAAE,IAAI,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;AAE3C,MAAM,SAAS,GAAG,CAAC,IAAW,EAAE,OAAqB,EAAE,EAAE;IACvD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAA;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,CAAA;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC9D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAA;IAE5C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAA;IACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;IACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;IAEpB,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAC5B,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAC5B,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAC5B,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;IAEhB,OAAO,CAAC,CAAC,CACP,GAAG,GAAG,CAAC;QACP,CAAC,GAAG,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC,GAAG,GAAG,CAAC,IAAI,GAAG,KAAK,KAAK,CAAC;QAC1B,CAAC,GAAG,GAAG,EAAE,IAAI,KAAK,KAAK,CAAC,CAAC,CAC1B,CAAA;AACH,CAAC,CAAA","sourcesContent":["/**\n * This is the Posix implementation of isexe, which uses the file\n * mode and uid/gid values.\n *\n * @module\n */\n\nimport { Stats, statSync } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { IsexeOptions } from './options.js'\n\n/**\n * Determine whether a path is executable according to the mode and\n * current (or specified) user and group IDs.\n */\nexport const isexe = async (\n path: string,\n options: IsexeOptions = {},\n): Promise<boolean> => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(await stat(path), options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\n/**\n * Synchronously determine whether a path is executable according to\n * the mode and current (or specified) user and group IDs.\n */\nexport const sync = (\n path: string,\n options: IsexeOptions = {},\n): boolean => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(statSync(path), options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\nconst checkStat = (stat: Stats, options: IsexeOptions) =>\n stat.isFile() && checkMode(stat, options)\n\nconst checkMode = (stat: Stats, options: IsexeOptions) => {\n const myUid = options.uid ?? process.getuid?.()\n const myGroups = options.groups ?? process.getgroups?.() ?? []\n const myGid = options.gid ?? process.getgid?.() ?? myGroups[0]\n if (myUid === undefined || myGid === undefined) {\n throw new Error('cannot get uid or gid')\n }\n\n const groups = new Set([myGid, ...myGroups])\n\n const mod = stat.mode\n const uid = stat.uid\n const gid = stat.gid\n\n const u = parseInt('100', 8)\n const g = parseInt('010', 8)\n const o = parseInt('001', 8)\n const ug = u | g\n\n return !!(\n mod & o ||\n (mod & g && groups.has(gid)) ||\n (mod & u && uid === myUid) ||\n (mod & ug && myUid === 0)\n )\n}\n"]}
@@ -0,0 +1,18 @@
/**
* This is the Windows implementation of isexe, which uses the file
* extension and PATHEXT setting.
*
* @module
*/
import { IsexeOptions } from './options.js';
/**
* Determine whether a path is executable based on the file extension
* and PATHEXT environment variable (or specified pathExt option)
*/
export declare const isexe: (path: string, options?: IsexeOptions) => Promise<boolean>;
/**
* Synchronously determine whether a path is executable based on the file
* extension and PATHEXT environment variable (or specified pathExt option)
*/
export declare const sync: (path: string, options?: IsexeOptions) => boolean;
//# sourceMappingURL=win32.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"win32.d.ts","sourceRoot":"","sources":["../../src/win32.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAG3C;;;GAGG;AACH,eAAO,MAAM,KAAK,GAChB,MAAM,MAAM,EACZ,UAAS,YAAiB,KACzB,OAAO,CAAC,OAAO,CASjB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,GACf,MAAM,MAAM,EACZ,UAAS,YAAiB,KACzB,OASF,CAAA"}
@@ -0,0 +1,63 @@
"use strict";
/**
* This is the Windows implementation of isexe, which uses the file
* extension and PATHEXT setting.
*
* @module
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.sync = exports.isexe = void 0;
const node_fs_1 = require("node:fs");
const promises_1 = require("node:fs/promises");
const node_path_1 = require("node:path");
/**
* Determine whether a path is executable based on the file extension
* and PATHEXT environment variable (or specified pathExt option)
*/
const isexe = async (path, options = {}) => {
const { ignoreErrors = false } = options;
try {
return checkStat(await (0, promises_1.stat)(path), path, options);
}
catch (e) {
const er = e;
if (ignoreErrors || er.code === 'EACCES')
return false;
throw er;
}
};
exports.isexe = isexe;
/**
* Synchronously determine whether a path is executable based on the file
* extension and PATHEXT environment variable (or specified pathExt option)
*/
const sync = (path, options = {}) => {
const { ignoreErrors = false } = options;
try {
return checkStat((0, node_fs_1.statSync)(path), path, options);
}
catch (e) {
const er = e;
if (ignoreErrors || er.code === 'EACCES')
return false;
throw er;
}
};
exports.sync = sync;
const checkPathExt = (path, options) => {
const { pathExt = process.env.PATHEXT || '' } = options;
const peSplit = pathExt.split(node_path_1.delimiter);
if (peSplit.indexOf('') !== -1) {
return true;
}
for (const pes of peSplit) {
const p = pes.toLowerCase();
const ext = path.substring(path.length - p.length).toLowerCase();
if (p && ext === p) {
return true;
}
}
return false;
};
const checkStat = (stat, path, options) => stat.isFile() && checkPathExt(path, options);
//# sourceMappingURL=win32.js.map
@@ -0,0 +1 @@
{"version":3,"file":"win32.js","sourceRoot":"","sources":["../../src/win32.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,qCAAyC;AACzC,+CAAuC;AAEvC,yCAAqC;AAErC;;;GAGG;AACI,MAAM,KAAK,GAAG,KAAK,EACxB,IAAY,EACZ,UAAwB,EAAE,EACR,EAAE;IACpB,MAAM,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IACxC,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACnD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAZY,QAAA,KAAK,SAYjB;AAED;;;GAGG;AACI,MAAM,IAAI,GAAG,CAClB,IAAY,EACZ,UAAwB,EAAE,EACjB,EAAE;IACX,MAAM,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IACxC,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,IAAA,kBAAQ,EAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACjD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAZY,QAAA,IAAI,QAYhB;AAED,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,OAAqB,EAAE,EAAE;IAC3D,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,OAAO,CAAA;IACvD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAS,CAAC,CAAA;IACxC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,CAAA;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAEhE,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;YACnB,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,IAAW,EAAE,IAAY,EAAE,OAAqB,EAAE,EAAE,CACrE,IAAI,CAAC,MAAM,EAAE,IAAI,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA","sourcesContent":["/**\n * This is the Windows implementation of isexe, which uses the file\n * extension and PATHEXT setting.\n *\n * @module\n */\n\nimport { Stats, statSync } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { IsexeOptions } from './options.js'\nimport { delimiter } from 'node:path'\n\n/**\n * Determine whether a path is executable based on the file extension\n * and PATHEXT environment variable (or specified pathExt option)\n */\nexport const isexe = async (\n path: string,\n options: IsexeOptions = {},\n): Promise<boolean> => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(await stat(path), path, options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\n/**\n * Synchronously determine whether a path is executable based on the file\n * extension and PATHEXT environment variable (or specified pathExt option)\n */\nexport const sync = (\n path: string,\n options: IsexeOptions = {},\n): boolean => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(statSync(path), path, options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\nconst checkPathExt = (path: string, options: IsexeOptions) => {\n const { pathExt = process.env.PATHEXT || '' } = options\n const peSplit = pathExt.split(delimiter)\n if (peSplit.indexOf('') !== -1) {\n return true\n }\n\n for (const pes of peSplit) {\n const p = pes.toLowerCase()\n const ext = path.substring(path.length - p.length).toLowerCase()\n\n if (p && ext === p) {\n return true\n }\n }\n return false\n}\n\nconst checkStat = (stat: Stats, path: string, options: IsexeOptions) =>\n stat.isFile() && checkPathExt(path, options)\n"]}
@@ -0,0 +1,14 @@
import * as posix from './posix.js';
import * as win32 from './win32.js';
export * from './options.js';
export { win32, posix };
/**
* Determine whether a path is executable on the current platform.
*/
export declare const isexe: (path: string, options?: import("./options.js").IsexeOptions) => Promise<boolean>;
/**
* Synchronously determine whether a path is executable on the
* current platform.
*/
export declare const sync: (path: string, options?: import("./options.js").IsexeOptions) => boolean;
//# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;AAKvB;;GAEG;AACH,eAAO,MAAM,KAAK,mFAAa,CAAA;AAC/B;;;GAGG;AACH,eAAO,MAAM,IAAI,0EAAY,CAAA"}
@@ -0,0 +1,16 @@
import * as posix from './posix.js';
import * as win32 from './win32.js';
export * from './options.js';
export { win32, posix };
const platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform;
const impl = platform === 'win32' ? win32 : posix;
/**
* Determine whether a path is executable on the current platform.
*/
export const isexe = impl.isexe;
/**
* Synchronously determine whether a path is executable on the
* current platform.
*/
export const sync = impl.sync;
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;AAEvB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,QAAQ,CAAA;AACtE,MAAM,IAAI,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAA;AAEjD;;GAEG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;AAC/B;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA","sourcesContent":["import * as posix from './posix.js'\nimport * as win32 from './win32.js'\nexport * from './options.js'\nexport { win32, posix }\n\nconst platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform\nconst impl = platform === 'win32' ? win32 : posix\n\n/**\n * Determine whether a path is executable on the current platform.\n */\nexport const isexe = impl.isexe\n/**\n * Synchronously determine whether a path is executable on the\n * current platform.\n */\nexport const sync = impl.sync\n"]}
@@ -0,0 +1,2 @@
var y=Object.defineProperty;var u=(t,r)=>{for(var e in r)y(t,e,{get:r[e],enumerable:!0})};var i={};u(i,{isexe:()=>C,sync:()=>A});import{statSync as w}from"node:fs";import{stat as S}from"node:fs/promises";var C=async(t,r={})=>{let{ignoreErrors:e=!1}=r;try{return d(await S(t),r)}catch(s){let o=s;if(e||o.code==="EACCES")return!1;throw o}},A=(t,r={})=>{let{ignoreErrors:e=!1}=r;try{return d(w(t),r)}catch(s){let o=s;if(e||o.code==="EACCES")return!1;throw o}},d=(t,r)=>t.isFile()&&T(t,r),T=(t,r)=>{let e=r.uid??process.getuid?.(),s=r.groups??process.getgroups?.()??[],o=r.gid??process.getgid?.()??s[0];if(e===void 0||o===void 0)throw new Error("cannot get uid or gid");let c=new Set([o,...s]),n=t.mode,l=t.uid,E=t.gid,f=parseInt("100",8),p=parseInt("010",8),x=parseInt("001",8),h=f|p;return!!(n&x||n&p&&c.has(E)||n&f&&l===e||n&h&&e===0)};var a={};u(a,{isexe:()=>F,sync:()=>L});import{statSync as k}from"node:fs";import{stat as I}from"node:fs/promises";import{delimiter as _}from"node:path";var F=async(t,r={})=>{let{ignoreErrors:e=!1}=r;try{return m(await I(t),t,r)}catch(s){let o=s;if(e||o.code==="EACCES")return!1;throw o}},L=(t,r={})=>{let{ignoreErrors:e=!1}=r;try{return m(k(t),t,r)}catch(s){let o=s;if(e||o.code==="EACCES")return!1;throw o}},P=(t,r)=>{let{pathExt:e=process.env.PATHEXT||""}=r,s=e.split(_);if(s.indexOf("")!==-1)return!0;for(let o of s){let c=o.toLowerCase(),n=t.substring(t.length-c.length).toLowerCase();if(c&&n===c)return!0}return!1},m=(t,r,e)=>t.isFile()&&P(r,e);var v=process.env._ISEXE_TEST_PLATFORM_||process.platform,g=v==="win32"?a:i,R=g.isexe,U=g.sync;export{R as isexe,i as posix,U as sync,a as win32};
//# sourceMappingURL=index.min.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/posix.ts", "../../src/win32.ts", "../../src/index.ts"],
"sourcesContent": ["/**\n * This is the Posix implementation of isexe, which uses the file\n * mode and uid/gid values.\n *\n * @module\n */\n\nimport { Stats, statSync } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { IsexeOptions } from './options.js'\n\n/**\n * Determine whether a path is executable according to the mode and\n * current (or specified) user and group IDs.\n */\nexport const isexe = async (\n path: string,\n options: IsexeOptions = {},\n): Promise<boolean> => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(await stat(path), options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\n/**\n * Synchronously determine whether a path is executable according to\n * the mode and current (or specified) user and group IDs.\n */\nexport const sync = (\n path: string,\n options: IsexeOptions = {},\n): boolean => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(statSync(path), options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\nconst checkStat = (stat: Stats, options: IsexeOptions) =>\n stat.isFile() && checkMode(stat, options)\n\nconst checkMode = (stat: Stats, options: IsexeOptions) => {\n const myUid = options.uid ?? process.getuid?.()\n const myGroups = options.groups ?? process.getgroups?.() ?? []\n const myGid = options.gid ?? process.getgid?.() ?? myGroups[0]\n if (myUid === undefined || myGid === undefined) {\n throw new Error('cannot get uid or gid')\n }\n\n const groups = new Set([myGid, ...myGroups])\n\n const mod = stat.mode\n const uid = stat.uid\n const gid = stat.gid\n\n const u = parseInt('100', 8)\n const g = parseInt('010', 8)\n const o = parseInt('001', 8)\n const ug = u | g\n\n return !!(\n mod & o ||\n (mod & g && groups.has(gid)) ||\n (mod & u && uid === myUid) ||\n (mod & ug && myUid === 0)\n )\n}\n", "/**\n * This is the Windows implementation of isexe, which uses the file\n * extension and PATHEXT setting.\n *\n * @module\n */\n\nimport { Stats, statSync } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { IsexeOptions } from './options.js'\nimport { delimiter } from 'node:path'\n\n/**\n * Determine whether a path is executable based on the file extension\n * and PATHEXT environment variable (or specified pathExt option)\n */\nexport const isexe = async (\n path: string,\n options: IsexeOptions = {},\n): Promise<boolean> => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(await stat(path), path, options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\n/**\n * Synchronously determine whether a path is executable based on the file\n * extension and PATHEXT environment variable (or specified pathExt option)\n */\nexport const sync = (\n path: string,\n options: IsexeOptions = {},\n): boolean => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(statSync(path), path, options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\nconst checkPathExt = (path: string, options: IsexeOptions) => {\n const { pathExt = process.env.PATHEXT || '' } = options\n const peSplit = pathExt.split(delimiter)\n if (peSplit.indexOf('') !== -1) {\n return true\n }\n\n for (const pes of peSplit) {\n const p = pes.toLowerCase()\n const ext = path.substring(path.length - p.length).toLowerCase()\n\n if (p && ext === p) {\n return true\n }\n }\n return false\n}\n\nconst checkStat = (stat: Stats, path: string, options: IsexeOptions) =>\n stat.isFile() && checkPathExt(path, options)\n", "import * as posix from './posix.js'\nimport * as win32 from './win32.js'\nexport * from './options.js'\nexport { win32, posix }\n\nconst platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform\nconst impl = platform === 'win32' ? win32 : posix\n\n/**\n * Determine whether a path is executable on the current platform.\n */\nexport const isexe = impl.isexe\n/**\n * Synchronously determine whether a path is executable on the\n * current platform.\n */\nexport const sync = impl.sync\n"],
"mappings": "0FAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,WAAAE,EAAA,SAAAC,IAOA,OAAgB,YAAAC,MAAgB,UAChC,OAAS,QAAAC,MAAY,mBAOd,IAAMH,EAAQ,MACnBI,EACAC,EAAwB,CAAA,IACJ,CACpB,GAAM,CAAE,aAAAC,EAAe,EAAK,EAAKD,EACjC,GAAI,CACF,OAAOE,EAAU,MAAMJ,EAAKC,CAAI,EAAGC,CAAO,CAC5C,OAASG,EAAG,CACV,IAAMC,EAAKD,EACX,GAAIF,GAAgBG,EAAG,OAAS,SAAU,MAAO,GACjD,MAAMA,CACR,CACF,EAMaR,EAAO,CAClBG,EACAC,EAAwB,CAAA,IACb,CACX,GAAM,CAAE,aAAAC,EAAe,EAAK,EAAKD,EACjC,GAAI,CACF,OAAOE,EAAUL,EAASE,CAAI,EAAGC,CAAO,CAC1C,OAASG,EAAG,CACV,IAAMC,EAAKD,EACX,GAAIF,GAAgBG,EAAG,OAAS,SAAU,MAAO,GACjD,MAAMA,CACR,CACF,EAEMF,EAAY,CAACJ,EAAaE,IAC9BF,EAAK,OAAM,GAAMO,EAAUP,EAAME,CAAO,EAEpCK,EAAY,CAACP,EAAaE,IAAyB,CACvD,IAAMM,EAAQN,EAAQ,KAAO,QAAQ,SAAQ,EACvCO,EAAWP,EAAQ,QAAU,QAAQ,YAAW,GAAM,CAAA,EACtDQ,EAAQR,EAAQ,KAAO,QAAQ,SAAQ,GAAMO,EAAS,CAAC,EAC7D,GAAID,IAAU,QAAaE,IAAU,OACnC,MAAM,IAAI,MAAM,uBAAuB,EAGzC,IAAMC,EAAS,IAAI,IAAI,CAACD,EAAO,GAAGD,CAAQ,CAAC,EAErCG,EAAMZ,EAAK,KACXa,EAAMb,EAAK,IACXc,EAAMd,EAAK,IAEXe,EAAI,SAAS,MAAO,CAAC,EACrBC,EAAI,SAAS,MAAO,CAAC,EACrBC,EAAI,SAAS,MAAO,CAAC,EACrBC,EAAKH,EAAIC,EAEf,MAAO,CAAC,EACNJ,EAAMK,GACLL,EAAMI,GAAKL,EAAO,IAAIG,CAAG,GACzBF,EAAMG,GAAKF,IAAQL,GACnBI,EAAMM,GAAMV,IAAU,EAE3B,EC3EA,IAAAW,EAAA,GAAAC,EAAAD,EAAA,WAAAE,EAAA,SAAAC,IAOA,OAAgB,YAAAC,MAAgB,UAChC,OAAS,QAAAC,MAAY,mBAErB,OAAS,aAAAC,MAAiB,YAMnB,IAAMJ,EAAQ,MACnBK,EACAC,EAAwB,CAAA,IACJ,CACpB,GAAM,CAAE,aAAAC,EAAe,EAAK,EAAKD,EACjC,GAAI,CACF,OAAOE,EAAU,MAAML,EAAKE,CAAI,EAAGA,EAAMC,CAAO,CAClD,OAASG,EAAG,CACV,IAAMC,EAAKD,EACX,GAAIF,GAAgBG,EAAG,OAAS,SAAU,MAAO,GACjD,MAAMA,CACR,CACF,EAMaT,EAAO,CAClBI,EACAC,EAAwB,CAAA,IACb,CACX,GAAM,CAAE,aAAAC,EAAe,EAAK,EAAKD,EACjC,GAAI,CACF,OAAOE,EAAUN,EAASG,CAAI,EAAGA,EAAMC,CAAO,CAChD,OAASG,EAAG,CACV,IAAMC,EAAKD,EACX,GAAIF,GAAgBG,EAAG,OAAS,SAAU,MAAO,GACjD,MAAMA,CACR,CACF,EAEMC,EAAe,CAACN,EAAcC,IAAyB,CAC3D,GAAM,CAAE,QAAAM,EAAU,QAAQ,IAAI,SAAW,EAAE,EAAKN,EAC1CO,EAAUD,EAAQ,MAAMR,CAAS,EACvC,GAAIS,EAAQ,QAAQ,EAAE,IAAM,GAC1B,MAAO,GAGT,QAAWC,KAAOD,EAAS,CACzB,IAAME,EAAID,EAAI,YAAW,EACnBE,EAAMX,EAAK,UAAUA,EAAK,OAASU,EAAE,MAAM,EAAE,YAAW,EAE9D,GAAIA,GAAKC,IAAQD,EACf,MAAO,EAEX,CACA,MAAO,EACT,EAEMP,EAAY,CAACL,EAAaE,EAAcC,IAC5CH,EAAK,OAAM,GAAMQ,EAAaN,EAAMC,CAAO,EC9D7C,IAAMW,EAAW,QAAQ,IAAI,uBAAyB,QAAQ,SACxDC,EAAOD,IAAa,QAAUE,EAAQC,EAK/BC,EAAQH,EAAK,MAKbI,EAAOJ,EAAK",
"names": ["posix_exports", "__export", "isexe", "sync", "statSync", "stat", "path", "options", "ignoreErrors", "checkStat", "e", "er", "checkMode", "myUid", "myGroups", "myGid", "groups", "mod", "uid", "gid", "u", "g", "o", "ug", "win32_exports", "__export", "isexe", "sync", "statSync", "stat", "delimiter", "path", "options", "ignoreErrors", "checkStat", "e", "er", "checkPathExt", "pathExt", "peSplit", "pes", "p", "ext", "platform", "impl", "win32_exports", "posix_exports", "isexe", "sync"]
}
@@ -0,0 +1,32 @@
export interface IsexeOptions {
/**
* Ignore errors arising from attempting to get file access status
* Note that EACCES is always ignored, because that just means
* it's not executable. If this is not set, then attempting to check
* the executable-ness of a nonexistent file will raise ENOENT, for
* example.
*/
ignoreErrors?: boolean;
/**
* effective uid when checking executable mode flags on posix
* Defaults to process.getuid()
*/
uid?: number;
/**
* effective gid when checking executable mode flags on posix
* Defaults to process.getgid()
*/
gid?: number;
/**
* effective group ID list to use when checking executable mode flags
* on posix
* Defaults to process.getgroups()
*/
groups?: number[];
/**
* The ;-delimited path extension list for win32 implementation.
* Defaults to process.env.PATHEXT
*/
pathExt?: string;
}
//# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB"}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/options.ts"],"names":[],"mappings":"","sourcesContent":["export interface IsexeOptions {\n /**\n * Ignore errors arising from attempting to get file access status\n * Note that EACCES is always ignored, because that just means\n * it's not executable. If this is not set, then attempting to check\n * the executable-ness of a nonexistent file will raise ENOENT, for\n * example.\n */\n ignoreErrors?: boolean\n\n /**\n * effective uid when checking executable mode flags on posix\n * Defaults to process.getuid()\n */\n uid?: number\n\n /**\n * effective gid when checking executable mode flags on posix\n * Defaults to process.getgid()\n */\n gid?: number\n\n /**\n * effective group ID list to use when checking executable mode flags\n * on posix\n * Defaults to process.getgroups()\n */\n groups?: number[]\n\n /**\n * The ;-delimited path extension list for win32 implementation.\n * Defaults to process.env.PATHEXT\n */\n pathExt?: string\n}\n"]}
@@ -0,0 +1,3 @@
{
"type": "module"
}
@@ -0,0 +1,18 @@
/**
* This is the Posix implementation of isexe, which uses the file
* mode and uid/gid values.
*
* @module
*/
import { IsexeOptions } from './options.js';
/**
* Determine whether a path is executable according to the mode and
* current (or specified) user and group IDs.
*/
export declare const isexe: (path: string, options?: IsexeOptions) => Promise<boolean>;
/**
* Synchronously determine whether a path is executable according to
* the mode and current (or specified) user and group IDs.
*/
export declare const sync: (path: string, options?: IsexeOptions) => boolean;
//# sourceMappingURL=posix.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"posix.d.ts","sourceRoot":"","sources":["../../src/posix.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE3C;;;GAGG;AACH,eAAO,MAAM,KAAK,GAChB,MAAM,MAAM,EACZ,UAAS,YAAiB,KACzB,OAAO,CAAC,OAAO,CASjB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,GACf,MAAM,MAAM,EACZ,UAAS,YAAiB,KACzB,OASF,CAAA"}
@@ -0,0 +1,62 @@
/**
* This is the Posix implementation of isexe, which uses the file
* mode and uid/gid values.
*
* @module
*/
import { statSync } from 'node:fs';
import { stat } from 'node:fs/promises';
/**
* Determine whether a path is executable according to the mode and
* current (or specified) user and group IDs.
*/
export const isexe = async (path, options = {}) => {
const { ignoreErrors = false } = options;
try {
return checkStat(await stat(path), options);
}
catch (e) {
const er = e;
if (ignoreErrors || er.code === 'EACCES')
return false;
throw er;
}
};
/**
* Synchronously determine whether a path is executable according to
* the mode and current (or specified) user and group IDs.
*/
export const sync = (path, options = {}) => {
const { ignoreErrors = false } = options;
try {
return checkStat(statSync(path), options);
}
catch (e) {
const er = e;
if (ignoreErrors || er.code === 'EACCES')
return false;
throw er;
}
};
const checkStat = (stat, options) => stat.isFile() && checkMode(stat, options);
const checkMode = (stat, options) => {
const myUid = options.uid ?? process.getuid?.();
const myGroups = options.groups ?? process.getgroups?.() ?? [];
const myGid = options.gid ?? process.getgid?.() ?? myGroups[0];
if (myUid === undefined || myGid === undefined) {
throw new Error('cannot get uid or gid');
}
const groups = new Set([myGid, ...myGroups]);
const mod = stat.mode;
const uid = stat.uid;
const gid = stat.gid;
const u = parseInt('100', 8);
const g = parseInt('010', 8);
const o = parseInt('001', 8);
const ug = u | g;
return !!(mod & o ||
(mod & g && groups.has(gid)) ||
(mod & u && uid === myUid) ||
(mod & ug && myUid === 0));
};
//# sourceMappingURL=posix.js.map
@@ -0,0 +1 @@
{"version":3,"file":"posix.js","sourceRoot":"","sources":["../../src/posix.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAS,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAGvC;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,EACxB,IAAY,EACZ,UAAwB,EAAE,EACR,EAAE;IACpB,MAAM,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IACxC,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;IAC7C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAClB,IAAY,EACZ,UAAwB,EAAE,EACjB,EAAE;IACX,MAAM,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IACxC,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;IAC3C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,IAAW,EAAE,OAAqB,EAAE,EAAE,CACvD,IAAI,CAAC,MAAM,EAAE,IAAI,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;AAE3C,MAAM,SAAS,GAAG,CAAC,IAAW,EAAE,OAAqB,EAAE,EAAE;IACvD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAA;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,CAAA;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC9D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAA;IAE5C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAA;IACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;IACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;IAEpB,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAC5B,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAC5B,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAC5B,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;IAEhB,OAAO,CAAC,CAAC,CACP,GAAG,GAAG,CAAC;QACP,CAAC,GAAG,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC,GAAG,GAAG,CAAC,IAAI,GAAG,KAAK,KAAK,CAAC;QAC1B,CAAC,GAAG,GAAG,EAAE,IAAI,KAAK,KAAK,CAAC,CAAC,CAC1B,CAAA;AACH,CAAC,CAAA","sourcesContent":["/**\n * This is the Posix implementation of isexe, which uses the file\n * mode and uid/gid values.\n *\n * @module\n */\n\nimport { Stats, statSync } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { IsexeOptions } from './options.js'\n\n/**\n * Determine whether a path is executable according to the mode and\n * current (or specified) user and group IDs.\n */\nexport const isexe = async (\n path: string,\n options: IsexeOptions = {},\n): Promise<boolean> => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(await stat(path), options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\n/**\n * Synchronously determine whether a path is executable according to\n * the mode and current (or specified) user and group IDs.\n */\nexport const sync = (\n path: string,\n options: IsexeOptions = {},\n): boolean => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(statSync(path), options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\nconst checkStat = (stat: Stats, options: IsexeOptions) =>\n stat.isFile() && checkMode(stat, options)\n\nconst checkMode = (stat: Stats, options: IsexeOptions) => {\n const myUid = options.uid ?? process.getuid?.()\n const myGroups = options.groups ?? process.getgroups?.() ?? []\n const myGid = options.gid ?? process.getgid?.() ?? myGroups[0]\n if (myUid === undefined || myGid === undefined) {\n throw new Error('cannot get uid or gid')\n }\n\n const groups = new Set([myGid, ...myGroups])\n\n const mod = stat.mode\n const uid = stat.uid\n const gid = stat.gid\n\n const u = parseInt('100', 8)\n const g = parseInt('010', 8)\n const o = parseInt('001', 8)\n const ug = u | g\n\n return !!(\n mod & o ||\n (mod & g && groups.has(gid)) ||\n (mod & u && uid === myUid) ||\n (mod & ug && myUid === 0)\n )\n}\n"]}
@@ -0,0 +1,18 @@
/**
* This is the Windows implementation of isexe, which uses the file
* extension and PATHEXT setting.
*
* @module
*/
import { IsexeOptions } from './options.js';
/**
* Determine whether a path is executable based on the file extension
* and PATHEXT environment variable (or specified pathExt option)
*/
export declare const isexe: (path: string, options?: IsexeOptions) => Promise<boolean>;
/**
* Synchronously determine whether a path is executable based on the file
* extension and PATHEXT environment variable (or specified pathExt option)
*/
export declare const sync: (path: string, options?: IsexeOptions) => boolean;
//# sourceMappingURL=win32.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"win32.d.ts","sourceRoot":"","sources":["../../src/win32.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAG3C;;;GAGG;AACH,eAAO,MAAM,KAAK,GAChB,MAAM,MAAM,EACZ,UAAS,YAAiB,KACzB,OAAO,CAAC,OAAO,CASjB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,GACf,MAAM,MAAM,EACZ,UAAS,YAAiB,KACzB,OASF,CAAA"}
@@ -0,0 +1,58 @@
/**
* This is the Windows implementation of isexe, which uses the file
* extension and PATHEXT setting.
*
* @module
*/
import { statSync } from 'node:fs';
import { stat } from 'node:fs/promises';
import { delimiter } from 'node:path';
/**
* Determine whether a path is executable based on the file extension
* and PATHEXT environment variable (or specified pathExt option)
*/
export const isexe = async (path, options = {}) => {
const { ignoreErrors = false } = options;
try {
return checkStat(await stat(path), path, options);
}
catch (e) {
const er = e;
if (ignoreErrors || er.code === 'EACCES')
return false;
throw er;
}
};
/**
* Synchronously determine whether a path is executable based on the file
* extension and PATHEXT environment variable (or specified pathExt option)
*/
export const sync = (path, options = {}) => {
const { ignoreErrors = false } = options;
try {
return checkStat(statSync(path), path, options);
}
catch (e) {
const er = e;
if (ignoreErrors || er.code === 'EACCES')
return false;
throw er;
}
};
const checkPathExt = (path, options) => {
const { pathExt = process.env.PATHEXT || '' } = options;
const peSplit = pathExt.split(delimiter);
if (peSplit.indexOf('') !== -1) {
return true;
}
for (const pes of peSplit) {
const p = pes.toLowerCase();
const ext = path.substring(path.length - p.length).toLowerCase();
if (p && ext === p) {
return true;
}
}
return false;
};
const checkStat = (stat, path, options) => stat.isFile() && checkPathExt(path, options);
//# sourceMappingURL=win32.js.map
@@ -0,0 +1 @@
{"version":3,"file":"win32.js","sourceRoot":"","sources":["../../src/win32.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAS,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAEvC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,EACxB,IAAY,EACZ,UAAwB,EAAE,EACR,EAAE;IACpB,MAAM,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IACxC,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACnD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAClB,IAAY,EACZ,UAAwB,EAAE,EACjB,EAAE;IACX,MAAM,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IACxC,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACjD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,OAAqB,EAAE,EAAE;IAC3D,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,OAAO,CAAA;IACvD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACxC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,CAAA;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAEhE,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;YACnB,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,IAAW,EAAE,IAAY,EAAE,OAAqB,EAAE,EAAE,CACrE,IAAI,CAAC,MAAM,EAAE,IAAI,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA","sourcesContent":["/**\n * This is the Windows implementation of isexe, which uses the file\n * extension and PATHEXT setting.\n *\n * @module\n */\n\nimport { Stats, statSync } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { IsexeOptions } from './options.js'\nimport { delimiter } from 'node:path'\n\n/**\n * Determine whether a path is executable based on the file extension\n * and PATHEXT environment variable (or specified pathExt option)\n */\nexport const isexe = async (\n path: string,\n options: IsexeOptions = {},\n): Promise<boolean> => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(await stat(path), path, options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\n/**\n * Synchronously determine whether a path is executable based on the file\n * extension and PATHEXT environment variable (or specified pathExt option)\n */\nexport const sync = (\n path: string,\n options: IsexeOptions = {},\n): boolean => {\n const { ignoreErrors = false } = options\n try {\n return checkStat(statSync(path), path, options)\n } catch (e) {\n const er = e as NodeJS.ErrnoException\n if (ignoreErrors || er.code === 'EACCES') return false\n throw er\n }\n}\n\nconst checkPathExt = (path: string, options: IsexeOptions) => {\n const { pathExt = process.env.PATHEXT || '' } = options\n const peSplit = pathExt.split(delimiter)\n if (peSplit.indexOf('') !== -1) {\n return true\n }\n\n for (const pes of peSplit) {\n const p = pes.toLowerCase()\n const ext = path.substring(path.length - p.length).toLowerCase()\n\n if (p && ext === p) {\n return true\n }\n }\n return false\n}\n\nconst checkStat = (stat: Stats, path: string, options: IsexeOptions) =>\n stat.isFile() && checkPathExt(path, options)\n"]}
+78
View File
@@ -0,0 +1,78 @@
{
"name": "isexe",
"version": "3.1.5",
"description": "Minimal module to check if a file is executable.",
"main": "./dist/commonjs/index.min.js",
"module": "./dist/esm/index.min.js",
"types": "./dist/commonjs/index.d.ts",
"files": [
"dist"
],
"tshy": {
"selfLink": false,
"exports": {
"./raw": "./src/index.ts",
"./package.json": "./package.json",
".": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.min.js"
},
"require": {
"types": "./dist/commonjs/index.d.ts",
"default": "./dist/commonjs/index.min.js"
}
}
}
},
"exports": {
"./raw": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
"types": "./dist/commonjs/index.d.ts",
"default": "./dist/commonjs/index.js"
}
},
"./package.json": "./package.json",
".": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.min.js"
},
"require": {
"types": "./dist/commonjs/index.d.ts",
"default": "./dist/commonjs/index.min.js"
}
}
},
"devDependencies": {
"@types/node": "^25.2.1",
"esbuild": "^0.27.3",
"prettier": "^3.8.1",
"tap": "^21.5.1",
"tshy": "^3.1.3",
"typedoc": "^0.28.16"
},
"scripts": {
"preversion": "npm test",
"postversion": "npm publish",
"prepublishOnly": "git push origin --follow-tags",
"prepare": "tshy && bash build.sh",
"pretest": "npm run prepare",
"presnap": "npm run prepare",
"test": "tap",
"snap": "tap",
"format": "prettier --write .",
"typedoc": "typedoc"
},
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"license": "BlueOak-1.0.0",
"repository": "https://github.com/isaacs/isexe",
"engines": {
"node": ">=18"
},
"type": "module"
}
+15
View File
@@ -0,0 +1,15 @@
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+51
View File
@@ -0,0 +1,51 @@
# which
Like the unix `which` utility.
Finds the first instance of a specified executable in the PATH
environment variable. Does not cache the results, so `hash -r` is not
needed when the PATH changes.
## USAGE
```javascript
const which = require('which')
// async usage
// rejects if not found
const resolved = await which('node')
// if nothrow option is used, returns null if not found
const resolvedOrNull = await which('node', { nothrow: true })
// sync usage
// throws if not found
const resolved = which.sync('node')
// if nothrow option is used, returns null if not found
const resolvedOrNull = which.sync('node', { nothrow: true })
// Pass options to override the PATH and PATHEXT environment vars.
await which('node', { path: someOtherPath, pathExt: somePathExt })
```
## CLI USAGE
Just like the BSD `which(1)` binary but using `node-which`.
```
usage: node-which [-as] program ...
```
You can learn more about why the binary is `node-which` and not `which`
[here](https://github.com/npm/node-which/pull/67)
## OPTIONS
You may pass an options object as the second argument.
- `path`: Use instead of the `PATH` environment variable.
- `pathExt`: Use instead of the `PATHEXT` environment variable.
- `all`: Return all matches, instead of just the first one. Note that
this means the function returns an array of strings instead of a
single string.
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env node
const which = require('../lib')
const argv = process.argv.slice(2)
const usage = (err) => {
if (err) {
console.error(`which: ${err}`)
}
console.error('usage: which [-as] program ...')
process.exit(1)
}
if (!argv.length) {
return usage()
}
let dashdash = false
const [commands, flags] = argv.reduce((acc, arg) => {
if (dashdash || arg === '--') {
dashdash = true
return acc
}
if (!/^-/.test(arg)) {
acc[0].push(arg)
return acc
}
for (const flag of arg.slice(1).split('')) {
if (flag === 's') {
acc[1].silent = true
} else if (flag === 'a') {
acc[1].all = true
} else {
usage(`illegal option -- ${flag}`)
}
}
return acc
}, [[], {}])
for (const command of commands) {
try {
const res = which.sync(command, { all: flags.all })
if (!flags.silent) {
console.log([].concat(res).join('\n'))
}
} catch (err) {
process.exitCode = 1
}
}
+111
View File
@@ -0,0 +1,111 @@
const { isexe, sync: isexeSync } = require('isexe')
const { join, delimiter, sep, posix } = require('path')
const isWindows = process.platform === 'win32'
// used to check for slashed in commands passed in. always checks for the posix
// seperator on all platforms, and checks for the current separator when not on
// a posix platform. don't use the isWindows check for this since that is mocked
// in tests but we still need the code to actually work when called. that is also
// why it is ignored from coverage.
/* istanbul ignore next */
const rSlash = new RegExp(`[${posix.sep}${sep === posix.sep ? '' : sep}]`.replace(/(\\)/g, '\\$1'))
const rRel = new RegExp(`^\\.${rSlash.source}`)
const getNotFoundError = (cmd) =>
Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' })
const getPathInfo = (cmd, {
path: optPath = process.env.PATH,
pathExt: optPathExt = process.env.PATHEXT,
delimiter: optDelimiter = delimiter,
}) => {
// If it has a slash, then we don't bother searching the pathenv.
// just check the file itself, and that's it.
const pathEnv = cmd.match(rSlash) ? [''] : [
// windows always checks the cwd first
...(isWindows ? [process.cwd()] : []),
...(optPath || /* istanbul ignore next: very unusual */ '').split(optDelimiter),
]
if (isWindows) {
const pathExtExe = optPathExt ||
['.EXE', '.CMD', '.BAT', '.COM'].join(optDelimiter)
const pathExt = pathExtExe.split(optDelimiter).flatMap((item) => [item, item.toLowerCase()])
if (cmd.includes('.') && pathExt[0] !== '') {
pathExt.unshift('')
}
return { pathEnv, pathExt, pathExtExe }
}
return { pathEnv, pathExt: [''] }
}
const getPathPart = (raw, cmd) => {
const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw
const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : ''
return prefix + join(pathPart, cmd)
}
const which = async (cmd, opt = {}) => {
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt)
const found = []
for (const envPart of pathEnv) {
const p = getPathPart(envPart, cmd)
for (const ext of pathExt) {
const withExt = p + ext
const is = await isexe(withExt, { pathExt: pathExtExe, ignoreErrors: true })
if (is) {
if (!opt.all) {
return withExt
}
found.push(withExt)
}
}
}
if (opt.all && found.length) {
return found
}
if (opt.nothrow) {
return null
}
throw getNotFoundError(cmd)
}
const whichSync = (cmd, opt = {}) => {
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt)
const found = []
for (const pathEnvPart of pathEnv) {
const p = getPathPart(pathEnvPart, cmd)
for (const ext of pathExt) {
const withExt = p + ext
const is = isexeSync(withExt, { pathExt: pathExtExe, ignoreErrors: true })
if (is) {
if (!opt.all) {
return withExt
}
found.push(withExt)
}
}
}
if (opt.all && found.length) {
return found
}
if (opt.nothrow) {
return null
}
throw getNotFoundError(cmd)
}
module.exports = which
which.sync = whichSync
+52
View File
@@ -0,0 +1,52 @@
{
"author": "GitHub Inc.",
"name": "which",
"description": "Like which(1) unix command. Find the first instance of an executable in the PATH.",
"version": "5.0.0",
"repository": {
"type": "git",
"url": "git+https://github.com/npm/node-which.git"
},
"main": "lib/index.js",
"bin": {
"node-which": "./bin/which.js"
},
"license": "ISC",
"dependencies": {
"isexe": "^3.1.1"
},
"devDependencies": {
"@npmcli/eslint-config": "^5.0.0",
"@npmcli/template-oss": "4.23.3",
"tap": "^16.3.0"
},
"scripts": {
"test": "tap",
"lint": "npm run eslint",
"postlint": "template-oss-check",
"template-oss-apply": "template-oss-apply --force",
"lintfix": "npm run eslint -- --fix",
"snap": "tap",
"posttest": "npm run lint",
"eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\""
},
"files": [
"bin/",
"lib/"
],
"tap": {
"check-coverage": true,
"nyc-arg": [
"--exclude",
"tap-snapshots/**"
]
},
"engines": {
"node": "^18.17.0 || >=20.5.0"
},
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
"version": "4.23.3",
"publish": "true"
}
}
+87
View File
@@ -0,0 +1,87 @@
{
"name": "npm-run-all2",
"type": "commonjs",
"version": "8.0.4",
"description": "A CLI tool to run multiple npm-scripts in parallel or sequential. (Maintenance fork)",
"bin": {
"run-p": "bin/run-p/index.js",
"run-s": "bin/run-s/index.js",
"npm-run-all": "bin/npm-run-all/index.js",
"npm-run-all2": "bin/npm-run-all/index.js"
},
"main": "lib/index.js",
"engines": {
"node": "^20.5.0 || >=22.0.0",
"npm": ">= 10"
},
"scripts": {
"clean": "rm -rf coverage jsdoc \"test-workspace/{build,test.txt}\"",
"docs": "jsdoc -c jsdoc.json",
"check:installed-check": "installed-check --ignore-dev",
"check:eslint": "eslint",
"check:knip": "knip",
"precheck": "node scripts/make-slink.js",
"check": "node ./bin/run-p/index.js check:*",
"pretest-mocha": "node scripts/make-slink.js",
"test-mocha": "c8 mocha --timeout 120000",
"test": "node ./bin/run-s/index.js check test-mocha",
"watch": "mocha --timeout 120000 --watch --growl",
"version": "auto-changelog -p --template keepachangelog auto-changelog --breaking-pattern 'BREAKING CHANGE:' && git add CHANGELOG.md",
"prepublishOnly": "git push --follow-tags && gh-release -y"
},
"dependencies": {
"ansi-styles": "^6.2.1",
"cross-spawn": "^7.0.6",
"memorystream": "^0.3.1",
"picomatch": "^4.0.2",
"pidtree": "^0.6.0",
"read-package-json-fast": "^4.0.0",
"shell-quote": "^1.7.3",
"which": "^5.0.0"
},
"devDependencies": {
"auto-changelog": "^2.2.0",
"c8": "^10.0.0",
"eslint": "^9.6.0",
"gh-release": "^7.0.0",
"installed-check": "^9.3.0",
"jsdoc": "^4.0.0",
"knip": "^5.23.3",
"mocha": "^11.0.1",
"neostandard": "^0.12.0",
"yarn": "^1.12.3"
},
"repository": {
"type": "git",
"url": "https://github.com/bcomnes/npm-run-all2.git"
},
"keywords": [
"cli",
"command",
"commandline",
"tool",
"npm",
"npm-scripts",
"run",
"sequential",
"serial",
"parallel",
"task"
],
"author": "Toru Nagashima",
"contributors": [
"Bret Comnes <bcomnes@gmail.com> (https://bret.io)"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/bcomnes/npm-run-all2/issues"
},
"homepage": "https://github.com/bcomnes/npm-run-all2",
"c8": {
"reporter": [
"html",
"lcovonly",
"text"
]
}
}
+21
View File
@@ -0,0 +1,21 @@
/**
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
'use strict'
const fs = require('fs')
const path = require('path')
try {
fs.symlinkSync(
path.resolve(__dirname, '../test/lib'),
path.resolve(__dirname, '../test-workspace/tasks/lib'),
'junction'
)
} catch (err) {
if (err.code !== 'EEXIST') {
throw err
}
}
@@ -0,0 +1 @@
to add to git.
@@ -0,0 +1,15 @@
{
"name": "npm-run-all-test",
"version": "0.0.0",
"private": true,
"description": "",
"config": {
"test": "OK"
},
"repository": {
"type": "git",
"url": "https://github.com/mysticatea/npm-run-all.git"
},
"author": "Toru Nagashima",
"license": "MIT"
}
+52
View File
@@ -0,0 +1,52 @@
{
"name": "npm-run-all-test",
"version": "0.0.0",
"private": true,
"description": "",
"engines": {
"node": ">=4"
},
"config": {
"DEST": "build",
"test": "OK"
},
"scripts": {
"start": "node tasks/append2.js start",
"stop": "node tasks/append2.js stop",
"test-task:package-config": "node tasks/package-config1.js",
"test-task:package-config2": "node tasks/package-config2.js",
"test-task:nested-package-config": "node ../bin/npm-run-all/index.js test-task:package-config",
"test-task:config": "node tasks/config1.js",
"test-task:config2": "node tasks/config2.js",
"test-task:nested-config": "node ../bin/npm-run-all/index.js test-task:config",
"test-task:append": "node tasks/append2.js",
"test-task:append:a": "node tasks/append2.js a",
"test-task:append:a:c": "node tasks/append2.js ac",
"test-task:append:a:d": "node tasks/append2.js ad",
"test-task:append:b": "node tasks/append2.js b",
"test-task:append1": "node tasks/append1.js",
"test-task:append2": "node tasks/append2.js",
"test-task:abort": "node tasks/abort.js",
"test-task:error": "node tasks/error.js",
"test-task:stdout": "node tasks/stdout.js > test.txt",
"test-task:stderr": "node tasks/stderr.js 2> test.txt",
"test-task:stdin": "echo STDIN | node tasks/stdin.js",
"test-task:issue14:win32": "rm -rf build && mkdir %npm_package_config_DEST% && cd build",
"test-task:issue14:posix": "rm -rf build && mkdir $npm_package_config_DEST && cd build",
"test-task:echo": "node tasks/echo.js",
"test-task:dump": "node tasks/dump.js",
"test-task:nest-append:npm-run-all": "node ../bin/npm-run-all/index.js test-task:append",
"test-task:nest-append:run-s": "node ../bin/run-s/index.js test-task:append",
"test-task:nest-append:run-p": "node ../bin/run-p/index.js test-task:append",
"test-task:delayed": "node tasks/output-with-delay.js",
"test-task:yarn": "node ../bin/npm-run-all/index.js test-task:append:{a,b} --npm-path yarn",
"!test": "node tasks/append1.js X",
"?test": "node tasks/append1.js Q"
},
"repository": {
"type": "git",
"url": "https://github.com/mysticatea/npm-run-all.git"
},
"author": "Toru Nagashima",
"license": "MIT"
}
@@ -0,0 +1,7 @@
{
"rules": {
"no-console": 0,
"no-process-env": 0,
"no-process-exit": 0
}
}
+5
View File
@@ -0,0 +1,5 @@
'use strict'
setTimeout(() => {
process.abort()
}, 500)
+6
View File
@@ -0,0 +1,6 @@
'use strict'
const appendResult = require('./lib/util').appendResult
appendResult(process.argv[2])
process.exit(0)
+17
View File
@@ -0,0 +1,17 @@
'use strict'
const appendResult = require('./lib/util').appendResult
appendResult(process.argv[2])
setTimeout(() => {
appendResult(process.argv[2])
process.exit(0)
}, 3000)
// SIGINT/SIGTERM Handling.
process.on('SIGINT', () => {
process.exit(0)
})
process.on('SIGTERM', () => {
process.exit(0)
})

Some files were not shown because too many files have changed in this diff Show More