@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.
@@ -8,6 +8,8 @@ import path, { dirname, isAbsolute, join, relative, resolve, sep } from "node:pa
8
8
  import { existsSync as existsSync$1 } from "node:fs";
9
9
  import { stripVTControlCharacters, styleText } from "node:util";
10
10
  import { ast, collectImportedRefNames, collectUsedSchemaNames, extractStringsFromNodes } from "@kubb/ast";
11
+ import dns from "node:dns";
12
+ import net from "node:net";
11
13
  import { tmpdir } from "node:os";
12
14
  //#region \0rolldown/runtime.js
13
15
  var __defProp = Object.defineProperty;
@@ -17,7 +19,7 @@ var __name = (target, value) => __defProp(target, "name", {
17
19
  });
18
20
  //#endregion
19
21
  //#region package.json
20
- var version = "5.12.0";
22
+ var version = "5.12.2";
21
23
  //#endregion
22
24
  //#region ../../internals/utils/src/casing.ts
23
25
  /**
@@ -1243,6 +1245,42 @@ function definePlugin(definition) {
1243
1245
  });
1244
1246
  }
1245
1247
  //#endregion
1248
+ //#region src/publicAddress.ts
1249
+ function createBlockList() {
1250
+ const list = new net.BlockList();
1251
+ for (const [address, prefix] of [
1252
+ ["0.0.0.0", 8],
1253
+ ["10.0.0.0", 8],
1254
+ ["100.64.0.0", 10],
1255
+ ["127.0.0.0", 8],
1256
+ ["169.254.0.0", 16],
1257
+ ["172.16.0.0", 12],
1258
+ ["192.0.0.0", 24],
1259
+ ["192.168.0.0", 16],
1260
+ ["198.18.0.0", 15],
1261
+ ["224.0.0.0", 3]
1262
+ ]) list.addSubnet(address, prefix, "ipv4");
1263
+ for (const [address, prefix] of [
1264
+ ["::", 128],
1265
+ ["::1", 128],
1266
+ ["64:ff9b::", 96],
1267
+ ["fc00::", 7],
1268
+ ["fe80::", 10],
1269
+ ["ff00::", 8]
1270
+ ]) list.addSubnet(address, prefix, "ipv6");
1271
+ return list;
1272
+ }
1273
+ const privateAddresses = createBlockList();
1274
+ /**
1275
+ * Whether `address` is a routable public IP. Loopback, private, link-local, cloud metadata, and
1276
+ * multicast ranges are not, and an IPv4-mapped IPv6 address counts as the IPv4 address it wraps.
1277
+ * Pass `blocked` to replace the ranges.
1278
+ */
1279
+ function isPublicAddress(address, blocked = privateAddresses) {
1280
+ const family = net.isIP(address);
1281
+ return family !== 0 && !blocked.check(address, family === 4 ? "ipv4" : "ipv6");
1282
+ }
1283
+ //#endregion
1246
1284
  //#region src/gitInput.ts
1247
1285
  /** Matches a git `input`: the `git+` prefix npm uses for git dependencies. */
1248
1286
  const gitInputRegExp = /^git\+/i;
@@ -1283,12 +1321,54 @@ function parseGitInput(input) {
1283
1321
  };
1284
1322
  }
