@kubb/core 5.11.6 → 5.12.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/dist/{Hookable-CvStaYYq.js → Hookable-Cqx0g2T-.js} +139 -10
- package/dist/Hookable-Cqx0g2T-.js.map +1 -0
- package/dist/{createAdapter-DtX_MKL-.d.ts → createAdapter-DFXvZLZC.d.ts} +138 -131
- package/dist/index.cjs +134 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +155 -135
- package/dist/index.d.ts +19 -6
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.js +1 -1
- package/package.json +2 -2
- package/dist/Hookable-CvStaYYq.js.map +0 -1
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import { satisfies } from "verkit";
|
|
3
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import process$1 from "node:process";
|
|
5
|
+
import { x } from "tinyexec";
|
|
6
|
+
import { glob, mkdir, mkdtemp, readFile, rm, rm as rm$1, writeFile } from "node:fs/promises";
|
|
7
|
+
import path, { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
6
8
|
import { existsSync as existsSync$1 } from "node:fs";
|
|
7
9
|
import { stripVTControlCharacters, styleText } from "node:util";
|
|
8
10
|
import { ast, collectImportedRefNames, collectUsedSchemaNames, extractStringsFromNodes } from "@kubb/ast";
|
|
11
|
+
import { tmpdir } from "node:os";
|
|
9
12
|
//#region \0rolldown/runtime.js
|
|
10
13
|
var __defProp = Object.defineProperty;
|
|
11
14
|
var __name = (target, value) => __defProp(target, "name", {
|
|
@@ -14,7 +17,7 @@ var __name = (target, value) => __defProp(target, "name", {
|
|
|
14
17
|
});
|
|
15
18
|
//#endregion
|
|
16
19
|
//#region package.json
|
|
17
|
-
var version = "5.
|
|
20
|
+
var version = "5.12.0";
|
|
18
21
|
//#endregion
|
|
19
22
|
//#region ../../internals/utils/src/casing.ts
|
|
20
23
|
/**
|
|
@@ -364,6 +367,12 @@ const diagnosticCatalog = {
|
|
|
364
367
|
cause: "A URL set as `input` (or reached through a `$ref`) never answered, so the request failed before a status came back. A refused connection, an unknown host, an expired certificate, and a timeout all land here.",
|
|
365
368
|
fix: "Check that the host is running and reachable from this machine. For a local server, start it and confirm the port matches the one in `input`."
|
|
366
369
|
},
|
|
370
|
+
gitInputFailed: {
|
|
371
|
+
code: "KUBB_GIT_INPUT_FAILED",
|
|
372
|
+
title: "Git input failed",
|
|
373
|
+
cause: "A git `input` (`git+<repo>#<ref>:<path>`) is malformed, or `git` could not fetch it: git is not installed, the repository or ref does not exist, or the credentials were refused.",
|
|
374
|
+
fix: "Write the input as `git+<repo>#<ref>:<path>`. Run `git fetch --depth 1 <repo> <ref>` yourself to see the git error, and set up a credential helper or SSH key for a private repository."
|
|
375
|
+
},
|
|
367
376
|
inputRequired: {
|
|
368
377
|
code: "KUBB_INPUT_REQUIRED",
|
|
369
378
|
title: "Input required",
|
|
@@ -1234,18 +1243,130 @@ function definePlugin(definition) {
|
|
|
1234
1243
|
});
|
|
1235
1244
|
}
|
|
1236
1245
|
//#endregion
|
|
1246
|
+
//#region src/gitInput.ts
|
|
1247
|
+
/** Matches a git `input`: the `git+` prefix npm uses for git dependencies. */
|
|
1248
|
+
const gitInputRegExp = /^git\+/i;
|
|
1249
|
+
function gitError(message, cause) {
|
|
1250
|
+
return new Diagnostics.Error({
|
|
1251
|
+
code: Diagnostics.code.gitInputFailed,
|
|
1252
|
+
severity: "error",
|
|
1253
|
+
message,
|
|
1254
|
+
help: "Write a git `input` as `git+<repo>#<ref>:<path>`, for example `git+https://github.com/org/api.git#main:specs/openapi.yaml`. Check that `git` is installed and that `git fetch` can reach the repository with your credentials.",
|
|
1255
|
+
location: { kind: "config" },
|
|
1256
|
+
cause: cause === void 0 ? void 0 : toError(cause)
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
/** The repository URL without a user or password, safe to print. */
|
|
1260
|
+
function redact(repo) {
|
|
1261
|
+
if (!URL.canParse(repo)) return repo;
|
|
1262
|
+
const url = new URL(repo);
|
|
1263
|
+
url.username = "";
|
|
1264
|
+
url.password = "";
|
|
1265
|
+
return url.href;
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* Splits `git+<repo>#<ref>:<path>` into its parts. Git refs cannot contain `:`, so the first one
|
|
1269
|
+
* in the fragment ends the ref. Throws `KUBB_GIT_INPUT_FAILED` when the fragment or path is missing.
|
|
1270
|
+
*/
|
|
1271
|
+
function parseGitInput(input) {
|
|
1272
|
+
const hashIndex = input.indexOf("#");
|
|
1273
|
+
const repo = input.slice(4, hashIndex === -1 ? void 0 : hashIndex);
|
|
1274
|
+
const fragment = hashIndex === -1 ? "" : input.slice(hashIndex + 1);
|
|
1275
|
+
const colonIndex = fragment.indexOf(":");
|
|
1276
|
+
const ref = colonIndex === -1 ? void 0 : fragment.slice(0, colonIndex);
|
|
1277
|
+
const path = colonIndex === -1 ? fragment : fragment.slice(colonIndex + 1);
|
|
1278
|
+
if (!repo || !path || ref === "") throw gitError(`The git \`input\` for ${redact(repo)} has no repository, ref, or spec path after \`#\`.`);
|
|
1279
|
+
return {
|
|
1280
|
+
repo,
|
|
1281
|
+
ref,
|
|
1282
|
+
path
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
/**
|
|
1286
|
+
* Fetches one commit of a git repository into a temporary directory with a shallow `git fetch`,
|
|
1287
|
+
* so any host and the user's own git credentials work, and relative `$ref` files resolve.
|
|
1288
|
+
* Resolves to the spec path on disk and a `dispose` that deletes the checkout.
|
|
1289
|
+
*/
|
|
1290
|
+
async function checkoutGitInput(input, signal) {
|
|
1291
|
+
const { repo, ref, path } = parseGitInput(input);
|
|
1292
|
+
const dir = await mkdtemp(join(tmpdir(), "kubb-git-"));
|
|
1293
|
+
const dispose = () => rm(dir, {
|
|
1294
|
+
recursive: true,
|
|
1295
|
+
force: true
|
|
1296
|
+
});
|
|
1297
|
+
const specPath = resolve(dir, path);
|
|
1298
|
+
const relativePath = relative(dir, specPath);
|
|
1299
|
+
if (relativePath === ".." || relativePath.startsWith(`..${sep}`) || isAbsolute(relativePath)) {
|
|
1300
|
+
await dispose();
|
|
1301
|
+
throw gitError(`The spec path "${path}" in the git \`input\` points outside the repository.`);
|
|
1302
|
+
}
|
|
1303
|
+
const label = `${redact(repo)}${ref ? ` at ${ref}` : ""}`;
|
|
1304
|
+
const env = {
|
|
1305
|
+
...process$1.env,
|
|
1306
|
+
GIT_TERMINAL_PROMPT: "0"
|
|
1307
|
+
};
|
|
1308
|
+
const steps = [
|
|
1309
|
+
["init", "--quiet"],
|
|
1310
|
+
[
|
|
1311
|
+
"config",
|
|
1312
|
+
"core.symlinks",
|
|
1313
|
+
"false"
|
|
1314
|
+
],
|
|
1315
|
+
[
|
|
1316
|
+
"fetch",
|
|
1317
|
+
"--quiet",
|
|
1318
|
+
"--depth",
|
|
1319
|
+
"1",
|
|
1320
|
+
"--end-of-options",
|
|
1321
|
+
repo,
|
|
1322
|
+
ref ?? "HEAD"
|
|
1323
|
+
],
|
|
1324
|
+
[
|
|
1325
|
+
"checkout",
|
|
1326
|
+
"--quiet",
|
|
1327
|
+
"FETCH_HEAD"
|
|
1328
|
+
]
|
|
1329
|
+
];
|
|
1330
|
+
try {
|
|
1331
|
+
for (const args of steps) {
|
|
1332
|
+
const result = await x("git", args, {
|
|
1333
|
+
nodeOptions: {
|
|
1334
|
+
cwd: dir,
|
|
1335
|
+
env,
|
|
1336
|
+
signal
|
|
1337
|
+
},
|
|
1338
|
+
throwOnError: false
|
|
1339
|
+
});
|
|
1340
|
+
if (result.exitCode !== 0) {
|
|
1341
|
+
const stderr = result.stderr.replaceAll(repo, redact(repo)).trim();
|
|
1342
|
+
throw gitError(`\`git ${args[0]}\` failed for ${label}: ${stderr || `exit code ${result.exitCode}`}`);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
} catch (error) {
|
|
1346
|
+
await dispose();
|
|
1347
|
+
if (Diagnostics.isError(error)) throw error;
|
|
1348
|
+
throw gitError(`Cannot run \`git\` for ${label}: ${getErrorMessage(error)}`, error);
|
|
1349
|
+
}
|
|
1350
|
+
return {
|
|
1351
|
+
path: specPath,
|
|
1352
|
+
dispose
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
//#endregion
|
|
1237
1356
|
//#region src/input.ts
|
|
1238
1357
|
/**
|
|
1239
1358
|
* Classifies an `input` value so callers branch on it once instead of repeating the checks.
|
|
1240
1359
|
*
|
|
1241
1360
|
* A non-string is a parsed spec (`object`). A string is `inline` when it holds OpenAPI content,
|
|
1242
1361
|
* meaning it starts with `{` or `[`, spans multiple lines, or opens with a YAML `openapi:` or
|
|
1243
|
-
* `swagger:` key. Otherwise a string is
|
|
1362
|
+
* `swagger:` key. Otherwise a string is `git` when it starts with `git+`, a `url` when it parses as
|
|
1363
|
+
* one, or a `file` path.
|
|
1244
1364
|
*/
|
|
1245
1365
|
function getInputKind(input) {
|
|
1246
1366
|
if (typeof input !== "string") return "object";
|
|
1247
1367
|
const trimmed = input.trimStart();
|
|
1248
1368
|
if (trimmed.startsWith("{") || trimmed.startsWith("[") || input.includes("\n") || /^(openapi|swagger)\s*:/i.test(trimmed)) return "inline";
|
|
1369
|
+
if (gitInputRegExp.test(input)) return "git";
|
|
1249
1370
|
if (URL.canParse(input)) return "url";
|
|
1250
1371
|
return "file";
|
|
1251
1372
|
}
|
|
@@ -1269,8 +1390,9 @@ function isLegacyInput(input) {
|
|
|
1269
1390
|
/**
|
|
1270
1391
|
* Normalizes `config.input` into an `AdapterSource` the adapter can parse.
|
|
1271
1392
|
*
|
|
1272
|
-
* A parsed object and inline content become `{ type: 'data' }`; a URL
|
|
1273
|
-
* local path is resolved against `config.root`,
|
|
1393
|
+
* A parsed object and inline content become `{ type: 'data' }`; a URL or git input is kept
|
|
1394
|
+
* verbatim and a local path is resolved against `config.root`, all as `{ type: 'path' }`. The
|
|
1395
|
+
* driver checks out a git input before the adapter parses it.
|
|
1274
1396
|
*/
|
|
1275
1397
|
function inputToAdapterSource(config) {
|
|
1276
1398
|
const input = config.input;
|
|
@@ -1297,7 +1419,7 @@ function inputToAdapterSource(config) {
|
|
|
1297
1419
|
type: "data",
|
|
1298
1420
|
data: input
|
|
1299
1421
|
};
|
|
1300
|
-
if (kind === "url") return {
|
|
1422
|
+
if (kind === "url" || kind === "git") return {
|
|
1301
1423
|
type: "path",
|
|
1302
1424
|
path: input
|
|
1303
1425
|
};
|
|
@@ -2231,13 +2353,20 @@ var KubbDriver = class {
|
|
|
2231
2353
|
async #parseInput() {
|
|
2232
2354
|
if (this.inputNode || !this.adapter || !this.#adapterSource) return;
|
|
2233
2355
|
this.options.signal?.throwIfAborted();
|
|
2356
|
+
const source = this.#adapterSource;
|
|
2357
|
+
const checkout = source.type === "path" && gitInputRegExp.test(source.path) ? await checkoutGitInput(source.path, this.options.signal) : void 0;
|
|
2234
2358
|
try {
|
|
2235
|
-
this.inputNode = await this.adapter.parse(
|
|
2359
|
+
this.inputNode = await this.adapter.parse(checkout ? {
|
|
2360
|
+
type: "path",
|
|
2361
|
+
path: checkout.path
|
|
2362
|
+
} : source, { signal: this.options.signal });
|
|
2236
2363
|
} catch (caughtError) {
|
|
2237
2364
|
throw new Diagnostics.Error(Diagnostics.fromExtension(caughtError, {
|
|
2238
2365
|
kind: "adapter",
|
|
2239
2366
|
extension: this.adapter
|
|
2240
2367
|
}));
|
|
2368
|
+
} finally {
|
|
2369
|
+
await checkout?.dispose();
|
|
2241
2370
|
}
|
|
2242
2371
|
}
|
|
2243
2372
|
/**
|
|
@@ -2856,6 +2985,6 @@ var Hookable = class {
|
|
|
2856
2985
|
}
|
|
2857
2986
|
};
|
|
2858
2987
|
//#endregion
|
|
2859
|
-
export {
|
|
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 };
|
|
2860
2989
|
|
|
2861
|
-
//# sourceMappingURL=Hookable-
|
|
2990
|
+
//# sourceMappingURL=Hookable-Cqx0g2T-.js.map
|