docs-util: created docblock-generator tool (#6096)
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
import path from "path"
|
||||
import { fileURLToPath } from "url"
|
||||
|
||||
export default function dirname() {
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
|
||||
return path.dirname(__filename)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { minimatch } from "minimatch"
|
||||
|
||||
export default function (files: string[]): string[] {
|
||||
return files.filter((file) =>
|
||||
minimatch(
|
||||
file,
|
||||
"**/packages/@(medusa|types|medusa-js|medusa-react)/src/**/*.@(ts|tsx|js|jsx)",
|
||||
{
|
||||
matchBase: true,
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -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() {
|
||||
return (
|
||||
process.env.MONOREPO_ROOT_PATH ||
|
||||
path.join(dirname(), "..", "..", "..", "..", "..")
|
||||
)
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 "./str-formatting.js"
|
||||
|
||||
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,
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import ts from "typescript"
|
||||
|
||||
/**
|
||||
* Checks whether a node has comments.
|
||||
*
|
||||
* @param {ts.Node} node - The node to check.
|
||||
* @returns {boolean} Whether the node has comments.
|
||||
*/
|
||||
export default function nodeHasComments(node: ts.Node): boolean {
|
||||
return (
|
||||
ts.getLeadingCommentRanges(
|
||||
node.getSourceFile().getFullText(),
|
||||
node.getFullStart()
|
||||
) !== undefined
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import util from "node:util"
|
||||
import { exec } from "child_process"
|
||||
|
||||
export default util.promisify(exec)
|
||||
@@ -0,0 +1,38 @@
|
||||
export function capitalize(str: string): string {
|
||||
return `${str.charAt(0).toUpperCase()}${str.substring(1).toLowerCase()}`
|
||||
}
|
||||
|
||||
export function camelToWords(str: string): string {
|
||||
return str
|
||||
.replaceAll(/([A-Z])/g, " $1")
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
}
|
||||
|
||||
export function camelToTitle(str: string): string {
|
||||
return str
|
||||
.replaceAll(/([A-Z])/g, " $1")
|
||||
.split(" ")
|
||||
.map((word) => capitalize(word))
|
||||
.join(" ")
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
}
|
||||
|
||||
export function snakeToWords(str: string): string {
|
||||
return str.replaceAll("_", " ").toLowerCase()
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)/i, "")
|
||||
.replace(/DTO$/, "")
|
||||
.replace(/^Filterable/, "")
|
||||
.replace(/Props$/, "")
|
||||
}
|
||||
Reference in New Issue
Block a user