Skip to content

Commit 2cf8154

Browse files
committed
fixup!
1 parent b8db226 commit 2cf8154

File tree

7 files changed

+201
-85
lines changed

7 files changed

+201
-85
lines changed

docs/configuration.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Configuration
2+
3+
`doc-kit`'s CLI supports a `--config-file` option, allowing for custom configuration files to be passed.
4+
These configuration files must be loadable via a `import()` call, so usually JSON or JavaScript files with default exports.
5+
6+
The structure of these files is the `Configuration` type.
7+
8+
## Configuration File Format
9+
10+
Configuration files can be either:
11+
12+
- **JavaScript/ESM** (`.mjs`, `.js` with `"type": "module"`)
13+
- **JSON** (`.json`)
14+
- **Remote URLs** (loaded dynamically)
15+
16+
### Basic Example
17+
18+
```javascript name=doc-kit.config.mjs
19+
export default {
20+
global: {
21+
version: '20.0.0',
22+
minify: true,
23+
repository: 'nodejs/node',
24+
ref: 'main',
25+
baseURL: 'https://nodejs.org/docs/',
26+
input: 'src/',
27+
output: 'dist/',
28+
ignore: ['node_modules/', 'test/'],
29+
changelog:
30+
'https://raw.githubusercontent.com/nodejs/node/main/CHANGELOG.md',
31+
index:
32+
'https://raw.githubusercontent.com/nodejs/node/main/doc/api/index.md',
33+
},
34+
35+
threads: 4,
36+
chunkSize: 10,
37+
38+
// Generator-specific configurations
39+
json: {
40+
format: 'json',
41+
minify: false, // Override global setting
42+
},
43+
44+
html: {
45+
format: 'html',
46+
},
47+
48+
metadata: {
49+
typeMap: {
50+
String: 'string',
51+
Number: 'number',
52+
Boolean: 'boolean',
53+
},
54+
},
55+
};
56+
```
57+
58+
## Configuration Structure
59+
60+
### Global Configuration
61+
62+
The `global` object contains settings that apply to all generators unless overridden:
63+
64+
| Property | Type | Description | Default |
65+
| ------------ | ------------------ | ------------------------------------------ | -------------------------------------------------- |
66+
| `version` | `string \| SemVer` | Documentation version | `process.version` |
67+
| `minify` | `boolean` | Whether to minify output | `false` |
68+
| `repository` | `string` | GitHub repository in `owner/repo` format | `'nodejs/node'` |
69+
| `ref` | `string` | Git reference (branch, tag, or commit SHA) | `'HEAD'` |
70+
| `baseURL` | `string \| URL` | Base URL for documentation | `'https://nodejs.org/docs'` |
71+
| `input` | `string[]` | Input directory path | - |
72+
| `output` | `string` | Output directory path | - |
73+
| `ignore` | `string[]` | Patterns to ignore | `[]` |
74+
| `changelog` | `string \| URL` | Changelog URL | Auto-generated URL based on `ref` and `repository` |
75+
| `index` | `string \| URL` | Index URL | - |
76+
77+
### Generator-Specific Configuration
78+
79+
Each generator (e.g., `json`, `html`, `markdown`) can have its own configuration that overrides global settings:
80+
81+
```javascript
82+
export default {
83+
global: {
84+
version: '20.0.0',
85+
minify: true,
86+
},
87+
88+
'legacy-json': {
89+
minify: false, // Override: JSON output won't be minified
90+
},
91+
};
92+
```
93+
94+
## Configuration Merging
95+
96+
Configurations are merged in the following order (earlier sources take precedence):
97+
98+
1. **Config file** (`--config-file`)
99+
2. **CLI options** (command-line arguments)
100+
3. **Default values** (built-in defaults)
101+
102+
## CLI Options Mapping
103+
104+
CLI options map to configuration properties:
105+
106+
| CLI Option | Config Property | Example |
107+
| ---------------------- | ------------------ | ------------------------- |
108+
| `--input <path>` | `global.input` | `--input src/` |
109+
| `--output <path>` | `global.output` | `--output dist/` |
110+
| `--ignore <pattern>` | `global.ignore[]` | `--ignore test/` |
111+
| `--minify` | `global.minify` | `--minify` |
112+
| `--git-ref <ref>` | `global.ref` | `--git-ref v20.0.0` |
113+
| `--version <version>` | `global.version` | `--version 20.0.0` |
114+
| `--changelog <url>` | `global.changelog` | `--changelog https://...` |
115+
| `--index <url>` | `global.index` | `--index file://...` |
116+
| `--type-map <map>` | `metadata.typeMap` | `--type-map file://...` |
117+
| `--target <generator>` | `target` | `--target json` |
118+
| `--threads <n>` | `threads` | `--threads 4` |
119+
| `--chunk-size <n>` | `chunkSize` | `--chunk-size 10` |

