avancement planning

This commit is contained in:
2026-05-26 11:58:39 +02:00
parent 619a2b240a
commit 150b97cd2e
4892 changed files with 99214 additions and 429382 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
{
".": "11.5.0"
".": "12.3.0"
}
+90
View File
@@ -1,5 +1,95 @@
# Changelog
## [12.3.0](https://github.com/nodejs/node-gyp/compare/v12.2.0...v12.3.0) (2026-04-21)
### Features
* replace make-fetch-happen with built-in fetch ([#3302](https://github.com/nodejs/node-gyp/issues/3302)) ([393ec2b](https://github.com/nodejs/node-gyp/commit/393ec2be480195b585768eb18ac2d92b858b12db))
* update gyp-next to v0.22.1 ([#3295](https://github.com/nodejs/node-gyp/issues/3295)) ([f4242fb](https://github.com/nodejs/node-gyp/commit/f4242fb7bf7592d71848bae5c7f8597f2718dc3f))
### Bug Fixes
* Switch to URL instead of url.resolve ([#3256](https://github.com/nodejs/node-gyp/issues/3256)) ([#3263](https://github.com/nodejs/node-gyp/issues/3263)) ([46d7576](https://github.com/nodejs/node-gyp/commit/46d75768018d10dc4b5693b35cf58f502425cbbe))
### Core
* **deps-dev:** bump neostandard from 0.12.2 to 0.13.0 ([#3289](https://github.com/nodejs/node-gyp/issues/3289)) ([19da158](https://github.com/nodejs/node-gyp/commit/19da1583b3876dce8c97263b168d9dfef637b76b))
* improve Add-Type with -IgnoreWarnings ([#3280](https://github.com/nodejs/node-gyp/issues/3280)) ([1381458](https://github.com/nodejs/node-gyp/commit/13814583a476c85a84d5ac902c7ffa310120cb88))
## [12.2.0](https://github.com/nodejs/node-gyp/compare/v12.1.0...v12.2.0) (2026-01-26)
### Features
* include built package version in error logs ([#3254](https://github.com/nodejs/node-gyp/issues/3254)) ([ee9cbdd](https://github.com/nodejs/node-gyp/commit/ee9cbdd6e1d40dc7c1cdc5ed6a75432c716eaf3f))
* update gyp-next to v0.21.1 ([#3273](https://github.com/nodejs/node-gyp/issues/3273)) ([888ff2c](https://github.com/nodejs/node-gyp/commit/888ff2c48a4cf5602013b96b52c6670906976f63))
### Bug Fixes
* cpu concurrency detection on some platforms ([#3255](https://github.com/nodejs/node-gyp/issues/3255)) ([f15b79a](https://github.com/nodejs/node-gyp/commit/f15b79a03c54cea0f66d940a0d6d839df867a319)), closes [#3191](https://github.com/nodejs/node-gyp/issues/3191)
* python is no longer a valid npm config setting ([#3258](https://github.com/nodejs/node-gyp/issues/3258)) ([c7c678f](https://github.com/nodejs/node-gyp/commit/c7c678f89837d956194f326b01c5a8eb1d745db3))
* Switch to URL instead of url.parse ([#3256](https://github.com/nodejs/node-gyp/issues/3256)) ([3f81949](https://github.com/nodejs/node-gyp/commit/3f819499d8ce6d46c646466de7b9492bf7bde663))
* Test Windows on Python 3.14, not 3.13 ([#3262](https://github.com/nodejs/node-gyp/issues/3262)) ([7b4f315](https://github.com/nodejs/node-gyp/commit/7b4f315e4dad880c841d21df641d6dd9b68bf36b))
### Core
* **deps:** bump actions/checkout from 5 to 6 ([#3248](https://github.com/nodejs/node-gyp/issues/3248)) ([db5385c](https://github.com/nodejs/node-gyp/commit/db5385c5467e5bfb914b9954f0313c46f1f4e10d))
### Doc
* add a note about changes in gyp folder ([#3259](https://github.com/nodejs/node-gyp/issues/3259)) ([a52bc81](https://github.com/nodejs/node-gyp/commit/a52bc819f44b881854ff798865ad416430e3dce2))
* correct typos ([#3269](https://github.com/nodejs/node-gyp/issues/3269)) ([0f2bc7d](https://github.com/nodejs/node-gyp/commit/0f2bc7d2e0665b1c7bb03e1cd8653ea330277a70))
* remove obsolete Microsoft Node.js Guidelines link ([#3268](https://github.com/nodejs/node-gyp/issues/3268)) ([30cda26](https://github.com/nodejs/node-gyp/commit/30cda268730798dc0f67182c8c568d8b8069964e))
* update Python manual install instructions for Windows ([#3265](https://github.com/nodejs/node-gyp/issues/3265)) ([0407877](https://github.com/nodejs/node-gyp/commit/0407877e3e26d3201f74cf1a9deabbbfc40bdbb7))
### Miscellaneous
* **deps:** upgrade tar to 7.5.4 to address CVE-2026-23950 ([#3271](https://github.com/nodejs/node-gyp/issues/3271)) ([7bf371c](https://github.com/nodejs/node-gyp/commit/7bf371c4dd7c694232ab3169d02fe8197e1ecc6d))
## [12.1.0](https://github.com/nodejs/node-gyp/compare/v12.0.0...v12.1.0) (2025-11-12)
### Features
* Add support for Visual Studio 2026 (18.x) ([69e5fd2](https://github.com/nodejs/node-gyp/commit/69e5fd2c98ac83dad5200a47515b301ccd80d2d3))
* Support for Visual Studio 2026 (18.x) ([69e5fd2](https://github.com/nodejs/node-gyp/commit/69e5fd2c98ac83dad5200a47515b301ccd80d2d3))
## [12.0.0](https://github.com/nodejs/node-gyp/compare/v11.5.0...v12.0.0) (2025-11-10)
### ⚠ BREAKING CHANGES
* align to npm 11 node engine range
### Features
* align to npm 11 node engine range ([2f85686](https://github.com/nodejs/node-gyp/commit/2f85686bbe745673350a8f9dbb0e86ee0190f213))
* update gyp-next to v0.21.0 ([c57cd2e](https://github.com/nodejs/node-gyp/commit/c57cd2e86dc57707475b9f7e676e189f064817de))
### Core
* **deps:** bump actions/setup-node from 5 to 6 ([ae90e63](https://github.com/nodejs/node-gyp/commit/ae90e632d9fab85f4cd902dc9205ba9dfafaf3bc))
* **deps:** bump env-paths from 2.2.1 to 3.0.0 ([#3235](https://github.com/nodejs/node-gyp/issues/3235)) ([5fffb2f](https://github.com/nodejs/node-gyp/commit/5fffb2ffee304cc898fdea7a0cd9e41d54c53839))
* **deps:** bump which from 5.0.0 to 6.0.0 ([#3238](https://github.com/nodejs/node-gyp/issues/3238)) ([eaa8e34](https://github.com/nodejs/node-gyp/commit/eaa8e34cb5a0710bef0602c42e5840b47eb76822))
* make-fetch-happen@15.0.0 ([e2b9d21](https://github.com/nodejs/node-gyp/commit/e2b9d21bce27c35d18fcb6f8583e386d15ce395c))
* nopt@9.0.0 ([9bdeaf3](https://github.com/nodejs/node-gyp/commit/9bdeaf307cd7a254946859d306465989fa39dfb2))
* proc-log@6.0.0 ([dfc68df](https://github.com/nodejs/node-gyp/commit/dfc68dfba3c17deb0bda9a395bb49d8fb9fa5951))
### Miscellaneous
* increase test timeouts ([#3237](https://github.com/nodejs/node-gyp/issues/3237)) ([3b41971](https://github.com/nodejs/node-gyp/commit/3b41971e2f6b90e02b1d7df592d403b8dfc8fa4d))
* setup dependabot for npm ([86d65c7](https://github.com/nodejs/node-gyp/commit/86d65c7874eb41eb49c9b8bbf342becac8e57c6f))
* update devDependencies ([41b0cea](https://github.com/nodejs/node-gyp/commit/41b0cea2f12342a790580cc8f844f075d49e096c))
## [11.5.0](https://github.com/nodejs/node-gyp/compare/v11.4.2...v11.5.0) (2025-10-15)
+10
View File
@@ -1,5 +1,13 @@
# Contributing to node-gyp
## Making changes to gyp-next
Changes in the subfolder `gyp/` should be submitted to the
[`gyp-next`][] repository first. The `gyp/` folder is regularly
synced from [`gyp-next`][] with GitHub Actions workflow
[`update-gyp-next.yml`](.github/workflows/update-gyp-next.yml),
and any changes in this folder would be overridden by the workflow.
## Code of Conduct
Please read the
@@ -32,3 +40,5 @@ By making a contribution to this project, I certify that:
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
[`gyp-next`]: https://github.com/nodejs/gyp-next
+6 -8
View File
@@ -55,19 +55,17 @@ choco install python visualstudio2022-workload-vctools -y
Or install and configure Python and Visual Studio tools manually:
* Install the current [version of Python](https://devguide.python.org/versions/) from the
[Microsoft Store](https://apps.microsoft.com/store/search?publisher=Python+Software+Foundation).
* Follow the instructions in [Using Python on Windows](https://docs.python.org/3/using/windows.html) to install
the current [version of Python](https://www.python.org/downloads/).
* Install Visual C++ Build Environment: For Visual Studio 2019 or later, use the `Desktop development with C++` workload from [Visual Studio Community](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community). For a version older than Visual Studio 2019, install [Visual Studio Build Tools](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) with the `Visual C++ build tools` option.
If the above steps didn't work for you, please visit [Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules) for additional tips.
To target native ARM64 Node.js on Windows on ARM, add the components "Visual C++ compilers and libraries for ARM64" and "Visual C++ ATL for ARM64".
To use the native ARM64 C++ compiler on Windows on ARM, ensure that you have Visual Studio 2022 [17.4 or later](https://devblogs.microsoft.com/visualstudio/arm64-visual-studio-is-officially-here/) installed.
It's advised to install following Powershell module: [VSSetup](https://github.com/microsoft/vssetup.powershell) using `Install-Module VSSetup -Scope CurrentUser`.
This will make Visual Studio detection logic to use more flexible and accessible method, avoiding Powershell's `ConstrainedLanguage` mode.
It's advised to install the following PowerShell module: [VSSetup](https://github.com/microsoft/vssetup.powershell) using `Install-Module VSSetup -Scope CurrentUser`.
This will make Visual Studio detection logic use a more flexible and accessible method, avoiding PowerShell's `ConstrainedLanguage` mode.
### Configuring Python Dependency
@@ -270,8 +268,8 @@ set npm_package_config_node_gyp_devdir=c:\temp\.gyp
```
Note that in versions of npm before v11 it was possible to use the prefix `npm_config_` for
environement variables. This was deprecated in npm@11 and will be removed in npm@12 so it
is recommened to convert your environment variables to the above format.
environment variables. This was deprecated in npm@11 and will be removed in npm@12 so it
is recommended to convert your environment variables to the above format.
### `npm` configuration for npm versions before v9
+7
View File
@@ -125,6 +125,13 @@ function errorMessage () {
log.error('cwd', process.cwd())
log.error('node -v', process.version)
log.error('node-gyp -v', 'v' + prog.package.version)
// print the npm package version
for (const env of ['npm_package_name', 'npm_package_version']) {
const value = process.env[env]
if (value != null) {
log.error(`$${env}`, value)
}
}
}
function issueMessage () {
+1 -1
View File
@@ -1,3 +1,3 @@
{
".": "0.20.5"
".": "0.22.1"
}
+3 -3
View File
@@ -34,7 +34,7 @@ def MakeGuid(name, seed="msvs_new"):
Args:
name: Target name.
seed: Seed for MD5 hash.
seed: Seed for SHA-256 hash.
Returns:
A GUID-line string calculated from the name and seed.
@@ -44,8 +44,8 @@ def MakeGuid(name, seed="msvs_new"):
determine the GUID to refer to explicitly. It also means that the GUID will
not change when the project for a target is rebuilt.
"""
# Calculate a MD5 signature for the seed and name.
d = hashlib.md5((str(seed) + str(name)).encode("utf-8")).hexdigest().upper()
# Calculate a SHA-256 signature for the seed and name.
d = hashlib.sha256((str(seed) + str(name)).encode("utf-8")).hexdigest().upper()
# Convert most of the signature to GUID form (discard the rest)
guid = (
"{"
+37 -4
View File
@@ -87,7 +87,7 @@ class VisualStudioVersion:
def _SetupScriptInternal(self, target_arch):
"""Returns a command (with arguments) to be used to set up the
environment."""
assert target_arch in ("x86", "x64"), "target_arch not supported"
assert target_arch in ("x86", "x64", "arm64"), "target_arch not supported"
# If WindowsSDKDir is set and SetEnv.Cmd exists then we are using the
# depot_tools build tools and should run SetEnv.Cmd to set up the
# environment. The check for WindowsSDKDir alone is not sufficient because
@@ -109,8 +109,16 @@ class VisualStudioVersion:
)
# Always use a native executable, cross-compiling if necessary.
host_arch = "amd64" if is_host_arch_x64 else "x86"
msvc_target_arch = "amd64" if target_arch == "x64" else "x86"
host_arch = (
"amd64"
if is_host_arch_x64
else (
"arm64"
if os.environ.get("PROCESSOR_ARCHITECTURE") == "ARM64"
else "x86"
)
)
msvc_target_arch = {"x64": "amd64"}.get(target_arch, target_arch)
arg = host_arch
if host_arch != msvc_target_arch:
arg += "_" + msvc_target_arch
@@ -270,6 +278,18 @@ def _CreateVersion(name, path, sdk_based=False):
if path:
path = os.path.normpath(path)
versions = {
"2026": VisualStudioVersion(
"2026",
"Visual Studio 2026",
solution_version="12.00",
project_version="18.0",
flat_sln=False,
uses_vcxproj=True,
path=path,
sdk_based=sdk_based,
default_toolset="v145",
compatible_sdks=["v8.1", "v10.0"],
),
"2022": VisualStudioVersion(
"2022",
"Visual Studio 2022",
@@ -462,6 +482,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
"15.0": "2017",
"16.0": "2019",
"17.0": "2022",
"18.0": "2026",
}
versions = []
for version in versions_to_check:
@@ -537,7 +558,18 @@ def SelectVisualStudioVersion(version="auto", allow_fallback=True):
if version == "auto":
version = os.environ.get("GYP_MSVS_VERSION", "auto")
version_map = {
"auto": ("17.0", "16.0", "15.0", "14.0", "12.0", "10.0", "9.0", "8.0", "11.0"),
"auto": (
"18.0",
"17.0",
"16.0",
"15.0",
"14.0",
"12.0",
"10.0",
"9.0",
"8.0",
"11.0",
),
"2005": ("8.0",),
"2005e": ("8.0",),
"2008": ("9.0",),
@@ -552,6 +584,7 @@ def SelectVisualStudioVersion(version="auto", allow_fallback=True):
"2017": ("15.0",),
"2019": ("16.0",),
"2022": ("17.0",),
"2026": ("18.0",),
}
if override_path := os.environ.get("GYP_MSVS_OVERRIDE_PATH"):
msvs_version = os.environ.get("GYP_MSVS_VERSION")
+2 -3
View File
@@ -13,6 +13,7 @@ import re
import shlex
import sys
import traceback
from importlib.metadata import version
import gyp.input
from gyp.common import GypError
@@ -491,9 +492,7 @@ def gyp_main(args):
options, build_files_arg = parser.parse_args(args)
if options.version:
import pkg_resources # noqa: PLC0415
print(f"v{pkg_resources.get_distribution('gyp-next').version}")
print(f"v{version('gyp-next')}")
return 0
build_files = build_files_arg
+1 -1
View File
@@ -2169,7 +2169,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
# - The multi-output rule will have an do-nothing recipe.
# Hash the target name to avoid generating overlong filenames.
cmddigest = hashlib.sha1(
cmddigest = hashlib.sha256(
(command or self.target).encode("utf-8")
).hexdigest()
intermediate = "%s.intermediate" % cmddigest
+1 -1
View File
@@ -857,7 +857,7 @@ def _EscapeCommandLineArgumentForMSBuild(s):
"""Escapes a Windows command-line argument for use by MSBuild."""
def _Replace(match):
return (len(match.group(1)) / 2 * 4) * "\\" + '\\"'
return (len(match.group(1)) // 2 * 4) * "\\" + '\\"'
# Escape all quotes so that they are interpreted literally.
s = quote_replacer_regex2.sub(_Replace, s)
+5 -5
View File
@@ -246,7 +246,7 @@ class NinjaWriter:
if flavor == "win":
# See docstring of msvs_emulation.GenerateEnvironmentFiles().
self.win_env = {}
for arch in ("x86", "x64"):
for arch in ("x86", "x64", "arm64"):
self.win_env[arch] = "environment." + arch
# Relative path from build output dir to base dir.
@@ -809,9 +809,8 @@ class NinjaWriter:
outputs = [self.GypPathToNinja(o, env) for o in outputs]
if self.flavor == "win":
# WriteNewNinjaRule uses unique_name to create a rsp file on win.
extra_bindings.append(
("unique_name", hashlib.md5(outputs[0]).hexdigest())
)
unique_name = hashlib.sha256(outputs[0].encode("utf-8")).hexdigest()
extra_bindings.append(("unique_name", unique_name))
self.ninja.build(
outputs,
@@ -2340,6 +2339,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
master_ninja.variable("rc", "rc.exe")
master_ninja.variable("ml_x86", "ml.exe")
master_ninja.variable("ml_x64", "ml64.exe")
master_ninja.variable("ml_arm64", "armasm64.exe")
master_ninja.variable("mt", "mt.exe")
else:
master_ninja.variable("ld", CommandWithWrapper("LINK", wrappers, ld))
@@ -2803,7 +2803,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
build_file, name, toolset
)
qualified_target_for_hash = qualified_target_for_hash.encode("utf-8")
hash_for_rules = hashlib.md5(qualified_target_for_hash).hexdigest()
hash_for_rules = hashlib.sha256(qualified_target_for_hash).hexdigest()
base_path = os.path.dirname(build_file)
obj = "obj"
+26 -16
View File
@@ -11,26 +11,36 @@ import unittest
from pathlib import Path
from gyp.generator import ninja
from gyp.MSVSVersion import SelectVisualStudioVersion
def _has_visual_studio():
"""Check if Visual Studio can be detected by gyp's registry-based detection."""
if not sys.platform.startswith("win"):
return False
try:
SelectVisualStudioVersion("auto", allow_fallback=False)
return True
except ValueError:
return False
class TestPrefixesAndSuffixes(unittest.TestCase):
@unittest.skipUnless(
_has_visual_studio(),
"requires Windows with a Visual Studio installation detected via the registry",
)
def test_BinaryNamesWindows(self):
# These cannot run on non-Windows as they require a VS installation to
# correctly handle variable expansion.
if sys.platform.startswith("win"):
writer = ninja.NinjaWriter(
"foo", "wee", ".", ".", "build.ninja", ".", "build.ninja", "win"
)
spec = {"target_name": "wee"}
self.assertTrue(
writer.ComputeOutputFileName(spec, "executable").endswith(".exe")
)
self.assertTrue(
writer.ComputeOutputFileName(spec, "shared_library").endswith(".dll")
)
self.assertTrue(
writer.ComputeOutputFileName(spec, "static_library").endswith(".lib")
)
writer = ninja.NinjaWriter(
"foo", "wee", ".", ".", "build.ninja", ".", "build.ninja", "win"
)
spec = {"target_name": "wee"}
for key, ext in {
"executable": ".exe",
"shared_library": ".dll",
"static_library": ".lib",
}.items():
self.assertTrue(writer.ComputeOutputFileName(spec, key).endswith(ext))
def test_BinaryNamesLinux(self):
writer = ninja.NinjaWriter(
+1 -1
View File
@@ -545,7 +545,7 @@ class MacTool:
# If the user has multiple provisioning profiles installed that can be
# used for ${bundle_identifier}, pick the most specific one (ie. the
# provisioning profile whose pattern is the longest).
selected_key = max(valid_provisioning_profiles, key=lambda v: len(v))
selected_key = max(valid_provisioning_profiles, key=len)
return valid_provisioning_profiles[selected_key]
def _LoadProvisioningProfile(self, profile_path):
+1 -1
View File
@@ -1174,7 +1174,7 @@ def GenerateEnvironmentFiles(
meet your requirement (e.g. for custom toolchains), you can pass
"-G ninja_use_custom_environment_files" to the gyp to suppress file
generation and use custom environment files prepared by yourself."""
archs = ("x86", "x64")
archs = ("x86", "x64", "arm64")
if generator_flags.get("ninja_use_custom_environment_files", 0):
cl_paths = {}
for arch in archs:
+2 -2
View File
@@ -24,8 +24,8 @@ def deepcopy(x):
return _deepcopy_dispatch[type(x)](x)
except KeyError:
raise Error(
"Unsupported type %s for deepcopy. Use copy.deepcopy "
+ "or expand simple_copy support." % type(x)
f"Unsupported type {type(x)} for deepcopy. Use copy.deepcopy "
+ "or expand simple_copy support."
)
+1 -1
View File
@@ -429,7 +429,7 @@ class XCObject:
hash.update(data)
if seed_hash is None:
seed_hash = hashlib.sha1()
seed_hash = hashlib.sha256()
hash = seed_hash.copy()
+3 -20
View File
@@ -21,27 +21,10 @@ from typing import (
from . import requirements, specifiers, utils, version as version_module
T = typing.TypeVar("T")
if sys.version_info[:2] >= (3, 8): # pragma: no cover
from typing import Literal, TypedDict
else: # pragma: no cover
if typing.TYPE_CHECKING:
from typing_extensions import Literal, TypedDict
else:
try:
from typing_extensions import Literal, TypedDict
except ImportError:
class Literal:
def __init_subclass__(*_args, **_kwargs):
pass
class TypedDict:
def __init_subclass__(*_args, **_kwargs):
pass
from typing import Literal, TypedDict
try:
ExceptionGroup
ExceptionGroup # Added in Python 3.11+
except NameError: # pragma: no cover
class ExceptionGroup(Exception): # noqa: N818
@@ -504,7 +487,7 @@ class _Validator(Generic[T]):
self.raw_name = _RAW_TO_EMAIL_MAPPING[name]
def __get__(self, instance: "Metadata", _owner: Type["Metadata"]) -> T:
# With Python 3.8, the caching can be replaced with functools.cached_property().
# With Python 3.8+, the caching can be replaced with functools.cached_property().
# No need to check the cache as attribute lookup will resolve into the
# instance's __dict__ before __get__ is called.
cache = instance.__dict__
+2 -14
View File
@@ -127,10 +127,8 @@ def _normalize_string(string: str) -> str:
def _abi3_applies(python_version: PythonVersion) -> bool:
"""
Determine if the Python version supports abi3.
PEP 384 was first implemented in Python 3.2.
"""
return len(python_version) > 1 and tuple(python_version) >= (3, 2)
return len(python_version) > 1
def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> List[str]:
@@ -146,17 +144,7 @@ def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> List[str]:
has_ext = "_d.pyd" in EXTENSION_SUFFIXES
if with_debug or (with_debug is None and (has_refcount or has_ext)):
debug = "d"
if py_version < (3, 8):
with_pymalloc = _get_config_var("WITH_PYMALLOC", warn)
if with_pymalloc or with_pymalloc is None:
pymalloc = "m"
if py_version < (3, 3):
unicode_size = _get_config_var("Py_UNICODE_SIZE", warn)
if unicode_size == 4 or (
unicode_size is None and sys.maxunicode == 0x10FFFF
):
ucs4 = "u"
elif debug:
if debug:
# Debug builds can also load "normal" extension modules.
# We can also assume no UCS-4 or pymalloc requirement.
abis.append(f"cp{version}")
+5 -3
View File
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
[project]
name = "gyp-next"
version = "0.20.5"
version = "0.22.1"
authors = [
{ name="Node.js contributors", email="ryzokuken@disroot.org" },
]
description = "A fork of the GYP build system for use in the Node.js projects"
readme = "README.md"
license = { file="LICENSE" }
requires-python = ">=3.8"
requires-python = ">=3.9"
dependencies = ["packaging>=24.0", "setuptools>=69.5.1"]
classifiers = [
"Development Status :: 3 - Alpha",
@@ -21,10 +21,12 @@ classifiers = [
"Natural Language :: English",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
[project.optional-dependencies]
+2 -2
View File
@@ -163,7 +163,7 @@ async function build (gyp, argv) {
if (!isNaN(j) && j > 0) {
argv.push('/m:' + j)
} else if (jobs.toUpperCase() === 'MAX') {
argv.push('/m:' + require('os').cpus().length)
argv.push('/m:' + require('os').availableParallelism())
}
}
} else {
@@ -178,7 +178,7 @@ async function build (gyp, argv) {
argv.push(j)
} else if (jobs.toUpperCase() === 'MAX') {
argv.push('--jobs')
argv.push(require('os').cpus().length)
argv.push(require('os').availableParallelism())
}
}
}
+55 -8
View File
@@ -1,4 +1,5 @@
const fetch = require('make-fetch-happen')
const { Readable } = require('stream')
const { EnvHttpProxyAgent } = require('undici')
const { promises: fs } = require('graceful-fs')
const log = require('./log')
@@ -10,19 +11,65 @@ async function download (gyp, url) {
'User-Agent': `node-gyp v${gyp.version} (node ${process.version})`,
Connection: 'keep-alive'
},
proxy: gyp.opts.proxy,
noProxy: gyp.opts.noproxy
dispatcher: await createDispatcher(gyp)
}
const cafile = gyp.opts.cafile
if (cafile) {
requestOpts.ca = await readCAFile(cafile)
let res
try {
res = await fetch(url, requestOpts)
} catch (err) {
// Built-in fetch wraps low-level errors in "TypeError: fetch failed" with
// the underlying error on .cause. Callers inspect .code (e.g. ENOTFOUND).
if (err.cause) {
throw err.cause
}
throw err
}
const res = await fetch(url, requestOpts)
log.http(res.status, res.url)
return res
const body = res.body ? Readable.fromWeb(res.body) : Readable.from([])
return {
status: res.status,
url: res.url,
body,
text: async () => {
let data = ''
body.setEncoding('utf8')
for await (const chunk of body) {
data += chunk
}
return data
}
}
}
async function createDispatcher (gyp) {
const env = process.env
const hasProxyEnv = env.http_proxy || env.HTTP_PROXY || env.https_proxy || env.HTTPS_PROXY
if (!gyp.opts.proxy && !gyp.opts.cafile && !hasProxyEnv) {
return undefined
}
const opts = {}
if (gyp.opts.cafile) {
const ca = await readCAFile(gyp.opts.cafile)
// EnvHttpProxyAgent forwards opts to both its internal Agent (direct) and
// ProxyAgent (proxied). Agent reads TLS config from `connect`; ProxyAgent
// reads it from `requestTls` (origin) / `proxyTls` (proxy). Set all three
// so the custom CA is applied regardless of which path a request takes.
opts.connect = { ca }
opts.requestTls = { ca }
opts.proxyTls = { ca }
}
if (gyp.opts.proxy) {
opts.httpProxy = gyp.opts.proxy
opts.httpsProxy = gyp.opts.proxy
}
if (gyp.opts.noproxy) {
opts.noProxy = gyp.opts.noproxy
}
return new EnvHttpProxyAgent(opts)
}
async function readCAFile (filename) {
+2 -8
View File
@@ -86,14 +86,10 @@ class PythonFinder {
{
before: () => {
if (!this.configPython) {
this.addLog(
'Python is not set from command line or npm configuration')
this.addLog('--python was not set on the command line')
return SKIP
}
this.addLog('checking Python explicitly set from command line or ' +
'npm configuration')
this.addLog('- "--python=" or "npm config get python" is ' +
`"${this.configPython}"`)
this.addLog(`--python=${this.configPython} was set on the command line`)
},
check: () => this.checkCommand(this.configPython)
},
@@ -295,8 +291,6 @@ class PythonFinder {
`- Use the switch --python="${pathExample}"`,
' (accepted by both node-gyp and npm)',
'- Set the environment variable PYTHON',
'- Set the npm configuration variable python:',
` npm config set python "${pathExample}"`,
'For more information consult the documentation at:',
'https://github.com/nodejs/node-gyp#installation',
'**********************************************************'
+12 -6
View File
@@ -30,7 +30,7 @@ class VisualStudioFinder {
this.configVersionYear = null
this.configPath = null
if (this.configMsvsVersion) {
this.addLog('msvs_version was set from command line or npm config')
this.addLog(`--msvs_version=${this.configMsvsVersion} was set on the command line`)
if (this.configMsvsVersion.match(/^\d{4}$/)) {
this.configVersionYear = parseInt(this.configMsvsVersion, 10)
this.addLog(
@@ -41,7 +41,7 @@ class VisualStudioFinder {
`- looking for Visual Studio installed in "${this.configPath}"`)
}
} else {
this.addLog('msvs_version not set from command line or npm config')
this.addLog('--msvs_version was not set on the command line')
}
if (process.env.VCINSTALLDIR) {
@@ -119,7 +119,7 @@ class VisualStudioFinder {
}
async findVisualStudio2019OrNewerFromSpecifiedLocation () {
return this.findVSFromSpecifiedLocation([2019, 2022])
return this.findVSFromSpecifiedLocation([2019, 2022, 2026])
}
async findVisualStudio2017FromSpecifiedLocation () {
@@ -162,7 +162,7 @@ class VisualStudioFinder {
}
async findVisualStudio2019OrNewerUsingSetupModule () {
return this.findNewVSUsingSetupModule([2019, 2022])
return this.findNewVSUsingSetupModule([2019, 2022, 2026])
}
async findVisualStudio2017UsingSetupModule () {
@@ -223,7 +223,7 @@ class VisualStudioFinder {
// Invoke the PowerShell script to get information about Visual Studio 2019
// or newer installations
async findVisualStudio2019OrNewer () {
return this.findNewVS([2019, 2022])
return this.findNewVS([2019, 2022, 2026])
}
// Invoke the PowerShell script to get information about Visual Studio 2017
@@ -247,7 +247,7 @@ class VisualStudioFinder {
'Unrestricted',
'-NoProfile',
'-Command',
'&{Add-Type -Path \'' + csFile + '\';' + '[VisualStudioConfiguration.Main]::PrintJson()}'
'&{Add-Type -IgnoreWarnings -Path \'' + csFile + '\';' + '[VisualStudioConfiguration.Main]::PrintJson()}'
]
this.log.silly('Running', ps, psArgs)
@@ -389,6 +389,10 @@ class VisualStudioFinder {
ret.versionYear = 2022
return ret
}
if (ret.versionMajor === 18) {
ret.versionYear = 2026
return ret
}
this.log.silly('- unsupported version:', ret.versionMajor)
return {}
}
@@ -456,6 +460,8 @@ class VisualStudioFinder {
return 'v142'
} else if (versionYear === 2022) {
return 'v143'
} else if (versionYear === 2026) {
return 'v145'
}
this.log.silly('- invalid versionYear:', versionYear)
return null
+1 -1
View File
@@ -198,7 +198,7 @@ async function install (gyp, argv) {
}
// download the tarball and extract!
// Ommited on Windows if only new node.lib is required
// Omitted on Windows if only new node.lib is required
// there can be file errors from tar if parallel installs
// are happening (not uncommon with multiple native modules) so
+17 -19
View File
@@ -1,9 +1,6 @@
/* eslint-disable n/no-deprecated-api */
'use strict'
const semver = require('semver')
const url = require('url')
const path = require('path')
const log = require('./log')
@@ -74,11 +71,11 @@ function processRelease (argv, gyp, defaultVersion, defaultRelease) {
} else {
distBaseUrl = 'https://nodejs.org/dist'
}
distBaseUrl += '/v' + version + '/'
distBaseUrl = new URL(distBaseUrl + '/v' + version + '/')
// new style, based on process.release so we have a lot of the data we need
if (defaultRelease && defaultRelease.headersUrl && !overrideDistUrl) {
baseUrl = url.resolve(defaultRelease.headersUrl, './')
baseUrl = new URL('./', defaultRelease.headersUrl)
libUrl32 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x86', versionSemver.major)
libUrl64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x64', versionSemver.major)
libUrlArm64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'arm64', versionSemver.major)
@@ -96,28 +93,28 @@ function processRelease (argv, gyp, defaultVersion, defaultRelease) {
// have a *-headers.tar.gz file in its dist location, even some frankenstein
// custom version
canGetHeaders = semver.satisfies(versionSemver, headersTarballRange)
tarballUrl = url.resolve(baseUrl, name + '-v' + version + (canGetHeaders ? '-headers' : '') + '.tar.gz')
tarballUrl = new URL(name + '-v' + version + (canGetHeaders ? '-headers' : '') + '.tar.gz', baseUrl).href
}
return {
version,
semver: versionSemver,
name,
baseUrl,
baseUrl: baseUrl.href,
tarballUrl,
shasumsUrl: url.resolve(baseUrl, 'SHASUMS256.txt'),
shasumsUrl: new URL('SHASUMS256.txt', baseUrl).href,
versionDir: (name !== 'node' ? name + '-' : '') + version,
ia32: {
libUrl: libUrl32,
libPath: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl32).path))
libUrl: libUrl32.href,
libPath: normalizePath(path.relative(baseUrl.pathname, libUrl32.pathname))
},
x64: {
libUrl: libUrl64,
libPath: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl64).path))
libUrl: libUrl64.href,
libPath: normalizePath(path.relative(baseUrl.pathname, libUrl64.pathname))
},
arm64: {
libUrl: libUrlArm64,
libPath: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrlArm64).path))
libUrl: libUrlArm64.href,
libPath: normalizePath(path.relative(baseUrl.pathname, libUrlArm64.pathname))
}
}
}
@@ -127,20 +124,21 @@ function normalizePath (p) {
}
function resolveLibUrl (name, defaultUrl, arch, versionMajor) {
const base = url.resolve(defaultUrl, './')
const hasLibUrl = bitsre.test(defaultUrl) || (versionMajor === 3 && bitsreV3.test(defaultUrl))
if (!defaultUrl.pathname) defaultUrl = new URL(defaultUrl)
const base = new URL('./', defaultUrl)
const hasLibUrl = bitsre.test(defaultUrl.pathname) || (versionMajor === 3 && bitsreV3.test(defaultUrl.pathname))
if (!hasLibUrl) {
// let's assume it's a baseUrl then
if (versionMajor >= 1) {
return url.resolve(base, 'win-' + arch + '/' + name + '.lib')
return new URL('win-' + arch + '/' + name + '.lib', base)
}
// prior to io.js@1.0.0 32-bit node.lib lives in /, 64-bit lives in /x64/
return url.resolve(base, (arch === 'x86' ? '' : arch + '/') + name + '.lib')
return new URL((arch === 'x86' ? '' : arch + '/') + name + '.lib', base)
}
// else we have a proper url to a .lib, just make sure it's the right arch
return defaultUrl.replace(versionMajor === 3 ? bitsreV3 : bitsre, '/win-' + arch + '/')
return new URL(defaultUrl.pathname.replace(versionMajor === 3 ? bitsreV3 : bitsre, '/win-' + arch + '/'), defaultUrl)
}
module.exports = processRelease
-63
View File
@@ -1,63 +0,0 @@
All packages under `src/` are licensed according to the terms in
their respective `LICENSE` or `LICENSE.md` files.
The remainder of this project is licensed under the Blue Oak
Model License, as follows:
-----
# 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.***
-3
View File
@@ -1,3 +0,0 @@
Like `chown -R`.
Takes the same arguments as `fs.chown()`
-3
View File
@@ -1,3 +0,0 @@
export declare const chownr: (p: string, uid: number, gid: number, cb: (er?: unknown) => any) => void;
export declare const chownrSync: (p: string, uid: number, gid: number) => void;
//# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,MAAM,MACd,MAAM,OACJ,MAAM,OACN,MAAM,YACD,OAAO,KAAK,GAAG,SA0B1B,CAAA;AAcD,eAAO,MAAM,UAAU,MAAO,MAAM,OAAO,MAAM,OAAO,MAAM,SAiB7D,CAAA"}
-93
View File
@@ -1,93 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.chownrSync = exports.chownr = void 0;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const lchownSync = (path, uid, gid) => {
try {
return node_fs_1.default.lchownSync(path, uid, gid);
}
catch (er) {
if (er?.code !== 'ENOENT')
throw er;
}
};
const chown = (cpath, uid, gid, cb) => {
node_fs_1.default.lchown(cpath, uid, gid, er => {
// Skip ENOENT error
cb(er && er?.code !== 'ENOENT' ? er : null);
});
};
const chownrKid = (p, child, uid, gid, cb) => {
if (child.isDirectory()) {
(0, exports.chownr)(node_path_1.default.resolve(p, child.name), uid, gid, (er) => {
if (er)
return cb(er);
const cpath = node_path_1.default.resolve(p, child.name);
chown(cpath, uid, gid, cb);
});
}
else {
const cpath = node_path_1.default.resolve(p, child.name);
chown(cpath, uid, gid, cb);
}
};
const chownr = (p, uid, gid, cb) => {
node_fs_1.default.readdir(p, { withFileTypes: true }, (er, children) => {
// any error other than ENOTDIR or ENOTSUP means it's not readable,
// or doesn't exist. give up.
if (er) {
if (er.code === 'ENOENT')
return cb();
else if (er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP')
return cb(er);
}
if (er || !children.length)
return chown(p, uid, gid, cb);
let len = children.length;
let errState = null;
const then = (er) => {
/* c8 ignore start */
if (errState)
return;
/* c8 ignore stop */
if (er)
return cb((errState = er));
if (--len === 0)
return chown(p, uid, gid, cb);
};
for (const child of children) {
chownrKid(p, child, uid, gid, then);
}
});
};
exports.chownr = chownr;
const chownrKidSync = (p, child, uid, gid) => {
if (child.isDirectory())
(0, exports.chownrSync)(node_path_1.default.resolve(p, child.name), uid, gid);
lchownSync(node_path_1.default.resolve(p, child.name), uid, gid);
};
const chownrSync = (p, uid, gid) => {
let children;
try {
children = node_fs_1.default.readdirSync(p, { withFileTypes: true });
}
catch (er) {
const e = er;
if (e?.code === 'ENOENT')
return;
else if (e?.code === 'ENOTDIR' || e?.code === 'ENOTSUP')
return lchownSync(p, uid, gid);
else
throw e;
}
for (const child of children) {
chownrKidSync(p, child, uid, gid);
}
return lchownSync(p, uid, gid);
};
exports.chownrSync = chownrSync;
//# sourceMappingURL=index.js.map
File diff suppressed because one or more lines are too long
-3
View File
@@ -1,3 +0,0 @@
{
"type": "commonjs"
}
-3
View File
@@ -1,3 +0,0 @@
export declare const chownr: (p: string, uid: number, gid: number, cb: (er?: unknown) => any) => void;
export declare const chownrSync: (p: string, uid: number, gid: number) => void;
//# sourceMappingURL=index.d.ts.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,MAAM,MACd,MAAM,OACJ,MAAM,OACN,MAAM,YACD,OAAO,KAAK,GAAG,SA0B1B,CAAA;AAcD,eAAO,MAAM,UAAU,MAAO,MAAM,OAAO,MAAM,OAAO,MAAM,SAiB7D,CAAA"}
-85
View File
@@ -1,85 +0,0 @@
import fs from 'node:fs';
import path from 'node:path';
const lchownSync = (path, uid, gid) => {
try {
return fs.lchownSync(path, uid, gid);
}
catch (er) {
if (er?.code !== 'ENOENT')
throw er;
}
};
const chown = (cpath, uid, gid, cb) => {
fs.lchown(cpath, uid, gid, er => {
// Skip ENOENT error
cb(er && er?.code !== 'ENOENT' ? er : null);
});
};
const chownrKid = (p, child, uid, gid, cb) => {
if (child.isDirectory()) {
chownr(path.resolve(p, child.name), uid, gid, (er) => {
if (er)
return cb(er);
const cpath = path.resolve(p, child.name);
chown(cpath, uid, gid, cb);
});
}
else {
const cpath = path.resolve(p, child.name);
chown(cpath, uid, gid, cb);
}
};
export const chownr = (p, uid, gid, cb) => {
fs.readdir(p, { withFileTypes: true }, (er, children) => {
// any error other than ENOTDIR or ENOTSUP means it's not readable,
// or doesn't exist. give up.
if (er) {
if (er.code === 'ENOENT')
return cb();
else if (er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP')
return cb(er);
}
if (er || !children.length)
return chown(p, uid, gid, cb);
let len = children.length;
let errState = null;
const then = (er) => {
/* c8 ignore start */
if (errState)
return;
/* c8 ignore stop */
if (er)
return cb((errState = er));
if (--len === 0)
return chown(p, uid, gid, cb);
};
for (const child of children) {
chownrKid(p, child, uid, gid, then);
}
});
};
const chownrKidSync = (p, child, uid, gid) => {
if (child.isDirectory())
chownrSync(path.resolve(p, child.name), uid, gid);
lchownSync(path.resolve(p, child.name), uid, gid);
};
export const chownrSync = (p, uid, gid) => {
let children;
try {
children = fs.readdirSync(p, { withFileTypes: true });
}
catch (er) {
const e = er;
if (e?.code === 'ENOENT')
return;
else if (e?.code === 'ENOTDIR' || e?.code === 'ENOTSUP')
return lchownSync(p, uid, gid);
else
throw e;
}
for (const child of children) {
chownrKidSync(p, child, uid, gid);
}
return lchownSync(p, uid, gid);
};
//# sourceMappingURL=index.js.map
File diff suppressed because one or more lines are too long
-3
View File
@@ -1,3 +0,0 @@
{
"type": "module"
}
-69
View File
@@ -1,69 +0,0 @@
{
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"name": "chownr",
"description": "like `chown -R`",
"version": "3.0.0",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/chownr.git"
},
"files": [
"dist"
],
"devDependencies": {
"@types/node": "^20.12.5",
"mkdirp": "^3.0.1",
"prettier": "^3.2.5",
"rimraf": "^5.0.5",
"tap": "^18.7.2",
"tshy": "^1.13.1",
"typedoc": "^0.25.12"
},
"scripts": {
"prepare": "tshy",
"pretest": "npm run prepare",
"test": "tap",
"preversion": "npm test",
"postversion": "npm publish",
"prepublishOnly": "git push origin --follow-tags",
"format": "prettier --write . --loglevel warn",
"typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts"
},
"license": "BlueOak-1.0.0",
"engines": {
"node": ">=18"
},
"tshy": {
"exports": {
"./package.json": "./package.json",
".": "./src/index.ts"
}
},
"exports": {
"./package.json": "./package.json",
".": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
"types": "./dist/commonjs/index.d.ts",
"default": "./dist/commonjs/index.js"
}
}
},
"main": "./dist/commonjs/index.js",
"types": "./dist/commonjs/index.d.ts",
"type": "module",
"prettier": {
"semi": false,
"printWidth": 75,
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"jsxSingleQuote": false,
"bracketSameLine": true,
"arrowParens": "avoid",
"endOfLine": "lf"
}
}
-15
View File
@@ -1,15 +0,0 @@
The ISC License
Copyright (c) 2016-2022 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.
+19 -13
View File
@@ -8,18 +8,24 @@ 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')
})
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')
@@ -66,9 +72,9 @@ The default exported implementation will be chosen based on
import type IsexeOptions from 'isexe'
```
* `ignoreErrors` Treat all errors as "no, this is not
- `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`
- `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.
-14
View File
@@ -1,14 +0,0 @@
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
-1
View File
@@ -1 +0,0 @@
{"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"}
-46
View File
@@ -1,46 +0,0 @@
"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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__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
-1
View File
@@ -1 +0,0 @@
{"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"]}
-32
View File
@@ -1,32 +0,0 @@
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
-1
View File
@@ -1 +0,0 @@
{"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"}
-3
View File
@@ -1,3 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=options.js.map
-1
View File
@@ -1 +0,0 @@
{"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"]}
-3
View File
@@ -1,3 +0,0 @@
{
"type": "commonjs"
}
-18
View File
@@ -1,18 +0,0 @@
/**
* This is the Posix implementation of isexe, which uses the file
* mode and uid/gid values.
*
* @module
*/
import { IsexeOptions } from './options';
/**
* 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
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"posix.d.ts","sourceRoot":"","sources":["../../src/posix.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC;;;GAGG;AACH,eAAO,MAAM,KAAK,SACV,MAAM,YACH,YAAY,KACpB,QAAQ,OAAO,CASjB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,SACT,MAAM,YACH,YAAY,KACpB,OASF,CAAA"}
-67
View File
@@ -1,67 +0,0 @@
"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 fs_1 = require("fs");
const promises_1 = require("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, 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
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"posix.js","sourceRoot":"","sources":["../../src/posix.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,2BAAoC;AACpC,0CAAkC;AAGlC;;;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;QACF,OAAO,SAAS,CAAC,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;KAC5C;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;KACT;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;QACF,OAAO,SAAS,CAAC,IAAA,aAAQ,EAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;KAC1C;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;KACT;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;QAC9C,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;KACzC;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 'fs'\nimport { stat } from 'fs/promises'\nimport { IsexeOptions } from './options'\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"]}
-18
View File
@@ -1,18 +0,0 @@
/**
* This is the Windows implementation of isexe, which uses the file
* extension and PATHEXT setting.
*
* @module
*/
import { IsexeOptions } from './options';
/**
* 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
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"win32.d.ts","sourceRoot":"","sources":["../../src/win32.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC;;;GAGG;AACH,eAAO,MAAM,KAAK,SACV,MAAM,YACH,YAAY,KACpB,QAAQ,OAAO,CASjB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,SACT,MAAM,YACH,YAAY,KACpB,OASF,CAAA"}
-62
View File
@@ -1,62 +0,0 @@
"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 fs_1 = require("fs");
const promises_1 = require("fs/promises");
/**
* 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, 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(';');
if (peSplit.indexOf('') !== -1) {
return true;
}
for (let i = 0; i < peSplit.length; i++) {
const p = peSplit[i].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
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"win32.js","sourceRoot":"","sources":["../../src/win32.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,2BAAoC;AACpC,0CAAkC;AAGlC;;;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;QACF,OAAO,SAAS,CAAC,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;KAClD;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;KACT;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;QACF,OAAO,SAAS,CAAC,IAAA,aAAQ,EAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;KAChD;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;KACT;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,GAAG,CAAC,CAAA;IAClC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE;QAC9B,OAAO,IAAI,CAAA;KACZ;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QAClC,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;YAClB,OAAO,IAAI,CAAA;SACZ;KACF;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 'fs'\nimport { stat } from 'fs/promises'\nimport { IsexeOptions } from './options'\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(';')\n if (peSplit.indexOf('') !== -1) {\n return true\n }\n\n for (let i = 0; i < peSplit.length; i++) {\n const p = peSplit[i].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"]}
-14
View File
@@ -1,14 +0,0 @@
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
-1
View File
@@ -1 +0,0 @@
{"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"}
-16
View File
@@ -1,16 +0,0 @@
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
-1
View File
@@ -1 +0,0 @@
{"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"]}
-32
View File
@@ -1,32 +0,0 @@
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
-1
View File
@@ -1 +0,0 @@
{"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"}
-2
View File
@@ -1,2 +0,0 @@
export {};
//# sourceMappingURL=options.js.map
-1
View File
@@ -1 +0,0 @@
{"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"]}
-3
View File
@@ -1,3 +0,0 @@
{
"type": "module"
}
-18
View File
@@ -1,18 +0,0 @@
/**
* This is the Posix implementation of isexe, which uses the file
* mode and uid/gid values.
*
* @module
*/
import { IsexeOptions } from './options';
/**
* 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
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"posix.d.ts","sourceRoot":"","sources":["../../src/posix.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC;;;GAGG;AACH,eAAO,MAAM,KAAK,SACV,MAAM,YACH,YAAY,KACpB,QAAQ,OAAO,CASjB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,SACT,MAAM,YACH,YAAY,KACpB,OASF,CAAA"}
-62
View File
@@ -1,62 +0,0 @@
/**
* This is the Posix implementation of isexe, which uses the file
* mode and uid/gid values.
*
* @module
*/
import { statSync } from 'fs';
import { stat } from '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
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"posix.js","sourceRoot":"","sources":["../../src/posix.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAS,QAAQ,EAAE,MAAM,IAAI,CAAA;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAGlC;;;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;QACF,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;KAC5C;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;KACT;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;QACF,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;KAC1C;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;KACT;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;QAC9C,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;KACzC;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 'fs'\nimport { stat } from 'fs/promises'\nimport { IsexeOptions } from './options'\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"]}
-18
View File
@@ -1,18 +0,0 @@
/**
* This is the Windows implementation of isexe, which uses the file
* extension and PATHEXT setting.
*
* @module
*/
import { IsexeOptions } from './options';
/**
* 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
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"win32.d.ts","sourceRoot":"","sources":["../../src/win32.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC;;;GAGG;AACH,eAAO,MAAM,KAAK,SACV,MAAM,YACH,YAAY,KACpB,QAAQ,OAAO,CASjB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,SACT,MAAM,YACH,YAAY,KACpB,OASF,CAAA"}
-57
View File
@@ -1,57 +0,0 @@
/**
* This is the Windows implementation of isexe, which uses the file
* extension and PATHEXT setting.
*
* @module
*/
import { statSync } from 'fs';
import { stat } from 'fs/promises';
/**
* 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(';');
if (peSplit.indexOf('') !== -1) {
return true;
}
for (let i = 0; i < peSplit.length; i++) {
const p = peSplit[i].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
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"win32.js","sourceRoot":"","sources":["../../src/win32.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAS,QAAQ,EAAE,MAAM,IAAI,CAAA;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAGlC;;;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;QACF,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;KAClD;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;KACT;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;QACF,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;KAChD;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,EAAE,GAAG,CAA0B,CAAA;QACrC,IAAI,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QACtD,MAAM,EAAE,CAAA;KACT;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,GAAG,CAAC,CAAA;IAClC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE;QAC9B,OAAO,IAAI,CAAA;KACZ;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QAClC,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;YAClB,OAAO,IAAI,CAAA;SACZ;KACF;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 'fs'\nimport { stat } from 'fs/promises'\nimport { IsexeOptions } from './options'\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(';')\n if (peSplit.indexOf('') !== -1) {\n return true\n }\n\n for (let i = 0; i < peSplit.length; i++) {\n const p = peSplit[i].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"]}
+52 -70
View File
@@ -1,96 +1,78 @@
{
"name": "isexe",
"version": "3.1.1",
"version": "4.0.0",
"description": "Minimal module to check if a file is executable.",
"main": "./dist/cjs/index.js",
"module": "./dist/mjs/index.js",
"types": "./dist/cjs/index.js",
"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/mjs/index.d.ts",
"default": "./dist/mjs/index.js"
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.min.js"
},
"require": {
"types": "./dist/cjs/index.d.ts",
"default": "./dist/cjs/index.js"
"types": "./dist/commonjs/index.d.ts",
"default": "./dist/commonjs/index.min.js"
}
},
"./posix": {
"import": {
"types": "./dist/mjs/posix.d.ts",
"default": "./dist/mjs/posix.js"
},
"require": {
"types": "./dist/cjs/posix.d.ts",
"default": "./dist/cjs/posix.js"
}
},
"./win32": {
"import": {
"types": "./dist/mjs/win32.d.ts",
"default": "./dist/mjs/win32.js"
},
"require": {
"types": "./dist/cjs/win32.d.ts",
"default": "./dist/cjs/win32.js"
}
},
"./package.json": "./package.json"
}
},
"devDependencies": {
"@types/node": "^20.4.5",
"@types/tap": "^15.0.8",
"c8": "^8.0.1",
"mkdirp": "^0.5.1",
"prettier": "^2.8.8",
"rimraf": "^2.5.0",
"sync-content": "^1.0.2",
"tap": "^16.3.8",
"ts-node": "^10.9.1",
"typedoc": "^0.24.8",
"typescript": "^5.1.6"
"@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": "tsc -p tsconfig/cjs.json && tsc -p tsconfig/esm.json && bash ./scripts/fixup.sh",
"prepare": "tshy && bash build.sh",
"pretest": "npm run prepare",
"presnap": "npm run prepare",
"test": "c8 tap",
"snap": "c8 tap",
"format": "prettier --write . --loglevel warn --ignore-path ../../.prettierignore --cache",
"typedoc": "typedoc --tsconfig tsconfig/esm.json ./src/*.ts"
"test": "tap",
"snap": "tap",
"format": "prettier --write .",
"typedoc": "typedoc"
},
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"license": "ISC",
"tap": {
"coverage": false,
"node-arg": [
"--enable-source-maps",
"--no-warnings",
"--loader",
"ts-node/esm"
],
"ts": false
},
"prettier": {
"semi": false,
"printWidth": 75,
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"jsxSingleQuote": false,
"bracketSameLine": true,
"arrowParens": "avoid",
"endOfLine": "lf"
},
"license": "BlueOak-1.0.0",
"repository": "https://github.com/isaacs/isexe",
"engines": {
"node": ">=16"
}
"node": ">=20"
},
"type": "module"
}
-55
View File
@@ -1,55 +0,0 @@
# 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.***
-1145
View File
File diff suppressed because it is too large Load Diff
-3
View File
@@ -1,3 +0,0 @@
import { Pack, PackSync } from './pack.js';
export declare const create: import("./make-command.js").TarCommand<Pack, PackSync>;
//# sourceMappingURL=create.d.ts.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/create.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AA8E1C,eAAO,MAAM,MAAM,wDAUlB,CAAA"}
-83
View File
@@ -1,83 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.create = void 0;
const fs_minipass_1 = require("@isaacs/fs-minipass");
const node_path_1 = __importDefault(require("node:path"));
const list_js_1 = require("./list.js");
const make_command_js_1 = require("./make-command.js");
const pack_js_1 = require("./pack.js");
const createFileSync = (opt, files) => {
const p = new pack_js_1.PackSync(opt);
const stream = new fs_minipass_1.WriteStreamSync(opt.file, {
mode: opt.mode || 0o666,
});
p.pipe(stream);
addFilesSync(p, files);
};
const createFile = (opt, files) => {
const p = new pack_js_1.Pack(opt);
const stream = new fs_minipass_1.WriteStream(opt.file, {
mode: opt.mode || 0o666,
});
p.pipe(stream);
const promise = new Promise((res, rej) => {
stream.on('error', rej);
stream.on('close', res);
p.on('error', rej);
});
addFilesAsync(p, files);
return promise;
};
const addFilesSync = (p, files) => {
files.forEach(file => {
if (file.charAt(0) === '@') {
(0, list_js_1.list)({
file: node_path_1.default.resolve(p.cwd, file.slice(1)),
sync: true,
noResume: true,
onReadEntry: entry => p.add(entry),
});
}
else {
p.add(file);
}
});
p.end();
};
const addFilesAsync = async (p, files) => {
for (let i = 0; i < files.length; i++) {
const file = String(files[i]);
if (file.charAt(0) === '@') {
await (0, list_js_1.list)({
file: node_path_1.default.resolve(String(p.cwd), file.slice(1)),
noResume: true,
onReadEntry: entry => {
p.add(entry);
},
});
}
else {
p.add(file);
}
}
p.end();
};
const createSync = (opt, files) => {
const p = new pack_js_1.PackSync(opt);
addFilesSync(p, files);
return p;
};
const createAsync = (opt, files) => {
const p = new pack_js_1.Pack(opt);
addFilesAsync(p, files);
return p;
};
exports.create = (0, make_command_js_1.makeCommand)(createFileSync, createFile, createSync, createAsync, (_opt, files) => {
if (!files?.length) {
throw new TypeError('no paths specified to add to archive');
}
});
//# sourceMappingURL=create.js.map
File diff suppressed because one or more lines are too long
-8
View File
@@ -1,8 +0,0 @@
export declare class CwdError extends Error {
path: string;
code: string;
syscall: 'chdir';
constructor(path: string, code: string);
get name(): string;
}
//# sourceMappingURL=cwd-error.d.ts.map
@@ -1 +0,0 @@
{"version":3,"file":"cwd-error.d.ts","sourceRoot":"","sources":["../../src/cwd-error.ts"],"names":[],"mappings":"AAAA,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAU;gBAEd,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAMtC,IAAI,IAAI,WAEP;CACF"}
-18
View File
@@ -1,18 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CwdError = void 0;
class CwdError extends Error {
path;
code;
syscall = 'chdir';
constructor(path, code) {
super(`${code}: Cannot cd into '${path}'`);
this.path = path;
this.code = code;
}
get name() {
return 'CwdError';
}
}
exports.CwdError = CwdError;
//# sourceMappingURL=cwd-error.js.map
@@ -1 +0,0 @@
{"version":3,"file":"cwd-error.js","sourceRoot":"","sources":["../../src/cwd-error.ts"],"names":[],"mappings":";;;AAAA,MAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,CAAQ;IACZ,IAAI,CAAQ;IACZ,OAAO,GAAY,OAAO,CAAA;IAE1B,YAAY,IAAY,EAAE,IAAY;QACpC,KAAK,CAAC,GAAG,IAAI,qBAAqB,IAAI,GAAG,CAAC,CAAA;QAC1C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,UAAU,CAAA;IACnB,CAAC;CACF;AAdD,4BAcC","sourcesContent":["export class CwdError extends Error {\n path: string\n code: string\n syscall: 'chdir' = 'chdir'\n\n constructor(path: string, code: string) {\n super(`${code}: Cannot cd into '${path}'`)\n this.path = path\n this.code = code\n }\n\n get name() {\n return 'CwdError'\n }\n}\n"]}
-3
View File
@@ -1,3 +0,0 @@
import { Unpack, UnpackSync } from './unpack.js';
export declare const extract: import("./make-command.js").TarCommand<Unpack, UnpackSync>;
//# sourceMappingURL=extract.d.ts.map
@@ -1 +0,0 @@
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/extract.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AA2ChD,eAAO,MAAM,OAAO,4DAQnB,CAAA"}
-78
View File
@@ -1,78 +0,0 @@
"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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.extract = void 0;
// tar -x
const fsm = __importStar(require("@isaacs/fs-minipass"));
const node_fs_1 = __importDefault(require("node:fs"));
const list_js_1 = require("./list.js");
const make_command_js_1 = require("./make-command.js");
const unpack_js_1 = require("./unpack.js");
const extractFileSync = (opt) => {
const u = new unpack_js_1.UnpackSync(opt);
const file = opt.file;
const stat = node_fs_1.default.statSync(file);
// This trades a zero-byte read() syscall for a stat
// However, it will usually result in less memory allocation
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
const stream = new fsm.ReadStreamSync(file, {
readSize: readSize,
size: stat.size,
});
stream.pipe(u);
};
const extractFile = (opt, _) => {
const u = new unpack_js_1.Unpack(opt);
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
const file = opt.file;
const p = new Promise((resolve, reject) => {
u.on('error', reject);
u.on('close', resolve);
// This trades a zero-byte read() syscall for a stat
// However, it will usually result in less memory allocation
node_fs_1.default.stat(file, (er, stat) => {
if (er) {
reject(er);
}
else {
const stream = new fsm.ReadStream(file, {
readSize: readSize,
size: stat.size,
});
stream.on('error', reject);
stream.pipe(u);
}
});
});
return p;
};
exports.extract = (0, make_command_js_1.makeCommand)(extractFileSync, extractFile, opt => new unpack_js_1.UnpackSync(opt), opt => new unpack_js_1.Unpack(opt), (opt, files) => {
if (files?.length)
(0, list_js_1.filesFilter)(opt, files);
});
//# sourceMappingURL=extract.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/extract.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS;AACT,yDAA0C;AAC1C,sDAAwB;AACxB,uCAAuC;AACvC,uDAA+C;AAE/C,2CAAgD;AAEhD,MAAM,eAAe,GAAG,CAAC,GAAuB,EAAE,EAAE;IAClD,MAAM,CAAC,GAAG,IAAI,sBAAU,CAAC,GAAG,CAAC,CAAA;IAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAA;IACrB,MAAM,IAAI,GAAG,iBAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC9B,oDAAoD;IACpD,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;IACpD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE;QAC1C,QAAQ,EAAE,QAAQ;QAClB,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC,CAAA;IACF,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAC,GAAmB,EAAE,CAAY,EAAE,EAAE;IACxD,MAAM,CAAC,GAAG,IAAI,kBAAM,CAAC,GAAG,CAAC,CAAA;IACzB,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;IAEpD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAA;IACrB,MAAM,CAAC,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC9C,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QACrB,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAEtB,oDAAoD;QACpD,4DAA4D;QAC5D,iBAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE;YACzB,IAAI,EAAE,EAAE,CAAC;gBACP,MAAM,CAAC,EAAE,CAAC,CAAA;YACZ,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE;oBACtC,QAAQ,EAAE,QAAQ;oBAClB,IAAI,EAAE,IAAI,CAAC,IAAI;iBAChB,CAAC,CAAA;gBACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;gBAC1B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAChB,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,OAAO,CAAC,CAAA;AACV,CAAC,CAAA;AAEY,QAAA,OAAO,GAAG,IAAA,6BAAW,EAChC,eAAe,EACf,WAAW,EACX,GAAG,CAAC,EAAE,CAAC,IAAI,sBAAU,CAAC,GAAG,CAAC,EAC1B,GAAG,CAAC,EAAE,CAAC,IAAI,kBAAM,CAAC,GAAG,CAAC,EACtB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IACb,IAAI,KAAK,EAAE,MAAM;QAAE,IAAA,qBAAW,EAAC,GAAG,EAAE,KAAK,CAAC,CAAA;AAC5C,CAAC,CACF,CAAA","sourcesContent":["// tar -x\nimport * as fsm from '@isaacs/fs-minipass'\nimport fs from 'node:fs'\nimport { filesFilter } from './list.js'\nimport { makeCommand } from './make-command.js'\nimport { TarOptionsFile, TarOptionsSyncFile } from './options.js'\nimport { Unpack, UnpackSync } from './unpack.js'\n\nconst extractFileSync = (opt: TarOptionsSyncFile) => {\n const u = new UnpackSync(opt)\n const file = opt.file\n const stat = fs.statSync(file)\n // This trades a zero-byte read() syscall for a stat\n // However, it will usually result in less memory allocation\n const readSize = opt.maxReadSize || 16 * 1024 * 1024\n const stream = new fsm.ReadStreamSync(file, {\n readSize: readSize,\n size: stat.size,\n })\n stream.pipe(u)\n}\n\nconst extractFile = (opt: TarOptionsFile, _?: string[]) => {\n const u = new Unpack(opt)\n const readSize = opt.maxReadSize || 16 * 1024 * 1024\n\n const file = opt.file\n const p = new Promise<void>((resolve, reject) => {\n u.on('error', reject)\n u.on('close', resolve)\n\n // This trades a zero-byte read() syscall for a stat\n // However, it will usually result in less memory allocation\n fs.stat(file, (er, stat) => {\n if (er) {\n reject(er)\n } else {\n const stream = new fsm.ReadStream(file, {\n readSize: readSize,\n size: stat.size,\n })\n stream.on('error', reject)\n stream.pipe(u)\n }\n })\n })\n return p\n}\n\nexport const extract = makeCommand<Unpack, UnpackSync>(\n extractFileSync,\n extractFile,\n opt => new UnpackSync(opt),\n opt => new Unpack(opt),\n (opt, files) => {\n if (files?.length) filesFilter(opt, files)\n },\n)\n"]}
@@ -1,2 +0,0 @@
export declare const getWriteFlag: (() => string) | ((size: number) => number | "w");
//# sourceMappingURL=get-write-flag.d.ts.map
@@ -1 +0,0 @@
{"version":3,"file":"get-write-flag.d.ts","sourceRoot":"","sources":["../../src/get-write-flag.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,YAAY,2BAGd,MAAM,kBAAwC,CAAA"}
-29
View File
@@ -1,29 +0,0 @@
"use strict";
// Get the appropriate flag to use for creating files
// We use fmap on Windows platforms for files less than
// 512kb. This is a fairly low limit, but avoids making
// things slower in some cases. Since most of what this
// library is used for is extracting tarballs of many
// relatively small files in npm packages and the like,
// it can be a big boost on Windows platforms.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getWriteFlag = void 0;
const fs_1 = __importDefault(require("fs"));
const platform = process.env.__FAKE_PLATFORM__ || process.platform;
const isWindows = platform === 'win32';
/* c8 ignore start */
const { O_CREAT, O_TRUNC, O_WRONLY } = fs_1.default.constants;
const UV_FS_O_FILEMAP = Number(process.env.__FAKE_FS_O_FILENAME__) ||
fs_1.default.constants.UV_FS_O_FILEMAP ||
0;
/* c8 ignore stop */
const fMapEnabled = isWindows && !!UV_FS_O_FILEMAP;
const fMapLimit = 512 * 1024;
const fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY;
exports.getWriteFlag = !fMapEnabled ?
() => 'w'
: (size) => (size < fMapLimit ? fMapFlag : 'w');
//# sourceMappingURL=get-write-flag.js.map
@@ -1 +0,0 @@
{"version":3,"file":"get-write-flag.js","sourceRoot":"","sources":["../../src/get-write-flag.ts"],"names":[],"mappings":";AAAA,qDAAqD;AACrD,uDAAuD;AACvD,wDAAwD;AACxD,wDAAwD;AACxD,qDAAqD;AACrD,uDAAuD;AACvD,8CAA8C;;;;;;AAE9C,4CAAmB;AAEnB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,QAAQ,CAAA;AAClE,MAAM,SAAS,GAAG,QAAQ,KAAK,OAAO,CAAA;AAEtC,qBAAqB;AACrB,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,YAAE,CAAC,SAAS,CAAA;AACnD,MAAM,eAAe,GACnB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IAC1C,YAAE,CAAC,SAAS,CAAC,eAAe;IAC5B,CAAC,CAAA;AACH,oBAAoB;AAEpB,MAAM,WAAW,GAAG,SAAS,IAAI,CAAC,CAAC,eAAe,CAAA;AAClD,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,CAAA;AAC5B,MAAM,QAAQ,GAAG,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAA;AAClD,QAAA,YAAY,GACvB,CAAC,WAAW,CAAC,CAAC;IACZ,GAAG,EAAE,CAAC,GAAG;IACX,CAAC,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA","sourcesContent":["// Get the appropriate flag to use for creating files\n// We use fmap on Windows platforms for files less than\n// 512kb. This is a fairly low limit, but avoids making\n// things slower in some cases. Since most of what this\n// library is used for is extracting tarballs of many\n// relatively small files in npm packages and the like,\n// it can be a big boost on Windows platforms.\n\nimport fs from 'fs'\n\nconst platform = process.env.__FAKE_PLATFORM__ || process.platform\nconst isWindows = platform === 'win32'\n\n/* c8 ignore start */\nconst { O_CREAT, O_TRUNC, O_WRONLY } = fs.constants\nconst UV_FS_O_FILEMAP =\n Number(process.env.__FAKE_FS_O_FILENAME__) ||\n fs.constants.UV_FS_O_FILEMAP ||\n 0\n/* c8 ignore stop */\n\nconst fMapEnabled = isWindows && !!UV_FS_O_FILEMAP\nconst fMapLimit = 512 * 1024\nconst fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY\nexport const getWriteFlag =\n !fMapEnabled ?\n () => 'w'\n : (size: number) => (size < fMapLimit ? fMapFlag : 'w')\n"]}
-55
View File
@@ -1,55 +0,0 @@
/// <reference types="node" />
/// <reference types="node" />
import type { EntryTypeCode, EntryTypeName } from './types.js';
export type HeaderData = {
path?: string;
mode?: number;
uid?: number;
gid?: number;
size?: number;
cksum?: number;
type?: EntryTypeName | 'Unsupported';
linkpath?: string;
uname?: string;
gname?: string;
devmaj?: number;
devmin?: number;
atime?: Date;
ctime?: Date;
mtime?: Date;
charset?: string;
comment?: string;
dev?: number;
ino?: number;
nlink?: number;
};
export declare class Header implements HeaderData {
#private;
cksumValid: boolean;
needPax: boolean;
nullBlock: boolean;
block?: Buffer;
path?: string;
mode?: number;
uid?: number;
gid?: number;
size?: number;
cksum?: number;
linkpath?: string;
uname?: string;
gname?: string;
devmaj: number;
devmin: number;
atime?: Date;
ctime?: Date;
mtime?: Date;
charset?: string;
comment?: string;
constructor(data?: Buffer | HeaderData, off?: number, ex?: HeaderData, gex?: HeaderData);
decode(buf: Buffer, off: number, ex?: HeaderData, gex?: HeaderData): void;
encode(buf?: Buffer, off?: number): boolean;
get type(): EntryTypeName;
get typeKey(): EntryTypeCode | 'Unsupported';
set type(type: EntryTypeCode | EntryTypeName | 'Unsupported');
}
//# sourceMappingURL=header.d.ts.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../src/header.ts"],"names":[],"mappings":";;AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG9D,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,aAAa,GAAG,aAAa,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IAIZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,qBAAa,MAAO,YAAW,UAAU;;IACvC,UAAU,EAAE,OAAO,CAAQ;IAC3B,OAAO,EAAE,OAAO,CAAQ;IACxB,SAAS,EAAE,OAAO,CAAQ;IAE1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAI;IAClB,MAAM,EAAE,MAAM,CAAI;IAClB,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IAEZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;gBAGd,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,EAC1B,GAAG,GAAE,MAAU,EACf,EAAE,CAAC,EAAE,UAAU,EACf,GAAG,CAAC,EAAE,UAAU;IASlB,MAAM,CACJ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,EAAE,CAAC,EAAE,UAAU,EACf,GAAG,CAAC,EAAE,UAAU;IA+GlB,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAU;IAwEpC,IAAI,IAAI,IAAI,aAAa,CAKxB;IAED,IAAI,OAAO,IAAI,aAAa,GAAG,aAAa,CAE3C;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,GAAG,aAAa,EAS3D;CACF"}
-315
View File
@@ -1,315 +0,0 @@
"use strict";
// parse a 512-byte header block to a data object, or vice-versa
// encode returns `true` if a pax extended header is needed, because
// the data could not be faithfully encoded in a simple header.
// (Also, check header.needPax to see if it needs a pax header.)
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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Header = void 0;
const node_path_1 = require("node:path");
const large = __importStar(require("./large-numbers.js"));
const types = __importStar(require("./types.js"));
class Header {
cksumValid = false;
needPax = false;
nullBlock = false;
block;
path;
mode;
uid;
gid;
size;
cksum;
#type = 'Unsupported';
linkpath;
uname;
gname;
devmaj = 0;
devmin = 0;
atime;
ctime;
mtime;
charset;
comment;
constructor(data, off = 0, ex, gex) {
if (Buffer.isBuffer(data)) {
this.decode(data, off || 0, ex, gex);
}
else if (data) {
this.#slurp(data);
}
}
decode(buf, off, ex, gex) {
if (!off) {
off = 0;
}
if (!buf || !(buf.length >= off + 512)) {
throw new Error('need 512 bytes for header');
}
this.path = ex?.path ?? decString(buf, off, 100);
this.mode = ex?.mode ?? gex?.mode ?? decNumber(buf, off + 100, 8);
this.uid = ex?.uid ?? gex?.uid ?? decNumber(buf, off + 108, 8);
this.gid = ex?.gid ?? gex?.gid ?? decNumber(buf, off + 116, 8);
this.size = ex?.size ?? gex?.size ?? decNumber(buf, off + 124, 12);
this.mtime =
ex?.mtime ?? gex?.mtime ?? decDate(buf, off + 136, 12);
this.cksum = decNumber(buf, off + 148, 12);
// if we have extended or global extended headers, apply them now
// See https://github.com/npm/node-tar/pull/187
// Apply global before local, so it overrides
if (gex)
this.#slurp(gex, true);
if (ex)
this.#slurp(ex);
// old tar versions marked dirs as a file with a trailing /
const t = decString(buf, off + 156, 1);
if (types.isCode(t)) {
this.#type = t || '0';
}
if (this.#type === '0' && this.path.slice(-1) === '/') {
this.#type = '5';
}
// tar implementations sometimes incorrectly put the stat(dir).size
// as the size in the tarball, even though Directory entries are
// not able to have any body at all. In the very rare chance that
// it actually DOES have a body, we weren't going to do anything with
// it anyway, and it'll just be a warning about an invalid header.
if (this.#type === '5') {
this.size = 0;
}
this.linkpath = decString(buf, off + 157, 100);
if (buf.subarray(off + 257, off + 265).toString() ===
'ustar\u000000') {
/* c8 ignore start */
this.uname =
ex?.uname ?? gex?.uname ?? decString(buf, off + 265, 32);
this.gname =
ex?.gname ?? gex?.gname ?? decString(buf, off + 297, 32);
this.devmaj =
ex?.devmaj ?? gex?.devmaj ?? decNumber(buf, off + 329, 8) ?? 0;
this.devmin =
ex?.devmin ?? gex?.devmin ?? decNumber(buf, off + 337, 8) ?? 0;
/* c8 ignore stop */
if (buf[off + 475] !== 0) {
// definitely a prefix, definitely >130 chars.
const prefix = decString(buf, off + 345, 155);
this.path = prefix + '/' + this.path;
}
else {
const prefix = decString(buf, off + 345, 130);
if (prefix) {
this.path = prefix + '/' + this.path;
}
/* c8 ignore start */
this.atime =
ex?.atime ?? gex?.atime ?? decDate(buf, off + 476, 12);
this.ctime =
ex?.ctime ?? gex?.ctime ?? decDate(buf, off + 488, 12);
/* c8 ignore stop */
}
}
let sum = 8 * 0x20;
for (let i = off; i < off + 148; i++) {
sum += buf[i];
}
for (let i = off + 156; i < off + 512; i++) {
sum += buf[i];
}
this.cksumValid = sum === this.cksum;
if (this.cksum === undefined && sum === 8 * 0x20) {
this.nullBlock = true;
}
}
#slurp(ex, gex = false) {
Object.assign(this, Object.fromEntries(Object.entries(ex).filter(([k, v]) => {
// we slurp in everything except for the path attribute in
// a global extended header, because that's weird. Also, any
// null/undefined values are ignored.
return !(v === null ||
v === undefined ||
(k === 'path' && gex) ||
(k === 'linkpath' && gex) ||
k === 'global');
})));
}
encode(buf, off = 0) {
if (!buf) {
buf = this.block = Buffer.alloc(512);
}
if (this.#type === 'Unsupported') {
this.#type = '0';
}
if (!(buf.length >= off + 512)) {
throw new Error('need 512 bytes for header');
}
const prefixSize = this.ctime || this.atime ? 130 : 155;
const split = splitPrefix(this.path || '', prefixSize);
const path = split[0];
const prefix = split[1];
this.needPax = !!split[2];
this.needPax = encString(buf, off, 100, path) || this.needPax;
this.needPax =
encNumber(buf, off + 100, 8, this.mode) || this.needPax;
this.needPax =
encNumber(buf, off + 108, 8, this.uid) || this.needPax;
this.needPax =
encNumber(buf, off + 116, 8, this.gid) || this.needPax;
this.needPax =
encNumber(buf, off + 124, 12, this.size) || this.needPax;
this.needPax =
encDate(buf, off + 136, 12, this.mtime) || this.needPax;
buf[off + 156] = this.#type.charCodeAt(0);
this.needPax =
encString(buf, off + 157, 100, this.linkpath) || this.needPax;
buf.write('ustar\u000000', off + 257, 8);
this.needPax =
encString(buf, off + 265, 32, this.uname) || this.needPax;
this.needPax =
encString(buf, off + 297, 32, this.gname) || this.needPax;
this.needPax =
encNumber(buf, off + 329, 8, this.devmaj) || this.needPax;
this.needPax =
encNumber(buf, off + 337, 8, this.devmin) || this.needPax;
this.needPax =
encString(buf, off + 345, prefixSize, prefix) || this.needPax;
if (buf[off + 475] !== 0) {
this.needPax =
encString(buf, off + 345, 155, prefix) || this.needPax;
}
else {
this.needPax =
encString(buf, off + 345, 130, prefix) || this.needPax;
this.needPax =
encDate(buf, off + 476, 12, this.atime) || this.needPax;
this.needPax =
encDate(buf, off + 488, 12, this.ctime) || this.needPax;
}
let sum = 8 * 0x20;
for (let i = off; i < off + 148; i++) {
sum += buf[i];
}
for (let i = off + 156; i < off + 512; i++) {
sum += buf[i];
}
this.cksum = sum;
encNumber(buf, off + 148, 8, this.cksum);
this.cksumValid = true;
return this.needPax;
}
get type() {
return (this.#type === 'Unsupported' ?
this.#type
: types.name.get(this.#type));
}
get typeKey() {
return this.#type;
}
set type(type) {
const c = String(types.code.get(type));
if (types.isCode(c) || c === 'Unsupported') {
this.#type = c;
}
else if (types.isCode(type)) {
this.#type = type;
}
else {
throw new TypeError('invalid entry type: ' + type);
}
}
}
exports.Header = Header;
const splitPrefix = (p, prefixSize) => {
const pathSize = 100;
let pp = p;
let prefix = '';
let ret = undefined;
const root = node_path_1.posix.parse(p).root || '.';
if (Buffer.byteLength(pp) < pathSize) {
ret = [pp, prefix, false];
}
else {
// first set prefix to the dir, and path to the base
prefix = node_path_1.posix.dirname(pp);
pp = node_path_1.posix.basename(pp);
do {
if (Buffer.byteLength(pp) <= pathSize &&
Buffer.byteLength(prefix) <= prefixSize) {
// both fit!
ret = [pp, prefix, false];
}
else if (Buffer.byteLength(pp) > pathSize &&
Buffer.byteLength(prefix) <= prefixSize) {
// prefix fits in prefix, but path doesn't fit in path
ret = [pp.slice(0, pathSize - 1), prefix, true];
}
else {
// make path take a bit from prefix
pp = node_path_1.posix.join(node_path_1.posix.basename(prefix), pp);
prefix = node_path_1.posix.dirname(prefix);
}
} while (prefix !== root && ret === undefined);
// at this point, found no resolution, just truncate
if (!ret) {
ret = [p.slice(0, pathSize - 1), '', true];
}
}
return ret;
};
const decString = (buf, off, size) => buf
.subarray(off, off + size)
.toString('utf8')
.replace(/\0.*/, '');
const decDate = (buf, off, size) => numToDate(decNumber(buf, off, size));
const numToDate = (num) => num === undefined ? undefined : new Date(num * 1000);
const decNumber = (buf, off, size) => Number(buf[off]) & 0x80 ?
large.parse(buf.subarray(off, off + size))
: decSmallNumber(buf, off, size);
const nanUndef = (value) => (isNaN(value) ? undefined : value);
const decSmallNumber = (buf, off, size) => nanUndef(parseInt(buf
.subarray(off, off + size)
.toString('utf8')
.replace(/\0.*$/, '')
.trim(), 8));
// the maximum encodable as a null-terminated octal, by field size
const MAXNUM = {
12: 0o77777777777,
8: 0o7777777,
};
const encNumber = (buf, off, size, num) => num === undefined ? false
: num > MAXNUM[size] || num < 0 ?
(large.encode(num, buf.subarray(off, off + size)), true)
: (encSmallNumber(buf, off, size, num), false);
const encSmallNumber = (buf, off, size, num) => buf.write(octalString(num, size), off, size, 'ascii');
const octalString = (num, size) => padOctal(Math.floor(num).toString(8), size);
const padOctal = (str, size) => (str.length === size - 1 ?
str
: new Array(size - str.length - 1).join('0') + str + ' ') + '\0';
const encDate = (buf, off, size, date) => date === undefined ? false : (encNumber(buf, off, size, date.getTime() / 1000));
// enough to fill the longest string we've got
const NULLS = new Array(156).join('\0');
// pad with nulls, return true if it's longer or non-ascii
const encString = (buf, off, size, str) => str === undefined ? false : ((buf.write(str + NULLS, off, size, 'utf8'),
str.length !== Buffer.byteLength(str) || str.length > size));
//# sourceMappingURL=header.js.map
File diff suppressed because one or more lines are too long
-20
View File
@@ -1,20 +0,0 @@
export { type TarOptionsWithAliasesAsync, type TarOptionsWithAliasesAsyncFile, type TarOptionsWithAliasesAsyncNoFile, type TarOptionsWithAliasesSyncNoFile, type TarOptionsWithAliases, type TarOptionsWithAliasesFile, type TarOptionsWithAliasesSync, type TarOptionsWithAliasesSyncFile, } from './options.js';
export * from './create.js';
export { create as c } from './create.js';
export * from './extract.js';
export { extract as x } from './extract.js';
export * from './header.js';
export * from './list.js';
export { list as t } from './list.js';
export * from './pack.js';
export * from './parse.js';
export * from './pax.js';
export * from './read-entry.js';
export * from './replace.js';
export { replace as r } from './replace.js';
export * as types from './types.js';
export * from './unpack.js';
export * from './update.js';
export { update as u } from './update.js';
export * from './write-entry.js';
//# sourceMappingURL=index.d.ts.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,gCAAgC,EACrC,KAAK,+BAA+B,EACpC,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,GACnC,MAAM,cAAc,CAAA;AAErB,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,aAAa,CAAA;AACzC,cAAc,cAAc,CAAA;AAC5B,OAAO,EAAE,OAAO,IAAI,CAAC,EAAE,MAAM,cAAc,CAAA;AAC3C,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,OAAO,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,WAAW,CAAA;AAErC,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA;AAC5B,OAAO,EAAE,OAAO,IAAI,CAAC,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,aAAa,CAAA;AACzC,cAAc,kBAAkB,CAAA"}

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