Skip to content

Commit

Permalink
feat: generate API as TypeDoc docs (#1705)
Browse files Browse the repository at this point in the history
* feat: generate API docs

* refactor: simplify output location, updated instructions, allow TypeDoc config options to be passed

* chore(deps): update yarn.lock
  • Loading branch information
huwshimi authored Nov 19, 2024
1 parent f01e8b6 commit e67fa69
Show file tree
Hide file tree
Showing 7 changed files with 567 additions and 5 deletions.
22 changes: 22 additions & 0 deletions docs/src/pages/reference/configuration/output.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,28 @@ Default Value: `en`.

Give you the possibility to set the locale for the mock generation. It is used by faker, see the list of available options [here](https://fakerjs.dev/guide/localization.html#available-locales). It should also be strongly typed using `defineConfig`.

### docs

Type: `Boolean | Object`.

Default Value: `false`.

Will generate API docs using [TypeDoc](https://typedoc.org/). by default these docs will be in Markdown format.

TypeDoc can be configured by passing the [options](https://typedoc.org/options/) to the `docs` object or by creating a config file e.g. `typedoc.config.mjs` in your project root (see the [config docs](https://typedoc.org/options/configuration/#options) for a full list of supported file names) or by passing a config filename to the `configPath` option below.

See the TypeDoc [configuration documentation](https://typedoc.org/options/) for more details.

The `docs` option can take some properties to customize the generation if you set it to an object. If you set it to `true`, the default options will be used.

When no output directory destination is specified in `config`, the file will be output to the `docs` directory by default.

#### configPath

Type: `String`.

Use to specify a TypeDoc config filename. This can be useful if your project already has a TypeDoc config for other docs.

### clean

Type: `Boolean | String[]`.
Expand Down
3 changes: 2 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"@types/lodash.uniq": "^4.5.9",
"@types/lodash.uniqby": "^4.7.9",
"@types/lodash.uniqwith": "^4.5.9",
"@types/micromatch": "^4.0.9"
"@types/micromatch": "^4.0.9",
"typedoc": "0.26.11"
},
"dependencies": {
"@apidevtools/swagger-parser": "^10.1.0",
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
} from 'openapi3-ts/oas30';
// @ts-ignore // FIXME when running `yarn test` getting `orval:test: ../core/src/types.ts(12,34): error TS7016: Could not find a declaration file for module 'swagger2openapi'. '/home/maxim/orval/node_modules/swagger2openapi/index.js' implicitly has an 'any' type.`
import type swagger2openapi from 'swagger2openapi';
import { TypeDocOptions } from 'typedoc';

export interface Options {
output?: string | OutputOptions;
Expand Down Expand Up @@ -50,6 +51,7 @@ export type NormalizedOutputOptions = {
client: OutputClient | OutputClientFunc;
httpClient: OutputHttpClient;
clean: boolean | string[];
docs: boolean | OutputDocsOptions;
prettier: boolean;
tslint: boolean;
biome: boolean;
Expand Down Expand Up @@ -174,6 +176,7 @@ export type OutputOptions = {
client?: OutputClient | OutputClientFunc;
httpClient?: OutputHttpClient;
clean?: boolean | string[];
docs?: boolean | OutputDocsOptions;
prettier?: boolean;
tslint?: boolean;
biome?: boolean;
Expand Down Expand Up @@ -239,6 +242,10 @@ export const OutputMode = {

export type OutputMode = (typeof OutputMode)[keyof typeof OutputMode];

export type OutputDocsOptions = {
configPath?: string;
} & Partial<TypeDocOptions>;

// TODO: add support for other mock types (like cypress or playwright)
export const OutputMockType = {
MSW: 'msw',
Expand Down
5 changes: 4 additions & 1 deletion packages/orval/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@
"lodash.uniq": "^4.5.0",
"openapi3-ts": "4.2.2",
"string-argv": "^0.3.2",
"tsconfck": "^2.0.1"
"tsconfck": "^2.0.1",
"typedoc": "0.26.11",
"typedoc-plugin-markdown": "4.2.10",
"typescript": "^5.6.3"
}
}
1 change: 1 addition & 0 deletions packages/orval/src/utils/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export const normalizeOptions = async (
mode: normalizeOutputMode(outputOptions.mode ?? mode),
mock,
clean: outputOptions.clean ?? clean ?? false,
docs: outputOptions.docs ?? false,
prettier: outputOptions.prettier ?? prettier ?? false,
tslint: outputOptions.tslint ?? tslint ?? false,
biome: outputOptions.biome ?? biome ?? false,
Expand Down
40 changes: 40 additions & 0 deletions packages/orval/src/write-specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import chalk from 'chalk';
import execa from 'execa';
import fs from 'fs-extra';
import { Application, TypeDocOptions } from 'typedoc';
import uniq from 'lodash.uniq';
import { InfoObject } from 'openapi3-ts/oas30';
import { executeHook } from './utils';
Expand Down Expand Up @@ -198,6 +199,45 @@ export const writeSpecs = async (
}
}

if (output.docs) {
try {
let config: Partial<TypeDocOptions> = {};
let configPath: string | null = null;
if (typeof output.docs === 'object') {
({ configPath = null, ...config } = output.docs);
if (configPath) {
config.options = configPath;
}
}
const app = await Application.bootstrapWithPlugins({
entryPoints: paths,
// Set the custom config location if it has been provided.
...config,
plugin: ['typedoc-plugin-markdown'],
});
// Set defaults if the have not been provided by the external config.
if (!app.options.isSet('readme')) {
app.options.setValue('readme', 'none');
}
if (!app.options.isSet('logLevel')) {
app.options.setValue('logLevel', 'None');
}
const project = await app.convert();
if (project) {
await app.generateDocs(project, app.options.getValue('out'));
} else {
throw new Error('TypeDoc not initialised');
}
} catch (e: any) {
const message =
e.exitCode === 1
? e.stdout + e.stderr
: `⚠️ ${projectTitle ? `${projectTitle} - ` : ''}Unable to generate docs`;

log(chalk.yellow(message));
}
}

createSuccessMessage(projectTitle);
};

Expand Down
Loading

0 comments on commit e67fa69

Please sign in to comment.