sandboxedjs 0.1.46 → 0.1.47

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/dist/index.cjs CHANGED
@@ -20318,6 +20318,8 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
20318
20318
  fetcher;
20319
20319
  metadata = /* @__PURE__ */ new Map();
20320
20320
  tarballs = /* @__PURE__ */ new Map();
20321
+ /** Single-version manifests, for the fields the packument omits. */
20322
+ details = /* @__PURE__ */ new Map();
20321
20323
  forCwd(cwd) {
20322
20324
  return new _CleanPackageInstaller(this.volume, { ...this.options, cwd });
20323
20325
  }
@@ -20343,10 +20345,17 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
20343
20345
  const version = resolveVersion(metadata, range);
20344
20346
  const manifest = metadata.versions[version];
20345
20347
  if (!manifest) throw new Error(`No matching version found for ${name}@${range}`);
20346
- if (!supportsPlatform(manifest)) {
20347
- throw new Error(`${name}@${version} is not compatible with linux/x64/glibc`);
20348
- }
20349
20348
  const identity = `${name}@${version}`;
20349
+ if (!supportsPlatform(manifest)) throw new IncompatiblePlatform(identity, "");
20350
+ if (manifest.os?.length || manifest.cpu?.length) {
20351
+ const detail = await this.platformDetail(name, version);
20352
+ if (!platformListAllows(detail.libc, PLATFORM.libc)) {
20353
+ throw new IncompatiblePlatform(identity, ` (needs ${detail.libc?.join(", ")})`);
20354
+ }
20355
+ if (detail.main?.endsWith(".node")) {
20356
+ throw new IncompatiblePlatform(identity, " (native addon; this runtime cannot dlopen)");
20357
+ }
20358
+ }
20350
20359
  const target = join(modulesRoot, name);
20351
20360
  const installed2 = this.tryReadJson(join(target, "package.json"));
20352
20361
  if (installed2?.version === version) return installed2;
@@ -20368,11 +20377,44 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
20368
20377
  try {
20369
20378
  await this.installAt(dependency, dependencyRange, childRoot, options, nextAncestry);
20370
20379
  } catch (error) {
20380
+ if (error instanceof IncompatiblePlatform) continue;
20371
20381
  options.onProgress?.(`Skipped optional ${dependency}: ${error instanceof Error ? error.message : String(error)}`);
20372
20382
  }
20373
20383
  }
20374
20384
  return manifest;
20375
20385
  }
20386
+ /**
20387
+ * The `libc` and `main` fields, which the abbreviated packument leaves out.
20388
+ *
20389
+ * Fetched per version rather than as a full packument: the single-version
20390
+ * document is a few kilobytes, while the full one for a popular package runs
20391
+ * to megabytes. Only packages that already declare `os` or `cpu` ask for it,
20392
+ * so an ordinary install of pure-JavaScript dependencies makes no extra
20393
+ * requests at all — it is the prebuilt binaries, a handful per project, that
20394
+ * need the answer.
20395
+ *
20396
+ * A failure here is not fatal. Being unable to read `libc` puts the check
20397
+ * back where it was before this existed, which is worth strictly less than
20398
+ * being right and strictly more than refusing to install.
20399
+ */
20400
+ async platformDetail(name, version) {
20401
+ const key = `${name}@${version}`;
20402
+ let request = this.details.get(key);
20403
+ if (!request) {
20404
+ request = (async () => {
20405
+ try {
20406
+ const encoded = name.startsWith("@") ? name.replace("/", "%2F") : encodeURIComponent(name);
20407
+ const response = await this.fetcher(`${this.registry}/${encoded}/${version}`);
20408
+ if (!response.ok) return {};
20409
+ return await response.json();
20410
+ } catch {
20411
+ return {};
20412
+ }
20413
+ })();
20414
+ this.details.set(key, request);
20415
+ }
20416
+ return request;
20417
+ }
20376
20418
  async getMetadata(name) {
20377
20419
  let request = this.metadata.get(name);
20378
20420
  if (!request) {
@@ -20440,8 +20482,15 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
20440
20482
  }
20441
20483
  }
20442
20484
  };
20485
+ var PLATFORM = { os: "linux", cpu: "x64", libc: "glibc" };
20486
+ var IncompatiblePlatform = class extends Error {
20487
+ constructor(identity, detail) {
20488
+ super(`${identity} is not compatible with ${PLATFORM.os}/${PLATFORM.cpu}/${PLATFORM.libc}${detail}`);
20489
+ this.name = "IncompatiblePlatform";
20490
+ }
20491
+ };
20443
20492
  function supportsPlatform(manifest) {
20444
- return !manifest.main?.endsWith(".node") && platformListAllows(manifest.os, "linux") && platformListAllows(manifest.cpu, "x64") && platformListAllows(manifest.libc, "glibc");
20493
+ return platformListAllows(manifest.os, PLATFORM.os) && platformListAllows(manifest.cpu, PLATFORM.cpu) && platformListAllows(manifest.libc, PLATFORM.libc);
20445
20494
  }
20446
20495
  function platformListAllows(values, current) {
20447
20496
  if (!values?.length) return true;