@redocly/cli 2.39.0 → 2.41.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/lib/index.js CHANGED
@@ -2,9 +2,9 @@
2
2
  import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
- j,
5
+ E,
6
6
  ulid
7
- } from "./chunks/ICAVAH7N.js";
7
+ } from "./chunks/ICPYP2LP.js";
8
8
  import {
9
9
  capitalize,
10
10
  cleanColors,
@@ -28,11 +28,16 @@ import {
28
28
  saveBundle,
29
29
  sortTopLevelKeys,
30
30
  writeToFileByExtension
31
- } from "./chunks/OYZMAAZV.js";
31
+ } from "./chunks/XDNYWH7V.js";
32
+ import {
33
+ OPENAPI3_COMPONENT_NAMES,
34
+ OPENAPI3_METHOD_NAMES,
35
+ Spinner
36
+ } from "./chunks/LCWGF7G6.js";
32
37
  import {
33
38
  AbortFlowError,
34
39
  exitWithError
35
- } from "./chunks/U4V3W7MN.js";
40
+ } from "./chunks/DT4UM7U4.js";
36
41
  import {
37
42
  RedoclyOAuthClient,
38
43
  ReuniteApi,
@@ -42,7 +47,7 @@ import {
42
47
  getProxyUrl,
43
48
  getReuniteUrl,
44
49
  shouldBypassProxy
45
- } from "./chunks/BA5AZJUM.js";
50
+ } from "./chunks/Q3KTKRJH.js";
46
51
  import {
47
52
  ANONYMOUS_ID_CACHE_FILE,
48
53
  DEFAULT_FETCH_TIMEOUT,
@@ -53,7 +58,7 @@ import {
53
58
  engines,
54
59
  name,
55
60
  version
56
- } from "./chunks/2LEVMD2A.js";
61
+ } from "./chunks/Z5H4OEIW.js";
57
62
  import {
58
63
  require_undici
59
64
  } from "./chunks/XB6C62FW.js";
@@ -61,7 +66,7 @@ import {
61
66
  RESET_ESCAPE_CODE,
62
67
  calculateTotals,
63
68
  conditionallyMaskSecrets
64
- } from "./chunks/OVY6O6WL.js";
69
+ } from "./chunks/6ABF7ZRJ.js";
65
70
  import "./chunks/VXIQEZPR.js";
66
71
  import "./chunks/UUU33DK3.js";
67
72
  import {
@@ -114,7 +119,7 @@ import {
114
119
  white,
115
120
  xmlEscape,
116
121
  yellow
117
- } from "./chunks/KYZEVOA2.js";
122
+ } from "./chunks/YK6T7IHG.js";
118
123
  import "./chunks/Z2I5YXYN.js";
