@fern-api/fern-api-dev 5.8.0 → 5.8.1-4-g1edc77ebd26

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 +252 -38
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -511686,7 +511686,8 @@ var CheckRulesConfig = external_exports.object({
511686
511686
  "valid-local-references": CheckRuleSeverity.optional(),
511687
511687
  "no-circular-redirects": CheckRuleSeverity.optional(),
511688
511688
  "valid-docs-endpoints": CheckRuleSeverity.optional(),
511689
- "missing-redirects": CheckRuleSeverity.optional()
511689
+ "missing-redirects": CheckRuleSeverity.optional(),
511690
+ "valid-changelog-slug": CheckRuleSeverity.optional()
511690
511691
  });
511691
511692
  var CheckConfig = external_exports.object({
511692
511693
  rules: CheckRulesConfig.optional()
@@ -514649,7 +514650,8 @@ var CheckRulesConfig2 = schemas_exports6.object({
514649
514650
  validLocalReferences: schemas_exports6.property("valid-local-references", CheckRuleSeverity3.optional()),
514650
514651
  noCircularRedirects: schemas_exports6.property("no-circular-redirects", CheckRuleSeverity3.optional()),
514651
514652
  validDocsEndpoints: schemas_exports6.property("valid-docs-endpoints", CheckRuleSeverity3.optional()),
514652
- missingRedirects: schemas_exports6.property("missing-redirects", CheckRuleSeverity3.optional())
514653
+ missingRedirects: schemas_exports6.property("missing-redirects", CheckRuleSeverity3.optional()),
514654
+ validChangelogSlug: schemas_exports6.property("valid-changelog-slug", CheckRuleSeverity3.optional())
514653
514655
  });
514654
514656
 
514655
514657
  // ../configuration/lib/docs-yml/schemas/sdk/serialization/resources/docs/types/CheckConfig.js
@@ -544583,7 +544585,8 @@ async function parseNavigationOverlayFromDocsYml({ docsYmlContent, langFernDir:
544583
544585
  subtitle: typeof productObj.subtitle === "string" ? productObj.subtitle : void 0,
544584
544586
  announcement: void 0,
544585
544587
  tabs: void 0,
544586
- navigation: void 0
544588
+ navigation: void 0,
544589
+ versions: void 0
544587
544590
  };
544588
544591
  if (isPlainObject4(productObj.announcement)) {
544589
544592
  const message = extractString(productObj.announcement, "message");
@@ -544592,28 +544595,28 @@ async function parseNavigationOverlayFromDocsYml({ docsYmlContent, langFernDir:
544592
544595
  }
544593
544596
  }
544594
544597
  if (typeof productObj.path === "string") {
544595
- const resolvedNavFilePath = import_path22.default.resolve(overlayDir, productObj.path);
544596
- if (!resolvedNavFilePath.startsWith(overlayDir)) {
544597
- context3.logger.warn(`Invalid path in product overlay: "${productObj.path}" escapes the translations directory. Skipping.`);
544598
- overlay.products.push(productOverlay);
544599
- continue;
544598
+ const navFile = await loadNavOverlayFile({
544599
+ relativeNavPath: productObj.path,
544600
+ overlayDir,
544601
+ overlayKind: "product",
544602
+ context: context3
544603
+ });
544604
+ if (navFile != null) {
544605
+ productOverlay.tabs = navFile.tabs;
544606
+ productOverlay.navigation = navFile.navigation;
544600
544607
  }
544601
- const navFilePath = resolvedNavFilePath;
544602
- if (await doesPathExist(navFilePath)) {
544603
- try {
544604
- const navContent = jsYaml.load(await (0, import_promises14.readFile)(navFilePath, "utf-8"));
544605
- if (isPlainObject4(navContent)) {
544606
- const navObj = navContent;
544607
- if (isPlainObject4(navObj.tabs)) {
544608
- productOverlay.tabs = parseTabOverlays(navObj.tabs);
544609
- }
544610
- if (Array.isArray(navObj.navigation)) {
544611
- productOverlay.navigation = parseNavigationItemOverlays(navObj.navigation);
544612
- }
544613
- }
544614
- } catch (error50) {
544615
- context3.logger.warn(`Failed to load translation nav file "${navFilePath}": ${String(error50)}`);
544608
+ }
544609
+ if (Array.isArray(productObj.versions)) {
544610
+ productOverlay.versions = [];
544611
+ for (const version7 of productObj.versions) {
544612
+ if (!isPlainObject4(version7)) {
544613
+ continue;
544616
544614
  }
544615
+ productOverlay.versions.push(await parseVersionOverlay({
544616
+ versionObj: version7,
544617
+ overlayDir,
544618
+ context: context3
544619
+ }));
544617
544620
  }
544618
544621
  }
544619
544622
  overlay.products.push(productOverlay);
@@ -544625,11 +544628,11 @@ async function parseNavigationOverlayFromDocsYml({ docsYmlContent, langFernDir:
544625
544628
  if (!isPlainObject4(version7)) {
544626
544629
  continue;
544627
544630
  }
544628
- const versionObj = version7;
544629
- overlay.versions.push({
544630
- slug: typeof versionObj.slug === "string" ? versionObj.slug : void 0,
544631
- displayName: typeof versionObj["display-name"] === "string" ? versionObj["display-name"] : void 0
544632
- });
544631
+ overlay.versions.push(await parseVersionOverlay({
544632
+ versionObj: version7,
544633
+ overlayDir,
544634
+ context: context3
544635
+ }));
544633
544636
  }
544634
544637
  }
544635
544638
  if (Array.isArray(docsYmlContent.navigation)) {
@@ -544637,6 +544640,51 @@ async function parseNavigationOverlayFromDocsYml({ docsYmlContent, langFernDir:
544637
544640
  }
544638
544641
  return overlay;
544639
544642
  }
544643
+ async function parseVersionOverlay({ versionObj, overlayDir, context: context3 }) {
544644
+ const versionOverlay = {
544645
+ slug: typeof versionObj.slug === "string" ? versionObj.slug : void 0,
544646
+ displayName: typeof versionObj["display-name"] === "string" ? versionObj["display-name"] : void 0,
544647
+ tabs: void 0,
544648
+ navigation: void 0
544649
+ };
544650
+ if (typeof versionObj.path === "string") {
544651
+ const navFile = await loadNavOverlayFile({
544652
+ relativeNavPath: versionObj.path,
544653
+ overlayDir,
544654
+ overlayKind: "version",
544655
+ context: context3
544656
+ });
544657
+ if (navFile != null) {
544658
+ versionOverlay.tabs = navFile.tabs;
544659
+ versionOverlay.navigation = navFile.navigation;
544660
+ }
544661
+ }
544662
+ return versionOverlay;
544663
+ }
544664
+ async function loadNavOverlayFile({ relativeNavPath, overlayDir, overlayKind, context: context3 }) {
544665
+ const resolvedNavFilePath = import_path22.default.resolve(overlayDir, relativeNavPath);
544666
+ if (!resolvedNavFilePath.startsWith(overlayDir)) {
544667
+ context3.logger.warn(`Invalid path in ${overlayKind} overlay: "${relativeNavPath}" escapes the translations directory. Skipping.`);
544668
+ return void 0;
544669
+ }
544670
+ if (!await doesPathExist(resolvedNavFilePath)) {
544671
+ return void 0;
544672
+ }
544673
+ try {
544674
+ const navContent = jsYaml.load(await (0, import_promises14.readFile)(resolvedNavFilePath, "utf-8"));
544675
+ if (!isPlainObject4(navContent)) {
544676
+ return void 0;
544677
+ }
544678
+ const navObj = navContent;
544679
+ return {
544680
+ tabs: isPlainObject4(navObj.tabs) ? parseTabOverlays(navObj.tabs) : void 0,
544681
+ navigation: Array.isArray(navObj.navigation) ? parseNavigationItemOverlays(navObj.navigation) : void 0
544682
+ };
544683
+ } catch (error50) {
544684
+ context3.logger.warn(`Failed to load translation nav file "${resolvedNavFilePath}": ${String(error50)}`);
544685
+ return void 0;
544686
+ }
544687
+ }
544640
544688
  function parseTabOverlays(tabsObj) {
544641
544689
  const result = {};
544642
544690
  for (const [tabId, tabConfig] of Object.entries(tabsObj)) {
@@ -622584,7 +622632,7 @@ var AccessTokenPosthogManager = class {
622584
622632
  properties: {
622585
622633
  ...event,
622586
622634
  ...event.properties,
622587
- version: "5.8.0",
622635
+ version: "5.8.1-4-g1edc77ebd26",
622588
622636
  usingAccessToken: true
622589
622637
  }
622590
622638
  });
@@ -622638,7 +622686,7 @@ var UserPosthogManager = class {
622638
622686
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
622639
622687
  event: "CLI",
622640
622688
  properties: {
622641
- version: "5.8.0",
622689
+ version: "5.8.1-4-g1edc77ebd26",
622642
622690
  ...event,
622643
622691
  ...event.properties,
622644
622692
  usingAccessToken: false,
@@ -804579,7 +804627,7 @@ function applyChildOverlays(children2, parent, overlay) {
804579
804627
  const scopedOverlay = {
804580
804628
  tabs: productOverlay.tabs ?? overlay.tabs,
804581
804629
  products: void 0,
804582
- versions: overlay.versions,
804630
+ versions: productOverlay.versions ?? overlay.versions,
804583
804631
  announcement: productOverlay.announcement ?? overlay.announcement,
804584
804632
  navigation: productOverlay.navigation ?? overlay.navigation,
804585
804633
  navbarLinks: overlay.navbarLinks
@@ -804597,11 +804645,19 @@ function applyChildOverlays(children2, parent, overlay) {
804597
804645
  return walkAndApply(child, overlay);
804598
804646
  }
804599
804647
  const versionOverlay = findVersionOverlay(childObj, overlay.versions ?? [], index3);
804600
- const walked = walkAndApply(child, overlay);
804601
804648
  if (versionOverlay != null) {
804649
+ const scopedOverlay = {
804650
+ tabs: versionOverlay.tabs ?? overlay.tabs,
804651
+ products: void 0,
804652
+ versions: void 0,
804653
+ announcement: overlay.announcement,
804654
+ navigation: versionOverlay.navigation ?? overlay.navigation,
804655
+ navbarLinks: overlay.navbarLinks
804656
+ };
804657
+ const walked = walkAndApply(child, scopedOverlay);
804602
804658
  return applyVersionOverlayToNode(walked, versionOverlay);
804603
804659
  }
804604
- return walked;
804660
+ return walkAndApply(child, overlay);
804605
804661
  });
804606
804662
  }
804607
804663
  if (parentType === "tabbed") {
@@ -819754,12 +819810,14 @@ var rules_exports = {};
819754
819810
  __export(rules_exports, {
819755
819811
  AccentColorContrastRule: () => AccentColorContrastRule,
819756
819812
  AllRolesMustBeDeclaredRule: () => AllRolesMustBeDeclaredRule,
819813
+ CHANGELOG_FEED_ALLOWED_SLUGS: () => CHANGELOG_FEED_ALLOWED_SLUGS,
819757
819814
  FilepathsExistRule: () => FilepathsExistRule,
819758
819815
  MissingRedirectsRule: () => MissingRedirectsRule,
819759
819816
  NoCircularRedirectsRule: () => NoCircularRedirectsRule,
819760
819817
  OnlyVersionedNavigation: () => OnlyVersionedNavigation,
819761
819818
  TabWithHrefRule: () => TabWithHrefRule,
819762
819819
  TranslationDirectoriesExistRule: () => TranslationDirectoriesExistRule,
819820
+ ValidChangelogSlugRule: () => ValidChangelogSlugRule,
819763
819821
  ValidDocsEndpoints: () => ValidDocsEndpoints,
819764
819822
  ValidFileTypes: () => ValidFileTypes,
819765
819823
  ValidFrontmatter: () => ValidFrontmatter,
@@ -819770,6 +819828,8 @@ __export(rules_exports, {
819770
819828
  ValidateProductFileRule: () => ValidateProductFileRule,
819771
819829
  ValidateVersionFileRule: () => ValidateVersionFileRule,
819772
819830
  enforceBackgroundTheme: () => enforceBackgroundTheme,
819831
+ getEffectiveChangelogSlugLastSegment: () => getEffectiveChangelogSlugLastSegment,
819832
+ isAllowedChangelogSlug: () => isAllowedChangelogSlug,
819773
819833
  validateTheme: () => validateTheme
819774
819834
  });
819775
819835
 
@@ -820796,6 +820856,148 @@ function buildExpectedDirectoryTree({ translationsDirExists, missingDirs, fernFo
820796
820856
  return lines.join("\n");
820797
820857
  }
820798
820858
 
820859
+ // ../yaml/docs-validator/lib/rules/valid-changelog-slug/valid-changelog-slug.js
820860
+ init_lodash();
820861
+ var CHANGELOG_FEED_ALLOWED_SLUGS = [
820862
+ "changelog",
820863
+ "changelogs",
820864
+ "release-notes",
820865
+ "releasenotes",
820866
+ "whats-new",
820867
+ "whatsnew"
820868
+ ];
820869
+ var DEFAULT_CHANGELOG_TITLE3 = "Changelog";
820870
+ function getEffectiveChangelogSlugLastSegment(config5) {
820871
+ const raw = config5.slug ?? kebabCase_default(config5.title ?? DEFAULT_CHANGELOG_TITLE3);
820872
+ const segments = raw.split("/").filter((s9) => s9.length > 0);
820873
+ return segments[segments.length - 1] ?? "";
820874
+ }
820875
+ function isAllowedChangelogSlug(lastSegment) {
820876
+ return CHANGELOG_FEED_ALLOWED_SLUGS.includes(lastSegment);
820877
+ }
820878
+ function collectChangelogLocations(items, breadcrumb) {
820879
+ if (items == null) {
820880
+ return [];
820881
+ }
820882
+ const out = [];
820883
+ for (const item of items) {
820884
+ if (isChangelog(item)) {
820885
+ out.push({
820886
+ where: `${breadcrumb} > changelog (${item.changelog})`,
820887
+ slug: item.slug,
820888
+ title: item.title
820889
+ });
820890
+ continue;
820891
+ }
820892
+ if (isSection3(item)) {
820893
+ const next2 = `${breadcrumb} > section "${item.section}"`;
820894
+ out.push(...collectChangelogLocations(item.contents, next2));
820895
+ }
820896
+ }
820897
+ return out;
820898
+ }
820899
+ function collectFromTabs(tabs, breadcrumb) {
820900
+ if (tabs == null) {
820901
+ return [];
820902
+ }
820903
+ const out = [];
820904
+ for (const [tabId, tab2] of Object.entries(tabs)) {
820905
+ if (tab2.changelog != null) {
820906
+ out.push({
820907
+ where: `${breadcrumb} > tab "${tabId}" (changelog: ${tab2.changelog})`,
820908
+ slug: tab2.slug,
820909
+ title: tab2.displayName
820910
+ });
820911
+ }
820912
+ }
820913
+ return out;
820914
+ }
820915
+ function collectFromNavigation(navigation2, breadcrumb) {
820916
+ if (navigation2 == null || !Array.isArray(navigation2) || navigation2.length === 0) {
820917
+ return [];
820918
+ }
820919
+ if (isTabbedNavigation(navigation2)) {
820920
+ const out = [];
820921
+ for (const item of navigation2) {
820922
+ const next2 = `${breadcrumb} > tab "${item.tab}"`;
820923
+ if ("layout" in item && Array.isArray(item.layout)) {
820924
+ out.push(...collectChangelogLocations(item.layout, next2));
820925
+ }
820926
+ if ("variants" in item && Array.isArray(item.variants)) {
820927
+ for (const variant of item.variants) {
820928
+ const variantBreadcrumb = `${next2} > variant "${variant.title}"`;
820929
+ out.push(...collectChangelogLocations(variant.layout, variantBreadcrumb));
820930
+ }
820931
+ }
820932
+ }
820933
+ return out;
820934
+ }
820935
+ return collectChangelogLocations(navigation2, breadcrumb);
820936
+ }
820937
+ function violationsForLocations(locations) {
820938
+ const violations = [];
820939
+ for (const loc of locations) {
820940
+ const lastSegment = getEffectiveChangelogSlugLastSegment(loc);
820941
+ if (lastSegment === "" || isAllowedChangelogSlug(lastSegment)) {
820942
+ continue;
820943
+ }
820944
+ const allowed = CHANGELOG_FEED_ALLOWED_SLUGS.join(", ");
820945
+ const sourceField = loc.slug != null ? `slug: "${loc.slug}"` : `title: "${loc.title ?? DEFAULT_CHANGELOG_TITLE3}"`;
820946
+ violations.push({
820947
+ severity: "error",
820948
+ message: `Changelog at ${loc.where} resolves to URL segment "${lastSegment}" (from ${sourceField}). The docs server only serves changelog feeds (.rss, .atom, .json) when the final URL segment is one of: ${allowed}. Rename the changelog's title or set an explicit slug to one of these values, otherwise subscribers will get a 404 when they request the feed.`
820949
+ });
820950
+ }
820951
+ return violations;
820952
+ }
820953
+ var ValidChangelogSlugRule = {
820954
+ name: "valid-changelog-slug",
820955
+ create: () => {
820956
+ return {
820957
+ file: async ({ config: config5 }) => {
820958
+ const locations = [
820959
+ ...collectFromNavigation(config5.navigation, "navigation"),
820960
+ ...collectFromTabs(config5.tabs, "tabs")
820961
+ ];
820962
+ return violationsForLocations(locations);
820963
+ },
820964
+ versionFile: async ({ path: path106, content: content5 }) => {
820965
+ const parseResult = await validateVersionConfigFileSchema({ value: content5 });
820966
+ if (parseResult.type !== "success") {
820967
+ return [];
820968
+ }
820969
+ const versionConfig = parseResult.contents;
820970
+ const locations = [
820971
+ ...collectFromNavigation(versionConfig.navigation, `version "${path106}" navigation`),
820972
+ ...collectFromTabs(versionConfig.tabs, `version "${path106}" tabs`)
820973
+ ];
820974
+ return violationsForLocations(locations);
820975
+ },
820976
+ productFile: async ({ path: path106, content: content5 }) => {
820977
+ const parseResult = await validateProductConfigFileSchema({ value: content5 });
820978
+ if (parseResult.type !== "success") {
820979
+ return [];
820980
+ }
820981
+ const productConfig = parseResult.contents;
820982
+ const locations = [
820983
+ ...collectFromNavigation(productConfig.navigation, `product "${path106}" navigation`),
820984
+ ...collectFromTabs(productConfig.tabs, `product "${path106}" tabs`)
820985
+ ];
820986
+ return violationsForLocations(locations);
820987
+ }
820988
+ };
820989
+ }
820990
+ };
820991
+ function isChangelog(item) {
820992
+ return item?.changelog != null;
820993
+ }
820994
+ function isSection3(item) {
820995
+ return item?.section != null;
820996
+ }
820997
+ function isTabbedNavigation(navigation2) {
820998
+ return Array.isArray(navigation2) && navigation2.length > 0 && navigation2[0]?.tab != null;
820999
+ }
821000
+
820799
821001
  // ../yaml/docs-validator/lib/rules/valid-docs-endpoints/valid-docs-endpoints.js
820800
821002
  var ValidDocsEndpoints = {
820801
821003
  name: "valid-docs-endpoints",
@@ -843275,7 +843477,8 @@ var allRules = [
843275
843477
  ValidDocsEndpoints,
843276
843478
  AllRolesMustBeDeclaredRule,
843277
843479
  ValidFrontmatter,
843278
- TranslationDirectoriesExistRule
843480
+ TranslationDirectoriesExistRule,
843481
+ ValidChangelogSlugRule
843279
843482
  // ValidMarkdownFileReferences
843280
843483
  ];
843281
843484
  function getAllRules3(exclusions) {
@@ -843304,7 +843507,8 @@ var CHECK_RULE_CONFIG_TO_RULE_NAME = {
843304
843507
  validLocalReferences: ValidLocalReferencesRule.name,
843305
843508
  noCircularRedirects: NoCircularRedirectsRule.name,
843306
843509
  validDocsEndpoints: ValidDocsEndpoints.name,
843307
- missingRedirects: MissingRedirectsRule.name
843510
+ missingRedirects: MissingRedirectsRule.name,
843511
+ validChangelogSlug: ValidChangelogSlugRule.name
843308
843512
  };
843309
843513
  function buildSeverityOverrides(checkConfig) {
843310
843514
  const severityOverrides = /* @__PURE__ */ new Map();
@@ -847384,7 +847588,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
847384
847588
  var LOGS_FOLDER_NAME = "logs";
847385
847589
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
847386
847590
  function getCliSource() {
847387
- const version7 = "5.8.0";
847591
+ const version7 = "5.8.1-4-g1edc77ebd26";
847388
847592
  return `cli@${version7}`;
847389
847593
  }
847390
847594
  var DebugLogger = class {
@@ -856171,6 +856375,16 @@ var definitions6 = {
856171
856375
  type: "null"
856172
856376
  }
856173
856377
  ]
856378
+ },
856379
+ "valid-changelog-slug": {
856380
+ oneOf: [
856381
+ {
856382
+ $ref: "#/definitions/docs.CheckRuleSeverity"
856383
+ },
856384
+ {
856385
+ type: "null"
856386
+ }
856387
+ ]
856174
856388
  }
856175
856389
  },
856176
856390
  additionalProperties: false
@@ -860027,7 +860241,7 @@ var LegacyDocsPublisher = class {
860027
860241
  previewId,
860028
860242
  disableTemplates: void 0,
860029
860243
  skipUpload,
860030
- cliVersion: "5.8.0",
860244
+ cliVersion: "5.8.1-4-g1edc77ebd26",
860031
860245
  loginCommand: "fern auth login"
860032
860246
  });
860033
860247
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -934469,7 +934683,7 @@ var CliContext = class _CliContext {
934469
934683
  if (false) {
934470
934684
  this.logger.error("CLI_VERSION is not defined");
934471
934685
  }
934472
- return "5.8.0";
934686
+ return "5.8.1-4-g1edc77ebd26";
934473
934687
  }
934474
934688
  getCliName() {
934475
934689
  if (false) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.8.0",
2
+ "version": "5.8.1-4-g1edc77ebd26",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",