registry-sync 7.1.0 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@ The local copy can then be used as a simple private NPM registry without publish
8
8
 
9
9
  ## Pre-requisites
10
10
 
11
- - Node.js v20.17.0 or newer
11
+ - Node.js v22.18.0 or newer
12
12
 
13
13
  ## Installation
14
14
 
@@ -118,5 +118,5 @@ See [releases](https://github.com/heikkipora/registry-sync/releases).
118
118
 
119
119
  ## Contributing
120
120
 
121
- Pull requests are welcome. Kindly check that your code passes ESLint checks by running `npm run eslint:check` first.
121
+ Pull requests are welcome. Kindly check that your code passes ESLint checks by running `npm run eslint` first.
122
122
  Integration tests can be run with `npm test`. Both are anyway run automatically by GitHub Actions.
package/bin/sync CHANGED
@@ -1,4 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const path = require('path')
4
- require(path.join(__dirname, '..', 'src'))
3
+ await import('../src/index.js')
package/package.json CHANGED
@@ -1,19 +1,18 @@
1
1
  {
2
2
  "name": "registry-sync",
3
- "version": "7.1.0",
3
+ "version": "8.1.0",
4
4
  "description": "synchronize a remote npm registry for private use",
5
5
  "repository": "https://github.com/heikkipora/registry-sync",
6
+ "type": "module",
6
7
  "bin": {
7
8
  "registry-sync": "bin/sync"
8
9
  },
9
10
  "scripts": {
10
11
  "build": "./build-npm",
11
- "prettier": "prettier --write .",
12
- "prettier:check": "prettier --check --loglevel warn .",
13
- "eslint": "eslint --fix --format=codeframe",
14
- "eslint:check": "eslint --max-warnings=0 --format=codeframe",
15
- "lint-staged": "lint-staged --verbose",
16
- "test": "mocha -r ts-node/register --config test/.mocharc.js --timeout 120000 test/*.ts",
12
+ "eslint": "eslint --max-warnings=0 src test release-test/server/src",
13
+ "fix-eslint": "eslint --fix src test release-test/server/src",
14
+ "test": "mocha --timeout 120000 test/*.ts",
15
+ "typecheck": "tsc",
17
16
  "release-test": "cd release-test && ./run-sync-install-cycle.sh"
18
17
  },
19
18
  "author": "Heikki Pora",
@@ -22,37 +21,28 @@
22
21
  "@yarnpkg/lockfile": "1.1.0",
23
22
  "axios": "1.13.2",
24
23
  "commander": "14.0.2",
25
- "lru-cache": "11.2.2",
24
+ "lru-cache": "11.2.4",
26
25
  "semver": "7.7.3",
27
26
  "ssri": "13.0.0",
28
27
  "tar-fs": "3.1.1"
29
28
  },
30
29
  "devDependencies": {
31
- "@arkweid/lefthook": "0.7.7",
32
- "@eslint/eslintrc": "3.3.1",
33
- "@eslint/js": "9.39.1",
34
30
  "@types/chai": "5.2.3",
35
- "@types/lodash": "4.17.20",
31
+ "@types/lodash": "4.17.21",
36
32
  "@types/mocha": "10.0.10",
37
33
  "@types/node": "20.17.32",
38
34
  "@types/semver": "7.7.1",
39
35
  "@types/ssri": "7.1.5",
40
36
  "@types/tar-fs": "2.0.4",
41
37
  "@types/yarnpkg__lockfile": "1.1.9",
42
- "@typescript-eslint/eslint-plugin": "8.46.4",
43
- "@typescript-eslint/parser": "8.46.4",
44
- "chai": "6.2.1",
45
- "eslint": "9.39.1",
46
- "eslint-config-prettier": "10.1.8",
47
- "eslint-formatter-codeframe": "7.32.2",
38
+ "chai": "6.2.2",
39
+ "eslint": "9.39.2",
48
40
  "eslint-plugin-mocha": "11.2.0",
49
- "express": "5.1.0",
50
- "globals": "16.5.0",
51
- "lint-staged": "16.2.6",
41
+ "express": "5.2.1",
42
+ "globals": "17.0.0",
52
43
  "mocha": "11.7.5",
53
- "prettier": "3.6.2",
54
- "ts-node": "10.9.2",
55
- "typescript": "5.9.3"
44
+ "typescript": "5.9.3",
45
+ "typescript-eslint": "8.51.0"
56
46
  },
57
47
  "keywords": [
58
48
  "registry",
@@ -62,6 +52,6 @@
62
52
  "offline"
63
53
  ],
64
54
  "engines": {
65
- "node": ">=20.17.0"
55
+ "node": ">=22.18.0"
66
56
  }
67
57
  }
