chore: move docs-util to www (#7232)

* reorganize docs apps

* add README

* fix directory

* add condition for old docs

* move docs-util to www

* remove remaining docs-util

* fixes of paths

* fix scripts

* path fixes

* fix github actions

* add build packages script
This commit is contained in:
Shahed Nasser authored and GitHub committed 2024-05-06 09:13:50 +03:00
1 parent cf9605fe6f
commit b39de05535
607 files changed
+183 -254

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
{
"name": "utils",
"private": true,
"license": "MIT",
"publishConfig": {
"access": "public"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"version": "0.0.0",
"scripts": {
"build": "yarn clean && tsc",
"lint": "eslint --ext .ts src",
"clean": "rimraf dist"
},
"peerDependencies": {
"typedoc": "0.25.x"
},
"devDependencies": {
"@types/node": "^16.11.10",
"typescript": "5.2"
},
"dependencies": {
"octokit": "^3.1.2",
"rimraf": "^5.0.5"
}
}
@@ -0,0 +1,49 @@
import {
DeclarationReflection,
ProjectReflection,
ReflectionKind,
} from "typedoc"
const MAX_LEVEL = 3
export function getProjectChild(
project: ProjectReflection,
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 && canExpandFurther) {
reflection = getProjectChild(
project,
splitChildName[splitChildName.length - 1],
level + 1
)
}
if (
!reflection &&
project.parent &&
project.parent instanceof ProjectReflection &&
canExpandFurther
) {
reflection = getProjectChild(project.parent, childName, level + 1)
}
if (!reflection) {
const modules = project.getChildrenByKind(ReflectionKind.Module)
for (const module of modules) {
reflection = module.getChildByName(childName) as DeclarationReflection
if (reflection) {
break
}
}
}
return reflection
}
@@ -0,0 +1,169 @@
/* eslint-disable no-case-declarations */
import { DeclarationReflection, ProjectReflection, SomeType } from "typedoc"
import { getProjectChild } from "./get-project-child"
type GetTypeChildrenOptions = {
reflectionType: SomeType
project: ProjectReflection | undefined
level?: number
maxLevel?: number
}
export function getTypeChildren({
reflectionType,
project,
level = 1,
maxLevel = 3,
}: GetTypeChildrenOptions): DeclarationReflection[] {
let children: DeclarationReflection[] = []
if (level > maxLevel) {
return children
}
switch (reflectionType.type) {
case "intersection":
reflectionType.types.forEach((intersectionType) => {
children.push(
...getTypeChildren({
reflectionType: intersectionType,
project,
level: level + 1,
maxLevel,
})
)
})
break
case "reference":
// eslint-disable-next-line no-case-declarations
const referencedReflection = reflectionType.reflection
? "children" in reflectionType.reflection
? reflectionType.reflection
: project
? project.getReflectionById(reflectionType.reflection.id)
: undefined
: project
? getProjectChild(project, reflectionType.name)
: undefined
if (referencedReflection instanceof DeclarationReflection) {
if (referencedReflection.children) {
children = referencedReflection.children
} else if (referencedReflection.type) {
children = getTypeChildren({
reflectionType: referencedReflection.type,
project,
level: level + 1,
maxLevel,
})
}
} else if (reflectionType.typeArguments?.length) {
// Only useful if the reflection type is `Pick<...>`.
const toKeepChildren: string[] = []
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({
reflectionType: childItem,
project,
level: level + 1,
maxLevel,
}).forEach((child) => {
removeChild(child.name, children)
})
}
})
}
} else if (reflectionType.name === "Pick") {
if (index === 0 && !children.length) {
children = getTypeChildren({
reflectionType: typeArgument,
project,
level: level + 1,
maxLevel,
})
} else {
switch (typeArgument.type) {
case "literal":
if (typeArgument.value) {
toKeepChildren.push(typeArgument.value?.toString())
}
break
case "union":
typeArgument.types.forEach((childItem) => {
if (childItem.type === "literal") {
if (childItem.value) {
toKeepChildren.push(childItem.value?.toString())
}
} else {
getTypeChildren({
reflectionType: childItem,
project,
level: level + 1,
maxLevel,
}).forEach((child) => {
if (child.name) {
toKeepChildren.push(child.name)
}
})
}
})
}
}
} else {
const typeArgumentChildren = getTypeChildren({
reflectionType: typeArgument,
project,
level: level + 1,
maxLevel,
})
children.push(...typeArgumentChildren)
}
})
if (toKeepChildren.length) {
children = children.filter((child) =>
toKeepChildren.includes(child.name)
)
}
}
break
case "reflection":
children = reflectionType.declaration.children || [
reflectionType.declaration,
]
break
case "array":
children = getTypeChildren({
reflectionType: reflectionType.elementType,
project,
level: level + 1,
maxLevel,
})
}
return filterChildren(children)
}
const REJECTED_CHILDREN_NAMES = ["__type"]
function filterChildren(children: DeclarationReflection[]) {
return children.filter(
(child) => !REJECTED_CHILDREN_NAMES.includes(child.name)
)
}
function removeChild(name: unknown, children: DeclarationReflection[]) {
const childIndex = children.findIndex((child) => child.name === name)
if (childIndex !== -1) {
children.splice(childIndex, 1)
}
}
@@ -0,0 +1,580 @@
import {
ArrayType,
ConditionalType,
DeclarationReflection,
IndexedAccessType,
InferredType,
IntersectionType,
IntrinsicType,
LiteralType,
ParameterReflection,
ProjectReflection,
QueryType,
ReferenceType,
ReflectionType,
SignatureReflection,
SomeType,
TupleType,
TypeOperatorType,
TypeParameterReflection,
UnionType,
UnknownType,
} from "typedoc"
import { escapeChars, getHTMLChar } from "./str-utils"
import { getProjectChild } from "./get-project-child"
export type ReflectionParameterType =
| ParameterReflection
| DeclarationReflection
| TypeParameterReflection
export type Collapse = "object" | "function" | "all" | "none"
export type TypeOptions<T = SomeType> = {
reflectionType: T
collapse?: Collapse
wrapBackticks?: boolean
hideLink?: boolean
escape?: boolean
project?: ProjectReflection
getRelativeUrlMethod?: (url: string) => string
}
export function getType({ reflectionType, ...options }: TypeOptions): string {
if (reflectionType instanceof ReferenceType) {
return getReferenceType({
reflectionType,
...options,
})
}
if (reflectionType instanceof ArrayType && reflectionType.elementType) {
return getArrayType({
reflectionType,
...options,
})
}
if (reflectionType instanceof UnionType && reflectionType.types) {
return getUnionType({
reflectionType,
...options,
})
}
if (reflectionType instanceof IntersectionType && reflectionType.types) {
return getIntersectionType({
reflectionType,
...options,
})
}
if (reflectionType instanceof TupleType && reflectionType.elements) {
return getTupleType({
reflectionType,
...options,
})
}
if (reflectionType instanceof IntrinsicType && reflectionType.name) {
return getIntrinsicType({
reflectionType,
...options,
})
}
if (reflectionType instanceof ReflectionType) {
return getReflectionType({
reflectionType: reflectionType.declaration,
...options,
})
}
if (reflectionType instanceof DeclarationReflection) {
return getReflectionType({
reflectionType,
...options,
})
}
if (reflectionType instanceof TypeOperatorType) {
return getTypeOperatorType({
reflectionType,
...options,
})
}
if (reflectionType instanceof QueryType) {
return getQueryType({
reflectionType,
...options,
})
}
if (reflectionType instanceof ConditionalType) {
return getConditionalType({
reflectionType,
...options,
})
}
if (reflectionType instanceof IndexedAccessType) {
return getIndexAccessType({
reflectionType,
...options,
})
}
if (reflectionType instanceof UnknownType) {
return getUnknownType({
reflectionType,
...options,
})
}
if (reflectionType instanceof InferredType) {
return getInferredType({
reflectionType,
...options,
})
}
if (reflectionType instanceof LiteralType) {
return getLiteralType({
reflectionType,
...options,
})
}
return reflectionType ? escapeChars(reflectionType.toString()) : ""
}
export function getReflectionType({
reflectionType: model,
collapse,
wrapBackticks = true,
hideLink = false,
...options
}: TypeOptions<ReflectionParameterType>): string {
if ("signatures" in model && model.signatures) {
return collapse === "function" || collapse === "all"
? `${wrapBackticks ? "`" : ""}fn${wrapBackticks ? "`" : ""}`
: getFunctionType({
modelSignatures: model.signatures,
wrapBackticks,
hideLink,
escape: !wrapBackticks,
...options,
})
}
return collapse === "object" || collapse === "all"
? `${wrapBackticks ? "`" : ""}object${wrapBackticks ? "`" : ""}`
: `${wrapBackticks ? "`" : ""}${getDeclarationType({
reflectionType: model as DeclarationReflection,
wrapBackticks,
hideLink,
escape: !wrapBackticks,
...options,
})}${wrapBackticks ? "`" : ""}`
}
export function getDeclarationType({
reflectionType: model,
wrapBackticks = true,
hideLink = false,
escape,
...options
}: TypeOptions<DeclarationReflection>): string {
escape = getShouldEscape(wrapBackticks, escape)
if (model.indexSignature || model.children) {
let indexSignature = ""
const declarationIndexSignature = model.indexSignature
if (declarationIndexSignature) {
const key = declarationIndexSignature.parameters
? declarationIndexSignature.parameters.map(
(param) => `[${param.name}: ${param.type}]`
)
: ""
const obj = declarationIndexSignature.type
? getType({
reflectionType: declarationIndexSignature.type,
wrapBackticks: false,
hideLink,
escape,
...options,
})
: ""
indexSignature = `${key}: ${obj}; `
}
const types =
model.children &&
model.children.map((obj) => {
return `${obj.name}${obj.flags.isOptional ? "?" : ""}: ${
obj.type
? getType({
reflectionType: obj.type,
wrapBackticks: false,
hideLink,
escape,
...options,
})
: getFormattedStr(obj.toString(), false, escape)
} ${
obj.defaultValue && obj.defaultValue !== "..."
? `= ${getFormattedStr(`${obj.defaultValue}`, false, escape)}`
: ""
}`
})
return `${wrapBackticks ? "`{" : getHTMLChar("{")} ${
indexSignature ? indexSignature : ""
}${types ? types.join("; ") : ""} ${
wrapBackticks ? "}`" : getHTMLChar("}")
}${
model.defaultValue && model.defaultValue !== "..."
? `= ${getFormattedStr(`${model.defaultValue}`, wrapBackticks, escape)}`
: ""
}`
}
return getFormattedStr("{}", wrapBackticks, escape)
}
export function getFunctionType({
modelSignatures,
wrapBackticks = true,
hideLink = false,
escape,
...options
}: Omit<TypeOptions, "reflectionType"> & {
modelSignatures: SignatureReflection[]
}): string {
escape = getShouldEscape(wrapBackticks, escape)
const functions = modelSignatures.map((fn) => {
const typeParams = fn.typeParameters
? `${wrapBackticks ? "`<" : getHTMLChar("<")}${fn.typeParameters
.map((typeParameter) => typeParameter.name)
.join(", ")}${wrapBackticks ? ">`" : getHTMLChar(">")}`
: []
const params = fn.parameters
? fn.parameters.map((param) => {
return `${param.flags.isRest ? "..." : ""}${
wrapBackticks ? "`" : ""
}${param.name}${param.flags.isOptional ? "?" : ""}${
wrapBackticks ? "`" : ""
}: ${
param.type
? getType({
reflectionType: param.type,
wrapBackticks,
hideLink,
escape,
...options,
})
: getFormattedStr(param.toString(), wrapBackticks, escape)
}`
})
: []
const returns = fn.type
? getType({
reflectionType: fn.type,
wrapBackticks,
hideLink,
escape,
...options,
})
: getFormattedStr(fn.toString(), wrapBackticks, escape)
return typeParams + `(${params.join(", ")}) => ${returns}`
})
return functions.join("")
}
export function getLiteralType({
reflectionType: model,
wrapBackticks = true,
escape,
}: TypeOptions<LiteralType>): string {
escape = getShouldEscape(wrapBackticks, escape)
return getFormattedStr(
model.value === "bigint" ? model.value : JSON.stringify(model.value),
wrapBackticks,
escape
)
}
export function getReferenceType({
reflectionType: model,
wrapBackticks = true,
hideLink = false,
escape,
project,
getRelativeUrlMethod,
...options
}: TypeOptions<ReferenceType>): string {
const shouldShowLink = !hideLink && model.name !== "Record"
const wrappedInBackticks = wrapBackticks && !shouldShowLink
escape = getShouldEscape(wrappedInBackticks, escape)
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 (modelReflection?.url) {
reflection.push(
shouldShowLink
? `[${modelReflection.name}](${
getRelativeUrlMethod?.(modelReflection.url) || modelReflection.url
})`
: getFormattedStr(modelReflection.name, false, escape)
)
} else {
reflection.push(
shouldShowLink
? model.externalUrl
? `[${model.name}]( ${model.externalUrl} )`
: model.name
: getFormattedStr(model.name, false, escape)
)
}
if (model.typeArguments && model.typeArguments.length > 0) {
reflection.push(
`${wrappedInBackticks ? "<" : getHTMLChar("<")}${model.typeArguments
.map((typeArgument) =>
getType({
reflectionType: typeArgument,
wrapBackticks: false,
hideLink,
escape: false,
getRelativeUrlMethod,
...options,
})
)
.join(", ")}${wrappedInBackticks ? ">" : getHTMLChar(">")}`
)
}
if (wrappedInBackticks) {
reflection.push("`")
}
return reflection.join("")
}
return shouldShowLink
? model.externalUrl
? `[${getFormattedStr(model.name, wrapBackticks, escape)}]( ${
model.externalUrl
} )`
: getFormattedStr(model.name, wrapBackticks, escape)
: getFormattedStr(model.name, wrapBackticks, escape)
}
export function getArrayType({
reflectionType: model,
hideLink = false,
...options
}: TypeOptions<ArrayType>): string {
const arrayType = getType({
reflectionType: model.elementType,
hideLink,
...options,
})
return model.elementType.type === "union"
? `(${arrayType})[]`
: `${arrayType}[]`
}
export function getUnionType({
reflectionType: model,
hideLink = false,
...options
}: TypeOptions<UnionType>): string {
return model.types
.map((unionType) =>
getType({
reflectionType: unionType,
hideLink,
...options,
})
)
.join(` \\| `)
}
export function getIntersectionType({
reflectionType: model,
hideLink = false,
...options
}: TypeOptions<IntersectionType>): string {
return model.types
.map((intersectionType) =>
getType({
reflectionType: intersectionType,
hideLink,
...options,
})
)
.join(" & ")
}
export function getTupleType({
reflectionType: model,
hideLink = false,
...options
}: TypeOptions<TupleType>): string {
return `[${model.elements
.map((element) =>
getType({
reflectionType: element,
hideLink,
...options,
})
)
.join(", ")}]`
}
export function getIntrinsicType({
reflectionType: model,
wrapBackticks = true,
escape,
}: TypeOptions<IntrinsicType>): string {
escape = getShouldEscape(wrapBackticks, escape)
return getFormattedStr(model.name, wrapBackticks, escape)
}
export function getTypeOperatorType({
reflectionType: model,
hideLink = false,
...options
}: TypeOptions<TypeOperatorType>): string {
return `${model.operator} ${getType({
reflectionType: model.target,
hideLink,
...options,
})}`
}
export function getQueryType({
reflectionType: model,
hideLink = false,
...options
}: TypeOptions<QueryType>): string {
return `typeof ${getType({
reflectionType: model.queryType,
hideLink,
...options,
})}`
}
export function getInferredType({
reflectionType: model,
escape,
}: TypeOptions<InferredType>): string {
escape = getShouldEscape(false, escape)
return `infer ${getFormattedStr(model.name, false, escape)}`
}
export function getUnknownType({
reflectionType: model,
escape,
}: TypeOptions<UnknownType>): string {
escape = getShouldEscape(false, escape)
return getFormattedStr(model.name, false, escape)
}
export function getConditionalType({
reflectionType: model,
hideLink = false,
...options
}: TypeOptions<ConditionalType>): string {
const md: string[] = []
if (model.checkType) {
md.push(
getType({
reflectionType: model.checkType,
hideLink,
...options,
})
)
}
md.push("extends")
if (model.extendsType) {
md.push(
getType({
reflectionType: model.extendsType,
hideLink,
...options,
})
)
}
md.push("?")
if (model.trueType) {
md.push(
getType({
reflectionType: model.trueType,
hideLink,
...options,
})
)
}
md.push(":")
if (model.falseType) {
md.push(
getType({
reflectionType: model.falseType,
hideLink,
...options,
})
)
}
return md.join(" ")
}
export function getIndexAccessType({
reflectionType: model,
hideLink = false,
...options
}: TypeOptions<IndexedAccessType>): string {
const md: string[] = []
if (model.objectType) {
md.push(
getType({
reflectionType: model.objectType,
hideLink,
...options,
})
)
}
if (model.indexType) {
md.push(
`[${getType({
reflectionType: model.indexType,
hideLink,
...options,
})}]`
)
}
return md.join("")
}
export function hasTypes(parameters: TypeParameterReflection[]) {
const types = (parameters as TypeParameterReflection[]).map(
(param) => !!param.type || !!param.default
)
return !types.every((value) => !value)
}
function getShouldEscape(wrapBackticks: boolean, escape?: boolean) {
return escape === undefined ? !wrapBackticks : escape
}
function getFormattedStr(
str: string,
wrapBackticks: boolean,
escape?: boolean
) {
return wrapBackticks ? `\`${str}\`` : escape ? escapeChars(str) : str
}
+5
View File
@@ -0,0 +1,5 @@
export * from "./get-type-children"
export * from "./get-project-child"
export * from "./get-type-str"
export * from "./str-formatting"
export * from "./str-utils"
@@ -0,0 +1,93 @@
export function kebabToSnake(str: string): string {
return str.replaceAll("-", "_")
}
export function capitalize(str: string): string {
return `${str.charAt(0).toUpperCase()}${str.substring(1).toLowerCase()}`
}
export function wordsToCamel(str: string): string {
return `${str.charAt(0).toLowerCase()}${str
.substring(1)
.replaceAll(/\s([a-zA-Z])/g, (captured) => captured.toUpperCase())}`
}
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()
}
export function snakeToWords(str: string): string {
return str.replaceAll("_", " ").toLowerCase()
}
export function kebabToTitle(str: string): string {
return str
.split("-")
.map((word) => capitalize(word))
.join(" ")
}
export function kebabToCamel(str: string): string {
return str
.split("-")
.map((word, index) => {
if (index === 0) {
return word
}
return `${word.charAt(0).toUpperCase()}${word.substring(1)}`
})
.join("")
}
export function kebabToPascal(str: string): string {
return str
.split("-")
.map((word) => capitalize(word))
.join("")
}
export function wordsToKebab(str: string): string {
return str
.split(" ")
.map((word) => word.toLowerCase())
.join("-")
}
export function wordsToPascal(str: string): string {
return str
.split(" ")
.map((word) => capitalize(word))
.join("")
}
export function pascalToCamel(str: string): string {
return `${str.charAt(0).toLowerCase()}${str.substring(1)}`
}
/**
* 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$/, "")
}
+23
View File
@@ -0,0 +1,23 @@
export function getHTMLChar(str: string) {
return str
.replace(/</g, "&#60;")
.replace(/{/g, "&#123;")
.replace(/}/g, "&#125;")
.replace(/>/g, "&#62;")
}
export function escapeChars(str: string, escapeBackticks = true) {
const result = getHTMLChar(str).replace(/_/g, "\\_").replace(/\|/g, "\\|")
return escapeBackticks ? result.replace(/`/g, "\\`") : result
}
export function stripLineBreaks(str: string) {
return str
? str
.replace(/\n/g, " ")
.replace(/\r/g, " ")
.replace(/\t/g, " ")
.replace(/[\s]{2,}/g, " ")
.trim()
: ""
}
+11
View File
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"esModuleInterop": true
},
"include": ["src"]
}