Skip to content

Commit 2c342b2

Browse files
committed
Add configurable source link generation for documentation
- Introduce `srcLink` configuration option in schema and configuration - Update CLI, Configuration, and Printer modules to support custom source links - Implement fallback source link generation using project homepage - Modify test cases to validate new source link configuration
1 parent abf0c8f commit 2c342b2

7 files changed

Lines changed: 31 additions & 5 deletions

File tree

docs/modules/Configuration.ts.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Since v0.6.0
3939
declare const ConfigurationSchema: Schema.Struct<{
4040
$schema: Schema.optional<typeof Schema.String>
4141
projectHomepage: Schema.optional<typeof Schema.String>
42+
srcLink: Schema.optional<typeof Schema.String>
4243
srcDir: Schema.optional<typeof Schema.String>
4344
outDir: Schema.optional<typeof Schema.String>
4445
theme: Schema.optional<typeof Schema.String>
@@ -66,6 +67,7 @@ Since v0.6.0
6667
export interface ConfigurationShape {
6768
readonly projectName: string
6869
readonly projectHomepage: string
70+
readonly srcLink: string
6971
readonly srcDir: string
7072
readonly outDir: string
7173
readonly theme: string

schema.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
"type": "string",
1313
"description": "Will link to the project homepage from the Auxiliary Links of the generated documentation."
1414
},
15+
"srcLink": {
16+
"type": "string",
17+
"description": "Will link to the project source code."
18+
},
1519
"srcDir": {
1620
"type": "string",
1721
"description": "The directory in which docgen will search for TypeScript files to parse.",
@@ -96,4 +100,4 @@
96100
}
97101
},
98102
"$ref": "#/$defs/ConfigurationSchema"
99-
}
103+
}

src/CLI.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ const projectHomepage = Options.text("homepage").pipe(
2727
Options.optional
2828
)
2929