package/src/client.js CHANGED
@@ -1,24 +1,21 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fetchJsonWithCacheCloned = fetchJsonWithCacheCloned;
4
- exports.fetchBinaryData = fetchBinaryData;
5
- const https = require("https");
6
- const axios_1 = require("axios");
7
- const lru_cache_1 = require("lru-cache");
8
- const metadataCache = new lru_cache_1.LRUCache({ max: 100 });
9
- const client = axios_1.default.create({
1
+ import * as https from 'https';
2
+ import axios from 'axios';
3
+ import { LRUCache } from 'lru-cache';
4
+ const metadataCache = new LRUCache({ max: 100 });
5
+ const client = axios.create({
10
6
  httpsAgent: new https.Agent({ keepAlive: true }),
11
7
  timeout: 30 * 1000
12
8
  });
13
- async function fetchJsonWithCacheCloned(url, token) {
14
- if (metadataCache.has(url)) {
15
- return structuredClone(metadataCache.get(url));
9
+ export async function fetchJsonWithCacheCloned(url, token) {
10
+ const cached = metadataCache.get(url);
11
+ if (cached) {
12
+ return structuredClone(cached);
16
13
  }
17
14
  const value = await fetch(url, 'json', token);
18
15
  metadataCache.set(url, value);
19
16
  return structuredClone(value);
20
17
  }
21
- function fetchBinaryData(url, token) {
18
+ export function fetchBinaryData(url, token) {
22
19
  return fetch(url, 'arraybuffer', token);
23
20
  }
24
21
  async function fetch(url, responseType, token) {
package/src/download.js CHANGED
@@ -1,15 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.downloadAll = downloadAll;
4
- const fs = require("fs");
5
- const path = require("path");
6
- const semver = require("semver");
7
- const url = require("url");
8
- const integrity_1 = require("./integrity");
9
- const pregyp_1 = require("./pregyp");
10
- const client_1 = require("./client");
11
- const metadata_1 = require("./metadata");
12
- async function downloadAll(packages, { localUrl, prebuiltBinaryProperties, registryUrl, registryToken, rootFolder, enforceTarballsOverHttps }) {
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as semver from 'semver';
4
+ import * as url from 'url';
5
+ import assert from 'assert';
6
+ import { downloadPrebuiltBinaries, hasPrebuiltBinaries } from "./pregyp.js";
7
+ import { fetchBinaryData, fetchJsonWithCacheCloned } from "./client.js";
8
+ import { rewriteMetadataInTarball, rewriteVersionMetadata, tarballFilename } from "./metadata.js";
9
+ import { verifyIntegrity } from "./integrity.js";
10
+ export async function downloadAll(packages, { localUrl, prebuiltBinaryProperties, registryUrl, registryToken, rootFolder, enforceTarballsOverHttps }) {
13
11
  const downloadFromRegistry = download.bind(null, registryUrl, registryToken, localUrl, rootFolder, prebuiltBinaryProperties, enforceTarballsOverHttps);
14
12
  for (const pkg of packages) {
15
13
  await downloadFromRegistry(pkg);
@@ -23,19 +21,19 @@ async function download(registryUrl, registryToken, localUrl, rootFolder, prebui
23
21
  }
24
22
  const localFolder = await ensureLocalFolderExists(name, rootFolder);
25
23
  let data = await downloadTarball(versionMetadata, enforceTarballsOverHttps, registryToken);
26
- if ((0, pregyp_1.hasPrebuiltBinaries)(versionMetadata)) {
24
+ if (hasPrebuiltBinaries(versionMetadata)) {
27
25
  const localPregypFolder = await ensureLocalFolderExists(version, localFolder);
28
- await (0, pregyp_1.downloadPrebuiltBinaries)(versionMetadata, localPregypFolder, prebuiltBinaryProperties);
29
- data = await (0, metadata_1.rewriteMetadataInTarball)(data, versionMetadata, localUrl, localFolder);
26
+ await downloadPrebuiltBinaries(versionMetadata, localPregypFolder, prebuiltBinaryProperties);
27
+ data = await rewriteMetadataInTarball(data, versionMetadata, localUrl, localFolder);
30
28
  }
31
29
  await saveTarball(versionMetadata, data, localFolder);
32
- (0, metadata_1.rewriteVersionMetadata)(versionMetadata, data, localUrl);
30
+ rewriteVersionMetadata(versionMetadata, data, localUrl);
33
31
  await updateMetadata(versionMetadata, registryMetadata, registryUrl, localFolder);
34
32
  }
35
33
  async function downloadTarball({ _id: id, dist }, enforceTarballsOverHttps, registryToken) {
36
34
  const tarballUrl = enforceTarballsOverHttps ? dist.tarball.replace('http://', 'https://') : dist.tarball;
37
- const data = await (0, client_1.fetchBinaryData)(tarballUrl, registryToken);
38
- (0, integrity_1.verifyIntegrity)(data, id, dist);
35
+ const data = await fetchBinaryData(tarballUrl, registryToken);
36
+ verifyIntegrity(data, id, dist);
39
37
  return data;
40
38
  }
41
39
  function saveTarball({ name, version }, data, localFolder) {
@@ -50,16 +48,18 @@ async function updateMetadata(versionMetadata, defaultMetadata, registryUrl, loc
50
48
  localMetadata['dist-tags'] = collectDistTags(localMetadata, defaultMetadata);
51
49
  await saveMetadata(localMetadataPath, localMetadata);
52
50
  }
53
- // Collect thise dist-tags entries (name -> version) from registry metadata,
51
+ // Collect dist-tags entries (name -> version) from registry metadata,
54
52
  // which point to versions we have locally available.
55
53
  // Override 'latest' tag to ensure its validity as we might not have the version
56
54
  // that is tagged latest in registry
57
55
  function collectDistTags(localMetadata, defaultMetadata) {
58
56
  const availableVersions = Object.keys(localMetadata.versions);
59
57
  const validDistTags = Object.entries(defaultMetadata['dist-tags']).filter(([, version]) => availableVersions.includes(version));
58
+ const latest = availableVersions.sort(semver.compare).pop();
59
+ assert(latest, 'At least one version should be locally available to determine "latest" dist-tag');
60
60
  return {
61
61
  ...Object.fromEntries(validDistTags),
62
- latest: availableVersions.sort(semver.compare).pop()
62
+ latest
63
63
  };
64
64
  }
65
65
  async function loadMetadata(path, defaultMetadata) {
@@ -76,7 +76,7 @@ function saveMetadata(path, metadata) {
76
76
  return fs.promises.writeFile(path, json, 'utf8');
77
77
  }
78
78
  function tarballPath(name, version, localFolder) {
79
- return path.join(localFolder, (0, metadata_1.tarballFilename)(name, version));
79
+ return path.join(localFolder, tarballFilename(name, version));
80
80
  }
81
81
  async function ensureLocalFolderExists(name, rootFolder) {
82
82
  const localFolder = path.resolve(rootFolder, name);
@@ -85,5 +85,5 @@ async function ensureLocalFolderExists(name, rootFolder) {
85
85
  }
86
86
  function fetchMetadataCloned(name, registryUrl, registryToken) {
87
87
  const urlSafeName = name.replace(/\//g, '%2f');
88
- return (0, client_1.fetchJsonWithCacheCloned)(url.resolve(registryUrl, urlSafeName), registryToken);
88
+ return fetchJsonWithCacheCloned(url.resolve(registryUrl, urlSafeName), registryToken);
89
89
  }
package/src/index.js CHANGED
@@ -1,12 +1,10 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const fs = require("fs");
4
- const path = require("path");
5
- const commander_1 = require("commander");
6
- const sync_1 = require("./sync");
7
- const url_1 = require("url");
8
- const { version } = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'));
9
- const program = new commander_1.Command();
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { Command } from 'commander';
4
+ import { synchronize } from "./sync.js";
5
+ import { URL } from 'url';
6
+ const { version } = JSON.parse(fs.readFileSync(path.join(import.meta.dirname, '..', 'package.json'), 'utf-8'));
7
+ const program = new Command();
10
8
  program
11
9
  .version(version)
12
10
  .requiredOption('--root <path>', 'Path to save NPM package tarballs and metadata to')
@@ -35,7 +33,7 @@ const prebuiltBinaryProperties = abis
35
33
  .map(abi => architectures.map(arch => platforms.map(platform => ({ abi, arch, platform }))).flat())
36
34
  .flat();
37
35
  const options = {
38
- localUrl: new url_1.URL(rawOptions.localUrl),
36
+ localUrl: new URL(rawOptions.localUrl),
39
37
  manifest: rawOptions.manifest,
40
38
  prebuiltBinaryProperties,
41
39
  registryUrl: rawOptions.registryUrl || 'https://registry.npmjs.org',
@@ -45,4 +43,4 @@ const options = {
45
43
  includeDevDependencies: Boolean(rawOptions.includeDev),
46
44
  dryRun: Boolean(rawOptions.dryRun)
47
45
  };
48
- (0, sync_1.synchronize)(options);
46
+ synchronize(options);
package/src/integrity.js CHANGED
@@ -1,10 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.verifyIntegrity = verifyIntegrity;
4
- exports.sha1 = sha1;
5
- exports.sha512 = sha512;
6
- const ssri = require("ssri");
7
- function verifyIntegrity(data, id, { integrity, shasum }) {
1
+ import * as ssri from 'ssri';
2
+ export function verifyIntegrity(data, id, { integrity, shasum }) {
8
3
  if (!integrity && !shasum) {
9
4
  throw new Error(`Integrity values not present in metadata for ${id}`);
10
5
  }
@@ -17,9 +12,9 @@ function verifyIntegrity(data, id, { integrity, shasum }) {
17
12
  throw new Error(`Integrity check with SHA1 failed for failed for ${id}`);
18
13
  }
19
14
  }
20
- function sha1(data) {
15
+ export function sha1(data) {
21
16
  return ssri.fromData(data, { algorithms: ['sha1'] }).hexDigest();
22
17
  }
23
- function sha512(data) {
18
+ export function sha512(data) {
24
19
  return ssri.fromData(data, { algorithms: ['sha512'] }).toString();
25
20
  }
package/src/metadata.js CHANGED
@@ -1,26 +1,20 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rewriteVersionMetadata = rewriteVersionMetadata;
4
- exports.rewriteMetadataInTarball = rewriteMetadataInTarball;
5
- exports.extractTgz = extractTgz;
6
- exports.tarballFilename = tarballFilename;
7
- const fs = require("fs");
8
- const path = require("path");
9
- const tar = require("tar-fs");
10
- const zlib = require("zlib");
11
- const pregyp_1 = require("./pregyp");
12
- const stream_1 = require("stream");
13
- const integrity_1 = require("./integrity");
14
- function rewriteVersionMetadata(versionMetadata, data, localUrl) {
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as tar from 'tar-fs';
4
+ import * as zlib from 'zlib';
5
+ import { hasPrebuiltBinaries } from "./pregyp.js";
6
+ import { Readable } from 'stream';
7
+ import { sha1, sha512 } from "./integrity.js";
8
+ export function rewriteVersionMetadata(versionMetadata, data, localUrl) {
15
9
  versionMetadata.dist.tarball = localTarballUrl(versionMetadata, localUrl);
16
- if ((0, pregyp_1.hasPrebuiltBinaries)(versionMetadata)) {
10
+ if (hasPrebuiltBinaries(versionMetadata)) {
17
11
  versionMetadata.binary.host = localUrl.origin;
18
12
  versionMetadata.binary.remote_path = createPrebuiltBinaryRemotePath(localUrl, versionMetadata);
19
- versionMetadata.dist.integrity = (0, integrity_1.sha512)(data);
20
- versionMetadata.dist.shasum = (0, integrity_1.sha1)(data);
13
+ versionMetadata.dist.integrity = sha512(data);
14
+ versionMetadata.dist.shasum = sha1(data);
21
15
  }
22
16
  }
23
- async function rewriteMetadataInTarball(data, versionMetadata, localUrl, localFolder) {
17
+ export async function rewriteMetadataInTarball(data, versionMetadata, localUrl, localFolder) {
24
18
  const tmpFolder = path.join(localFolder, '.tmp');
25
19
  await fs.promises.mkdir(tmpFolder, { recursive: true });
26
20
  await extractTgz(data, tmpFolder);
@@ -37,9 +31,9 @@ async function rewriteMetadataInTarball(data, versionMetadata, localUrl, localFo
37
31
  function createPrebuiltBinaryRemotePath(url, versionMetadata) {
38
32
  return `${removeTrailingSlash(url.pathname)}/${versionMetadata.name}/${versionMetadata.version}/`;
39
33
  }
40
- function extractTgz(data, folder) {
34
+ export function extractTgz(data, folder) {
41
35
  return new Promise((resolve, reject) => {
42
- const tgz = stream_1.Readable.from(data).pipe(zlib.createGunzip()).pipe(tar.extract(folder));
36
+ const tgz = Readable.from(data).pipe(zlib.createGunzip()).pipe(tar.extract(folder));
43
37
  tgz.on('finish', resolve);
44
38
  tgz.on('error', reject);
45
39
  });
@@ -56,7 +50,7 @@ function compressTgz(folder) {
56
50
  function localTarballUrl({ name, version }, localUrl) {
57
51
  return `${localUrl.origin}${removeTrailingSlash(localUrl.pathname)}/${name}/${tarballFilename(name, version)}`;
58
52
  }
59
- function tarballFilename(name, version) {
53
+ export function tarballFilename(name, version) {
60
54
  const normalized = name.replace(/\//g, '-');
61
55
  return `${normalized}-${version}.tgz`;
62
56
  }
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /*
3
2
  BSD 2-Clause License
4
3
 
@@ -28,9 +27,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
27
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
28
  */
30
29
  // From https://github.com/yarnpkg/yarn/blob/953c8b6a20e360b097625d64189e6e56ed813e0f/src/util/normalize-pattern.js#L2
31
- Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.normalizeYarnPackagePattern = normalizeYarnPackagePattern;
33
- function normalizeYarnPackagePattern(pattern) {
30
+ export function normalizeYarnPackagePattern(pattern) {
34
31
  let hasVersion = false;
35
32
  let range = 'latest';
36
33
  let name = pattern;
package/src/pregyp.js CHANGED
@@ -1,16 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasPrebuiltBinaries = hasPrebuiltBinaries;
4
- exports.downloadPrebuiltBinaries = downloadPrebuiltBinaries;
5
- const fs = require("fs");
6
- const path = require("path");
7
- const semver = require("semver");
8
- const url = require("url");
9
- const client_1 = require("./client");
10
- function hasPrebuiltBinaries({ binary }) {
11
- return Boolean(binary && binary.module_name);
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as semver from 'semver';
4
+ import * as url from 'url';
5
+ import { fetchBinaryData } from "./client.js";
6
+ export function hasPrebuiltBinaries(metadata) {
7
+ return Boolean(metadata.binary
8
+ && metadata.binary.host
9
+ && metadata.binary.module_name
10
+ && metadata.binary.package_name
11
+ && metadata.binary.remote_path);
12
12
  }
13
- async function downloadPrebuiltBinaries(versionMetadata, localFolder, prebuiltBinaryProperties) {
13
+ export async function downloadPrebuiltBinaries(versionMetadata, localFolder, prebuiltBinaryProperties) {
14
14
  const { binary, name, version } = versionMetadata;
15
15
  if (!binary.napi_versions) {
16
16
  for (const { abi, arch, platform } of prebuiltBinaryProperties) {
@@ -31,6 +31,7 @@ async function downloadPrebuiltBinary(localFolder, name, version, binary, abi, p
31
31
  }
32
32
  catch (err) {
33
33
  // pre-built binaries are commonly not available on all platforms (and S3 will commonly respond with 403 for a non-existent file)
34
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
35
  const fileNotFoundError = err.response && (err.response.status == 403 || err.response.status == 404);
35
36
  if (!fileNotFoundError) {
36
37
  console.error(`Unexpected error fetching prebuilt binary for ${name} and ABI v${abi} on ${arch}-${platform} (n-api version ${napiVersion})`);
@@ -39,7 +40,7 @@ async function downloadPrebuiltBinary(localFolder, name, version, binary, abi, p
39
40
  }
40
41
  }
41
42
  function fetchPrebuiltBinary(name, version, binary, abi, platform, arch, napiVersion) {
42
- return (0, client_1.fetchBinaryData)(prebuiltBinaryUrl(name, version, binary, abi, platform, arch, napiVersion), '');
43
+ return fetchBinaryData(prebuiltBinaryUrl(name, version, binary, abi, platform, arch, napiVersion), '');
43
44
  }
44
45
  function prebuiltBinaryFilePath(localFolder, name, version, binary, abi, platform, arch, napiVersion) {
45
46
  return path.join(localFolder, prebuiltBinaryFileName(name, version, binary, abi, platform, arch, napiVersion));
@@ -57,7 +58,7 @@ function prebuiltBinaryFileName(name, version, binary, abi, platform, arch, napi
57
58
  }
58
59
  // see node-pre-gyp: /lib/util/versioning.js for documentation of possible values
59
60
  function formatPrebuilt(formatString, name, version, moduleName, abi, platform, arch, napiVersion) {
60
- const moduleVersion = semver.parse(version);
61
+ const moduleVersion = semver.parse(version, false, true);
61
62
  const prerelease = (moduleVersion.prerelease || []).join('.');
62
63
  const build = (moduleVersion.build || []).join('.');
63
64
  const formatted = formatString
package/src/resolve.js CHANGED
@@ -1,17 +1,12 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.updateDependenciesCache = updateDependenciesCache;
4
- exports.dependenciesNotInCache = dependenciesNotInCache;
5
- exports.dependenciesFromPackageLock = dependenciesFromPackageLock;
6
- const fs = require("fs");
7
- const pathLib = require("path");
8
- const readline = require("readline");
9
- const url = require("url");
10
- const assert_1 = require("assert");
11
- const yarnLockfile = require("@yarnpkg/lockfile");
12
- const normalize_yarn_pattern_1 = require("./normalize-yarn-pattern");
1
+ import * as fs from 'fs';
2
+ import * as pathLib from 'path';
3
+ import * as readline from 'readline';
4
+ import * as url from 'url';
5
+ import assert, { deepStrictEqual } from 'assert';
6
+ import yarnLockfile from '@yarnpkg/lockfile';
7
+ import { normalizeYarnPackagePattern } from "./normalize-yarn-pattern.js";
13
8
  const YARN_LOCK_FILENAME = 'yarn.lock';
14
- async function updateDependenciesCache(newDependencies, cacheFilePath, prebuiltBinaryProperties) {
9
+ export async function updateDependenciesCache(newDependencies, cacheFilePath, prebuiltBinaryProperties) {
15
10
  const { dependencies: cachedDependencies } = await loadCache(cacheFilePath);
16
11
  const dependencies = cachedDependencies.concat(newDependencies).sort(sortById).filter(uniqueById);
17
12
  const data = {
@@ -21,7 +16,7 @@ async function updateDependenciesCache(newDependencies, cacheFilePath, prebuiltB
21
16
  };
22
17
  return fs.promises.writeFile(cacheFilePath, JSON.stringify(data), 'utf8');
23
18
  }
24
- async function dependenciesNotInCache(dependencies, cacheFilePath, prebuiltBinaryProperties) {
19
+ export async function dependenciesNotInCache(dependencies, cacheFilePath, prebuiltBinaryProperties) {
25
20
  const { dependencies: cachedDependencies, prebuiltBinaryProperties: cachedPrebuiltBinaryProperties, prebuiltBinaryNApiSupport } = await loadCache(cacheFilePath);
26
21
  if (cachedDependencies.length > 0 &&
27
22
  (!isDeepEqual(prebuiltBinaryProperties, cachedPrebuiltBinaryProperties) || !prebuiltBinaryNApiSupport)) {
@@ -85,6 +80,7 @@ function isNonRegistryYarnPackagePattern(packagePattern) {
85
80
  return path.split('/').filter((p) => !!p).length === 2;
86
81
  }
87
82
  }
83
+ return false;
88
84
  }
89
85
  function resolvePackageNameFromRegistryYarnPackagePattern(packagePattern) {
90
86
  // See https://github.com/yarnpkg/yarn/blob/953c8b6a20e360b097625d64189e6e56ed813e0f/src/resolvers/exotics/registry-resolver.js#L12
@@ -108,7 +104,7 @@ function resolveNpmPackagesFromYarnLockDependencies(yarnLockDependencies) {
108
104
  else {
109
105
  // Package pattern not yet recognized, continue with parsing logic from
110
106
  // https://github.com/yarnpkg/yarn/blob/953c8b6a20e360b097625d64189e6e56ed813e0f/src/package-request.js#L99
111
- const { name: namePart, range: rangePart } = (0, normalize_yarn_pattern_1.normalizeYarnPackagePattern)(packagePattern);
107
+ const { name: namePart, range: rangePart } = normalizeYarnPackagePattern(packagePattern);
112
108
  if (isNonRegistryYarnPackagePattern(rangePart)) {
113
109
  return filterMappedDependencies;
114
110
  }
@@ -129,7 +125,7 @@ function resolveNpmPackagesFromYarnLockDependencies(yarnLockDependencies) {
129
125
  async function parseDependenciesFromNpmLockFile(lockFilepath, includeDevDependencies) {
130
126
  const packageLock = JSON.parse(await fs.promises.readFile(lockFilepath, 'utf8'));
131
127
  const fileVersion = packageLock.lockfileVersion || 1;
132
- if (![2, 3].includes(packageLock.lockfileVersion)) {
128
+ if (![2, 3].includes(fileVersion)) {
133
129
  throw new Error(`Unsupported package-lock.json version ${fileVersion}`);
134
130
  }
135
131
  const dependencies = collectNpmLockfileDependencies(packageLock, includeDevDependencies);
@@ -162,7 +158,7 @@ async function parseDependenciesFromYarnLockFile(lockFilepath) {
162
158
  const yarnLockDependencies = Object.entries(packagePatternToLockedVersion).map(([packagePattern, { version }]) => ({ packagePattern, version }));
163
159
  return resolveNpmPackagesFromYarnLockDependencies(yarnLockDependencies);
164
160
  }
165
- async function dependenciesFromPackageLock(path, includeDevDependencies) {
161
+ export async function dependenciesFromPackageLock(path, includeDevDependencies) {
166
162
  const filename = pathLib.basename(path);
167
163
  const dependencies = filename === YARN_LOCK_FILENAME
168
164
  ? await parseDependenciesFromYarnLockFile(path)
@@ -194,11 +190,13 @@ function collectNpmLockfileDependencies({ packages }, includeDevDependencies) {
194
190
  // "node_modules/lodash" -> "lodash"
195
191
  // "node_modules/make-dir/node_modules/semver" -> "semver"
196
192
  function pathToName(path) {
197
- return path.split('node_modules/').pop();
193
+ const name = path.split('node_modules/').pop();
194
+ assert(name, `Failed to extract package name from path ${path}`);
195
+ return name;
198
196
  }
199
197
  function isDeepEqual(a, b) {
200
198
  try {
201
- (0, assert_1.deepStrictEqual)(a, b);
199
+ deepStrictEqual(a, b);
202
200
  return true;
203
201
  }
204
202
  catch {
package/src/sync.js CHANGED
@@ -1,19 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.synchronize = synchronize;
4
- const download_1 = require("./download");
5
- const resolve_1 = require("./resolve");
6
- async function synchronize(options) {
1
+ import { dependenciesFromPackageLock, dependenciesNotInCache, updateDependenciesCache } from "./resolve.js";
2
+ import { downloadAll } from "./download.js";
3
+ export async function synchronize(options) {
7
4
  const cacheFilePath = `${options.rootFolder}/.registry-sync-cache.json`;
8
- const packages = await (0, resolve_1.dependenciesFromPackageLock)(options.manifest, options.includeDevDependencies);
9
- const newPackages = await (0, resolve_1.dependenciesNotInCache)(packages, cacheFilePath, options.prebuiltBinaryProperties);
5
+ const packages = await dependenciesFromPackageLock(options.manifest, options.includeDevDependencies);
6
+ const newPackages = await dependenciesNotInCache(packages, cacheFilePath, options.prebuiltBinaryProperties);
10
7
  if (options.dryRun) {
11
8
  console.log(newPackages.map(({ name, version }) => `${name}@${version}`).join('\n'));
12
9
  console.log(`\nWould download ${newPackages.length} packages.`);
13
10
  }
14
11
  else {
15
- await (0, download_1.downloadAll)(newPackages, options);
16
- await (0, resolve_1.updateDependenciesCache)(newPackages, cacheFilePath, options.prebuiltBinaryProperties);
12
+ await downloadAll(newPackages, options);
13
+ await updateDependenciesCache(newPackages, cacheFilePath, options.prebuiltBinaryProperties);
17
14
  console.log(`Downloaded ${newPackages.length} packages`);
18
15
  }
19
16
  return newPackages;