docs: added typedoc plugin to parse DML json files (#8300)

* docs-util: add docblock generator for models built with DML

* add missing turbo task

* docs-util: added typedoc plugin to parse dml json files
This commit is contained in:
Shahed Nasser
2024-07-29 15:19:04 +03:00
committed by GitHub
parent df734a3ce9
commit 7ad4e7b1c9
11 changed files with 124 additions and 29 deletions

View File

@@ -34,6 +34,7 @@
},
"devDependencies": {
"@types/node": "^20.9.4",
"@types/pluralize": "^0.0.33"
"@types/pluralize": "^0.0.33",
"types": "*"
}
}

View File

@@ -5,7 +5,7 @@ import { GeneratorEvent } from "../helpers/generator-event-manager.js"
import { minimatch } from "minimatch"
import getBasePath from "../../utils/get-base-path.js"
import toJsonFormatted from "../../utils/to-json-formatted.js"
import { DmlFile } from "../../types/index.js"
import { DmlFile } from "types"
/**
* A class used to generate DML JSON files with descriptions of properties.

View File

@@ -5,7 +5,7 @@ import { getDmlOutputBasePath } from "../../utils/get-output-base-paths.js"
import path from "path"
import { camelToWords, RELATION_NAMES, snakeToPascal } from "utils"
import toJsonFormatted from "../../utils/to-json-formatted.js"
import { DmlFile, DmlObject } from "../../types/index.js"
import { DmlFile, DmlObject } from "types"
/**
* DML generator for data models created with DML.

View File

@@ -2,7 +2,7 @@ import { readdirSync, existsSync, readFileSync, writeFileSync } from "fs"
import { getDmlOutputBasePath } from "../utils/get-output-base-paths.js"
import path from "path"
import getMonorepoRoot from "../utils/get-monorepo-root.js"
import { DmlFile } from "../types/index.js"
import { DmlFile } from "types"
import toJsonFormatted from "../utils/to-json-formatted.js"
export default async function () {

View File

@@ -2,7 +2,7 @@
"name": "typedoc-generate-references",
"license": "MIT",
"scripts": {
"dev": "cross-env ts-node src/index.ts",
"dev": "node --loader ts-node/esm src/index.ts",
"start": "node dist/index.js",
"build": "tsc",
"watch": "tsc --watch",

View File

@@ -24,6 +24,7 @@
"devDependencies": {
"@types/eslint": "^8.56.6",
"@types/node": "^16.11.10",
"types": "*",
"typescript": "5.5"
},
"keywords": [

View File

@@ -0,0 +1,104 @@
import { existsSync, readFileSync } from "fs"
import path from "path"
import {
Application,
Comment,
Context,
Converter,
DeclarationReflection,
ReferenceType,
} from "typedoc"
import { getDmlProperties, isDmlEntity } from "utils"
import { DmlFile } from "types"
const FILE_NAME_REGEX = /packages\/modules\/(?<module>[a-z-]+)/
export function load(app: Application) {
app.converter.on(
Converter.EVENT_CREATE_DECLARATION,
getDescriptionsFromJson,
2
)
}
function getDescriptionsFromJson(
context: Context,
reflection: DeclarationReflection
) {
if (!isDmlEntity(reflection)) {
return
}
const dmlPropertyReflections = getDmlProperties(
reflection.type as ReferenceType
)
if (!dmlPropertyReflections) {
return
}
const fileName = context.project
.getSymbolFromReflection(reflection)
?.valueDeclaration?.parent.getSourceFile().fileName
if (!fileName) {
return
}
const moduleName = FILE_NAME_REGEX.exec(fileName)
if (!moduleName?.groups?.module) {
return
}
const jsonFilePath = path.resolve(
__dirname,
path.join(
"..",
"..",
"..",
"generated",
"dml-output",
`${moduleName.groups.module}.json`
)
)
if (!existsSync(jsonFilePath)) {
return
}
const jsonFileContent = JSON.parse(
readFileSync(jsonFilePath, "utf-8")
) as DmlFile
if (!jsonFileContent[reflection.name]) {
return
}
Object.entries(jsonFileContent[reflection.name].properties).forEach(
([propertyName, description]) => {
const propertyReflection = dmlPropertyReflections.find(
(propertyRef) => propertyRef.name === propertyName
)
if (!propertyReflection) {
return
}
const comment = propertyReflection.comment || new Comment()
const isExpandable = description.includes("@expandable")
comment.summary.push({
kind: "text",
text: description.replace("@expandable", "").trim(),
})
if (isExpandable) {
comment.modifierTags.add("@expandable")
}
propertyReflection.comment = comment
}
)
}

View File

@@ -41,12 +41,6 @@ export class DmlRelationsResolver {
this.resolveRelationReferences.bind(this),
1
)
// this.app.converter.on(
// Converter.EVENT_RESOLVE_BEGIN,
// this.resolveRelationTargets.bind(this),
// -1
// )
}
addReflection(_context: Context, reflection: DeclarationReflection) {
@@ -110,24 +104,6 @@ export class DmlRelationsResolver {
})
}
resolveRelationTargets(context: Context) {
if (!this.app.options.getValue("resolveDmlRelations")) {
return
}
this.relationProperties.forEach(({ property, target }) => {
const targetSymbol = context.project.getSymbolFromReflection(target)
if (property.type?.type !== "reference" || !targetSymbol) {
return
}
// change reference to the target itself.
property.type = ReferenceType.createResolvedReference(
`DmlEntity`,
target,
context.project
)
})
}
findReflectionMatchingProperties(
properties: DeclarationReflection[]
): DeclarationReflection | undefined {

View File

@@ -11,6 +11,7 @@ import { GenerateNamespacePlugin } from "./generate-namespace"
import { DmlRelationsResolver } from "./dml-relations-resolver"
import { load as dmlTypesNormalizer } from "./dml-types-normalizer"
import { MermaidDiagramDMLGenerator } from "./mermaid-diagram-dml-generator"
import { load as dmlJsonParser } from "./dml-json-parser"
export function load(app: Application) {
resolveReferencesPluginLoad(app)
@@ -21,6 +22,7 @@ export function load(app: Application) {
signatureModifierPlugin(app)
parentIgnorePlugin(app)
dmlTypesNormalizer(app)
dmlJsonParser(app)
new GenerateNamespacePlugin(app)
new MermaidDiagramGenerator(app)

View File

@@ -259,3 +259,12 @@ export declare module "typedoc" {
normalizeDmlTypes: boolean
}
}
export declare type DmlObject = Record<string, string>
export declare type DmlFile = {
[k: string]: {
filePath: string
properties: DmlObject
}
}