@fern-api/fern-api-dev 4.70.2 → 4.71.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 +179 -67
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -458829,14 +458829,14 @@ function _wrapSingleQueryHandle(query, sqlInstance, options2) {
458829
458829
  }
458830
458830
  const queryWithCallbacks = this;
458831
458831
  queryWithCallbacks.resolve = new Proxy(queryWithCallbacks.resolve, {
458832
- apply: (resolveTarget, resolveThisArg, resolveArgs) => {
458832
+ apply: (resolveTarget2, resolveThisArg, resolveArgs) => {
458833
458833
  try {
458834
458834
  _setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);
458835
458835
  span.end();
458836
458836
  } catch (e6) {
458837
458837
  DEBUG_BUILD && debug.error("Error ending span in resolve callback:", e6);
458838
458838
  }
458839
- return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);
458839
+ return Reflect.apply(resolveTarget2, resolveThisArg, resolveArgs);
458840
458840
  }
458841
458841
  });
458842
458842
  queryWithCallbacks.reject = new Proxy(queryWithCallbacks.reject, {
@@ -469534,14 +469534,14 @@ var PostgresJsInstrumentation = class extends InstrumentationBase {
469534
469534
  }
469535
469535
  const originalResolve = this.resolve;
469536
469536
  this.resolve = new Proxy(originalResolve, {
469537
- apply: (resolveTarget, resolveThisArg, resolveArgs) => {
469537
+ apply: (resolveTarget2, resolveThisArg, resolveArgs) => {
469538
469538
  try {
469539
469539
  self2._setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);
469540
469540
  span.end();
469541
469541
  } catch (e6) {
469542
469542
  DEBUG_BUILD4 && debug.error("Error ending span in resolve callback:", e6);
469543
469543
  }
469544
- return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);
469544
+ return Reflect.apply(resolveTarget2, resolveThisArg, resolveArgs);
469545
469545
  }
469546
469546
  });
469547
469547
  const originalReject = this.reject;
@@ -621039,7 +621039,7 @@ var AccessTokenPosthogManager = class {
621039
621039
  properties: {
621040
621040
  ...event,
621041
621041
  ...event.properties,
621042
- version: "4.70.2",
621042
+ version: "4.71.0",
621043
621043
  usingAccessToken: true
621044
621044
  }
621045
621045
  });