30+
const srcLink = Options.text("srcLink").pipe(
31+
Options.withFallbackConfig(Config.string("srcLink")),
32+
Options.withDescription(
33+
"The link to the project source code"
34+
),
35+
Options.optional
36+
)
37+
3038
const srcDir = Options.directory("src", { exists: "yes" }).pipe(
3139
Options.withFallbackConfig(Config.string("src").pipe(Config.withDefault("src"))),
3240
Options.withDescription(
@@ -157,6 +165,7 @@ const examplesCompilerOptions = Options.file("examples-tsconfig-file", { exists:
157165

158166
const options = {
159167
projectHomepage,
168+
srcLink,
160169
srcDir,
161170
outDir,
162171
theme,

src/Configuration.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ export const ConfigurationSchema = Schema.Struct({
3535
projectHomepage: Schema.optional(Schema.String).annotations({
3636
description: "Will link to the project homepage from the Auxiliary Links of the generated documentation."
3737
}),
38+
srcLink: Schema.optional(Schema.String).annotations({
39+
description: "Will link to the project source code."
40+
}),
3841
srcDir: Schema.optional(Schema.String).annotations({
3942
description: "The directory in which docgen will search for TypeScript files to parse.",
4043
default: "src"
@@ -85,6 +88,7 @@ export const ConfigurationSchema = Schema.Struct({
8588
export interface ConfigurationShape {
8689
readonly projectName: string
8790
readonly projectHomepage: string
91+
readonly srcLink: string
8892
readonly srcDir: string
8993
readonly outDir: string
9094
readonly theme: string
@@ -225,6 +229,7 @@ const PackageJsonSchema = Schema.Struct({
225229
/** @internal */
226230
export const load = (args: {
227231
readonly projectHomepage: Option.Option<string>
232+
readonly srcLink: Option.Option<string>
228233
readonly srcDir: string
229234
readonly outDir: string
230235
readonly theme: string
@@ -248,6 +253,7 @@ export const load = (args: {
248253
const packageJson = yield* validateJsonFile(PackageJsonSchema, packageJsonPath)
249254
const projectName = packageJson.name
250255
const projectHomepage = Option.getOrElse(args.projectHomepage, () => packageJson.homepage)
256+
const srcLink = Option.getOrElse(args.srcLink, () => `${projectHomepage}/blob/main/src/`)
251257

252258
// Read the `docgen.json` configuration file to gain access to the TypeScript
253259
// configuration options
@@ -292,6 +298,7 @@ export const load = (args: {
292298
outDir,
293299
projectName,
294300
projectHomepage,
301+
srcLink,
295302
exclude,
296303
examplesCompilerOptions,
297304
parseCompilerOptions

src/Printer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ const printOptionalSourceLink = (position?: Domain.Position) => {
117117
const config = yield* Configuration.Configuration
118118
const source = yield* Parser.Source
119119
const name = source.sourceFile.getBaseName()
120-
return `\n\n[Source](${config.projectHomepage}/blob/main/src/${name}#L${position.line})`
120+
return `\n\n[Source](${config.srcLink}${name}#L${position.line})`
121121
})
122122
}
123123

test/Configuration.test.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ import * as Option from "effect/Option"
1515
import * as assert from "node:assert/strict"
1616
import { describe, it } from "vitest"
1717

18-
type DocgenJson = Record<string, unknown>
18+
type DocgenJson = typeof Configuration.ConfigurationSchema.Type
1919

2020
class DocgenJsonTag extends Context.Tag("DocgenJsonTag")<DocgenJsonTag, DocgenJson>() {}
2121

22-
const makeDocgenJson = (config: Record<string, unknown>) => Layer.succeed(DocgenJsonTag, config)
22+
const makeDocgenJson = (config: DocgenJson) => Layer.succeed(DocgenJsonTag, config)
2323

2424
const TestFileSystem = Layer.effect(
2525
FileSystem.FileSystem,
@@ -79,6 +79,7 @@ describe("Configuration", () => {
7979
assert.deepStrictEqual(config, {
8080
projectName: "name",
8181
projectHomepage: "homepage",
82+
srcLink: "homepage/blob/main/src/",
8283
srcDir: "src",
8384
outDir: "docs",
8485
theme: "mikearnaldi/just-the-docs",
@@ -114,6 +115,7 @@ describe("Configuration", () => {
114115
assert.deepStrictEqual(config, {
115116
projectName: "name",
116117
projectHomepage: "myproject",
118+
srcLink: "mygithub",
117119
srcDir: "src",
118120
outDir: "docs",
119121
theme: "mikearnaldi/just-the-docs",
@@ -132,6 +134,7 @@ describe("Configuration", () => {
132134
Effect.provide(TestLive.pipe(Layer.provide(
133135
makeDocgenJson({
134136
projectHomepage: "myproject",
137+
srcLink: "mygithub",
135138
parseCompilerOptions
136139
})
137140
))),
@@ -142,7 +145,7 @@ describe("Configuration", () => {
142145
it("should raise a validation error if docgen.json is not valid", async () => {
143146
const cli = testCliFor(Effect.void)
144147
const result = await cli([]).pipe(
145-
Effect.provide(TestLive.pipe(Layer.provide(makeDocgenJson({ projectHomepage: 1 })))),
148+
Effect.provide(TestLive.pipe(Layer.provide(makeDocgenJson({ projectHomepage: 1 } as any)))),
146149
Effect.runPromiseExit
147150
)
148151
assert.deepStrictEqual(

test/Parser.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const project = new ast.Project({
1818
const defaultConfig: Configuration.ConfigurationShape = {
1919
projectName: "docgen",
2020
projectHomepage: "https://github.com/effect-ts/docgen",
21+
srcLink: "https://github.com/effect-ts/docgen/blob/main/src/",
2122
srcDir: "src",
2223
outDir: "docs",
2324
theme: "pmarsceill/just-the-docs",

0 commit comments

Comments
 (0)