Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: custom leading pages #24

Merged
merged 1 commit into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
YfmTocItem,
} from './models';

import RefsService from './services/refs';

const INCLUDER_NAME = 'openapi';

class OpenApiIncluderError extends Error {
Expand All @@ -54,10 +55,12 @@
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 @@
data,
writePath,
leadingPage,
contentPath,
filter,
noindex,
vars,
Expand Down Expand Up @@ -162,7 +166,13 @@

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 @@
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 @@ -184,7 +199,7 @@
href: href,
});
} else {
section.href = href;

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

View workflow job for this annotation

GitHub Actions / build (18.x)

Assignment to property of function parameter 'section'
}
}

Expand All @@ -193,6 +208,7 @@
vars: YfmPreset;
writePath: string;
allRefs: Refs;
contentPath: string;
leadingPage: OpenApiIncluderParams['leadingPage'];
filter?: OpenApiIncluderParams['filter'];
noindex?: OpenApiIncluderParams['noindex'];
Expand All @@ -206,14 +222,18 @@
};

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'
});

const applyHidden = matchFilter(hidden || {}, vars, (endpoint) => {
endpoint.hidden = true;

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

View workflow job for this annotation

GitHub Actions / build (18.x)

Assignment to property of function parameter 'endpoint'
});

const leadingPageSpecRenderMode = leadingPage?.spec?.renderMode ?? SPEC_RENDER_MODE_DEFAULT;
Expand All @@ -234,12 +254,18 @@

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 @@
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
19 changes: 19 additions & 0 deletions src/includer/services/argv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {CustomTag, OpenApiIncluderParams} from '../models';

type Config = Exclude<OpenApiIncluderParams['tags'], undefined>;

let _config: Config = {};

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

function tags() {
return _config;
}

function tag(id: string): CustomTag | undefined {
return _config[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
Loading