1285
1323
  /**
1324
+ * The `git -c` settings that confine a fetch to https and to `addresses`: the connection goes to
1325
+ * the addresses already checked, whatever the host answers to a second lookup, and a redirect to
1326
+ * another host is an error. Needs git 2.37 for the pinning.
1327
+ *
1328
+ * @internal
1329
+ */
1330
+ function publicFetchConfig({ host, port, addresses }) {
1331
+ const pinned = addresses.map((address) => net.isIPv6(address) ? `[${address}]` : address).join(",");
1332
+ const config = [
1333
+ "http.followRedirects=false",
1334
+ "protocol.allow=never",
1335
+ "protocol.https.allow=always"
1336
+ ];
1337
+ if (!net.isIP(host)) config.push(`http.curloptResolve=${host}:${port}:${pinned}`);
1338
+ return config.flatMap((setting) => ["-c", setting]);
1339
+ }
1340
+ async function resolvePublicFetchConfig(repo, signal) {
1341
+ 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.");
1342
+ const url = new URL(repo);
1343
+ const host = url.hostname.replace(/^\[|\]$/g, "");
1344
+ const isLiteral = net.isIP(host) !== 0;
1345
+ const addresses = isLiteral ? [host] : (await dns.promises.lookup(host, { all: true })).map(({ address }) => address);
1346
+ if (!addresses.length || addresses.some((address) => !isPublicAddress(address))) throw gitError(`${host} is not a public address, so this git \`input\` is not fetched.`);
1347
+ if (!isLiteral) {
1348
+ const { stdout } = await x("git", ["--version"], {
1349
+ nodeOptions: { signal },
1350
+ throwOnError: true
1351
+ });
1352
+ const [, major = 0, minor = 0] = /(\d+)\.(\d+)/.exec(stdout)?.map(Number) ?? [];
1353
+ if (major < 2 || major === 2 && minor < 37) throw gitError(`Fetching a public git \`input\` needs git 2.37 or newer, found ${stdout.trim()}.`);
1354
+ }
1355
+ return publicFetchConfig({
1356
+ host,
1357
+ port: url.port || "443",
1358
+ addresses
1359
+ });
1360
+ }
1361
+ /**
1286
1362
  * Fetches one commit of a git repository into a temporary directory with a shallow `git fetch`,
1287
1363
  * so any host and the user's own git credentials work, and relative `$ref` files resolve.
1288
1364
  * Resolves to the spec path on disk and a `dispose` that deletes the checkout.
1365
+ *
1366
+ * With `publicOnly`, the repository must be an https URL on public addresses, the fetch connects to
1367
+ * the addresses checked, and it does not follow a redirect.
1289
1368
  */
1290
- async function checkoutGitInput(input, signal) {
1369
+ async function checkoutGitInput(input, signal, { publicOnly = false } = {}) {
1291
1370
  const { repo, ref, path } = parseGitInput(input);
1371
+ const fetchConfig = publicOnly ? await resolvePublicFetchConfig(repo, signal) : [];
1292
1372
  const dir = await mkdtemp(join(tmpdir(), "kubb-git-"));
1293
1373
  const dispose = () => rm(dir, {
1294
1374
  recursive: true,
@@ -1313,6 +1393,7 @@ async function checkoutGitInput(input, signal) {
1313
1393
  "false"
1314
1394
  ],
1315
1395
  [
1396
+ ...fetchConfig,
1316
1397
  "fetch",
1317
1398
  "--quiet",
1318
1399
  "--depth",
@@ -2985,6 +3066,6 @@ var Hookable = class {
2985
3066
  }
2986
3067
  };
2987
3068
  //#endregion
2988
- export { getElapsedMs as A, camelCase as B, useKubb as C, resolveMeta as D, defineExtension as E, read as F, rm$1 as I, write as L, existsSync$1 as M, isPathInside as N, Diagnostics as O, listFiles as P, writeRaw as R, useConfig as S, checkCompatibility as T, __name as V, requirePlugin as _, FileManager as a, setResolver as b, Resolver as c, assertPluginOption as d, definePlugin as f, kubbContext as g, injectFile as h, createNodeCache as i, inParallel as j, formatMs as k, getInputKind as l, addMacro as m, KubbDriver as n, _usingCtx as o, addGenerator as p, pluginNotFoundError as r, createResolver as s, Hookable as t, checkoutGitInput as u, setMacros as v, useOptions as w, tryUseKubb as x, setOptions as y, toError as z };
3069
+ export { formatMs as A, toError as B, useConfig as C, defineExtension as D, checkCompatibility as E, listFiles as F, __name as H, read as I, rm$1 as L, inParallel as M, existsSync$1 as N, resolveMeta as O, isPathInside as P, write as R, tryUseKubb as S, useOptions as T, camelCase as V, kubbContext as _, FileManager as a, setOptions as b, Resolver as c, isPublicAddress as d, assertPluginOption as f, injectFile as g, addMacro as h, createNodeCache as i, getElapsedMs as j, Diagnostics as k, getInputKind as l, addGenerator as m, KubbDriver as n, _usingCtx as o, definePlugin as p, pluginNotFoundError as r, createResolver as s, Hookable as t, checkoutGitInput as u, requirePlugin as v, useKubb as w, setResolver as x, setMacros as y, writeRaw as z };
2989
3070
 
2990
- //# sourceMappingURL=Hookable-Cqx0g2T-.js.map
3071
+ //# sourceMappingURL=Hookable-DuUzYJNA.js.map