docs-util: rename docblock-generator to docs-generator (#8331)
* docs-util: rename docblock-generator to docs-generator * change program name * fix action
This commit is contained in:
8
www/utils/packages/docs-generator/src/utils/dirname.ts
Normal file
8
www/utils/packages/docs-generator/src/utils/dirname.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import path from "path"
|
||||
import { fileURLToPath } from "url"
|
||||
|
||||
export default function dirname(fileUrl: string) {
|
||||
const __filename = fileURLToPath(fileUrl)
|
||||
|
||||
return path.dirname(__filename)
|
||||
}
|
||||
13
www/utils/packages/docs-generator/src/utils/filter-files.ts
Normal file
13
www/utils/packages/docs-generator/src/utils/filter-files.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { minimatch } from "minimatch"
|
||||
|
||||
export default function (files: string[]): string[] {
|
||||
return files.filter((file) =>
|
||||
minimatch(
|
||||
file,
|
||||
"**/packages/@(medusa|core/types|medusa-js|medusa-react)/src/**/*.@(ts|tsx|js|jsx)",
|
||||
{
|
||||
matchBase: true,
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
20
www/utils/packages/docs-generator/src/utils/format-oas.ts
Normal file
20
www/utils/packages/docs-generator/src/utils/format-oas.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { stringify } from "yaml"
|
||||
import { DOCBLOCK_END_LINE, DOCBLOCK_NEW_LINE } from "../constants.js"
|
||||
import { OpenApiOperation, OpenApiSchema } from "../types/index.js"
|
||||
|
||||
/**
|
||||
* Retrieve the OAS as a formatted string that can be used as a comment.
|
||||
*
|
||||
* @param oas - The OAS operation to format.
|
||||
* @param oasPrefix - The OAS prefix that's used before the OAS operation.
|
||||
* @returns The formatted OAS comment.
|
||||
*/
|
||||
export default function formatOas(
|
||||
oas: OpenApiOperation | OpenApiSchema,
|
||||
oasPrefix: string
|
||||
) {
|
||||
return `* ${oasPrefix}${DOCBLOCK_NEW_LINE}${stringify(oas).replaceAll(
|
||||
"\n",
|
||||
DOCBLOCK_NEW_LINE
|
||||
)}${DOCBLOCK_END_LINE}`
|
||||
}
|
||||
15
www/utils/packages/docs-generator/src/utils/get-base-path.ts
Normal file
15
www/utils/packages/docs-generator/src/utils/get-base-path.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Retrieve the pathname of a file without the relative part before `packages/`
|
||||
*
|
||||
* @param fileName - The file name/path
|
||||
* @returns The path without the relative part.
|
||||
*/
|
||||
export default function getBasePath(fileName: string) {
|
||||
let basePath = fileName
|
||||
const packageIndex = fileName.indexOf("packages/")
|
||||
if (packageIndex) {
|
||||
basePath = basePath.substring(packageIndex)
|
||||
}
|
||||
|
||||
return basePath
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Due to some types using Zod in their declaration
|
||||
// The type name isn't picked properly by typescript
|
||||
|
||||
import ts from "typescript"
|
||||
import isZodObject from "./is-zod-object.js"
|
||||
|
||||
// this ensures that the correct type name is used.
|
||||
export default function getCorrectZodTypeName({
|
||||
typeReferenceNode,
|
||||
itemType,
|
||||
}: {
|
||||
typeReferenceNode: ts.TypeReferenceNode
|
||||
itemType: ts.Type
|
||||
}): string | undefined {
|
||||
if (!isZodObject(itemType)) {
|
||||
return
|
||||
}
|
||||
|
||||
return typeReferenceNode.typeArguments?.[0] &&
|
||||
"typeName" in typeReferenceNode.typeArguments[0]
|
||||
? (typeReferenceNode.typeArguments?.[0].typeName as ts.Identifier).getText()
|
||||
: undefined
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import path from "path"
|
||||
import dirname from "./dirname.js"
|
||||
|
||||
/**
|
||||
* Retrieves the monorepo root either from the `MONOREPO_ROOT_PATH` environment
|
||||
* variable, or inferring it from the path.
|
||||
*
|
||||
* @returns {string} The absolute path to the monorepository.
|
||||
*/
|
||||
export default function getMonorepoRoot(): string {
|
||||
return (
|
||||
process.env.MONOREPO_ROOT_PATH ||
|
||||
path.join(dirname(import.meta.url), "..", "..", "..", "..", "..", "..")
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import path from "path"
|
||||
import getMonorepoRoot from "./get-monorepo-root.js"
|
||||
|
||||
/**
|
||||
* Retrieves the base path to the `oas-output` directory.
|
||||
*/
|
||||
export function getOasOutputBasePath() {
|
||||
return path.join(getMonorepoRoot(), "www", "utils", "generated", "oas-output")
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the base path to the `dml-output` directory
|
||||
*/
|
||||
export function getDmlOutputBasePath() {
|
||||
return path.join(getMonorepoRoot(), "www", "utils", "generated", "dml-output")
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import path from "path"
|
||||
|
||||
/**
|
||||
* Get relative path of multiple file paths to a specified path.
|
||||
*
|
||||
* @param {string[]} filePaths - The file paths to retrieve their relative path.
|
||||
* @param {string} pathPrefix - The path to retrieve paths relative to.
|
||||
* @returns {string[]} The relative file paths.
|
||||
*/
|
||||
export default function getRelativePaths(
|
||||
filePaths: string[],
|
||||
pathPrefix: string
|
||||
): string[] {
|
||||
return filePaths.map((filePath) => path.resolve(pathPrefix, filePath))
|
||||
}
|
||||
24
www/utils/packages/docs-generator/src/utils/get-symbol.ts
Normal file
24
www/utils/packages/docs-generator/src/utils/get-symbol.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import ts from "typescript"
|
||||
|
||||
/**
|
||||
* Retrieves the symbol of a node.
|
||||
*
|
||||
* @param {ts.Node} node - The node to retrieve its symbol.
|
||||
* @param {ts.TypeChecker} checker - The type checker of the TypeScript program the symbol is in.
|
||||
* @returns {ts.Symbol | undefined} The symbol if found.
|
||||
*/
|
||||
export default function getSymbol(
|
||||
node: ts.Node,
|
||||
checker: ts.TypeChecker
|
||||
): ts.Symbol | undefined {
|
||||
if (
|
||||
ts.isVariableStatement(node) &&
|
||||
node.declarationList.declarations.length
|
||||
) {
|
||||
return getSymbol(node.declarationList.declarations[0], checker)
|
||||
}
|
||||
|
||||
return "symbol" in node && node.symbol
|
||||
? (node.symbol as ts.Symbol)
|
||||
: undefined
|
||||
}
|
||||
15
www/utils/packages/docs-generator/src/utils/is-zod-object.ts
Normal file
15
www/utils/packages/docs-generator/src/utils/is-zod-object.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import ts from "typescript"
|
||||
|
||||
export default function isZodObject(itemType: ts.Type): boolean {
|
||||
if (!itemType.symbol?.declarations?.length) {
|
||||
return false
|
||||
}
|
||||
|
||||
const parent = itemType.symbol.declarations[0].parent
|
||||
|
||||
if (!("typeName" in parent)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return (parent.typeName as ts.Identifier).getText().includes("ZodObject")
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import path from "path"
|
||||
import getMonorepoRoot from "./get-monorepo-root.js"
|
||||
import ts from "typescript"
|
||||
import { minimatch } from "minimatch"
|
||||
import { capitalize } from "utils"
|
||||
|
||||
export const kindsCanHaveNamespace = [
|
||||
ts.SyntaxKind.SourceFile,
|
||||
ts.SyntaxKind.ClassDeclaration,
|
||||
ts.SyntaxKind.EnumDeclaration,
|
||||
ts.SyntaxKind.ModuleDeclaration,
|
||||
ts.SyntaxKind.InterfaceDeclaration,
|
||||
ts.SyntaxKind.TypeAliasDeclaration,
|
||||
ts.SyntaxKind.MethodDeclaration,
|
||||
ts.SyntaxKind.MethodSignature,
|
||||
ts.SyntaxKind.FunctionDeclaration,
|
||||
ts.SyntaxKind.ArrowFunction,
|
||||
ts.SyntaxKind.VariableStatement,
|
||||
]
|
||||
|
||||
export const pathsHavingCustomNamespace = [
|
||||
"**/packages/medusa\\-react/src/hooks/**/index.ts",
|
||||
"**/packages/medusa\\-react/src/@(helpers|contexts)/**/*.@(tsx|ts)",
|
||||
]
|
||||
|
||||
export const CUSTOM_NAMESPACE_TAG = "@customNamespace"
|
||||
|
||||
/**
|
||||
* Get the path used with the {@link CUSTOM_NAMESPACE_TAG}.
|
||||
*
|
||||
* @param {ts.Node} node - The node to retrieve its custom namespace path.
|
||||
* @returns {string} The namespace path.
|
||||
*/
|
||||
export function getNamespacePath(node: ts.Node): string {
|
||||
const packagePathPrefix = `${path.resolve(
|
||||
getMonorepoRoot(),
|
||||
"packages/medusa-react/src"
|
||||
)}/`
|
||||
|
||||
const sourceFile = node.getSourceFile()
|
||||
|
||||
let hookPath = path
|
||||
.dirname(sourceFile.fileName)
|
||||
.replace(packagePathPrefix, "")
|
||||
|
||||
const fileName = path.basename(sourceFile.fileName)
|
||||
|
||||
if (
|
||||
!fileName.startsWith("index") &&
|
||||
!fileName.startsWith("mutations") &&
|
||||
!fileName.startsWith("queries")
|
||||
) {
|
||||
hookPath += `/${fileName.replace(path.extname(fileName), "")}`
|
||||
}
|
||||
|
||||
return hookPath
|
||||
.split("/")
|
||||
.map((pathItem, index) => {
|
||||
if (index === 0) {
|
||||
pathItem = pathItem
|
||||
.replace("contexts", "providers")
|
||||
.replace("helpers", "utilities")
|
||||
}
|
||||
|
||||
return pathItem
|
||||
.split("-")
|
||||
.map((item) => capitalize(item))
|
||||
.join(" ")
|
||||
})
|
||||
.join(".")
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the full tag of the custom namespace with its value.
|
||||
*
|
||||
* @param {ts.Node} node - The node to retrieve its custom namespace path.
|
||||
* @returns {string} The custom namespace tag and value.
|
||||
*/
|
||||
export function getCustomNamespaceTag(node: ts.Node): string {
|
||||
return `${CUSTOM_NAMESPACE_TAG} ${getNamespacePath(node)}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a node should have a custom namespace path.
|
||||
*
|
||||
* @param {ts.Node} node - The node to check.
|
||||
* @returns {boolean} Whether the node should have a custom namespace.
|
||||
*/
|
||||
export function shouldHaveCustomNamespace(node: ts.Node): boolean {
|
||||
if (!kindsCanHaveNamespace.includes(node.kind)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const fileName = node.getSourceFile().fileName
|
||||
|
||||
return pathsHavingCustomNamespace.some((pattern) =>
|
||||
minimatch(fileName, pattern, {
|
||||
matchBase: true,
|
||||
})
|
||||
)
|
||||
}
|
||||
42
www/utils/packages/docs-generator/src/utils/parse-oas.ts
Normal file
42
www/utils/packages/docs-generator/src/utils/parse-oas.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { parse } from "yaml"
|
||||
import { OpenApiOperation } from "../types/index.js"
|
||||
import { DOCBLOCK_LINE_ASTRIX } from "../constants.js"
|
||||
|
||||
export type ExistingOas = {
|
||||
oas: OpenApiOperation
|
||||
oasPrefix: string
|
||||
}
|
||||
|
||||
export default function parseOas(content: string): ExistingOas | undefined {
|
||||
content = content
|
||||
.replace(`/**\n`, "")
|
||||
.replaceAll(DOCBLOCK_LINE_ASTRIX, "")
|
||||
.replaceAll("*/", "")
|
||||
.trim()
|
||||
|
||||
if (!content.startsWith("@oas")) {
|
||||
// the file is of an invalid format.
|
||||
return
|
||||
}
|
||||
|
||||
// extract oas prefix line
|
||||
const splitNodeComments = content.split("\n")
|
||||
const oasPrefix = content.split("\n")[0]
|
||||
content = splitNodeComments.slice(1).join("\n")
|
||||
|
||||
let oas: OpenApiOperation | undefined
|
||||
|
||||
try {
|
||||
oas = parse(content) as OpenApiOperation
|
||||
} catch (e) {
|
||||
// couldn't parse the OAS, so consider it
|
||||
// not existent
|
||||
}
|
||||
|
||||
return oas
|
||||
? {
|
||||
oas,
|
||||
oasPrefix,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import util from "node:util"
|
||||
import { exec } from "child_process"
|
||||
|
||||
export default util.promisify(exec)
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Remove parts of the name such as DTO, Filterable, etc...
|
||||
*
|
||||
* @param {string} str - The name to format.
|
||||
* @returns {string} The normalized name.
|
||||
*/
|
||||
export function normalizeName(str: string): string {
|
||||
return str
|
||||
.replace(/^(create|update|delete|upsert)/i, "")
|
||||
.replace(/DTO$/, "")
|
||||
.replace(/^Filterable/, "")
|
||||
.replace(/Props$/, "")
|
||||
.replace(/^I([A-Z])/, "$1")
|
||||
.replace(/ModuleService$/, "")
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Retrieves the stringified JSON of a variable formatted.
|
||||
*
|
||||
* @param item The item to stringify
|
||||
* @returns The formatted JSON string
|
||||
*/
|
||||
export default function toJsonFormatted(item: unknown): string {
|
||||
return JSON.stringify(item, undefined, "\t")
|
||||
}
|
||||
Reference in New Issue
Block a user