docs: enhance how references are generated (#5805)

* adjusted configurations

* enhancements to tool and configurations

* change reference in docs

* fixed issue in workflows reference

* added project name

* more optimizations

* fix context error

* added a types reference

* resolved missing types

* fix reference reflection types not having children

* add an expand url parameter

* added new option to the README

* added details about new option
This commit is contained in:
Shahed Nasser authored and GitHub committed 2023-12-05 15:29:41 +02:00
1 parent a418e6cebc
commit 892d737c1f
4358 files changed
+947876 -534760

No files matched your search

@@ -11,6 +11,9 @@ const require = createRequire(import.meta.url)
const referenceNames = process.argv.slice(2) || ["all"]
const basePath = path.join(require.resolve("typedoc-config"), "..")
let generatedCount = 0
let totalCount = 0
let ranMerger = false
if (!referenceNames.length) {
console.error(
@@ -27,15 +30,19 @@ referenceNames.forEach((name) => {
// `typedoc-config` directory, except for files starting
// with `_`
const files = globSync("[^_]**.js", {
cwd: path.join(basePath),
cwd: basePath,
})
totalCount = files.length
files.forEach((file) => generateReference(file))
} else if (name === "merge") {
runMerger()
} else {
totalCount = 1
generateReference(`${name}.js`)
}
})
function generateReference(referenceName: string) {
export function generateReference(referenceName: string) {
const configPathName = path.join(basePath, referenceName)
// check if the config file exists
@@ -54,6 +61,12 @@ function generateReference(referenceName: string) {
typedocProcess.stdout?.on("data", (chunk: string) => {
formatColoredLog(colorLog, referenceName, chunk.trim())
})
typedocProcess.on("exit", (code) => {
generatedCount++
if (generatedCount >= totalCount && !ranMerger && code !== 1) {
runMerger()
}
})
typedocProcess.stderr?.on("data", (chunk: string) => {
// split multiline outputs
const split: string[] = chunk.split("\n")
@@ -79,3 +92,10 @@ function formatColoredLog(
) {
console.log(`${chalkInstance(title)} -> ${message}`)
}
function runMerger() {
// run merger
console.log(chalk.bgBlueBright("\n\nRunning Merger\n\n"))
ranMerger = true
generateReference("_merger.js")
}
+1
View File
@@ -8,6 +8,7 @@
"scripts": {
"generate:announcement": "ts-node ./doc-change-release.ts",
"generate:reference": "ts-node ./generate-reference.ts",
"merge:references": "yarn generate:reference merge",
"check:freshness": "ts-node ./freshness-check.ts",
"generate:message": "ts-node ./get-generate-diff-message.ts"
},
+2
View File
@@ -8,5 +8,7 @@
"include": ["*.ts"],
"ts-node": {
"esm": true,
"experimentalSpecifierResolution": "node",
"transpileOnly": true
},
}
+9 -2
View File
@@ -5,8 +5,7 @@ const pathPrefix = path.join(__dirname, "..", "..", "..")
/** @type {import('typedoc').TypeDocOptions} */
module.exports = {
// extends: [typedocConfig],
plugin: ["typedoc-plugin-markdown-medusa", "typedoc-plugin-custom"],
plugin: ["typedoc-plugin-custom"],
readme: "none",
eslintPathName: path.join(
pathPrefix,
@@ -15,6 +14,14 @@ module.exports = {
pluginsResolvePath: path.join(pathPrefix, "www"),
exclude: [path.join(pathPrefix, "node_modules/**")],
excludeInternal: true,
excludeExternals: true,
excludeReferences: true,
disableSources: true,
validation: {
notExported: false,
// invalidLink: false,
},
// logLevel: "Error",
// Uncomment this when debugging
// showConfig: true,
}
@@ -0,0 +1,412 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path")
const globalTypedocOptions = require("./_base")
const baseSectionsOptions = {
member_sources_definedIn: false,
reflection_hierarchy: false,
member_sources_inheritedFrom: false,
member_sources_implementationOf: false,
reflection_implementedBy: false,
member_signature_sources: false,
reflection_callable: false,
reflection_indexable: false,
reflection_implements: false,
member_signature_title: false,
member_signature_returns: false,
title_reflectionPath: false,
}
const modulesSectionsOptions = {
...baseSectionsOptions,
member_signature_typeParameters: false,
member_declaration_typeParameters: false,
}
const modulesOptions = {
sections: modulesSectionsOptions,
expandMembers: true,
}
/** @type {import('typedoc').TypeDocOptions} */
module.exports = {
...globalTypedocOptions,
entryPoints: [
path.join(__dirname, "..", "..", "typedoc-json-output", "*.json"),
],
entryPointStrategy: "merge",
entryDocument: "_index.mdx",
out: path.join(
__dirname,
"..",
"..",
"..",
"www",
"apps",
"docs",
"content",
"references"
),
name: "references",
indexTitle: "Medusa References",
plugin: [...globalTypedocOptions.plugin, "typedoc-plugin-markdown-medusa"],
excludeReferences: true,
excludeNotDocumented: true,
hideInPageTOC: true,
hideBreadcrumbs: true,
objectLiteralTypeDeclarationStyle: "component",
mdxOutput: true,
maxLevel: 3,
allReflectionsHaveOwnDocument: [
"inventory",
"pricing",
"product",
"stock-location",
"workflows",
],
formatting: {
"*": {
showCommentsAsHeader: true,
sections: baseSectionsOptions,
parameterStyle: "component",
parameterComponent: "ParameterTypes",
mdxImports: [
`import ParameterTypes from "@site/src/components/ParameterTypes"`,
],
},
internal: {
maxLevel: 1,
},
// ENTITIES CONFIG
"^entities": {
reflectionGroups: {
Constructors: false,
Methods: false,
},
frontmatterData: {
displayed_sidebar: "entitiesSidebar",
},
maxLevel: 2,
parameterComponentExtraProps: {
expandUrl:
"https://docs.medusajs.com/development/entities/repositories#retrieving-a-list-of-records",
},
},
"^entities/classes": {
frontmatterData: {
displayed_sidebar: "entitiesSidebar",
slug: "/references/entities/classes/{{alias}}",
},
},
"^entities/.*(Order|Swap|Cart|LineItem)": {
maxLevel: 1,
},
// FULFILLMENT CONFIG
"^fulfillment": {
reflectionGroups: {
Properties: false,
},
frontmatterData: {
displayed_sidebar: "modules",
},
maxLevel: 2,
},
"^fulfillment/.*AbstractFulfillmentService": {
reflectionDescription: `In this document, you’ll learn how to create a fulfillment provider to a Medusa backend and the methods you must implement in it. If you’re unfamiliar with the Shipping architecture in Medusa, make sure to [check out the overview first](https://docs.medusajs.com/modules/carts-and-checkout/shipping).`,
frontmatterData: {
displayed_sidebar: "modules",
slug: "/modules/carts-and-checkout/backend/add-fulfillment-provider",
},
reflectionTitle: {
fullReplacement: "How to Create a Fulfillment Provider",
},
},
// INVENTORY CONFIG
"^inventory": {
...modulesOptions,
frontmatterData: {
displayed_sidebar: "inventoryReference",
},
},
"^IInventoryService/methods": {
reflectionDescription:
"This documentation provides a reference to the `{{alias}}` {{kind}}. This belongs to the Inventory Module.",
frontmatterData: {
displayed_sidebar: "inventoryReference",
slug: "/references/inventory/{{alias}}",
sidebar_label: "{{alias}}",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: "- Inventory Module Reference",
},
},
"^inventory/.*IInventoryService\\.md": {
reflectionDescription:
"This section of the documentation provides a reference to the `IInventoryService` interface’s methods. This is the interface developers use to use the functionalities provided by the Inventory Module.",
frontmatterData: {
displayed_sidebar: "inventoryReference",
slug: "/references/inventory",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: " Reference",
},
},
// JS CLIENT CONFIG
"^js_client": {
sections: {
...baseSectionsOptions,
member_declaration_title: false,
},
reflectionGroups: {
Constructors: false,
},
frontmatterData: {
displayed_sidebar: "jsClientSidebar",
},
parameterComponentExtraProps: {
expandUrl:
"https://docs.medusajs.com/js-client/overview#expanding-fields",
},
maxLevel: 4,
},
"^js_client/classes/": {
frontmatterData: {
displayed_sidebar: "jsClientSidebar",
slug: "/references/js-client/{{alias}}",
},
},
"^js_client/.*AdminOrdersResource": {
maxLevel: 2,
},
"^js_client/.*LineItemsResource": {
maxLevel: 3,
},
"^(js_client/.*modules/.*internal|internal.*/modules)": {
reflectionGroups: {
Constructors: false,
"Type Aliases": false,
Enumerations: false,
"Enumeration Members": false,
Classes: false,
Functions: false,
Interfaces: false,
References: false,
},
},
"^internal.*/.*js_client.*": {
reflectionGroups: {
Constructors: false,
},
frontmatterData: {
displayed_sidebar: "jsClientSidebar",
},
},
// MEDUSA CONFIG
"^medusa": {
frontmatterData: {
displayed_sidebar: "homepage",
},
maxLevel: 2,
parameterComponentExtraProps: {
expandUrl:
"https://docs.medusajs.com/development/entities/repositories#retrieving-a-list-of-records",
},
},
// PRICING CONFIG
"^pricing": {
...modulesOptions,
frontmatterData: {
displayed_sidebar: "pricingReference",
},
},
"^IPricingModuleService/methods": {
reflectionDescription:
"This documentation provides a reference to the `{{alias}}` {{kind}}. This belongs to the Pricing Module.",
frontmatterData: {
displayed_sidebar: "pricingReference",
badge: {
variant: "orange",
text: "Beta",
},
slug: "/references/pricing/{{alias}}",
sidebar_label: "{{alias}}",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: "- Pricing Module Reference",
},
},
"^pricing/.*IPricingModuleService\\.md": {
reflectionDescription:
"This section of the documentation provides a reference to the `IPricingModuleService` interface’s methods. This is the interface developers use to use the functionalities provided by the Pricing Module.",
frontmatterData: {
displayed_sidebar: "pricingReference",
badge: {
variant: "orange",
text: "Beta",
},
slug: "/references/pricing",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: " Reference",
},
},
// PRODUCT CONFIG
"^product": {
...modulesOptions,
frontmatterData: {
displayed_sidebar: "productReference",
},
},
"^IProductModuleService/methods": {
reflectionDescription:
"This documentation provides a reference to the {{alias}} {{kind}}. This belongs to the Product Module.",
frontmatterData: {
displayed_sidebar: "productReference",
badge: {
variant: "orange",
text: "Beta",
},
slug: "/references/product/{{alias}}",
sidebar_label: "{{alias}}",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: "- Product Module Reference",
},
},
"^product/.*IProductModuleService\\.md": {
reflectionDescription:
"This section of the documentation provides a reference to the `IProductModuleService` interface’s methods. This is the interface developers use to use the functionalities provided by the Product Module.",
frontmatterData: {
displayed_sidebar: "productReference",
badge: {
variant: "orange",
text: "Beta",
},
slug: "/references/product",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: " Reference",
},
},
// SERVICES CONFIG
"^services": {
frontmatterData: {
displayed_sidebar: "servicesSidebar",
},
maxLevel: 1,
},
// STOCK LOCATION CONFIG
"^stock-location": {
...modulesOptions,
frontmatterData: {
displayed_sidebar: "stockLocationReference",
},
},
"^IStockLocationService/methods": {
reflectionDescription:
"This documentation provides a reference to the `{{alias}}` {{kind}}. This belongs to the Stock Location Module.",
frontmatterData: {
displayed_sidebar: "stockLocationReference",
slug: "/references/stock-location/{{alias}}",
sidebar_label: "{{alias}}",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: "- Stock Location Module Reference",
},
},
"^stock-location/.*IStockLocationService\\.md": {
reflectionDescription:
"This section of the documentation provides a reference to the `IStockLocationService` interface’s methods. This is the interface developers use to use the functionalities provided by the Stock Location Module.",
frontmatterData: {
displayed_sidebar: "stockLocationReference",
slug: "/references/stock-location",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: " Reference",
},
},
// WORKFLOWS CONFIG
"^workflows": {
expandMembers: true,
sections: {
...baseSectionsOptions,
member_getterSetter: false,
},
frontmatterData: {
displayed_sidebar: "workflowsSidebar",
},
maxLevel: 2,
},
"^modules/workflows\\.md": {
reflectionDescription:
"This section of the documentation provides a reference to the utility functions of the `@medusajs/workflows-sdk` package.",
reflectionGroups: {
Namespaces: false,
Enumerations: false,
Classes: false,
Interfaces: false,
"Type Aliases": false,
Variables: false,
"Enumeration Members": false,
},
frontmatterData: {
displayed_sidebar: "workflowsSidebar",
slug: "/references/workflows",
},
reflectionTitle: {
fullReplacement: "Workflows API Reference",
},
},
"^workflows/functions": {
maxLevel: 1,
reflectionDescription:
"This documentation provides a reference to the `{{alias}}` {{kind}}. It belongs to the `@medusajs/workflows-sdk` package.",
frontmatterData: {
displayed_sidebar: "workflowsSidebar",
slug: "/references/workflows/{{alias}}",
sidebar_label: "{{alias}}",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: "- Workflows API Reference",
},
},
"^workflows/.*classes/.*StepResponse": {
reflectionGroups: {
Properties: false,
},
},
"^workflows/.*transform": {
reflectionGroups: {
"Type Parameters": false,
},
},
},
}
+7 -83
View File
@@ -1,89 +1,13 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path")
const globalTypedocOptions = require("./_base")
const getConfig = require("./utils/get-config")
const pathPrefix = path.join(__dirname, "..", "..", "..")
module.exports = ({
entryPointPath,
outPath,
tsconfigPath = "",
moduleName = "",
documentsToFormat = [],
extraOptions = {},
}) => {
const formatting = {}
documentsToFormat.forEach(
({ pattern, additionalFormatting, useDefaults = false }) => {
formatting[pattern] = {
...(!useDefaults
? {
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: "Reference",
},
expandMembers: true,
showCommentsAsHeader: true,
parameterStyle: "component",
useTsLinkResolution: false,
sections: {
reflection_typeParameters: false,
member_declaration_typeParameters: false,
reflection_implements: false,
reflection_implementedBy: false,
reflection_callable: false,
reflection_indexable: false,
member_signature_typeParameters: false,
member_signature_sources: false,
member_signature_title: false,
title_reflectionPath: false,
member_sources_definedIn: false,
member_signature_returns: false,
},
reflectionGroups: {
Constructors: false,
Properties: false,
},
parameterComponent: "ParameterTypes",
mdxImports: [
`import ParameterTypes from "@site/src/components/ParameterTypes"`,
],
}
: {
showCommentsAsHeader: true,
sections: {
member_sources_definedIn: false,
reflection_hierarchy: false,
},
parameterStyle: "component",
parameterComponent: "ParameterTypes",
mdxImports: [
`import ParameterTypes from "@site/src/components/ParameterTypes"`,
],
}),
...additionalFormatting,
}
}
)
return {
...globalTypedocOptions,
entryPoints: [path.join(pathPrefix, entryPointPath)],
out: [path.join(pathPrefix, outPath)],
tsconfig: tsconfigPath.length
? path.join(pathPrefix, tsconfigPath)
: path.join(__dirname, "extended-tsconfig", "types.json"),
name: `${moduleName} Reference`,
indexTitle: `${moduleName} Reference`,
entryDocument: "index.md",
module.exports = (options) => {
return getConfig({
...options,
tsConfigName: "types.json",
entryPointStrategy: "expand",
hideInPageTOC: true,
hideBreadcrumbs: true,
plugin: [...globalTypedocOptions.plugin, "typedoc-plugin-rename-defaults"],
formatting,
allReflectionsHaveOwnDocument: true,
objectLiteralTypeDeclarationStyle: "component",
mdxOutput: true,
...extraOptions,
}
enableInternalResolve: true,
})
}
+6 -48
View File
@@ -1,50 +1,8 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path")
const globalTypedocOptions = require("./_base")
const getConfig = require("./utils/get-config")
const pathPrefix = path.join(__dirname, "..", "..", "..")
module.exports = {
...globalTypedocOptions,
entryPoints: [path.join(pathPrefix, "packages/medusa/src/models/index.ts")],
out: [path.join(pathPrefix, "www/apps/docs/content/references/entities")],
tsconfig: path.join(__dirname, "extended-tsconfig", "medusa.json"),
name: "Entities Reference",
indexTitle: "Entities Reference",
entryDocument: "index.mdx",
hideInPageTOC: true,
hideBreadcrumbs: true,
formatting: {
"*": {
showCommentsAsHeader: true,
sections: {
member_sources_definedIn: false,
reflection_hierarchy: false,
member_sources_inheritedFrom: false,
member_sources_implementationOf: false,
reflection_implementedBy: false,
member_signature_sources: false,
reflection_callable: false,
reflection_indexable: false,
},
parameterStyle: "component",
parameterComponent: "ParameterTypes",
mdxImports: [
`import ParameterTypes from "@site/src/components/ParameterTypes"`,
],
reflectionGroups: {
Constructors: false,
Methods: false,
},
frontmatterData: {
displayed_sidebar: "entitiesSidebar",
},
},
"(Order|Swap|Cart|LineItem)": {
maxLevel: 1,
},
},
objectLiteralTypeDeclarationStyle: "component",
mdxOutput: true,
maxLevel: 2,
}
module.exports = getConfig({
entryPointPath: "packages/medusa/src/models/index.ts",
tsConfigName: "medusa.json",
name: "entities",
})
@@ -1,64 +1,9 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path")
const globalTypedocOptions = require("./_base")
const getConfig = require("./utils/get-config")
const pathPrefix = path.join(__dirname, "..", "..", "..")
module.exports = {
...globalTypedocOptions,
entryPoints: [
path.join(
pathPrefix,
"packages/medusa/src/interfaces/fulfillment-service.ts"
),
],
out: [path.join(pathPrefix, "www/apps/docs/content/references/fulfillment")],
tsconfig: path.join(__dirname, "extended-tsconfig", "medusa.json"),
name: "Fulfillment Provider Reference",
indexTitle: "Fulfillment Provider Reference",
entryDocument: "_index.mdx",
hideInPageTOC: true,
hideBreadcrumbs: true,
formatting: {
"*": {
showCommentsAsHeader: true,
sections: {
member_sources_definedIn: false,
reflection_hierarchy: false,
member_sources_inheritedFrom: false,
member_sources_implementationOf: false,
reflection_implementedBy: false,
member_signature_sources: false,
reflection_callable: false,
reflection_indexable: false,
reflection_implements: false,
member_signature_title: false,
member_signature_returns: false,
},
parameterStyle: "component",
parameterComponent: "ParameterTypes",
mdxImports: [
`import ParameterTypes from "@site/src/components/ParameterTypes"`,
],
reflectionGroups: {
Properties: false,
},
frontmatterData: {
displayed_sidebar: "modules",
},
},
AbstractFulfillmentService: {
reflectionDescription: `In this document, you’ll learn how to create a fulfillment provider to a Medusa backend and the methods you must implement in it. If you’re unfamiliar with the Shipping architecture in Medusa, make sure to [check out the overview first](https://docs.medusajs.com/modules/carts-and-checkout/shipping).`,
frontmatterData: {
displayed_sidebar: "modules",
slug: "/modules/carts-and-checkout/backend/add-fulfillment-provider",
},
reflectionTitle: {
fullReplacement: "How to Create a Fulfillment Provider",
},
},
},
objectLiteralTypeDeclarationStyle: "component",
mdxOutput: true,
maxLevel: 2,
}
module.exports = getConfig({
entryPointPath: "packages/medusa/src/interfaces/fulfillment-service.ts",
tsConfigName: "medusa.json",
name: "fulfillment",
// enableInternalResolve: true,
})
+1 -41
View File
@@ -3,45 +3,5 @@ const modulesConfig = require("./_modules")
module.exports = modulesConfig({
entryPointPath: "packages/types/src/inventory/service.ts",
outPath: "www/apps/docs/content/references/inventory",
moduleName: "Inventory Module Reference",
documentsToFormat: [
{
pattern: "*",
useDefaults: true,
additionalFormatting: {
frontmatterData: {
displayed_sidebar: "inventoryReference",
},
},
},
{
pattern: "IInventoryService/methods",
additionalFormatting: {
reflectionDescription:
"This documentation provides a reference to the `{{alias}}` {{kind}}. This belongs to the Inventory Module.",
frontmatterData: {
displayed_sidebar: "inventoryReference",
slug: "/references/inventory/{{alias}}",
sidebar_label: "{{alias}}",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: "- Inventory Module Reference",
},
},
},
{
pattern: "IInventoryService.md",
additionalFormatting: {
reflectionDescription:
"This section of the documentation provides a reference to the `IInventoryService` interface’s methods. This is the interface developers use to use the functionalities provided by the Inventory Module.",
frontmatterData: {
displayed_sidebar: "inventoryReference",
slug: "/references/inventory",
},
},
},
],
name: "inventory",
})
+10 -75
View File
@@ -1,87 +1,22 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path")
const globalTypedocOptions = require("./_base")
const getConfig = require("./utils/get-config")
const pathPrefix = path.join(__dirname, "..", "..", "..")
const defaultFormattingOptions = {
showCommentsAsHeader: true,
sections: {
member_sources_definedIn: false,
reflection_hierarchy: false,
member_signature_typeParameters: false,
member_signature_sources: false,
member_signature_title: false,
member_signature_returns: false,
title_reflectionPath: false,
reflection_callable: false,
reflection_indexable: false,
reflection_implementedBy: false,
member_declaration_title: false,
},
parameterStyle: "component",
parameterComponent: "ParameterTypes",
mdxImports: [
`import ParameterTypes from "@site/src/components/ParameterTypes"`,
],
reflectionGroups: {
Constructors: false,
},
frontmatterData: {
displayed_sidebar: "jsClientSidebar",
},
}
const classesFormattingOptions = {
...defaultFormattingOptions,
frontmatterData: {
...defaultFormattingOptions.frontmatterData,
slug: "/references/js-client/{{alias}}",
},
}
/** @type {import('typedoc').TypeDocOptions} */
module.exports = {
...globalTypedocOptions,
entryPoints: [path.join(pathPrefix, "packages/medusa-js/src/resources")],
out: [path.join(pathPrefix, "www/apps/docs/content/references/js-client")],
tsconfig: path.join(__dirname, "extended-tsconfig", "js-client.json"),
name: "JS Client Reference",
indexTitle: "JS Client Reference",
entryDocument: "index.mdx",
hideInPageTOC: true,
hideBreadcrumbs: true,
module.exports = getConfig({
entryPointPath: "packages/medusa-js/src/resources",
tsConfigName: "js-client.json",
name: "js-client",
plugin: [...globalTypedocOptions.plugin, "typedoc-plugin-rename-defaults"],
exclude: [
...globalTypedocOptions.exclude,
path.join(pathPrefix, "packages/medusa-js/src/resources/base.ts"),
],
internalModule: "internal",
formatting: {
"*": defaultFormattingOptions,
"^classes/": classesFormattingOptions,
AdminOrdersResource: {
maxLevel: 2,
},
internal: {
maxLevel: 1,
},
"internal/modules/internal": {
reflectionGroups: {
...defaultFormattingOptions.reflectionGroups,
"Type Aliases": false,
Enumerations: false,
Classes: false,
Functions: false,
Interfaces: false,
},
},
},
objectLiteralTypeDeclarationStyle: "component",
mdxOutput: true,
maxLevel: 4,
// internalModule: "internal",
ignoreApi: true,
outputModules: false,
outputNamespace: false,
excludeReferences: true,
}
// outputModules: false,
// outputNamespace: false,
// excludeReferences: true,
})
@@ -0,0 +1,11 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const getConfig = require("./utils/get-config")
module.exports = getConfig({
entryPointPath: "packages/medusa/src/index.js",
tsConfigName: "medusa.json",
name: "medusa",
jsonFileName: "0-medusa",
enableInternalResolve: true,
exclude: ["**/models/**.ts", "**/services/**.ts"],
})
@@ -9,5 +9,8 @@
"typedoc": "0.25.x"
},
"main": "_base.js",
"version": "0.0.0"
"version": "0.0.0",
"dependencies": {
"glob": "^10.3.10"
}
}
+1 -49
View File
@@ -3,53 +3,5 @@ const modulesConfig = require("./_modules")
module.exports = modulesConfig({
entryPointPath: "packages/types/src/pricing/service.ts",
outPath: "www/apps/docs/content/references/pricing",
moduleName: "Pricing Module Reference",
documentsToFormat: [
{
pattern: "*",
useDefaults: true,
additionalFormatting: {
frontmatterData: {
displayed_sidebar: "pricingReference",
},
},
},
{
pattern: "IPricingModuleService/methods",
additionalFormatting: {
reflectionDescription:
"This documentation provides a reference to the `{{alias}}` {{kind}}. This belongs to the Pricing Module.",
frontmatterData: {
displayed_sidebar: "pricingReference",
badge: {
variant: "orange",
text: "Beta",
},
slug: "/references/pricing/{{alias}}",
sidebar_label: "{{alias}}",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: "- Pricing Module Reference",
},
},
},
{
pattern: "IPricingModuleService.md",
additionalFormatting: {
reflectionDescription:
"This section of the documentation provides a reference to the `IPricingModuleService` interface’s methods. This is the interface developers use to use the functionalities provided by the Pricing Module.",
frontmatterData: {
displayed_sidebar: "pricingReference",
badge: {
variant: "orange",
text: "Beta",
},
slug: "/references/pricing",
},
},
},
],
name: "pricing",
})
+1 -49
View File
@@ -3,53 +3,5 @@ const modulesConfig = require("./_modules")
module.exports = modulesConfig({
entryPointPath: "packages/types/src/product/service.ts",
outPath: "www/apps/docs/content/references/product",
moduleName: "Product Module Reference",
documentsToFormat: [
{
pattern: "*",
useDefaults: true,
additionalFormatting: {
frontmatterData: {
displayed_sidebar: "productReference",
},
},
},
{
pattern: "IProductModuleService/methods",
additionalFormatting: {
reflectionDescription:
"This documentation provides a reference to the {{alias}} {{kind}}. This belongs to the Product Module.",
frontmatterData: {
displayed_sidebar: "productReference",
badge: {
variant: "orange",
text: "Beta",
},
slug: "/references/product/{{alias}}",
sidebar_label: "{{alias}}",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: "- Product Module Reference",
},
},
},
{
pattern: "IProductModuleService.md",
additionalFormatting: {
reflectionDescription:
"This section of the documentation provides a reference to the `IProductModuleService` interface’s methods. This is the interface developers use to use the functionalities provided by the Product Module.",
frontmatterData: {
displayed_sidebar: "productReference",
badge: {
variant: "orange",
text: "Beta",
},
slug: "/references/product",
},
},
},
],
name: "product",
})
+6 -41
View File
@@ -1,43 +1,8 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path")
const globalTypedocOptions = require("./_base")
const getConfig = require("./utils/get-config")
const pathPrefix = path.join(__dirname, "..", "..", "..")
module.exports = {
...globalTypedocOptions,
entryPoints: [path.join(pathPrefix, "packages/medusa/src/services/index.ts")],
out: [path.join(pathPrefix, "www/apps/docs/content/references/services")],
tsconfig: path.join(__dirname, "extended-tsconfig", "medusa.json"),
name: "Services Reference",
indexTitle: "Services Reference",
entryDocument: "index.md",
hideInPageTOC: true,
hideBreadcrumbs: true,
formatting: {
"*": {
showCommentsAsHeader: true,
sections: {
member_sources_definedIn: false,
reflection_hierarchy: false,
member_sources_inheritedFrom: false,
member_sources_implementationOf: false,
reflection_implementedBy: false,
member_signature_sources: false,
reflection_callable: false,
reflection_indexable: false,
},
parameterStyle: "component",
parameterComponent: "ParameterTypes",
mdxImports: [
`import ParameterTypes from "@site/src/components/ParameterTypes"`,
],
frontmatterData: {
displayed_sidebar: "servicesSidebar",
},
},
},
objectLiteralTypeDeclarationStyle: "component",
mdxOutput: true,
maxLevel: 1,
}
module.exports = getConfig({
entryPointPath: "packages/medusa/src/services/index.ts",
tsConfigName: "medusa.json",
name: "services",
})
@@ -3,45 +3,5 @@ const modulesConfig = require("./_modules")
module.exports = modulesConfig({
entryPointPath: "packages/types/src/stock-location/service.ts",
outPath: "www/apps/docs/content/references/stock-location",
moduleName: "Stock Location Module Reference",
documentsToFormat: [
{
pattern: "*",
useDefaults: true,
additionalFormatting: {
frontmatterData: {
displayed_sidebar: "stockLocationReference",
},
},
},
{
pattern: "IStockLocationService/methods",
additionalFormatting: {
reflectionDescription:
"This documentation provides a reference to the `{{alias}}` {{kind}}. This belongs to the Stock Location Module.",
frontmatterData: {
displayed_sidebar: "stockLocationReference",
slug: "/references/stock-location/{{alias}}",
sidebar_label: "{{alias}}",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: "- Stock Location Module Reference",
},
},
},
{
pattern: "IStockLocationService.md",
additionalFormatting: {
reflectionDescription:
"This section of the documentation provides a reference to the `IStockLocationService` interface’s methods. This is the interface developers use to use the functionalities provided by the Stock Location Module.",
frontmatterData: {
displayed_sidebar: "stockLocationReference",
slug: "/references/stock-location",
},
},
},
],
name: "stock-location",
})
@@ -1,4 +1,4 @@
{
"extends": "../../tsconfig",
"include": ["*.js"]
"include": ["**/*.js"]
}
@@ -0,0 +1,16 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const getConfig = require("./utils/get-config")
module.exports = getConfig({
entryPointPath: "packages/types/src/index.ts",
tsConfigName: "types.json",
name: "types",
jsonFileName: "0-types",
enableInternalResolve: true,
exclude: [
"**/pricing/**.ts",
"**/product/**.ts",
"**/inventory/**.ts",
"**/stock-location/**.ts",
],
})
@@ -0,0 +1,44 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path")
const globalTypedocOptions = require("../_base")
function getEntryPoints(entryPointPaths) {
if (Array.isArray(entryPointPaths)) {
return entryPointPaths.map((entryPath) =>
path.join(__dirname, "..", "..", "..", "..", entryPath)
)
} else {
return path.join(__dirname, "..", "..", "..", "..", entryPointPaths)
}
}
/**
*
* @param {Record<string, any>} param0 - The configuration options
* @returns {import('typedoc').TypeDocOptions}
*/
function getConfig({
entryPointPath,
tsConfigName,
name,
jsonFileName,
...otherOptions
}) {
return {
...globalTypedocOptions,
entryPoints: getEntryPoints(entryPointPath),
tsconfig: path.join(__dirname, "..", "extended-tsconfig", tsConfigName),
name,
json: path.join(
__dirname,
"..",
"..",
"..",
"typedoc-json-output",
`${jsonFileName || name}.json`
),
...otherOptions,
}
}
module.exports = getConfig
+8 -87
View File
@@ -1,89 +1,10 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path")
const globalTypedocOptions = require("./_base")
const getConfig = require("./utils/get-config")
const pathPrefix = path.join(__dirname, "..", "..", "..")
module.exports = {
...globalTypedocOptions,
entryPoints: [
path.join(pathPrefix, "packages/workflows-sdk/src/utils/composer/index.ts"),
],
out: [path.join(pathPrefix, "www/apps/docs/content/references/workflows")],
tsconfig: path.join(__dirname, "extended-tsconfig", "workflows.json"),
name: "Workflows API Reference",
indexTitle: "Workflows API Reference",
entryDocument: "index.mdx",
hideInPageTOC: true,
hideBreadcrumbs: true,
formatting: {
"*": {
expandMembers: true,
showCommentsAsHeader: true,
sections: {
member_sources_definedIn: false,
reflection_hierarchy: false,
member_sources_inheritedFrom: false,
member_sources_implementationOf: false,
reflection_implementedBy: false,
member_signature_sources: false,
reflection_callable: false,
reflection_indexable: false,
member_signature_title: false,
member_signature_returns: false,
member_getterSetter: false,
},
parameterStyle: "component",
parameterComponent: "ParameterTypes",
mdxImports: [
`import ParameterTypes from "@site/src/components/ParameterTypes"`,
],
frontmatterData: {
displayed_sidebar: "workflowsSidebar",
},
},
"index\\.mdx": {
reflectionDescription:
"This section of the documentation provides a reference to the utility functions of the `@medusajs/workflows-sdk` package.",
reflectionGroups: {
Namespaces: false,
Enumerations: false,
Classes: false,
Interfaces: false,
"Type Aliases": false,
Variables: false,
"Enumeration Members": false,
},
},
functions: {
maxLevel: 1,
reflectionDescription:
"This documentation provides a reference to the `{{alias}}` {{kind}}. It belongs to the `@medusajs/workflows-sdk` package.",
frontmatterData: {
displayed_sidebar: "workflowsSidebar",
slug: "/references/workflows/{{alias}}",
sidebar_label: "{{alias}}",
},
reflectionTitle: {
kind: false,
typeParameters: false,
suffix: "- Workflows Reference",
},
},
"classes/StepResponse": {
reflectionGroups: {
Properties: false,
},
},
transform: {
reflectionGroups: {
"Type Parameters": false,
},
},
},
objectLiteralTypeDeclarationStyle: "component",
mdxOutput: true,
maxLevel: 2,
allReflectionsHaveOwnDocument: true,
excludeExternals: true,
}
module.exports = getConfig({
entryPointPath: "packages/workflows-sdk/src/utils/composer/index.ts",
// entryPointStrategy: "expand",
tsConfigName: "workflows.json",
name: "workflows",
// enableInternalResolve: true,
})
@@ -8,6 +8,8 @@ A Typedoc plugin that combines utility plugins for documenting references.
The [`resolve-reference-plugin`](./src/resolve-references-plugin.ts) imitates the [`typedoc-plugin-missing-exports`](https://www.npmjs.com/package/typedoc-plugin-missing-exports) plugin. So, it accepts the same options as the [`typedoc-plugin-missing-exports`](https://www.npmjs.com/package/typedoc-plugin-missing-exports) plugin.
This plugin only runs if the `enableInternalResolve` option is enabled.
### Frontmatter
`frontmatterData` is an object of key-value pairs. If none provided, no frontmatter variables will be added to the Markdown files.
@@ -9,6 +9,7 @@ import {
Reflection,
DeclarationReflection,
ProjectReflection,
ParameterType,
} from "typedoc"
declare module "typedoc" {
@@ -27,6 +28,18 @@ export function load(app: Application) {
}
hasMonkeyPatched = true
app.options.addDeclaration({
name: "internalModule",
help: "Define the name of the module that internal symbols which are not exported should be placed into.",
})
app.options.addDeclaration({
name: "enableInternalResolve",
help: "Whether to run this plugin or not.",
type: ParameterType.Boolean,
defaultValue: false,
})
let activeReflection: Reflection | undefined
const referencedSymbols = new Map<ts.Program, Set<ts.Symbol>>()
const symbolToActiveRefl = new Map<ts.Symbol, Reflection>()
@@ -58,6 +71,9 @@ export function load(app: Application) {
// Monkey patch the constructor for references so that we can get every
const origCreateSymbolReference = ReferenceType.createSymbolReference
ReferenceType.createSymbolReference = function (symbol, context, name) {
if (!app.options.getValue("enableInternalResolve")) {
return origCreateSymbolReference.call(this, symbol, context, name)
}
ok(activeReflection, "active reflection has not been set")
const set = referencedSymbols.get(context.program)
symbolToActiveRefl.set(symbol, activeReflection)
@@ -69,14 +85,12 @@ export function load(app: Application) {
return origCreateSymbolReference.call(this, symbol, context, name)
}
app.options.addDeclaration({
name: "internalModule",
help: "Define the name of the module that internal symbols which are not exported should be placed into.",
})
app.converter.on(
Converter.EVENT_CREATE_DECLARATION,
(context: Context, refl: Reflection) => {
if (!app.options.getValue("enableInternalResolve")) {
return
}
if (refl.kindOf(ReflectionKind.Project | ReflectionKind.Module)) {
knownPrograms.set(refl, context.program)
activeReflection = refl
@@ -87,6 +101,9 @@ export function load(app: Application) {
app.converter.on(
Converter.EVENT_RESOLVE_BEGIN,
function onResolveBegin(context: Context) {
if (!app.options.getValue("enableInternalResolve")) {
return
}
const modules: (DeclarationReflection | ProjectReflection)[] =
context.project.getChildrenByKind(ReflectionKind.Module)
if (modules.length === 0) {
@@ -21,7 +21,9 @@ Aside from the options detailed in [typedoc-plugin-markdown](https://github.com/
- `parameterStyle`: (optional) a string indicating how parameters are displayed. Its value can be `table` (default), `list`, or `component`.
- `showReturnSignature`: (optional) a boolean indicating whether to show the signature for returned values.
- `frontmatterData`: (optional) an object that will be injected as frontmatter to the pages matching specified pattern.
- `parameterComponent`: (optional) a string indicating the name of a React component to pass the parameters as an object to. This is only used if the `parameterStyle` option is set to `component`. This also must be used with the `mdxOutput` option enabled, and an import string for the component passed to the `mdxImports` option. The React component will receive a `parameters` prop, which is an array of type [Parameter](./src/types.ts#L95).
- `parameterComponent`: (optional) a string indicating the name of a React component to pass the parameters as an object to. This is only used if the
- `parameterComponentExtraProps`: (optional) an object that specifies props to pass to the `parameterComponent`.
- `parameterStyle` option is set to `component`. This also must be used with the `mdxOutput` option enabled, and an import string for the component passed to the `mdxImports` option. The React component will receive a `parameters` prop, which is an array of type [Parameter](./src/types.ts#L95).
- `mdxImports`: (optional) an array of strings, each holding an import statement that will be added to the beginning of each page. For example, `["import ParameterTypes from "@site/src/components/ParameterTypes""]`. Must be used along with the `mdxOutput` option enabled.
- `maxLevel`: (optional) a number indicating the maximum level parameters and return types are expanded. Default is `3`.
@@ -34,10 +34,10 @@ export function load(app: Application) {
})
app.options.addDeclaration({
help: "[Markdown Plugin] Output all reflections into seperate output files.",
help: "[Markdown Plugin] Specify module names where all reflections are outputted into seperate files.",
name: "allReflectionsHaveOwnDocument",
type: ParameterType.Boolean,
defaultValue: false,
type: ParameterType.Array,
defaultValue: [],
})
app.options.addDeclaration({
@@ -8,18 +8,32 @@ export default function (theme: MarkdownTheme) {
Handlebars.registerHelper(
"parameterComponent",
function (this: ReflectionParameterType[]) {
const { parameterComponent, maxLevel } =
const { parameterComponent, maxLevel, parameterComponentExtraProps } =
theme.getFormattingOptionsForLocation()
const parameters = this.reduce(
(acc: ReflectionParameterType[], current) => parseParams(current, acc),
[]
).map((parameter) => reflectionComponentFormatter(parameter, 1, maxLevel))
).map((parameter) =>
reflectionComponentFormatter({
reflection: parameter,
level: 1,
maxLevel,
})
)
let extraProps: string[] = []
if (parameterComponentExtraProps) {
extraProps = Object.entries(parameterComponentExtraProps).map(
([key, value]) => `${key}=${JSON.stringify(value)}`
)
}
return `<${parameterComponent} parameters={${JSON.stringify(
parameters,
null,
2
)}} />`
)}} ${extraProps.join(" ")}/>`
}
)
}
@@ -21,7 +21,10 @@ export default function () {
function list(parameters: ReflectionParameterType[]) {
const items = parameters.map((parameter) => {
return reflectionFormatter(parameter, "list")
return reflectionFormatter({
reflection: parameter,
type: "list",
})
})
return items.join("\n")
@@ -20,7 +20,9 @@ export default function () {
const headers = getTableHeaders(parameters)
const rows = parameters.map((parameter) =>
reflectionTableFormatter(parameter)
reflectionTableFormatter({
reflection: parameter,
})
)
return `\n| ${headers.join(" | ")} |\n| ${headers
@@ -88,7 +88,12 @@ function getReturnFromComment(theme: MarkdownTheme, comment: Comment) {
commentPart.target instanceof DeclarationReflection
) {
const content = commentPart.target.children?.map((childItem) =>
reflectionFormatter(childItem, parameterStyle, 1, maxLevel)
reflectionFormatter({
reflection: childItem,
type: parameterStyle,
level: 1,
maxLevel,
})
)
result +=
parameterStyle === "component"
@@ -6,13 +6,6 @@ export default function (theme: MarkdownTheme) {
Handlebars.registerHelper("titleLevel", function (this: Reflection): string {
const { currentTitleLevel } = theme
// let titleLevel = currentTitleLevel
// if (isChild) {
// titleLevel++
// theme.setCurrentTitleLevel(titleLevel + 1)
// }
return Array(currentTitleLevel).fill("#").join("")
})
}
@@ -49,7 +49,10 @@ export default function (theme: MarkdownTheme) {
function getListMarkdownContent(properties: DeclarationReflection[]) {
const items = properties.map((property) =>
reflectionFormatter(property, "list")
reflectionFormatter({
reflection: property,
type: "list",
})
)
return items.join("\n")
@@ -61,7 +64,12 @@ function getComponentMarkdownContent(
maxLevel?: number | undefined
) {
const parameters = properties.map((property) =>
reflectionFormatter(property, "component", 1, maxLevel)
reflectionFormatter({
reflection: property,
type: "component",
level: 1,
maxLevel,
})
)
return `<${parameterComponent} parameters={${JSON.stringify(
@@ -10,7 +10,11 @@ export default function (theme: MarkdownTheme) {
const { parameterComponent, maxLevel } =
theme.getFormattingOptionsForLocation()
const parameters = this.map((parameter) =>
reflectionComponentFormatter(parameter, 1, maxLevel)
reflectionComponentFormatter({
reflection: parameter,
level: 1,
maxLevel,
})
)
return `<${parameterComponent} parameters={${JSON.stringify(
@@ -13,7 +13,10 @@ export default function () {
function list(parameters: TypeParameterReflection[]) {
const items = parameters.map((parameter) =>
reflectionFormatter(parameter, "list")
reflectionFormatter({
reflection: parameter,
type: "list",
})
)
return items.join("\n")
@@ -13,7 +13,11 @@ export default function () {
const showTypeCol = hasTypes(this)
const headers = getTableHeaders(this, showTypeCol)
const rows = this.map((parameter) => reflectionTableFormatter(parameter))
const rows = this.map((parameter) =>
reflectionTableFormatter({
reflection: parameter,
})
)
return `\n| ${headers.join(" | ")} |\n| ${headers
.map(() => ":------")
@@ -39,7 +39,11 @@ export default function () {
collapse: Collapse = "none",
emphasis = true
) {
return getType(this, collapse, emphasis)
return getType({
reflectionType: this,
collapse,
wrapBackticks: emphasis,
})
}
)
}
@@ -28,7 +28,7 @@ import {
} from "./types"
export class MarkdownTheme extends Theme {
allReflectionsHaveOwnDocument!: boolean
allReflectionsHaveOwnDocument!: string[]
entryDocument: string
entryPoints!: string[]
filenameSeparator!: string
@@ -64,7 +64,7 @@ export class MarkdownTheme extends Theme {
super(renderer)
// prettier-ignore
this.allReflectionsHaveOwnDocument = this.getOption("allReflectionsHaveOwnDocument") as boolean
this.allReflectionsHaveOwnDocument = this.getOption("allReflectionsHaveOwnDocument") as string[]
this.entryDocument = this.getOption("entryDocument") as string
this.entryPoints = this.getOption("entryPoints") as string[]
this.filenameSeparator = this.getOption("filenameSeparator") as string
@@ -147,6 +147,7 @@ export class MarkdownTheme extends Theme {
urls: UrlMapping[]
): UrlMapping[] {
const mapping = this.getMappings(
reflection,
reflection.parent?.isProject() ? "" : reflection.parent?.getAlias()
).find((mapping) => reflection.kindOf(mapping.kind))
if (mapping) {
@@ -278,7 +279,31 @@ export class MarkdownTheme extends Theme {
}
}
getMappings(directoryPrefix?: string): Mapping[] {
getModuleParents(reflection: DeclarationReflection): DeclarationReflection[] {
const parents: DeclarationReflection[] = []
let currentParent = reflection?.parent as DeclarationReflection | undefined
do {
if (currentParent?.kind === ReflectionKind.Module) {
parents.push(currentParent)
}
currentParent = currentParent?.parent as DeclarationReflection | undefined
} while (currentParent)
return parents
}
getAllReflectionsHaveOwnDocument(reflection: DeclarationReflection): boolean {
const moduleParents = this.getModuleParents(reflection)
return moduleParents.some((parent) =>
this.allReflectionsHaveOwnDocument.includes(parent.name)
)
}
getMappings(
reflection: DeclarationReflection,
directoryPrefix?: string
): Mapping[] {
return [
{
kind: [ReflectionKind.Module],
@@ -316,7 +341,7 @@ export class MarkdownTheme extends Theme {
directory: path.join(directoryPrefix || "", "types"),
template: this.getReflectionMemberTemplate(),
},
...(this.allReflectionsHaveOwnDocument
...(this.getAllReflectionsHaveOwnDocument(reflection)
? [
{
kind: [ReflectionKind.Variable],
@@ -76,6 +76,7 @@ export type FormattingOptionType = {
parameterStyle?: ParameterStyle
frontmatterData?: Record<string, unknown>
parameterComponent?: string
parameterComponentExtraProps?: Record<string, unknown>
mdxImports?: string[]
maxLevel?: number
}
@@ -1,6 +1,7 @@
import {
Comment,
DeclarationReflection,
ProjectReflection,
ReflectionKind,
ReflectionType,
} from "typedoc"
@@ -22,29 +23,35 @@ const ALLOWED_KINDS: ReflectionKind[] = [
ReflectionKind.Reference,
]
export default function reflectionFormatter(
reflection: ReflectionParameterType,
type: ParameterStyle = "table",
level = 1,
type ReflectionFormatterOptions = {
reflection: ReflectionParameterType
level?: number
maxLevel?: number | undefined
): string | Parameter {
project?: ProjectReflection
type?: ParameterStyle
}
export default function reflectionFormatter({
type = "table",
...options
}: ReflectionFormatterOptions): string | Parameter {
switch (type) {
case "list":
return reflectionListFormatter(reflection, level)
return reflectionListFormatter(options)
case "component":
return reflectionComponentFormatter(reflection, level, maxLevel)
return reflectionComponentFormatter(options)
case "table":
return reflectionTableFormatter(reflection)
return reflectionTableFormatter(options)
default:
return ""
}
}
export function reflectionListFormatter(
reflection: ReflectionParameterType,
export function reflectionListFormatter({
reflection,
level = 1,
maxLevel?: number | undefined
): string {
maxLevel,
}: ReflectionFormatterOptions): string {
const prefix = `${Array(level - 1)
.fill("\t")
.join("")}-`
@@ -81,7 +88,13 @@ export function reflectionListFormatter(
if (!itemChildrenKind) {
itemChildrenKind = childItem.kind
}
itemChildren.push(reflectionListFormatter(childItem, level + 1))
itemChildren.push(
reflectionListFormatter({
reflection: childItem,
level: level + 1,
maxLevel,
})
)
})
if (itemChildren.length) {
item += ` ${getItemExpandText(
@@ -94,11 +107,12 @@ export function reflectionListFormatter(
return item
}
export function reflectionComponentFormatter(
reflection: ReflectionParameterType,
export function reflectionComponentFormatter({
reflection,
level = 1,
maxLevel?: number | undefined
): Parameter {
maxLevel,
project,
}: ReflectionFormatterOptions): Parameter {
const defaultValue = getDefaultValue(reflection) || ""
const optional =
reflection.flags.isOptional || reflection.kind === ReflectionKind.EnumMember
@@ -106,8 +120,17 @@ export function reflectionComponentFormatter(
const componentItem: Parameter = {
name: reflection.name,
type: reflection.type
? getType(reflection.type, "object")
: getReflectionType(reflection, "object", true),
? getType({
reflectionType: reflection.type,
collapse: "object",
project: reflection.project,
})
: getReflectionType({
reflectionType: reflection,
collapse: "object",
wrapBackticks: true,
project: reflection.project,
}),
description: comments
? Handlebars.helpers.comments(comments, true, false)
: "",
@@ -124,9 +147,18 @@ export function reflectionComponentFormatter(
(reflection.type || hasChildren) &&
level + 1 <= (maxLevel || MarkdownTheme.MAX_LEVEL)
) {
// if (
// reflection.name === "user" &&
// reflection.type &&
// "name" in reflection.type &&
// reflection.type.name.startsWith("Omit") &&
// "typeArguments" in reflection.type
// ) {
// console.log(reflection)
// }
const children = hasChildren
? reflection.children
: getTypeChildren(reflection.type!, reflection.project)
: getTypeChildren(reflection.type!, project || reflection.project)
children
?.filter((childItem: DeclarationReflection) =>
@@ -134,7 +166,12 @@ export function reflectionComponentFormatter(
)
.forEach((childItem: DeclarationReflection) => {
componentItem.children?.push(
reflectionComponentFormatter(childItem, level + 1, maxLevel)
reflectionComponentFormatter({
reflection: childItem,
level: level + 1,
maxLevel,
project,
})
)
})
}
@@ -142,9 +179,9 @@ export function reflectionComponentFormatter(
return componentItem
}
export function reflectionTableFormatter(
parameter: ReflectionParameterType
): string {
export function reflectionTableFormatter({
reflection: parameter,
}: ReflectionFormatterOptions): string {
const showDefaults = hasDefaultValues([parameter])
const hasComments = !!parameter.comment?.hasVisibleComponent()
@@ -170,7 +207,11 @@ export function reflectionTableFormatter(
row.push(
parameter.type
? Handlebars.helpers.type.call(parameter.type, "object")
: getReflectionType(parameter, "object", true)
: getReflectionType({
reflectionType: parameter,
collapse: "object",
wrapBackticks: true,
})
)
if (showDefaults) {
@@ -14,6 +14,7 @@ import {
reflectionComponentFormatter,
} from "./reflection-formatter"
import { MarkdownTheme } from "../theme"
import { getProjectChild, getTypeChildren } from "utils"
type ReturnReflectionComponentFormatterParams = {
reflectionType: SomeType
@@ -30,8 +31,18 @@ export function returnReflectionComponentFormatter({
level = 1,
maxLevel,
}: ReturnReflectionComponentFormatterParams): Parameter[] {
const typeName = getType(reflectionType, "object", false, true)
const type = getType(reflectionType, "object")
const typeName = getType({
reflectionType,
collapse: "object",
wrapBackticks: false,
hideLink: true,
project,
})
const type = getType({
reflectionType: reflectionType,
collapse: "object",
project,
})
const componentItem: Parameter[] = []
const canRetrieveChildren = level + 1 <= (maxLevel || MarkdownTheme.MAX_LEVEL)
if (reflectionType.type === "reference") {
@@ -57,8 +68,8 @@ export function returnReflectionComponentFormatter({
const typeArgs = reflectionType.typeArguments
? reflectionType.typeArguments
: "typeParameters" in reflectionType
? (reflectionType.typeParameters as TypeParameterReflection[])
: undefined
? (reflectionType.typeParameters as TypeParameterReflection[])
: undefined
if (
typeArgs &&
!isOnlyVoid(typeArgs as unknown as SomeType[]) &&
@@ -82,27 +93,52 @@ export function returnReflectionComponentFormatter({
}
} else {
const reflection = (reflectionType.reflection ||
project.getChildByName(reflectionType.name)) as DeclarationReflection
getProjectChild(project, reflectionType.name)) as DeclarationReflection
if (reflection) {
if (reflection.children?.length) {
reflection.children.forEach((childItem) => {
const reflectionChildren = canRetrieveChildren
? reflection.children ||
getTypeChildren(reflectionType, project, level)
: undefined
if (reflectionChildren?.length) {
reflectionChildren.forEach((childItem) => {
componentItem.push(
reflectionComponentFormatter(
childItem as DeclarationReflection,
reflectionComponentFormatter({
reflection: childItem as DeclarationReflection,
level,
maxLevel
)
maxLevel,
project,
})
)
})
} else {
componentItem.push(
reflectionComponentFormatter(
reflection as DeclarationReflection,
reflectionComponentFormatter({
reflection,
level,
maxLevel
)
maxLevel,
project,
})
)
}
} else {
componentItem.push({
name: "name" in reflectionType ? reflectionType.name : typeName,
type,
optional:
"flags" in reflectionType
? (reflectionType.flags as ReflectionFlags).isOptional
: false,
defaultValue:
"declaration" in reflectionType
? getDefaultValue(
reflectionType.declaration as DeclarationReflection
) || ""
: "",
description: comment ? getReturnComment(comment) : "",
expandable: comment?.hasModifier(`@expandable`) || false,
featureFlag: Handlebars.helpers.featureFlag(comment),
children: [],
})
}
}
} else if (reflectionType.type === "array") {
@@ -7,6 +7,7 @@ import {
IntersectionType,
IntrinsicType,
LiteralType,
ProjectReflection,
QueryType,
ReferenceType,
ReflectionType,
@@ -21,116 +22,164 @@ import {
import * as Handlebars from "handlebars"
import { ReflectionParameterType } from "../types"
import { escapeChars, getHTMLChar } from "../utils"
import { getProjectChild } from "utils"
export type Collapse = "object" | "function" | "all" | "none"
export default function getType(
reflectionType: SomeType,
collapse: Collapse = "none",
wrapBackticks = true,
hideLink = false,
export type TypeOptions<T = SomeType> = {
reflectionType: T
collapse?: Collapse
wrapBackticks?: boolean
hideLink?: boolean
escape?: boolean
): string {
project?: ProjectReflection
}
export default function getType({
reflectionType,
...options
}: TypeOptions): string {
if (reflectionType instanceof ReferenceType) {
return getReferenceType(reflectionType, wrapBackticks, hideLink, escape)
return getReferenceType({
reflectionType,
...options,
})
}
if (reflectionType instanceof ArrayType && reflectionType.elementType) {
return getArrayType(reflectionType, wrapBackticks, hideLink, escape)
return getArrayType({
reflectionType,
...options,
})
}
if (reflectionType instanceof UnionType && reflectionType.types) {
return getUnionType(reflectionType, wrapBackticks, hideLink, escape)
return getUnionType({
reflectionType,
...options,
})
}
if (reflectionType instanceof IntersectionType && reflectionType.types) {
return getIntersectionType(reflectionType, wrapBackticks, hideLink, escape)
return getIntersectionType({
reflectionType,
...options,
})
}
if (reflectionType instanceof TupleType && reflectionType.elements) {
return getTupleType(reflectionType, wrapBackticks, hideLink, escape)
return getTupleType({
reflectionType,
...options,
})
}
if (reflectionType instanceof IntrinsicType && reflectionType.name) {
return getIntrinsicType(reflectionType, wrapBackticks, escape)
return getIntrinsicType({
reflectionType,
...options,
})
}
if (reflectionType instanceof ReflectionType) {
return getReflectionType(
reflectionType.declaration,
collapse,
wrapBackticks,
hideLink
)
return getReflectionType({
reflectionType: reflectionType.declaration,
...options,
})
}
if (reflectionType instanceof DeclarationReflection) {
return getReflectionType(reflectionType, collapse, wrapBackticks, hideLink)
return getReflectionType({
reflectionType,
...options,
})
}
if (reflectionType instanceof TypeOperatorType) {
return getTypeOperatorType(reflectionType, wrapBackticks, hideLink, escape)
return getTypeOperatorType({
reflectionType,
...options,
})
}
if (reflectionType instanceof QueryType) {
return getQueryType(reflectionType, wrapBackticks, hideLink, escape)
return getQueryType({
reflectionType,
...options,
})
}
if (reflectionType instanceof ConditionalType) {
return getConditionalType(reflectionType, wrapBackticks, hideLink, escape)
return getConditionalType({
reflectionType,
...options,
})
}
if (reflectionType instanceof IndexedAccessType) {
return getIndexAccessType(reflectionType, wrapBackticks, hideLink, escape)
return getIndexAccessType({
reflectionType,
...options,
})
}
if (reflectionType instanceof UnknownType) {
return getUnknownType(reflectionType, escape)
return getUnknownType({
reflectionType,
...options,
})
}
if (reflectionType instanceof InferredType) {
return getInferredType(reflectionType, escape)
return getInferredType({
reflectionType,
...options,
})
}
if (reflectionType instanceof LiteralType) {
return getLiteralType(reflectionType, wrapBackticks, escape)
return getLiteralType({
reflectionType,
...options,
})
}
return reflectionType ? escapeChars(reflectionType.toString()) : ""
}
export function getReflectionType(
model: ReflectionParameterType,
collapse: Collapse,
export function getReflectionType({
reflectionType: model,
collapse,
wrapBackticks = true,
hideLink = false
): string {
hideLink = false,
}: TypeOptions<ReflectionParameterType>): string {
if ("signatures" in model && model.signatures) {
return collapse === "function" || collapse === "all"
? `${wrapBackticks ? "`" : ""}fn${wrapBackticks ? "`" : ""}`
: getFunctionType(
model.signatures,
: getFunctionType({
modelSignatures: model.signatures,
wrapBackticks,
hideLink,
!wrapBackticks
)
escape: !wrapBackticks,
})
}
return collapse === "object" || collapse === "all"
? `${wrapBackticks ? "`" : ""}object${wrapBackticks ? "`" : ""}`
: `${wrapBackticks ? "`" : ""}${getDeclarationType(
model as DeclarationReflection,
: `${wrapBackticks ? "`" : ""}${getDeclarationType({
reflectionType: model as DeclarationReflection,
wrapBackticks,
hideLink,
!wrapBackticks
)}${wrapBackticks ? "`" : ""}`
escape: !wrapBackticks,
})}${wrapBackticks ? "`" : ""}`
}
export function getDeclarationType(
model: DeclarationReflection,
export function getDeclarationType({
reflectionType: model,
wrapBackticks = true,
hideLink = false,
escape?: boolean
): string {
escape,
...options
}: TypeOptions<DeclarationReflection>): string {
escape = getShouldEscape(wrapBackticks, escape)
if (model.indexSignature || model.children) {
@@ -143,13 +192,13 @@ export function getDeclarationType(
)
: ""
const obj = declarationIndexSignature.type
? getType(
declarationIndexSignature.type,
"none",
false,
? getType({
reflectionType: declarationIndexSignature.type,
wrapBackticks: false,
hideLink,
escape
)
escape,
...options,
})
: ""
indexSignature = `${key}: ${obj}; `
}
@@ -158,7 +207,13 @@ export function getDeclarationType(
model.children.map((obj) => {
return `${obj.name}${obj.flags.isOptional ? "?" : ""}: ${
obj.type
? getType(obj.type, "none", false, hideLink, escape)
? getType({
reflectionType: obj.type,
wrapBackticks: false,
hideLink,
escape,
...options,
})
: getFormattedStr(obj.toString(), false, escape)
} ${
obj.defaultValue && obj.defaultValue !== "..."
@@ -179,12 +234,15 @@ export function getDeclarationType(
return getFormattedStr("{}", wrapBackticks, escape)
}
export function getFunctionType(
modelSignatures: SignatureReflection[],
wrapBackticks: boolean,
export function getFunctionType({
modelSignatures,
wrapBackticks = true,
hideLink = false,
escape?: boolean
): string {
escape,
...options
}: Omit<TypeOptions, "reflectionType"> & {
modelSignatures: SignatureReflection[]
}): string {
escape = getShouldEscape(wrapBackticks, escape)
const functions = modelSignatures.map((fn) => {
@@ -201,24 +259,36 @@ export function getFunctionType(
wrapBackticks ? "`" : ""
}: ${
param.type
? getType(param.type, "none", wrapBackticks, hideLink, escape)
? getType({
reflectionType: param.type,
wrapBackticks,
hideLink,
escape,
...options,
})
: getFormattedStr(param.toString(), wrapBackticks, escape)
}`
})
: []
const returns = fn.type
? getType(fn.type, "none", wrapBackticks, hideLink, escape)
? getType({
reflectionType: fn.type,
wrapBackticks,
hideLink,
escape,
...options,
})
: getFormattedStr(fn.toString(), wrapBackticks, escape)
return typeParams + `(${params.join(", ")}) => ${returns}`
})
return functions.join("")
}
export function getLiteralType(
model: LiteralType,
wrapBackticks: boolean,
escape?: boolean
): string {
export function getLiteralType({
reflectionType: model,
wrapBackticks = true,
escape,
}: TypeOptions<LiteralType>): string {
escape = getShouldEscape(wrapBackticks, escape)
return getFormattedStr(
@@ -228,26 +298,33 @@ export function getLiteralType(
)
}
export function getReferenceType(
model: ReferenceType,
export function getReferenceType({
reflectionType: model,
wrapBackticks = true,
hideLink = false,
escape?: boolean
): string {
escape,
project,
...options
}: TypeOptions<ReferenceType>): string {
escape = getShouldEscape(wrapBackticks, escape)
const shouldShowLink = !hideLink && model.name !== "Record"
const wrappedInBackticks = wrapBackticks && !shouldShowLink
if (model.reflection || (model.name && model.typeArguments)) {
let modelReflection = model.reflection
if (!modelReflection && project) {
// try to load reflection
modelReflection = getProjectChild(project!, model.name)
}
if (modelReflection || (model.name && model.typeArguments)) {
const reflection: string[] = [wrappedInBackticks ? "`" : ""]
if (model.reflection?.url) {
if (modelReflection?.url) {
reflection.push(
shouldShowLink
? `[${model.reflection.name}](${Handlebars.helpers.relativeURL(
model.reflection.url
? `[${modelReflection.name}](${Handlebars.helpers.relativeURL(
modelReflection.url
)})`
: getFormattedStr(model.reflection.name, false, escape)
: getFormattedStr(modelReflection.name, false, escape)
)
} else {
reflection.push(
@@ -262,7 +339,13 @@ export function getReferenceType(
reflection.push(
`${wrappedInBackticks ? "<" : getHTMLChar("<")}${model.typeArguments
.map((typeArgument) =>
getType(typeArgument, "none", false, hideLink, false)
getType({
reflectionType: typeArgument,
wrapBackticks: false,
hideLink,
escape: false,
...options,
})
)
.join(", ")}${wrappedInBackticks ? ">" : getHTMLChar(">")}`
)
@@ -281,151 +364,191 @@ export function getReferenceType(
: getFormattedStr(model.name, wrapBackticks, escape)
}
export function getArrayType(
model: ArrayType,
wrapBackticks: boolean,
export function getArrayType({
reflectionType: model,
hideLink = false,
escape?: boolean
): string {
const arrayType = getType(
model.elementType,
"none",
wrapBackticks,
...options
}: TypeOptions<ArrayType>): string {
const arrayType = getType({
reflectionType: model.elementType,
hideLink,
escape
)
...options,
})
return model.elementType.type === "union"
? `(${arrayType})[]`
: `${arrayType}[]`
}
export function getUnionType(
model: UnionType,
wrapBackticks: boolean,
export function getUnionType({
reflectionType: model,
hideLink = false,
escape?: boolean
): string {
...options
}: TypeOptions<UnionType>): string {
return model.types
.map((unionType) =>
getType(unionType, "none", wrapBackticks, hideLink, escape)
getType({
reflectionType: unionType,
hideLink,
...options,
})
)
.join(` \\| `)
}
export function getIntersectionType(
model: IntersectionType,
wrapBackticks: boolean,
export function getIntersectionType({
reflectionType: model,
hideLink = false,
escape?: boolean
): string {
...options
}: TypeOptions<IntersectionType>): string {
return model.types
.map((intersectionType) =>
getType(intersectionType, "none", wrapBackticks, hideLink, escape)
getType({
reflectionType: intersectionType,
hideLink,
...options,
})
)
.join(" & ")
}
export function getTupleType(
model: TupleType,
wrapBackticks: boolean,
export function getTupleType({
reflectionType: model,
hideLink = false,
escape?: boolean
): string {
...options
}: TypeOptions<TupleType>): string {
return `[${model.elements
.map((element) => getType(element, "none", wrapBackticks, hideLink, escape))
.map((element) =>
getType({
reflectionType: element,
hideLink,
...options,
})
)
.join(", ")}]`
}
export function getIntrinsicType(
model: IntrinsicType,
wrapBackticks: boolean,
escape?: boolean
): string {
export function getIntrinsicType({
reflectionType: model,
wrapBackticks = true,
escape,
}: TypeOptions<IntrinsicType>): string {
escape = getShouldEscape(wrapBackticks, escape)
return getFormattedStr(model.name, wrapBackticks, escape)
}
export function getTypeOperatorType(
model: TypeOperatorType,
wrapBackticks: boolean,
export function getTypeOperatorType({
reflectionType: model,
hideLink = false,
escape?: boolean
): string {
return `${model.operator} ${getType(
model.target,
"none",
wrapBackticks,
...options
}: TypeOptions<TypeOperatorType>): string {
return `${model.operator} ${getType({
reflectionType: model.target,
hideLink,
escape
)}`
...options,
})}`
}
export function getQueryType(
model: QueryType,
wrapBackticks: boolean,
export function getQueryType({
reflectionType: model,
hideLink = false,
escape?: boolean
): string {
return `typeof ${getType(
model.queryType,
"none",
wrapBackticks,
...options
}: TypeOptions<QueryType>): string {
return `typeof ${getType({
reflectionType: model.queryType,
hideLink,
escape
)}`
...options,
})}`
}
export function getInferredType(model: InferredType, escape?: boolean): string {
export function getInferredType({
reflectionType: model,
escape,
}: TypeOptions<InferredType>): string {
escape = getShouldEscape(false, escape)
return `infer ${getFormattedStr(model.name, false, escape)}`
}
export function getUnknownType(model: UnknownType, escape?: boolean): string {
export function getUnknownType({
reflectionType: model,
escape,
}: TypeOptions<UnknownType>): string {
escape = getShouldEscape(false, escape)
return getFormattedStr(model.name, false, escape)
}
export function getConditionalType(
model: ConditionalType,
wrapBackticks: boolean,
export function getConditionalType({
reflectionType: model,
hideLink = false,
escape?: boolean
): string {
...options
}: TypeOptions<ConditionalType>): string {
const md: string[] = []
if (model.checkType) {
md.push(getType(model.checkType, "none", wrapBackticks, hideLink, escape))
md.push(
getType({
reflectionType: model.checkType,
hideLink,
...options,
})
)
}
md.push("extends")
if (model.extendsType) {
md.push(getType(model.extendsType, "none", wrapBackticks, hideLink, escape))
md.push(
getType({
reflectionType: model.extendsType,
hideLink,
...options,
})
)
}
md.push("?")
if (model.trueType) {
md.push(getType(model.trueType, "none", wrapBackticks, hideLink, escape))
md.push(
getType({
reflectionType: model.trueType,
hideLink,
...options,
})
)
}
md.push(":")
if (model.falseType) {
md.push(getType(model.falseType, "none", wrapBackticks, hideLink, escape))
md.push(
getType({
reflectionType: model.falseType,
hideLink,
...options,
})
)
}
return md.join(" ")
}
export function getIndexAccessType(
model: IndexedAccessType,
wrapBackticks: boolean,
export function getIndexAccessType({
reflectionType: model,
hideLink = false,
escape?: boolean
): string {
...options
}: TypeOptions<IndexedAccessType>): string {
const md: string[] = []
if (model.objectType) {
md.push(getType(model.objectType, "none", wrapBackticks, hideLink, escape))
md.push(
getType({
reflectionType: model.objectType,
hideLink,
...options,
})
)
}
if (model.indexType) {
md.push(
`[${getType(model.indexType, "none", wrapBackticks, hideLink, escape)}]`
`[${getType({
reflectionType: model.indexType,
hideLink,
...options,
})}]`
)
}
return md.join("")
@@ -4,28 +4,34 @@ import {
ReflectionKind,
} from "typedoc"
const MAX_LEVEL = 3
export function getProjectChild(
project: ProjectReflection,
childName: string
childName: string,
level = 1
): DeclarationReflection | undefined {
let reflection: DeclarationReflection | undefined = project.getChildByName(
childName
) as DeclarationReflection
const splitChildName = childName.split(".")
const canExpandFurther = level <= MAX_LEVEL
if (!reflection && splitChildName.length > 1) {
if (!reflection && splitChildName.length > 1 && canExpandFurther) {
reflection = getProjectChild(
project,
splitChildName[splitChildName.length - 1]
splitChildName[splitChildName.length - 1],
level + 1
)
}
if (
!reflection &&
project.parent &&
project.parent instanceof ProjectReflection
project.parent instanceof ProjectReflection &&
canExpandFurther
) {
reflection = getProjectChild(project.parent, childName)
reflection = getProjectChild(project.parent, childName, level + 1)
}
if (!reflection) {
@@ -1,16 +1,23 @@
import { DeclarationReflection, ProjectReflection, SomeType } from "typedoc"
import { getProjectChild } from "./get-project-child"
const MAX_LEVEL = 3
export function getTypeChildren(
reflectionType: SomeType,
project: ProjectReflection | undefined
project: ProjectReflection | undefined,
level = 1
): DeclarationReflection[] {
let children: DeclarationReflection[] = []
if (level > MAX_LEVEL) {
return children
}
switch (reflectionType.type) {
case "intersection":
reflectionType.types.forEach((intersectionType) => {
children.push(...getTypeChildren(intersectionType, project))
children.push(...getTypeChildren(intersectionType, project, level + 1))
})
break
case "reference":
@@ -19,41 +26,48 @@ export function getTypeChildren(
reflectionType.reflection && "children" in reflectionType.reflection
? reflectionType.reflection
: project
? getProjectChild(project, reflectionType.name)
: undefined
? getProjectChild(project, reflectionType.name)
: undefined
if (referencedReflection instanceof DeclarationReflection) {
if (referencedReflection.children) {
children = referencedReflection.children
} else if (reflectionType.typeArguments?.length) {
reflectionType.typeArguments.forEach((typeArgument, index) => {
if (reflectionType.name === "Omit" && index > 0) {
switch (typeArgument.type) {
case "literal":
removeChild(typeArgument.value?.toString(), children)
break
case "union":
typeArgument.types.forEach((childItem) => {
if (childItem.type === "literal") {
removeChild(childItem.value?.toString(), children)
} else {
getTypeChildren(childItem, project).forEach((child) => {
removeChild(child.name, children)
})
}
})
}
} else {
const typeArgumentChildren = getTypeChildren(
typeArgument,
project
)
children.push(...typeArgumentChildren)
}
})
} else if (referencedReflection.type) {
children = getTypeChildren(referencedReflection.type, project)
children = getTypeChildren(
referencedReflection.type,
project,
level + 1
)
}
} else if (reflectionType.typeArguments?.length) {
reflectionType.typeArguments.forEach((typeArgument, index) => {
if (reflectionType.name === "Omit" && index > 0) {
switch (typeArgument.type) {
case "literal":
removeChild(typeArgument.value?.toString(), children)
break
case "union":
typeArgument.types.forEach((childItem) => {
if (childItem.type === "literal") {
removeChild(childItem.value?.toString(), children)
} else {
getTypeChildren(childItem, project, level + 1).forEach(
(child) => {
removeChild(child.name, children)
}
)
}
})
}
} else {
const typeArgumentChildren = getTypeChildren(
typeArgument,
project,
level + 1
)
children.push(...typeArgumentChildren)
}
})
}
break
case "reflection":
@@ -62,7 +76,7 @@ export function getTypeChildren(
]
break
case "array":
children = getTypeChildren(reflectionType.elementType, project)
children = getTypeChildren(reflectionType.elementType, project, level + 1)
}
return filterChildren(children)