Skip to content

Commit db81975

Browse files
committed
feat(toc): unify toc config into single field
1 parent 0ed8631 commit db81975

5 files changed

Lines changed: 17 additions & 71 deletions

File tree

README.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Documentation is cached in a gitignored location, exposed to agent and tool targ
1919
- **Fast**: Local cache avoids network roundtrips after sync.
2020
- **Flexible**: Cache full repos or just the subdirectories you need.
2121

22-
> **Note**: Sources are downloaded to a local cache. If you provide a `targetDir`, `docs-cache` creates a symlink or copy from the cache to that target directory. The target should be outside `.docs`.
22+
> **Note**: Sources are downloaded to a local cache. If you provide a `targetDir`, `docs-cache` creates a symlink or copy from the cache to that target directory.
2323
2424
## Usage
2525

@@ -99,9 +99,7 @@ All fields in `defaults` apply to all sources unless overridden per-source.
9999
| `maxBytes` | Maximum total bytes to materialize. Default: `200000000` (200 MB). |
100100
| `maxFiles` | Maximum total files to materialize. |
101101
| `allowHosts` | Allowed Git hosts. Default: `["github.com", "gitlab.com"]`. |
102-
| `toc` | Generate per-source `TOC.md` listing all documentation files. Default: `true`. |
103-
104-
> **Note**: Git operation timeout can be configured via the `--timeout-ms` CLI flag (default: 120000ms / 2 minutes).
102+
| `toc` | Generate per-source `TOC.md`. Default: `true`. Supports `true`, `false`, or a format (`"tree"`, `"compressed"`). |
105103

106104
### Source options
107105

@@ -124,7 +122,7 @@ All fields in `defaults` apply to all sources unless overridden per-source.
124122
| `required` | Whether missing sources should fail. |
125123
| `maxBytes` | Maximum total bytes to materialize. |
126124
| `maxFiles` | Maximum total files to materialize. |
127-
| `toc` | Generate per-source `TOC.md` listing all documentation files. |
125+
| `toc` | Generate per-source `TOC.md`. Supports `true`, `false`, or a format (`"tree"`, `"compressed"`). |
128126

129127
> **Note**: Sources are always downloaded to `.docs/<id>/`. If you provide a `targetDir`, `docs-cache` will create a symlink or copy pointing from the cache to that target directory. The target should be outside `.docs`. Git operation timeout is configured via the `--timeout-ms` CLI flag, not as a per-source configuration option.
130128

src/config-schema.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export const DefaultsSchema = z
2222
maxFiles: z.number().min(1).optional(),
2323
allowHosts: z.array(z.string().min(1)).min(1),
2424
toc: z.union([z.boolean(), TocFormatSchema]).optional(),
25-
tocFormat: TocFormatSchema.optional(),
2625
})
2726
.strict();
2827

@@ -42,7 +41,6 @@ export const SourceSchema = z
4241
maxFiles: z.number().min(1).optional(),
4342
integrity: IntegritySchema.optional(),
4443
toc: z.union([z.boolean(), TocFormatSchema]).optional(),
45-
tocFormat: TocFormatSchema.optional(),
4644
})
4745
.strict();
4846

src/config.ts

Lines changed: 7 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ export interface DocsCacheDefaults {
2626
maxFiles?: number;
2727
allowHosts: string[];
2828
toc?: boolean | TocFormat;
29-
tocFormat?: TocFormat;
3029
}
3130