docs/generators.md

Lines changed: 70 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,7 @@ Each generator declares its dependency using the `dependsOn` field, allowing aut
2828

2929
## Generator Structure
3030

31-
A generator is defined as a module exporting an object conforming to the `GeneratorMetadata` interface:
32-
33-
```typescript
34-
interface GeneratorMetadata<Input, Output> {
35-
name: string;
36-
version: string;
37-
description: string;
38-
dependsOn?: string;
39-
40-
// Core generation function
41-
generate(
42-
input: Input,
43-
options: Partial<GeneratorOptions>
44-
): Promise<Output> | AsyncGenerator<Output>;
45-
46-
// Optional: for parallel processing
47-
processChunk?(
48-
fullInput: any,
49-
itemIndices: number[],
50-
deps: any
51-
): Promise<Output>;
52-
}
53-
```
31+
A generator is defined as a module exporting an object conforming to the `GeneratorMetadata` interface.
5432

5533
## Creating a Basic Generator
5634

@@ -60,14 +38,35 @@ Create a new directory in `src/generators/`:
6038

6139
```
6240
src/generators/my-format/
63-
├── index.mjs # Main generator file
41+
├── index.mjs # Main generator file (required)
6442
├── constants.mjs # Constants (optional)
65-
├── types.d.ts # TypeScript types (optional)
43+
├── types.d.ts # TypeScript types (required)
6644
└── utils/ # Utility functions (optional)
6745
└── formatter.mjs
6846
```
6947

70-
### Step 2: Implement the Generator
48+
### Step 2: Define Types
49+
50+
Create a `types.d.ts` file containing a `Generator` export. Use this when typing your generator.
51+
52+
```ts
53+
export type Generator = GeneratorMetadata<
54+
{
55+
// If your generator supports a custom configuration,
56+
// define it here
57+
myCustomOption: string;
58+
},
59+
Generate<InputToMyGenerator, Promise<OutputOfMyGenerator>>,
60+
// If your generator supports parallel processing:
61+
ProcessChunk<
62+
InputToMyParallelProcessor,
63+
OutputOfMyParallelProcessor,
64+
DependenciesOfMyParallelProcessor
65+
>
66+
>;
67+
```
68+
69+
### Step 3: Implement the Generator
7170

7271
```javascript
7372
// src/generators/my-format/index.mjs
@@ -92,6 +91,15 @@ export default {
9291
// This generator depends on the metadata generator
9392
dependsOn: 'metadata',
9493

94+
defaultConfiguration: {
95+
// If your generator supports a custom configuration, define the defaults here
96+
myCustomOption: 'myDefaultValue'
97+
98+
// All generators support options in the GlobalConfiguration object
99+
// To override the defaults, they can be specified here
100+
ref: 'overriddenRef'
101+
}
102+
95103
/**
96104
* Main generation function
97105
*
@@ -126,7 +134,7 @@ function transformToMyFormat(entries, version) {
126134
}
127135
```
128136

129-
### Step 3: Register the Generator
137+
### Step 4: Register the Generator
130138

131139
Add your generator to the exports in `src/generators/index.mjs`:
132140

