Skip to content
Merged
42 changes: 29 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,24 +73,40 @@ npx docs-cache clean

### Options

| Field | Type | Description |
| ---------- | ------- | ---------------------------------------- |
| `cacheDir` | string | Directory for cache, defaults to `.docs` |
| `index` | boolean | Write `index.json` summary file |
| `sources` | array | List of repositories to sync |
| `defaults` | object | Default settings for all sources |
| Field | Type | Description |
| ---------- | ------- | ---------------------------------------------------- |
| `cacheDir` | string | Directory for cache, defaults to `.docs` |
| `sources` | array | List of repositories to sync |
| `defaults` | object | Default settings for all sources |

**Default Options:**

All fields in `defaults` apply to all sources unless overridden per-source:

- `ref`: Branch, tag, or commit (default: `"HEAD"`)
- `mode`: Cache mode (default: `"materialize"`)
- `include`: Glob patterns to copy (default: `["**/*.{md,mdx,markdown,mkd,txt,rst,adoc,asciidoc}"]`)
- `targetMode`: `"symlink"` or `"copy"` (default: `"symlink"` on Unix, `"copy"` on Windows)
- `depth`: Git clone depth (default: `1`)
- `required`: Whether missing sources should fail (default: `true`)
- `maxBytes`: Maximum total bytes to materialize (default: `200000000`)
- `maxFiles`: Maximum total files to materialize (optional)
- `allowHosts`: Allowed Git hosts (default: `["github.com", "gitlab.com"]`)
- `toc`: Generate per-source `TOC.md` listing all documentation files (default: `true`)

**Source Options:**

- `repo`: Git URL
- `ref`: Branch, tag, or commit
- `include`: Glob patterns to copy, defaults to `"**/*.{md,mdx,markdown,mkd,txt,rst,adoc,asciidoc}"`,
- `repo`: Git URL (required)
- `id`: Unique identifier for the source (required)
- `ref`: Branch, tag, or commit (overrides default)
- `include`: Glob patterns to copy (overrides default)
- `exclude`: Glob patterns to skip
- `targetDir`: Optional path where files should be symlinked/copied to, outside `.docs`
- `targetMode`: Defaults to `symlink` on Unix and `copy` on Windows
- `required`: Whether missing sources should fail in offline/strict runs
- `maxBytes`: Maximum total bytes to materialize for the source
- `maxFiles`: Maximum total files to materialize for the source
- `targetMode`: `"symlink"` or `"copy"` (overrides default)
- `required`: Whether missing sources should fail (overrides default)
- `maxBytes`: Maximum total bytes to materialize (overrides default)
- `maxFiles`: Maximum total files to materialize (overrides default)
- `toc`: Generate per-source `TOC.md` listing all documentation files (overrides default)