3231
export interface DocsCacheSource {
@@ -44,7 +43,6 @@ export interface DocsCacheSource {
4443
maxFiles?: number;
4544
integrity?: DocsCacheIntegrity;
4645
toc?: boolean | TocFormat;
47-
tocFormat?: TocFormat;
4846
}
4947

5048
export interface DocsCacheConfig {
@@ -70,7 +68,6 @@ export interface DocsCacheResolvedSource {
7068
maxFiles?: number;
7169
integrity?: DocsCacheIntegrity;
7270
toc?: boolean | TocFormat;
73-
tocFormat?: TocFormat;
7471
}
7572

7673
export const DEFAULT_CONFIG_FILENAME = "docs.config.json";
@@ -88,7 +85,7 @@ export const DEFAULT_CONFIG: DocsCacheConfig = {
8885
required: true,
8986
maxBytes: 200000000,
9087
allowHosts: ["github.com", "gitlab.com"],
91-
tocFormat: "compressed",
88+
toc: true,
9289
},
9390
sources: [],
9491
};
@@ -238,33 +235,6 @@ const assertIntegrity = (value: unknown, label: string): DocsCacheIntegrity => {
238235
return { type, value: integrityValue };
239236
};
240237

241-
const normalizeTocConfig = (
242-
toc: boolean | TocFormat | undefined,
243-
tocFormat: TocFormat | undefined,
244-
): { toc?: boolean | TocFormat; tocFormat?: TocFormat } => {
245-
// If tocFormat is explicitly set, use it (and keep toc if it was set too)
246-
if (tocFormat !== undefined) {
247-
if (toc !== undefined) {
248-
return { toc, tocFormat };
249-
}
250-
return { tocFormat };
251-
}
252-
// If toc is a format string, set tocFormat but also keep toc
253-
if (typeof toc === "string") {
254-
return { toc, tocFormat: toc };
255-
}
256-
// If toc is a boolean, keep it and set tocFormat accordingly
257-
if (typeof toc === "boolean") {
258-
if (toc) {
259-
return { toc, tocFormat: "compressed" };
260-
}
261-
// When toc is explicitly false, omit tocFormat to avoid setting a format for a disabled TOC
262-
return { toc };
263-
}
264-
// Default case - no toc or tocFormat provided
265-
return {};
266-
};
267-
268238
export const validateConfig = (input: unknown): DocsCacheConfig => {
269239
if (!isRecord(input)) {
270240
throw new Error("Config must be a JSON object.");
@@ -293,12 +263,6 @@ export const validateConfig = (input: unknown): DocsCacheConfig => {
293263
throw new Error("defaults must be an object.");
294264
}
295265

296-
// Normalize toc/tocFormat config for defaults
297-
const normalizedToc = normalizeTocConfig(
298-
defaultsInput.toc as boolean | TocFormat | undefined,
299-
defaultsInput.tocFormat as TocFormat | undefined,
300-
);
301-
302266
defaults = {
303267
ref:
304268
defaultsInput.ref !== undefined
@@ -336,11 +300,10 @@ export const validateConfig = (input: unknown): DocsCacheConfig => {
336300
defaultsInput.allowHosts !== undefined
337301
? assertStringArray(defaultsInput.allowHosts, "defaults.allowHosts")
338302
: defaultValues.allowHosts,
339-
toc: normalizedToc.toc,
340-
tocFormat:
341-
normalizedToc.tocFormat !== undefined
342-
? normalizedToc.tocFormat
343-
: defaultValues.tocFormat,
303+
toc:
304+
defaultsInput.toc !== undefined
305+
? (defaultsInput.toc as boolean | TocFormat)
306+
: defaultValues.toc,
344307
};
345308
} else if (targetModeOverride !== undefined) {
346309
defaults = {
@@ -428,16 +391,8 @@ export const validateConfig = (input: unknown): DocsCacheConfig => {
428391
);
429392
}
430393

431-
// Normalize toc/tocFormat config for this source
432-
const normalizedToc = normalizeTocConfig(
433-
entry.toc as boolean | TocFormat | undefined,
434-
entry.tocFormat as TocFormat | undefined,
435-
);
436-
if (normalizedToc.toc !== undefined) {
437-
source.toc = normalizedToc.toc;
438-
}
439-
if (normalizedToc.tocFormat !== undefined) {
440-
source.tocFormat = normalizedToc.tocFormat;
394+
if (entry.toc !== undefined) {
395+
source.toc = entry.toc as boolean | TocFormat;
441396
}
442397

443398
return source;
@@ -486,7 +441,6 @@ export const resolveSources = (
486441
maxFiles: source.maxFiles ?? defaults.maxFiles,
487442
integrity: source.integrity,
488443
toc: source.toc ?? defaults.toc,
489-
tocFormat: source.tocFormat ?? defaults.tocFormat,
490444
}));
491445
};
492446

src/toc.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,17 +210,13 @@ export const writeToc = async (params: {
210210

211211
// Determine if TOC should be generated and what format to use
212212
const sourceTocConfig = source?.toc;
213-
const sourceTocFormat = source?.tocFormat;
214213

215214
// Determine if TOC is enabled (default: true)
216215
const tocEnabled = sourceTocConfig !== false;
217216

218217
// Determine TOC format
219218
let tocFormat: TocFormat = "compressed"; // default
220-
if (sourceTocFormat) {
221-
tocFormat = sourceTocFormat;
222-
} else if (typeof sourceTocConfig === "string") {
223-
// Backward compatibility: if toc is a format string, use it
219+
if (typeof sourceTocConfig === "string") {
224220
tocFormat = sourceTocConfig;
225221
}
226222

tests/sync-toc-formats.test.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ test("sync writes TOC with tree format when specified", async () => {
104104
{
105105
id: "local",
106106
repo: "https://example.com/repo.git",
107-
tocFormat: "tree",
107+
toc: "tree",
108108
},
109109
],
110110
};
@@ -157,7 +157,7 @@ test("sync writes TOC with tree format when specified", async () => {
157157
assert.ok(!sourceToc.includes("repository:"));
158158
});
159159

160-
test("sync writes TOC with compressed format via defaults.tocFormat", async () => {
160+
test("sync writes TOC with compressed format via defaults.toc", async () => {
161161
const tmpRoot = path.join(
162162
tmpdir(),
163163
`docs-cache-toc-defaults-compressed-${Date.now().toString(36)}`,
@@ -174,7 +174,7 @@ test("sync writes TOC with compressed format via defaults.tocFormat", async () =
174174
$schema:
175175
"https://raw.githubusercontent.com/fbosch/docs-cache/main/docs.config.schema.json",
176176
defaults: {
177-
tocFormat: "compressed",
177+
toc: "compressed",
178178
},
179179
sources: [
180180
{
@@ -223,7 +223,7 @@ test("sync writes TOC with compressed format via defaults.tocFormat", async () =
223223
assert.ok(sourceToc.includes("root:{README.md}"));
224224
});
225225

226-
test("sync writes TOC with tree format via defaults.tocFormat", async () => {
226+
test("sync writes TOC with tree format via defaults.toc", async () => {
227227
const tmpRoot = path.join(
228228
tmpdir(),
229229
`docs-cache-toc-defaults-tree-${Date.now().toString(36)}`,
@@ -241,7 +241,7 @@ test("sync writes TOC with tree format via defaults.tocFormat", async () => {
241241
$schema:
242242
"https://raw.githubusercontent.com/fbosch/docs-cache/main/docs.config.schema.json",
243243
defaults: {
244-
tocFormat: "tree",
244+
toc: "tree",
245245
},
246246
sources: [
247247
{
@@ -295,7 +295,7 @@ test("sync writes TOC with tree format via defaults.tocFormat", async () => {
295295
assert.ok(!sourceToc.includes("---"));
296296
});
297297

298-
test("sync supports backward compatibility: toc=true uses compressed format", async () => {
298+
test("sync supports toc=true using compressed format", async () => {
299299
const tmpRoot = path.join(
300300
tmpdir(),
301301
`docs-cache-toc-backward-compat-${Date.now().toString(36)}`,

0 commit comments

Comments
 (0)