mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-02-19 02:24:30 +00:00
135 lines
3.9 KiB
Nix
135 lines
3.9 KiB
Nix
![]() |
{ lib
|
||
|
, fetchurl
|
||
|
, stdenv
|
||
|
, callPackages
|
||
|
, runCommand
|
||
|
}:
|
||
|
|
||
|
let
|
||
|
inherit (builtins) match elemAt toJSON removeAttrs;
|
||
|
inherit (lib) importJSON mapAttrs;
|
||
|
|
||
|
matchGitHubReference = match "github(.com)?:.+";
|
||
|
getName = package: package.name or "unknown";
|
||
|
getVersion = package: package.version or "0.0.0";
|
||
|
|
||
|
# Fetch a module from package-lock.json -> packages
|
||
|
fetchModule =
|
||
|
{ module
|
||
|
, npmRoot ? null
|
||
|
}: (
|
||
|
if module ? "resolved" then
|
||
|
(
|
||
|
let
|
||
|
# Parse scheme from URL
|
||
|
mUrl = match "(.+)://(.+)" module.resolved;
|
||
|
scheme = elemAt mUrl 0;
|
||
|
in
|
||
|
(
|
||
|
if mUrl == null then
|
||
|
(
|
||
|
assert npmRoot != null; {
|
||
|
outPath = npmRoot + "/${module.resolved}";
|
||
|
}
|
||
|
)
|
||
|
else if (scheme == "http" || scheme == "https") then
|
||
|
(
|
||
|
fetchurl {
|
||
|
url = module.resolved;
|
||
|
hash = module.integrity;
|
||
|
}
|
||
|
)
|
||
|
else if lib.hasPrefix "git" module.resolved then
|
||
|
(
|
||
|
builtins.fetchGit {
|
||
|
url = module.resolved;
|
||
|
}
|
||
|
)
|
||
|
else throw "Unsupported URL scheme: ${scheme}"
|
||
|
)
|
||
|
)
|
||
|
else null
|
||
|
);
|
||
|
|
||
|
# Manage node_modules outside of the store with hooks
|
||
|
hooks = callPackages ./hooks { };
|
||
|
|
||
|
in
|
||
|
{
|
||
|
importNpmLock =
|
||
|
{ npmRoot ? null
|
||
|
, package ? importJSON (npmRoot + "/package.json")
|
||
|
, packageLock ? importJSON (npmRoot + "/package-lock.json")
|
||
|
, pname ? getName package
|
||
|
, version ? getVersion package
|
||
|
}:
|
||
|
let
|
||
|
mapLockDependencies =
|
||
|
mapAttrs
|
||
|
(name: version: (
|
||
|
# Substitute the constraint with the version of the dependency from the top-level of package-lock.
|
||
|
if (
|
||
|
# if the version is `latest`
|
||
|
version == "latest"
|
||
|
||
|
||
|
# Or if it's a github reference
|
||
|
matchGitHubReference version != null
|
||
|
) then packageLock'.packages.${"node_modules/${name}"}.version
|
||
|
# But not a regular version constraint
|
||
|
else version
|
||
|
));
|
||
|
|
||
|
packageLock' = packageLock // {
|
||
|
packages =
|
||
|
mapAttrs
|
||
|
(_: module:
|
||
|
let
|
||
|
src = fetchModule {
|
||
|
inherit module npmRoot;
|
||
|
};
|
||
|
in
|
||
|
(removeAttrs module [
|
||
|
"link"
|
||
|
"funding"
|
||
|
]) // lib.optionalAttrs (src != null) {
|
||
|
resolved = "file:${src}";
|
||
|
} // lib.optionalAttrs (module ? dependencies) {
|
||
|
dependencies = mapLockDependencies module.dependencies;
|
||
|
} // lib.optionalAttrs (module ? optionalDependencies) {
|
||
|
optionalDependencies = mapLockDependencies module.optionalDependencies;
|
||
|
})
|
||
|
packageLock.packages;
|
||
|
};
|
||
|
|
||
|
mapPackageDependencies = mapAttrs (name: _: packageLock'.packages.${"node_modules/${name}"}.resolved);
|
||
|
|
||
|
# Substitute dependency references in package.json with Nix store paths
|
||
|
packageJSON' = package // lib.optionalAttrs (package ? dependencies) {
|
||
|
dependencies = mapPackageDependencies package.dependencies;
|
||
|
} // lib.optionalAttrs (package ? devDependencies) {
|
||
|
devDependencies = mapPackageDependencies package.devDependencies;
|
||
|
};
|
||
|
|
||
|
pname = package.name or "unknown";
|
||
|
|
||
|
in
|
||
|
runCommand "${pname}-${version}-sources"
|
||
|
{
|
||
|
inherit pname version;
|
||
|
|
||
|
passAsFile = [ "package" "packageLock" ];
|
||
|
|
||
|
package = toJSON packageJSON';
|
||
|
packageLock = toJSON packageLock';
|
||
|
} ''
|
||
|
mkdir $out
|
||
|
cp "$packagePath" $out/package.json
|
||
|
cp "$packageLockPath" $out/package-lock.json
|
||
|
'';
|
||
|
|
||
|
inherit hooks;
|
||
|
inherit (hooks) npmConfigHook;
|
||
|
|
||
|
__functor = self: self.importNpmLock;
|
||
|
}
|