From 7ad4e7b1c928d028081d7d56bca560f263cc2c13 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Mon, 29 Jul 2024 15:19:04 +0300 Subject: [PATCH] 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 --- .../packages/docblock-generator/package.json | 3 +- .../src/classes/generators/dml.ts | 2 +- .../src/classes/kinds/dml.ts | 2 +- .../src/commands/clean-dml.ts | 2 +- .../typedoc-generate-references/package.json | 2 +- .../typedoc-plugin-custom/package.json | 1 + .../src/dml-json-parser.ts | 104 ++++++++++++++++++ .../src/dml-relations-resolver.ts | 24 ---- .../typedoc-plugin-custom/src/index.ts | 2 + www/utils/packages/types/lib/index.d.ts | 9 ++ www/utils/yarn.lock | 2 + 11 files changed, 124 insertions(+), 29 deletions(-) create mode 100644 www/utils/packages/typedoc-plugin-custom/src/dml-json-parser.ts diff --git a/www/utils/packages/docblock-generator/package.json b/www/utils/packages/docblock-generator/package.json index 72e76f8fe4..926605f82a 100644 --- a/www/utils/packages/docblock-generator/package.json +++ b/www/utils/packages/docblock-generator/package.json @@ -34,6 +34,7 @@ }, "devDependencies": { "@types/node": "^20.9.4", - "@types/pluralize": "^0.0.33" + "@types/pluralize": "^0.0.33", + "types": "*" } } diff --git a/www/utils/packages/docblock-generator/src/classes/generators/dml.ts b/www/utils/packages/docblock-generator/src/classes/generators/dml.ts index df1d2d02e8..cd171fe6fb 100644 --- a/www/utils/packages/docblock-generator/src/classes/generators/dml.ts +++ b/www/utils/packages/docblock-generator/src/classes/generators/dml.ts @@ -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. diff --git a/www/utils/packages/docblock-generator/src/classes/kinds/dml.ts b/www/utils/packages/docblock-generator/src/classes/kinds/dml.ts index 0436bd0778..104a9381bb 100644 --- a/www/utils/packages/docblock-generator/src/classes/kinds/dml.ts +++ b/www/utils/packages/docblock-generator/src/classes/kinds/dml.ts @@ -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. diff --git a/www/utils/packages/docblock-generator/src/commands/clean-dml.ts b/www/utils/packages/docblock-generator/src/commands/clean-dml.ts index 08b54a5edc..94aca2754b 100644 --- a/www/utils/packages/docblock-generator/src/commands/clean-dml.ts +++ b/www/utils/packages/docblock-generator/src/commands/clean-dml.ts @@ -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 () { diff --git a/www/utils/packages/typedoc-generate-references/package.json b/www/utils/packages/typedoc-generate-references/package.json index f3f729cda8..5d8cc8d323 100644 --- a/www/utils/packages/typedoc-generate-references/package.json +++ b/www/utils/packages/typedoc-generate-references/package.json @@ -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", diff --git a/www/utils/packages/typedoc-plugin-custom/package.json b/www/utils/packages/typedoc-plugin-custom/package.json index aa2ff5180f..f2ba0931d2 100644 --- a/www/utils/packages/typedoc-plugin-custom/package.json +++ b/www/utils/packages/typedoc-plugin-custom/package.json @@ -24,6 +24,7 @@ "devDependencies": { "@types/eslint": "^8.56.6", "@types/node": "^16.11.10", + "types": "*", "typescript": "5.5" }, "keywords": [ diff --git a/www/utils/packages/typedoc-plugin-custom/src/dml-json-parser.ts b/www/utils/packages/typedoc-plugin-custom/src/dml-json-parser.ts new file mode 100644 index 0000000000..6d130c802e --- /dev/null +++ b/www/utils/packages/typedoc-plugin-custom/src/dml-json-parser.ts @@ -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\/(?[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 + } + ) +} diff --git a/www/utils/packages/typedoc-plugin-custom/src/dml-relations-resolver.ts b/www/utils/packages/typedoc-plugin-custom/src/dml-relations-resolver.ts index 87710537ef..bae293ce87 100644 --- a/www/utils/packages/typedoc-plugin-custom/src/dml-relations-resolver.ts +++ b/www/utils/packages/typedoc-plugin-custom/src/dml-relations-resolver.ts @@ -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 { diff --git a/www/utils/packages/typedoc-plugin-custom/src/index.ts b/www/utils/packages/typedoc-plugin-custom/src/index.ts index b625669621..5adf125339 100644 --- a/www/utils/packages/typedoc-plugin-custom/src/index.ts +++ b/www/utils/packages/typedoc-plugin-custom/src/index.ts @@ -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) diff --git a/www/utils/packages/types/lib/index.d.ts b/www/utils/packages/types/lib/index.d.ts index a866a9b38a..975073f5f1 100644 --- a/www/utils/packages/types/lib/index.d.ts +++ b/www/utils/packages/types/lib/index.d.ts @@ -259,3 +259,12 @@ export declare module "typedoc" { normalizeDmlTypes: boolean } } + +export declare type DmlObject = Record + +export declare type DmlFile = { + [k: string]: { + filePath: string + properties: DmlObject + } +} diff --git a/www/utils/yarn.lock b/www/utils/yarn.lock index 9f876a404c..2cc8db0453 100644 --- a/www/utils/yarn.lock +++ b/www/utils/yarn.lock @@ -2360,6 +2360,7 @@ __metadata: pluralize: ^8.0.0 prettier: ^3.2.4 ts-node: ^10.9.1 + types: "*" typescript: 5.5 utils: "*" yaml: ^2.3.4 @@ -5346,6 +5347,7 @@ __metadata: "@types/node": ^16.11.10 eslint: ^8.53.0 glob: ^10.3.10 + types: "*" typescript: 5.5 utils: "*" yaml: ^2.3.3