mirror of
https://github.com/modrinth/code.git
synced 2026-09-02 04:56:52 +00:00
checklist docs generator
This commit is contained in:
@@ -5,6 +5,9 @@ dist
|
|||||||
tmp
|
tmp
|
||||||
/out-tsc
|
/out-tsc
|
||||||
|
|
||||||
|
# generated checklist structure dump (packages/moderation/scripts/checklist-docs.ts)
|
||||||
|
.checklist-docs
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
"lint": "eslint . && prettier --check .",
|
"lint": "eslint . && prettier --check .",
|
||||||
"fix": "eslint . --fix && prettier --write .",
|
"fix": "eslint . --fix && prettier --write .",
|
||||||
"intl:extract": "formatjs extract \"**/*.{vue,ts,tsx,js,jsx,mts,cts,mjs,cjs}\" --ignore \"**/*.d.ts\" --ignore \"node_modules/**/*\" --out-file src/locales/en-US/index.json --preserve-whitespace",
|
"intl:extract": "formatjs extract \"**/*.{vue,ts,tsx,js,jsx,mts,cts,mjs,cjs}\" --ignore \"**/*.d.ts\" --ignore \"node_modules/**/*\" --out-file src/locales/en-US/index.json --preserve-whitespace",
|
||||||
"intl:prune-local": "pnpm -w scripts i18n-icu-contract prune-local --scope packages/moderation"
|
"intl:prune-local": "pnpm -w scripts i18n-icu-contract prune-local --scope packages/moderation",
|
||||||
|
"docs:dump": "pnpx tsx scripts/checklist-docs.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modrinth/assets": "workspace:*",
|
"@modrinth/assets": "workspace:*",
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
"@formatjs/cli": "^6.2.12",
|
"@formatjs/cli": "^6.2.12",
|
||||||
"@modrinth/tooling-config": "workspace:*",
|
"@modrinth/tooling-config": "workspace:*",
|
||||||
"@modrinth/ui": "workspace:*",
|
"@modrinth/ui": "workspace:*",
|
||||||
|
"ts-morph": "^24.0.0",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.4.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,338 @@
|
|||||||
|
|
||||||
|
import { existsSync, mkdirSync, writeFileSync } from 'node:fs'
|
||||||
|
import { dirname, join } from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
|
import type { CallExpression, Node, ReturnStatement } from 'ts-morph'
|
||||||
|
import { Project, SyntaxKind } from 'ts-morph'
|
||||||
|
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||||
|
const PACKAGE_ROOT = join(__dirname, '..')
|
||||||
|
const STAGES_GLOB = join(PACKAGE_ROOT, 'src/data/stages/*.tsx')
|
||||||
|
const OUT_DIR = join(PACKAGE_ROOT, '.checklist-docs')
|
||||||
|
|
||||||
|
const FACTORY_INPUT_TYPES: Record<string, string> = {
|
||||||
|
stage: 'Stage',
|
||||||
|
toggle: 'Toggle',
|
||||||
|
toggleSwitch: 'Switch',
|
||||||
|
check: 'Checkbox',
|
||||||
|
button: 'Button',
|
||||||
|
group: 'Group',
|
||||||
|
externalGroup: 'Group (no input, external state)',
|
||||||
|
option: 'Option',
|
||||||
|
dropdown: 'Dropdown',
|
||||||
|
text: 'Text Input',
|
||||||
|
markdown: 'Markdown Editor',
|
||||||
|
appComponent: 'Custom Component',
|
||||||
|
}
|
||||||
|
const FACTORY_NAMES = new Set(Object.keys(FACTORY_INPUT_TYPES))
|
||||||
|
|
||||||
|
interface NodeInfo {
|
||||||
|
type: string
|
||||||
|
id?: string
|
||||||
|
label?: string
|
||||||
|
shown?: string
|
||||||
|
suggestedStatus?: string
|
||||||
|
messagePath?: string
|
||||||
|
fix?: string
|
||||||
|
priority?: string
|
||||||
|
hint?: string
|
||||||
|
guidance?: string
|
||||||
|
navigate?: string
|
||||||
|
children: NodeInfo[]
|
||||||
|
}
|
||||||
|
|
||||||
|
function unwrapParens(node: Node): Node {
|
||||||
|
let current = node
|
||||||
|
while (current.getKind() === SyntaxKind.ParenthesizedExpression) {
|
||||||
|
current = (current as unknown as { getExpression(): Node }).getExpression()
|
||||||
|
}
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeCode(text: string): string {
|
||||||
|
return text.replace(/\s+/g, ' ').trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveRelativeMessagePath(name: string, statePath: string[]): string {
|
||||||
|
if (name.startsWith('/')) return `checklist/messages${name}`
|
||||||
|
const parts = [...statePath.slice(0, -1), ...name.split('/')]
|
||||||
|
const normalized = parts.reduce<string[]>((acc, p) => {
|
||||||
|
if (p === '..') acc.pop()
|
||||||
|
else if (p) acc.push(p)
|
||||||
|
return acc
|
||||||
|
}, [])
|
||||||
|
return `checklist/messages/${normalized.join('/')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoMessagePath(statePath: string[]): string {
|
||||||
|
return `checklist/messages/${statePath.join('/')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function literalText(arg: Node | undefined): string | undefined {
|
||||||
|
if (!arg) return undefined
|
||||||
|
if (arg.getKind() === SyntaxKind.StringLiteral || arg.getKind() === SyntaxKind.NoSubstitutionTemplateLiteral) {
|
||||||
|
return (arg as unknown as { getLiteralText(): string }).getLiteralText()
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
function findDocsComment(node: Node): string | undefined {
|
||||||
|
let current: Node | undefined = node
|
||||||
|
while (current) {
|
||||||
|
const ranges = current.getLeadingCommentRanges()
|
||||||
|
for (const range of ranges) {
|
||||||
|
const text = range.getText()
|
||||||
|
const match = text.match(/@docs\s+([\s\S]*?)(?:\*\/)?\s*$/)
|
||||||
|
if (match) {
|
||||||
|
return match[1]
|
||||||
|
.replace(/^\/\*+\s*|\s*\*+\/$/g, '')
|
||||||
|
.replace(/^\/\/\s*/g, '')
|
||||||
|
.trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const parent = current.getParent()
|
||||||
|
if (!parent || current.getKind() === SyntaxKind.ExpressionStatement) break
|
||||||
|
current = parent
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
function unwindChain(expr: CallExpression): { root: CallExpression | undefined; calls: CallExpression[] } {
|
||||||
|
const calls: CallExpression[] = []
|
||||||
|
let current: Node = expr
|
||||||
|
while (current.getKind() === SyntaxKind.CallExpression) {
|
||||||
|
const call = current as CallExpression
|
||||||
|
const callee = call.getExpression()
|
||||||
|
if (callee.getKind() === SyntaxKind.PropertyAccessExpression) {
|
||||||
|
calls.unshift(call)
|
||||||
|
current = (callee as unknown as { getExpression(): Node }).getExpression()
|
||||||
|
} else if (callee.getKind() === SyntaxKind.Identifier) {
|
||||||
|
return { root: call, calls }
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { root: undefined, calls }
|
||||||
|
}
|
||||||
|
|
||||||
|
const FUNCTION_LIKE_KINDS = new Set([
|
||||||
|
SyntaxKind.ArrowFunction,
|
||||||
|
SyntaxKind.FunctionExpression,
|
||||||
|
SyntaxKind.FunctionDeclaration,
|
||||||
|
SyntaxKind.MethodDeclaration,
|
||||||
|
])
|
||||||
|
|
||||||
|
function getOwnReturnStatements(fn: Node): ReturnStatement[] {
|
||||||
|
return fn.getDescendantsOfKind(SyntaxKind.ReturnStatement).filter((ret) => {
|
||||||
|
let current: Node | undefined = ret.getParent()
|
||||||
|
while (current && current !== fn) {
|
||||||
|
if (FUNCTION_LIKE_KINDS.has(current.getKind())) return false
|
||||||
|
current = current.getParent()
|
||||||
|
}
|
||||||
|
return current === fn
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveLocalHelperCall(call: CallExpression, path: string[]): NodeInfo | undefined {
|
||||||
|
const callee = call.getExpression()
|
||||||
|
if (callee.getKind() !== SyntaxKind.Identifier) return undefined
|
||||||
|
const name = callee.getText()
|
||||||
|
const sourceFile = call.getSourceFile()
|
||||||
|
const fn = sourceFile
|
||||||
|
.getDescendantsOfKind(SyntaxKind.FunctionDeclaration)
|
||||||
|
.find((f) => f.getName() === name)
|
||||||
|
if (!fn) return { type: 'UNRESOLVED', children: [] }
|
||||||
|
const returnStatements = getOwnReturnStatements(fn)
|
||||||
|
for (const ret of returnStatements) {
|
||||||
|
const returnExpr = ret.getExpression() ? unwrapParens(ret.getExpression()!) : undefined
|
||||||
|
if (returnExpr && returnExpr.getKind() === SyntaxKind.CallExpression) {
|
||||||
|
const resolved = resolveNode(returnExpr as CallExpression, path)
|
||||||
|
if (resolved) return resolved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { type: 'UNRESOLVED', children: [] }
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveChildEntry(rawArg: Node, path: string[]): NodeInfo[] {
|
||||||
|
const arg = unwrapParens(rawArg)
|
||||||
|
if (arg.getKind() === SyntaxKind.CallExpression) {
|
||||||
|
const call = arg as CallExpression
|
||||||
|
const callee = call.getExpression()
|
||||||
|
if (callee.getKind() === SyntaxKind.Identifier && !FACTORY_NAMES.has(callee.getText())) {
|
||||||
|
const calleeName = callee.getText()
|
||||||
|
if (calleeName === 'computed' || calleeName === 'ref') {
|
||||||
|
const docs = findDocsComment(call)
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: docs ? `Dynamic children: ${docs}` : 'UNRESOLVED',
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
return [resolveLocalHelperCall(call, path)!]
|
||||||
|
}
|
||||||
|
const resolved = resolveNode(call, path)
|
||||||
|
return [resolved ?? { type: 'UNRESOLVED', children: [] }]
|
||||||
|
}
|
||||||
|
if (arg.getKind() === SyntaxKind.SpreadElement) {
|
||||||
|
const spreadArg = (arg as unknown as { getExpression(): Node }).getExpression()
|
||||||
|
return resolveChildEntry(spreadArg, path)
|
||||||
|
}
|
||||||
|
if (arg.getKind() === SyntaxKind.ArrayLiteralExpression) {
|
||||||
|
return arg
|
||||||
|
.getChildrenOfKind(SyntaxKind.SyntaxList)
|
||||||
|
.flatMap((list) => list.getChildren().flatMap((c) => resolveChildEntry(c, path)))
|
||||||
|
}
|
||||||
|
if (arg.getKind() === SyntaxKind.ArrowFunction || arg.getKind() === SyntaxKind.FunctionExpression) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
if (arg.getKind() === SyntaxKind.StringLiteral) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return [{ type: 'UNRESOLVED', children: [] }]
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveNode(expr: CallExpression, path: string[]): NodeInfo | undefined {
|
||||||
|
const { root, calls } = unwindChain(expr)
|
||||||
|
if (!root) return undefined
|
||||||
|
const factoryName = root.getExpression().getText()
|
||||||
|
const type = FACTORY_INPUT_TYPES[factoryName]
|
||||||
|
if (!type) return undefined
|
||||||
|
|
||||||
|
const rootArgs = root.getArguments()
|
||||||
|
const info: NodeInfo = {
|
||||||
|
type,
|
||||||
|
id: literalText(rootArgs[0]),
|
||||||
|
label: literalText(rootArgs[1]),
|
||||||
|
children: [],
|
||||||
|
}
|
||||||
|
const nodePath = info.id ? [...path, info.id] : path
|
||||||
|
|
||||||
|
for (const call of calls) {
|
||||||
|
const callee = call.getExpression()
|
||||||
|
if (callee.getKind() !== SyntaxKind.PropertyAccessExpression) continue
|
||||||
|
const methodName = (callee as unknown as { getName(): string }).getName()
|
||||||
|
const args = call.getArguments()
|
||||||
|
|
||||||
|
switch (methodName) {
|
||||||
|
case 'shown':
|
||||||
|
info.shown = findDocsComment(call) ?? (args[0] ? normalizeCode(args[0].getText()) : undefined)
|
||||||
|
break
|
||||||
|
case 'suggestedStatus':
|
||||||
|
info.suggestedStatus = literalText(args[0])
|
||||||
|
break
|
||||||
|
case 'message': {
|
||||||
|
const arg0 = args[0]
|
||||||
|
const literal = literalText(arg0)
|
||||||
|
if (literal !== undefined) {
|
||||||
|
info.messagePath = resolveRelativeMessagePath(literal, nodePath)
|
||||||
|
} else if (
|
||||||
|
arg0 &&
|
||||||
|
(arg0.getKind() === SyntaxKind.ArrowFunction ||
|
||||||
|
arg0.getKind() === SyntaxKind.FunctionExpression)
|
||||||
|
) {
|
||||||
|
const paramCount = (
|
||||||
|
arg0 as unknown as { getParameters(): unknown[] }
|
||||||
|
).getParameters().length
|
||||||
|
info.messagePath =
|
||||||
|
paramCount >= 1 ? autoMessagePath(nodePath) : normalizeCode(arg0.getText())
|
||||||
|
} else if (arg0) {
|
||||||
|
info.messagePath = normalizeCode(arg0.getText())
|
||||||
|
} else {
|
||||||
|
info.messagePath = autoMessagePath(nodePath)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'fix':
|
||||||
|
info.fix = findDocsComment(call) ?? (args[0] ? normalizeCode(args[0].getText()) : 'UNRESOLVED')
|
||||||
|
break
|
||||||
|
case 'priority':
|
||||||
|
info.priority = args[0] ? normalizeCode(args[0].getText()) : undefined
|
||||||
|
break
|
||||||
|
case 'hint':
|
||||||
|
info.hint = literalText(args[0])
|
||||||
|
break
|
||||||
|
case 'guidance':
|
||||||
|
info.guidance = literalText(args[0])
|
||||||
|
break
|
||||||
|
case 'navigate':
|
||||||
|
info.navigate = literalText(args[0])
|
||||||
|
break
|
||||||
|
case 'children':
|
||||||
|
for (const arg of args) {
|
||||||
|
info.children.push(...resolveChildEntry(arg, nodePath))
|
||||||
|
}
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
|
function pruneForJson(node: NodeInfo): Record<string, unknown> {
|
||||||
|
const out: Record<string, unknown> = { type: node.type }
|
||||||
|
if (node.id) out.id = node.id
|
||||||
|
if (node.label) out.label = node.label
|
||||||
|
if (node.shown) out.shown = node.shown
|
||||||
|
if (node.fix) out.fix = node.fix
|
||||||
|
if (node.suggestedStatus) out.suggestedStatus = node.suggestedStatus
|
||||||
|
if (node.messagePath) out.messagePath = node.messagePath
|
||||||
|
if (node.priority) out.priority = node.priority
|
||||||
|
if (node.hint) out.hint = node.hint
|
||||||
|
if (node.guidance) out.guidance = node.guidance
|
||||||
|
if (node.navigate) out.navigate = node.navigate
|
||||||
|
if (node.children.length > 0) out.children = node.children.map(pruneForJson)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const project = new Project({
|
||||||
|
tsConfigFilePath: join(PACKAGE_ROOT, 'tsconfig.json'),
|
||||||
|
})
|
||||||
|
project.addSourceFilesAtPaths(STAGES_GLOB)
|
||||||
|
|
||||||
|
const jsonOutput: Record<string, NodeInfo | undefined> = {}
|
||||||
|
|
||||||
|
for (const sourceFile of project.getSourceFiles(STAGES_GLOB)) {
|
||||||
|
const stageFileName = sourceFile.getBaseNameWithoutExtension()
|
||||||
|
const defaultExport =
|
||||||
|
sourceFile.getFunction((f) => f.isDefaultExport()) ??
|
||||||
|
sourceFile.getExportAssignments()[0]?.getExpression()
|
||||||
|
|
||||||
|
let returnExpr: Node | undefined
|
||||||
|
if (defaultExport && 'getDescendantsOfKind' in defaultExport) {
|
||||||
|
const returnStatements = getOwnReturnStatements(defaultExport as unknown as Node)
|
||||||
|
const lastReturnExpr = returnStatements[returnStatements.length - 1]?.getExpression()
|
||||||
|
returnExpr = lastReturnExpr ? unwrapParens(lastReturnExpr) : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!returnExpr || returnExpr.getKind() !== SyntaxKind.CallExpression) {
|
||||||
|
console.warn(`[skip] ${stageFileName}: could not find a default-export stage() call`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const stageNode = resolveNode(returnExpr as CallExpression, [])
|
||||||
|
if (!stageNode) {
|
||||||
|
console.warn(`[skip] ${stageFileName}: default export didn't resolve to a stage() chain`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonOutput[stageFileName] = stageNode
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existsSync(OUT_DIR)) mkdirSync(OUT_DIR, { recursive: true })
|
||||||
|
|
||||||
|
const prunedJsonOutput = Object.fromEntries(
|
||||||
|
Object.entries(jsonOutput).map(([key, node]) => [key, node ? pruneForJson(node) : node]),
|
||||||
|
)
|
||||||
|
const jsonPath = join(OUT_DIR, 'checklist-structure.json')
|
||||||
|
writeFileSync(jsonPath, JSON.stringify(prunedJsonOutput, null, 2))
|
||||||
|
|
||||||
|
console.log(`Wrote ${Object.keys(jsonOutput).length} stages to:`)
|
||||||
|
console.log(` ${jsonPath}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
Generated
+26
-1
@@ -570,6 +570,9 @@ importers:
|
|||||||
'@modrinth/ui':
|
'@modrinth/ui':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../ui
|
version: link:../ui
|
||||||
|
ts-morph:
|
||||||
|
specifier: ^24.0.0
|
||||||
|
version: 24.0.0
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.4.5
|
specifier: ^5.4.5
|
||||||
version: 5.9.3
|
version: 5.9.3
|
||||||
@@ -4558,6 +4561,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
|
|
||||||
|
'@ts-morph/common@0.25.0':
|
||||||
|
resolution: {integrity: sha512-kMnZz+vGGHi4GoHnLmMhGNjm44kGtKUXGnOvrKmMwAuvNjM/PgKVGfUnL7IDvK7Jb2QQ82jq3Zmp04Gy+r3Dkg==}
|
||||||
|
|
||||||
'@tweenjs/tween.js@23.1.3':
|
'@tweenjs/tween.js@23.1.3':
|
||||||
resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==}
|
resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==}
|
||||||
|
|
||||||
@@ -5710,6 +5716,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
|
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
code-block-writer@13.0.3:
|
||||||
|
resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==}
|
||||||
|
|
||||||
collapse-white-space@2.1.0:
|
collapse-white-space@2.1.0:
|
||||||
resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
|
resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
|
||||||
|
|
||||||
@@ -9506,6 +9515,9 @@ packages:
|
|||||||
ts-map@1.0.3:
|
ts-map@1.0.3:
|
||||||
resolution: {integrity: sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w==}
|
resolution: {integrity: sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w==}
|
||||||
|
|
||||||
|
ts-morph@24.0.0:
|
||||||
|
resolution: {integrity: sha512-2OAOg/Ob5yx9Et7ZX4CvTCc0UFoZHwLEJ+dpDPSUi5TgwwlTlX47w+iFRrEwzUZwYACjq83cgjS/Da50Ga37uw==}
|
||||||
|
|
||||||
tsconfck@3.1.6:
|
tsconfck@3.1.6:
|
||||||
resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==}
|
resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==}
|
||||||
engines: {node: ^18 || >=20}
|
engines: {node: ^18 || >=20}
|
||||||
@@ -14095,6 +14107,12 @@ snapshots:
|
|||||||
|
|
||||||
'@trysound/sax@0.2.0': {}
|
'@trysound/sax@0.2.0': {}
|
||||||
|
|
||||||
|
'@ts-morph/common@0.25.0':
|
||||||
|
dependencies:
|
||||||
|
minimatch: 9.0.5
|
||||||
|
path-browserify: 1.0.1
|
||||||
|
tinyglobby: 0.2.15
|
||||||
|
|
||||||
'@tweenjs/tween.js@23.1.3': {}
|
'@tweenjs/tween.js@23.1.3': {}
|
||||||
|
|
||||||
'@tybys/wasm-util@0.10.1':
|
'@tybys/wasm-util@0.10.1':
|
||||||
@@ -15507,6 +15525,8 @@ snapshots:
|
|||||||
|
|
||||||
cluster-key-slot@1.1.2: {}
|
cluster-key-slot@1.1.2: {}
|
||||||
|
|
||||||
|
code-block-writer@13.0.3: {}
|
||||||
|
|
||||||
collapse-white-space@2.1.0: {}
|
collapse-white-space@2.1.0: {}
|
||||||
|
|
||||||
color-convert@2.0.1:
|
color-convert@2.0.1:
|
||||||
@@ -16654,7 +16674,7 @@ snapshots:
|
|||||||
|
|
||||||
glob@13.0.1:
|
glob@13.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
minimatch: 10.1.2
|
minimatch: 10.2.3
|
||||||
minipass: 7.1.2
|
minipass: 7.1.2
|
||||||
path-scurry: 2.0.1
|
path-scurry: 2.0.1
|
||||||
|
|
||||||
@@ -20248,6 +20268,11 @@ snapshots:
|
|||||||
|
|
||||||
ts-map@1.0.3: {}
|
ts-map@1.0.3: {}
|
||||||
|
|
||||||
|
ts-morph@24.0.0:
|
||||||
|
dependencies:
|
||||||
|
'@ts-morph/common': 0.25.0
|
||||||
|
code-block-writer: 13.0.3
|
||||||
|
|
||||||
tsconfck@3.1.6(typescript@5.9.3):
|
tsconfck@3.1.6(typescript@5.9.3):
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
|
|||||||
Reference in New Issue
Block a user