Skip to content

Commit

Permalink
allow merging subpackages
Browse files Browse the repository at this point in the history
  • Loading branch information
abvthecity committed Jun 14, 2024
1 parent fc18577 commit ac09844
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 24 deletions.
14 changes: 10 additions & 4 deletions packages/cli/configuration/fern/definition/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -444,18 +444,24 @@ types:
- LinkConfiguration
- ApiPackageConfiguration

SubpackageOrSubpackages:
discriminated: false
union:
- string
- list<string>

ApiPackageConfiguration:
properties:
package:
type: string
docs: |
The title of the api package that will be displayed in the sidebar.
Alternatively, if this is a Subpackage ID. The title of this section will be inherited from the subpackage.
Alternatively, `subpackage` is unset, and this is a Subpackage ID. The title of this section will be inherited from the subpackage.
Any endpoints that are not explicitly defined within the contents of this object will be implicitly included.
title:
type: optional<string>
docs: This overrides the title of the package.
subpackage:
type: optional<SubpackageOrSubpackages>
docs: If `subpackage` is set, this section will inherit the endpoints from the specified subpackage(s).
summary:
type: optional<string>
docs: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ export declare namespace ParsedApiNavigationItem {
export interface Package {
type: "package";
package: string; // title or subpackage ID
titleOverride: string | undefined;
subpackages: string[]; // subpackage IDs
summaryAbsolutePath: AbsoluteFilePath | undefined;
contents: ParsedApiNavigationItem[];
slug: string | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ function parseApiNavigationItem(
{
type: "package",
package: item.package,
titleOverride: item.title,
subpackages: typeof item.subpackage === "string" ? [item.subpackage] : item.subpackage ?? [],
summaryAbsolutePath: resolveFilepath(item.summary, absolutePathToConfig),
contents: item.contents.flatMap((value) => parseApiNavigationItem(value, absolutePathToConfig)),
slug: item.slug,
Expand All @@ -607,7 +607,7 @@ function parseApiNavigationItem(
([key, values]): ParsedApiNavigationItem.Package => ({
type: "package",
package: key,
titleOverride: undefined,
subpackages: [],
summaryAbsolutePath: undefined,
contents: values.flatMap((value) => parseApiNavigationItem(value, absolutePathToConfig)),
hidden: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ export interface ApiPackageConfiguration {
/**
* The title of the api package that will be displayed in the sidebar.
*
* Alternatively, if this is a Subpackage ID. The title of this section will be inherited from the subpackage.
* Alternatively, `subpackage` is unset, and this is a Subpackage ID. The title of this section will be inherited from the subpackage.
* Any endpoints that are not explicitly defined within the contents of this object will be implicitly included.
*/
package: string;
/** This overrides the title of the package. */
title?: string;
/** If `subpackage` is set, this section will inherit the endpoints from the specified subpackage(s). */
subpackage?: FernDocsConfig.SubpackageOrSubpackages;
/** Relative path to the markdown file. This summary is displayed at the top of the API section. */
summary?: string;
contents: FernDocsConfig.ApiNavigationItems;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/

export type SubpackageOrSubpackages = string | string[];
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export * from "./PageConfiguration";
export * from "./SectionConfiguration";
export * from "./ApiSectionConfiguration";
export * from "./ApiNavigationItem";
export * from "./SubpackageOrSubpackages";
export * from "./ApiPackageConfiguration";
export * from "./ApiNavigationItems";
export * from "./LinkConfiguration";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const ApiPackageConfiguration: core.serialization.ObjectSchema<
FernDocsConfig.ApiPackageConfiguration
> = core.serialization.object({
package: core.serialization.string(),
title: core.serialization.string().optional(),
subpackage: core.serialization.lazy(async () => (await import("../../..")).SubpackageOrSubpackages).optional(),
summary: core.serialization.string().optional(),
contents: core.serialization.lazy(async () => (await import("../../..")).ApiNavigationItems),
slug: core.serialization.string().optional(),
Expand All @@ -23,7 +23,7 @@ export const ApiPackageConfiguration: core.serialization.ObjectSchema<
export declare namespace ApiPackageConfiguration {
interface Raw {
package: string;
title?: string | null;
subpackage?: serializers.SubpackageOrSubpackages.Raw | null;
summary?: string | null;
contents: serializers.ApiNavigationItems.Raw;
slug?: string | null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/

import * as serializers from "../../..";
import * as FernDocsConfig from "../../../../api";
import * as core from "../../../../core";

export const SubpackageOrSubpackages: core.serialization.Schema<
serializers.SubpackageOrSubpackages.Raw,
FernDocsConfig.SubpackageOrSubpackages
> = core.serialization.undiscriminatedUnion([
core.serialization.string(),
core.serialization.list(core.serialization.string()),
]);

export declare namespace SubpackageOrSubpackages {
type Raw = string | string[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export * from "./PageConfiguration";
export * from "./SectionConfiguration";
export * from "./ApiSectionConfiguration";
export * from "./ApiNavigationItem";
export * from "./SubpackageOrSubpackages";
export * from "./ApiPackageConfiguration";
export * from "./ApiNavigationItems";
export * from "./LinkConfiguration";
Expand Down
78 changes: 66 additions & 12 deletions packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,6 @@ export class ApiReferenceNodeConverter {
parentSlug: FernNavigation.SlugGenerator,
idgen: NodeIdGenerator
): FernNavigation.ApiPackageNode {
const subpackage = this.#holder.getSubpackage(pkg.package);

const overviewPageId =
pkg.summaryAbsolutePath != null
? FernNavigation.PageId(this.toRelativeFilepath(pkg.summaryAbsolutePath))
Expand All @@ -153,13 +151,72 @@ export class ApiReferenceNodeConverter {
const maybeFullSlug =
pkg.summaryAbsolutePath != null ? this.markdownFilesToFullSlugs.get(pkg.summaryAbsolutePath) : undefined;

if (pkg.subpackages.length > 0) {
let subpackage: APIV1Read.ApiDefinitionPackage | undefined = undefined;
let i = 0;
while (subpackage == null && i < pkg.subpackages.length) {
subpackage = this.#holder.getSubpackage(pkg.subpackages[i]!);

Check warning on line 158 in packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts

View workflow job for this annotation

GitHub Actions / eslint

Forbidden non-null assertion
i++;
}

if (subpackage != null) {
const subpackageId = ApiDefinitionHolder.getSubpackageId(subpackage);
const subpackageNodeId = idgen.append(subpackageId);
this.#visitedSubpackages.add(subpackageId);
this.#nodeIdToSubpackageId.set(subpackageNodeId.get(), subpackageId);
const urlSlug =
pkg.slug ??
(isSubpackage(subpackage)
? subpackage.urlSlug
: this.apiSection.slug ?? kebabCase(this.apiSection.title));
const slug = parentSlug.apply({
fullSlug: maybeFullSlug?.split("/"),
skipUrlSlug: pkg.skipUrlSlug,
urlSlug
});
const convertedItems: FernNavigation.ApiPackageChild[] = [];
pkg.subpackages.forEach((subpackageId) => {
const subpackage = this.#holder.getSubpackage(subpackageId);
if (subpackage == null) {
this.taskContext.logger.error(
`Subpackage ${subpackageId} not found in ${this.apiDefinitionId}`
);
return;
}
this.#visitedSubpackages.add(subpackageId);
this.#nodeIdToSubpackageId.set(subpackageNodeId.get(), subpackageId);
convertedItems.push(
...this.#convertApiNavigationItems(pkg.contents, subpackage, slug, subpackageNodeId)
);
});
return {
id: subpackageNodeId.get(),
type: "apiPackage",
children: convertedItems,
title: pkg.package,
slug: slug.get(),
icon: pkg.icon,
hidden: pkg.hidden,
overviewPageId,
availability: undefined,
apiDefinitionId: this.apiDefinitionId,
pointsTo: undefined
};
}
}

const subpackage = this.#holder.getSubpackage(pkg.package);

if (subpackage != null) {
const subpackageId = ApiDefinitionHolder.getSubpackageId(subpackage);
const subpackageNodeId = idgen.append(subpackageId);
this.#visitedSubpackages.add(subpackageId);
this.#nodeIdToSubpackageId.set(subpackageNodeId.get(), subpackageId);
const urlSlug =
pkg.slug ?? (isSubpackage(subpackage) ? subpackage.urlSlug : kebabCase(pkg.titleOverride ?? ""));
pkg.slug ??
(isSubpackage(subpackage)
? subpackage.urlSlug
: this.apiSection.slug ?? kebabCase(this.apiSection.title));
const slug = parentSlug.apply({
fullSlug: maybeFullSlug?.split("/"),
skipUrlSlug: pkg.skipUrlSlug,
Expand All @@ -170,11 +227,9 @@ export class ApiReferenceNodeConverter {
id: subpackageNodeId.get(),
type: "apiPackage",
children: convertedItems,
title:
pkg.titleOverride ??
(isSubpackage(subpackage)
? subpackage.displayName ?? titleCase(subpackage.name)
: this.apiSection.title),
title: isSubpackage(subpackage)
? subpackage.displayName ?? titleCase(subpackage.name)
: this.apiSection.title,
slug: slug.get(),
icon: pkg.icon,
hidden: pkg.hidden,
Expand All @@ -184,7 +239,7 @@ export class ApiReferenceNodeConverter {
pointsTo: undefined
};
} else {
const urlSlug = pkg.slug ?? kebabCase(pkg.titleOverride ?? pkg.package);
const urlSlug = pkg.slug ?? kebabCase(pkg.package);
const slug = parentSlug.apply({
fullSlug: maybeFullSlug?.split("/"),
skipUrlSlug: pkg.skipUrlSlug,
Expand All @@ -195,7 +250,7 @@ export class ApiReferenceNodeConverter {
id: idgen.append(kebabCase(pkg.package)).get(),
type: "apiPackage",
children: convertedItems,
title: pkg.titleOverride ?? pkg.package,
title: pkg.package,
slug: slug.get(),
icon: pkg.icon,
hidden: pkg.hidden,
Expand Down Expand Up @@ -291,8 +346,7 @@ export class ApiReferenceNodeConverter {
}
const subpackage = this.#holder.getSubpackage(subpackageId);
if (subpackage == null) {
// eslint-disable-next-line no-console
console.error(`Subpackage ${subpackageId} not found in ${this.apiDefinitionId}`);
this.taskContext.logger.error(`Subpackage ${subpackageId} not found in ${this.apiDefinitionId}`);
return;
}

Expand Down

0 comments on commit ac09844

Please sign in to comment.