@fern-api/fern-api-dev 5.75.3 → 5.75.5

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 +238 -44
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -691149,7 +691149,7 @@ var AccessTokenPosthogManager = class {
691149
691149
  properties: {
691150
691150
  ...event,
691151
691151
  ...event.properties,
691152
- version: "5.75.3",
691152
+ version: "5.75.5",
691153
691153
  usingAccessToken: true,
691154
691154
  ...getRunIdProperties()
691155
691155
  }
@@ -691215,7 +691215,7 @@ var UserPosthogManager = class {
691215
691215
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
691216
691216
  event: "CLI",
691217
691217
  properties: {
691218
- version: "5.75.3",
691218
+ version: "5.75.5",
691219
691219
  ...event,
691220
691220
  ...event.properties,
691221
691221
  usingAccessToken: false,
@@ -866515,7 +866515,9 @@ var ValidMarkdownRule = {
866515
866515
  const message = markdownParseResult.message != null ? `Markdown failed to parse: ${markdownParseResult.message}` : "Markdown failed to parse";
866516
866516
  return [
866517
866517
  {
866518
- severity: "fatal",
866518
+ // Surfaced as a warning (not an error) so re-enabling this rule does not
866519
+ // suddenly break existing `fern check` runs on repos with latent MDX issues.
866520
+ severity: "warning",
866519
866521
  message
866520
866522
  }
866521
866523
  ];
@@ -868492,6 +868494,8 @@ var allRules = [
868492
868494
  // Check non-component references (will skip v2 files)
868493
868495
  ValidLocalReferencesRule,
868494
868496
  // Validate that local references actually exist
868497
+ ValidMarkdownRule,
868498
+ // Compile each page's MDX and surface syntax errors (e.g. unclosed components)
868495
868499
  NavigationConflicts,
868496
868500
  ValidateVersionFileRule,
868497
868501
  ValidateProductFileRule,
@@ -872316,7 +872320,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
872316
872320
  var LOGS_FOLDER_NAME = "logs";
872317
872321
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
872318
872322
  function getCliSource() {
872319
- const version7 = "5.75.3";
872323
+ const version7 = "5.75.5";
872320
872324
  return `cli@${version7}`;
872321
872325
  }
872322
872326
  var DebugLogger = class {
@@ -875594,6 +875598,8 @@ var SnippetDependencyTracker = class {
875594
875598
  snippetToPages = /* @__PURE__ */ new Map();
875595
875599
  // Map: page file path -> Set of snippet files it references
875596
875600
  pageToSnippets = /* @__PURE__ */ new Map();
875601
+ // Whether a full scan has populated the maps at least once.
875602
+ hasBuiltInitialMap = false;
875597
875603
  constructor(context3) {
875598
875604
  this.context = context3;
875599
875605
  }
@@ -875639,21 +875645,77 @@ var SnippetDependencyTracker = class {
875639
875645
  const content5 = await (0, import_promises101.readFile)(markdownFile, "utf-8");
875640
875646
  const referencedFiles = this.extractReferences(content5, markdownFile, docsWorkspace.absoluteFilePath);
875641
875647
  this.pageToSnippets.set(markdownFile, referencedFiles);
875642
- for (const referencedFile of referencedFiles) {
875643
- if (!this.snippetToPages.has(referencedFile)) {
875644
- this.snippetToPages.set(referencedFile, /* @__PURE__ */ new Set());
875645
- }
875646
- this.snippetToPages.get(referencedFile)?.add(markdownFile);
875647
- }
875648
875648
  } catch (error50) {
875649
875649
  this.context.logger.debug(`Failed to read markdown file ${markdownFile}: ${error50}`);
875650
875650
  }
875651
875651
  }
875652
+ this.rebuildReverseMap();
875653
+ this.hasBuiltInitialMap = true;
875652
875654
  this.context.logger.debug(`Built dependency map: ${this.snippetToPages.size} snippets, ${this.pageToSnippets.size} pages`);
875653
875655
  } catch (error50) {
875654
875656
  this.context.logger.debug(`Failed to build dependency map: ${error50}`);
875655
875657
  }
875656
875658
  }
875659
+ /**
875660
+ * Incrementally updates the dependency maps for a set of changed markdown files,
875661
+ * avoiding a full re-scan of every page in the workspace.
875662
+ *
875663
+ * Only content-only (`.md`/`.mdx`) reloads take this path. For each changed file we
875664
+ * re-read it and recompute its outgoing references (the page -> snippets forward
875665
+ * edge); deleted files are dropped. We then rebuild the snippet -> pages reverse
875666
+ * map from the forward map in memory (no disk I/O), so the reverse map is always
875667
+ * fully consistent with the forward map and can never accumulate stale edges.
875668
+ *
875669
+ * Reloads never overlap (the watcher handler serializes them behind `isReloading`),
875670
+ * so these mutations are not subject to concurrent access. Falls back to a full
875671
+ * scan if an initial map has not been built yet.
875672
+ */
875673
+ async updateDependencyMapForFiles(changedFiles, project) {
875674
+ const docsWorkspace = project.docsWorkspaces;
875675
+ if (!docsWorkspace) {
875676
+ return;
875677
+ }
875678
+ if (!this.hasBuiltInitialMap) {
875679
+ await this.buildDependencyMap(project);
875680
+ return;
875681
+ }
875682
+ for (const changedFile of changedFiles) {
875683
+ const lower = changedFile.toLowerCase();
875684
+ if (!lower.endsWith(".md") && !lower.endsWith(".mdx")) {
875685
+ continue;
875686
+ }
875687
+ if (!await doesPathExist(changedFile)) {
875688
+ this.pageToSnippets.delete(changedFile);
875689
+ continue;
875690
+ }
875691
+ try {
875692
+ const content5 = await (0, import_promises101.readFile)(changedFile, "utf-8");
875693
+ const referencedFiles = this.extractReferences(content5, changedFile, docsWorkspace.absoluteFilePath);
875694
+ this.pageToSnippets.set(changedFile, referencedFiles);
875695
+ } catch (error50) {
875696
+ this.context.logger.debug(`Failed to read markdown file ${changedFile}: ${error50}`);
875697
+ this.pageToSnippets.delete(changedFile);
875698
+ }
875699
+ }
875700
+ this.rebuildReverseMap();
875701
+ }
875702
+ /**
875703
+ * Rebuilds the snippet -> pages (reverse) map from the page -> snippets (forward)
875704
+ * map. A pure in-memory transformation, so it can never leave stale reverse edges.
875705
+ */
875706
+ rebuildReverseMap() {
875707
+ this.snippetToPages.clear();
875708
+ for (const [page, references] of this.pageToSnippets) {
875709
+ for (const reference4 of references) {
875710
+ let pages = this.snippetToPages.get(reference4);
875711
+ if (pages == null) {
875712
+ pages = /* @__PURE__ */ new Set();
875713
+ this.snippetToPages.set(reference4, pages);
875714
+ }
875715
+ pages.add(page);
875716
+ }
875717
+ }
875718
+ }
875657
875719
  /**
875658
875720
  * Find all markdown files in the docs workspace directory
875659
875721
  */
@@ -876074,10 +876136,16 @@ async function runAppPreviewServer({ initialProject, reloadProject, validateProj
876074
876136
  context3.logger.info("Reloading docs...");
876075
876137
  const startTime = Date.now();
876076
876138
  void debugLogger.logCliReloadStart();
876139
+ const contentOnlyEdit = isContentOnlyEdit(editedAbsoluteFilepaths2);
876077
876140
  try {
876078
- project = await reloadProject();
876079
- await snippetTracker.buildDependencyMap(project);
876080
- if (!isContentOnlyEdit(editedAbsoluteFilepaths2)) {
876141
+ if (contentOnlyEdit) {
876142
+ context3.logger.debug("Content-only edit; reusing loaded project (skipping full reload).");
876143
+ await snippetTracker.updateDependencyMapForFiles(editedAbsoluteFilepaths2 ?? [], project);
876144
+ } else {
876145
+ project = await reloadProject();
876146
+ await snippetTracker.buildDependencyMap(project);
876147
+ }
876148
+ if (!contentOnlyEdit) {
876081
876149
  const validationStartTime = Date.now();
876082
876150
  void validateProject(project).then(() => {
876083
876151
  const validationTime = Date.now() - validationStartTime;
@@ -904905,7 +904973,7 @@ var LegacyDocsPublisher = class {
904905
904973
  previewId,
904906
904974
  disableTemplates: void 0,
904907
904975
  skipUpload,
904908
- cliVersion: "5.75.3",
904976
+ cliVersion: "5.75.5",
904909
904977
  loginCommand: "fern auth login"
904910
904978
  });
904911
904979
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -929238,6 +929306,9 @@ var DynamicTypeInstantiationMapper = class {
929238
929306
  return this.convertLiteralToOptionalPrimitive(named.typeReference.value);
929239
929307
  }
929240
929308
  }
929309
+ if (inner2.type === "literal") {
929310
+ return this.convertLiteralToOptionalPrimitive(inner2.value);
929311
+ }
929241
929312
  return go_exports.TypeInstantiation.optional(this.convert({ typeReference: inner2, value: args.value, as: args.as }));
929242
929313
  }
929243
929314
  case "optional": {
@@ -929262,6 +929333,9 @@ var DynamicTypeInstantiationMapper = class {
929262
929333
  return this.convertLiteralToOptionalPrimitive(named.typeReference.value);
929263
929334
  }
929264
929335
  }
929336
+ if (inner2.type === "literal") {
929337
+ return this.convertLiteralToOptionalPrimitive(inner2.value);
929338
+ }
929265
929339
  return go_exports.TypeInstantiation.optional(this.convert({ typeReference: inner2, value: args.value, as: args.as }));
929266
929340
  }
929267
929341
  case "primitive":
@@ -935486,10 +935560,12 @@ function convertToPhpVariableName(name2) {
935486
935560
  // ../../../generators/php/codegen/lib/ast/Comment.js
935487
935561
  var Comment4 = class extends AstNode4 {
935488
935562
  docs;
935563
+ codeExample;
935489
935564
  tags = [];
935490
- constructor({ docs: docs2 } = {}) {
935565
+ constructor({ docs: docs2, codeExample } = {}) {
935491
935566
  super();
935492
935567
  this.docs = docs2;
935568
+ this.codeExample = codeExample;
935493
935569
  }
935494
935570
  addTag(tag2) {
935495
935571
  this.tags.push({
@@ -935503,6 +935579,17 @@ var Comment4 = class extends AstNode4 {
935503
935579
  this.docs.split("\n").forEach((line) => {
935504
935580
  writer2.writeLine(` * ${line}`);
935505
935581
  });
935582
+ if (this.codeExample != null || this.tags.length > 0) {
935583
+ writer2.writeLine(" *");
935584
+ }
935585
+ }
935586
+ if (this.codeExample != null) {
935587
+ writer2.writeLine(" * Example:");
935588
+ writer2.writeLine(" * ```php");
935589
+ this.codeExample.split("\n").forEach((line) => {
935590
+ writer2.writeLine(` * ${this.escapeDocs(line)}`.trimEnd());
935591
+ });
935592
+ writer2.writeLine(" * ```");
935506
935593
  if (this.tags.length > 0) {
935507
935594
  writer2.writeLine(" *");
935508
935595
  }
@@ -935512,6 +935599,9 @@ var Comment4 = class extends AstNode4 {
935512
935599
  }
935513
935600
  writer2.writeLine(" */");
935514
935601
  }
935602
+ escapeDocs(line) {
935603
+ return line.replaceAll("*/", "*\\/");
935604
+ }
935515
935605
  writeTag({ writer: writer2, tag: tag2 }) {
935516
935606
  const docsSplit = tag2.docs != null ? tag2.docs.split("\n") : void 0;
935517
935607
  if (docsSplit != null && docsSplit.length > 1) {
@@ -936684,10 +936774,11 @@ var Method4 = class extends AstNode4 {
936684
936774
  return_;
936685
936775
  body;
936686
936776
  docs;
936777
+ codeExample;
936687
936778
  classReference;
936688
936779
  static_;
936689
936780
  noBody;
936690
- constructor({ name: name2, access: access7, parameters: parameters2, throws, return_, body, docs: docs2, classReference: classReference4, static_, noBody }) {
936781
+ constructor({ name: name2, access: access7, parameters: parameters2, throws, return_, body, docs: docs2, codeExample, classReference: classReference4, static_, noBody }) {
936691
936782
  super();
936692
936783
  this.name = name2;
936693
936784
  this.access = access7;
@@ -936696,6 +936787,7 @@ var Method4 = class extends AstNode4 {
936696
936787
  this.return_ = return_;
936697
936788
  this.body = body;
936698
936789
  this.docs = docs2;
936790
+ this.codeExample = codeExample;
936699
936791
  this.classReference = classReference4;
936700
936792
  this.static_ = static_ ?? false;
936701
936793
  this.noBody = noBody ?? false;
@@ -936729,7 +936821,7 @@ var Method4 = class extends AstNode4 {
936729
936821
  }
936730
936822
  }
936731
936823
  writeComment(writer2) {
936732
- const comment6 = new Comment4({ docs: this.docs });
936824
+ const comment6 = new Comment4({ docs: this.docs, codeExample: this.codeExample });
936733
936825
  for (const parameter6 of this.parameters) {
936734
936826
  comment6.addTag({
936735
936827
  tagType: "param",
@@ -941726,6 +941818,10 @@ var EndpointSnippetGenerator5 = class {
941726
941818
  assertNever(named);
941727
941819
  }
941728
941820
  }
941821
+ // Whether a type resolves to a literal, treating optional/nullable literals AS literals.
941822
+ // Used for request-body properties and path parameters, which omit ALL literals (required
941823
+ // and optional alike) from the generated method call because they are set internally.
941824
+ // Contrast with resolvesToNonOptionalLiteralType below, which keeps optional literals.
941729
941825
  resolvesToLiteralType(typeReference2) {
941730
941826
  switch (typeReference2.type) {
941731
941827
  case "literal":
@@ -941753,6 +941849,44 @@ var EndpointSnippetGenerator5 = class {
941753
941849
  assertNever(typeReference2);
941754
941850
  }
941755
941851
  }
941852
+ // Whether a type resolves to a REQUIRED literal, i.e. a literal NOT wrapped in optional/nullable.
941853
+ // Used to filter query parameters and headers: a required literal (e.g. response_type="code") is
941854
+ // hardcoded inside the generated method and omitted from its signature, so passing it as a keyword
941855
+ // argument raises TypeError. An optional literal, by contrast, stays in the signature, so it must
941856
+ // remain a valid keyword argument and is kept.
941857
+ //
941858
+ // This deliberately differs from resolvesToLiteralType above in the optional/nullable cases: here
941859
+ // they return false (keep the parameter) instead of recursing. The asymmetry is intentional and is
941860
+ // validated by the literal fixture's wire tests. Note the two cannot be collapsed into a single
941861
+ // guard like `t.type !== "optional" && resolvesToLiteralType(t)`: a named alias whose target is
941862
+ // optional<literal> has top-level type "named", so such a guard would misclassify it as a required
941863
+ // literal and wrongly drop it, whereas recursing through the alias here correctly returns false.
941864
+ resolvesToNonOptionalLiteralType(typeReference2) {
941865
+ switch (typeReference2.type) {
941866
+ case "literal":
941867
+ return true;
941868
+ case "named": {
941869
+ const named = this.context.resolveNamedType({ typeId: typeReference2.value });
941870
+ if (named == null) {
941871
+ return false;
941872
+ }
941873
+ if (named.type === "alias") {
941874
+ return this.resolvesToNonOptionalLiteralType(named.typeReference);
941875
+ }
941876
+ return false;
941877
+ }
941878
+ case "optional":
941879
+ case "nullable":
941880
+ case "list":
941881
+ case "map":
941882
+ case "set":
941883
+ case "primitive":
941884
+ case "unknown":
941885
+ return false;
941886
+ default:
941887
+ assertNever(typeReference2);
941888
+ }
941889
+ }
941756
941890
  getBodyRequestArgsForBytes({ body, value: value2 }) {
941757
941891
  const typeInstantiation = this.getBytesBodyRequestTypeInstantiation({ value: value2 });
941758
941892
  if (python_exports.TypeInstantiation.isNop(typeInstantiation)) {
@@ -941866,7 +942000,7 @@ var EndpointSnippetGenerator5 = class {
941866
942000
  parameters: request7.queryParameters ?? [],
941867
942001
  values: snippet.queryParameters ?? {}
941868
942002
  });
941869
- const queryParameterFields = queryParameters.map((queryParameter) => ({
942003
+ const queryParameterFields = queryParameters.filter((queryParameter) => !this.resolvesToNonOptionalLiteralType(queryParameter.typeReference)).map((queryParameter) => ({
941870
942004
  name: this.context.getPropertyName(queryParameter.name.name),
941871
942005
  value: this.context.dynamicTypeLiteralMapper.convert(queryParameter)
941872
942006
  }));
@@ -941876,7 +942010,7 @@ var EndpointSnippetGenerator5 = class {
941876
942010
  parameters: request7.headers ?? [],
941877
942011
  values: snippet.headers ?? {}
941878
942012
  });
941879
- const headerFields = headers2.map((header) => ({
942013
+ const headerFields = headers2.filter((header) => !this.resolvesToNonOptionalLiteralType(header.typeReference)).map((header) => ({
941880
942014
  name: this.context.getPropertyName(header.name.name),
941881
942015
  value: this.context.dynamicTypeLiteralMapper.convert(header)
941882
942016
  }));
@@ -942677,7 +942811,8 @@ var Method6 = class extends AstNode6 {
942677
942811
  statements;
942678
942812
  returnType;
942679
942813
  splatOptionDocs;
942680
- constructor({ name: name2, docstring, kind, visibility, parameters: parameters2, returnType, statements, splatOptionDocs }) {
942814
+ codeExample;
942815
+ constructor({ name: name2, docstring, kind, visibility, parameters: parameters2, returnType, statements, splatOptionDocs, codeExample }) {
942681
942816
  super();
942682
942817
  this.name = name2;
942683
942818
  this.docstring = docstring;
@@ -942691,6 +942826,7 @@ var Method6 = class extends AstNode6 {
942691
942826
  this.returnType = returnType ?? Type35.untyped();
942692
942827
  this.statements = statements ?? [];
942693
942828
  this.splatOptionDocs = splatOptionDocs ?? [];
942829
+ this.codeExample = codeExample;
942694
942830
  }
942695
942831
  addStatement(statement) {
942696
942832
  this.statements.push(statement);
@@ -942736,8 +942872,18 @@ var Method6 = class extends AstNode6 {
942736
942872
  for (const optionDoc of this.splatOptionDocs) {
942737
942873
  writer2.writeLine(`# ${optionDoc}`);
942738
942874
  }
942875
+ const codeExample = this.codeExample?.trim();
942876
+ if (codeExample) {
942877
+ if (this.docstring || hasAnyParameters || this.splatOptionDocs.length > 0) {
942878
+ writer2.writeLine("#");
942879
+ }
942880
+ writer2.writeLine("# @example");
942881
+ for (const line of codeExample.split("\n")) {
942882
+ writer2.writeLine(line.trim() === "" ? "#" : `# ${line.trimEnd()}`);
942883
+ }
942884
+ }
942739
942885
  if (this.returnType != null) {
942740
- if (hasAnyParameters || this.docstring) {
942886
+ if (hasAnyParameters || this.docstring || codeExample) {
942741
942887
  writer2.writeLine("#");
942742
942888
  }
942743
942889
  writer2.write(`# @return [`);
@@ -946179,7 +946325,7 @@ var DocComment = class extends AstNode7 {
946179
946325
  examples;
946180
946326
  constructor({ summary, description, parameters: parameters2, returns, errors: errors4, examples }) {
946181
946327
  super();
946182
- this.summary = this.sanitizeText(summary);
946328
+ this.summary = summary ? this.sanitizeText(summary) : void 0;
946183
946329
  this.description = description ? this.sanitizeText(description) : void 0;
946184
946330
  this.parameters = (parameters2 ?? []).map((param) => ({
946185
946331
  name: param.name,
@@ -946189,15 +946335,25 @@ var DocComment = class extends AstNode7 {
946189
946335
  this.examples = (examples ?? []).map((e2) => this.sanitizeText(e2));
946190
946336
  }
946191
946337
  write(writer2) {
946192
- this.writeMultilineText(writer2, this.summary);
946338
+ let hasContent = false;
946339
+ if (this.summary) {
946340
+ this.writeMultilineText(writer2, this.summary);
946341
+ hasContent = true;
946342
+ }
946193
946343
  if (this.description) {
946194
- writer2.write("///");
946195
- writer2.newLine();
946344
+ if (hasContent) {
946345
+ writer2.write("///");
946346
+ writer2.newLine();
946347
+ }
946196
946348
  this.writeMultilineText(writer2, this.description);
946349
+ hasContent = true;
946197
946350
  }
946198
946351
  if (this.parameters.length > 0) {
946199
- writer2.write("///");
946200
- writer2.newLine();
946352
+ if (hasContent) {
946353
+ writer2.write("///");
946354
+ writer2.newLine();
946355
+ }
946356
+ hasContent = true;
946201
946357
  writer2.write("/// # Arguments");
946202
946358
  writer2.newLine();
946203
946359
  writer2.write("///");
@@ -946215,8 +946371,11 @@ var DocComment = class extends AstNode7 {
946215
946371
  });
946216
946372
  }
946217
946373
  if (this.returns) {
946218
- writer2.write("///");
946219
- writer2.newLine();
946374
+ if (hasContent) {
946375
+ writer2.write("///");
946376
+ writer2.newLine();
946377
+ }
946378
+ hasContent = true;
946220
946379
  writer2.write("/// # Returns");
946221
946380
  writer2.newLine();
946222
946381
  writer2.write("///");
@@ -946228,16 +946387,18 @@ var DocComment = class extends AstNode7 {
946228
946387
  });
946229
946388
  }
946230
946389
  if (this.examples.length > 0) {
946231
- writer2.write("///");
946232
- writer2.newLine();
946390
+ if (hasContent) {
946391
+ writer2.write("///");
946392
+ writer2.newLine();
946393
+ }
946233
946394
  writer2.write("/// # Examples");
946234
946395
  writer2.newLine();
946235
946396
  writer2.write("///");
946236
946397
  writer2.newLine();
946237
946398
  this.examples.forEach((example) => {
946238
- writer2.write("/// ```rust");
946399
+ writer2.write("/// ```no_run");
946239
946400
  writer2.newLine();
946240
- this.writeMultilineText(writer2, example);
946401
+ this.writeCodeBlock(writer2, example);
946241
946402
  writer2.write("/// ```");
946242
946403
  writer2.newLine();
946243
946404
  });
@@ -946251,6 +946412,14 @@ var DocComment = class extends AstNode7 {
946251
946412
  writer2.newLine();
946252
946413
  }
946253
946414
  }
946415
+ writeCodeBlock(writer2, code5) {
946416
+ const lines = code5.split("\n");
946417
+ for (const line of lines) {
946418
+ const trimmed2 = line.trimEnd();
946419
+ writer2.write(trimmed2.length > 0 ? `/// ${trimmed2}` : "///");
946420
+ writer2.newLine();
946421
+ }
946422
+ }
946254
946423
  /**
946255
946424
  * Sanitizes text content to ensure it doesn't break Rust doc comment syntax.
946256
946425
  */
@@ -952027,13 +952196,15 @@ var ComputedProperty = class extends AstNode8 {
952027
952196
  var DocComment2 = class _DocComment extends AstNode8 {
952028
952197
  summary;
952029
952198
  description;
952199
+ codeExample;
952030
952200
  parameters;
952031
952201
  returns;
952032
952202
  throws;
952033
- constructor({ summary, description, parameters: parameters2, returns, throws }) {
952203
+ constructor({ summary, description, codeExample, parameters: parameters2, returns, throws }) {
952034
952204
  super();
952035
- this.summary = _DocComment.sanitizeText(summary);
952205
+ this.summary = summary != null ? _DocComment.sanitizeText(summary) : void 0;
952036
952206
  this.description = description != null ? _DocComment.sanitizeText(description) : void 0;
952207
+ this.codeExample = codeExample != null ? _DocComment.sanitizeText(codeExample) : void 0;
952037
952208
  this.parameters = (parameters2 ?? []).map((param) => ({
952038
952209
  name: param.name,
952039
952210
  description: _DocComment.sanitizeText(param.description)
@@ -952042,15 +952213,34 @@ var DocComment2 = class _DocComment extends AstNode8 {
952042
952213
  this.throws = (throws ?? []).map((t3) => _DocComment.sanitizeText(t3));
952043
952214
  }
952044
952215
  write(writer2) {
952045
- this.writeMultilineText(writer2, this.summary);
952216
+ let hasPrecedingSection = false;
952217
+ if (this.summary != null) {
952218
+ this.writeMultilineText(writer2, this.summary);
952219
+ hasPrecedingSection = true;
952220
+ }
952046
952221
  if (this.description != null) {
952047
- writer2.write("///");
952048
- writer2.newLine();
952222
+ if (hasPrecedingSection) {
952223
+ writer2.write("///");
952224
+ writer2.newLine();
952225
+ }
952049
952226
  this.writeMultilineText(writer2, this.description);
952227
+ hasPrecedingSection = true;
952228
+ }
952229
+ if (this.codeExample != null) {
952230
+ if (hasPrecedingSection) {
952231
+ writer2.write("///");
952232
+ writer2.newLine();
952233
+ }
952234
+ this.writeMultilineText(writer2, `\`\`\`swift
952235
+ ${this.codeExample}
952236
+ \`\`\``);
952237
+ hasPrecedingSection = true;
952050
952238
  }
952051
952239
  if (this.parameters.length > 0) {
952052
- writer2.write("///");
952053
- writer2.newLine();
952240
+ if (hasPrecedingSection) {
952241
+ writer2.write("///");
952242
+ writer2.newLine();
952243
+ }
952054
952244
  for (const param of this.parameters) {
952055
952245
  const paramLines = param.description.split("\n");
952056
952246
  paramLines.forEach((line, lineIdx) => {
@@ -952099,8 +952289,12 @@ var DocComment2 = class _DocComment extends AstNode8 {
952099
952289
  writeMultilineText(writer2, sanitizedText) {
952100
952290
  const lines = sanitizedText.split("\n");
952101
952291
  for (const line of lines) {
952102
- writer2.write("/// ");
952103
- writer2.write(line);
952292
+ if (line === "") {
952293
+ writer2.write("///");
952294
+ } else {
952295
+ writer2.write("/// ");
952296
+ writer2.write(line);
952297
+ }
952104
952298
  writer2.newLine();
952105
952299
  }
952106
952300
  }
@@ -971692,7 +971886,7 @@ function getAutomationContextFromEnv() {
971692
971886
  config_branch: process.env.FERN_CONFIG_BRANCH,
971693
971887
  config_pr_number: process.env.FERN_CONFIG_PR_NUMBER,
971694
971888
  trigger: process.env.GITHUB_EVENT_NAME,
971695
- cli_version: "5.75.3"
971889
+ cli_version: "5.75.5"
971696
971890
  };
971697
971891
  }
971698
971892
  function isAutomationMode() {
@@ -972524,7 +972718,7 @@ var CliContext = class _CliContext {
972524
972718
  if (false) {
972525
972719
  this.logger.error("CLI_VERSION is not defined");
972526
972720
  }
972527
- return "5.75.3";
972721
+ return "5.75.5";
972528
972722
  }
972529
972723
  getCliName() {
972530
972724
  if (false) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.75.3",
2
+ "version": "5.75.5",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",