@kubb/core 5.12.0 → 5.12.2

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
@@ -32,6 +32,10 @@ node_path = __toESM(node_path, 1);
32
32
  let node_fs = require("node:fs");
33
33
  let node_util = require("node:util");
34
34
  let _kubb_ast = require("@kubb/ast");
35
+ let node_dns = require("node:dns");
36
+ node_dns = __toESM(node_dns, 1);
37
+ let node_net = require("node:net");
38
+ node_net = __toESM(node_net, 1);
35
39
  let node_os = require("node:os");
36
40
  let node_crypto = require("node:crypto");
37
41
  let node_readline = require("node:readline");
@@ -41,7 +45,7 @@ unstorage_drivers_fs = __toESM(unstorage_drivers_fs, 1);
41
45
  let node_url = require("node:url");
42
46
  let node_module = require("node:module");
43
47
  //#region package.json
44
- var version = "5.12.0";
48
+ var version = "5.12.2";
45
49
  //#endregion
46
50
  //#region ../../internals/utils/src/casing.ts
47
51
  /**
@@ -1423,6 +1427,42 @@ function definePlugin(definition) {
1423
1427
  });
1424
1428
  }
1425
1429
  //#endregion
1430
+ //#region src/publicAddress.ts
1431
+ function createBlockList() {
1432
+ const list = new node_net.default.BlockList();
1433
+ for (const [address, prefix] of [
1434
+ ["0.0.0.0", 8],
1435
+ ["10.0.0.0", 8],
1436
+ ["100.64.0.0", 10],
1437
+ ["127.0.0.0", 8],
1438
+ ["169.254.0.0", 16],
1439
+ ["172.16.0.0", 12],
1440
+ ["192.0.0.0", 24],
1441
+ ["192.168.0.0", 16],
1442
+ ["198.18.0.0", 15],
1443
+ ["224.0.0.0", 3]
1444
+ ]) list.addSubnet(address, prefix, "ipv4");
1445
+ for (const [address, prefix] of [
1446
+ ["::", 128],
1447
+ ["::1", 128],
1448
+ ["64:ff9b::", 96],
1449
+ ["fc00::", 7],
1450
+ ["fe80::", 10],
1451
+ ["ff00::", 8]
1452
+ ]) list.addSubnet(address, prefix, "ipv6");
1453
+ return list;
1454
+ }
1455
+ const privateAddresses = createBlockList();
1456
+ /**
1457
+ * Whether `address` is a routable public IP. Loopback, private, link-local, cloud metadata, and
1458
+ * multicast ranges are not, and an IPv4-mapped IPv6 address counts as the IPv4 address it wraps.
1459
+ * Pass `blocked` to replace the ranges.
1460
+ */
1461
+ function isPublicAddress(address, blocked = privateAddresses) {
1462
+ const family = node_net.default.isIP(address);
1463
+ return family !== 0 && !blocked.check(address, family === 4 ? "ipv4" : "ipv6");
1464
+ }
1465
+ //#endregion
1426
1466
  //#region src/gitInput.ts
1427
1467
  /** Matches a git `input`: the `git+` prefix npm uses for git dependencies. */
1428
1468
  const gitInputRegExp = /^git\+/i;
@@ -1463,12 +1503,54 @@ function parseGitInput(input) {
1463
1503
  };
1464
1504
  }
1465
1505
  /**
1506
+ * The `git -c` settings that confine a fetch to https and to `addresses`: the connection goes to
1507
+ * the addresses already checked, whatever the host answers to a second lookup, and a redirect to
1508
+ * another host is an error. Needs git 2.37 for the pinning.
1509
+ *
1510
+ * @internal
1511
+ */
1512
+ function publicFetchConfig({ host, port, addresses }) {
1513
+ const pinned = addresses.map((address) => node_net.default.isIPv6(address) ? `[${address}]` : address).join(",");
1514
+ const config = [
1515
+ "http.followRedirects=false",
1516
+ "protocol.allow=never",
1517
+ "protocol.https.allow=always"
1518
+ ];
1519
+ if (!node_net.default.isIP(host)) config.push(`http.curloptResolve=${host}:${port}:${pinned}`);
1520
+ return config.flatMap((setting) => ["-c", setting]);
1521
+ }
1522
+ async function resolvePublicFetchConfig(repo, signal) {
1523
+ if (!URL.canParse(repo) || new URL(repo).protocol !== "https:") throw gitError("A public git `input` must be an https repository URL, not an ssh, git, or file address.");
1524
+ const url = new URL(repo);
1525
+ const host = url.hostname.replace(/^\[|\]$/g, "");
1526
+ const isLiteral = node_net.default.isIP(host) !== 0;
1527
+ const addresses = isLiteral ? [host] : (await node_dns.default.promises.lookup(host, { all: true })).map(({ address }) => address);
1528
+ if (!addresses.length || addresses.some((address) => !isPublicAddress(address))) throw gitError(`${host} is not a public address, so this git \`input\` is not fetched.`);
1529
+ if (!isLiteral) {
1530
+ const { stdout } = await (0, tinyexec.x)("git", ["--version"], {
1531
+ nodeOptions: { signal },
1532
+ throwOnError: true
1533
+ });
1534
+ const [, major = 0, minor = 0] = /(\d+)\.(\d+)/.exec(stdout)?.map(Number) ?? [];
1535
+ if (major < 2 || major === 2 && minor < 37) throw gitError(`Fetching a public git \`input\` needs git 2.37 or newer, found ${stdout.trim()}.`);
1536
+ }
1537
+ return publicFetchConfig({
1538
+ host,
1539
+ port: url.port || "443",
1540
+ addresses
1541
+ });
1542
+ }
1543
+ /**
1466
1544
  * Fetches one commit of a git repository into a temporary directory with a shallow `git fetch`,
1467
1545
  * so any host and the user's own git credentials work, and relative `$ref` files resolve.
1468
1546
  * Resolves to the spec path on disk and a `dispose` that deletes the checkout.
1547
+ *
1548
+ * With `publicOnly`, the repository must be an https URL on public addresses, the fetch connects to
1549
+ * the addresses checked, and it does not follow a redirect.
1469
1550
  */
1470
- async function checkoutGitInput(input, signal) {
1551
+ async function checkoutGitInput(input, signal, { publicOnly = false } = {}) {
1471
1552
  const { repo, ref, path } = parseGitInput(input);
1553
+ const fetchConfig = publicOnly ? await resolvePublicFetchConfig(repo, signal) : [];
1472
1554
  const dir = await (0, node_fs_promises.mkdtemp)((0, node_path.join)((0, node_os.tmpdir)(), "kubb-git-"));
1473
1555
  const dispose = () => (0, node_fs_promises.rm)(dir, {
1474
1556
  recursive: true,
@@ -1493,6 +1575,7 @@ async function checkoutGitInput(input, signal) {
1493
1575
  "false"
1494
1576
  ],
1495
1577
  [
1578
+ ...fetchConfig,
1496
1579
  "fetch",
1497
1580
  "--quiet",
1498
1581
  "--depth",
@@ -4409,6 +4492,7 @@ exports.htmlReporter = htmlReporter;
4409
4492
  exports.injectFile = injectFile;
4410
4493
  exports.isExtensionManifest = isExtensionManifest;
4411
4494
  exports.isPackageName = isPackageName;
4495
+ exports.isPublicAddress = isPublicAddress;
4412
4496
  exports.isRegistryEntry = isRegistryEntry;
4413
4497
  exports.jsonReporter = jsonReporter;
4414
4498
  exports.kubbContext = kubbContext;