@fern-api/fern-api-dev 5.65.3 → 5.65.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 +332 -175
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -145267,7 +145267,6 @@ function buildEndpoint({ endpoint: endpoint3, declarationFile, context: context3
145267
145267
  fileContainingReference: declarationFile,
145268
145268
  namespace: maybeEndpointNamespace
145269
145269
  });
145270
- names2.add(pathParameter.name);
145271
145270
  }
145272
145271
  const queryParameters = {};
145273
145272
  for (const queryParameter of endpoint3.queryParameters) {
@@ -450039,6 +450038,13 @@ function parseImagePaths(markdown, metadata, context3) {
450039
450038
  }
450040
450039
  visitFrontmatterImages(data2, ["image", "og:image", "og:logo", "twitter:image"], mapImage);
450041
450040
  replaceFrontmatterImagesforLogo(data2, mapImage);
450041
+ const hasImageIndicators = content5.includes("![") || content5.includes("src=") || content5.includes("icon=");
450042
+ if (!hasImageIndicators) {
450043
+ return {
450044
+ filepaths: [...filepaths],
450045
+ markdown: requoteLeadingZeroValues(import_gray_matter3.default.stringify(content5, data2))
450046
+ };
450047
+ }
450042
450048
  const contentBytes = Buffer.byteLength(content5, "utf8");
450043
450049
  const isLargeFile = contentBytes > getLargeFileBytes();
450044
450050
  let replacedContent;
@@ -450238,142 +450244,208 @@ function replaceImagePathsAndUrls(markdown, fileIdsMap, markdownFilesToPathName,
450238
450244
  }
450239
450245
  visitFrontmatterImages(data2, ["image", "og:image", "og:logo", "twitter:image"], mapImage);
450240
450246
  replaceFrontmatterImagesforLogo(data2, mapImage);
450241
- const contentBytes = Buffer.byteLength(content5, "utf8");
450242
- const isLargeFile = contentBytes > getLargeFileBytes();
450243
- let replacedContent;
450244
- if (isLargeFile) {
450245
- context3.logger.debug(`Using streaming parser for large file replacement: ${metadata.absolutePathToMarkdownFile} (${(contentBytes / 1024 / 1024).toFixed(2)} MB)`);
450246
- const streamingStart = performance.now();
450247
- const edits = [];
450248
- let i5 = 0;
450249
- const len = content5.length;
450250
- while (i5 < len) {
450251
- if (content5[i5] === "!" && content5[i5 + 1] === "[") {
450252
- const result = parseMarkdownImage(content5, i5, metadata);
450253
- if (result) {
450254
- const imageSrc = mapImage(result.src);
450255
- if (imageSrc) {
450256
- edits.push({
450257
- start: result.edit.start,
450258
- end: result.edit.end,
450259
- replacement: result.originalUrl.replace(result.rawSrc, imageSrc)
450260
- });
450261
- }
450262
- i5 = result.nextIndex;
450263
- continue;
450247
+ const edits = [];
450248
+ let hasUnhandledExpressions = false;
450249
+ let i5 = 0;
450250
+ const len = content5.length;
450251
+ while (i5 < len) {
450252
+ if (content5[i5] === "!" && content5[i5 + 1] === "[") {
450253
+ const result = parseMarkdownImage(content5, i5, metadata);
450254
+ if (result) {
450255
+ const imageSrc = mapImage(result.src);
450256
+ if (imageSrc) {
450257
+ edits.push({
450258
+ start: result.edit.start,
450259
+ end: result.edit.end,
450260
+ replacement: result.originalUrl.replace(result.rawSrc, imageSrc)
450261
+ });
450264
450262
  }
450265
- } else if (content5[i5] === "[" && content5[i5 - 1] !== "!") {
450266
- const linkStart = i5;
450267
- let j5 = i5 + 1;
450268
- while (j5 < len && content5[j5] !== "]") {
450263
+ i5 = result.nextIndex;
450264
+ continue;
450265
+ }
450266
+ } else if (content5[i5] === "[" && content5[i5 - 1] !== "!") {
450267
+ let j5 = i5 + 1;
450268
+ while (j5 < len && content5[j5] !== "]") {
450269
+ if (content5[j5] === "\\") {
450270
+ j5 += 2;
450271
+ } else {
450272
+ j5++;
450273
+ }
450274
+ }
450275
+ if (j5 < len && content5[j5] === "]" && content5[j5 + 1] === "(") {
450276
+ j5 += 2;
450277
+ const urlStart = j5;
450278
+ let parenDepth = 1;
450279
+ while (j5 < len && parenDepth > 0) {
450269
450280
  if (content5[j5] === "\\") {
450270
450281
  j5 += 2;
450282
+ } else if (content5[j5] === "(") {
450283
+ parenDepth++;
450284
+ j5++;
450285
+ } else if (content5[j5] === ")") {
450286
+ parenDepth--;
450287
+ j5++;
450271
450288
  } else {
450272
450289
  j5++;
450273
450290
  }
450274
450291
  }
450275
- if (j5 < len && content5[j5] === "]" && content5[j5 + 1] === "(") {
450276
- j5 += 2;
450277
- const urlStart = j5;
450278
- let parenDepth = 1;
450279
- while (j5 < len && parenDepth > 0) {
450280
- if (content5[j5] === "\\") {
450281
- j5 += 2;
450282
- } else if (content5[j5] === "(") {
450283
- parenDepth++;
450284
- j5++;
450285
- } else if (content5[j5] === ")") {
450286
- parenDepth--;
450287
- j5++;
450288
- } else {
450292
+ const urlEnd = j5 - 1;
450293
+ const href = content5.slice(urlStart, urlEnd).trim();
450294
+ const trimmedHref = trimAnchor(href) ?? href;
450295
+ const hrefAnchor = trimmedHref !== href ? href.slice(trimmedHref.length) : "";
450296
+ const replacedHref = getReplacedHref({
450297
+ href: trimmedHref,
450298
+ markdownFilesToPathName,
450299
+ metadata
450300
+ });
450301
+ if (replacedHref && replacedHref.type === "replace") {
450302
+ edits.push({
450303
+ start: urlStart,
450304
+ end: urlEnd,
450305
+ replacement: replacedHref.slug + hrefAnchor
450306
+ });
450307
+ }
450308
+ i5 = j5;
450309
+ continue;
450310
+ }
450311
+ } else if (content5[i5] === "<") {
450312
+ let j5 = i5 + 1;
450313
+ while (j5 < len && content5[j5] !== ">" && content5[j5] !== " " && content5[j5] !== "\n") {
450314
+ j5++;
450315
+ }
450316
+ while (j5 < len && content5[j5] !== ">") {
450317
+ while (j5 < len && (content5[j5] === " " || content5[j5] === "\n")) {
450318
+ j5++;
450319
+ }
450320
+ const attrStart = j5;
450321
+ while (j5 < len && content5[j5] !== "=" && content5[j5] !== ">" && content5[j5] !== " " && content5[j5] !== "\n") {
450322
+ j5++;
450323
+ }
450324
+ const attrName = content5.slice(attrStart, j5).trim();
450325
+ if (attrName.startsWith("{")) {
450326
+ hasUnhandledExpressions = true;
450327
+ let braceDepth = 0;
450328
+ j5 = attrStart;
450329
+ while (j5 < len) {
450330
+ if (content5[j5] === "{") {
450331
+ braceDepth++;
450332
+ } else if (content5[j5] === "}") {
450333
+ braceDepth--;
450334
+ if (braceDepth === 0) {
450335
+ j5++;
450336
+ break;
450337
+ }
450338
+ } else if (content5[j5] === '"' || content5[j5] === "'") {
450339
+ const q5 = content5[j5];
450289
450340
  j5++;
450341
+ while (j5 < len && content5[j5] !== q5) {
450342
+ if (content5[j5] === "\\") {
450343
+ j5++;
450344
+ }
450345
+ j5++;
450346
+ }
450290
450347
  }
450348
+ j5++;
450291
450349
  }
450292
- const urlEnd = j5 - 1;
450293
- const href = content5.slice(urlStart, urlEnd).trim();
450294
- const replacedHref = getReplacedHref({ href, markdownFilesToPathName, metadata });
450295
- if (replacedHref && replacedHref.type === "replace") {
450296
- edits.push({ start: urlStart, end: urlEnd, replacement: replacedHref.slug });
450297
- }
450298
- i5 = j5;
450299
450350
  continue;
450300
450351
  }
450301
- } else if (content5[i5] === "<") {
450302
- let j5 = i5 + 1;
450303
- while (j5 < len && content5[j5] !== ">" && content5[j5] !== " " && content5[j5] !== "\n") {
450352
+ if (content5[j5] === "=") {
450304
450353
  j5++;
450305
- }
450306
- while (j5 < len && content5[j5] !== ">") {
450307
450354
  while (j5 < len && (content5[j5] === " " || content5[j5] === "\n")) {
450308
450355
  j5++;
450309
450356
  }
450310
- const attrStart = j5;
450311
- while (j5 < len && content5[j5] !== "=" && content5[j5] !== ">" && content5[j5] !== " " && content5[j5] !== "\n") {
450312
- j5++;
450313
- }
450314
- const attrName = content5.slice(attrStart, j5).trim();
450315
- if (content5[j5] === "=") {
450357
+ const isCurlyWrapped = content5[j5] === "{";
450358
+ if (isCurlyWrapped) {
450316
450359
  j5++;
450317
450360
  while (j5 < len && (content5[j5] === " " || content5[j5] === "\n")) {
450318
450361
  j5++;
450319
450362
  }
450320
- if (content5[j5] === '"' || content5[j5] === "'") {
450321
- const quote2 = content5[j5];
450322
- j5++;
450323
- const valueStart = j5;
450324
- while (j5 < len && content5[j5] !== quote2) {
450325
- if (content5[j5] === "\\") {
450326
- j5 += 2;
450327
- } else {
450328
- j5++;
450329
- }
450363
+ }
450364
+ if (content5[j5] === '"' || content5[j5] === "'") {
450365
+ const quote2 = content5[j5];
450366
+ j5++;
450367
+ const valueStart = j5;
450368
+ while (j5 < len && content5[j5] !== quote2) {
450369
+ if (content5[j5] === "\\") {
450370
+ j5 += 2;
450371
+ } else {
450372
+ j5++;
450330
450373
  }
450331
- const value2 = content5.slice(valueStart, j5);
450332
- j5++;
450333
- if (attrName === "src" || attrName === "icon" && isLocalIconReference(value2)) {
450334
- const imageSrc = mapImage(value2);
450335
- if (imageSrc) {
450336
- edits.push({
450337
- start: valueStart,
450338
- end: valueStart + value2.length,
450339
- replacement: imageSrc
450340
- });
450341
- }
450342
- } else if (attrName === "href") {
450343
- const replacedHref = getReplacedHref({
450344
- href: value2,
450345
- markdownFilesToPathName,
450346
- metadata
450374
+ }
450375
+ const value2 = content5.slice(valueStart, j5);
450376
+ j5++;
450377
+ if (isCurlyWrapped) {
450378
+ while (j5 < len && (content5[j5] === " " || content5[j5] === "\n")) {
450379
+ j5++;
450380
+ }
450381
+ if (j5 < len && content5[j5] === "}") {
450382
+ j5++;
450383
+ }
450384
+ }
450385
+ if (attrName === "src" || attrName === "icon" && isLocalIconReference(value2)) {
450386
+ const trimmedValue = trimAnchor(value2);
450387
+ const anchor = trimmedValue && value2 !== trimmedValue ? value2.slice(trimmedValue.length) : "";
450388
+ const imageSrc = mapImage(trimmedValue ?? value2);
450389
+ if (imageSrc) {
450390
+ edits.push({
450391
+ start: valueStart,
450392
+ end: valueStart + value2.length,
450393
+ replacement: imageSrc + anchor
450347
450394
  });
450348
- if (replacedHref && replacedHref.type === "replace") {
450349
- edits.push({
450350
- start: valueStart,
450351
- end: valueStart + value2.length,
450352
- replacement: replacedHref.slug
450353
- });
450395
+ }
450396
+ } else if (attrName === "href") {
450397
+ const trimmedHrefValue = trimAnchor(value2) ?? value2;
450398
+ const hrefAnchorSuffix = trimmedHrefValue !== value2 ? value2.slice(trimmedHrefValue.length) : "";
450399
+ const replacedHref = getReplacedHref({
450400
+ href: trimmedHrefValue,
450401
+ markdownFilesToPathName,
450402
+ metadata
450403
+ });
450404
+ if (replacedHref && replacedHref.type === "replace") {
450405
+ edits.push({
450406
+ start: valueStart,
450407
+ end: valueStart + value2.length,
450408
+ replacement: replacedHref.slug + hrefAnchorSuffix
450409
+ });
450410
+ }
450411
+ }
450412
+ } else if (isCurlyWrapped && (attrName === "src" || attrName === "icon" || attrName === "href")) {
450413
+ hasUnhandledExpressions = true;
450414
+ let braceDepth = 1;
450415
+ while (j5 < len && braceDepth > 0) {
450416
+ if (content5[j5] === "{") {
450417
+ braceDepth++;
450418
+ } else if (content5[j5] === "}") {
450419
+ braceDepth--;
450420
+ } else if (content5[j5] === '"' || content5[j5] === "'") {
450421
+ const q5 = content5[j5];
450422
+ j5++;
450423
+ while (j5 < len && content5[j5] !== q5) {
450424
+ if (content5[j5] === "\\") {
450425
+ j5++;
450426
+ }
450427
+ j5++;
450354
450428
  }
450355
450429
  }
450430
+ j5++;
450356
450431
  }
450357
450432
  }
450358
450433
  }
450359
- if (j5 < len && content5[j5] === ">") {
450360
- j5++;
450361
- }
450362
- i5 = j5;
450363
- continue;
450364
450434
  }
450365
- i5++;
450435
+ if (j5 < len && content5[j5] === ">") {
450436
+ j5++;
450437
+ }
450438
+ i5 = j5;
450439
+ continue;
450366
450440
  }
450367
- replacedContent = applyEdits(content5, edits);
450368
- const streamingTime = performance.now() - streamingStart;
450369
- context3.logger.debug(`Streaming replacement completed in ${streamingTime.toFixed(0)}ms: ${edits.length} edits applied`);
450370
- } else {
450441
+ i5++;
450442
+ }
450443
+ if (hasUnhandledExpressions) {
450371
450444
  const tree = parseMarkdownToTree(content5);
450372
450445
  const lineStarts = precomputeLineStarts(content5);
450373
- const edits = [];
450374
450446
  const nodeTypeFilter = (node4) => {
450375
450447
  const n2 = node4;
450376
- return n2.type === "image" || n2.type === "link" || n2.type === "mdxJsxFlowElement" || n2.type === "mdxJsxTextElement" || n2.type === "mdxFlowExpression" || n2.type === "mdxTextExpression";
450448
+ return n2.type === "mdxJsxFlowElement" || n2.type === "mdxJsxTextElement" || n2.type === "mdxFlowExpression" || n2.type === "mdxTextExpression";
450377
450449
  };
450378
450450
  visit3(tree, nodeTypeFilter, (node4) => {
450379
450451
  if (node4.position == null) {
@@ -450406,25 +450478,12 @@ function replaceImagePathsAndUrls(markdown, fileIdsMap, markdownFilesToPathName,
450406
450478
  href: (attr) => replaceHref(trimAnchor(extractSingleLiteral(attr.value)))
450407
450479
  });
450408
450480
  }
450409
- if (node4.type === "image") {
450410
- const src = trimAnchor(node4.url);
450411
- replaceSrc(trimAnchor(src));
450412
- }
450413
- if (node4.type === "link") {
450414
- replaceHref(trimAnchor(node4.url));
450415
- }
450416
450481
  if (isMdxJsxElement(node4)) {
450417
- const srcAttr = node4.attributes.filter(isMdxJsxAttribute).find((attr) => attr.name === "src");
450418
- replaceSrc(trimAnchor(extractAttributeValueLiteral(srcAttr?.value)));
450419
- const iconAttr = node4.attributes.filter(isMdxJsxAttribute).find((attr) => attr.name === "icon");
450420
- const iconValue = trimAnchor(extractAttributeValueLiteral(iconAttr?.value));
450421
- if (isLocalIconReference(iconValue)) {
450422
- replaceSrc(iconValue);
450423
- }
450424
- const hrefAttr = node4.attributes.find((attr) => attr.type === "mdxJsxAttribute" && attr.name === "href");
450425
- replaceHref(trimAnchor(extractAttributeValueLiteral(hrefAttr?.value)));
450426
450482
  node4.attributes.forEach((attr) => {
450427
450483
  if (isMdxJsxAttribute(attr) && typeof attr.value !== "string" && attr.value != null && attr.value.data?.estree) {
450484
+ if (extractSingleLiteral(attr.value.data.estree) != null) {
450485
+ return;
450486
+ }
450428
450487
  walkEstreeForSrcAndHref(attr.value.data.estree);
450429
450488
  } else if (isMdxJsxExpressionAttribute(attr) && attr.data?.estree) {
450430
450489
  walkEstreeForSrcAndHref(attr.data.estree);
@@ -450439,8 +450498,8 @@ function replaceImagePathsAndUrls(markdown, fileIdsMap, markdownFilesToPathName,
450439
450498
  }
450440
450499
  return CONTINUE;
450441
450500
  });
450442
- replacedContent = applyEdits(content5, edits);
450443
450501
  }
450502
+ const replacedContent = applyEdits(content5, edits);
450444
450503
  return requoteLeadingZeroValues(import_gray_matter3.default.stringify(replacedContent, data2));
450445
450504
  }
450446
450505
  function trimAnchor(text9) {
@@ -450571,18 +450630,56 @@ function extractLines(content5, linesParam) {
450571
450630
  const extractedLines = sortedIndices.filter((idx) => idx >= 0 && idx < allLines.length).map((idx) => allLines[idx] ?? "");
450572
450631
  return extractedLines.join("\n");
450573
450632
  }
450633
+ function collectCodeSrcUrls(markdown) {
450634
+ if (!markdown.includes("<Code")) {
450635
+ return [];
450636
+ }
450637
+ const urls = [];
450638
+ const regex6 = new RegExp(CODE_TAG_REGEX.source, CODE_TAG_REGEX.flags);
450639
+ let match3;
450640
+ while ((match3 = regex6.exec(markdown)) != null) {
450641
+ const src = match3[2];
450642
+ if (src && isUrl(src)) {
450643
+ urls.push(src);
450644
+ }
450645
+ }
450646
+ return urls;
450647
+ }
450648
+ async function prefetchCodeSrcUrls(urls, context3) {
450649
+ const cache2 = /* @__PURE__ */ new Map();
450650
+ const unique = [...new Set(urls)];
450651
+ if (unique.length === 0) {
450652
+ return cache2;
450653
+ }
450654
+ const results = await Promise.allSettled(unique.map(async (url3) => {
450655
+ const response = await fetch(url3);
450656
+ if (!response.ok) {
450657
+ context3.logger.warn(`Failed to prefetch code from URL "${url3}" (status ${response.status})`);
450658
+ return { url: url3, content: void 0 };
450659
+ }
450660
+ const content5 = await response.text();
450661
+ return { url: url3, content: content5 };
450662
+ }));
450663
+ for (const result of results) {
450664
+ if (result.status === "fulfilled" && result.value.content !== void 0) {
450665
+ cache2.set(result.value.url, result.value.content);
450666
+ }
450667
+ }
450668
+ return cache2;
450669
+ }
450574
450670
  async function replaceReferencedCode({
450575
450671
  markdown,
450576
450672
  absolutePathToFernFolder,
450577
450673
  absolutePathToMarkdownFile,
450578
450674
  context: context3,
450579
450675
  // allow for custom markdown loader for testing
450580
- fileLoader = defaultFileLoader
450676
+ fileLoader = defaultFileLoader,
450677
+ urlCache
450581
450678
  }) {
450582
450679
  if (!markdown.includes("<Code")) {
450583
450680
  return markdown;
450584
450681
  }
450585
- const regex6 = /([ \t]*)<Code(?:\s+[^>]*?)?\s+src={?['"]([^'"]+)['"](?! \+)}?((?:\s+[^>]*)?)\/>/g;
450682
+ const regex6 = new RegExp(CODE_TAG_REGEX.source, CODE_TAG_REGEX.flags);
450586
450683
  let newMarkdown = markdown;
450587
450684
  let match3;
450588
450685
  while ((match3 = regex6.exec(markdown)) != null) {
@@ -450597,21 +450694,26 @@ async function replaceReferencedCode({
450597
450694
  let language;
450598
450695
  let title2;
450599
450696
  if (isUrl(src)) {
450600
- try {
450601
- const response = await fetch(src);
450602
- if (!response.ok) {
450603
- context3.logger.warn(`Failed to fetch code from URL "${src}" (status ${response.status}) referenced in ${absolutePathToMarkdownFile}`);
450697
+ const cached2 = urlCache?.get(src);
450698
+ if (cached2 !== void 0) {
450699
+ replacement = cached2;
450700
+ } else {
450701
+ try {
450702
+ const response = await fetch(src);
450703
+ if (!response.ok) {
450704
+ context3.logger.warn(`Failed to fetch code from URL "${src}" (status ${response.status}) referenced in ${absolutePathToMarkdownFile}`);
450705
+ break;
450706
+ }
450707
+ replacement = await response.text();
450708
+ } catch (e2) {
450709
+ context3.logger.warn(`Failed to fetch code from URL "${src}" referenced in ${absolutePathToMarkdownFile}: ${e2}`);
450604
450710
  break;
450605
450711
  }
450606
- replacement = await response.text();
450607
- const url3 = new URL(src);
450608
- const pathname = url3.pathname;
450609
- language = pathname.split(".").pop();
450610
- title2 = pathname.split("/").pop();
450611
- } catch (e2) {
450612
- context3.logger.warn(`Failed to fetch code from URL "${src}" referenced in ${absolutePathToMarkdownFile}: ${e2}`);
450613
- break;
450614
450712
  }
450713
+ const url3 = new URL(src);
450714
+ const pathname = url3.pathname;
450715
+ language = pathname.split(".").pop();
450716
+ title2 = pathname.split("/").pop();
450615
450717
  } else {
450616
450718
  const filepath = resolve6(src.startsWith("/") ? absolutePathToFernFolder : dirname6(absolutePathToMarkdownFile), RelativeFilePath2.of(src.replace(/^\//, "")));
450617
450719
  replacement = await fileLoader(filepath);
@@ -450694,12 +450796,13 @@ ${replacement}
450694
450796
  }
450695
450797
  return newMarkdown;
450696
450798
  }
450697
- var import_promises68;
450799
+ var import_promises68, CODE_TAG_REGEX;
450698
450800
  var init_replaceReferencedCode = __esm({
450699
450801
  "../docs-markdown-utils/lib/replaceReferencedCode.js"() {
450700
450802
  "use strict";
450701
450803
  init_lib8();
450702
450804
  import_promises68 = require("fs/promises");
450805
+ CODE_TAG_REGEX = /([ \t]*)<Code(?:\s+[^>]*?)?\s+src={?['"]([^'"]+)['"](?! \+)}?((?:\s+[^>]*)?)\/>/g;
450703
450806
  }
450704
450807
  });
450705
450808
 
@@ -450917,6 +451020,7 @@ var init_transformAtPrefixImports = __esm({
450917
451020
  // ../docs-markdown-utils/lib/index.js
450918
451021
  var lib_exports10 = {};
450919
451022
  __export(lib_exports10, {
451023
+ collectCodeSrcUrls: () => collectCodeSrcUrls,
450920
451024
  extractAttributeValueLiteral: () => extractAttributeValueLiteral,
450921
451025
  extractSingleLiteral: () => extractSingleLiteral,
450922
451026
  getMarkdownFormat: () => getMarkdownFormat,
@@ -450928,6 +451032,7 @@ __export(lib_exports10, {
450928
451032
  isValidRelativeSlug: () => isValidRelativeSlug,
450929
451033
  parseImagePaths: () => parseImagePaths,
450930
451034
  parseMarkdownToTree: () => parseMarkdownToTree,
451035
+ prefetchCodeSrcUrls: () => prefetchCodeSrcUrls,
450931
451036
  replaceImagePathsAndUrls: () => replaceImagePathsAndUrls,
450932
451037
  replaceReferencedCode: () => replaceReferencedCode,
450933
451038
  replaceReferencedMarkdown: () => replaceReferencedMarkdown,
@@ -460602,7 +460707,18 @@ var init_DocsDefinitionResolver = __esm({
460602
460707
  this.taskContext.logger.debug("Replacing referenced markdown and code files...");
460603
460708
  const refStart = performance.now();
460604
460709
  const seenReferencedFiles = /* @__PURE__ */ new Set();
460605
- for (const [relativePath, markdown] of Object.entries(this.parsedDocsConfig.pages)) {
460710
+ const pageEntries = Object.entries(this.parsedDocsConfig.pages);
460711
+ const allCodeSrcUrls = [];
460712
+ for (const [, markdown] of pageEntries) {
460713
+ allCodeSrcUrls.push(...collectCodeSrcUrls(markdown));
460714
+ }
460715
+ const prefetchStart = Date.now();
460716
+ const urlCache = await prefetchCodeSrcUrls(allCodeSrcUrls, this.taskContext);
460717
+ if (urlCache.size > 0) {
460718
+ const uniqueCount = new Set(allCodeSrcUrls).size;
460719
+ this.taskContext.logger.info(`Prefetched ${uniqueCount} external code URLs in ${Date.now() - prefetchStart}ms`);
460720
+ }
460721
+ for (const [relativePath, markdown] of pageEntries) {
460606
460722
  const result = await replaceReferencedMarkdown({
460607
460723
  markdown,
460608
460724
  absolutePathToFernFolder: this.docsWorkspace.absoluteFilePath,
@@ -460619,7 +460735,8 @@ var init_DocsDefinitionResolver = __esm({
460619
460735
  markdown: result.markdown,
460620
460736
  absolutePathToFernFolder: this.docsWorkspace.absoluteFilePath,
460621
460737
  absolutePathToMarkdownFile: this.resolveFilepath(relativePath),
460622
- context: this.taskContext
460738
+ context: this.taskContext,
460739
+ urlCache
460623
460740
  });
460624
460741
  const newMarkdown = transformAtPrefixImports({
460625
460742
  markdown: codeReplacedMarkdown,
@@ -582009,7 +582126,9 @@ var require_ReplayStep = __commonJS({
582009
582126
  "use strict";
582010
582127
  Object.defineProperty(exports2, "__esModule", { value: true });
582011
582128
  exports2.ReplayStep = void 0;
582129
+ var child_process_1 = require("child_process");
582012
582130
  var replay_run_1 = require_replay_run();
582131
+ var constants_1 = require_constants8();
582013
582132
  var BaseStep_1 = require_BaseStep();
582014
582133
  var ReplayStep = class extends BaseStep_1.BaseStep {
582015
582134
  config;
@@ -582051,17 +582170,21 @@ var require_ReplayStep = __commonJS({
582051
582170
  patchesWithConflicts: 0
582052
582171
  };
582053
582172
  }
582173
+ const stageOnly = this.config.stageOnly ?? false;
582054
582174
  const result = prepared != null ? await (0, replay_run_1.replayApply)(prepared, {
582055
- stageOnly: this.config.stageOnly ?? false,
582175
+ stageOnly,
582056
582176
  logger: this.logger
582057
582177
  }) : await (0, replay_run_1.replayRun)({
582058
582178
  outputDir: this.outputDir,
582059
582179
  cliVersion: this.cliVersion,
582060
582180
  generatorVersions: this.generatorVersions,
582061
- stageOnly: this.config.stageOnly ?? false,
582181
+ stageOnly,
582062
582182
  skipApplication: this.config.skipApplication,
582063
582183
  logger: this.logger
582064
582184
  });
582185
+ if (!stageOnly) {
582186
+ this.commitLockfileIfUncommitted();
582187
+ }
582065
582188
  if (result.failureReason != null) {
582066
582189
  return {
582067
582190
  executed: true,
@@ -582125,6 +582248,40 @@ var require_ReplayStep = __commonJS({
582125
582248
  warnings: report.warnings
582126
582249
  };
582127
582250
  }
582251
+ /**
582252
+ * Commits `.fern/replay.lock` when replay saved the lockfile to disk but
582253
+ * didn't create a `[fern-replay]` commit (e.g. no-patches flow with zero
582254
+ * new patches). Without this, `skipCommit = true` in GithubStep drops the
582255
+ * lockfile advance, freezing `previousGenerationSha` across runs.
582256
+ */
582257
+ commitLockfileIfUncommitted() {
582258
+ try {
582259
+ const status = (0, child_process_1.execFileSync)("git", ["status", "--porcelain", "--", ".fern/replay.lock"], {
582260
+ cwd: this.outputDir,
582261
+ encoding: "utf-8",
582262
+ stdio: ["pipe", "pipe", "pipe"]
582263
+ }).trim();
582264
+ if (status.length === 0) {
582265
+ return;
582266
+ }
582267
+ (0, child_process_1.execFileSync)("git", ["add", "--", ".fern/replay.lock"], {
582268
+ cwd: this.outputDir,
582269
+ stdio: "pipe"
582270
+ });
582271
+ (0, child_process_1.execFileSync)("git", [
582272
+ "-c",
582273
+ `user.name=${constants_1.FERN_BOT_NAME}`,
582274
+ "-c",
582275
+ `user.email=${constants_1.FERN_BOT_EMAIL}`,
582276
+ "commit",
582277
+ "-m",
582278
+ "[fern-replay] advance lockfile"
582279
+ ], { cwd: this.outputDir, stdio: "pipe" });
582280
+ this.logger.debug("ReplayStep: committed uncommitted lockfile advance.");
582281
+ } catch (error50) {
582282
+ this.logger.debug("ReplayStep: failed to commit lockfile advance: " + String(error50));
582283
+ }
582284
+ }
582128
582285
  };
582129
582286
  exports2.ReplayStep = ReplayStep;
582130
582287
  }
@@ -674562,7 +674719,7 @@ var NoConflictingRequestWrapperPropertiesRule = {
674562
674719
  }
674563
674720
  violations.push({
674564
674721
  severity: "fatal",
674565
- message: `Multiple request properties have the name ${source_default.bold(name2)}. This is not suitable for code generation. Use the "name" property to deconflict.
674722
+ message: `Multiple request properties have the name ${source_default.bold(name2)}. This is not suitable for code generation. Use the "name" property (or "x-fern-parameter-name" in OpenAPI) to deconflict.
674566
674723
  ` + propertiesWithName.map((property24) => ` - ${convertRequestWrapperPropertyToString(property24)}`).join("\n")
674567
674724
  });
674568
674725
  }
@@ -674598,6 +674755,26 @@ function getRequestWrapperPropertiesByName({ endpoint: endpoint3, service, relat
674598
674755
  });
674599
674756
  }
674600
674757
  }
674758
+ if (service["path-parameters"] != null) {
674759
+ for (const [pathParameterKey, pathParameter] of Object.entries(service["path-parameters"])) {
674760
+ if (isVariablePathParameter(pathParameter)) {
674761
+ continue;
674762
+ }
674763
+ addProperty3(pathParameterKey, {
674764
+ type: "service-path-parameter",
674765
+ pathParameterKey
674766
+ });
674767
+ }
674768
+ }
674769
+ for (const [pathParameterKey, pathParameter] of Object.entries(getEndpointPathParameters(endpoint3))) {
674770
+ if (isVariablePathParameter(pathParameter)) {
674771
+ continue;
674772
+ }
674773
+ addProperty3(pathParameterKey, {
674774
+ type: "endpoint-path-parameter",
674775
+ pathParameterKey
674776
+ });
674777
+ }
674601
674778
  if (service.headers != null) {
674602
674779
  for (const [headerKey, header] of Object.entries(service.headers)) {
674603
674780
  addProperty3(getHeaderName3({ headerKey, header }).name, {
@@ -674653,6 +674830,10 @@ function convertRequestWrapperPropertyToString(property24) {
674653
674830
  switch (property24.type) {
674654
674831
  case "service-header":
674655
674832
  return `Service header "${property24.headerKey}"`;
674833
+ case "service-path-parameter":
674834
+ return `Service path parameter "${property24.pathParameterKey}"`;
674835
+ case "endpoint-path-parameter":
674836
+ return `Path parameter "${property24.pathParameterKey}"`;
674656
674837
  case "endpoint-header":
674657
674838
  return `Endpoint header "${property24.headerKey}"`;
674658
674839
  case "endpoint-query-parameter":
@@ -674688,7 +674869,7 @@ function getCamelCaseNormalizedCollisions(nameToProperties) {
674688
674869
  }
674689
674870
  violations.push({
674690
674871
  severity: "fatal",
674691
- message: `Multiple request properties resolve to the same generated name ${source_default.bold(normalizedName)} after camelCase normalization. This causes broken generated code. Use the "name" property to disambiguate.
674872
+ message: `Multiple request properties resolve to the same generated name ${source_default.bold(normalizedName)} after camelCase normalization. This causes broken generated code. Use the "name" property (or "x-fern-parameter-name" in OpenAPI) to disambiguate.
674692
674873
  ` + entries24.map((entry) => ` - ${convertRequestWrapperPropertyToString(entry.property)} (name: "${entry.rawName}")`).join("\n")
674693
674874
  });
674694
674875
  }
@@ -688415,7 +688596,7 @@ var AccessTokenPosthogManager = class {
688415
688596
  properties: {
688416
688597
  ...event,
688417
688598
  ...event.properties,
688418
- version: "5.65.3",
688599
+ version: "5.65.5",
688419
688600
  usingAccessToken: true,
688420
688601
  ...getRunIdProperties()
688421
688602
  }
@@ -688481,7 +688662,7 @@ var UserPosthogManager = class {
688481
688662
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
688482
688663
  event: "CLI",
688483
688664
  properties: {
688484
- version: "5.65.3",
688665
+ version: "5.65.5",
688485
688666
  ...event,
688486
688667
  ...event.properties,
688487
688668
  usingAccessToken: false,
@@ -869577,7 +869758,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
869577
869758
  var LOGS_FOLDER_NAME = "logs";
869578
869759
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
869579
869760
  function getCliSource() {
869580
- const version7 = "5.65.3";
869761
+ const version7 = "5.65.5";
869581
869762
  return `cli@${version7}`;
869582
869763
  }
869583
869764
  var DebugLogger = class {
@@ -902139,7 +902320,7 @@ var LegacyDocsPublisher = class {
902139
902320
  previewId,
902140
902321
  disableTemplates: void 0,
902141
902322
  skipUpload,
902142
- cliVersion: "5.65.3",
902323
+ cliVersion: "5.65.5",
902143
902324
  loginCommand: "fern auth login"
902144
902325
  });
902145
902326
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -941515,8 +941696,7 @@ var EndpointSnippetGenerator6 = class {
941515
941696
  args.push(...this.getNamedParameterArgs({
941516
941697
  kind: "PathParameters",
941517
941698
  namedParameters: pathParameters,
941518
- values: snippet.pathParameters,
941519
- reservedNames: this.getInlinedBodyPropertyNames({ request: request7 })
941699
+ values: snippet.pathParameters
941520
941700
  }));
941521
941701
  args.push(...this.getNamedParameterArgs({
941522
941702
  kind: "QueryParameters",
@@ -941579,23 +941759,7 @@ var EndpointSnippetGenerator6 = class {
941579
941759
  }
941580
941760
  return args;
941581
941761
  }
941582
- /**
941583
- * Property names of an inlined request body (both Ruby names and wire values). Path
941584
- * parameters that collide with these are renamed in the generated SDK, so snippets
941585
- * must rename them the same way.
941586
- */
941587
- getInlinedBodyPropertyNames({ request: request7 }) {
941588
- const names2 = /* @__PURE__ */ new Set();
941589
- if (request7.body?.type !== "properties") {
941590
- return names2;
941591
- }
941592
- for (const property24 of request7.body.value) {
941593
- names2.add(this.context.getPropertyName(property24.name.name));
941594
- names2.add(property24.name.wireValue);
941595
- }
941596
- return names2;
941597
- }
941598
- getNamedParameterArgs({ kind, namedParameters, values: values2, reservedNames }) {
941762
+ getNamedParameterArgs({ kind, namedParameters, values: values2 }) {
941599
941763
  const args = [];
941600
941764
  this.context.errors.scope(kind);
941601
941765
  if (namedParameters != null) {
@@ -941609,15 +941773,8 @@ var EndpointSnippetGenerator6 = class {
941609
941773
  if (ruby_exports.TypeLiteral.isNop(value2)) {
941610
941774
  continue;
941611
941775
  }
941612
- let name2 = this.context.getPropertyName(parameter6.name.name);
941613
- if (reservedNames != null && reservedNames.has(name2)) {
941614
- name2 = `${name2}_path_param`;
941615
- while (reservedNames.has(name2)) {
941616
- name2 = `${name2}_`;
941617
- }
941618
- }
941619
941776
  args.push(ruby_exports.keywordArgument({
941620
- name: name2,
941777
+ name: this.context.getPropertyName(parameter6.name.name),
941621
941778
  value: value2
941622
941779
  }));
941623
941780
  }
@@ -968473,7 +968630,7 @@ function getAutomationContextFromEnv() {
968473
968630
  config_branch: process.env.FERN_CONFIG_BRANCH,
968474
968631
  config_pr_number: process.env.FERN_CONFIG_PR_NUMBER,
968475
968632
  trigger: process.env.GITHUB_EVENT_NAME,
968476
- cli_version: "5.65.3"
968633
+ cli_version: "5.65.5"
968477
968634
  };
968478
968635
  }
968479
968636
  function isAutomationMode() {
@@ -969305,7 +969462,7 @@ var CliContext = class _CliContext {
969305
969462
  if (false) {
969306
969463
  this.logger.error("CLI_VERSION is not defined");
969307
969464
  }
969308
- return "5.65.3";
969465
+ return "5.65.5";
969309
969466
  }
969310
969467
  getCliName() {
969311
969468
  if (false) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.65.3",
2
+ "version": "5.65.5",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",