@fern-api/fern-api-dev 4.72.0-1-g2825b1479c3 → 4.72.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.
Files changed (2) hide show
  1. package/cli.cjs +61 -206
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -621394,7 +621394,7 @@ var AccessTokenPosthogManager = class {
621394
621394
  properties: {
621395
621395
  ...event,
621396
621396
  ...event.properties,
621397
- version: "4.72.0-1-g2825b1479c3",
621397
+ version: "4.72.0",
621398
621398
  usingAccessToken: true
621399
621399
  }
621400
621400
  });
@@ -621448,7 +621448,7 @@ var UserPosthogManager = class {
621448
621448
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
621449
621449
  event: "CLI",
621450
621450
  properties: {
621451
- version: "4.72.0-1-g2825b1479c3",
621451
+ version: "4.72.0",
621452
621452
  ...event,
621453
621453
  ...event.properties,
621454
621454
  usingAccessToken: false,
@@ -624684,8 +624684,7 @@ var YamlConfigLoader = class {
624684
624684
  data: parseResult.data,
624685
624685
  sourced: sourceResolver.toSourced(parseResult.data),
624686
624686
  absoluteFilePath,
624687
- relativeFilePath: RelativeFilePath2.of(relative4(this.cwd, absoluteFilePath)),
624688
- pathMappings: resolved.pathMappings
624687
+ relativeFilePath: RelativeFilePath2.of(relative4(this.cwd, absoluteFilePath))
624689
624688
  };
624690
624689
  }
624691
624690
  async parseDocument(absoluteFilePath) {
@@ -624748,17 +624747,6 @@ var YamlConfigLoader = class {
624748
624747
  case "unrecognized_keys":
624749
624748
  return `unknown key(s): ${issue2.keys.join(", ")}`;
624750
624749
  case "invalid_union": {
624751
- const unknownKeys = [];
624752
- for (const errorGroup of issue2.errors) {
624753
- for (const err of errorGroup) {
624754
- if (err.code === "unrecognized_keys") {
624755
- unknownKeys.push(...err.keys);
624756
- }
624757
- }
624758
- }
624759
- if (unknownKeys.length > 0) {
624760
- return `unknown key(s): ${[...new Set(unknownKeys)].join(", ")}`;
624761
- }
624762
624750
  const expectedTypes = /* @__PURE__ */ new Set();
624763
624751
  for (const errorGroup of issue2.errors) {
624764
624752
  for (const err of errorGroup) {
@@ -625087,7 +625075,7 @@ var ApiDefinitionConverter = class {
625087
625075
  let result = {};
625088
625076
  if (api != null && !isNullish2(sourced.api)) {
625089
625077
  result = await this.convertApi({
625090
- absoluteFernYmlPath: this.resolveBasePathForKey("api", fernYml),
625078
+ absoluteFernYmlPath: fernYml.absoluteFilePath,
625091
625079
  api,
625092
625080
  sourcedApi: sourced.api
625093
625081
  });
@@ -625095,7 +625083,6 @@ var ApiDefinitionConverter = class {
625095
625083
  if (apis != null && !isNullish2(sourced.apis)) {
625096
625084
  result = await this.convertApis({
625097
625085
  absoluteFernYmlPath: fernYml.absoluteFilePath,
625098
- pathMappings: fernYml.pathMappings,
625099
625086
  apis,
625100
625087
  sourcedApis: sourced.apis
625101
625088
  });
@@ -625133,15 +625120,14 @@ var ApiDefinitionConverter = class {
625133
625120
  [DEFAULT_API_NAME]: apiDefinition
625134
625121
  };
625135
625122
  }
625136
- async convertApis({ absoluteFernYmlPath, pathMappings, apis, sourcedApis }) {
625123
+ async convertApis({ absoluteFernYmlPath, apis, sourcedApis }) {
625137
625124
  if (isNullish2(sourcedApis)) {
625138
625125
  return {};
625139
625126
  }
625140
625127
  const apiEntries = Object.entries(apis).filter(([apiName]) => !isNullish2(sourcedApis[apiName])).map(([apiName, apiDef]) => ({ apiName, apiDef, sourcedApiDef: sourcedApis[apiName] })).filter((entry) => !isNullish2(entry.sourcedApiDef));
625141
625128
  const convertedEntries = await Promise.all(apiEntries.map(async ({ apiName, apiDef, sourcedApiDef }) => {
625142
- const entryBasePath = this.findBasePathInMappings(["apis", apiName], pathMappings) ?? this.findBasePathInMappings(["apis"], pathMappings) ?? absoluteFernYmlPath;
625143
625129
  const specs = await this.convertSpecs({
625144
- absoluteFernYmlPath: entryBasePath,
625130
+ absoluteFernYmlPath,
625145
625131
  specs: apiDef.specs,
625146
625132
  sourced: sourcedApiDef.specs
625147
625133
  });
@@ -625437,33 +625423,9 @@ var ApiDefinitionConverter = class {
625437
625423
  }
625438
625424
  }
625439
625425
  }
625440
- /**
625441
- * Returns the file path of the document that provided the content at the
625442
- * given YAML path prefix (via a `$ref`), or `undefined` if no mapping matches.
625443
- *
625444
- * Used to resolve spec paths relative to the correct source file when a
625445
- * config section (e.g. `api`, `apis`, `apis.my-api`) was loaded via `$ref`.
625446
- */
625447
- findBasePathInMappings(yamlPath, pathMappings) {
625448
- for (const mapping of pathMappings) {
625449
- if (mapping.yamlPath.length === yamlPath.length && yamlPath.every((seg, i11) => seg === mapping.yamlPath[i11])) {
625450
- return mapping.document.absoluteFilePath;
625451
- }
625452
- }
625453
- return void 0;
625454
- }
625455
- /**
625456
- * Returns the base file path to use for resolving paths in the given top-level
625457
- * key (e.g. "api"). If the key was `$ref`'d, returns the path of the referenced
625458
- * file; otherwise falls back to the fern.yml path.
625459
- */
625460
- resolveBasePathForKey(key2, fernYml) {
625461
- return this.findBasePathInMappings([key2], fernYml.pathMappings) ?? fernYml.absoluteFilePath;
625462
- }
625463
625426
  };
625464
625427
 
625465
625428
  // ../cli-v2/lib/docs/config/converter/DocsConfigConverter.js
625466
- var DOCS_YAML_PATH = "docs";
625467
625429
  var DocsConfigConverter = class {
625468
625430
  issues = [];
625469
625431
  convert({ fernYml }) {
@@ -625475,13 +625437,10 @@ var DocsConfigConverter = class {
625475
625437
  if (this.issues.length > 0) {
625476
625438
  return { success: false, issues: this.issues };
625477
625439
  }
625478
- const docsPathMapping = fernYml.pathMappings.find((m11) => m11.yamlPath.length === 1 && m11.yamlPath[0] === DOCS_YAML_PATH);
625479
- const absoluteFilePath = docsPathMapping != null ? docsPathMapping.document.absoluteFilePath : fernYml.absoluteFilePath;
625480
625440
  return {
625481
625441
  success: true,
625482
625442
  config: {
625483
- raw: docs,
625484
- absoluteFilePath
625443
+ raw: docs
625485
625444
  }
625486
625445
  };
625487
625446
  }
@@ -753773,13 +753732,8 @@ var IrCompiler = class {
753773
753732
  var CompileCommand = class {
753774
753733
  async handle(context3, args) {
753775
753734
  const workspace = await context3.loadWorkspaceOrThrow();
753776
- const entries23 = this.resolveApiEntries(args, workspace);
753777
- if (args.output != null && entries23.length > 1) {
753778
- throw new CliError({
753779
- message: `--output requires --api when multiple APIs are configured`,
753780
- code: CliError.Code.ConfigError
753781
- });
753782
- }
753735
+ const { apiName, definition: definition3 } = this.resolveApi(args, workspace);
753736
+ await this.checkOrThrow({ context: context3, workspace, apiName });
753783
753737
  const compiler2 = new IrCompiler({
753784
753738
  context: context3,
753785
753739
  cliVersion: workspace.cliVersion
@@ -753791,35 +753745,43 @@ var CompileCommand = class {
753791
753745
  disableExamples: args["disable-examples"],
753792
753746
  irVersion: args["ir-version"]
753793
753747
  };
753794
- for (const { apiName, definition: definition3 } of entries23) {
753795
- await this.checkOrThrow({ context: context3, workspace, apiName });
753796
- const result = args.dynamic ? await compiler2.compileDynamic({ apiName, definition: definition3, options: options2 }) : await compiler2.compile({ apiName, definition: definition3, options: options2 });
753797
- await this.writeOutput(context3, args, result.object);
753798
- }
753748
+ const result = args.dynamic ? await compiler2.compileDynamic({ apiName, definition: definition3, options: options2 }) : await compiler2.compile({ apiName, definition: definition3, options: options2 });
753749
+ await this.writeOutput(context3, args, result.object);
753799
753750
  }
753800
- /**
753801
- * Resolves the set of APIs to compile.
753802
- *
753803
- * - If `--api` is provided, returns only that API (throws if not found).
753804
- * - Otherwise returns all APIs in the workspace, matching the behavior of
753805
- * `check`, `merge`, and `split` which also run on all APIs by default.
753806
- */
753807
- resolveApiEntries(args, workspace) {
753808
- const allApiNames = Object.keys(workspace.apis);
753751
+ resolveApi(args, workspace) {
753752
+ const apiNames = Object.keys(workspace.apis);
753809
753753
  if (args.api != null) {
753810
753754
  const definition3 = workspace.apis[args.api];
753811
753755
  if (definition3 == null) {
753812
- const available = allApiNames.join(", ");
753756
+ const available2 = apiNames.join(", ");
753813
753757
  throw new CliError({
753814
- message: `API '${args.api}' not found. Available APIs: ${available}`,
753758
+ message: `API '${args.api}' not found. Available APIs: ${available2}`,
753815
753759
  code: CliError.Code.ConfigError
753816
753760
  });
753817
753761
  }
753818
- return [{ apiName: args.api, definition: definition3 }];
753762
+ return { apiName: args.api, definition: definition3 };
753819
753763
  }
753820
- return allApiNames.flatMap((apiName) => {
753764
+ if (apiNames.length === 1) {
753765
+ const apiName = apiNames[0];
753766
+ if (apiName == null) {
753767
+ throw new CliError({
753768
+ message: "Internal error; no APIs found in workspace",
753769
+ code: CliError.Code.InternalError
753770
+ });
753771
+ }
753821
753772
  const definition3 = workspace.apis[apiName];
753822
- return definition3 != null ? [{ apiName, definition: definition3 }] : [];
753773
+ if (definition3 == null) {
753774
+ throw new CliError({
753775
+ message: `Internal error; API '${apiName}' not found in workspace`,
753776
+ code: CliError.Code.InternalError
753777
+ });
753778
+ }
753779
+ return { apiName, definition: definition3 };
753780
+ }
753781
+ const available = apiNames.join(", ");
753782
+ throw new CliError({
753783
+ message: `Multiple APIs found: ${available}. Use --api to select one.`,
753784
+ code: CliError.Code.ConfigError
753823
753785
  });
753824
753786
  }
753825
753787
  async checkOrThrow({ context: context3, workspace, apiName }) {
@@ -834736,15 +834698,13 @@ async function runRulesOnDocsWorkspace({ workspace, rules: selectedRules, contex
834736
834698
  }
834737
834699
 
834738
834700
  // ../cli-v2/lib/docs/adapter/LegacyDocsWorkspaceAdapter.js
834739
- init_lib6();
834740
834701
  var LegacyDocsWorkspaceAdapter = class {
834741
834702
  adapt({ docsConfig, absoluteFilePath }) {
834742
- const docsFilePath = docsConfig.absoluteFilePath ?? absoluteFilePath;
834743
834703
  return {
834744
834704
  type: "docs",
834745
834705
  workspaceName: void 0,
834746
- absoluteFilePath: dirname6(docsFilePath),
834747
- absoluteFilepathToDocsConfig: docsFilePath,
834706
+ absoluteFilePath,
834707
+ absoluteFilepathToDocsConfig: absoluteFilePath,
834748
834708
  config: docsConfig.raw
834749
834709
  };
834750
834710
  }
@@ -834761,9 +834721,9 @@ var LegacyProjectAdapter = class {
834761
834721
  }
834762
834722
  adapt(workspace) {
834763
834723
  const apiWorkspaces = this.buildApiWorkspaces(workspace);
834764
- const docsWorkspace = workspace.docs != null ? this.docsAdapter.adapt({
834724
+ const docsWorkspace = workspace.docs != null && workspace.absoluteFilePath != null ? this.docsAdapter.adapt({
834765
834725
  docsConfig: workspace.docs,
834766
- absoluteFilePath: workspace.docs.absoluteFilePath ?? workspace.absoluteFilePath ?? this.context.cwd
834726
+ absoluteFilePath: workspace.absoluteFilePath
834767
834727
  }) : void 0;
834768
834728
  return {
834769
834729
  config: {
@@ -838658,7 +838618,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
838658
838618
  var LOGS_FOLDER_NAME = "logs";
838659
838619
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
838660
838620
  function getCliSource() {
838661
- const version7 = "4.72.0-1-g2825b1479c3";
838621
+ const version7 = "4.72.0";
838662
838622
  return `cli@${version7}`;
838663
838623
  }
838664
838624
  var DebugLogger = class {
@@ -849905,7 +849865,7 @@ var LegacyDocsPublisher = class {
849905
849865
  previewId,
849906
849866
  disableTemplates: void 0,
849907
849867
  skipUpload,
849908
- cliVersion: "4.72.0-1-g2825b1479c3"
849868
+ cliVersion: "4.72.0"
849909
849869
  });
849910
849870
  if (taskContext.getResult() === TaskResult.Failure) {
849911
849871
  return { success: false };
@@ -850474,36 +850434,6 @@ var DocsTaskGroup = class {
850474
850434
  }
850475
850435
  };
850476
850436
 
850477
- // ../cli-v2/lib/ui/promptSelect.js
850478
- async function promptSelect({ isTTY, message, choices, nonInteractiveError, flagHint }) {
850479
- if (choices.length === 0) {
850480
- throw new CliError({
850481
- message: "No options available to select from.",
850482
- code: CliError.Code.InternalError
850483
- });
850484
- }
850485
- if (!isTTY) {
850486
- throw new CliError({ message: nonInteractiveError, code: CliError.Code.ConfigError });
850487
- }
850488
- const maxNameLen = Math.max(...choices.map((c16) => c16.name.length));
850489
- const { selected } = await lib_default4.prompt([
850490
- {
850491
- type: "list",
850492
- name: "selected",
850493
- message,
850494
- choices: choices.map((c16) => {
850495
- if (flagHint == null) {
850496
- return { name: c16.name, value: c16.value };
850497
- }
850498
- const hint = flagHint(c16.value);
850499
- const label = hint != null ? `${c16.name.padEnd(maxNameLen)} ${source_default.dim(hint)}` : c16.name;
850500
- return { name: label, value: c16.value };
850501
- })
850502
- }
850503
- ]);
850504
- return selected;
850505
- }
850506
-
850507
850437
  // ../cli-v2/lib/commands/docs/publish/command.js
850508
850438
  var PublishCommand = class {
850509
850439
  async handle(context3, args) {
@@ -850532,8 +850462,7 @@ var PublishCommand = class {
850532
850462
  code: CliError.Code.ConfigError
850533
850463
  });
850534
850464
  }
850535
- const instanceUrl = await this.resolveInstanceUrl({
850536
- context: context3,
850465
+ const instanceUrl = this.resolveInstanceUrl({
850537
850466
  instances: workspace.docs.raw.instances,
850538
850467
  instance: args.instance
850539
850468
  });
@@ -850615,7 +850544,7 @@ var PublishCommand = class {
850615
850544
  throw new CliError({ code: CliError.Code.ContainerError });
850616
850545
  }
850617
850546
  }
850618
- async resolveInstanceUrl({ context: context3, instances: instances2, instance }) {
850547
+ resolveInstanceUrl({ instances: instances2, instance }) {
850619
850548
  if (instances2.length === 0) {
850620
850549
  throw new CliError({
850621
850550
  message: "No docs instances configured.\n\n Add an instance to the 'docs:' section of your fern.yml.",
@@ -850640,17 +850569,14 @@ ${available}
850640
850569
  }
850641
850570
  if (instances2.length > 1) {
850642
850571
  const available = instances2.map((i11) => ` - ${i11.url}`).join("\n");
850643
- return await promptSelect({
850644
- isTTY: context3.isTTY,
850645
- message: "Multiple docs instances configured. Select one:",
850646
- choices: instances2.map((i11) => ({ name: i11.url, value: i11.url })),
850647
- nonInteractiveError: `Multiple docs instances configured. Please specify which instance to publish.
850572
+ throw new CliError({
850573
+ message: `Multiple docs instances configured. Please specify which instance to publish.
850648
850574
 
850649
850575
  Available instances:
850650
850576
  ${available}
850651
850577
 
850652
850578
  Use --instance <url> to select one.`,
850653
- flagHint: (value) => `--instance ${value}`
850579
+ code: CliError.Code.ConfigError
850654
850580
  });
850655
850581
  }
850656
850582
  const first3 = instances2[0];
@@ -904111,8 +904037,7 @@ var GenerateCommand = class {
904111
904037
  org: args.org
904112
904038
  };
904113
904039
  }
904114
- const targets2 = await this.getTargets({
904115
- context: context3,
904040
+ const targets2 = this.getTargets({
904116
904041
  workspace: workspaceWithOverrides,
904117
904042
  args,
904118
904043
  groupName: args.target != null ? void 0 : args.group ?? workspaceWithOverrides.sdks?.defaultGroup
@@ -904145,13 +904070,10 @@ var GenerateCommand = class {
904145
904070
  code: CliError.Code.ConfigError
904146
904071
  });
904147
904072
  }
904148
- if (args.api == null || args.target == null || args.org == null || args.output == null) {
904149
- throw new CliError({
904150
- message: "Internal error: required flags missing",
904151
- code: CliError.Code.InternalError
904152
- });
904153
- }
904154
- const { api, target, org, output: output2 } = args;
904073
+ const api = args.api;
904074
+ const target = args.target;
904075
+ const org = args.org;
904076
+ const output2 = args.output;
904155
904077
  const resolver2 = new ApiSpecResolver({ context: context3 });
904156
904078
  const resolvedSpec = await resolver2.resolve({
904157
904079
  reference: api
@@ -904400,70 +904322,19 @@ Example:
904400
904322
  }
904401
904323
  return { path: args.output };
904402
904324
  }
904403
- async getTargets({ context: context3, workspace, args, groupName }) {
904325
+ getTargets({ workspace, args, groupName }) {
904404
904326
  let matched = workspace.sdks != null ? this.filterTargetsByGroup(workspace.sdks.targets, groupName) : [];
904405
904327
  if (args.target != null) {
904406
904328
  matched = matched.filter((t3) => t3.name === args.target);
904407
904329
  if (matched.length === 0) {
904408
- const allTargets = workspace.sdks?.targets ?? [];
904409
- const available = allTargets.map((t3) => t3.name);
904410
- if (available.length > 0) {
904411
- throw new CliError({
904412
- message: `Target '${args.target}' not found. Available targets: ${available.join(", ")}`,
904413
- code: CliError.Code.ConfigError
904414
- });
904415
- } else {
904416
- throw new CliError({
904417
- message: `Target '${args.target}' not found`,
904418
- code: CliError.Code.ConfigError
904419
- });
904420
- }
904330
+ throw new Error(`Target '${args.target}' not found`);
904421
904331
  }
904422
904332
  }
904423
904333
  if (matched.length === 0) {
904424
904334
  if (groupName != null) {
904425
- throw new CliError({
904426
- message: `No targets found for group '${groupName}'`,
904427
- code: CliError.Code.ConfigError
904428
- });
904429
- }
904430
- throw new CliError({
904431
- message: "No targets configured in fern.yml",
904432
- code: CliError.Code.ConfigError
904433
- });
904434
- }
904435
- if (groupName == null && args.target == null && matched.length > 1) {
904436
- const allGroups = this.collectGroups(matched);
904437
- if (allGroups.length > 1) {
904438
- const selectedGroup = await promptSelect({
904439
- isTTY: context3.isTTY,
904440
- message: "Multiple SDK groups found. Select one:",
904441
- choices: [
904442
- { name: `all (${matched.length} targets)`, value: void 0 },
904443
- ...allGroups.map((g19) => ({ name: g19, value: g19 }))
904444
- ],
904445
- nonInteractiveError: `Multiple SDK groups found: ${allGroups.join(", ")}. Use --group to select one.`,
904446
- flagHint: (value) => value != null ? `--group ${value}` : void 0
904447
- });
904448
- if (selectedGroup != null) {
904449
- matched = this.filterTargetsByGroup(matched, selectedGroup);
904450
- }
904451
- } else {
904452
- const targetNames = matched.map((t3) => t3.name);
904453
- const selectedTarget = await promptSelect({
904454
- isTTY: context3.isTTY,
904455
- message: "Multiple SDK targets found. Select one:",
904456
- choices: [
904457
- { name: `all (${matched.length} targets)`, value: void 0 },
904458
- ...targetNames.map((name2) => ({ name: name2, value: name2 }))
904459
- ],
904460
- nonInteractiveError: `Multiple SDK targets found: ${targetNames.join(", ")}. Use --target to select one.`,
904461
- flagHint: (value) => value != null ? `--target ${value}` : void 0
904462
- });
904463
- if (selectedTarget != null) {
904464
- matched = matched.filter((t3) => t3.name === selectedTarget);
904465
- }
904335
+ throw new Error(`No targets found for group '${groupName}'`);
904466
904336
  }
904337
+ throw new Error("No targets configured in fern.yml");
904467
904338
  }
904468
904339
  return matched.map((target) => ({
904469
904340
  ...target,
@@ -904471,17 +904342,6 @@ Example:
904471
904342
  output: args.output != null ? this.parseTargetOutput(args) : target.output
904472
904343
  }));
904473
904344
  }
904474
- collectGroups(targets2) {
904475
- const groups2 = /* @__PURE__ */ new Set();
904476
- for (const target of targets2) {
904477
- if (target.groups != null) {
904478
- for (const group of target.groups) {
904479
- groups2.add(group);
904480
- }
904481
- }
904482
- }
904483
- return [...groups2].sort();
904484
- }
904485
904345
  async checkOutputDirectory({ context: context3, args, outputPath }) {
904486
904346
  if (args.force || !context3.isTTY) {
904487
904347
  return { shouldProceed: true };
@@ -904511,13 +904371,11 @@ Example:
904511
904371
  return targets2.filter((target) => target.groups?.includes(groupName));
904512
904372
  }
904513
904373
  resolveLanguage(target) {
904514
- if (isLanguage(target)) {
904515
- return target;
904374
+ const lang = target;
904375
+ if (LANGUAGES.includes(lang)) {
904376
+ return lang;
904516
904377
  }
904517
- throw new CliError({
904518
- message: `"${target}" is not a supported language. Supported: ${LANGUAGES.join(", ")}`,
904519
- code: CliError.Code.ConfigError
904520
- });
904378
+ throw new Error(`"${target}" is not a supported language. Supported: ${LANGUAGES.join(", ")}`);
904521
904379
  }
904522
904380
  parseAudiences(audiences) {
904523
904381
  if (audiences == null || audiences.length === 0) {
@@ -904569,9 +904427,6 @@ Example:
904569
904427
  return text9.trimEnd().split("\n").map((line) => line.length > 0 ? ` ${line}` : line).join("\n");
904570
904428
  }
904571
904429
  };
904572
- function isLanguage(target) {
904573
- return LANGUAGES.includes(target);
904574
- }
904575
904430
  function addGenerateCommand(cli) {
904576
904431
  const cmd = new GenerateCommand();
904577
904432
  command2(cli, "generate", "Generate SDKs from fern.yml or directly from an API spec", async (context3, args) => {
@@ -924363,7 +924218,7 @@ var CliContext = class _CliContext {
924363
924218
  if (false) {
924364
924219
  this.logger.error("CLI_VERSION is not defined");
924365
924220
  }
924366
- return "4.72.0-1-g2825b1479c3";
924221
+ return "4.72.0";
924367
924222
  }
924368
924223
  getCliName() {
924369
924224
  if (false) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.72.0-1-g2825b1479c3",
2
+ "version": "4.72.0",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",