@@ -621093,7 +621093,7 @@ var UserPosthogManager = class {
621093
621093
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
621094
621094
  event: "CLI",
621095
621095
  properties: {
621096
- version: "4.70.2",
621096
+ version: "4.71.0",
621097
621097
  ...event,
621098
621098
  ...event.properties,
621099
621099
  usingAccessToken: false,
@@ -836457,6 +836457,46 @@ async function getPorts(options2) {
836457
836457
  throw new Error("No available ports found");
836458
836458
  }
836459
836459
 
836460
+ // ../docs-preview/lib/previewUrlUtils.js
836461
+ var PREVIEW_URL_PATTERN = /^[a-z0-9-]+-preview-[a-z0-9-]+\.docs\.buildwithfern\.com$/i;
836462
+ var DOMAIN_SUFFIX = "docs.buildwithfern.com";
836463
+ var SUBDOMAIN_LIMIT = 62;
836464
+ function isPreviewUrl(url3) {
836465
+ let hostname4 = url3.toLowerCase().trim();
836466
+ if (hostname4.startsWith("https://")) {
836467
+ hostname4 = hostname4.slice(8);
836468
+ } else if (hostname4.startsWith("http://")) {
836469
+ hostname4 = hostname4.slice(7);
836470
+ }
836471
+ const slashIndex = hostname4.indexOf("/");
836472
+ if (slashIndex !== -1) {
836473
+ hostname4 = hostname4.slice(0, slashIndex);
836474
+ }
836475
+ return PREVIEW_URL_PATTERN.test(hostname4);
836476
+ }
836477
+ function sanitizePreviewId(id2) {
836478
+ const sanitized = id2.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "");
836479
+ if (sanitized.length === 0) {
836480
+ return "default";
836481
+ }
836482
+ return sanitized;
836483
+ }
836484
+ function buildPreviewDomain({ orgId, previewId }) {
836485
+ const sanitizedId = sanitizePreviewId(previewId);
836486
+ const fullDomain = `${orgId}-preview-${sanitizedId}.${DOMAIN_SUFFIX}`;
836487
+ if (fullDomain.length <= SUBDOMAIN_LIMIT) {
836488
+ return fullDomain;
836489
+ }
836490
+ const prefix2 = `${orgId}-preview-`;
836491
+ const availableSpace = SUBDOMAIN_LIMIT - prefix2.length;
836492
+ const minIdLength = 8;
836493
+ if (availableSpace < minIdLength) {
836494
+ throw new Error(`Organization name "${orgId}" is too long to generate a valid preview URL`);
836495
+ }
836496
+ const truncatedId = sanitizedId.slice(0, availableSpace).replace(/-+$/, "");
836497
+ return `${prefix2}${truncatedId}.${DOMAIN_SUFFIX}`;
836498
+ }
836499
+
836460
836500
  // ../docs-preview/lib/runAppPreviewServer.js
836461
836501
  init_lib4();
836462
836502
  init_js();
@@ -838145,7 +838185,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
838145
838185
  var LOGS_FOLDER_NAME = "logs";
838146
838186
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
838147
838187
  function getCliSource() {
838148
- const version7 = "4.70.2";
838188
+ const version7 = "4.71.0";
838149
838189
  return `cli@${version7}`;
838150
838190
  }
838151
838191
  var DebugLogger = class {
@@ -848392,7 +848432,7 @@ async function asyncPool2(limit, items, fn5) {
848392
848432
  var MEASURE_IMAGE_BATCH_SIZE = 10;
848393
848433
  var UPLOAD_FILE_BATCH_SIZE = 10;
848394
848434
  var HASH_CONCURRENCY = parseInt(process.env.FERN_DOCS_ASSET_HASH_CONCURRENCY ?? "32", 10);
848395
- function sanitizePreviewId(id2) {
848435
+ function sanitizePreviewId2(id2) {
848396
848436
  const sanitized = id2.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "");
848397
848437
  if (sanitized.length === 0) {
848398
848438
  return "default";
@@ -848533,7 +848573,7 @@ async function publishDocs({ token, organization, docsWorkspace, domain: domain3
848533
848573
  filepaths,
848534
848574
  images,
848535
848575
  basePath,
848536
- previewId: previewId != null ? sanitizePreviewId(previewId) : void 0
848576
+ previewId: previewId != null ? sanitizePreviewId2(previewId) : void 0
848537
848577
  });
848538
848578
  if (startDocsRegisterResponse.ok) {
848539
848579
  urlToOutput = startDocsRegisterResponse.body.previewUrl;
@@ -849392,7 +849432,7 @@ var LegacyDocsPublisher = class {
849392
849432
  previewId,
849393
849433
  disableTemplates: void 0,
849394
849434
  skipUpload,
849395
- cliVersion: "4.70.2"
849435
+ cliVersion: "4.71.0"
849396
849436
  });
849397
849437
  if (taskContext.getResult() === TaskResult.Failure) {
849398
849438
  return { success: false };
@@ -850183,59 +850223,85 @@ function addPublishCommand(cli) {
850183
850223
  }
850184
850224
 
850185
850225
  // ../cli-v2/lib/commands/docs/preview/delete/command.js
850186
- var PREVIEW_URL_PATTERN = /^[a-z0-9-]+-preview-[a-z0-9-]+\.docs\.buildwithfern\.com$/i;
850187
850226
  var DeleteCommand = class {
850188
850227
  async handle(context3, args) {
850189
- if (!this.isPreviewUrl(args.url)) {
850228
+ const resolvedUrl = await this.resolveUrl(context3, args);
850229
+ if (!isPreviewUrl(resolvedUrl)) {
850190
850230
  throw new CliError({
850191
- message: `Invalid preview URL: ${args.url}
850231
+ message: `Invalid preview URL: ${resolvedUrl}
850192
850232
  Preview URLs follow the pattern: {org}-preview-{hash}.docs.buildwithfern.com`,
850193
850233
  code: CliError.Code.ConfigError
850194
850234
  });
850195
850235
  }
850196
850236
  const token = await context3.getTokenOrPrompt();
850197
850237
  const fdr = createFdrService({ token: token.value });
850198
- context3.stderr.debug(`Deleting preview site: ${args.url}`);
850238
+ context3.stderr.debug(`Deleting preview site: ${resolvedUrl}`);
850199
850239
  const deleteResponse = await fdr.docs.v2.write.deleteDocsSite({
850200
- url: args.url
850240
+ url: resolvedUrl
850201
850241
  });
850202
850242
  if (!deleteResponse.ok) {
850203
850243
  switch (deleteResponse.error.error) {
850204
850244
  case "UnauthorizedError":
850205
850245
  throw CliError.unauthorized("You do not have permissions to delete this preview site. Reach out to support@buildwithfern.com");
850206
850246
  case "DocsNotFoundError":
850207
- throw CliError.notFound(`Preview site not found: ${args.url}`);
850247
+ throw CliError.notFound(`Preview site not found: ${resolvedUrl}`);
850208
850248
  default:
850209
850249
  throw new CliError({
850210
- message: `Failed to delete preview site: ${args.url}`,
850250
+ message: `Failed to delete preview site: ${resolvedUrl}`,
850211
850251
  code: CliError.Code.InternalError
850212
850252
  });
850213
850253
  }
850214
850254
  }
850215
- context3.stderr.info(source_default.green(`Successfully deleted preview site: ${args.url}`));
850255
+ context3.stderr.info(source_default.green(`Successfully deleted preview site: ${resolvedUrl}`));
850216
850256
  }
850217
- isPreviewUrl(url3) {
850218
- let hostname4 = url3.toLowerCase().trim();
850219
- if (hostname4.startsWith("https://")) {
850220
- hostname4 = hostname4.slice(8);
850221
- } else if (hostname4.startsWith("http://")) {
850222
- hostname4 = hostname4.slice(7);
850257
+ resolveTarget(args) {
850258
+ if (args.url != null) {
850259
+ return { type: "url", value: args.url };
850260
+ }
850261
+ if (args.id != null) {
850262
+ return { type: "id", value: args.id };
850263
+ }
850264
+ if (args.target == null) {
850265
+ throw new CliError({ message: "Must provide a preview URL or --id.", code: CliError.Code.ConfigError });
850223
850266
  }
850224
- const slashIndex = hostname4.indexOf("/");
850225
- if (slashIndex !== -1) {
850226
- hostname4 = hostname4.slice(0, slashIndex);
850267
+ if (isPreviewUrl(args.target)) {
850268
+ return { type: "url", value: args.target };
850227
850269
  }
850228
- return PREVIEW_URL_PATTERN.test(hostname4);
850270
+ return { type: "id", value: args.target };
850271
+ }
850272
+ async resolveUrl(context3, args) {
850273
+ const resolved = this.resolveTarget(args);
850274
+ if (resolved.type === "id") {
850275
+ const workspace = await context3.loadWorkspaceOrThrow();
850276
+ const url3 = buildPreviewDomain({ orgId: workspace.org, previewId: resolved.value });
850277
+ context3.stderr.debug(`Resolved preview ID "${resolved.value}" to URL: ${url3}`);
850278
+ return url3;
850279
+ }
850280
+ return resolved.value;
850229
850281
  }
850230
850282
  };
850231
850283
  function addDeleteCommand(cli) {
850232
850284
  const cmd = new DeleteCommand();
850233
- command2(cli, "delete <url>", "Delete a preview deployment", async (context3, args) => {
850285
+ command2(cli, "delete [target]", "Delete a preview deployment", async (context3, args) => {
850234
850286
  await cmd.handle(context3, args);
850235
- }, (yargs) => yargs.positional("url", {
850287
+ }, (yargs) => yargs.positional("target", {
850288
+ type: "string",
850289
+ description: "A preview URL or ID (auto-detected)"
850290
+ }).option("url", {
850236
850291
  type: "string",
850237
- description: "The FQDN of the preview deployment to delete (e.g. acme-preview-abc123.docs.buildwithfern.com)",
850238
- demandOption: true
850292
+ description: "The FQDN of the preview deployment to delete (e.g. acme-preview-abc123.docs.buildwithfern.com)"
850293
+ }).option("id", {
850294
+ type: "string",
850295
+ description: "The preview ID to delete. Resolves the URL from the organization in fern.config.json."
850296
+ }).check((argv) => {
850297
+ const sources = [argv.target, argv.url, argv.id].filter(Boolean);
850298
+ if (sources.length === 0) {
850299
+ throw new Error("Must provide a preview URL or --id.");
850300
+ }
850301
+ if (sources.length > 1) {
850302
+ throw new Error("Provide only one of: [target], --url, or --id.");
850303
+ }
850304
+ return true;
850239
850305
  }));
850240
850306
  }
850241
850307
 
@@ -923696,7 +923762,7 @@ var CliContext = class _CliContext {
923696
923762
  if (false) {
923697
923763
  this.logger.error("CLI_VERSION is not defined");
923698
923764
  }
923699
- return "4.70.2";
923765
+ return "4.71.0";
923700
923766
  }
923701
923767
  getCliName() {
923702
923768
  if (false) {
@@ -930683,27 +930749,57 @@ async function downloadIr(client3, jobId, libraryName, language, context3) {
930683
930749
  }
930684
930750
 
930685
930751
  // src/commands/docs-preview/deleteDocsPreview.ts
930686
- var PREVIEW_URL_PATTERN2 = /^[a-z0-9-]+-preview-[a-z0-9-]+\.docs\.buildwithfern\.com$/i;
930687
- function isPreviewUrl(url3) {
930688
- let hostname4 = url3.toLowerCase().trim();
930689
- if (hostname4.startsWith("https://")) {
930690
- hostname4 = hostname4.slice(8);
930691
- } else if (hostname4.startsWith("http://")) {
930692
- hostname4 = hostname4.slice(7);
930752
+ async function resolvePreviewUrlFromId({
930753
+ cliContext,
930754
+ previewId
930755
+ }) {
930756
+ const fernDirectory = await getFernDirectory();
930757
+ if (fernDirectory == null) {
930758
+ return cliContext.failAndThrow(
930759
+ "No fern directory found. The --id flag requires a Fern project to resolve the organization.\nRun this command from within a Fern project directory, or use the URL argument instead."
930760
+ );
930693
930761
  }
930694
- const slashIndex = hostname4.indexOf("/");
930695
- if (slashIndex !== -1) {
930696
- hostname4 = hostname4.slice(0, slashIndex);
930762
+ const projectConfig = await cliContext.runTask(
930763
+ (context3) => loadProjectConfig({ directory: fernDirectory, context: context3 })
930764
+ );
930765
+ return buildPreviewDomain({ orgId: projectConfig.organization, previewId });
930766
+ }
930767
+ function resolveTarget({
930768
+ target,
930769
+ url: url3,
930770
+ id: id2
930771
+ }) {
930772
+ if (url3 != null) {
930773
+ return { type: "url", value: url3 };
930774
+ }
930775
+ if (id2 != null) {
930776
+ return { type: "id", value: id2 };
930697
930777
  }
930698
- return PREVIEW_URL_PATTERN2.test(hostname4);
930778
+ if (target == null) {
930779
+ throw new Error("Must provide a preview URL or --id.");
930780
+ }
930781
+ if (isPreviewUrl(target)) {
930782
+ return { type: "url", value: target };
930783
+ }
930784
+ return { type: "id", value: target };
930699
930785
  }
930700
930786
  async function deleteDocsPreview({
930701
930787
  cliContext,
930702
- previewUrl
930788
+ target,
930789
+ previewUrl,
930790
+ previewId
930703
930791
  }) {
930704
- if (!isPreviewUrl(previewUrl)) {
930792
+ const resolved = resolveTarget({ target, url: previewUrl, id: previewId });
930793
+ let resolvedUrl;
930794
+ if (resolved.type === "id") {
930795
+ resolvedUrl = await resolvePreviewUrlFromId({ cliContext, previewId: resolved.value });
930796
+ cliContext.logger.debug(`Resolved preview ID "${resolved.value}" to URL: ${resolvedUrl}`);
930797
+ } else {
930798
+ resolvedUrl = resolved.value;
930799
+ }
930800
+ if (!isPreviewUrl(resolvedUrl)) {
930705
930801
  cliContext.failAndThrow(
930706
- `Invalid preview URL: ${previewUrl}
930802
+ `Invalid preview URL: ${resolvedUrl}
930707
930803
  Only preview sites can be deleted with this command.
930708
930804
  Preview URLs follow the pattern: {org}-preview-{hash}.docs.buildwithfern.com
930709
930805
  Example: acme-preview-abc123.docs.buildwithfern.com`,
@@ -930722,13 +930818,13 @@ Example: acme-preview-abc123.docs.buildwithfern.com`,
930722
930818
  return;
930723
930819
  }
930724
930820
  await cliContext.runTask(async (context3) => {
930725
- context3.logger.info(`Deleting preview site: ${previewUrl}`);
930821
+ context3.logger.info(`Deleting preview site: ${resolvedUrl}`);
930726
930822
  const fdr = createFdrService({ token: token.value });
930727
930823
  const deleteResponse = await fdr.docs.v2.write.deleteDocsSite({
930728
- url: previewUrl
930824
+ url: resolvedUrl
930729
930825
  });
930730
930826
  if (deleteResponse.ok) {
930731
- context3.logger.info(source_default.green(`Successfully deleted preview site: ${previewUrl}`));
930827
+ context3.logger.info(source_default.green(`Successfully deleted preview site: ${resolvedUrl}`));
930732
930828
  } else {
930733
930829
  switch (deleteResponse.error.error) {
930734
930830
  case "UnauthorizedError":
@@ -930738,11 +930834,11 @@ Example: acme-preview-abc123.docs.buildwithfern.com`,
930738
930834
  { code: CliError.Code.NetworkError }
930739
930835
  );
930740
930836
  case "DocsNotFoundError":
930741
- return context3.failAndThrow(`Preview site not found: ${previewUrl}`, void 0, {
930837
+ return context3.failAndThrow(`Preview site not found: ${resolvedUrl}`, void 0, {
930742
930838
  code: CliError.Code.ConfigError
930743
930839
  });
930744
930840
  default:
930745
- return context3.failAndThrow(`Failed to delete preview site: ${previewUrl}`, deleteResponse.error, {
930841
+ return context3.failAndThrow(`Failed to delete preview site: ${resolvedUrl}`, deleteResponse.error, {
930746
930842
  code: CliError.Code.NetworkError
930747
930843
  });
930748
930844
  }
@@ -933579,23 +933675,23 @@ function isCI2() {
933579
933675
  }
933580
933676
 
933581
933677
  // src/commands/generate/generateDocsWorkspace.ts
933582
- var DOMAIN_SUFFIX = "docs.buildwithfern.com";
933583
- var SUBDOMAIN_LIMIT = 62;
933584
- function sanitizePreviewId2(id2) {
933678
+ var DOMAIN_SUFFIX2 = "docs.buildwithfern.com";
933679
+ var SUBDOMAIN_LIMIT2 = 62;
933680
+ function sanitizePreviewId3(id2) {
933585
933681
  const sanitized = id2.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "");
933586
933682
  if (sanitized.length === 0) {
933587
933683
  return "default";
933588
933684
  }
933589
933685
  return sanitized;
933590
933686
  }
933591
- function buildPreviewDomain({ orgId, previewId }) {
933592
- const sanitizedId = sanitizePreviewId2(previewId);
933593
- const fullDomain = `${orgId}-preview-${sanitizedId}.${DOMAIN_SUFFIX}`;
933594
- if (fullDomain.length <= SUBDOMAIN_LIMIT) {
933687
+ function buildPreviewDomain2({ orgId, previewId }) {
933688
+ const sanitizedId = sanitizePreviewId3(previewId);
933689
+ const fullDomain = `${orgId}-preview-${sanitizedId}.${DOMAIN_SUFFIX2}`;
933690
+ if (fullDomain.length <= SUBDOMAIN_LIMIT2) {
933595
933691
  return fullDomain;
933596
933692
  }
933597
933693
  const prefix2 = `${orgId}-preview-`;
933598
- const availableSpace = SUBDOMAIN_LIMIT - prefix2.length;
933694
+ const availableSpace = SUBDOMAIN_LIMIT2 - prefix2.length;
933599
933695
  const minIdLength = 8;
933600
933696
  if (availableSpace < minIdLength) {
933601
933697
  throw new CliError({
@@ -933604,7 +933700,7 @@ function buildPreviewDomain({ orgId, previewId }) {
933604
933700
  });
933605
933701
  }
933606
933702
  const truncatedId = sanitizedId.slice(0, availableSpace).replace(/-+$/, "");
933607
- return `${prefix2}${truncatedId}.${DOMAIN_SUFFIX}`;
933703
+ return `${prefix2}${truncatedId}.${DOMAIN_SUFFIX2}`;
933608
933704
  }
933609
933705
  async function generateDocsWorkspace({
933610
933706
  project,
@@ -933668,7 +933764,7 @@ ${source_default.yellow("?")} Are you sure you want to continue?`,
933668
933764
  }
933669
933765
  }
933670
933766
  if (previewId != null && !isCI2() && !force) {
933671
- const expectedDomain = buildPreviewDomain({ orgId: project.config.organization, previewId });
933767
+ const expectedDomain = buildPreviewDomain2({ orgId: project.config.organization, previewId });
933672
933768
  const fdr = createFdrService({ token: token.value });
933673
933769
  const metadataResponse = await fdr.docs.v2.read.getDocsUrlMetadata({ url: FdrAPI_exports.Url(expectedDomain) });
933674
933770
  if (metadataResponse.ok) {
@@ -943656,12 +943752,26 @@ function addDocsPreviewListCommand(cli, cliContext) {
943656
943752
  }
943657
943753
  function addDocsPreviewDeleteCommand(cli, cliContext) {
943658
943754
  cli.command(
943659
- "delete <url>",
943755
+ "delete [target]",
943660
943756
  "Delete a preview deployment",
943661
- (yargs) => yargs.positional("url", {
943757
+ (yargs) => yargs.positional("target", {
943662
943758
  type: "string",
943663
- description: "The FQDN of the preview deployment to delete (e.g. acme-preview-abc123.docs.buildwithfern.com)",
943664
- demandOption: true
943759
+ description: "A preview URL or ID (auto-detected)"
943760
+ }).option("url", {
943761
+ type: "string",
943762
+ description: "The FQDN of the preview deployment to delete (e.g. acme-preview-abc123.docs.buildwithfern.com)"
943763
+ }).option("id", {
943764
+ type: "string",
943765
+ description: "The preview ID to delete. Resolves the URL from the organization in fern.config.json."
943766
+ }).check((argv) => {
943767
+ const sources = [argv.target, argv.url, argv.id].filter(Boolean);
943768
+ if (sources.length === 0) {
943769
+ throw new Error("Must provide a preview URL or --id.");
943770
+ }
943771
+ if (sources.length > 1) {
943772
+ throw new Error("Provide only one of: [target], --url, or --id.");
943773
+ }
943774
+ return true;
943665
943775
  }),
943666
943776
  async (argv) => {
943667
943777
  cliContext.instrumentPostHogEvent({
@@ -943669,7 +943779,9 @@ function addDocsPreviewDeleteCommand(cli, cliContext) {
943669
943779
  });
943670
943780
  await deleteDocsPreview({
943671
943781
  cliContext,
943672
- previewUrl: argv.url
943782
+ target: argv.target,
943783
+ previewUrl: argv.url,
943784
+ previewId: argv.id
943673
943785
  });
943674
943786
  }
943675
943787
  );
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.70.2",
2
+ "version": "4.71.0",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",