Skip to content

Commit

Permalink
feat: custom leading pages
Browse files Browse the repository at this point in the history
  • Loading branch information
v8tenko committed Nov 28, 2023
1 parent 5a7beb0 commit 5c2cd06
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 17 deletions.
62 changes: 49 additions & 13 deletions src/includer/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import assert from 'assert';
import RefsService from './services/refs';
import ArgvService from './services/argv';

import assert from 'assert';
import {dirname, join, resolve} from 'path';
import {mkdir, writeFile} from 'fs/promises';
import {readFileSync} from 'fs';
import {matchFilter} from './utils';

import {dump} from 'js-yaml';
Expand Down Expand Up @@ -33,8 +36,6 @@ import {
YfmTocItem,
} from './models';

import RefsService from './services/refs';

const INCLUDER_NAME = 'openapi';

class OpenApiIncluderError extends Error {
Expand All @@ -54,10 +55,12 @@ async function includerFunction(params: IncluderFunctionParams<OpenApiIncluderPa
writeBasePath,
tocPath,
vars,
passedParams: {input, leadingPage = {}, filter, noindex, hidden, sandbox},
passedParams: {input, leadingPage = {}, filter, noindex, hidden, sandbox, tags = {}},
index,
} = params;

ArgvService.init({tags});

const tocDirPath = dirname(tocPath);

const contentPath =
Expand Down Expand Up @@ -91,6 +94,7 @@ async function includerFunction(params: IncluderFunctionParams<OpenApiIncluderPa
data,
writePath,
leadingPage,
contentPath,
filter,
noindex,
vars,
Expand Down Expand Up @@ -162,7 +166,13 @@ async function generateToc(params: GenerateTocParams): Promise<void> {

section.items = endpointsOfTag.map((endpoint) => handleEndpointRender(endpoint, id));

addLeadingPage(section, leadingPageMode, leadingPageName, join(id, 'index.md'));
const custom = ArgvService.tag(tag.name);

const customLeadingPageName = custom?.name || leadingPageName;

if (!custom?.hidden) {
addLeadingPage(section, leadingPageMode, customLeadingPageName, join(id, 'index.md'));
}

toc.items.push(section);
});
Expand All @@ -171,7 +181,12 @@ async function generateToc(params: GenerateTocParams): Promise<void> {
toc.items.push(handleEndpointRender(endpoint));
}

addLeadingPage(toc, leadingPageMode, leadingPageName, 'index.md');
const root = ArgvService.tag('__root__');
const rootLadingPageName = root?.name || leadingPageName;

if (!root?.hidden) {
addLeadingPage(toc, leadingPageMode, rootLadingPageName, 'index.md');
}

await mkdir(dirname(writePath), {recursive: true});
await writeFile(join(writePath, 'toc.yaml'), dump(toc));
Expand All @@ -193,6 +208,7 @@ export type GenerateContentParams = {
vars: YfmPreset;
writePath: string;
allRefs: Refs;
contentPath: string;
leadingPage: OpenApiIncluderParams['leadingPage'];
filter?: OpenApiIncluderParams['filter'];
noindex?: OpenApiIncluderParams['noindex'];
Expand All @@ -206,7 +222,11 @@ type EndpointRoute = {
};

async function generateContent(params: GenerateContentParams): Promise<void> {
const {data, writePath, leadingPage, filter, noindex, hidden, vars, sandbox} = params;
const {data, writePath, leadingPage, filter, noindex, hidden, vars, sandbox, contentPath} =
params;

const customLeadingPageDir = dirname(contentPath);

const filterContent = filterUsefullContent(filter, vars);
const applyNoindex = matchFilter(noindex || {}, vars, (endpoint) => {
endpoint.noindex = true;

Check warning on line 232 in src/includer/index.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Assignment to property of function parameter 'endpoint'
Expand Down Expand Up @@ -234,12 +254,18 @@ async function generateContent(params: GenerateContentParams): Promise<void> {

spec = filterContent(spec);

const main: string = generators.main({data, info, spec, leadingPageSpecRenderMode});
const root = ArgvService.tag('__root__');

results.push({
path: join(writePath, 'index.md'),
content: main,
});
if (!root?.hidden) {
const mainContent = root?.path
? readFileSync(join(customLeadingPageDir, root.path)).toString()
: generators.main({data, info, spec, leadingPageSpecRenderMode});

results.push({
path: join(writePath, 'index.md'),
content: mainContent,
});
}

spec.tags.forEach((tag, id) => {
const {endpoints} = tag;
Expand All @@ -248,9 +274,19 @@ async function generateContent(params: GenerateContentParams): Promise<void> {
results.push(handleEndpointIncluder(endpoint, join(writePath, id), sandbox));
});

const custom = ArgvService.tag(tag.name);

if (custom?.hidden) {
return;
}

const content = custom?.path
? readFileSync(join(customLeadingPageDir, custom.path)).toString()
: generators.section(tag);

results.push({
path: join(writePath, id, 'index.md'),
content: generators.section(tag),
content,
});
});

Expand Down
11 changes: 11 additions & 0 deletions src/includer/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,12 @@ export type OpenApiFilter = {
tag?: string;
};

export type CustomTag = {
hidden?: boolean;
name?: string;
path?: string;
};

export type OpenApiIncluderParams = {
allowAnonymousObjects?: boolean;
input: string;
Expand All @@ -288,6 +294,11 @@ export type OpenApiIncluderParams = {
tabName?: string;
host?: string;
};
tags: {
[tag: string]: CustomTag | undefined;
/** top-level leading page */
__root__?: CustomTag;
};
};

export type OpenJSONSchema = JSONSchema6 & {
Expand Down
21 changes: 21 additions & 0 deletions src/includer/services/argv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {CustomTag, OpenApiIncluderParams} from '../models';

type Config = Pick<OpenApiIncluderParams, 'tags'>;

let _config: Config = {
tags: {},
};

function init(config: Config) {
_config = config;
}

function tags() {
return _config.tags;
}

function tag(id: string): CustomTag | undefined {
return _config.tags[id];
}

export default {init, tags, tag};
18 changes: 14 additions & 4 deletions src/includer/ui/main.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import ArgvService from '../services/argv';

import stringify from 'json-stringify-safe';

import {sep} from 'path';
Expand Down Expand Up @@ -69,10 +71,18 @@ function description(text?: string) {
function sections({tags, endpoints}: Specification) {
const content = [];

// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
const taggedLinks = Array.from(tags).map(([_, {name, id}]: [any, Tag]) =>
link(name, id + sep + 'index.md'),
);
const taggedLinks = Array.from(tags)
.map(([_, {name, id}]: [unknown, Tag]) => {
const custom = ArgvService.tag(name);

if (custom?.hidden) {
return undefined;
}

return link(name, id + sep + 'index.md');
})
.filter(Boolean) as string[];

if (taggedLinks.length) {
content.push(title(2)(TAGS_SECTION_NAME), list(taggedLinks));
}
Expand Down

0 comments on commit 5c2cd06

Please sign in to comment.