@theholocron/holocron-plugin-fern 5.0.0-alpha.20 → 5.0.0-alpha.200
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.d.mts +31 -8
- package/dist/index.mjs +48 -12
- package/package.json +13 -10
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ pnpm add -D @theholocron/holocron-plugin-fern
|
|
|
42
42
|
| `domain` | No | Base domain (`"wiki.theholocron.dev"`) or full path (`"wiki.theholocron.dev/myrepo"`). When a base domain is given, the repo name is appended automatically as a basepath. |
|
|
43
43
|
| `fernOrg` | No | Fern workspace slug. Defaults to `config.org`. Set this when the Fern workspace name differs from the GitHub org (e.g. workspace `"holocron"`, org `"theholocron"`). |
|
|
44
44
|
|
|
45
|
-
## What `holocron setup` does
|
|
45
|
+
## What `holocron repo setup` does
|
|
46
46
|
|
|
47
47
|
1. **Writes `fern/fern.config.json`** — Fern workspace org name and pinned
|
|
48
48
|
CLI version. Always overwritten.
|
|
@@ -79,7 +79,7 @@ DNS: add one CNAME record — `wiki.theholocron.dev` →
|
|
|
79
79
|
Password protection is configured in the **Fern Dashboard**
|
|
80
80
|
(`dashboard.buildwithfern.com`) — it is not configurable via `docs.yml` or
|
|
81
81
|
any CLI flag. Configure access control manually in the dashboard after
|
|
82
|
-
running `holocron setup`.
|
|
82
|
+
running `holocron repo setup`.
|
|
83
83
|
|
|
84
84
|
## CI secrets
|
|
85
85
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { AuthError, ResolveTokenInput, Wiki,
|
|
1
|
+
import { AuthError, DnsRecordRequest, ResolveTokenInput, Wiki, WikiProvisionOpts, WikiProxyConfig } from "@theholocron/cli";
|
|
2
|
+
//#region src/auth.d.ts
|
|
3
|
+
declare const resolveToken: (input?: ResolveTokenInput) => string;
|
|
4
|
+
//#endregion
|
|
2
5
|
//#region src/capabilities/wiki.d.ts
|
|
3
6
|
declare const FERN_VERSION = "5.114.1";
|
|
4
|
-
interface FernWikiOptions {
|
|
7
|
+
interface FernWikiOptions extends ResolveTokenInput {
|
|
5
8
|
/** Absolute path to the working repo root. Injected by the loader from RuntimeContext. */
|
|
6
9
|
repoRoot?: string;
|
|
7
10
|
/** Active org name (e.g. "theholocron"). Injected by the loader from RuntimeContext. */
|
|
@@ -36,12 +39,12 @@ interface FernWikiOptions {
|
|
|
36
39
|
/**
|
|
37
40
|
* One-line description shown on the global product switcher card.
|
|
38
41
|
* Falls back to the top-level `description` field in `holocron.config.ts`
|
|
39
|
-
* when omitted. Only used by `holocron sync --steps wiki`.
|
|
42
|
+
* when omitted. Only used by `holocron repo sync --steps wiki`.
|
|
40
43
|
*/
|
|
41
44
|
subtitle?: string;
|
|
42
45
|
/**
|
|
43
46
|
* Font Awesome icon class for the product switcher card (e.g. `"fa-duotone fa-gear"`).
|
|
44
|
-
* Only used by `holocron sync --steps wiki`.
|
|
47
|
+
* Only used by `holocron repo sync --steps wiki`.
|
|
45
48
|
*/
|
|
46
49
|
icon?: string;
|
|
47
50
|
}
|
|
@@ -52,12 +55,32 @@ declare class FernWiki implements Wiki {
|
|
|
52
55
|
constructor(opts: FernWikiOptions);
|
|
53
56
|
provision(callOpts?: WikiProvisionOpts): Promise<string>;
|
|
54
57
|
proxyConfig(): WikiProxyConfig | null;
|
|
55
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Confirms `HOLOCRON_FERN_TOKEN`/`FERN_TOKEN` resolves, or a Fern token
|
|
60
|
+
* is stored in the keyring — not a live check. Fern exposes no
|
|
61
|
+
* lightweight endpoint to verify a token actually works (the only
|
|
62
|
+
* token-consuming operation is a full `fern generate`, see
|
|
63
|
+
* holocron#1079); this only confirms one is configured, the same way
|
|
64
|
+
* CI's `fern generate --docs` step would find it.
|
|
65
|
+
*
|
|
66
|
+
* Deliberately ignores `cliToken` (`--token`): CI's step only ever sees
|
|
67
|
+
* the env var from a GitHub Actions secret, never a CLI flag — and a
|
|
68
|
+
* bare `--token <value>` meant for some OTHER provider is forwarded to
|
|
69
|
+
* every loaded plugin as a fallback (see AGENTS.md), so honoring it
|
|
70
|
+
* here would report "configured" even when no Fern-specific credential
|
|
71
|
+
* exists anywhere CI would actually look.
|
|
72
|
+
*
|
|
73
|
+
* Only `AuthError` (the specific "no token found" signal) is treated as
|
|
74
|
+
* `ok: false` — any other error (e.g. a real keyring failure) is a
|
|
75
|
+
* genuine problem and must surface as a failure, not get misreported as
|
|
76
|
+
* a missing token.
|
|
77
|
+
*/
|
|
78
|
+
whoami(): Promise<{
|
|
79
|
+
ok: boolean;
|
|
80
|
+
}>;
|
|
81
|
+
dnsRecord(): DnsRecordRequest | null;
|
|
56
82
|
}
|
|
57
83
|
//#endregion
|
|
58
|
-
//#region src/auth.d.ts
|
|
59
|
-
declare const resolveToken: (input?: ResolveTokenInput) => string;
|
|
60
|
-
//#endregion
|
|
61
84
|
//#region src/index.d.ts
|
|
62
85
|
type FernPluginOptions = FernWikiOptions;
|
|
63
86
|
declare function wiki(opts: FernPluginOptions): Wiki;
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { stringifyJson } from "@theholocron/json-utils";
|
|
3
4
|
import { AuthError, createResolveToken } from "@theholocron/cli";
|
|
5
|
+
//#region src/auth.ts
|
|
6
|
+
const resolveToken = createResolveToken({
|
|
7
|
+
envName: "HOLOCRON_FERN_TOKEN",
|
|
8
|
+
vendorEnvName: "FERN_TOKEN",
|
|
9
|
+
keyringService: "fern",
|
|
10
|
+
errorMessage: "no Fern token found. Set HOLOCRON_FERN_TOKEN / FERN_TOKEN, or run: holocron auth set fern <token>"
|
|
11
|
+
});
|
|
12
|
+
//#endregion
|
|
4
13
|
//#region src/capabilities/wiki.ts
|
|
5
14
|
const FERN_VERSION = "5.114.1";
|
|
6
15
|
var FernWiki = class {
|
|
@@ -33,6 +42,38 @@ var FernWiki = class {
|
|
|
33
42
|
headers: { "X-Fern-Host": this.opts.domain.split("/")[0] }
|
|
34
43
|
};
|
|
35
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Confirms `HOLOCRON_FERN_TOKEN`/`FERN_TOKEN` resolves, or a Fern token
|
|
47
|
+
* is stored in the keyring — not a live check. Fern exposes no
|
|
48
|
+
* lightweight endpoint to verify a token actually works (the only
|
|
49
|
+
* token-consuming operation is a full `fern generate`, see
|
|
50
|
+
* holocron#1079); this only confirms one is configured, the same way
|
|
51
|
+
* CI's `fern generate --docs` step would find it.
|
|
52
|
+
*
|
|
53
|
+
* Deliberately ignores `cliToken` (`--token`): CI's step only ever sees
|
|
54
|
+
* the env var from a GitHub Actions secret, never a CLI flag — and a
|
|
55
|
+
* bare `--token <value>` meant for some OTHER provider is forwarded to
|
|
56
|
+
* every loaded plugin as a fallback (see AGENTS.md), so honoring it
|
|
57
|
+
* here would report "configured" even when no Fern-specific credential
|
|
58
|
+
* exists anywhere CI would actually look.
|
|
59
|
+
*
|
|
60
|
+
* Only `AuthError` (the specific "no token found" signal) is treated as
|
|
61
|
+
* `ok: false` — any other error (e.g. a real keyring failure) is a
|
|
62
|
+
* genuine problem and must surface as a failure, not get misreported as
|
|
63
|
+
* a missing token.
|
|
64
|
+
*/
|
|
65
|
+
async whoami() {
|
|
66
|
+
try {
|
|
67
|
+
resolveToken({
|
|
68
|
+
...this.opts,
|
|
69
|
+
cliToken: void 0
|
|
70
|
+
});
|
|
71
|
+
return { ok: true };
|
|
72
|
+
} catch (err) {
|
|
73
|
+
if (err instanceof AuthError) return { ok: false };
|
|
74
|
+
throw err;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
36
77
|
dnsRecord() {
|
|
37
78
|
const { org, domain, fernOrg } = this.opts;
|
|
38
79
|
if (!domain) return null;
|
|
@@ -40,8 +81,11 @@ var FernWiki = class {
|
|
|
40
81
|
const hostname = domain.split("/")[0];
|
|
41
82
|
return {
|
|
42
83
|
zone: hostname.split(".").slice(-2).join("."),
|
|
43
|
-
|
|
44
|
-
|
|
84
|
+
record: {
|
|
85
|
+
type: "CNAME",
|
|
86
|
+
name: hostname,
|
|
87
|
+
content: `${resolvedFernOrg}.docs.buildwithfern.com`
|
|
88
|
+
}
|
|
45
89
|
};
|
|
46
90
|
}
|
|
47
91
|
};
|
|
@@ -49,10 +93,10 @@ async function writeFernConfig({ repoRoot, fernOrg }) {
|
|
|
49
93
|
const fernDir = join(repoRoot, "fern");
|
|
50
94
|
await mkdir(fernDir, { recursive: true });
|
|
51
95
|
const org = fernOrg ?? "holocron";
|
|
52
|
-
const content =
|
|
96
|
+
const content = stringifyJson({
|
|
53
97
|
organization: org,
|
|
54
98
|
version: FERN_VERSION
|
|
55
|
-
}
|
|
99
|
+
});
|
|
56
100
|
await writeFile(join(fernDir, "fern.config.json"), content, "utf8");
|
|
57
101
|
return `fern.config.json: org=${org}, version=${FERN_VERSION}`;
|
|
58
102
|
}
|
|
@@ -128,14 +172,6 @@ function updateInstancesBlock(content, instanceUrl, customDomain, multiSource, r
|
|
|
128
172
|
return content.replace(blockRe, newBlock);
|
|
129
173
|
}
|
|
130
174
|
//#endregion
|
|
131
|
-
//#region src/auth.ts
|
|
132
|
-
const resolveToken = createResolveToken({
|
|
133
|
-
envName: "HOLOCRON_FERN_TOKEN",
|
|
134
|
-
vendorEnvName: "FERN_TOKEN",
|
|
135
|
-
keyringService: "fern",
|
|
136
|
-
errorMessage: "no Fern token found. Set HOLOCRON_FERN_TOKEN / FERN_TOKEN, or run: holocron auth set fern <token>"
|
|
137
|
-
});
|
|
138
|
-
//#endregion
|
|
139
175
|
//#region src/index.ts
|
|
140
176
|
function wiki(opts) {
|
|
141
177
|
return new FernWiki(opts);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/holocron-plugin-fern",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.200",
|
|
4
4
|
"description": "Holocron plugin for Fern. Implements the wiki capability for engineering knowledge publishing.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fern",
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"plugin",
|
|
9
9
|
"wiki"
|
|
10
10
|
],
|
|
11
|
-
"homepage": "https://github.com/theholocron/holocron/tree/main/
|
|
11
|
+
"homepage": "https://github.com/theholocron/holocron/tree/main/plugins/holocron-plugin-fern#readme",
|
|
12
12
|
"bugs": "https://github.com/theholocron/holocron/issues",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
15
|
"url": "git+https://github.com/theholocron/holocron.git",
|
|
16
|
-
"directory": "
|
|
16
|
+
"directory": "plugins/holocron-plugin-fern"
|
|
17
17
|
},
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"author": "Newton Koumantzelis",
|
|
@@ -29,11 +29,14 @@
|
|
|
29
29
|
"files": [
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@theholocron/json-utils": "^1.16.0"
|
|
34
|
+
},
|
|
32
35
|
"devDependencies": {
|
|
33
|
-
"@theholocron/eslint-config": "^8.
|
|
34
|
-
"@theholocron/tsconfig": "^8.
|
|
35
|
-
"@theholocron/tsdown-config": "^8.
|
|
36
|
-
"@theholocron/vitest-config": "^8.
|
|
36
|
+
"@theholocron/eslint-config": "^8.8.2",
|
|
37
|
+
"@theholocron/tsconfig": "^8.8.2",
|
|
38
|
+
"@theholocron/tsdown-config": "^8.8.2",
|
|
39
|
+
"@theholocron/vitest-config": "^8.8.2",
|
|
37
40
|
"@types/node": "^26",
|
|
38
41
|
"@vitest/coverage-v8": "^4.1.11",
|
|
39
42
|
"@vitest/eslint-plugin": "^1.6.27",
|
|
@@ -41,13 +44,13 @@
|
|
|
41
44
|
"eslint-plugin-n": "^18.3.0",
|
|
42
45
|
"globals": "^17.11.0",
|
|
43
46
|
"tsdown": "^0.22.14",
|
|
44
|
-
"tsx": "4.23.
|
|
47
|
+
"tsx": "4.23.15",
|
|
45
48
|
"typescript": "^5.9.3",
|
|
46
49
|
"vitest": "^4.1.11",
|
|
47
|
-
"@theholocron/cli": "5.0.0-alpha.
|
|
50
|
+
"@theholocron/cli": "5.0.0-alpha.200"
|
|
48
51
|
},
|
|
49
52
|
"peerDependencies": {
|
|
50
|
-
"@theholocron/cli": "5.0.0-alpha.
|
|
53
|
+
"@theholocron/cli": "5.0.0-alpha.200"
|
|
51
54
|
},
|
|
52
55
|
"engines": {
|
|
53
56
|
"node": ">=22"
|