119
124
  import {
120
125
  __commonJS,
@@ -3437,11 +3442,11 @@ var YargsParser = class {
3437
3442
  } else if (arg.match(/^-[^-]+/) && !arg.match(negative)) {
3438
3443
  letters = arg.slice(1, -1).split("");
3439
3444
  broken = false;
3440
- for (let j2 = 0; j2 < letters.length; j2++) {
3441
- next = arg.slice(j2 + 2);
3442
- if (letters[j2 + 1] && letters[j2 + 1] === "=") {
3443
- value = arg.slice(j2 + 3);
3444
- key = letters[j2];
3445
+ for (let j = 0; j < letters.length; j++) {
3446
+ next = arg.slice(j + 2);
3447
+ if (letters[j + 1] && letters[j + 1] === "=") {
3448
+ value = arg.slice(j + 3);
3449
+ key = letters[j];
3445
3450
  if (checkAllAliases(key, flags.arrays)) {
3446
3451
  i = eatArray(i, key, args, value);
3447
3452
  } else if (checkAllAliases(key, flags.nargs) !== false) {
@@ -3453,20 +3458,20 @@ var YargsParser = class {
3453
3458
  break;
3454
3459
  }
3455
3460
  if (next === "-") {
3456
- setArg(letters[j2], next);
3461
+ setArg(letters[j], next);
3457
3462
  continue;
3458
3463
  }
3459
- if (/[A-Za-z]/.test(letters[j2]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next) && checkAllAliases(next, flags.bools) === false) {
3460
- setArg(letters[j2], next);
3464
+ if (/[A-Za-z]/.test(letters[j]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next) && checkAllAliases(next, flags.bools) === false) {
3465
+ setArg(letters[j], next);
3461
3466
  broken = true;
3462
3467
  break;
3463
3468
  }
3464
- if (letters[j2 + 1] && letters[j2 + 1].match(/\W/)) {
3465
- setArg(letters[j2], next);
3469
+ if (letters[j + 1] && letters[j + 1].match(/\W/)) {
3470
+ setArg(letters[j], next);
3466
3471
  broken = true;
3467
3472
  break;
3468
3473
  } else {
3469
- setArg(letters[j2], defaultValue(letters[j2]));
3474
+ setArg(letters[j], defaultValue(letters[j]));
3470
3475
  }
3471
3476
  }
3472
3477
  key = arg.slice(-1)[0];
@@ -3928,13 +3933,13 @@ var YargsParser = class {
3928
3933
  let hasAllFlags = true;
3929
3934
  let next;
3930
3935
  const letters = arg.slice(1).split("");
3931
- for (let j2 = 0; j2 < letters.length; j2++) {
3932
- next = arg.slice(j2 + 2);
3933
- if (!hasAnyFlag(letters[j2])) {
3936
+ for (let j = 0; j < letters.length; j++) {
3937
+ next = arg.slice(j + 2);
3938
+ if (!hasAnyFlag(letters[j])) {
3934
3939
  hasAllFlags = false;
3935
3940
  break;
3936
3941
  }
3937
- if (letters[j2 + 1] && letters[j2 + 1] === "=" || next === "-" || /[A-Za-z]/.test(letters[j2]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next) || letters[j2 + 1] && letters[j2 + 1].match(/\W/)) {
3942
+ if (letters[j + 1] && letters[j + 1] === "=" || next === "-" || /[A-Za-z]/.test(letters[j]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next) || letters[j + 1] && letters[j + 1].match(/\W/)) {
3938
3943
  break;
3939
3944
  }
3940
3945
  }
@@ -5710,16 +5715,16 @@ function levenshtein(a, b) {
5710
5715
  for (i = 0; i <= b.length; i++) {
5711
5716
  matrix[i] = [i];
5712
5717
  }
5713
- let j2;
5714
- for (j2 = 0; j2 <= a.length; j2++) {
5715
- matrix[0][j2] = j2;
5718
+ let j;
5719
+ for (j = 0; j <= a.length; j++) {
5720
+ matrix[0][j] = j;
5716
5721
  }
5717
5722
  for (i = 1; i <= b.length; i++) {
5718
- for (j2 = 1; j2 <= a.length; j2++) {
5719
- if (b.charAt(i - 1) === a.charAt(j2 - 1)) {
5720
- matrix[i][j2] = matrix[i - 1][j2 - 1];
5723
+ for (j = 1; j <= a.length; j++) {
5724
+ if (b.charAt(i - 1) === a.charAt(j - 1)) {
5725
+ matrix[i][j] = matrix[i - 1][j - 1];
5721
5726
  } else {
5722
- matrix[i][j2] = Math.min(matrix[i - 1][j2 - 1] + 1, Math.min(matrix[i][j2 - 1] + 1, matrix[i - 1][j2] + 1));
5727
+ matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, Math.min(matrix[i][j - 1] + 1, matrix[i - 1][j] + 1));
5723
5728
  }
5724
5729
  }
5725
5730
  }
@@ -7709,7 +7714,7 @@ async function handleGenerateArazzo({
7709
7714
  config: config3
7710
7715
  };
7711
7716
  try {
7712
- const { generate } = await import("./chunks/W5R2GYDZ.js");
7717
+ const { generate } = await import("./chunks/VMHXZFTB.js");
7713
7718
  logger.info(gray("\n Generating Arazzo description... \n"));
7714
7719
  const generatedArazzo = await generate(options);
7715
7720
  writeFileSync2(outputFile, stringifyYaml(generatedArazzo));
@@ -8026,30 +8031,6 @@ function collectExternalDocs({
8026
8031
  }
8027
8032
  }
8028
8033
 
8029
- // src/commands/split/oas/constants.ts
8030
- var OPENAPI3_METHOD_NAMES = [
8031
- "get",
8032
- "put",
8033
- "post",
8034
- "delete",
8035
- "options",
8036
- "head",
8037
- "patch",
8038
- "trace",
8039
- "query"
8040
- ];
8041
- var OPENAPI3_COMPONENT_NAMES = [
8042
- "schemas",
8043
- "responses",
8044
- "parameters",
8045
- "examples",
8046
- "headers",
8047
- "requestBodies",
8048
- "links",
8049
- "callbacks",
8050
- "securitySchemes"
8051
- ];
8052
-
8053
8034
  // src/commands/join/utils/collect-paths.ts
8054
8035
  function collectPaths({
8055
8036
  joinedDef,
@@ -8092,7 +8073,7 @@ function collectPaths({
8092
8073
  if (field === "parameters") {
8093
8074
  collectPathParameters(pathItem, path28);
8094
8075
  }
8095
- if (typeof pathItem[field] === "string") {
8076
+ if (typeof pathItem[field] === "string" || field.startsWith("x-")) {
8096
8077
  collectPathStringFields(pathItem, path28, field);
8097
8078
  }
8098
8079
  }
@@ -8100,7 +8081,7 @@ function collectPaths({
8100
8081
  }
8101
8082
  function collectPathStringFields(pathItem, path28, field) {
8102
8083
  const fieldValue = pathItem[field];
8103
- if (joinedDef.paths[path28].hasOwnProperty(field) && joinedDef.paths[path28][field] !== fieldValue) {
8084
+ if (joinedDef.paths[path28].hasOwnProperty(field) && !dequal(joinedDef.paths[path28][field], fieldValue)) {
8104
8085
  logger.warn(`warning: different ${field} values in ${path28}
8105
8086
  `);
8106
8087
  return;
@@ -9185,7 +9166,7 @@ async function handleRespect({
9185
9166
  let mtlsCerts;
9186
9167
  let harLogs;
9187
9168
  try {
9188
- const { run, conditionallyMaskSecrets: conditionallyMaskSecrets2 } = await import("./chunks/W5R2GYDZ.js");
9169
+ const { run, conditionallyMaskSecrets: conditionallyMaskSecrets2 } = await import("./chunks/VMHXZFTB.js");
9189
9170
  const workingDir = config3.configPath ? dirname4(config3.configPath) : process.cwd();
9190
9171
  if (argv.mtls) {
9191
9172
  mtlsCerts = resolveMtlsCertificates(argv.mtls, workingDir);
@@ -10064,9 +10045,9 @@ function computeDependencyDepths(operations) {
10064
10045
  if (ops.size < 2) continue;
10065
10046
  const opArray = Array.from(ops);
10066
10047
  for (let i = 0; i < opArray.length; i++) {
10067
- for (let j2 = i + 1; j2 < opArray.length; j2++) {
10068
- adjacency.get(opArray[i]).add(opArray[j2]);
10069
- adjacency.get(opArray[j2]).add(opArray[i]);
10048
+ for (let j = i + 1; j < opArray.length; j++) {
10049
+ adjacency.get(opArray[i]).add(opArray[j]);
10050
+ adjacency.get(opArray[j]).add(opArray[i]);
10070
10051
  }
10071
10052
  }
10072
10053
  }
@@ -12070,50 +12051,6 @@ Launching translate using NPX.
12070
12051
  });
12071
12052
  };
12072
12053
 
12073
- // src/utils/spinner.ts
12074
- import * as process4 from "node:process";
12075
- var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
12076
- var Spinner = class {
12077
- frames;
12078
- currentFrame;
12079
- intervalId;
12080
- message;
12081
- constructor() {
12082
- this.frames = SPINNER_FRAMES;
12083
- this.currentFrame = 0;
12084
- this.intervalId = null;
12085
- this.message = "";
12086
- }
12087
- showFrame() {
12088
- logger.info("\r" + this.frames[this.currentFrame] + " " + this.message);
12089
- this.currentFrame = (this.currentFrame + 1) % this.frames.length;
12090
- }
12091
- start(message) {
12092
- if (this.message === message) {
12093
- return;
12094
- }
12095
- this.message = message;
12096
- if (!process4.stderr.isTTY) {
12097
- logger.info(`${message}...
12098
- `);
12099
- return;
12100
- }
12101
- if (this.intervalId === null) {
12102
- this.intervalId = setInterval(() => {
12103
- this.showFrame();
12104
- }, 100);
12105
- }
12106
- }
12107
- stop() {
12108
- if (this.intervalId !== null) {
12109
- clearInterval(this.intervalId);
12110
- this.intervalId = null;
12111
- logger.info("\r");
12112
- }
12113
- this.message = "";
12114
- }
12115
- };
12116
-
12117
12054
  // src/reunite/utils.ts
12118
12055
  var DeploymentError = class extends Error {
12119
12056
  };
@@ -12555,11 +12492,11 @@ var import_semver = __toESM(require_semver2(), 1);
12555
12492
  import { existsSync as existsSync7, writeFileSync as writeFileSync5, readFileSync as readFileSync7, statSync as statSync5 } from "node:fs";
12556
12493
  import { tmpdir } from "node:os";
12557
12494
  import { join as join13 } from "node:path";
12558
- import * as process5 from "node:process";
12495
+ import * as process4 from "node:process";
12559
12496
  var VERSION_CACHE_FILE = "redocly-cli-version";
12560
12497
  var SPACE_TO_BORDER = 4;
12561
12498
  var INTERVAL_TO_CHECK = 1e3 * 60 * 60 * 12;
12562
- var SHOULD_NOT_NOTIFY = process5.env.NODE_ENV === "test" || process5.env.CI || !!process5.env.LAMBDA_TASK_ROOT || process5.env.REDOCLY_SUPPRESS_UPDATE_NOTICE === "true";
12499
+ var SHOULD_NOT_NOTIFY = process4.env.NODE_ENV === "test" || process4.env.CI || !!process4.env.LAMBDA_TASK_ROOT || process4.env.REDOCLY_SUPPRESS_UPDATE_NOTICE === "true";
12563
12500
  var notifyUpdateCliVersion = () => {
12564
12501
  if (SHOULD_NOT_NOTIFY) {
12565
12502
  return;
@@ -12705,7 +12642,7 @@ async function sendTelemetry({
12705
12642
  $0: _,
12706
12643
  ...args
12707
12644
  } = argv;
12708
- const { RedoclyOAuthClient: RedoclyOAuthClient2 } = await import("./chunks/V6CVT3XE.js");
12645
+ const { RedoclyOAuthClient: RedoclyOAuthClient2 } = await import("./chunks/SZLWDHZK.js");
12709
12646
  const oauthClient = new RedoclyOAuthClient2();
12710
12647
  const reuniteUrl = getReuniteUrl(config3, args.residency);
12711
12648
  const logged_in = await oauthClient.isAuthorized(reuniteUrl);
@@ -12717,11 +12654,11 @@ async function sendTelemetry({
12717
12654
  const majorSpecVersion = getMajorSpecVersion(spec_version);
12718
12655
  const eventData = [
12719
12656
  {
12720
- id: "cli-command-run",
12657
+ id: command2,
12721
12658
  object: "command",
12722
- uri: "urn:redocly:cli",
12659
+ uri: `urn:redocly:cli:command:${command2}`,
12723
12660
  logged_in: logged_in ? "yes" : "no",
12724
- command: `${command2}`,
12661
+ command: command2,
12725
12662
  ...cleanArgs(args, process.argv.slice(2)),
12726
12663
  node_version: process.version,
12727
12664
  npm_version: execSync("npm -v").toString().replace("\n", ""),
@@ -12740,9 +12677,9 @@ async function sendTelemetry({
12740
12677
  respect_criterion_object_types: majorSpecVersion === "arazzo1" && respect_criterion_object_types?.length ? JSON.stringify(respect_criterion_object_types) : void 0
12741
12678
  }
12742
12679
  ];
12743
- const cloudEvent = j.mapToCloudEvent({
12680
+ const cloudEvent = E.mapToCloudEvent({
12744
12681
  type: "com.redocly.command.ran",
12745
- source: "com.redocly.cli",
12682
+ source: "urn:redocly:cli",
12746
12683
  origin: "redocly-cli",
12747
12684
  osPlatform: os.platform(),
12748
12685
  actor: {
@@ -12753,7 +12690,7 @@ async function sendTelemetry({
12753
12690
  category: "product",
12754
12691
  data: eventData
12755
12692
  });
12756
- const { otelTelemetry } = await import("./chunks/C3PXBQU5.js");
12693
+ const { otelTelemetry } = await import("./chunks/5YSNZVUA.js");
12757
12694
  otelTelemetry.send(cloudEvent);
12758
12695
  } catch (err) {
12759
12696
  }
@@ -13583,7 +13520,7 @@ yargs_default(hideBin(process.argv)).version("version", "Show version number.",
13583
13520
  return true;
13584
13521
  }),
13585
13522
  async (argv) => {
13586
- const { handlerBuildCommand } = await import("./chunks/V74PIVJZ.js");
13523
+ const { handlerBuildCommand } = await import("./chunks/7H6CC6CT.js");
13587
13524
  commandWrapper(handlerBuildCommand)(argv);
13588
13525
  }
13589
13526
  ).command(
@@ -13744,6 +13681,69 @@ yargs_default(hideBin(process.argv)).version("version", "Show version number.",
13744
13681
  async (argv) => {
13745
13682
  commandWrapper(handleGenerateArazzo)(argv);
13746
13683
  }
13684
+ ).command(
13685
+ "generate-spec <traffic>",
13686
+ "Infer an OpenAPI description from recorded HTTP traffic, optionally refined with AI [experimental].",
13687
+ (yargs) => yargs.env("REDOCLY_CLI_GENERATE_SPEC").positional("traffic", {
13688
+ describe: "Path to a traffic log file or folder (HAR, Kong, Nginx/Apache JSON, NDJSON).",
13689
+ type: "string"
13690
+ }).option({
13691
+ type: {
13692
+ describe: "Target API description type.",
13693
+ choices: ["openapi"],
13694
+ default: "openapi"
13695
+ },
13696
+ "traffic-format": {
13697
+ describe: "Traffic input format.",
13698
+ choices: [
13699
+ "auto",
13700
+ "har",
13701
+ "kong",
13702
+ "nginx-json",
13703
+ "apache-json",
13704
+ "ndjson"
13705
+ ],
13706
+ default: "auto"
13707
+ },
13708
+ server: {
13709
+ describe: "Server URL the traffic was captured against: only requests under it are considered, the rest of their URL becomes the API path, and it becomes the servers URL of the generated description.",
13710
+ type: "string"
13711
+ },
13712
+ title: {
13713
+ describe: "Title for the generated API description.",
13714
+ type: "string"
13715
+ },
13716
+ "with-ai": {
13717
+ describe: "Refine the inferred description with an AI provider to narrow the hypothesis.",
13718
+ type: "boolean",
13719
+ default: false
13720
+ },
13721
+ "ai-provider": {
13722
+ describe: 'AI provider used with --with-ai; runs the "claude", "codex", or "cursor" CLI in non-interactive mode.',
13723
+ choices: ["claude", "codex", "cursor"],
13724
+ default: "claude"
13725
+ },
13726
+ "ai-model": {
13727
+ describe: "Model passed to the selected AI provider (provider-specific default applies).",
13728
+ type: "string"
13729
+ },
13730
+ "ai-concurrency": {
13731
+ describe: "Number of operations refined in parallel with --with-ai.",
13732
+ type: "number",
13733
+ default: 4,
13734
+ coerce: validatePositiveNumber("ai-concurrency", true)
13735
+ },
13736
+ output: {
13737
+ alias: "o",
13738
+ describe: "Write the generated description to this file instead of stdout.",
13739
+ type: "string"
13740
+ },
13741
+ config: { describe: "Path to the config file.", type: "string" }
13742
+ }),
13743
+ async (argv) => {
13744
+ const { handleGenerateSpec } = await import("./chunks/PFPGSTSG.js");
13745
+ commandWrapper(handleGenerateSpec)(argv);
13746
+ }
13747
13747
  ).command(
13748
13748
  "scorecard-classic [api]",
13749
13749
  "Run quality scorecards with multiple rule levels to validate and maintain API description standards.",
@@ -13821,6 +13821,10 @@ yargs_default(hideBin(process.argv)).version("version", "Show version number.",
13821
13821
  type: "boolean",
13822
13822
  default: false
13823
13823
  },
13824
+ "ignore-headers": {
13825
+ describe: 'Comma-separated header names to skip in undocumented-header checks. A trailing "*" matches by prefix, e.g. "x-consumer-*".',
13826
+ type: "string"
13827
+ },
13824
13828
  "max-findings": {
13825
13829
  describe: "Maximum findings shown in pretty output.",
13826
13830
  type: "number",
@@ -13852,7 +13856,7 @@ yargs_default(hideBin(process.argv)).version("version", "Show version number.",
13852
13856
  }
13853
13857
  }),
13854
13858
  async (argv) => {
13855
- const { handleDrift } = await import("./chunks/C5HID4LT.js");
13859
+ const { handleDrift } = await import("./chunks/HQDT5XFP.js");
13856
13860
  commandWrapper(handleDrift)(argv);
13857
13861
  }
13858
13862
  ).command(
@@ -13899,6 +13903,10 @@ yargs_default(hideBin(process.argv)).version("version", "Show version number.",
13899
13903
  type: "boolean",
13900
13904
  default: false
13901
13905
  },
13906
+ "ignore-headers": {
13907
+ describe: 'Comma-separated header names to skip in undocumented-header checks. A trailing "*" matches by prefix, e.g. "x-consumer-*".',
13908
+ type: "string"
13909
+ },
13902
13910
  "max-findings": {
13903
13911
  describe: "Maximum findings shown in pretty output.",
13904
13912
  type: "number",
@@ -13916,7 +13924,7 @@ yargs_default(hideBin(process.argv)).version("version", "Show version number.",
13916
13924
  }
13917
13925
  }),
13918
13926
  async (argv) => {
13919
- const { handleProxy } = await import("./chunks/BNHQNMUG.js");
13927
+ const { handleProxy } = await import("./chunks/GOFLD5MJ.js");
13920
13928
  commandWrapper(handleProxy)(argv);
13921
13929
  }
13922
13930
  ).completion("completion", "Generate autocomplete script for `redocly` command.").demandCommand(1).middleware([notifyUpdateCliVersion]).strict().argv;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/cli",
3
- "version": "2.39.0",
3
+ "version": "2.41.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "type": "module",