Skip to content

Commit

Permalink
fix: typecheck examples deeply nested within namespaces (#93) (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
vecerek authored Nov 25, 2024
1 parent 3ce1371 commit 0b3b34e
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 33 deletions.
5 changes: 5 additions & 0 deletions .changeset/poor-plants-look.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect/docgen": patch
---

Typecheck examples deeply nested within namespaces
42 changes: 15 additions & 27 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,81 +7,69 @@
"required": [],
"properties": {
"$schema": {
"type": "string",
"description": "a string",
"title": "string"
"type": "string"
},
"projectHomepage": {
"type": "string",
"description": "Will link to the project homepage from the Auxiliary Links of the generated documentation.",
"title": "string"
"description": "Will link to the project homepage from the Auxiliary Links of the generated documentation."
},
"srcDir": {
"type": "string",
"description": "The directory in which docgen will search for TypeScript files to parse.",
"title": "string",
"default": "src"
},
"outDir": {
"type": "string",
"description": "The directory to which docgen will generate its output markdown documents.",
"title": "string",
"default": "docs"
},
"theme": {
"type": "string",
"description": "The theme that docgen will specify should be used for GitHub Docs in the generated _config.yml file.",
"title": "string",
"default": "mikearnaldi/just-the-docs"
},
"enableSearch": {
"type": "boolean",
"description": "Whether or not search should be enabled for GitHub Docs in the generated _config.yml file.",
"title": "boolean",
"default": true
},
"enforceDescriptions": {
"type": "boolean",
"description": "Whether or not descriptions for each module export should be required.",
"title": "boolean",
"default": false
},
"enforceExamples": {
"type": "boolean",
"description": "Whether or not @example tags for each module export should be required. (Note: examples will not be enforced in module documentation)",
"title": "boolean",
"default": false
},
"enforceVersion": {
"type": "boolean",
"description": "Whether or not @since tags for each module export should be required.",
"title": "boolean",
"default": true
},
"exclude": {
"type": "array",
"items": {
"type": "string",
"description": "a string",
"title": "string"
"type": "string"
},
"description": "An array of glob strings specifying files that should be excluded from the documentation.",
"default": []
},
"parseCompilerOptions": {
"anyOf": [
{
"type": "string",
"description": "a string",
"title": "string"
"type": "string"
},
{
"type": "object",
"required": [],
"properties": {},
"additionalProperties": {
"$id": "/schemas/unknown",
"title": "unknown"
"patternProperties": {
"": {
"$id": "/schemas/unknown",
"title": "unknown"
}
}
}
],
Expand All @@ -91,17 +79,17 @@
"examplesCompilerOptions": {
"anyOf": [
{
"type": "string",
"description": "a string",
"title": "string"
"type": "string"
},
{
"type": "object",
"required": [],
"properties": {},
"additionalProperties": {
"$id": "/schemas/unknown",
"title": "unknown"
"patternProperties": {
"": {
"$id": "/schemas/unknown",
"title": "unknown"
}
}
}
],
Expand Down
63 changes: 57 additions & 6 deletions src/Core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as CommandExecutor from "@effect/platform/CommandExecutor"
import * as FileSystem from "@effect/platform/FileSystem"
import * as Path from "@effect/platform/Path"
import chalk from "chalk"
import { pipe } from "effect"
import * as Array from "effect/Array"
import * as Chunk from "effect/Chunk"
import * as Effect from "effect/Effect"
Expand Down Expand Up @@ -130,6 +131,32 @@ const typeCheckAndRunExamples = (modules: ReadonlyArray<Domain.Module>) =>
}
})

/**
* Joins an array of strings with a "-" after dropping all empty strings.
*/
const filterJoin = (self: Array<string>) =>
pipe(
self,
Array.filter(String.isNonEmpty),
Array.join("-")
)

/**
* Extracts deeply nested namespaces with their corresponding namespace prefix
* from a given namespace.
*/
const extractPrefixedNestedNamespaces = (
doc: Domain.Namespace,
prefix: string
): ReadonlyArray<[string, Domain.Namespace]> => {
const newPrefix = String.isEmpty(prefix) ? doc.name : `${prefix}-${doc.name}`
const namespaces = Array.flatMap(
doc.namespaces,
(namespace) => extractPrefixedNestedNamespaces(namespace, newPrefix)
)
return Array.prepend(namespaces, [prefix, doc])
}

/**
* Generates example files for the given modules.
*/
Expand All @@ -155,6 +182,9 @@ const getExampleFiles = (modules: ReadonlyArray<Domain.Module>) =>
)
)

const allPrefixedNamespaces = Array.flatMap(module.namespaces, (namespace) =>
extractPrefixedNestedNamespaces(namespace, ""))

const moduleExamples = getFiles("module")(module)
const methodsExamples = Array.flatMap(module.classes, (c) =>
Array.flatten([
Expand All @@ -167,13 +197,33 @@ const getExampleFiles = (modules: ReadonlyArray<Domain.Module>) =>
getFiles(`${c.name}-staticmethod`)
)
]))
const allPrefixedInterfaces = [
...module.interfaces.map((iface) =>
["" as string, iface] as const
),
...Array.flatMap(allPrefixedNamespaces, ([prefix, namespace]) =>
namespace.interfaces.map((iface) =>
[filterJoin([prefix, namespace.name]), iface] as const
))
]
const interfacesExamples = Array.flatMap(
module.interfaces,
getFiles("interface")
allPrefixedInterfaces,
([ns, doc]) =>
getFiles(filterJoin(["interface", ns]))(doc)
)
const allPrefixedTypeAliases = [
...module.typeAliases.map((typeAlias) =>
["" as string, typeAlias] as const
),
...Array.flatMap(allPrefixedNamespaces, ([prefix, namespace]) =>
namespace.typeAliases.map((typeAlias) =>
[filterJoin([prefix, namespace.name]), typeAlias] as const
))
]
const typeAliasesExamples = Array.flatMap(
module.typeAliases,
getFiles("typealias")
allPrefixedTypeAliases,
([ns, doc]) =>
getFiles(filterJoin(["typealias", ns]))(doc)
)
const constantsExamples = Array.flatMap(
module.constants,
Expand All @@ -184,8 +234,9 @@ const getExampleFiles = (modules: ReadonlyArray<Domain.Module>) =>
getFiles("function")
)
const namespacesExamples = Array.flatMap(
module.namespaces,
getFiles("namespace")
allPrefixedNamespaces,
([ns, doc]) =>
getFiles(filterJoin(["namespace", ns]))(doc)
)

return Array.flatten([
Expand Down

0 comments on commit 0b3b34e

Please sign in to comment.