@fern-api/fern-api-dev 5.30.1 → 5.30.2

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 -147
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -668026,7 +668026,7 @@ var AccessTokenPosthogManager = class {
668026
668026
  properties: {
668027
668027
  ...event,
668028
668028
  ...event.properties,
668029
- version: "5.30.1",
668029
+ version: "5.30.2",
668030
668030
  usingAccessToken: true,
668031
668031
  ...getRunIdProperties()
668032
668032
  }
@@ -668090,7 +668090,7 @@ var UserPosthogManager = class {
668090
668090
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
668091
668091
  event: "CLI",
668092
668092
  properties: {
668093
- version: "5.30.1",
668093
+ version: "5.30.2",
668094
668094
  ...event,
668095
668095
  ...event.properties,
668096
668096
  usingAccessToken: false,
@@ -859866,7 +859866,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
859866
859866
  var LOGS_FOLDER_NAME = "logs";
859867
859867
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
859868
859868
  function getCliSource() {
859869
- const version7 = "5.30.1";
859869
+ const version7 = "5.30.2";
859870
859870
  return `cli@${version7}`;
859871
859871
  }
859872
859872
  var DebugLogger = class {
@@ -862627,6 +862627,8 @@ init_lib6();
862627
862627
  var import_path72 = __toESM(require("path"), 1);
862628
862628
 
862629
862629
  // ../cli-v2/lib/commands/docs/link/check/LinkCheckClient.js
862630
+ var MAX_RETRIES = 3;
862631
+ var RETRY_DELAY_MS = 2e3;
862630
862632
  var LinkCheckClient = class {
862631
862633
  baseUrl;
862632
862634
  token;
@@ -862644,161 +862646,139 @@ var LinkCheckClient = class {
862644
862646
  let workingLinks = 0;
862645
862647
  let pagesScrapedSoFar = 0;
862646
862648
  let linksCheckedSoFar = 0;
862647
- let serverError;
862648
- let sawComplete = false;
862649
- const url3 = `${this.baseUrl}?${new URLSearchParams({ domain: domain3 }).toString()}`;
862650
- const response = await fetch(url3, {
862651
- headers: {
862652
- Authorization: `Bearer ${this.token}`,
862653
- Accept: "text/event-stream"
862654
- }
862655
- });
862656
- if (!response.ok) {
862657
- let errorMessage;
862658
- try {
862659
- const body = await response.json();
862660
- if (typeof body === "object" && body != null) {
862661
- const obj = body;
862662
- if (typeof obj.message === "string") {
862663
- errorMessage = obj.message;
862664
- } else if (typeof obj.error === "string") {
862665
- errorMessage = obj.error;
862666
- } else {
862667
- errorMessage = response.statusText;
862649
+ let scrapeJobId = null;
862650
+ let checkJobId = null;
862651
+ let scrapeComplete = false;
862652
+ while (!scrapeComplete) {
862653
+ const params2 = new URLSearchParams({ domain: domain3, phase: "scrape" });
862654
+ if (scrapeJobId != null) {
862655
+ params2.set("scrapeJobId", scrapeJobId);
862656
+ }
862657
+ const events = await this.fetchSseStream(params2);
862658
+ let batchAdvanced = false;
862659
+ for (const event of events) {
862660
+ switch (event.type) {
862661
+ case "sitemap_fetched": {
862662
+ if (isSitemapFetchedData(event.data)) {
862663
+ totalPages = event.data.totalPages;
862664
+ callbacks.onSitemapFetched?.({ totalPages: event.data.totalPages });
862665
+ }
862666
+ break;
862667
+ }
862668
+ case "page_scraped": {
862669
+ if (isPageScrapedData(event.data)) {
862670
+ totalPages = event.data.totalPages;
862671
+ pagesScrapedSoFar = event.data.pageIndex;
862672
+ callbacks.onPageScraped?.(event.data);
862673
+ }
862674
+ break;
862675
+ }
862676
+ case "scrape_batch_complete": {
862677
+ if (isScrapeBatchCompleteData(event.data)) {
862678
+ scrapeJobId = event.data.scrapeJobId;
862679
+ batchAdvanced = true;
862680
+ }
862681
+ break;
862682
+ }
862683
+ case "scrape_complete": {
862684
+ if (isScrapeCompleteData(event.data)) {
862685
+ checkJobId = event.data.jobId;
862686
+ totalPages = event.data.totalPages;
862687
+ totalLinks = event.data.totalLinks;
862688
+ scrapeComplete = true;
862689
+ batchAdvanced = true;
862690
+ }
862691
+ break;
862692
+ }
862693
+ case "error": {
862694
+ if (isErrorData(event.data)) {
862695
+ throw new LinkCheckError(0, event.data.message);
862696
+ }
862697
+ break;
862668
862698
  }
862669
- } else {
862670
- errorMessage = response.statusText;
862671
862699
  }
862672
- } catch {
862673
- errorMessage = response.statusText;
862674
862700
  }
862675
- throw new LinkCheckError(response.status, errorMessage);
862701
+ if (!scrapeComplete && !batchAdvanced) {
862702
+ callbacks.onStreamInterrupted?.({
862703
+ phase: "scraping pages",
862704
+ pagesScraped: pagesScrapedSoFar,
862705
+ totalPages,
862706
+ linksChecked: 0,
862707
+ totalLinks: 0
862708
+ });
862709
+ return {
862710
+ totalPages: pagesScrapedSoFar,
862711
+ totalLinks: 0,
862712
+ workingLinks: 0,
862713
+ brokenLinks,
862714
+ blockedLinks,
862715
+ durationMs: Date.now() - startTime
862716
+ };
862717
+ }
862676
862718
  }
862677
- const reader = response.body?.getReader();
862678
- if (reader == null) {
862679
- throw new LinkCheckError(0, "No response body received from server.");
862719
+ if (checkJobId == null) {
862720
+ throw new LinkCheckError(0, "Scraping completed but no check job ID was returned.");
862680
862721
  }
862681
- const decoder = new TextDecoder();
862682
- let buffer = "";
862683
- const processLine = (line) => {
862684
- let payload;
862685
- if (line.startsWith("data: ")) {
862686
- payload = line.slice(6);
862687
- } else if (line.startsWith("data:")) {
862688
- payload = line.slice(5);
862689
- } else {
862690
- return;
862691
- }
862692
- let event;
862693
- try {
862694
- const parsed = JSON.parse(payload);
862695
- if (parsed == null || typeof parsed !== "object" || !("type" in parsed) || typeof parsed.type !== "string" || !("data" in parsed) || typeof parsed.data !== "object" || parsed.data == null) {
862696
- return;
862697
- }
862698
- event = parsed;
862699
- } catch {
862700
- return;
862701
- }
862702
- switch (event.type) {
862703
- case "sitemap_fetched": {
862704
- if (isSitemapFetchedData(event.data)) {
862705
- totalPages = event.data.totalPages;
862706
- callbacks.onSitemapFetched?.({ totalPages: event.data.totalPages });
862707
- }
862708
- break;
862709
- }
862710
- case "page_scraped": {
862711
- if (isPageScrapedData(event.data)) {
862712
- totalPages = event.data.totalPages;
862713
- pagesScrapedSoFar = event.data.pageIndex + 1;
862714
- callbacks.onPageScraped?.({
862715
- ...event.data,
862716
- pageIndex: event.data.pageIndex + 1
862717
- });
862722
+ let checkComplete = false;
862723
+ while (!checkComplete) {
862724
+ const params2 = new URLSearchParams({ domain: domain3, phase: "check", jobId: checkJobId });
862725
+ const events = await this.fetchSseStream(params2);
862726
+ let batchAdvanced = false;
862727
+ for (const event of events) {
862728
+ switch (event.type) {
862729
+ case "links_check_started": {
862730
+ if (isLinksCheckStartedData(event.data)) {
862731
+ totalLinks = event.data.totalLinks;
862732
+ }
862733
+ break;
862718
862734
  }
862719
- break;
862720
- }
862721
- case "links_check_started": {
862722
- if (isLinksCheckStartedData(event.data)) {
862723
- totalLinks = event.data.totalLinks;
862735
+ case "link_check_progress": {
862736
+ if (isLinkCheckProgressData(event.data)) {
862737
+ totalLinks = event.data.totalLinks;
862738
+ linksCheckedSoFar = event.data.linksChecked;
862739
+ callbacks.onLinkChecked?.(event.data);
862740
+ }
862741
+ break;
862724
862742
  }
862725
- break;
862726
- }
862727
- case "link_check_progress": {
862728
- if (isLinkCheckProgressData(event.data)) {
862729
- totalLinks = event.data.totalLinks;
862730
- linksCheckedSoFar = event.data.linksChecked;
862731
- callbacks.onLinkChecked?.(event.data);
862743
+ case "link_checked": {
862744
+ if (isLinkCheckedData(event.data)) {
862745
+ brokenLinks.push(toBrokenLink(event.data));
862746
+ }
862747
+ break;
862732
862748
  }
862733
- break;
862734
- }
862735
- case "link_checked": {
862736
- if (isLinkCheckedData(event.data)) {
862737
- brokenLinks.push(toBrokenLink(event.data));
862749
+ case "link_blocked": {
862750
+ if (isLinkCheckedData(event.data)) {
862751
+ blockedLinks.push(toBrokenLink(event.data));
862752
+ }
862753
+ break;
862738
862754
  }
862739
- break;
862740
- }
862741
- case "complete": {
862742
- if (isCompleteData(event.data)) {
862743
- sawComplete = true;
862744
- totalPages = event.data.totalPages;
862745
- totalLinks = event.data.totalLinks;
862746
- workingLinks = event.data.workingLinks;
862747
- brokenLinks.length = 0;
862748
- for (const link3 of event.data.brokenLinks) {
862749
- if (typeof link3 !== "object" || link3 == null) {
862750
- continue;
862751
- }
862752
- if (isLinkCheckedData(link3)) {
862753
- brokenLinks.push(toBrokenLink(link3));
862754
- }
862755
+ case "batch_complete": {
862756
+ if (isBatchCompleteData(event.data)) {
862757
+ batchAdvanced = true;
862755
862758
  }
862756
- blockedLinks.length = 0;
862757
- for (const link3 of event.data.blockedLinks) {
862758
- if (typeof link3 !== "object" || link3 == null) {
862759
- continue;
862760
- }
862761
- if (isLinkCheckedData(link3)) {
862762
- blockedLinks.push(toBrokenLink(link3));
862763
- }
862759
+ break;
862760
+ }
862761
+ case "complete": {
862762
+ if (isCompleteData(event.data)) {
862763
+ checkComplete = true;
862764
+ batchAdvanced = true;
862765
+ totalPages = event.data.totalPages;
862766
+ totalLinks = event.data.totalLinks;
862767
+ workingLinks = event.data.workingLinks;
862764
862768
  }
862769
+ break;
862765
862770
  }
862766
- break;
862767
- }
862768
- case "error": {
862769
- if (isErrorData(event.data)) {
862770
- serverError = event.data.message;
862771
+ case "error": {
862772
+ if (isErrorData(event.data)) {
862773
+ throw new LinkCheckError(0, event.data.message);
862774
+ }
862775
+ break;
862771
862776
  }
862772
- break;
862773
862777
  }
862774
862778
  }
862775
- };
862776
- while (true) {
862777
- const { done, value: value2 } = await reader.read();
862778
- if (done) {
862779
- break;
862780
- }
862781
- buffer += decoder.decode(value2, { stream: true });
862782
- const lines = buffer.split("\n");
862783
- buffer = lines.pop() ?? "";
862784
- for (const line of lines) {
862785
- processLine(line);
862786
- }
862787
- }
862788
- buffer += decoder.decode();
862789
- if (buffer.length > 0) {
862790
- for (const line of buffer.split("\n")) {
862791
- processLine(line);
862792
- }
862793
- }
862794
- if (serverError != null) {
862795
- throw new LinkCheckError(0, serverError);
862796
- }
862797
- if (!sawComplete) {
862798
- const phase = totalLinks > 0 ? "checking links" : pagesScrapedSoFar > 0 ? "scraping pages" : "connecting";
862799
- if (brokenLinks.length > 0 || blockedLinks.length > 0) {
862779
+ if (!checkComplete && !batchAdvanced) {
862800
862780
  callbacks.onStreamInterrupted?.({
862801
- phase,
862781
+ phase: "checking links",
862802
862782
  pagesScraped: pagesScrapedSoFar,
862803
862783
  totalPages,
862804
862784
  linksChecked: linksCheckedSoFar,
@@ -862813,8 +862793,6 @@ var LinkCheckClient = class {
862813
862793
  durationMs: Date.now() - startTime
862814
862794
  };
862815
862795
  }
862816
- const detail = phase === "connecting" ? "The server closed the connection before sending any data. This may indicate a timeout or network issue." : `The connection was lost while ${phase} (${pagesScrapedSoFar} pages scraped, ${linksCheckedSoFar}/${totalLinks} links checked). This is usually caused by a server timeout.`;
862817
- throw new LinkCheckError(0, detail);
862818
862796
  }
862819
862797
  return {
862820
862798
  totalPages,
@@ -862825,7 +862803,111 @@ var LinkCheckClient = class {
862825
862803
  durationMs: Date.now() - startTime
862826
862804
  };
862827
862805
  }
862806
+ /**
862807
+ * Opens an SSE connection with retries and returns all parsed events.
862808
+ * Retries on connection failures up to MAX_RETRIES times.
862809
+ */
862810
+ async fetchSseStream(params2) {
862811
+ let lastError;
862812
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
862813
+ if (attempt > 0) {
862814
+ await new Promise((resolve15) => setTimeout(resolve15, RETRY_DELAY_MS * attempt));
862815
+ }
862816
+ try {
862817
+ return await this.readSseStream(params2);
862818
+ } catch (error50) {
862819
+ if (error50 instanceof LinkCheckError) {
862820
+ throw error50;
862821
+ }
862822
+ lastError = error50 instanceof Error ? error50 : new Error(String(error50));
862823
+ }
862824
+ }
862825
+ throw new LinkCheckError(0, `Connection failed after ${MAX_RETRIES + 1} attempts: ${lastError?.message ?? "unknown error"}`);
862826
+ }
862827
+ /**
862828
+ * Opens a single SSE connection and reads all events until the stream closes.
862829
+ */
862830
+ async readSseStream(params2) {
862831
+ const url3 = `${this.baseUrl}?${params2.toString()}`;
862832
+ const response = await fetch(url3, {
862833
+ headers: {
862834
+ Authorization: `Bearer ${this.token}`,
862835
+ Accept: "text/event-stream"
862836
+ }
862837
+ });
862838
+ if (!response.ok) {
862839
+ const errorMessage = await this.extractErrorMessage(response);
862840
+ throw new LinkCheckError(response.status, errorMessage);
862841
+ }
862842
+ const reader = response.body?.getReader();
862843
+ if (reader == null) {
862844
+ throw new LinkCheckError(0, "No response body received from server.");
862845
+ }
862846
+ const decoder = new TextDecoder();
862847
+ let buffer = "";
862848
+ const events = [];
862849
+ while (true) {
862850
+ const { done, value: value2 } = await reader.read();
862851
+ if (done) {
862852
+ break;
862853
+ }
862854
+ buffer += decoder.decode(value2, { stream: true });
862855
+ const lines = buffer.split("\n");
862856
+ buffer = lines.pop() ?? "";
862857
+ for (const line of lines) {
862858
+ const event = parseSseLine(line);
862859
+ if (event != null) {
862860
+ events.push(event);
862861
+ }
862862
+ }
862863
+ }
862864
+ buffer += decoder.decode();
862865
+ if (buffer.length > 0) {
862866
+ for (const line of buffer.split("\n")) {
862867
+ const event = parseSseLine(line);
862868
+ if (event != null) {
862869
+ events.push(event);
862870
+ }
862871
+ }
862872
+ }
862873
+ return events;
862874
+ }
862875
+ async extractErrorMessage(response) {
862876
+ try {
862877
+ const body = await response.json();
862878
+ if (typeof body === "object" && body != null) {
862879
+ const obj = body;
862880
+ if (typeof obj.message === "string") {
862881
+ return obj.message;
862882
+ }
862883
+ if (typeof obj.error === "string") {
862884
+ return obj.error;
862885
+ }
862886
+ }
862887
+ } catch {
862888
+ }
862889
+ return response.statusText;
862890
+ }
862828
862891
  };
862892
+ function parseSseLine(line) {
862893
+ let payload;
862894
+ if (line.startsWith("data: ")) {
862895
+ payload = line.slice(6);
862896
+ } else if (line.startsWith("data:")) {
862897
+ payload = line.slice(5);
862898
+ } else {
862899
+ return void 0;
862900
+ }
862901
+ try {
862902
+ const parsed = JSON.parse(payload);
862903
+ if (parsed == null || typeof parsed !== "object" || !("type" in parsed) || typeof parsed.type !== "string" || !("data" in parsed) || typeof parsed.data !== "object" || parsed.data == null) {
862904
+ return void 0;
862905
+ }
862906
+ return parsed;
862907
+ } catch {
862908
+ return void 0;
862909
+ }
862910
+ }
862829
862911
  function isSitemapFetchedData(data2) {
862830
862912
  return typeof data2.totalPages === "number";
862831
862913
  }
@@ -862844,6 +862926,15 @@ function isLinkCheckedData(data2) {
862844
862926
  function isCompleteData(data2) {
862845
862927
  return typeof data2.totalPages === "number" && typeof data2.totalLinks === "number" && typeof data2.workingLinks === "number" && Array.isArray(data2.brokenLinks) && Array.isArray(data2.blockedLinks);
862846
862928
  }
862929
+ function isScrapeBatchCompleteData(data2) {
862930
+ return typeof data2.scrapeJobId === "string" && typeof data2.hasMore === "boolean";
862931
+ }
862932
+ function isScrapeCompleteData(data2) {
862933
+ return typeof data2.jobId === "string" && typeof data2.totalPages === "number" && typeof data2.totalLinks === "number";
862934
+ }
862935
+ function isBatchCompleteData(data2) {
862936
+ return typeof data2.jobId === "string" && typeof data2.hasMore === "boolean";
862937
+ }
862847
862938
  function isErrorData(data2) {
862848
862939
  return typeof data2.message === "string";
862849
862940
  }
@@ -878607,7 +878698,7 @@ var LegacyDocsPublisher = class {
878607
878698
  previewId,
878608
878699
  disableTemplates: void 0,
878609
878700
  skipUpload,
878610
- cliVersion: "5.30.1",
878701
+ cliVersion: "5.30.2",
878611
878702
  loginCommand: "fern auth login"
878612
878703
  });
878613
878704
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -953017,7 +953108,7 @@ function getAutomationContextFromEnv() {
953017
953108
  config_branch: process.env.FERN_CONFIG_BRANCH,
953018
953109
  config_pr_number: process.env.FERN_CONFIG_PR_NUMBER,
953019
953110
  trigger: process.env.GITHUB_EVENT_NAME,
953020
- cli_version: "5.30.1"
953111
+ cli_version: "5.30.2"
953021
953112
  };
953022
953113
  }
953023
953114
  function isAutomationMode() {
@@ -953843,7 +953934,7 @@ var CliContext = class _CliContext {
953843
953934
  if (false) {
953844
953935
  this.logger.error("CLI_VERSION is not defined");
953845
953936
  }
953846
- return "5.30.1";
953937
+ return "5.30.2";
953847
953938
  }
953848
953939
  getCliName() {
953849
953940
  if (false) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.30.1",
2
+ "version": "5.30.2",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",