> **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`.

Expand Down
9 changes: 6 additions & 3 deletions docs.config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
"type": "string",
"enum": ["symlink", "copy"]
},
"index": {
"type": "boolean"
},
"defaults": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -62,6 +59,9 @@
"type": "string",
"minLength": 1
}
},
"toc": {
"type": "boolean"
}
},
"additionalProperties": false
Expand Down Expand Up @@ -144,6 +144,9 @@
},
"required": ["type", "value"],
"additionalProperties": false
},
"toc": {
"type": "boolean"
}
},
"required": ["id", "repo"],
Expand Down
3 changes: 0 additions & 3 deletions src/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,6 @@ export const addSources = async (params: {
if (rawConfig?.cacheDir) {
nextConfig.cacheDir = rawConfig.cacheDir;
}
if (rawConfig?.index !== undefined) {
nextConfig.index = rawConfig.index;
}
if (rawConfig?.defaults) {
nextConfig.defaults = rawConfig.defaults;
}
Expand Down
3 changes: 2 additions & 1 deletion src/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const DefaultsSchema = z
maxBytes: z.number().min(1),
maxFiles: z.number().min(1).optional(),
allowHosts: z.array(z.string().min(1)).min(1),
toc: z.boolean().optional(),
})
.strict();

Expand All @@ -38,6 +39,7 @@ export const SourceSchema = z
maxBytes: z.number().min(1).optional(),
maxFiles: z.number().min(1).optional(),
integrity: IntegritySchema.optional(),
toc: z.boolean().optional(),
})
.strict();

Expand All @@ -46,7 +48,6 @@ export const ConfigSchema = z
$schema: z.string().min(1).optional(),
cacheDir: z.string().min(1).optional(),
targetMode: TargetModeSchema.optional(),
index: z.boolean().optional(),
defaults: DefaultsSchema.partial().optional(),
sources: z.array(SourceSchema),
})
Expand Down
20 changes: 12 additions & 8 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface DocsCacheDefaults {
maxBytes: number;
maxFiles?: number;
allowHosts: string[];
toc?: boolean;
}

export interface DocsCacheSource {
Expand All @@ -39,13 +40,13 @@ export interface DocsCacheSource {
maxBytes?: number;
maxFiles?: number;
integrity?: DocsCacheIntegrity;
toc?: boolean;
}

export interface DocsCacheConfig {
$schema?: string;
cacheDir?: string;
targetMode?: "symlink" | "copy";
index?: boolean;
defaults?: Partial<DocsCacheDefaults>;
sources: DocsCacheSource[];
}
Expand All @@ -64,6 +65,7 @@ export interface DocsCacheResolvedSource {
maxBytes: number;
maxFiles?: number;
integrity?: DocsCacheIntegrity;
toc?: boolean;
}

export const DEFAULT_CONFIG_FILENAME = "docs.config.json";
Expand All @@ -72,7 +74,6 @@ const PACKAGE_JSON_FILENAME = "package.json";
const DEFAULT_TARGET_MODE = process.platform === "win32" ? "copy" : "symlink";
export const DEFAULT_CONFIG: DocsCacheConfig = {
cacheDir: DEFAULT_CACHE_DIR,
index: false,
defaults: {
ref: "HEAD",
mode: "materialize",
Expand All @@ -82,6 +83,7 @@ export const DEFAULT_CONFIG: DocsCacheConfig = {
required: true,
maxBytes: 200000000,
allowHosts: ["github.com", "gitlab.com"],
toc: true,
Comment thread
fbosch marked this conversation as resolved.
},
sources: [],
};
Expand Down Expand Up @@ -144,7 +146,6 @@ export const stripDefaultConfigValues = (
const next: DocsCacheConfig = {
$schema: pruned.$schema as DocsCacheConfig["$schema"],
cacheDir: pruned.cacheDir as DocsCacheConfig["cacheDir"],
index: pruned.index as DocsCacheConfig["index"],
targetMode: pruned.targetMode as DocsCacheConfig["targetMode"],
defaults: pruned.defaults as DocsCacheConfig["defaults"],
sources: config.sources,
Expand Down Expand Up @@ -247,10 +248,6 @@ export const validateConfig = (input: unknown): DocsCacheConfig => {
const cacheDir = input.cacheDir
? assertString(input.cacheDir, "cacheDir")
: DEFAULT_CACHE_DIR;
const index =
input.index !== undefined
? assertBoolean(input.index, "index")
: (DEFAULT_CONFIG.index ?? false);

const defaultsInput = input.defaults;
const targetModeOverride =
Expand Down Expand Up @@ -300,6 +297,10 @@ export const validateConfig = (input: unknown): DocsCacheConfig => {
defaultsInput.allowHosts !== undefined
? assertStringArray(defaultsInput.allowHosts, "defaults.allowHosts")
: defaultValues.allowHosts,
toc:
defaultsInput.toc !== undefined
? assertBoolean(defaultsInput.toc, "defaults.toc")
: defaultValues.toc,
};
} else if (targetModeOverride !== undefined) {
defaults = {
Expand Down Expand Up @@ -386,6 +387,9 @@ export const validateConfig = (input: unknown): DocsCacheConfig => {
`sources[${index}].integrity`,
);
}
if (entry.toc !== undefined) {
source.toc = assertBoolean(entry.toc, `sources[${index}].toc`);
}
return source;
});

Expand All @@ -407,7 +411,6 @@ export const validateConfig = (input: unknown): DocsCacheConfig => {
return {
cacheDir,
targetMode: targetModeOverride,
index,
defaults,
sources,
};
Expand All @@ -432,6 +435,7 @@ export const resolveSources = (
maxBytes: source.maxBytes ?? defaults.maxBytes,
maxFiles: source.maxFiles ?? defaults.maxFiles,
integrity: source.integrity,
toc: source.toc ?? defaults.toc,
}));
};

Expand Down
60 changes: 0 additions & 60 deletions src/index.ts

This file was deleted.

22 changes: 12 additions & 10 deletions src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ export const initConfig = async (
throw new Error("Init cancelled.");
}
const cacheDirValue = cacheDirAnswer || DEFAULT_CACHE_DIR;
const indexAnswer = await confirm({
const tocAnswer = await confirm({
message:
"Generate index.json (summary of cached sources + paths for tools)",
initialValue: false,
"Generate TOC.md (table of contents with links to all documentation)",
initialValue: true,
});
if (isCancel(indexAnswer)) {
if (isCancel(tocAnswer)) {
throw new Error("Init cancelled.");
}
const gitignoreStatus = await getGitignoreStatus(cwd, cacheDirValue);
Expand All @@ -117,12 +117,12 @@ export const initConfig = async (
const answers = {
configPath,
cacheDir: cacheDirAnswer,
index: indexAnswer,
toc: tocAnswer,
gitignore: gitignoreAnswer,
} as {
configPath: string;
cacheDir: string;
index: boolean;
toc: boolean;
gitignore: boolean;
};

Expand All @@ -144,8 +144,9 @@ export const initConfig = async (
if (resolvedCacheDir !== DEFAULT_CACHE_DIR) {
baseConfig.cacheDir = resolvedCacheDir;
}
if (answers.index) {
baseConfig.index = true;
// Since TOC defaults to true, only set it explicitly if user chose false
if (!answers.toc) {
baseConfig.defaults = { toc: false };
}
pkg["docs-cache"] = stripDefaultConfigValues(baseConfig);
await writeFile(
Expand Down Expand Up @@ -178,8 +179,9 @@ export const initConfig = async (
if (resolvedCacheDir !== DEFAULT_CACHE_DIR) {
config.cacheDir = resolvedCacheDir;
}
if (answers.index) {
config.index = true;
// Since TOC defaults to true, only set it explicitly if user chose false
if (!answers.toc) {
config.defaults = { toc: false };
}

await writeConfig(resolvedConfigPath, config);
Expand Down
4 changes: 1 addition & 3 deletions src/paths.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from "node:path";

export const DEFAULT_LOCK_FILENAME = "docs.lock";
export const DEFAULT_INDEX_FILENAME = "index.json";
export const DEFAULT_TOC_FILENAME = "TOC.md";

export const toPosixPath = (value: string) => value.replace(/\\/g, "/");

Expand Down Expand Up @@ -40,10 +40,8 @@ export const resolveCacheDir = (
export const getCacheLayout = (cacheDir: string, sourceId: string) => {
const _reposDir = path.join(cacheDir, "repos");
const sourceDir = path.join(cacheDir, sourceId);
const indexPath = path.join(cacheDir, DEFAULT_INDEX_FILENAME);
return {
cacheDir,
sourceDir,
indexPath,
};
};
3 changes: 0 additions & 3 deletions src/remove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,6 @@ export const removeSources = async (params: {
if (rawConfig?.cacheDir) {
nextConfig.cacheDir = rawConfig.cacheDir;
}
if (rawConfig?.index !== undefined) {
nextConfig.index = rawConfig.index;
}
if (rawConfig?.defaults) {
nextConfig.defaults = rawConfig.defaults;
}
Expand Down
Loading
Loading