Skip to content

Commit 868083a

Browse files
committed
chore: add doc generation for AI
1 parent d98a42a commit 868083a

File tree

10 files changed

+187
-16
lines changed

10 files changed

+187
-16
lines changed

docs/modules/Configuration.ts.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export declare const ConfigurationSchema: Schema.Struct<{
5353
examplesCompilerOptions: Schema.optional<
5454
Schema.Union<[typeof Schema.String, Schema.Record$<typeof Schema.String, typeof Schema.Unknown>]>
5555
>
56+
enableAI: Schema.optional<typeof Schema.Boolean>
5657
}>
5758
```
5859

@@ -77,6 +78,7 @@ export interface ConfigurationShape {
7778
readonly exclude: ReadonlyArray<string>
7879
readonly parseCompilerOptions: Record<string, unknown>
7980
readonly examplesCompilerOptions: Record<string, unknown>
81+
readonly enableAI: boolean
8082
}
8183
```
8284

docs/modules/Domain.ts.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Added in v1.0.0
1212

1313
<h2 class="text-delta">Table of contents</h2>
1414

15+
- [accessors](#accessors)
16+
- [printablesFromModule](#printablesfrommodule)
1517
- [constructors](#constructors)
1618
- [createClass](#createclass)
1719
- [createConstant](#createconstant)
@@ -37,13 +39,26 @@ Added in v1.0.0
3739
- [Module (interface)](#module-interface)
3840
- [NamedDoc (interface)](#nameddoc-interface)
3941
- [Namespace (interface)](#namespace-interface)
42+
- [Printable (type alias)](#printable-type-alias)
4043
- [Property (interface)](#property-interface)
4144
- [TypeAlias (interface)](#typealias-interface)
4245
- [sorting](#sorting)
4346
- [ByPath](#bypath)
4447

4548
---
4649

50+
# accessors
51+
52+
## printablesFromModule
53+
54+
**Signature**
55+
56+
```ts
57+
export declare const printablesFromModule: (module: Module) => ReadonlyArray<Printable>
58+
```
59+
60+
Added in v1.0.0
61+
4762
# constructors
4863
4964
## createClass
@@ -370,6 +385,16 @@ export interface Namespace extends NamedDoc {
370385

371386
Added in v1.0.0
372387

388+
## Printable (type alias)
389+
390+
**Signature**
391+
392+
```ts
393+
export type Printable = Class | Constant | Export | Function | Interface | TypeAlias | Namespace
394+
```
395+
396+
Added in v1.0.0
397+
373398
## Property (interface)
374399
375400
**Signature**

docs/modules/Markdown.ts.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Added in v1.0.0
1414

1515
- [printers](#printers)
1616
- [printModule](#printmodule)
17+
- [printPrintableForAI](#printprintableforai)
1718

1819
---
1920

@@ -40,3 +41,17 @@ console.log(Markdown.printModule(m, 0))
4041
```
4142

4243
Added in v1.0.0
44+
45+
## printPrintableForAI
46+
47+
**Signature**
48+
49+
```ts
50+
export declare const printPrintableForAI: (
51+
projectName: string,
52+
module: Domain.Module,
53+
printable: Domain.Printable
54+
) => Effect.Effect<string, never, never>
55+
```
56+
57+
Added in v1.0.0

schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@
9595
],
9696
"description": "tsconfig for the examples options (or path to a tsconfig)",
9797
"default": {}
98+
},
99+
"enableAI": {
100+
"type": "boolean",
101+
"description": "Whether or not to enable AI for the examples",
102+
"default": true
98103
}
99104
},
100105
"additionalProperties": false

src/CLI.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,17 @@ const examplesCompilerOptions = Options.file("examples-tsconfig-file", { exists:
156156
Options.optional
157157
)
158158

159+
const enableAI = Options.boolean("no-run-examples", {
160+
ifPresent: false,
161+
negationNames: ["run-examples"]
162+
}).pipe(
163+
Options.withFallbackConfig(Config.boolean("enableAI")),
164+
Options.withDefault(true),
165+
Options.withDescription(
166+
"Whether or not to generate AI documentation for the project"
167+
)
168+
)
169+
159170
const options = {
160171
projectHomepage,
161172
srcDir,
@@ -168,7 +179,8 @@ const options = {
168179
runExamples,
169180
exclude,
170181
parseCompilerOptions,
171-
examplesCompilerOptions
182+
examplesCompilerOptions,
183+
enableAI
172184
}
173185

174186
/** @internal */

src/Configuration.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ export const ConfigurationSchema = Schema.Struct({
7979
examplesCompilerOptions: Schema.optional(compilerOptionsSchema).annotations({
8080
description: "tsconfig for the examples options (or path to a tsconfig)",
8181
default: {}
82+
}),
83+
enableAI: Schema.optional(Schema.Boolean).annotations({
84+
description: "Whether or not to enable AI for the examples",
85+
default: true
8286
})
8387
}).annotations({ identifier: "ConfigurationSchema" })
8488

@@ -100,6 +104,7 @@ export interface ConfigurationShape {
100104
readonly exclude: ReadonlyArray<string>
101105
readonly parseCompilerOptions: Record<string, unknown>
102106
readonly examplesCompilerOptions: Record<string, unknown>
107+
readonly enableAI: boolean
103108
}
104109

105110
/**
@@ -244,6 +249,7 @@ export const load = (args: {
244249
readonly exclude: ReadonlyArray<string>
245250
readonly parseCompilerOptions: Option.Option<string | Record<string, unknown>>
246251
readonly examplesCompilerOptions: Option.Option<string | Record<string, unknown>>
252+
readonly enableAI: boolean
247253
}) =>
248254
Effect.gen(function*(_) {
249255
// Extract the requisite services

src/Core.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ import { pipe } from "effect"
1212
import * as Array from "effect/Array"
1313
import * as Chunk from "effect/Chunk"
1414
import * as Effect from "effect/Effect"
15+
import { pipe } from "effect/Function"
1516
import * as Stream from "effect/Stream"
1617
import * as String from "effect/String"
1718
import * as Glob from "glob"
1819
import * as Configuration from "./Configuration.js"
19-
import type * as Domain from "./Domain.js"
20+
import * as Domain from "./Domain.js"
2021
import { DocgenError } from "./Error.js"
2122
import * as File from "./File.js"
22-
import { printModule } from "./Markdown.js"
23+
import { printModule, printPrintableForAI } from "./Markdown.js"
2324
import * as Parser from "./Parser.js"
2425
import * as Process from "./Process.js"
2526

@@ -436,7 +437,8 @@ const getMarkdown = (modules: ReadonlyArray<Domain.Module>) =>
436437
const index = yield* _(getMarkdownIndex)
437438
const yml = yield* _(getMarkdownConfigYML)
438439
const moduleFiles = yield* _(getModuleMarkdownFiles(modules))
439-
return [homepage, index, yml, ...moduleFiles]
440+
const aiFiles = yield* _(maybeGetAIMarkdownFiles(modules))
441+
return [homepage, index, yml, ...moduleFiles, ...aiFiles]
440442
})
441443

442444
const getMarkdownHomepage = Effect.gen(function*(_) {
@@ -538,6 +540,14 @@ const getModuleMarkdownOutputPath = (module: Domain.Module) =>
538540
))
539541
)
540542

543+
const getAIMarkdownOutputPath = (module: Domain.Module, printable: Domain.Printable) =>
544+
Effect.map(Effect.all([Configuration.Configuration, Path.Path]), ([config, path]) =>
545+
path.join(
546+
config.outDir,
547+
"ai",
548+
`${module.path.slice(1).join("-").replace(/\.ts$/, "")}-${printable.name}.md`
549+
))
550+
541551
const getModuleMarkdownFiles = (modules: ReadonlyArray<Domain.Module>) =>
542552
Effect.forEach(modules, (module, order) =>
543553
Effect.gen(function*(_) {
@@ -546,6 +556,34 @@ const getModuleMarkdownFiles = (modules: ReadonlyArray<Domain.Module>) =>
546556
return File.createFile(outputPath, content, true)
547557
}))
548558

559+
const getAIMarkdownFiles = (projectName: string, modules: ReadonlyArray<Domain.Module>) =>
560+
Effect.gen(function*(_) {
561+
const aiModules = pipe(
562+
modules,
563+
Array.flatMap((module) =>
564+
pipe(
565+
Domain.printablesFromModule(module),
566+
Array.map((printable) => ({ module, printable }))
567+
)
568+
),
569+
Array.filter(({ printable }) => printable.description._tag === "Some")
570+
)
571+
572+
return yield* _(Effect.forEach(aiModules, ({ module, printable }) =>
573+
Effect.gen(function*(_) {
574+
const outputPath = yield* _(getAIMarkdownOutputPath(module, printable))
575+
const content = yield* _(printPrintableForAI(projectName, module, printable))
576+
return File.createFile(outputPath, content, true)
577+
})))
578+
})
579+
580+
const maybeGetAIMarkdownFiles = (modules: ReadonlyArray<Domain.Module>) =>
581+
Effect.flatMap(
582+
Configuration.Configuration,
583+
(config) =>
584+
config.enableAI ? getAIMarkdownFiles(config.projectName, modules) : Effect.succeed([])
585+
)
586+
549587
const writeMarkdown = (files: ReadonlyArray<File.File>) =>
550588
Effect.gen(function*(_) {
551589
const config = yield* _(Configuration.Configuration)

src/Domain.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,19 @@ export interface Namespace extends NamedDoc {
147147
readonly namespaces: ReadonlyArray<Namespace>
148148
}
149149

150+
/**
151+
* @category model
152+
* @since 1.0.0
153+
*/
154+
export type Printable =
155+
| Class
156+
| Constant
157+
| Export
158+
| Function
159+
| Interface
160+
| TypeAlias
161+
| Namespace
162+
150163
// -------------------------------------------------------------------------------------
151164
// constructors
152165
// -------------------------------------------------------------------------------------
@@ -282,6 +295,24 @@ export const createExport = (doc: NamedDoc, signature: string): Export => ({
282295
signature
283296
})
284297

298+
// -------------------------------------------------------------------------------------
299+
// accessors
300+
// -------------------------------------------------------------------------------------
301+
302+
/**
303+
* @category accessors
304+
* @since 1.0.0
305+
*/
306+
export const printablesFromModule = (module: Module): ReadonlyArray<Printable> =>
307+
[
308+
module.classes,
309+
module.constants,
310+
module.exports,
311+
module.functions,
312+
module.interfaces,
313+
module.typeAliases
314+
].flat()
315+
285316
/**
286317
* @category constructors
287318
* @since 1.0.0

src/Markdown.ts

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,6 @@ import * as String from "effect/String"
1111
import * as Prettier from "prettier"
1212
import type * as Domain from "./Domain.js"
1313

14-
type Printable =
15-
| Domain.Class
16-
| Domain.Constant
17-
| Domain.Export
18-
| Domain.Function
19-
| Domain.Interface
20-
| Domain.TypeAlias
21-
| Domain.Namespace
22-
2314
const createHeaderPrinter = (level: number) => (content: string): string =>
2415
"#".repeat(level) + " " + content + "\n\n"
2516

@@ -72,6 +63,28 @@ const printExamples = (es: ReadonlyArray<Domain.Example>): string =>
7263
)
7364
.join("\n\n")
7465

66+
const printImportDescription = (
67+
projectName: string,
68+
module: Domain.Module,
69+
method: string
70+
): string => {
71+
const namespace = module.path.slice(1).join("/").replace(/\.ts$/, "")
72+
73+
return (
74+
MarkdownPrinter.paragraph(
75+
`To import and use \`${method}\` from the "${module.name}" module:`
76+
) +
77+
MarkdownPrinter.paragraph(
78+
MarkdownPrinter.fence(
79+
"ts",
80+
`import * as ${module.name} from "${projectName}/${namespace}"
81+
// Can be accessed like this
82+
${module.name}.${method}`
83+
)
84+
)
85+
)
86+
}
87+
7588
const printStaticMethod = (m: Domain.Method): string =>
7689
MarkdownPrinter.paragraph(
7790
MarkdownPrinter.h3(printTitle(m.name, m.deprecated, "(static method)")),
@@ -229,7 +242,7 @@ export const printNamespace = (ns: Domain.Namespace, indentation: number): strin
229242
)
230243

231244
/** @internal */
232-
export const print = (p: Printable): string => {
245+
export const print = (p: Domain.Printable): string => {
233246
switch (p._tag) {
234247
case "Class":
235248
return printClass(p)
@@ -248,7 +261,7 @@ export const print = (p: Printable): string => {
248261
}
249262
}
250263

251-
const getPrintables = (module: Domain.Module): ReadonlyArray<Printable> =>
264+
const getPrintables = (module: Domain.Module): ReadonlyArray<Domain.Printable> =>
252265
Array.flatten([
253266
module.classes,
254267
module.constants,
@@ -301,7 +314,7 @@ export const printModule = (
301314
Array.sort(
302315
Order.mapInput(
303316
String.Order,
304-
(printable: Printable) => printable.name
317+
(printable: Domain.Printable) => printable.name
305318
)
306319
),
307320
Array.map(print)
@@ -337,6 +350,29 @@ export const printModule = (
337350
))
338351
})
339352

353+
/**
354+
* @category printers
355+
* @since 1.0.0
356+
*/
357+
export const printPrintableForAI = (
358+
projectName: string,
359+
module: Domain.Module,
360+
printable: Domain.Printable
361+
) =>
362+
prettify(
363+
[
364+
MarkdownPrinter.h1(printable.name),
365+
printDescription(printable.description),
366+
printImportDescription(projectName, module, printable.name),
367+
printExamples(printable.examples),
368+
printable._tag === "Function"
369+
? printSignatures(printable.signatures)
370+
: printable._tag === "Constant"
371+
? printSignature(printable.signature)
372+
: ""
373+
].join("\n")
374+
)
375+
340376
const defaultPrettierOptions: Prettier.Options = {
341377
parser: "markdown",
342378
semi: false,

test/Parser.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const defaultConfig: Configuration.ConfigurationShape = {
2121
srcDir: "src",
2222
outDir: "docs",
2323
theme: "pmarsceill/just-the-docs",
24+
enableAI: true,
2425
enableSearch: true,
2526
enforceDescriptions: false,
2627
enforceExamples: false,

0 commit comments

Comments
 (0)