@@ -187,12 +195,15 @@ export default {
187195
* Main generation function that orchestrates worker threads
188196
*
189197
* @param {Input} input
190-
* @param {Partial<GeneratorOptions>} options
198+
* @param {ParallelWorker} options
191199
*/
192-
async *generate(input, { worker, output }) {
200+
async *generate(input, worker) {
201+
// Configuration for this generator is based on it's name
202+
const { 'parallel-generator': config } = getConfig();
203+
193204
// Prepare serializable dependencies
194205
const deps = {
195-
version: options.version,
206+
version: config.version,
196207
...someConfig,
197208
};
198209

@@ -245,9 +256,7 @@ export default {
245256
/**
246257
* Generator function that yields results incrementally
247258
*/
248-
async *generate(input, options) {
249-
const { worker } = options;
250-
259+
async *generate(input, worker) {
251260
// Stream results as workers complete chunks
252261
for await (const chunkResult of worker.stream(input, input, {})) {
253262
// Yield immediately - downstream can start processing
@@ -277,7 +286,7 @@ export default {
277286
/**
278287
* Non-streaming - returns Promise instead of AsyncGenerator
279288
*/
280-
async generate(input, options) {
289+
async generate(input, worker) {
281290
// Collect all input (if dependency is streaming, this waits for completion)
282291
const allData = await collectAll(input);
283292

@@ -304,7 +313,7 @@ export default {
304313
name: 'my-generator',
305314
dependsOn: 'metadata', // This generator requires metadata output
306315

307-
async generate(input, options) {
316+
async generate(input, worker) {
308317
// input contains the output from 'metadata' generator
309318
},
310319
};
@@ -352,60 +361,46 @@ The framework ensures `metadata` runs once and its output is cached for all cons
352361
### Writing Output Files
353362

354363
```javascript
355-
import { writeFile, mkdir } from 'node:fs/promises';
356-
import { join } from 'node:path';
364+
const { 'my-generator': config } = getConfig();
357365

358-
async generate(input, options) {
359-
const { output } = options;
366+
if (!config.output) {
367+
// Return data without writing
368+
return result;
369+
}
360370

361-
if (!output) {
362-
// Return data without writing
363-
return result;
364-
}
371+
// Ensure directory exists
372+
await mkdir(config.output, { recursive: true });
365373

366-
// Ensure directory exists
367-
await mkdir(output, { recursive: true });
374+
// Write single file
375+
await writeFile(join(config.output, 'output.txt'), content, 'utf-8');
368376

369-
// Write single file
377+
// Write multiple files
378+
for (const item of items) {
370379
await writeFile(
371-
join(output, 'output.txt'),
372-
content,
380+
join(config.output, `${item.name}.txt`),
381+
item.content,
373382
'utf-8'
374383
);
375-
376-
// Write multiple files
377-
for (const item of items) {
378-
await writeFile(
379-
join(output, `${item.name}.txt`),
380-
item.content,
381-
'utf-8'
382-
);
383-
}
384-
385-
return result;
386384
}
385+
386+
return result;
387387
```
388388

389389
### Copying Assets
390390

391391
```javascript
392-
import { cp } from 'node:fs/promises';
393-
import { join } from 'node:path';
394-
395-
async generate(input, options) {
396-
const { output } = options;
397-
398-
if (output) {
399-
// Copy asset directory
400-
await cp(
401-
new URL('./assets', import.meta.url),
402-
join(output, 'assets'),
403-
{ recursive: true }
404-
);
405-
}
406-
407-
return result;
392+
const { 'my-generator': config } = getConfig();
393+
394+
if (config.output) {
395+
// Copy asset directory
396+
await cp(
397+
new URL('./assets', import.meta.url),
398+
join(config.output, 'assets'),
399+
{ recursive: true }
400+
);
408401
}
402+
403+
return result;
409404
```
410405
411406
### Output Structure

src/generators/api-links/index.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export default {
6262

6363
checkIndirectReferences(program, exports, nameToLineNumberMap);
6464

65-
const fullGitUrl = `${populate(GITHUB_BLOB_URL, config)}/lib/${baseName}.js`;
65+
const fullGitUrl = `${populate(GITHUB_BLOB_URL, config)}lib/${baseName}.js`;
6666

6767
// Add the exports we found in this program to our output
6868
Object.keys(nameToLineNumberMap).forEach(key => {

src/generators/legacy-html/index.mjs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export default {
9999
async *generate(input, worker) {
100100
const { 'legacy-html': config } = getConfig();
101101

102-
const apiTemplate = await readFile(config.template, 'utf-8');
102+
const apiTemplate = await readFile(config.templatePath, 'utf-8');
103103

104104
const groupedModules = groupNodesByModule(input);
105105

@@ -116,11 +116,13 @@ export default {
116116
}))
117117
: headNodes;
118118

119-
const navigation = remarkRehypeProcessor.processSync(
120-
tableOfContents(indexOfFiles, {
121-
maxDepth: 1,
122-
parser: tableOfContents.parseNavigationNode,
123-
})
119+
const navigation = String(
120+
remarkRehypeProcessor.processSync(
121+
tableOfContents(indexOfFiles, {
122+
maxDepth: 1,
123+
parser: tableOfContents.parseNavigationNode,
124+
})
125+
)
124126
);
125127

126128
if (config.output) {

src/generators/legacy-html/utils/replaceTemplateValues.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const replaceTemplateValues = (
3636
.replace('__CONTENT__', content)
3737
.replace(/__TOC_PICKER__/g, buildToC(toc))
3838
.replace(/__GTOC_PICKER__/g, skipGtocPicker ? '' : buildNavigation(nav))
39-
.replace('__ALTDOCS__', buildVersions(api, added, config.releases))
39+
.replace('__ALTDOCS__', buildVersions(api, added, config.changelog))
4040
.replace(
4141
'__EDIT_ON_GITHUB__',
4242
skipGitHub

0 commit comments

Comments
 (0)