@metamask-previews/messenger-cli 0.1.0-preview-8f51c7a3a → 0.1.0-preview-2a71f636e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,24 +24,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.extractFromFile = void 0;
27
+ const node_1 = require("@metamask/utils/node");
27
28
  const fs = __importStar(require("node:fs/promises"));
28
29
  const path = __importStar(require("node:path"));
29
30
  const typescript_1 = require("typescript");
30
- /**
31
- * Check whether a file exists.
32
- *
33
- * @param filePath - The path to check.
34
- * @returns A promise that resolves to true if the file exists.
35
- */
36
- async function fileExists(filePath) {
37
- try {
38
- await fs.access(filePath);
39
- return true;
40
- }
41
- catch {
42
- return false;
43
- }
44
- }
45
31
  /**
46
32
  * Extract string constants from top-level variable declarations in a source file.
47
33
  * Only looks at top-level `const x = 'string'` or `const x = 'string' as const`.
@@ -114,7 +100,7 @@ async function resolveControllerName(sourceFile, filePath) {
114
100
  ]
115
101
  : [path.join(dir, `${spec}.ts`), path.join(dir, spec, 'index.ts')];
116
102
  for (const candidate of candidates) {
117
- if (!(await fileExists(candidate))) {
103
+ if (!(await (0, node_1.fileExists)(candidate))) {
118
104
  continue;
119
105
  }
120
106
  const content = await fs.readFile(candidate, 'utf8');
@@ -229,6 +215,23 @@ function extractJsDocText(node, sourceFile) {
229
215
  }
230
216
  const fullText = sourceFile.getFullText();
231
217
  const raw = fullText.substring(jsDoc.getFullStart(), jsDoc.getEnd()).trim();
218
+ // Handle single-line JSDoc: /** Gets the current state. */
219
+ const singleLineMatch = raw.match(/^\/\*\*\s*(.*?)\s*\*\/$/u);
220
+ if (singleLineMatch) {
221
+ let text = singleLineMatch[1].replace(/^\*\s*/u, '');
222
+ // Apply same escaping as multi-line path
223
+ text = text.replace(/\{@link\s+([^}]+)\}/gu, '`$1`');
224
+ text = text.replace(/`[^`]*`|(\{)|(\})/gu, (match, open, close) => {
225
+ if (open) {
226
+ return '\\{';
227
+ }
228
+ if (close) {
229
+ return '\\}';
230
+ }
231
+ return match;
232
+ });
233
+ return text || '';
234
+ }
232
235
  // Strip comment delimiters, leading asterisks, and @param/@returns/@see tags
233
236
  const lines = raw.split('\n');
234
237
  const cleaned = [];
@@ -1 +1 @@
1
- {"version":3,"file":"extraction.cjs","sourceRoot":"","sources":["../../src/docs/extraction.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport {\n createSourceFile,\n getJSDocCommentsAndTags,\n getJSDocTags,\n isAsExpression,\n isClassDeclaration,\n isIdentifier,\n isImportDeclaration,\n isInterfaceDeclaration,\n isJSDoc,\n isLiteralTypeNode,\n isMethodDeclaration,\n isNamedImports,\n isNoSubstitutionTemplateLiteral,\n isPropertySignature,\n isStringLiteral,\n isTemplateExpression,\n isTemplateLiteralTypeNode,\n isTypeAliasDeclaration,\n isTypeLiteralNode,\n isTypeOfExpression,\n isTypeQueryNode,\n isTypeReferenceNode,\n isVariableStatement,\n ScriptTarget,\n} from 'typescript';\nimport type {\n Expression,\n InterfaceDeclaration,\n Node as TsNode,\n NodeArray,\n SourceFile,\n TemplateLiteralTypeNode as TemplateLiteralType,\n TypeAliasDeclaration,\n TypeElement,\n} from 'typescript';\n\nimport type { MessengerItemDoc, MethodInfo } from './types';\n\n/**\n * Check whether a file exists.\n *\n * @param filePath - The path to check.\n * @returns A promise that resolves to true if the file exists.\n */\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Extract string constants from top-level variable declarations in a source file.\n * Only looks at top-level `const x = 'string'` or `const x = 'string' as const`.\n *\n * @param sourceFile - The TypeScript source file to extract constants from.\n * @returns A map of constant name to string value.\n */\nfunction extractStringConstants(sourceFile: SourceFile): Map<string, string> {\n const names = new Map<string, string>();\n\n for (const statement of sourceFile.statements) {\n if (!isVariableStatement(statement)) {\n continue;\n }\n for (const decl of statement.declarationList.declarations) {\n if (!isIdentifier(decl.name)) {\n continue;\n }\n\n if (decl.initializer) {\n const init = decl.initializer;\n if (isStringLiteral(init)) {\n names.set(decl.name.text, init.text);\n } else if (isAsExpression(init) && isStringLiteral(init.expression)) {\n names.set(decl.name.text, init.expression.text);\n }\n }\n\n // Handle `declare const x: \"value\"` (common in .d.cts files)\n if (\n !decl.initializer &&\n decl.type &&\n isLiteralTypeNode(decl.type) &&\n isStringLiteral(decl.type.literal)\n ) {\n names.set(decl.name.text, decl.type.literal.text);\n }\n }\n }\n\n return names;\n}\n\n/**\n * Resolve the value of `controllerName` (or similar constant) defined in the\n * same file or imported from a local `./constants*` module (single-hop only).\n *\n * @param sourceFile - The TypeScript source file to search.\n * @param filePath - The absolute path of the source file on disk.\n * @returns A promise that resolves to a map of constant name to resolved string value.\n */\nasync function resolveControllerName(\n sourceFile: SourceFile,\n filePath: string,\n): Promise<Map<string, string>> {\n const names = extractStringConstants(sourceFile);\n\n // Chase single-hop local imports (no further recursion):\n // import { BRIDGE_CONTROLLER_NAME } from './constants/bridge';\n for (const statement of sourceFile.statements) {\n if (\n !isImportDeclaration(statement) ||\n !statement.moduleSpecifier ||\n !isStringLiteral(statement.moduleSpecifier)\n ) {\n continue;\n }\n\n const spec = statement.moduleSpecifier.text;\n if (!spec.startsWith('.')) {\n continue;\n }\n\n const dir = path.dirname(filePath);\n const isDts = filePath.endsWith('.d.cts') || filePath.endsWith('.d.ts');\n // Strip .cjs/.js extension from specifier for .d.cts resolution\n const bareSpec = spec.replace(/\\.(c|m)?js$/u, '');\n const candidates = isDts\n ? [\n path.join(dir, `${bareSpec}.d.cts`),\n path.join(dir, bareSpec, 'index.d.cts'),\n path.join(dir, `${bareSpec}.d.ts`),\n path.join(dir, bareSpec, 'index.d.ts'),\n ]\n : [path.join(dir, `${spec}.ts`), path.join(dir, spec, 'index.ts')];\n\n for (const candidate of candidates) {\n if (!(await fileExists(candidate))) {\n continue;\n }\n\n const content = await fs.readFile(candidate, 'utf8');\n const sf = createSourceFile(\n candidate,\n content,\n ScriptTarget.Latest,\n true,\n );\n // Only extract constants — do NOT follow further imports\n const imported = extractStringConstants(sf);\n\n if (\n statement.importClause?.namedBindings &&\n isNamedImports(statement.importClause.namedBindings)\n ) {\n for (const element of statement.importClause.namedBindings.elements) {\n const importedName = (element.propertyName ?? element.name).text;\n const localName = element.name.text;\n const value = imported.get(importedName);\n if (value !== undefined) {\n names.set(localName, value);\n }\n }\n }\n break;\n }\n }\n\n return names;\n}\n\n/**\n * Resolve a template-literal or string-literal `type` property to its string\n * value. Returns null if unresolvable.\n *\n * @param node - The expression node to resolve.\n * @param constants - A map of known constant names to their string values.\n * @returns The resolved string value, or null if unresolvable.\n */\nfunction resolveTypeString(\n node: Expression,\n constants: Map<string, string>,\n): string | null {\n if (isStringLiteral(node) || isNoSubstitutionTemplateLiteral(node)) {\n return node.text;\n }\n\n if (isTemplateExpression(node)) {\n let result = node.head.text;\n for (const span of node.templateSpans) {\n // typeof X → resolve X\n if (isTypeOfExpression(span.expression)) {\n if (isIdentifier(span.expression.expression)) {\n const val = constants.get(span.expression.expression.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else {\n return null;\n }\n } else if (isIdentifier(span.expression)) {\n const val = constants.get(span.expression.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else {\n return null;\n }\n result += span.literal.text;\n }\n return result;\n }\n\n return null;\n}\n\n/**\n * Resolve a TemplateLiteralTypeNode (used in type positions like\n * `type: \\`${typeof controllerName}:name\\``) to its string value.\n *\n * @param node - The template literal type node to resolve.\n * @param constants - A map of known constant names to their string values.\n * @returns The resolved string value, or null if unresolvable.\n */\nfunction resolveTemplateLiteralType(\n node: TemplateLiteralType,\n constants: Map<string, string>,\n): string | null {\n let result = node.head.text;\n\n for (const span of node.templateSpans) {\n // In type position, `typeof X` is a TypeQueryNode\n if (isTypeQueryNode(span.type) && isIdentifier(span.type.exprName)) {\n const val = constants.get(span.type.exprName.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else if (\n isLiteralTypeNode(span.type) &&\n isStringLiteral(span.type.literal)\n ) {\n result += span.type.literal.text;\n } else {\n return null;\n }\n result += span.literal.text;\n }\n\n return result;\n}\n\n/**\n * Extract cleaned JSDoc body text from a node.\n *\n * @param node - The AST node to extract JSDoc from.\n * @param sourceFile - The source file containing the node.\n * @returns The cleaned JSDoc text, or empty string if none.\n */\nfunction extractJsDocText(node: TsNode, sourceFile: SourceFile): string {\n const jsDocs = getJSDocCommentsAndTags(node);\n if (jsDocs.length === 0) {\n return '';\n }\n\n const jsDoc = jsDocs[0];\n if (!isJSDoc(jsDoc)) {\n return '';\n }\n\n const fullText = sourceFile.getFullText();\n const raw = fullText.substring(jsDoc.getFullStart(), jsDoc.getEnd()).trim();\n\n // Strip comment delimiters, leading asterisks, and @param/@returns/@see tags\n const lines = raw.split('\\n');\n const cleaned: string[] = [];\n const skippedTags = [\n '@param',\n '@returns',\n '@see',\n '@throws',\n '@template',\n '@example',\n ];\n let currentTag: 'skip' | 'deprecated' | null = null;\n let deprecatedParts: string[] = [];\n\n for (const rawLine of lines) {\n let trimmed = rawLine.trim();\n if (trimmed === '/**' || trimmed === '*/') {\n continue;\n }\n if (trimmed.startsWith('* ')) {\n trimmed = trimmed.slice(2);\n } else if (trimmed === '*') {\n trimmed = '';\n } else if (trimmed.startsWith('*')) {\n trimmed = trimmed.slice(1);\n }\n\n // Check if this line starts a new tag\n if (trimmed.startsWith('@')) {\n // Flush any accumulated deprecated text\n if (currentTag === 'deprecated' && deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n deprecatedParts = [];\n }\n\n if (trimmed.startsWith('@deprecated')) {\n currentTag = 'deprecated';\n const depText = trimmed.slice('@deprecated'.length).trim();\n if (depText) {\n deprecatedParts.push(depText);\n }\n continue;\n }\n\n currentTag = skippedTags.some((tag) => trimmed.startsWith(tag))\n ? 'skip'\n : null;\n if (currentTag === 'skip') {\n continue;\n }\n } else if (currentTag === 'skip') {\n if (trimmed === '') {\n currentTag = null;\n } else {\n continue;\n }\n } else if (currentTag === 'deprecated') {\n if (trimmed === '') {\n // End of deprecated tag\n if (deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n deprecatedParts = [];\n }\n currentTag = null;\n } else {\n deprecatedParts.push(trimmed);\n continue;\n }\n }\n\n cleaned.push(trimmed);\n }\n\n // Flush any remaining deprecated text\n if (deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n }\n\n let result = cleaned.join('\\n').trim();\n\n // Convert JSDoc {@link X} references to markdown backtick code\n result = result.replace(/\\{@link\\s+([^}]+)\\}/gu, '`$1`');\n\n // Escape remaining curly braces for MDX safety (but not inside backtick code spans)\n result = result.replace(/`[^`]*`|(\\{)|(\\})/gu, (match, open, close) => {\n if (open) {\n return '\\\\{';\n }\n if (close) {\n return '\\\\}';\n }\n return match; // preserve content inside backticks\n });\n\n return result;\n}\n\n/**\n * Check whether a node has an `@deprecated` JSDoc tag.\n *\n * @param node - The AST node to check.\n * @returns True if the node has an `@deprecated` tag.\n */\nfunction isDeprecated(node: TsNode): boolean {\n const tags = getJSDocTags(node);\n return tags.some((tag) => tag.tagName.text === 'deprecated');\n}\n\n/**\n * Collect method info from all class declarations in a source file.\n * Returns a map keyed by \"ClassName.methodName\".\n *\n * @param sourceFile - The TypeScript source file to scan.\n * @returns A map of \"ClassName.methodName\" to method info.\n */\nfunction collectClassMethods(sourceFile: SourceFile): Map<string, MethodInfo> {\n const methods = new Map<string, MethodInfo>();\n\n for (const statement of sourceFile.statements) {\n if (!isClassDeclaration(statement) || !statement.name) {\n continue;\n }\n\n const className = statement.name.text;\n\n for (const member of statement.members) {\n if (\n !isMethodDeclaration(member) ||\n !member.name ||\n !isIdentifier(member.name)\n ) {\n continue;\n }\n\n const methodName = member.name.text;\n\n // Build parameter list\n const params = member.parameters\n .map((param) => {\n const paramName = param.name.getText(sourceFile);\n const optional = param.questionToken ? '?' : '';\n const paramType = param.type\n ? param.type.getText(sourceFile)\n : 'unknown';\n return `${paramName}${optional}: ${paramType}`;\n })\n .join(', ');\n\n // Get return type\n const returnType = member.type ? member.type.getText(sourceFile) : 'void';\n\n // For async methods, the declared return type already includes Promise<>,\n // so we don't need to wrap again.\n const methodSignature = `(${params}) => ${returnType}`;\n\n const jsDoc = extractJsDocText(member, sourceFile);\n\n methods.set(`${className}.${methodName}`, {\n jsDoc,\n signature: methodSignature,\n });\n }\n }\n\n return methods;\n}\n\n/**\n * If `handlerText` matches `ClassName['methodName']`, look it up in classMethodInfo\n * and return the resolved signature. Otherwise return the original text.\n *\n * @param handlerText - The raw handler text to resolve.\n * @param classMethods - A map of class methods collected from the source file.\n * @returns An object with the resolved signature and any associated JSDoc.\n */\nfunction resolveHandler(\n handlerText: string,\n classMethods: Map<string, MethodInfo>,\n): { signature: string; methodJsDoc: string } {\n const match = handlerText.match(/^(\\w+)\\['(\\w+)'\\]$/u);\n if (match) {\n const key = `${match[1]}.${match[2]}`;\n const info = classMethods.get(key);\n if (info) {\n return { signature: info.signature, methodJsDoc: info.jsDoc };\n }\n }\n return { signature: handlerText, methodJsDoc: '' };\n}\n\n/**\n * Get the raw source text for a property value inside a type literal.\n *\n * @param members - The type literal members to search.\n * @param propName - The property name to find.\n * @param sourceFile - The source file for getText calls.\n * @returns The raw text of the property type, or empty string if not found.\n */\nfunction getPropertyText(\n members: NodeArray<TypeElement>,\n propName: string,\n sourceFile: SourceFile,\n): string {\n for (const member of members) {\n if (\n isPropertySignature(member) &&\n member.name &&\n isIdentifier(member.name) &&\n member.name.text === propName &&\n member.type\n ) {\n return member.type.getText(sourceFile).trim();\n }\n }\n return '';\n}\n\n// ---------------------------------------------------------------------------\n// Main extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Extract messenger action/event type definitions from a single TypeScript file.\n *\n * @param filePath - The absolute path to the TypeScript file.\n * @param relBase - Base path for computing relative source paths.\n * @returns A promise that resolves to an array of extracted messenger item docs.\n */\nexport async function extractFromFile(\n filePath: string,\n relBase: string,\n): Promise<MessengerItemDoc[]> {\n const content = await fs.readFile(filePath, 'utf8');\n const sourceFile = createSourceFile(\n filePath,\n content,\n ScriptTarget.Latest,\n true,\n );\n\n const constants = await resolveControllerName(sourceFile, filePath);\n const classMethods = collectClassMethods(sourceFile);\n const items: MessengerItemDoc[] = [];\n const relPath = path.relative(relBase, filePath);\n\n // Type aliases and interfaces are always top-level statements\n for (const statement of sourceFile.statements) {\n // ---------------------------------------------------------------\n // Pattern 1: { type: '...'; handler/payload: ... }\n // Matches both:\n // type X = { type: '...'; handler: ... } (type alias with literal body)\n // interface X { type: '...'; handler: ... } (interface declaration)\n // ---------------------------------------------------------------\n let inlineNode: TypeAliasDeclaration | InterfaceDeclaration | undefined;\n let inlineMembers: NodeArray<TypeElement> | undefined;\n\n if (\n isTypeAliasDeclaration(statement) &&\n isTypeLiteralNode(statement.type)\n ) {\n inlineNode = statement;\n inlineMembers = statement.type.members;\n } else if (isInterfaceDeclaration(statement)) {\n inlineNode = statement;\n inlineMembers = statement.members;\n }\n\n if (inlineNode && inlineMembers) {\n const typeName = inlineNode.name.text;\n const line =\n sourceFile.getLineAndCharacterOfPosition(inlineNode.getStart()).line +\n 1;\n\n // Find `type` property\n let typeString: string | null = null;\n for (const member of inlineMembers) {\n if (\n isPropertySignature(member) &&\n member.name &&\n isIdentifier(member.name) &&\n member.name.text === 'type' &&\n member.type\n ) {\n if (isLiteralTypeNode(member.type)) {\n typeString = resolveTypeString(member.type.literal, constants);\n } else if (isTemplateLiteralTypeNode(member.type)) {\n typeString = resolveTemplateLiteralType(member.type, constants);\n }\n }\n }\n\n if (typeString?.includes(':')) {\n const handlerText = getPropertyText(\n inlineMembers,\n 'handler',\n sourceFile,\n );\n const payloadText = getPropertyText(\n inlineMembers,\n 'payload',\n sourceFile,\n );\n\n if (handlerText || payloadText) {\n const kind: 'action' | 'event' = handlerText ? 'action' : 'event';\n\n // For actions, resolve ClassName['methodName'] to actual signature + JSDoc\n let resolvedHandler = handlerText || payloadText;\n let typeAliasJsDoc = extractJsDocText(inlineNode, sourceFile);\n\n if (handlerText) {\n const resolved = resolveHandler(handlerText, classMethods);\n resolvedHandler = resolved.signature;\n // If the type alias has no JSDoc, use the method's JSDoc\n if (!typeAliasJsDoc && resolved.methodJsDoc) {\n typeAliasJsDoc = resolved.methodJsDoc;\n }\n }\n\n items.push({\n typeName,\n typeString,\n kind,\n jsDoc: typeAliasJsDoc,\n handlerOrPayload: resolvedHandler,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(inlineNode),\n });\n }\n }\n }\n\n // -------------------------------------------------------------------\n // Patterns 2 & 3 only apply to type aliases (generic type references)\n // -------------------------------------------------------------------\n if (!isTypeAliasDeclaration(statement)) {\n continue;\n }\n const node = statement;\n const typeName = node.name.text;\n const line =\n sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;\n\n // -------------------------------------------------------------------\n // Pattern 2: ControllerGetStateAction<typeof cn, State>\n // -------------------------------------------------------------------\n if (\n isTypeReferenceNode(node.type) &&\n isIdentifier(node.type.typeName) &&\n node.type.typeName.text === 'ControllerGetStateAction' &&\n node.type.typeArguments &&\n node.type.typeArguments.length >= 2\n ) {\n const firstArg = node.type.typeArguments[0];\n const stateArg = node.type.typeArguments[1];\n let namespace: string | null = null;\n\n if (isTypeQueryNode(firstArg) && isIdentifier(firstArg.exprName)) {\n namespace = constants.get(firstArg.exprName.text) ?? null;\n }\n if (isLiteralTypeNode(firstArg) && isStringLiteral(firstArg.literal)) {\n namespace = firstArg.literal.text;\n }\n\n if (namespace) {\n items.push({\n typeName,\n typeString: `${namespace}:getState`,\n kind: 'action',\n jsDoc: extractJsDocText(node, sourceFile),\n handlerOrPayload: `() => ${stateArg.getText(sourceFile)}`,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(node),\n });\n }\n }\n\n // -------------------------------------------------------------------\n // Pattern 3: ControllerStateChangeEvent<typeof cn, State>\n // -------------------------------------------------------------------\n if (\n isTypeReferenceNode(node.type) &&\n isIdentifier(node.type.typeName) &&\n node.type.typeName.text === 'ControllerStateChangeEvent' &&\n node.type.typeArguments &&\n node.type.typeArguments.length >= 2\n ) {\n const firstArg = node.type.typeArguments[0];\n const stateArg = node.type.typeArguments[1];\n let namespace: string | null = null;\n\n if (isTypeQueryNode(firstArg) && isIdentifier(firstArg.exprName)) {\n namespace = constants.get(firstArg.exprName.text) ?? null;\n }\n if (isLiteralTypeNode(firstArg) && isStringLiteral(firstArg.literal)) {\n namespace = firstArg.literal.text;\n }\n\n if (namespace) {\n items.push({\n typeName,\n typeString: `${namespace}:stateChange`,\n kind: 'event',\n jsDoc: extractJsDocText(node, sourceFile),\n handlerOrPayload: `[${stateArg.getText(sourceFile)}, Patch[]]`,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(node),\n });\n }\n }\n }\n\n return items;\n}\n"]}
1
+ {"version":3,"file":"extraction.cjs","sourceRoot":"","sources":["../../src/docs/extraction.ts"],"names":[],"mappings":"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","sourcesContent":["import { fileExists } from '@metamask/utils/node';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport {\n createSourceFile,\n getJSDocCommentsAndTags,\n getJSDocTags,\n isAsExpression,\n isClassDeclaration,\n isIdentifier,\n isImportDeclaration,\n isInterfaceDeclaration,\n isJSDoc,\n isLiteralTypeNode,\n isMethodDeclaration,\n isNamedImports,\n isNoSubstitutionTemplateLiteral,\n isPropertySignature,\n isStringLiteral,\n isTemplateExpression,\n isTemplateLiteralTypeNode,\n isTypeAliasDeclaration,\n isTypeLiteralNode,\n isTypeOfExpression,\n isTypeQueryNode,\n isTypeReferenceNode,\n isVariableStatement,\n ScriptTarget,\n} from 'typescript';\nimport type {\n Expression,\n InterfaceDeclaration,\n Node as TsNode,\n NodeArray,\n SourceFile,\n TemplateLiteralTypeNode as TemplateLiteralType,\n TypeAliasDeclaration,\n TypeElement,\n} from 'typescript';\n\nimport type { MessengerItemDoc, MethodInfo } from './types';\n\n\n/**\n * Extract string constants from top-level variable declarations in a source file.\n * Only looks at top-level `const x = 'string'` or `const x = 'string' as const`.\n *\n * @param sourceFile - The TypeScript source file to extract constants from.\n * @returns A map of constant name to string value.\n */\nfunction extractStringConstants(sourceFile: SourceFile): Map<string, string> {\n const names = new Map<string, string>();\n\n for (const statement of sourceFile.statements) {\n if (!isVariableStatement(statement)) {\n continue;\n }\n for (const decl of statement.declarationList.declarations) {\n if (!isIdentifier(decl.name)) {\n continue;\n }\n\n if (decl.initializer) {\n const init = decl.initializer;\n if (isStringLiteral(init)) {\n names.set(decl.name.text, init.text);\n } else if (isAsExpression(init) && isStringLiteral(init.expression)) {\n names.set(decl.name.text, init.expression.text);\n }\n }\n\n // Handle `declare const x: \"value\"` (common in .d.cts files)\n if (\n !decl.initializer &&\n decl.type &&\n isLiteralTypeNode(decl.type) &&\n isStringLiteral(decl.type.literal)\n ) {\n names.set(decl.name.text, decl.type.literal.text);\n }\n }\n }\n\n return names;\n}\n\n/**\n * Resolve the value of `controllerName` (or similar constant) defined in the\n * same file or imported from a local `./constants*` module (single-hop only).\n *\n * @param sourceFile - The TypeScript source file to search.\n * @param filePath - The absolute path of the source file on disk.\n * @returns A promise that resolves to a map of constant name to resolved string value.\n */\nasync function resolveControllerName(\n sourceFile: SourceFile,\n filePath: string,\n): Promise<Map<string, string>> {\n const names = extractStringConstants(sourceFile);\n\n // Chase single-hop local imports (no further recursion):\n // import { BRIDGE_CONTROLLER_NAME } from './constants/bridge';\n for (const statement of sourceFile.statements) {\n if (\n !isImportDeclaration(statement) ||\n !statement.moduleSpecifier ||\n !isStringLiteral(statement.moduleSpecifier)\n ) {\n continue;\n }\n\n const spec = statement.moduleSpecifier.text;\n if (!spec.startsWith('.')) {\n continue;\n }\n\n const dir = path.dirname(filePath);\n const isDts = filePath.endsWith('.d.cts') || filePath.endsWith('.d.ts');\n // Strip .cjs/.js extension from specifier for .d.cts resolution\n const bareSpec = spec.replace(/\\.(c|m)?js$/u, '');\n const candidates = isDts\n ? [\n path.join(dir, `${bareSpec}.d.cts`),\n path.join(dir, bareSpec, 'index.d.cts'),\n path.join(dir, `${bareSpec}.d.ts`),\n path.join(dir, bareSpec, 'index.d.ts'),\n ]\n : [path.join(dir, `${spec}.ts`), path.join(dir, spec, 'index.ts')];\n\n for (const candidate of candidates) {\n if (!(await fileExists(candidate))) {\n continue;\n }\n\n const content = await fs.readFile(candidate, 'utf8');\n const sf = createSourceFile(\n candidate,\n content,\n ScriptTarget.Latest,\n true,\n );\n // Only extract constants — do NOT follow further imports\n const imported = extractStringConstants(sf);\n\n if (\n statement.importClause?.namedBindings &&\n isNamedImports(statement.importClause.namedBindings)\n ) {\n for (const element of statement.importClause.namedBindings.elements) {\n const importedName = (element.propertyName ?? element.name).text;\n const localName = element.name.text;\n const value = imported.get(importedName);\n if (value !== undefined) {\n names.set(localName, value);\n }\n }\n }\n break;\n }\n }\n\n return names;\n}\n\n/**\n * Resolve a template-literal or string-literal `type` property to its string\n * value. Returns null if unresolvable.\n *\n * @param node - The expression node to resolve.\n * @param constants - A map of known constant names to their string values.\n * @returns The resolved string value, or null if unresolvable.\n */\nfunction resolveTypeString(\n node: Expression,\n constants: Map<string, string>,\n): string | null {\n if (isStringLiteral(node) || isNoSubstitutionTemplateLiteral(node)) {\n return node.text;\n }\n\n if (isTemplateExpression(node)) {\n let result = node.head.text;\n for (const span of node.templateSpans) {\n // typeof X → resolve X\n if (isTypeOfExpression(span.expression)) {\n if (isIdentifier(span.expression.expression)) {\n const val = constants.get(span.expression.expression.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else {\n return null;\n }\n } else if (isIdentifier(span.expression)) {\n const val = constants.get(span.expression.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else {\n return null;\n }\n result += span.literal.text;\n }\n return result;\n }\n\n return null;\n}\n\n/**\n * Resolve a TemplateLiteralTypeNode (used in type positions like\n * `type: \\`${typeof controllerName}:name\\``) to its string value.\n *\n * @param node - The template literal type node to resolve.\n * @param constants - A map of known constant names to their string values.\n * @returns The resolved string value, or null if unresolvable.\n */\nfunction resolveTemplateLiteralType(\n node: TemplateLiteralType,\n constants: Map<string, string>,\n): string | null {\n let result = node.head.text;\n\n for (const span of node.templateSpans) {\n // In type position, `typeof X` is a TypeQueryNode\n if (isTypeQueryNode(span.type) && isIdentifier(span.type.exprName)) {\n const val = constants.get(span.type.exprName.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else if (\n isLiteralTypeNode(span.type) &&\n isStringLiteral(span.type.literal)\n ) {\n result += span.type.literal.text;\n } else {\n return null;\n }\n result += span.literal.text;\n }\n\n return result;\n}\n\n/**\n * Extract cleaned JSDoc body text from a node.\n *\n * @param node - The AST node to extract JSDoc from.\n * @param sourceFile - The source file containing the node.\n * @returns The cleaned JSDoc text, or empty string if none.\n */\nfunction extractJsDocText(node: TsNode, sourceFile: SourceFile): string {\n const jsDocs = getJSDocCommentsAndTags(node);\n if (jsDocs.length === 0) {\n return '';\n }\n\n const jsDoc = jsDocs[0];\n if (!isJSDoc(jsDoc)) {\n return '';\n }\n\n const fullText = sourceFile.getFullText();\n const raw = fullText.substring(jsDoc.getFullStart(), jsDoc.getEnd()).trim();\n\n // Handle single-line JSDoc: /** Gets the current state. */\n const singleLineMatch = raw.match(/^\\/\\*\\*\\s*(.*?)\\s*\\*\\/$/u);\n if (singleLineMatch) {\n let text = singleLineMatch[1].replace(/^\\*\\s*/u, '');\n // Apply same escaping as multi-line path\n text = text.replace(/\\{@link\\s+([^}]+)\\}/gu, '`$1`');\n text = text.replace(/`[^`]*`|(\\{)|(\\})/gu, (match, open, close) => {\n if (open) {\n return '\\\\{';\n }\n if (close) {\n return '\\\\}';\n }\n return match;\n });\n return text || '';\n }\n\n // Strip comment delimiters, leading asterisks, and @param/@returns/@see tags\n const lines = raw.split('\\n');\n const cleaned: string[] = [];\n const skippedTags = [\n '@param',\n '@returns',\n '@see',\n '@throws',\n '@template',\n '@example',\n ];\n let currentTag: 'skip' | 'deprecated' | null = null;\n let deprecatedParts: string[] = [];\n\n for (const rawLine of lines) {\n let trimmed = rawLine.trim();\n if (trimmed === '/**' || trimmed === '*/') {\n continue;\n }\n if (trimmed.startsWith('* ')) {\n trimmed = trimmed.slice(2);\n } else if (trimmed === '*') {\n trimmed = '';\n } else if (trimmed.startsWith('*')) {\n trimmed = trimmed.slice(1);\n }\n\n // Check if this line starts a new tag\n if (trimmed.startsWith('@')) {\n // Flush any accumulated deprecated text\n if (currentTag === 'deprecated' && deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n deprecatedParts = [];\n }\n\n if (trimmed.startsWith('@deprecated')) {\n currentTag = 'deprecated';\n const depText = trimmed.slice('@deprecated'.length).trim();\n if (depText) {\n deprecatedParts.push(depText);\n }\n continue;\n }\n\n currentTag = skippedTags.some((tag) => trimmed.startsWith(tag))\n ? 'skip'\n : null;\n if (currentTag === 'skip') {\n continue;\n }\n } else if (currentTag === 'skip') {\n if (trimmed === '') {\n currentTag = null;\n } else {\n continue;\n }\n } else if (currentTag === 'deprecated') {\n if (trimmed === '') {\n // End of deprecated tag\n if (deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n deprecatedParts = [];\n }\n currentTag = null;\n } else {\n deprecatedParts.push(trimmed);\n continue;\n }\n }\n\n cleaned.push(trimmed);\n }\n\n // Flush any remaining deprecated text\n if (deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n }\n\n let result = cleaned.join('\\n').trim();\n\n // Convert JSDoc {@link X} references to markdown backtick code\n result = result.replace(/\\{@link\\s+([^}]+)\\}/gu, '`$1`');\n\n // Escape remaining curly braces for MDX safety (but not inside backtick code spans)\n result = result.replace(/`[^`]*`|(\\{)|(\\})/gu, (match, open, close) => {\n if (open) {\n return '\\\\{';\n }\n if (close) {\n return '\\\\}';\n }\n return match; // preserve content inside backticks\n });\n\n return result;\n}\n\n/**\n * Check whether a node has an `@deprecated` JSDoc tag.\n *\n * @param node - The AST node to check.\n * @returns True if the node has an `@deprecated` tag.\n */\nfunction isDeprecated(node: TsNode): boolean {\n const tags = getJSDocTags(node);\n return tags.some((tag) => tag.tagName.text === 'deprecated');\n}\n\n/**\n * Collect method info from all class declarations in a source file.\n * Returns a map keyed by \"ClassName.methodName\".\n *\n * @param sourceFile - The TypeScript source file to scan.\n * @returns A map of \"ClassName.methodName\" to method info.\n */\nfunction collectClassMethods(sourceFile: SourceFile): Map<string, MethodInfo> {\n const methods = new Map<string, MethodInfo>();\n\n for (const statement of sourceFile.statements) {\n if (!isClassDeclaration(statement) || !statement.name) {\n continue;\n }\n\n const className = statement.name.text;\n\n for (const member of statement.members) {\n if (\n !isMethodDeclaration(member) ||\n !member.name ||\n !isIdentifier(member.name)\n ) {\n continue;\n }\n\n const methodName = member.name.text;\n\n // Build parameter list\n const params = member.parameters\n .map((param) => {\n const paramName = param.name.getText(sourceFile);\n const optional = param.questionToken ? '?' : '';\n const paramType = param.type\n ? param.type.getText(sourceFile)\n : 'unknown';\n return `${paramName}${optional}: ${paramType}`;\n })\n .join(', ');\n\n // Get return type\n const returnType = member.type ? member.type.getText(sourceFile) : 'void';\n\n // For async methods, the declared return type already includes Promise<>,\n // so we don't need to wrap again.\n const methodSignature = `(${params}) => ${returnType}`;\n\n const jsDoc = extractJsDocText(member, sourceFile);\n\n methods.set(`${className}.${methodName}`, {\n jsDoc,\n signature: methodSignature,\n });\n }\n }\n\n return methods;\n}\n\n/**\n * If `handlerText` matches `ClassName['methodName']`, look it up in classMethodInfo\n * and return the resolved signature. Otherwise return the original text.\n *\n * @param handlerText - The raw handler text to resolve.\n * @param classMethods - A map of class methods collected from the source file.\n * @returns An object with the resolved signature and any associated JSDoc.\n */\nfunction resolveHandler(\n handlerText: string,\n classMethods: Map<string, MethodInfo>,\n): { signature: string; methodJsDoc: string } {\n const match = handlerText.match(/^(\\w+)\\['(\\w+)'\\]$/u);\n if (match) {\n const key = `${match[1]}.${match[2]}`;\n const info = classMethods.get(key);\n if (info) {\n return { signature: info.signature, methodJsDoc: info.jsDoc };\n }\n }\n return { signature: handlerText, methodJsDoc: '' };\n}\n\n/**\n * Get the raw source text for a property value inside a type literal.\n *\n * @param members - The type literal members to search.\n * @param propName - The property name to find.\n * @param sourceFile - The source file for getText calls.\n * @returns The raw text of the property type, or empty string if not found.\n */\nfunction getPropertyText(\n members: NodeArray<TypeElement>,\n propName: string,\n sourceFile: SourceFile,\n): string {\n for (const member of members) {\n if (\n isPropertySignature(member) &&\n member.name &&\n isIdentifier(member.name) &&\n member.name.text === propName &&\n member.type\n ) {\n return member.type.getText(sourceFile).trim();\n }\n }\n return '';\n}\n\n// ---------------------------------------------------------------------------\n// Main extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Extract messenger action/event type definitions from a single TypeScript file.\n *\n * @param filePath - The absolute path to the TypeScript file.\n * @param relBase - Base path for computing relative source paths.\n * @returns A promise that resolves to an array of extracted messenger item docs.\n */\nexport async function extractFromFile(\n filePath: string,\n relBase: string,\n): Promise<MessengerItemDoc[]> {\n const content = await fs.readFile(filePath, 'utf8');\n const sourceFile = createSourceFile(\n filePath,\n content,\n ScriptTarget.Latest,\n true,\n );\n\n const constants = await resolveControllerName(sourceFile, filePath);\n const classMethods = collectClassMethods(sourceFile);\n const items: MessengerItemDoc[] = [];\n const relPath = path.relative(relBase, filePath);\n\n // Type aliases and interfaces are always top-level statements\n for (const statement of sourceFile.statements) {\n // ---------------------------------------------------------------\n // Pattern 1: { type: '...'; handler/payload: ... }\n // Matches both:\n // type X = { type: '...'; handler: ... } (type alias with literal body)\n // interface X { type: '...'; handler: ... } (interface declaration)\n // ---------------------------------------------------------------\n let inlineNode: TypeAliasDeclaration | InterfaceDeclaration | undefined;\n let inlineMembers: NodeArray<TypeElement> | undefined;\n\n if (\n isTypeAliasDeclaration(statement) &&\n isTypeLiteralNode(statement.type)\n ) {\n inlineNode = statement;\n inlineMembers = statement.type.members;\n } else if (isInterfaceDeclaration(statement)) {\n inlineNode = statement;\n inlineMembers = statement.members;\n }\n\n if (inlineNode && inlineMembers) {\n const typeName = inlineNode.name.text;\n const line =\n sourceFile.getLineAndCharacterOfPosition(inlineNode.getStart()).line +\n 1;\n\n // Find `type` property\n let typeString: string | null = null;\n for (const member of inlineMembers) {\n if (\n isPropertySignature(member) &&\n member.name &&\n isIdentifier(member.name) &&\n member.name.text === 'type' &&\n member.type\n ) {\n if (isLiteralTypeNode(member.type)) {\n typeString = resolveTypeString(member.type.literal, constants);\n } else if (isTemplateLiteralTypeNode(member.type)) {\n typeString = resolveTemplateLiteralType(member.type, constants);\n }\n }\n }\n\n if (typeString?.includes(':')) {\n const handlerText = getPropertyText(\n inlineMembers,\n 'handler',\n sourceFile,\n );\n const payloadText = getPropertyText(\n inlineMembers,\n 'payload',\n sourceFile,\n );\n\n if (handlerText || payloadText) {\n const kind: 'action' | 'event' = handlerText ? 'action' : 'event';\n\n // For actions, resolve ClassName['methodName'] to actual signature + JSDoc\n let resolvedHandler = handlerText || payloadText;\n let typeAliasJsDoc = extractJsDocText(inlineNode, sourceFile);\n\n if (handlerText) {\n const resolved = resolveHandler(handlerText, classMethods);\n resolvedHandler = resolved.signature;\n // If the type alias has no JSDoc, use the method's JSDoc\n if (!typeAliasJsDoc && resolved.methodJsDoc) {\n typeAliasJsDoc = resolved.methodJsDoc;\n }\n }\n\n items.push({\n typeName,\n typeString,\n kind,\n jsDoc: typeAliasJsDoc,\n handlerOrPayload: resolvedHandler,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(inlineNode),\n });\n }\n }\n }\n\n // -------------------------------------------------------------------\n // Patterns 2 & 3 only apply to type aliases (generic type references)\n // -------------------------------------------------------------------\n if (!isTypeAliasDeclaration(statement)) {\n continue;\n }\n const node = statement;\n const typeName = node.name.text;\n const line =\n sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;\n\n // -------------------------------------------------------------------\n // Pattern 2: ControllerGetStateAction<typeof cn, State>\n // -------------------------------------------------------------------\n if (\n isTypeReferenceNode(node.type) &&\n isIdentifier(node.type.typeName) &&\n node.type.typeName.text === 'ControllerGetStateAction' &&\n node.type.typeArguments &&\n node.type.typeArguments.length >= 2\n ) {\n const firstArg = node.type.typeArguments[0];\n const stateArg = node.type.typeArguments[1];\n let namespace: string | null = null;\n\n if (isTypeQueryNode(firstArg) && isIdentifier(firstArg.exprName)) {\n namespace = constants.get(firstArg.exprName.text) ?? null;\n }\n if (isLiteralTypeNode(firstArg) && isStringLiteral(firstArg.literal)) {\n namespace = firstArg.literal.text;\n }\n\n if (namespace) {\n items.push({\n typeName,\n typeString: `${namespace}:getState`,\n kind: 'action',\n jsDoc: extractJsDocText(node, sourceFile),\n handlerOrPayload: `() => ${stateArg.getText(sourceFile)}`,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(node),\n });\n }\n }\n\n // -------------------------------------------------------------------\n // Pattern 3: ControllerStateChangeEvent<typeof cn, State>\n // -------------------------------------------------------------------\n if (\n isTypeReferenceNode(node.type) &&\n isIdentifier(node.type.typeName) &&\n node.type.typeName.text === 'ControllerStateChangeEvent' &&\n node.type.typeArguments &&\n node.type.typeArguments.length >= 2\n ) {\n const firstArg = node.type.typeArguments[0];\n const stateArg = node.type.typeArguments[1];\n let namespace: string | null = null;\n\n if (isTypeQueryNode(firstArg) && isIdentifier(firstArg.exprName)) {\n namespace = constants.get(firstArg.exprName.text) ?? null;\n }\n if (isLiteralTypeNode(firstArg) && isStringLiteral(firstArg.literal)) {\n namespace = firstArg.literal.text;\n }\n\n if (namespace) {\n items.push({\n typeName,\n typeString: `${namespace}:stateChange`,\n kind: 'event',\n jsDoc: extractJsDocText(node, sourceFile),\n handlerOrPayload: `[${stateArg.getText(sourceFile)}, Patch[]]`,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(node),\n });\n }\n }\n }\n\n return items;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"extraction.d.cts","sourceRoot":"","sources":["../../src/docs/extraction.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,gBAAgB,EAAc,oBAAgB;AA+c5D;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAyL7B"}
1
+ {"version":3,"file":"extraction.d.cts","sourceRoot":"","sources":["../../src/docs/extraction.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,gBAAgB,EAAc,oBAAgB;AAmd5D;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAyL7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"extraction.d.mts","sourceRoot":"","sources":["../../src/docs/extraction.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,gBAAgB,EAAc,oBAAgB;AA+c5D;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAyL7B"}
1
+ {"version":3,"file":"extraction.d.mts","sourceRoot":"","sources":["../../src/docs/extraction.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,gBAAgB,EAAc,oBAAgB;AAmd5D;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAyL7B"}
@@ -1,22 +1,8 @@
1
+ import { fileExists } from "@metamask/utils/node";
1
2
  import * as fs from "node:fs/promises";
2
3
  import * as path from "node:path";
3
4
  import $typescript from "typescript";
4
5
  const { createSourceFile, getJSDocCommentsAndTags, getJSDocTags, isAsExpression, isClassDeclaration, isIdentifier, isImportDeclaration, isInterfaceDeclaration, isJSDoc, isLiteralTypeNode, isMethodDeclaration, isNamedImports, isNoSubstitutionTemplateLiteral, isPropertySignature, isStringLiteral, isTemplateExpression, isTemplateLiteralTypeNode, isTypeAliasDeclaration, isTypeLiteralNode, isTypeOfExpression, isTypeQueryNode, isTypeReferenceNode, isVariableStatement, ScriptTarget } = $typescript;
5
- /**
6
- * Check whether a file exists.
7
- *
8
- * @param filePath - The path to check.
9
- * @returns A promise that resolves to true if the file exists.
10
- */
11
- async function fileExists(filePath) {
12
- try {
13
- await fs.access(filePath);
14
- return true;
15
- }
16
- catch {
17
- return false;
18
- }
19
- }
20
6
  /**
21
7
  * Extract string constants from top-level variable declarations in a source file.
22
8
  * Only looks at top-level `const x = 'string'` or `const x = 'string' as const`.
@@ -204,6 +190,23 @@ function extractJsDocText(node, sourceFile) {
204
190
  }
205
191
  const fullText = sourceFile.getFullText();
206
192
  const raw = fullText.substring(jsDoc.getFullStart(), jsDoc.getEnd()).trim();
193
+ // Handle single-line JSDoc: /** Gets the current state. */
194
+ const singleLineMatch = raw.match(/^\/\*\*\s*(.*?)\s*\*\/$/u);
195
+ if (singleLineMatch) {
196
+ let text = singleLineMatch[1].replace(/^\*\s*/u, '');
197
+ // Apply same escaping as multi-line path
198
+ text = text.replace(/\{@link\s+([^}]+)\}/gu, '`$1`');
199
+ text = text.replace(/`[^`]*`|(\{)|(\})/gu, (match, open, close) => {
200
+ if (open) {
201
+ return '\\{';
202
+ }
203
+ if (close) {
204
+ return '\\}';
205
+ }
206
+ return match;
207
+ });
208
+ return text || '';
209
+ }
207
210
  // Strip comment delimiters, leading asterisks, and @param/@returns/@see tags
208
211
  const lines = raw.split('\n');
209
212
  const cleaned = [];
@@ -1 +1 @@
1
- {"version":3,"file":"extraction.mjs","sourceRoot":"","sources":["../../src/docs/extraction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB;AACvC,OAAO,KAAK,IAAI,kBAAkB;;;AAwClC;;;;;GAKG;AACH,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,sBAAsB,CAAC,UAAsB;IACpD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAExC,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QAC9C,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,SAAS;QACX,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,eAAe,CAAC,YAAY,EAAE,CAAC;YAC1D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,SAAS;YACX,CAAC;YAED,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC;gBAC9B,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1B,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBACvC,CAAC;qBAAM,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;oBACpE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC;YAED,6DAA6D;YAC7D,IACE,CAAC,IAAI,CAAC,WAAW;gBACjB,IAAI,CAAC,IAAI;gBACT,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC5B,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAClC,CAAC;gBACD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,qBAAqB,CAClC,UAAsB,EACtB,QAAgB;IAEhB,MAAM,KAAK,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAEjD,yDAAyD;IACzD,iEAAiE;IACjE,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QAC9C,IACE,CAAC,mBAAmB,CAAC,SAAS,CAAC;YAC/B,CAAC,SAAS,CAAC,eAAe;YAC1B,CAAC,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC,EAC3C,CAAC;YACD,SAAS;QACX,CAAC;QAED,MAAM,IAAI,GAAG,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,SAAS;QACX,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACxE,gEAAgE;QAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,UAAU,GAAG,KAAK;YACtB,CAAC,CAAC;gBACE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,QAAQ,CAAC;gBACnC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC;gBACvC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,OAAO,CAAC;gBAClC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,YAAY,CAAC;aACvC;YACH,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,KAAK,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;QAErE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;gBACnC,SAAS;YACX,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YACrD,MAAM,EAAE,GAAG,gBAAgB,CACzB,SAAS,EACT,OAAO,EACP,YAAY,CAAC,MAAM,EACnB,IAAI,CACL,CAAC;YACF,yDAAyD;YACzD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,EAAE,CAAC,CAAC;YAE5C,IACE,SAAS,CAAC,YAAY,EAAE,aAAa;gBACrC,cAAc,CAAC,SAAS,CAAC,YAAY,CAAC,aAAa,CAAC,EACpD,CAAC;gBACD,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,YAAY,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;oBACpE,MAAM,YAAY,GAAG,CAAC,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;oBACjE,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;oBACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;oBACzC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;wBACxB,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;oBAC9B,CAAC;gBACH,CAAC;YACH,CAAC;YACD,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,iBAAiB,CACxB,IAAgB,EAChB,SAA8B;IAE9B,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,+BAA+B,CAAC,IAAI,CAAC,EAAE,CAAC;QACnE,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,IAAI,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACtC,yBAAyB;YACzB,IAAI,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBACxC,IAAI,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC7C,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;oBAC3D,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;wBACtB,OAAO,IAAI,CAAC;oBACd,CAAC;oBACD,MAAM,IAAI,GAAG,CAAC;gBAChB,CAAC;qBAAM,CAAC;oBACN,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;iBAAM,IAAI,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBACzC,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAChD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;oBACtB,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM,IAAI,GAAG,CAAC;YAChB,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QAC9B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,0BAA0B,CACjC,IAAyB,EACzB,SAA8B;IAE9B,IAAI,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAE5B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACtC,kDAAkD;QAClD,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnE,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACnD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,IAAI,GAAG,CAAC;QAChB,CAAC;aAAM,IACL,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;YAC5B,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAClC,CAAC;YACD,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QACnC,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,IAAY,EAAE,UAAsB;IAC5D,MAAM,MAAM,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAE5E,6EAA6E;IAC7E,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,WAAW,GAAG;QAClB,QAAQ;QACR,UAAU;QACV,MAAM;QACN,SAAS;QACT,WAAW;QACX,UAAU;KACX,CAAC;IACF,IAAI,UAAU,GAAiC,IAAI,CAAC;IACpD,IAAI,eAAe,GAAa,EAAE,CAAC;IAEnC,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;QAC5B,IAAI,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,OAAO,KAAK,KAAK,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;YAC3B,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;aAAM,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;QAED,sCAAsC;QACtC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,wCAAwC;YACxC,IAAI,UAAU,KAAK,YAAY,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9D,OAAO,CAAC,IAAI,CAAC,mBAAmB,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC7D,eAAe,GAAG,EAAE,CAAC;YACvB,CAAC;YAED,IAAI,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;gBACtC,UAAU,GAAG,YAAY,CAAC;gBAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC3D,IAAI,OAAO,EAAE,CAAC;oBACZ,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAChC,CAAC;gBACD,SAAS;YACX,CAAC;YAED,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;gBAC7D,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,IAAI,CAAC;YACT,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;gBAC1B,SAAS;YACX,CAAC;QACH,CAAC;aAAM,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;YACjC,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;gBACnB,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,SAAS;YACX,CAAC;QACH,CAAC;aAAM,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;YACvC,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;gBACnB,wBAAwB;gBACxB,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,OAAO,CAAC,IAAI,CAAC,mBAAmB,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAC7D,eAAe,GAAG,EAAE,CAAC;gBACvB,CAAC;gBACD,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC9B,SAAS;YACX,CAAC;QACH,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,sCAAsC;IACtC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,mBAAmB,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAEvC,+DAA+D;IAC/D,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;IAEzD,oFAAoF;IACpF,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpE,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,KAAK,CAAC,CAAC,oCAAoC;IACpD,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,UAAsB;IACjD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;IAE9C,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QAC9C,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YACtD,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAEtC,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACvC,IACE,CAAC,mBAAmB,CAAC,MAAM,CAAC;gBAC5B,CAAC,MAAM,CAAC,IAAI;gBACZ,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAC1B,CAAC;gBACD,SAAS;YACX,CAAC;YAED,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YAEpC,uBAAuB;YACvB,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU;iBAC7B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;gBACb,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI;oBAC1B,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;oBAChC,CAAC,CAAC,SAAS,CAAC;gBACd,OAAO,GAAG,SAAS,GAAG,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjD,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,CAAC;YAEd,kBAAkB;YAClB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAE1E,0EAA0E;YAC1E,kCAAkC;YAClC,MAAM,eAAe,GAAG,IAAI,MAAM,QAAQ,UAAU,EAAE,CAAC;YAEvD,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAEnD,OAAO,CAAC,GAAG,CAAC,GAAG,SAAS,IAAI,UAAU,EAAE,EAAE;gBACxC,KAAK;gBACL,SAAS,EAAE,eAAe;aAC3B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CACrB,WAAmB,EACnB,YAAqC;IAErC,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACvD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAChE,CAAC;IACH,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;AACrD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CACtB,OAA+B,EAC/B,QAAgB,EAChB,UAAsB;IAEtB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IACE,mBAAmB,CAAC,MAAM,CAAC;YAC3B,MAAM,CAAC,IAAI;YACX,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ;YAC7B,MAAM,CAAC,IAAI,EACX,CAAC;YACD,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,OAAe;IAEf,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,gBAAgB,CACjC,QAAQ,EACR,OAAO,EACP,YAAY,CAAC,MAAM,EACnB,IAAI,CACL,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACpE,MAAM,YAAY,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IACrD,MAAM,KAAK,GAAuB,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAEjD,8DAA8D;IAC9D,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QAC9C,kEAAkE;QAClE,mDAAmD;QACnD,gBAAgB;QAChB,4EAA4E;QAC5E,sEAAsE;QACtE,kEAAkE;QAClE,IAAI,UAAmE,CAAC;QACxE,IAAI,aAAiD,CAAC;QAEtD,IACE,sBAAsB,CAAC,SAAS,CAAC;YACjC,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,EACjC,CAAC;YACD,UAAU,GAAG,SAAS,CAAC;YACvB,aAAa,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;QACzC,CAAC;aAAM,IAAI,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7C,UAAU,GAAG,SAAS,CAAC;YACvB,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC;QACpC,CAAC;QAED,IAAI,UAAU,IAAI,aAAa,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;YACtC,MAAM,IAAI,GACR,UAAU,CAAC,6BAA6B,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI;gBACpE,CAAC,CAAC;YAEJ,uBAAuB;YACvB,IAAI,UAAU,GAAkB,IAAI,CAAC;YACrC,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;gBACnC,IACE,mBAAmB,CAAC,MAAM,CAAC;oBAC3B,MAAM,CAAC,IAAI;oBACX,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;oBACzB,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM;oBAC3B,MAAM,CAAC,IAAI,EACX,CAAC;oBACD,IAAI,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;wBACnC,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;oBACjE,CAAC;yBAAM,IAAI,yBAAyB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;wBAClD,UAAU,GAAG,0BAA0B,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;oBAClE,CAAC;gBACH,CAAC;YACH,CAAC;YAED,IAAI,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9B,MAAM,WAAW,GAAG,eAAe,CACjC,aAAa,EACb,SAAS,EACT,UAAU,CACX,CAAC;gBACF,MAAM,WAAW,GAAG,eAAe,CACjC,aAAa,EACb,SAAS,EACT,UAAU,CACX,CAAC;gBAEF,IAAI,WAAW,IAAI,WAAW,EAAE,CAAC;oBAC/B,MAAM,IAAI,GAAuB,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;oBAElE,2EAA2E;oBAC3E,IAAI,eAAe,GAAG,WAAW,IAAI,WAAW,CAAC;oBACjD,IAAI,cAAc,GAAG,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;oBAE9D,IAAI,WAAW,EAAE,CAAC;wBAChB,MAAM,QAAQ,GAAG,cAAc,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;wBAC3D,eAAe,GAAG,QAAQ,CAAC,SAAS,CAAC;wBACrC,yDAAyD;wBACzD,IAAI,CAAC,cAAc,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;4BAC5C,cAAc,GAAG,QAAQ,CAAC,WAAW,CAAC;wBACxC,CAAC;oBACH,CAAC;oBAED,KAAK,CAAC,IAAI,CAAC;wBACT,QAAQ;wBACR,UAAU;wBACV,IAAI;wBACJ,KAAK,EAAE,cAAc;wBACrB,gBAAgB,EAAE,eAAe;wBACjC,UAAU,EAAE,OAAO;wBACnB,IAAI;wBACJ,UAAU,EAAE,YAAY,CAAC,UAAU,CAAC;qBACrC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,sEAAsE;QACtE,sEAAsE;QACtE,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,SAAS,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAChC,MAAM,IAAI,GACR,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;QAErE,sEAAsE;QACtE,wDAAwD;QACxD,sEAAsE;QACtE,IACE,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;YAC9B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,0BAA0B;YACtD,IAAI,CAAC,IAAI,CAAC,aAAa;YACvB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,IAAI,CAAC,EACnC,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YAC5C,IAAI,SAAS,GAAkB,IAAI,CAAC;YAEpC,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjE,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;YAC5D,CAAC;YACD,IAAI,iBAAiB,CAAC,QAAQ,CAAC,IAAI,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrE,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;YACpC,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACd,KAAK,CAAC,IAAI,CAAC;oBACT,QAAQ;oBACR,UAAU,EAAE,GAAG,SAAS,WAAW;oBACnC,IAAI,EAAE,QAAQ;oBACd,KAAK,EAAE,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC;oBACzC,gBAAgB,EAAE,SAAS,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;oBACzD,UAAU,EAAE,OAAO;oBACnB,IAAI;oBACJ,UAAU,EAAE,YAAY,CAAC,IAAI,CAAC;iBAC/B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,0DAA0D;QAC1D,sEAAsE;QACtE,IACE,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;YAC9B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,4BAA4B;YACxD,IAAI,CAAC,IAAI,CAAC,aAAa;YACvB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,IAAI,CAAC,EACnC,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YAC5C,IAAI,SAAS,GAAkB,IAAI,CAAC;YAEpC,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjE,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;YAC5D,CAAC;YACD,IAAI,iBAAiB,CAAC,QAAQ,CAAC,IAAI,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrE,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;YACpC,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACd,KAAK,CAAC,IAAI,CAAC;oBACT,QAAQ;oBACR,UAAU,EAAE,GAAG,SAAS,cAAc;oBACtC,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC;oBACzC,gBAAgB,EAAE,IAAI,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,YAAY;oBAC9D,UAAU,EAAE,OAAO;oBACnB,IAAI;oBACJ,UAAU,EAAE,YAAY,CAAC,IAAI,CAAC;iBAC/B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport {\n createSourceFile,\n getJSDocCommentsAndTags,\n getJSDocTags,\n isAsExpression,\n isClassDeclaration,\n isIdentifier,\n isImportDeclaration,\n isInterfaceDeclaration,\n isJSDoc,\n isLiteralTypeNode,\n isMethodDeclaration,\n isNamedImports,\n isNoSubstitutionTemplateLiteral,\n isPropertySignature,\n isStringLiteral,\n isTemplateExpression,\n isTemplateLiteralTypeNode,\n isTypeAliasDeclaration,\n isTypeLiteralNode,\n isTypeOfExpression,\n isTypeQueryNode,\n isTypeReferenceNode,\n isVariableStatement,\n ScriptTarget,\n} from 'typescript';\nimport type {\n Expression,\n InterfaceDeclaration,\n Node as TsNode,\n NodeArray,\n SourceFile,\n TemplateLiteralTypeNode as TemplateLiteralType,\n TypeAliasDeclaration,\n TypeElement,\n} from 'typescript';\n\nimport type { MessengerItemDoc, MethodInfo } from './types';\n\n/**\n * Check whether a file exists.\n *\n * @param filePath - The path to check.\n * @returns A promise that resolves to true if the file exists.\n */\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Extract string constants from top-level variable declarations in a source file.\n * Only looks at top-level `const x = 'string'` or `const x = 'string' as const`.\n *\n * @param sourceFile - The TypeScript source file to extract constants from.\n * @returns A map of constant name to string value.\n */\nfunction extractStringConstants(sourceFile: SourceFile): Map<string, string> {\n const names = new Map<string, string>();\n\n for (const statement of sourceFile.statements) {\n if (!isVariableStatement(statement)) {\n continue;\n }\n for (const decl of statement.declarationList.declarations) {\n if (!isIdentifier(decl.name)) {\n continue;\n }\n\n if (decl.initializer) {\n const init = decl.initializer;\n if (isStringLiteral(init)) {\n names.set(decl.name.text, init.text);\n } else if (isAsExpression(init) && isStringLiteral(init.expression)) {\n names.set(decl.name.text, init.expression.text);\n }\n }\n\n // Handle `declare const x: \"value\"` (common in .d.cts files)\n if (\n !decl.initializer &&\n decl.type &&\n isLiteralTypeNode(decl.type) &&\n isStringLiteral(decl.type.literal)\n ) {\n names.set(decl.name.text, decl.type.literal.text);\n }\n }\n }\n\n return names;\n}\n\n/**\n * Resolve the value of `controllerName` (or similar constant) defined in the\n * same file or imported from a local `./constants*` module (single-hop only).\n *\n * @param sourceFile - The TypeScript source file to search.\n * @param filePath - The absolute path of the source file on disk.\n * @returns A promise that resolves to a map of constant name to resolved string value.\n */\nasync function resolveControllerName(\n sourceFile: SourceFile,\n filePath: string,\n): Promise<Map<string, string>> {\n const names = extractStringConstants(sourceFile);\n\n // Chase single-hop local imports (no further recursion):\n // import { BRIDGE_CONTROLLER_NAME } from './constants/bridge';\n for (const statement of sourceFile.statements) {\n if (\n !isImportDeclaration(statement) ||\n !statement.moduleSpecifier ||\n !isStringLiteral(statement.moduleSpecifier)\n ) {\n continue;\n }\n\n const spec = statement.moduleSpecifier.text;\n if (!spec.startsWith('.')) {\n continue;\n }\n\n const dir = path.dirname(filePath);\n const isDts = filePath.endsWith('.d.cts') || filePath.endsWith('.d.ts');\n // Strip .cjs/.js extension from specifier for .d.cts resolution\n const bareSpec = spec.replace(/\\.(c|m)?js$/u, '');\n const candidates = isDts\n ? [\n path.join(dir, `${bareSpec}.d.cts`),\n path.join(dir, bareSpec, 'index.d.cts'),\n path.join(dir, `${bareSpec}.d.ts`),\n path.join(dir, bareSpec, 'index.d.ts'),\n ]\n : [path.join(dir, `${spec}.ts`), path.join(dir, spec, 'index.ts')];\n\n for (const candidate of candidates) {\n if (!(await fileExists(candidate))) {\n continue;\n }\n\n const content = await fs.readFile(candidate, 'utf8');\n const sf = createSourceFile(\n candidate,\n content,\n ScriptTarget.Latest,\n true,\n );\n // Only extract constants — do NOT follow further imports\n const imported = extractStringConstants(sf);\n\n if (\n statement.importClause?.namedBindings &&\n isNamedImports(statement.importClause.namedBindings)\n ) {\n for (const element of statement.importClause.namedBindings.elements) {\n const importedName = (element.propertyName ?? element.name).text;\n const localName = element.name.text;\n const value = imported.get(importedName);\n if (value !== undefined) {\n names.set(localName, value);\n }\n }\n }\n break;\n }\n }\n\n return names;\n}\n\n/**\n * Resolve a template-literal or string-literal `type` property to its string\n * value. Returns null if unresolvable.\n *\n * @param node - The expression node to resolve.\n * @param constants - A map of known constant names to their string values.\n * @returns The resolved string value, or null if unresolvable.\n */\nfunction resolveTypeString(\n node: Expression,\n constants: Map<string, string>,\n): string | null {\n if (isStringLiteral(node) || isNoSubstitutionTemplateLiteral(node)) {\n return node.text;\n }\n\n if (isTemplateExpression(node)) {\n let result = node.head.text;\n for (const span of node.templateSpans) {\n // typeof X → resolve X\n if (isTypeOfExpression(span.expression)) {\n if (isIdentifier(span.expression.expression)) {\n const val = constants.get(span.expression.expression.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else {\n return null;\n }\n } else if (isIdentifier(span.expression)) {\n const val = constants.get(span.expression.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else {\n return null;\n }\n result += span.literal.text;\n }\n return result;\n }\n\n return null;\n}\n\n/**\n * Resolve a TemplateLiteralTypeNode (used in type positions like\n * `type: \\`${typeof controllerName}:name\\``) to its string value.\n *\n * @param node - The template literal type node to resolve.\n * @param constants - A map of known constant names to their string values.\n * @returns The resolved string value, or null if unresolvable.\n */\nfunction resolveTemplateLiteralType(\n node: TemplateLiteralType,\n constants: Map<string, string>,\n): string | null {\n let result = node.head.text;\n\n for (const span of node.templateSpans) {\n // In type position, `typeof X` is a TypeQueryNode\n if (isTypeQueryNode(span.type) && isIdentifier(span.type.exprName)) {\n const val = constants.get(span.type.exprName.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else if (\n isLiteralTypeNode(span.type) &&\n isStringLiteral(span.type.literal)\n ) {\n result += span.type.literal.text;\n } else {\n return null;\n }\n result += span.literal.text;\n }\n\n return result;\n}\n\n/**\n * Extract cleaned JSDoc body text from a node.\n *\n * @param node - The AST node to extract JSDoc from.\n * @param sourceFile - The source file containing the node.\n * @returns The cleaned JSDoc text, or empty string if none.\n */\nfunction extractJsDocText(node: TsNode, sourceFile: SourceFile): string {\n const jsDocs = getJSDocCommentsAndTags(node);\n if (jsDocs.length === 0) {\n return '';\n }\n\n const jsDoc = jsDocs[0];\n if (!isJSDoc(jsDoc)) {\n return '';\n }\n\n const fullText = sourceFile.getFullText();\n const raw = fullText.substring(jsDoc.getFullStart(), jsDoc.getEnd()).trim();\n\n // Strip comment delimiters, leading asterisks, and @param/@returns/@see tags\n const lines = raw.split('\\n');\n const cleaned: string[] = [];\n const skippedTags = [\n '@param',\n '@returns',\n '@see',\n '@throws',\n '@template',\n '@example',\n ];\n let currentTag: 'skip' | 'deprecated' | null = null;\n let deprecatedParts: string[] = [];\n\n for (const rawLine of lines) {\n let trimmed = rawLine.trim();\n if (trimmed === '/**' || trimmed === '*/') {\n continue;\n }\n if (trimmed.startsWith('* ')) {\n trimmed = trimmed.slice(2);\n } else if (trimmed === '*') {\n trimmed = '';\n } else if (trimmed.startsWith('*')) {\n trimmed = trimmed.slice(1);\n }\n\n // Check if this line starts a new tag\n if (trimmed.startsWith('@')) {\n // Flush any accumulated deprecated text\n if (currentTag === 'deprecated' && deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n deprecatedParts = [];\n }\n\n if (trimmed.startsWith('@deprecated')) {\n currentTag = 'deprecated';\n const depText = trimmed.slice('@deprecated'.length).trim();\n if (depText) {\n deprecatedParts.push(depText);\n }\n continue;\n }\n\n currentTag = skippedTags.some((tag) => trimmed.startsWith(tag))\n ? 'skip'\n : null;\n if (currentTag === 'skip') {\n continue;\n }\n } else if (currentTag === 'skip') {\n if (trimmed === '') {\n currentTag = null;\n } else {\n continue;\n }\n } else if (currentTag === 'deprecated') {\n if (trimmed === '') {\n // End of deprecated tag\n if (deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n deprecatedParts = [];\n }\n currentTag = null;\n } else {\n deprecatedParts.push(trimmed);\n continue;\n }\n }\n\n cleaned.push(trimmed);\n }\n\n // Flush any remaining deprecated text\n if (deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n }\n\n let result = cleaned.join('\\n').trim();\n\n // Convert JSDoc {@link X} references to markdown backtick code\n result = result.replace(/\\{@link\\s+([^}]+)\\}/gu, '`$1`');\n\n // Escape remaining curly braces for MDX safety (but not inside backtick code spans)\n result = result.replace(/`[^`]*`|(\\{)|(\\})/gu, (match, open, close) => {\n if (open) {\n return '\\\\{';\n }\n if (close) {\n return '\\\\}';\n }\n return match; // preserve content inside backticks\n });\n\n return result;\n}\n\n/**\n * Check whether a node has an `@deprecated` JSDoc tag.\n *\n * @param node - The AST node to check.\n * @returns True if the node has an `@deprecated` tag.\n */\nfunction isDeprecated(node: TsNode): boolean {\n const tags = getJSDocTags(node);\n return tags.some((tag) => tag.tagName.text === 'deprecated');\n}\n\n/**\n * Collect method info from all class declarations in a source file.\n * Returns a map keyed by \"ClassName.methodName\".\n *\n * @param sourceFile - The TypeScript source file to scan.\n * @returns A map of \"ClassName.methodName\" to method info.\n */\nfunction collectClassMethods(sourceFile: SourceFile): Map<string, MethodInfo> {\n const methods = new Map<string, MethodInfo>();\n\n for (const statement of sourceFile.statements) {\n if (!isClassDeclaration(statement) || !statement.name) {\n continue;\n }\n\n const className = statement.name.text;\n\n for (const member of statement.members) {\n if (\n !isMethodDeclaration(member) ||\n !member.name ||\n !isIdentifier(member.name)\n ) {\n continue;\n }\n\n const methodName = member.name.text;\n\n // Build parameter list\n const params = member.parameters\n .map((param) => {\n const paramName = param.name.getText(sourceFile);\n const optional = param.questionToken ? '?' : '';\n const paramType = param.type\n ? param.type.getText(sourceFile)\n : 'unknown';\n return `${paramName}${optional}: ${paramType}`;\n })\n .join(', ');\n\n // Get return type\n const returnType = member.type ? member.type.getText(sourceFile) : 'void';\n\n // For async methods, the declared return type already includes Promise<>,\n // so we don't need to wrap again.\n const methodSignature = `(${params}) => ${returnType}`;\n\n const jsDoc = extractJsDocText(member, sourceFile);\n\n methods.set(`${className}.${methodName}`, {\n jsDoc,\n signature: methodSignature,\n });\n }\n }\n\n return methods;\n}\n\n/**\n * If `handlerText` matches `ClassName['methodName']`, look it up in classMethodInfo\n * and return the resolved signature. Otherwise return the original text.\n *\n * @param handlerText - The raw handler text to resolve.\n * @param classMethods - A map of class methods collected from the source file.\n * @returns An object with the resolved signature and any associated JSDoc.\n */\nfunction resolveHandler(\n handlerText: string,\n classMethods: Map<string, MethodInfo>,\n): { signature: string; methodJsDoc: string } {\n const match = handlerText.match(/^(\\w+)\\['(\\w+)'\\]$/u);\n if (match) {\n const key = `${match[1]}.${match[2]}`;\n const info = classMethods.get(key);\n if (info) {\n return { signature: info.signature, methodJsDoc: info.jsDoc };\n }\n }\n return { signature: handlerText, methodJsDoc: '' };\n}\n\n/**\n * Get the raw source text for a property value inside a type literal.\n *\n * @param members - The type literal members to search.\n * @param propName - The property name to find.\n * @param sourceFile - The source file for getText calls.\n * @returns The raw text of the property type, or empty string if not found.\n */\nfunction getPropertyText(\n members: NodeArray<TypeElement>,\n propName: string,\n sourceFile: SourceFile,\n): string {\n for (const member of members) {\n if (\n isPropertySignature(member) &&\n member.name &&\n isIdentifier(member.name) &&\n member.name.text === propName &&\n member.type\n ) {\n return member.type.getText(sourceFile).trim();\n }\n }\n return '';\n}\n\n// ---------------------------------------------------------------------------\n// Main extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Extract messenger action/event type definitions from a single TypeScript file.\n *\n * @param filePath - The absolute path to the TypeScript file.\n * @param relBase - Base path for computing relative source paths.\n * @returns A promise that resolves to an array of extracted messenger item docs.\n */\nexport async function extractFromFile(\n filePath: string,\n relBase: string,\n): Promise<MessengerItemDoc[]> {\n const content = await fs.readFile(filePath, 'utf8');\n const sourceFile = createSourceFile(\n filePath,\n content,\n ScriptTarget.Latest,\n true,\n );\n\n const constants = await resolveControllerName(sourceFile, filePath);\n const classMethods = collectClassMethods(sourceFile);\n const items: MessengerItemDoc[] = [];\n const relPath = path.relative(relBase, filePath);\n\n // Type aliases and interfaces are always top-level statements\n for (const statement of sourceFile.statements) {\n // ---------------------------------------------------------------\n // Pattern 1: { type: '...'; handler/payload: ... }\n // Matches both:\n // type X = { type: '...'; handler: ... } (type alias with literal body)\n // interface X { type: '...'; handler: ... } (interface declaration)\n // ---------------------------------------------------------------\n let inlineNode: TypeAliasDeclaration | InterfaceDeclaration | undefined;\n let inlineMembers: NodeArray<TypeElement> | undefined;\n\n if (\n isTypeAliasDeclaration(statement) &&\n isTypeLiteralNode(statement.type)\n ) {\n inlineNode = statement;\n inlineMembers = statement.type.members;\n } else if (isInterfaceDeclaration(statement)) {\n inlineNode = statement;\n inlineMembers = statement.members;\n }\n\n if (inlineNode && inlineMembers) {\n const typeName = inlineNode.name.text;\n const line =\n sourceFile.getLineAndCharacterOfPosition(inlineNode.getStart()).line +\n 1;\n\n // Find `type` property\n let typeString: string | null = null;\n for (const member of inlineMembers) {\n if (\n isPropertySignature(member) &&\n member.name &&\n isIdentifier(member.name) &&\n member.name.text === 'type' &&\n member.type\n ) {\n if (isLiteralTypeNode(member.type)) {\n typeString = resolveTypeString(member.type.literal, constants);\n } else if (isTemplateLiteralTypeNode(member.type)) {\n typeString = resolveTemplateLiteralType(member.type, constants);\n }\n }\n }\n\n if (typeString?.includes(':')) {\n const handlerText = getPropertyText(\n inlineMembers,\n 'handler',\n sourceFile,\n );\n const payloadText = getPropertyText(\n inlineMembers,\n 'payload',\n sourceFile,\n );\n\n if (handlerText || payloadText) {\n const kind: 'action' | 'event' = handlerText ? 'action' : 'event';\n\n // For actions, resolve ClassName['methodName'] to actual signature + JSDoc\n let resolvedHandler = handlerText || payloadText;\n let typeAliasJsDoc = extractJsDocText(inlineNode, sourceFile);\n\n if (handlerText) {\n const resolved = resolveHandler(handlerText, classMethods);\n resolvedHandler = resolved.signature;\n // If the type alias has no JSDoc, use the method's JSDoc\n if (!typeAliasJsDoc && resolved.methodJsDoc) {\n typeAliasJsDoc = resolved.methodJsDoc;\n }\n }\n\n items.push({\n typeName,\n typeString,\n kind,\n jsDoc: typeAliasJsDoc,\n handlerOrPayload: resolvedHandler,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(inlineNode),\n });\n }\n }\n }\n\n // -------------------------------------------------------------------\n // Patterns 2 & 3 only apply to type aliases (generic type references)\n // -------------------------------------------------------------------\n if (!isTypeAliasDeclaration(statement)) {\n continue;\n }\n const node = statement;\n const typeName = node.name.text;\n const line =\n sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;\n\n // -------------------------------------------------------------------\n // Pattern 2: ControllerGetStateAction<typeof cn, State>\n // -------------------------------------------------------------------\n if (\n isTypeReferenceNode(node.type) &&\n isIdentifier(node.type.typeName) &&\n node.type.typeName.text === 'ControllerGetStateAction' &&\n node.type.typeArguments &&\n node.type.typeArguments.length >= 2\n ) {\n const firstArg = node.type.typeArguments[0];\n const stateArg = node.type.typeArguments[1];\n let namespace: string | null = null;\n\n if (isTypeQueryNode(firstArg) && isIdentifier(firstArg.exprName)) {\n namespace = constants.get(firstArg.exprName.text) ?? null;\n }\n if (isLiteralTypeNode(firstArg) && isStringLiteral(firstArg.literal)) {\n namespace = firstArg.literal.text;\n }\n\n if (namespace) {\n items.push({\n typeName,\n typeString: `${namespace}:getState`,\n kind: 'action',\n jsDoc: extractJsDocText(node, sourceFile),\n handlerOrPayload: `() => ${stateArg.getText(sourceFile)}`,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(node),\n });\n }\n }\n\n // -------------------------------------------------------------------\n // Pattern 3: ControllerStateChangeEvent<typeof cn, State>\n // -------------------------------------------------------------------\n if (\n isTypeReferenceNode(node.type) &&\n isIdentifier(node.type.typeName) &&\n node.type.typeName.text === 'ControllerStateChangeEvent' &&\n node.type.typeArguments &&\n node.type.typeArguments.length >= 2\n ) {\n const firstArg = node.type.typeArguments[0];\n const stateArg = node.type.typeArguments[1];\n let namespace: string | null = null;\n\n if (isTypeQueryNode(firstArg) && isIdentifier(firstArg.exprName)) {\n namespace = constants.get(firstArg.exprName.text) ?? null;\n }\n if (isLiteralTypeNode(firstArg) && isStringLiteral(firstArg.literal)) {\n namespace = firstArg.literal.text;\n }\n\n if (namespace) {\n items.push({\n typeName,\n typeString: `${namespace}:stateChange`,\n kind: 'event',\n jsDoc: extractJsDocText(node, sourceFile),\n handlerOrPayload: `[${stateArg.getText(sourceFile)}, Patch[]]`,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(node),\n });\n }\n }\n }\n\n return items;\n}\n"]}
1
+ {"version":3,"file":"extraction.mjs","sourceRoot":"","sources":["../../src/docs/extraction.ts"],"names":[],"mappings":"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","sourcesContent":["import { fileExists } from '@metamask/utils/node';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport {\n createSourceFile,\n getJSDocCommentsAndTags,\n getJSDocTags,\n isAsExpression,\n isClassDeclaration,\n isIdentifier,\n isImportDeclaration,\n isInterfaceDeclaration,\n isJSDoc,\n isLiteralTypeNode,\n isMethodDeclaration,\n isNamedImports,\n isNoSubstitutionTemplateLiteral,\n isPropertySignature,\n isStringLiteral,\n isTemplateExpression,\n isTemplateLiteralTypeNode,\n isTypeAliasDeclaration,\n isTypeLiteralNode,\n isTypeOfExpression,\n isTypeQueryNode,\n isTypeReferenceNode,\n isVariableStatement,\n ScriptTarget,\n} from 'typescript';\nimport type {\n Expression,\n InterfaceDeclaration,\n Node as TsNode,\n NodeArray,\n SourceFile,\n TemplateLiteralTypeNode as TemplateLiteralType,\n TypeAliasDeclaration,\n TypeElement,\n} from 'typescript';\n\nimport type { MessengerItemDoc, MethodInfo } from './types';\n\n\n/**\n * Extract string constants from top-level variable declarations in a source file.\n * Only looks at top-level `const x = 'string'` or `const x = 'string' as const`.\n *\n * @param sourceFile - The TypeScript source file to extract constants from.\n * @returns A map of constant name to string value.\n */\nfunction extractStringConstants(sourceFile: SourceFile): Map<string, string> {\n const names = new Map<string, string>();\n\n for (const statement of sourceFile.statements) {\n if (!isVariableStatement(statement)) {\n continue;\n }\n for (const decl of statement.declarationList.declarations) {\n if (!isIdentifier(decl.name)) {\n continue;\n }\n\n if (decl.initializer) {\n const init = decl.initializer;\n if (isStringLiteral(init)) {\n names.set(decl.name.text, init.text);\n } else if (isAsExpression(init) && isStringLiteral(init.expression)) {\n names.set(decl.name.text, init.expression.text);\n }\n }\n\n // Handle `declare const x: \"value\"` (common in .d.cts files)\n if (\n !decl.initializer &&\n decl.type &&\n isLiteralTypeNode(decl.type) &&\n isStringLiteral(decl.type.literal)\n ) {\n names.set(decl.name.text, decl.type.literal.text);\n }\n }\n }\n\n return names;\n}\n\n/**\n * Resolve the value of `controllerName` (or similar constant) defined in the\n * same file or imported from a local `./constants*` module (single-hop only).\n *\n * @param sourceFile - The TypeScript source file to search.\n * @param filePath - The absolute path of the source file on disk.\n * @returns A promise that resolves to a map of constant name to resolved string value.\n */\nasync function resolveControllerName(\n sourceFile: SourceFile,\n filePath: string,\n): Promise<Map<string, string>> {\n const names = extractStringConstants(sourceFile);\n\n // Chase single-hop local imports (no further recursion):\n // import { BRIDGE_CONTROLLER_NAME } from './constants/bridge';\n for (const statement of sourceFile.statements) {\n if (\n !isImportDeclaration(statement) ||\n !statement.moduleSpecifier ||\n !isStringLiteral(statement.moduleSpecifier)\n ) {\n continue;\n }\n\n const spec = statement.moduleSpecifier.text;\n if (!spec.startsWith('.')) {\n continue;\n }\n\n const dir = path.dirname(filePath);\n const isDts = filePath.endsWith('.d.cts') || filePath.endsWith('.d.ts');\n // Strip .cjs/.js extension from specifier for .d.cts resolution\n const bareSpec = spec.replace(/\\.(c|m)?js$/u, '');\n const candidates = isDts\n ? [\n path.join(dir, `${bareSpec}.d.cts`),\n path.join(dir, bareSpec, 'index.d.cts'),\n path.join(dir, `${bareSpec}.d.ts`),\n path.join(dir, bareSpec, 'index.d.ts'),\n ]\n : [path.join(dir, `${spec}.ts`), path.join(dir, spec, 'index.ts')];\n\n for (const candidate of candidates) {\n if (!(await fileExists(candidate))) {\n continue;\n }\n\n const content = await fs.readFile(candidate, 'utf8');\n const sf = createSourceFile(\n candidate,\n content,\n ScriptTarget.Latest,\n true,\n );\n // Only extract constants — do NOT follow further imports\n const imported = extractStringConstants(sf);\n\n if (\n statement.importClause?.namedBindings &&\n isNamedImports(statement.importClause.namedBindings)\n ) {\n for (const element of statement.importClause.namedBindings.elements) {\n const importedName = (element.propertyName ?? element.name).text;\n const localName = element.name.text;\n const value = imported.get(importedName);\n if (value !== undefined) {\n names.set(localName, value);\n }\n }\n }\n break;\n }\n }\n\n return names;\n}\n\n/**\n * Resolve a template-literal or string-literal `type` property to its string\n * value. Returns null if unresolvable.\n *\n * @param node - The expression node to resolve.\n * @param constants - A map of known constant names to their string values.\n * @returns The resolved string value, or null if unresolvable.\n */\nfunction resolveTypeString(\n node: Expression,\n constants: Map<string, string>,\n): string | null {\n if (isStringLiteral(node) || isNoSubstitutionTemplateLiteral(node)) {\n return node.text;\n }\n\n if (isTemplateExpression(node)) {\n let result = node.head.text;\n for (const span of node.templateSpans) {\n // typeof X → resolve X\n if (isTypeOfExpression(span.expression)) {\n if (isIdentifier(span.expression.expression)) {\n const val = constants.get(span.expression.expression.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else {\n return null;\n }\n } else if (isIdentifier(span.expression)) {\n const val = constants.get(span.expression.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else {\n return null;\n }\n result += span.literal.text;\n }\n return result;\n }\n\n return null;\n}\n\n/**\n * Resolve a TemplateLiteralTypeNode (used in type positions like\n * `type: \\`${typeof controllerName}:name\\``) to its string value.\n *\n * @param node - The template literal type node to resolve.\n * @param constants - A map of known constant names to their string values.\n * @returns The resolved string value, or null if unresolvable.\n */\nfunction resolveTemplateLiteralType(\n node: TemplateLiteralType,\n constants: Map<string, string>,\n): string | null {\n let result = node.head.text;\n\n for (const span of node.templateSpans) {\n // In type position, `typeof X` is a TypeQueryNode\n if (isTypeQueryNode(span.type) && isIdentifier(span.type.exprName)) {\n const val = constants.get(span.type.exprName.text);\n if (val === undefined) {\n return null;\n }\n result += val;\n } else if (\n isLiteralTypeNode(span.type) &&\n isStringLiteral(span.type.literal)\n ) {\n result += span.type.literal.text;\n } else {\n return null;\n }\n result += span.literal.text;\n }\n\n return result;\n}\n\n/**\n * Extract cleaned JSDoc body text from a node.\n *\n * @param node - The AST node to extract JSDoc from.\n * @param sourceFile - The source file containing the node.\n * @returns The cleaned JSDoc text, or empty string if none.\n */\nfunction extractJsDocText(node: TsNode, sourceFile: SourceFile): string {\n const jsDocs = getJSDocCommentsAndTags(node);\n if (jsDocs.length === 0) {\n return '';\n }\n\n const jsDoc = jsDocs[0];\n if (!isJSDoc(jsDoc)) {\n return '';\n }\n\n const fullText = sourceFile.getFullText();\n const raw = fullText.substring(jsDoc.getFullStart(), jsDoc.getEnd()).trim();\n\n // Handle single-line JSDoc: /** Gets the current state. */\n const singleLineMatch = raw.match(/^\\/\\*\\*\\s*(.*?)\\s*\\*\\/$/u);\n if (singleLineMatch) {\n let text = singleLineMatch[1].replace(/^\\*\\s*/u, '');\n // Apply same escaping as multi-line path\n text = text.replace(/\\{@link\\s+([^}]+)\\}/gu, '`$1`');\n text = text.replace(/`[^`]*`|(\\{)|(\\})/gu, (match, open, close) => {\n if (open) {\n return '\\\\{';\n }\n if (close) {\n return '\\\\}';\n }\n return match;\n });\n return text || '';\n }\n\n // Strip comment delimiters, leading asterisks, and @param/@returns/@see tags\n const lines = raw.split('\\n');\n const cleaned: string[] = [];\n const skippedTags = [\n '@param',\n '@returns',\n '@see',\n '@throws',\n '@template',\n '@example',\n ];\n let currentTag: 'skip' | 'deprecated' | null = null;\n let deprecatedParts: string[] = [];\n\n for (const rawLine of lines) {\n let trimmed = rawLine.trim();\n if (trimmed === '/**' || trimmed === '*/') {\n continue;\n }\n if (trimmed.startsWith('* ')) {\n trimmed = trimmed.slice(2);\n } else if (trimmed === '*') {\n trimmed = '';\n } else if (trimmed.startsWith('*')) {\n trimmed = trimmed.slice(1);\n }\n\n // Check if this line starts a new tag\n if (trimmed.startsWith('@')) {\n // Flush any accumulated deprecated text\n if (currentTag === 'deprecated' && deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n deprecatedParts = [];\n }\n\n if (trimmed.startsWith('@deprecated')) {\n currentTag = 'deprecated';\n const depText = trimmed.slice('@deprecated'.length).trim();\n if (depText) {\n deprecatedParts.push(depText);\n }\n continue;\n }\n\n currentTag = skippedTags.some((tag) => trimmed.startsWith(tag))\n ? 'skip'\n : null;\n if (currentTag === 'skip') {\n continue;\n }\n } else if (currentTag === 'skip') {\n if (trimmed === '') {\n currentTag = null;\n } else {\n continue;\n }\n } else if (currentTag === 'deprecated') {\n if (trimmed === '') {\n // End of deprecated tag\n if (deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n deprecatedParts = [];\n }\n currentTag = null;\n } else {\n deprecatedParts.push(trimmed);\n continue;\n }\n }\n\n cleaned.push(trimmed);\n }\n\n // Flush any remaining deprecated text\n if (deprecatedParts.length > 0) {\n cleaned.push(`**Deprecated:** ${deprecatedParts.join(' ')}`);\n }\n\n let result = cleaned.join('\\n').trim();\n\n // Convert JSDoc {@link X} references to markdown backtick code\n result = result.replace(/\\{@link\\s+([^}]+)\\}/gu, '`$1`');\n\n // Escape remaining curly braces for MDX safety (but not inside backtick code spans)\n result = result.replace(/`[^`]*`|(\\{)|(\\})/gu, (match, open, close) => {\n if (open) {\n return '\\\\{';\n }\n if (close) {\n return '\\\\}';\n }\n return match; // preserve content inside backticks\n });\n\n return result;\n}\n\n/**\n * Check whether a node has an `@deprecated` JSDoc tag.\n *\n * @param node - The AST node to check.\n * @returns True if the node has an `@deprecated` tag.\n */\nfunction isDeprecated(node: TsNode): boolean {\n const tags = getJSDocTags(node);\n return tags.some((tag) => tag.tagName.text === 'deprecated');\n}\n\n/**\n * Collect method info from all class declarations in a source file.\n * Returns a map keyed by \"ClassName.methodName\".\n *\n * @param sourceFile - The TypeScript source file to scan.\n * @returns A map of \"ClassName.methodName\" to method info.\n */\nfunction collectClassMethods(sourceFile: SourceFile): Map<string, MethodInfo> {\n const methods = new Map<string, MethodInfo>();\n\n for (const statement of sourceFile.statements) {\n if (!isClassDeclaration(statement) || !statement.name) {\n continue;\n }\n\n const className = statement.name.text;\n\n for (const member of statement.members) {\n if (\n !isMethodDeclaration(member) ||\n !member.name ||\n !isIdentifier(member.name)\n ) {\n continue;\n }\n\n const methodName = member.name.text;\n\n // Build parameter list\n const params = member.parameters\n .map((param) => {\n const paramName = param.name.getText(sourceFile);\n const optional = param.questionToken ? '?' : '';\n const paramType = param.type\n ? param.type.getText(sourceFile)\n : 'unknown';\n return `${paramName}${optional}: ${paramType}`;\n })\n .join(', ');\n\n // Get return type\n const returnType = member.type ? member.type.getText(sourceFile) : 'void';\n\n // For async methods, the declared return type already includes Promise<>,\n // so we don't need to wrap again.\n const methodSignature = `(${params}) => ${returnType}`;\n\n const jsDoc = extractJsDocText(member, sourceFile);\n\n methods.set(`${className}.${methodName}`, {\n jsDoc,\n signature: methodSignature,\n });\n }\n }\n\n return methods;\n}\n\n/**\n * If `handlerText` matches `ClassName['methodName']`, look it up in classMethodInfo\n * and return the resolved signature. Otherwise return the original text.\n *\n * @param handlerText - The raw handler text to resolve.\n * @param classMethods - A map of class methods collected from the source file.\n * @returns An object with the resolved signature and any associated JSDoc.\n */\nfunction resolveHandler(\n handlerText: string,\n classMethods: Map<string, MethodInfo>,\n): { signature: string; methodJsDoc: string } {\n const match = handlerText.match(/^(\\w+)\\['(\\w+)'\\]$/u);\n if (match) {\n const key = `${match[1]}.${match[2]}`;\n const info = classMethods.get(key);\n if (info) {\n return { signature: info.signature, methodJsDoc: info.jsDoc };\n }\n }\n return { signature: handlerText, methodJsDoc: '' };\n}\n\n/**\n * Get the raw source text for a property value inside a type literal.\n *\n * @param members - The type literal members to search.\n * @param propName - The property name to find.\n * @param sourceFile - The source file for getText calls.\n * @returns The raw text of the property type, or empty string if not found.\n */\nfunction getPropertyText(\n members: NodeArray<TypeElement>,\n propName: string,\n sourceFile: SourceFile,\n): string {\n for (const member of members) {\n if (\n isPropertySignature(member) &&\n member.name &&\n isIdentifier(member.name) &&\n member.name.text === propName &&\n member.type\n ) {\n return member.type.getText(sourceFile).trim();\n }\n }\n return '';\n}\n\n// ---------------------------------------------------------------------------\n// Main extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Extract messenger action/event type definitions from a single TypeScript file.\n *\n * @param filePath - The absolute path to the TypeScript file.\n * @param relBase - Base path for computing relative source paths.\n * @returns A promise that resolves to an array of extracted messenger item docs.\n */\nexport async function extractFromFile(\n filePath: string,\n relBase: string,\n): Promise<MessengerItemDoc[]> {\n const content = await fs.readFile(filePath, 'utf8');\n const sourceFile = createSourceFile(\n filePath,\n content,\n ScriptTarget.Latest,\n true,\n );\n\n const constants = await resolveControllerName(sourceFile, filePath);\n const classMethods = collectClassMethods(sourceFile);\n const items: MessengerItemDoc[] = [];\n const relPath = path.relative(relBase, filePath);\n\n // Type aliases and interfaces are always top-level statements\n for (const statement of sourceFile.statements) {\n // ---------------------------------------------------------------\n // Pattern 1: { type: '...'; handler/payload: ... }\n // Matches both:\n // type X = { type: '...'; handler: ... } (type alias with literal body)\n // interface X { type: '...'; handler: ... } (interface declaration)\n // ---------------------------------------------------------------\n let inlineNode: TypeAliasDeclaration | InterfaceDeclaration | undefined;\n let inlineMembers: NodeArray<TypeElement> | undefined;\n\n if (\n isTypeAliasDeclaration(statement) &&\n isTypeLiteralNode(statement.type)\n ) {\n inlineNode = statement;\n inlineMembers = statement.type.members;\n } else if (isInterfaceDeclaration(statement)) {\n inlineNode = statement;\n inlineMembers = statement.members;\n }\n\n if (inlineNode && inlineMembers) {\n const typeName = inlineNode.name.text;\n const line =\n sourceFile.getLineAndCharacterOfPosition(inlineNode.getStart()).line +\n 1;\n\n // Find `type` property\n let typeString: string | null = null;\n for (const member of inlineMembers) {\n if (\n isPropertySignature(member) &&\n member.name &&\n isIdentifier(member.name) &&\n member.name.text === 'type' &&\n member.type\n ) {\n if (isLiteralTypeNode(member.type)) {\n typeString = resolveTypeString(member.type.literal, constants);\n } else if (isTemplateLiteralTypeNode(member.type)) {\n typeString = resolveTemplateLiteralType(member.type, constants);\n }\n }\n }\n\n if (typeString?.includes(':')) {\n const handlerText = getPropertyText(\n inlineMembers,\n 'handler',\n sourceFile,\n );\n const payloadText = getPropertyText(\n inlineMembers,\n 'payload',\n sourceFile,\n );\n\n if (handlerText || payloadText) {\n const kind: 'action' | 'event' = handlerText ? 'action' : 'event';\n\n // For actions, resolve ClassName['methodName'] to actual signature + JSDoc\n let resolvedHandler = handlerText || payloadText;\n let typeAliasJsDoc = extractJsDocText(inlineNode, sourceFile);\n\n if (handlerText) {\n const resolved = resolveHandler(handlerText, classMethods);\n resolvedHandler = resolved.signature;\n // If the type alias has no JSDoc, use the method's JSDoc\n if (!typeAliasJsDoc && resolved.methodJsDoc) {\n typeAliasJsDoc = resolved.methodJsDoc;\n }\n }\n\n items.push({\n typeName,\n typeString,\n kind,\n jsDoc: typeAliasJsDoc,\n handlerOrPayload: resolvedHandler,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(inlineNode),\n });\n }\n }\n }\n\n // -------------------------------------------------------------------\n // Patterns 2 & 3 only apply to type aliases (generic type references)\n // -------------------------------------------------------------------\n if (!isTypeAliasDeclaration(statement)) {\n continue;\n }\n const node = statement;\n const typeName = node.name.text;\n const line =\n sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;\n\n // -------------------------------------------------------------------\n // Pattern 2: ControllerGetStateAction<typeof cn, State>\n // -------------------------------------------------------------------\n if (\n isTypeReferenceNode(node.type) &&\n isIdentifier(node.type.typeName) &&\n node.type.typeName.text === 'ControllerGetStateAction' &&\n node.type.typeArguments &&\n node.type.typeArguments.length >= 2\n ) {\n const firstArg = node.type.typeArguments[0];\n const stateArg = node.type.typeArguments[1];\n let namespace: string | null = null;\n\n if (isTypeQueryNode(firstArg) && isIdentifier(firstArg.exprName)) {\n namespace = constants.get(firstArg.exprName.text) ?? null;\n }\n if (isLiteralTypeNode(firstArg) && isStringLiteral(firstArg.literal)) {\n namespace = firstArg.literal.text;\n }\n\n if (namespace) {\n items.push({\n typeName,\n typeString: `${namespace}:getState`,\n kind: 'action',\n jsDoc: extractJsDocText(node, sourceFile),\n handlerOrPayload: `() => ${stateArg.getText(sourceFile)}`,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(node),\n });\n }\n }\n\n // -------------------------------------------------------------------\n // Pattern 3: ControllerStateChangeEvent<typeof cn, State>\n // -------------------------------------------------------------------\n if (\n isTypeReferenceNode(node.type) &&\n isIdentifier(node.type.typeName) &&\n node.type.typeName.text === 'ControllerStateChangeEvent' &&\n node.type.typeArguments &&\n node.type.typeArguments.length >= 2\n ) {\n const firstArg = node.type.typeArguments[0];\n const stateArg = node.type.typeArguments[1];\n let namespace: string | null = null;\n\n if (isTypeQueryNode(firstArg) && isIdentifier(firstArg.exprName)) {\n namespace = constants.get(firstArg.exprName.text) ?? null;\n }\n if (isLiteralTypeNode(firstArg) && isStringLiteral(firstArg.literal)) {\n namespace = firstArg.literal.text;\n }\n\n if (namespace) {\n items.push({\n typeName,\n typeString: `${namespace}:stateChange`,\n kind: 'event',\n jsDoc: extractJsDocText(node, sourceFile),\n handlerOrPayload: `[${stateArg.getText(sourceFile)}, Patch[]]`,\n sourceFile: relPath,\n line,\n deprecated: isDeprecated(node),\n });\n }\n }\n }\n\n return items;\n}\n"]}
@@ -184,7 +184,7 @@ async function generate(options) {
184
184
  const ns = item.typeString.split(':')[0];
185
185
  const group = byNamespace.get(ns);
186
186
  if (group) {
187
- const list = item.kind === 'action' ? group.actions : group.events;
187
+ const list = existing.kind === 'action' ? group.actions : group.events;
188
188
  const idx = list.indexOf(existing);
189
189
  if (idx !== -1) {
190
190
  list[idx] = item;
@@ -1 +1 @@
1
- {"version":3,"file":"generate.cjs","sourceRoot":"","sources":["../../src/docs/generate.ts"],"names":[],"mappings":"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","sourcesContent":["import { directoryExists } from '@metamask/utils/node';\nimport { execFile } from 'node:child_process';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport { findDtsFiles, findTsFiles } from './discovery';\nimport { extractFromFile } from './extraction';\nimport {\n generateIndexPage,\n generateNamespacePage,\n generateSidebars,\n} from './markdown';\nimport type { MessengerItemDoc, NamespaceGroup } from './types';\n\n/**\n * Compute a deduplication score for a messenger item, preferring items with\n * JSDoc and from the \"home\" package whose name matches the namespace.\n *\n * @param item - The messenger item to score.\n * @returns A numeric score (higher is better).\n */\nfunction deduplicationScore(item: MessengerItemDoc): number {\n const jsDocScore = item.jsDoc ? 2 : 0;\n const namespacePrefix = item.typeString\n .split(':')[0]\n .replace(/Controller|Service/u, '')\n .toLowerCase();\n const homeScore = item.sourceFile.includes(namespacePrefix) ? 1 : 0;\n return jsDocScore + homeScore;\n}\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Resolve the GitHub blob base URL for a project by reading its git remote.\n *\n * @param projectPath - Absolute path to the project root.\n * @returns A base URL like \"https://github.com/Owner/Repo/blob/main/\" or null.\n */\nasync function resolveRepoBaseUrl(projectPath: string): Promise<string | null> {\n try {\n const { stdout: remoteRaw } = await execFileAsync(\n 'git',\n ['remote', 'get-url', 'origin'],\n { cwd: projectPath },\n );\n\n const remote = remoteRaw.trim();\n\n // Parse owner/repo from SSH or HTTPS remote URLs\n // Handles aliases like github.com-Org used in SSH configs\n const match = remote.match(\n /github\\.com[^:/]*[:/]([^/]+\\/[^/]+?)(?:\\.git)?$/u,\n );\n if (!match) {\n return null;\n }\n\n return `https://github.com/${match[1]}/blob/main/`;\n } catch {\n return null;\n }\n}\n\n/**\n * Options for the generate function.\n */\nexport type GenerateOptions = {\n /** Absolute path to the project to scan. */\n projectPath: string;\n /** Absolute path to the output directory for generated docs. */\n outputDir: string;\n /** Directories (relative to projectPath) to scan for .ts source files. */\n scanDirs: string[];\n};\n\n/**\n * Result returned by the generate function.\n */\nexport type GenerateResult = {\n namespaces: number;\n actions: number;\n events: number;\n};\n\n/**\n * Scan a project for messenger action/event types and generate documentation.\n *\n * @param options - Generation options.\n * @returns A promise resolving to counts of generated namespaces, actions, and events.\n */\nexport async function generate(\n options: GenerateOptions,\n): Promise<GenerateResult> {\n const { projectPath, outputDir, scanDirs } = options;\n\n const allItems: MessengerItemDoc[] = [];\n\n // Check which sources are available\n const existingScanDirs: string[] = [];\n for (const dir of scanDirs) {\n const abs = path.join(projectPath, dir);\n if (await directoryExists(abs)) {\n existingScanDirs.push(dir);\n }\n }\n const packagesDir = path.join(projectPath, 'packages');\n const hasPackages = await directoryExists(packagesDir);\n const nmDir = path.join(projectPath, 'node_modules', '@metamask');\n const hasNodeModules = await directoryExists(nmDir);\n\n const sources: string[] = [];\n for (const dir of existingScanDirs) {\n sources.push(`${dir}/ (.ts)`);\n }\n if (hasPackages) {\n sources.push('packages/*/src (.ts)');\n }\n if (hasNodeModules) {\n sources.push('node_modules/@metamask/*/dist (.d.cts)');\n }\n console.log(\n `Scanning ${sources.join(', ')} for Messenger action/event types...`,\n );\n\n // Scan configured source directories for .ts files\n for (const dir of existingScanDirs) {\n const abs = path.join(projectPath, dir);\n const tsFiles = await findTsFiles(abs);\n for (const file of tsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n\n // Scan packages/*/src for .ts source files (monorepo)\n if (hasPackages) {\n const entries = await fs.readdir(packagesDir, { withFileTypes: true });\n const packageDirs = entries\n .filter((dirent) => dirent.isDirectory())\n .map((dirent) => path.join(packagesDir, dirent.name, 'src'));\n\n for (const srcDir of packageDirs) {\n if (!(await directoryExists(srcDir))) {\n continue;\n }\n\n const tsFiles = await findTsFiles(srcDir);\n for (const file of tsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n }\n\n // Scan node_modules/@metamask/*/dist for .d.cts declaration files\n if (hasNodeModules) {\n const entries = await fs.readdir(nmDir, { withFileTypes: true });\n const pkgDirs = entries\n .filter((dirent) => dirent.isDirectory() || dirent.isSymbolicLink())\n .map((dirent) => path.join(nmDir, dirent.name, 'dist'));\n\n for (const distDir of pkgDirs) {\n if (!(await directoryExists(distDir))) {\n continue;\n }\n\n const dtsFiles = await findDtsFiles(distDir);\n for (const file of dtsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n }\n\n if (existingScanDirs.length === 0 && !hasPackages && !hasNodeModules) {\n throw new Error(\n `No scannable directories found in ${projectPath}. ` +\n `Looked for: ${scanDirs.join(', ')}, packages/, node_modules/@metamask/`,\n );\n }\n\n console.log(`Found ${allItems.length} messenger items total.`);\n\n // Group by namespace (part before the colon), deduplicating by typeString.\n // When duplicates exist, prefer the one with JSDoc, or from the package\n // whose name matches the namespace.\n const byNamespace = new Map<string, NamespaceGroup>();\n const seen = new Map<string, MessengerItemDoc>(); // key: typeString\n\n for (const item of allItems) {\n const existing = seen.get(item.typeString);\n if (existing) {\n // Prefer item with JSDoc, or from the \"home\" package\n const existingScore = deduplicationScore(existing);\n const newScore = deduplicationScore(item);\n if (newScore <= existingScore) {\n continue;\n }\n // Replace existing with better item\n const ns = item.typeString.split(':')[0];\n const group = byNamespace.get(ns);\n if (group) {\n const list = item.kind === 'action' ? group.actions : group.events;\n const idx = list.indexOf(existing);\n if (idx !== -1) {\n list[idx] = item;\n }\n }\n seen.set(item.typeString, item);\n continue;\n }\n\n seen.set(item.typeString, item);\n const ns = item.typeString.split(':')[0];\n if (!byNamespace.has(ns)) {\n byNamespace.set(ns, { namespace: ns, actions: [], events: [] });\n }\n const group = byNamespace.get(ns);\n if (group) {\n if (item.kind === 'action') {\n group.actions.push(item);\n } else {\n group.events.push(item);\n }\n }\n }\n\n // Sort namespaces alphabetically, sort items within each namespace\n const namespaces = Array.from(byNamespace.values()).sort((a, b) =>\n a.namespace.localeCompare(b.namespace),\n );\n\n for (const ns of namespaces) {\n ns.actions.sort((a, b) => a.typeString.localeCompare(b.typeString));\n ns.events.sort((a, b) => a.typeString.localeCompare(b.typeString));\n }\n\n // Resolve repository base URL for source links\n const repoBaseUrl = await resolveRepoBaseUrl(projectPath);\n\n // Write output\n const docsDir = path.join(outputDir, 'docs');\n\n // Clean existing generated docs\n if (await directoryExists(docsDir)) {\n await fs.rm(docsDir, { recursive: true });\n }\n await fs.mkdir(docsDir, { recursive: true });\n\n // Generate namespace pages\n for (const ns of namespaces) {\n const nsDir = path.join(docsDir, ns.namespace);\n await fs.mkdir(nsDir, { recursive: true });\n\n if (ns.actions.length > 0) {\n await fs.writeFile(\n path.join(nsDir, 'actions.md'),\n generateNamespacePage(ns, 'action', repoBaseUrl),\n );\n }\n\n if (ns.events.length > 0) {\n await fs.writeFile(\n path.join(nsDir, 'events.md'),\n generateNamespacePage(ns, 'event', repoBaseUrl),\n );\n }\n }\n\n // Generate index page\n await fs.writeFile(\n path.join(docsDir, 'index.md'),\n generateIndexPage(namespaces),\n );\n\n // Generate sidebars\n await fs.writeFile(\n path.join(outputDir, 'sidebars.ts'),\n generateSidebars(namespaces),\n );\n\n const totalActions = namespaces.reduce(\n (sum, ns) => sum + ns.actions.length,\n 0,\n );\n const totalEvents = namespaces.reduce((sum, ns) => sum + ns.events.length, 0);\n\n console.log(`Generated docs for ${namespaces.length} namespaces.`);\n console.log(` Actions: ${totalActions}`);\n console.log(` Events: ${totalEvents}`);\n console.log(`Output: ${docsDir}/`);\n\n return {\n namespaces: namespaces.length,\n actions: totalActions,\n events: totalEvents,\n };\n}\n"]}
1
+ {"version":3,"file":"generate.cjs","sourceRoot":"","sources":["../../src/docs/generate.ts"],"names":[],"mappings":"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","sourcesContent":["import { directoryExists } from '@metamask/utils/node';\nimport { execFile } from 'node:child_process';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport { findDtsFiles, findTsFiles } from './discovery';\nimport { extractFromFile } from './extraction';\nimport {\n generateIndexPage,\n generateNamespacePage,\n generateSidebars,\n} from './markdown';\nimport type { MessengerItemDoc, NamespaceGroup } from './types';\n\n/**\n * Compute a deduplication score for a messenger item, preferring items with\n * JSDoc and from the \"home\" package whose name matches the namespace.\n *\n * @param item - The messenger item to score.\n * @returns A numeric score (higher is better).\n */\nfunction deduplicationScore(item: MessengerItemDoc): number {\n const jsDocScore = item.jsDoc ? 2 : 0;\n const namespacePrefix = item.typeString\n .split(':')[0]\n .replace(/Controller|Service/u, '')\n .toLowerCase();\n const homeScore = item.sourceFile.includes(namespacePrefix) ? 1 : 0;\n return jsDocScore + homeScore;\n}\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Resolve the GitHub blob base URL for a project by reading its git remote.\n *\n * @param projectPath - Absolute path to the project root.\n * @returns A base URL like \"https://github.com/Owner/Repo/blob/main/\" or null.\n */\nasync function resolveRepoBaseUrl(projectPath: string): Promise<string | null> {\n try {\n const { stdout: remoteRaw } = await execFileAsync(\n 'git',\n ['remote', 'get-url', 'origin'],\n { cwd: projectPath },\n );\n\n const remote = remoteRaw.trim();\n\n // Parse owner/repo from SSH or HTTPS remote URLs\n // Handles aliases like github.com-Org used in SSH configs\n const match = remote.match(\n /github\\.com[^:/]*[:/]([^/]+\\/[^/]+?)(?:\\.git)?$/u,\n );\n if (!match) {\n return null;\n }\n\n return `https://github.com/${match[1]}/blob/main/`;\n } catch {\n return null;\n }\n}\n\n/**\n * Options for the generate function.\n */\nexport type GenerateOptions = {\n /** Absolute path to the project to scan. */\n projectPath: string;\n /** Absolute path to the output directory for generated docs. */\n outputDir: string;\n /** Directories (relative to projectPath) to scan for .ts source files. */\n scanDirs: string[];\n};\n\n/**\n * Result returned by the generate function.\n */\nexport type GenerateResult = {\n namespaces: number;\n actions: number;\n events: number;\n};\n\n/**\n * Scan a project for messenger action/event types and generate documentation.\n *\n * @param options - Generation options.\n * @returns A promise resolving to counts of generated namespaces, actions, and events.\n */\nexport async function generate(\n options: GenerateOptions,\n): Promise<GenerateResult> {\n const { projectPath, outputDir, scanDirs } = options;\n\n const allItems: MessengerItemDoc[] = [];\n\n // Check which sources are available\n const existingScanDirs: string[] = [];\n for (const dir of scanDirs) {\n const abs = path.join(projectPath, dir);\n if (await directoryExists(abs)) {\n existingScanDirs.push(dir);\n }\n }\n const packagesDir = path.join(projectPath, 'packages');\n const hasPackages = await directoryExists(packagesDir);\n const nmDir = path.join(projectPath, 'node_modules', '@metamask');\n const hasNodeModules = await directoryExists(nmDir);\n\n const sources: string[] = [];\n for (const dir of existingScanDirs) {\n sources.push(`${dir}/ (.ts)`);\n }\n if (hasPackages) {\n sources.push('packages/*/src (.ts)');\n }\n if (hasNodeModules) {\n sources.push('node_modules/@metamask/*/dist (.d.cts)');\n }\n console.log(\n `Scanning ${sources.join(', ')} for Messenger action/event types...`,\n );\n\n // Scan configured source directories for .ts files\n for (const dir of existingScanDirs) {\n const abs = path.join(projectPath, dir);\n const tsFiles = await findTsFiles(abs);\n for (const file of tsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n\n // Scan packages/*/src for .ts source files (monorepo)\n if (hasPackages) {\n const entries = await fs.readdir(packagesDir, { withFileTypes: true });\n const packageDirs = entries\n .filter((dirent) => dirent.isDirectory())\n .map((dirent) => path.join(packagesDir, dirent.name, 'src'));\n\n for (const srcDir of packageDirs) {\n if (!(await directoryExists(srcDir))) {\n continue;\n }\n\n const tsFiles = await findTsFiles(srcDir);\n for (const file of tsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n }\n\n // Scan node_modules/@metamask/*/dist for .d.cts declaration files\n if (hasNodeModules) {\n const entries = await fs.readdir(nmDir, { withFileTypes: true });\n const pkgDirs = entries\n .filter((dirent) => dirent.isDirectory() || dirent.isSymbolicLink())\n .map((dirent) => path.join(nmDir, dirent.name, 'dist'));\n\n for (const distDir of pkgDirs) {\n if (!(await directoryExists(distDir))) {\n continue;\n }\n\n const dtsFiles = await findDtsFiles(distDir);\n for (const file of dtsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n }\n\n if (existingScanDirs.length === 0 && !hasPackages && !hasNodeModules) {\n throw new Error(\n `No scannable directories found in ${projectPath}. ` +\n `Looked for: ${scanDirs.join(', ')}, packages/, node_modules/@metamask/`,\n );\n }\n\n console.log(`Found ${allItems.length} messenger items total.`);\n\n // Group by namespace (part before the colon), deduplicating by typeString.\n // When duplicates exist, prefer the one with JSDoc, or from the package\n // whose name matches the namespace.\n const byNamespace = new Map<string, NamespaceGroup>();\n const seen = new Map<string, MessengerItemDoc>(); // key: typeString\n\n for (const item of allItems) {\n const existing = seen.get(item.typeString);\n if (existing) {\n // Prefer item with JSDoc, or from the \"home\" package\n const existingScore = deduplicationScore(existing);\n const newScore = deduplicationScore(item);\n if (newScore <= existingScore) {\n continue;\n }\n // Replace existing with better item\n const ns = item.typeString.split(':')[0];\n const group = byNamespace.get(ns);\n if (group) {\n const list = existing.kind === 'action' ? group.actions : group.events;\n const idx = list.indexOf(existing);\n if (idx !== -1) {\n list[idx] = item;\n }\n }\n seen.set(item.typeString, item);\n continue;\n }\n\n seen.set(item.typeString, item);\n const ns = item.typeString.split(':')[0];\n if (!byNamespace.has(ns)) {\n byNamespace.set(ns, { namespace: ns, actions: [], events: [] });\n }\n const group = byNamespace.get(ns);\n if (group) {\n if (item.kind === 'action') {\n group.actions.push(item);\n } else {\n group.events.push(item);\n }\n }\n }\n\n // Sort namespaces alphabetically, sort items within each namespace\n const namespaces = Array.from(byNamespace.values()).sort((a, b) =>\n a.namespace.localeCompare(b.namespace),\n );\n\n for (const ns of namespaces) {\n ns.actions.sort((a, b) => a.typeString.localeCompare(b.typeString));\n ns.events.sort((a, b) => a.typeString.localeCompare(b.typeString));\n }\n\n // Resolve repository base URL for source links\n const repoBaseUrl = await resolveRepoBaseUrl(projectPath);\n\n // Write output\n const docsDir = path.join(outputDir, 'docs');\n\n // Clean existing generated docs\n if (await directoryExists(docsDir)) {\n await fs.rm(docsDir, { recursive: true });\n }\n await fs.mkdir(docsDir, { recursive: true });\n\n // Generate namespace pages\n for (const ns of namespaces) {\n const nsDir = path.join(docsDir, ns.namespace);\n await fs.mkdir(nsDir, { recursive: true });\n\n if (ns.actions.length > 0) {\n await fs.writeFile(\n path.join(nsDir, 'actions.md'),\n generateNamespacePage(ns, 'action', repoBaseUrl),\n );\n }\n\n if (ns.events.length > 0) {\n await fs.writeFile(\n path.join(nsDir, 'events.md'),\n generateNamespacePage(ns, 'event', repoBaseUrl),\n );\n }\n }\n\n // Generate index page\n await fs.writeFile(\n path.join(docsDir, 'index.md'),\n generateIndexPage(namespaces),\n );\n\n // Generate sidebars\n await fs.writeFile(\n path.join(outputDir, 'sidebars.ts'),\n generateSidebars(namespaces),\n );\n\n const totalActions = namespaces.reduce(\n (sum, ns) => sum + ns.actions.length,\n 0,\n );\n const totalEvents = namespaces.reduce((sum, ns) => sum + ns.events.length, 0);\n\n console.log(`Generated docs for ${namespaces.length} namespaces.`);\n console.log(` Actions: ${totalActions}`);\n console.log(` Events: ${totalEvents}`);\n console.log(`Output: ${docsDir}/`);\n\n return {\n namespaces: namespaces.length,\n actions: totalActions,\n events: totalEvents,\n };\n}\n"]}
@@ -158,7 +158,7 @@ export async function generate(options) {
158
158
  const ns = item.typeString.split(':')[0];
159
159
  const group = byNamespace.get(ns);
160
160
  if (group) {
161
- const list = item.kind === 'action' ? group.actions : group.events;
161
+ const list = existing.kind === 'action' ? group.actions : group.events;
162
162
  const idx = list.indexOf(existing);
163
163
  if (idx !== -1) {
164
164
  list[idx] = item;
@@ -1 +1 @@
1
- {"version":3,"file":"generate.mjs","sourceRoot":"","sources":["../../src/docs/generate.ts"],"names":[],"mappings":"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","sourcesContent":["import { directoryExists } from '@metamask/utils/node';\nimport { execFile } from 'node:child_process';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport { findDtsFiles, findTsFiles } from './discovery';\nimport { extractFromFile } from './extraction';\nimport {\n generateIndexPage,\n generateNamespacePage,\n generateSidebars,\n} from './markdown';\nimport type { MessengerItemDoc, NamespaceGroup } from './types';\n\n/**\n * Compute a deduplication score for a messenger item, preferring items with\n * JSDoc and from the \"home\" package whose name matches the namespace.\n *\n * @param item - The messenger item to score.\n * @returns A numeric score (higher is better).\n */\nfunction deduplicationScore(item: MessengerItemDoc): number {\n const jsDocScore = item.jsDoc ? 2 : 0;\n const namespacePrefix = item.typeString\n .split(':')[0]\n .replace(/Controller|Service/u, '')\n .toLowerCase();\n const homeScore = item.sourceFile.includes(namespacePrefix) ? 1 : 0;\n return jsDocScore + homeScore;\n}\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Resolve the GitHub blob base URL for a project by reading its git remote.\n *\n * @param projectPath - Absolute path to the project root.\n * @returns A base URL like \"https://github.com/Owner/Repo/blob/main/\" or null.\n */\nasync function resolveRepoBaseUrl(projectPath: string): Promise<string | null> {\n try {\n const { stdout: remoteRaw } = await execFileAsync(\n 'git',\n ['remote', 'get-url', 'origin'],\n { cwd: projectPath },\n );\n\n const remote = remoteRaw.trim();\n\n // Parse owner/repo from SSH or HTTPS remote URLs\n // Handles aliases like github.com-Org used in SSH configs\n const match = remote.match(\n /github\\.com[^:/]*[:/]([^/]+\\/[^/]+?)(?:\\.git)?$/u,\n );\n if (!match) {\n return null;\n }\n\n return `https://github.com/${match[1]}/blob/main/`;\n } catch {\n return null;\n }\n}\n\n/**\n * Options for the generate function.\n */\nexport type GenerateOptions = {\n /** Absolute path to the project to scan. */\n projectPath: string;\n /** Absolute path to the output directory for generated docs. */\n outputDir: string;\n /** Directories (relative to projectPath) to scan for .ts source files. */\n scanDirs: string[];\n};\n\n/**\n * Result returned by the generate function.\n */\nexport type GenerateResult = {\n namespaces: number;\n actions: number;\n events: number;\n};\n\n/**\n * Scan a project for messenger action/event types and generate documentation.\n *\n * @param options - Generation options.\n * @returns A promise resolving to counts of generated namespaces, actions, and events.\n */\nexport async function generate(\n options: GenerateOptions,\n): Promise<GenerateResult> {\n const { projectPath, outputDir, scanDirs } = options;\n\n const allItems: MessengerItemDoc[] = [];\n\n // Check which sources are available\n const existingScanDirs: string[] = [];\n for (const dir of scanDirs) {\n const abs = path.join(projectPath, dir);\n if (await directoryExists(abs)) {\n existingScanDirs.push(dir);\n }\n }\n const packagesDir = path.join(projectPath, 'packages');\n const hasPackages = await directoryExists(packagesDir);\n const nmDir = path.join(projectPath, 'node_modules', '@metamask');\n const hasNodeModules = await directoryExists(nmDir);\n\n const sources: string[] = [];\n for (const dir of existingScanDirs) {\n sources.push(`${dir}/ (.ts)`);\n }\n if (hasPackages) {\n sources.push('packages/*/src (.ts)');\n }\n if (hasNodeModules) {\n sources.push('node_modules/@metamask/*/dist (.d.cts)');\n }\n console.log(\n `Scanning ${sources.join(', ')} for Messenger action/event types...`,\n );\n\n // Scan configured source directories for .ts files\n for (const dir of existingScanDirs) {\n const abs = path.join(projectPath, dir);\n const tsFiles = await findTsFiles(abs);\n for (const file of tsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n\n // Scan packages/*/src for .ts source files (monorepo)\n if (hasPackages) {\n const entries = await fs.readdir(packagesDir, { withFileTypes: true });\n const packageDirs = entries\n .filter((dirent) => dirent.isDirectory())\n .map((dirent) => path.join(packagesDir, dirent.name, 'src'));\n\n for (const srcDir of packageDirs) {\n if (!(await directoryExists(srcDir))) {\n continue;\n }\n\n const tsFiles = await findTsFiles(srcDir);\n for (const file of tsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n }\n\n // Scan node_modules/@metamask/*/dist for .d.cts declaration files\n if (hasNodeModules) {\n const entries = await fs.readdir(nmDir, { withFileTypes: true });\n const pkgDirs = entries\n .filter((dirent) => dirent.isDirectory() || dirent.isSymbolicLink())\n .map((dirent) => path.join(nmDir, dirent.name, 'dist'));\n\n for (const distDir of pkgDirs) {\n if (!(await directoryExists(distDir))) {\n continue;\n }\n\n const dtsFiles = await findDtsFiles(distDir);\n for (const file of dtsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n }\n\n if (existingScanDirs.length === 0 && !hasPackages && !hasNodeModules) {\n throw new Error(\n `No scannable directories found in ${projectPath}. ` +\n `Looked for: ${scanDirs.join(', ')}, packages/, node_modules/@metamask/`,\n );\n }\n\n console.log(`Found ${allItems.length} messenger items total.`);\n\n // Group by namespace (part before the colon), deduplicating by typeString.\n // When duplicates exist, prefer the one with JSDoc, or from the package\n // whose name matches the namespace.\n const byNamespace = new Map<string, NamespaceGroup>();\n const seen = new Map<string, MessengerItemDoc>(); // key: typeString\n\n for (const item of allItems) {\n const existing = seen.get(item.typeString);\n if (existing) {\n // Prefer item with JSDoc, or from the \"home\" package\n const existingScore = deduplicationScore(existing);\n const newScore = deduplicationScore(item);\n if (newScore <= existingScore) {\n continue;\n }\n // Replace existing with better item\n const ns = item.typeString.split(':')[0];\n const group = byNamespace.get(ns);\n if (group) {\n const list = item.kind === 'action' ? group.actions : group.events;\n const idx = list.indexOf(existing);\n if (idx !== -1) {\n list[idx] = item;\n }\n }\n seen.set(item.typeString, item);\n continue;\n }\n\n seen.set(item.typeString, item);\n const ns = item.typeString.split(':')[0];\n if (!byNamespace.has(ns)) {\n byNamespace.set(ns, { namespace: ns, actions: [], events: [] });\n }\n const group = byNamespace.get(ns);\n if (group) {\n if (item.kind === 'action') {\n group.actions.push(item);\n } else {\n group.events.push(item);\n }\n }\n }\n\n // Sort namespaces alphabetically, sort items within each namespace\n const namespaces = Array.from(byNamespace.values()).sort((a, b) =>\n a.namespace.localeCompare(b.namespace),\n );\n\n for (const ns of namespaces) {\n ns.actions.sort((a, b) => a.typeString.localeCompare(b.typeString));\n ns.events.sort((a, b) => a.typeString.localeCompare(b.typeString));\n }\n\n // Resolve repository base URL for source links\n const repoBaseUrl = await resolveRepoBaseUrl(projectPath);\n\n // Write output\n const docsDir = path.join(outputDir, 'docs');\n\n // Clean existing generated docs\n if (await directoryExists(docsDir)) {\n await fs.rm(docsDir, { recursive: true });\n }\n await fs.mkdir(docsDir, { recursive: true });\n\n // Generate namespace pages\n for (const ns of namespaces) {\n const nsDir = path.join(docsDir, ns.namespace);\n await fs.mkdir(nsDir, { recursive: true });\n\n if (ns.actions.length > 0) {\n await fs.writeFile(\n path.join(nsDir, 'actions.md'),\n generateNamespacePage(ns, 'action', repoBaseUrl),\n );\n }\n\n if (ns.events.length > 0) {\n await fs.writeFile(\n path.join(nsDir, 'events.md'),\n generateNamespacePage(ns, 'event', repoBaseUrl),\n );\n }\n }\n\n // Generate index page\n await fs.writeFile(\n path.join(docsDir, 'index.md'),\n generateIndexPage(namespaces),\n );\n\n // Generate sidebars\n await fs.writeFile(\n path.join(outputDir, 'sidebars.ts'),\n generateSidebars(namespaces),\n );\n\n const totalActions = namespaces.reduce(\n (sum, ns) => sum + ns.actions.length,\n 0,\n );\n const totalEvents = namespaces.reduce((sum, ns) => sum + ns.events.length, 0);\n\n console.log(`Generated docs for ${namespaces.length} namespaces.`);\n console.log(` Actions: ${totalActions}`);\n console.log(` Events: ${totalEvents}`);\n console.log(`Output: ${docsDir}/`);\n\n return {\n namespaces: namespaces.length,\n actions: totalActions,\n events: totalEvents,\n };\n}\n"]}
1
+ {"version":3,"file":"generate.mjs","sourceRoot":"","sources":["../../src/docs/generate.ts"],"names":[],"mappings":"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","sourcesContent":["import { directoryExists } from '@metamask/utils/node';\nimport { execFile } from 'node:child_process';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport { findDtsFiles, findTsFiles } from './discovery';\nimport { extractFromFile } from './extraction';\nimport {\n generateIndexPage,\n generateNamespacePage,\n generateSidebars,\n} from './markdown';\nimport type { MessengerItemDoc, NamespaceGroup } from './types';\n\n/**\n * Compute a deduplication score for a messenger item, preferring items with\n * JSDoc and from the \"home\" package whose name matches the namespace.\n *\n * @param item - The messenger item to score.\n * @returns A numeric score (higher is better).\n */\nfunction deduplicationScore(item: MessengerItemDoc): number {\n const jsDocScore = item.jsDoc ? 2 : 0;\n const namespacePrefix = item.typeString\n .split(':')[0]\n .replace(/Controller|Service/u, '')\n .toLowerCase();\n const homeScore = item.sourceFile.includes(namespacePrefix) ? 1 : 0;\n return jsDocScore + homeScore;\n}\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Resolve the GitHub blob base URL for a project by reading its git remote.\n *\n * @param projectPath - Absolute path to the project root.\n * @returns A base URL like \"https://github.com/Owner/Repo/blob/main/\" or null.\n */\nasync function resolveRepoBaseUrl(projectPath: string): Promise<string | null> {\n try {\n const { stdout: remoteRaw } = await execFileAsync(\n 'git',\n ['remote', 'get-url', 'origin'],\n { cwd: projectPath },\n );\n\n const remote = remoteRaw.trim();\n\n // Parse owner/repo from SSH or HTTPS remote URLs\n // Handles aliases like github.com-Org used in SSH configs\n const match = remote.match(\n /github\\.com[^:/]*[:/]([^/]+\\/[^/]+?)(?:\\.git)?$/u,\n );\n if (!match) {\n return null;\n }\n\n return `https://github.com/${match[1]}/blob/main/`;\n } catch {\n return null;\n }\n}\n\n/**\n * Options for the generate function.\n */\nexport type GenerateOptions = {\n /** Absolute path to the project to scan. */\n projectPath: string;\n /** Absolute path to the output directory for generated docs. */\n outputDir: string;\n /** Directories (relative to projectPath) to scan for .ts source files. */\n scanDirs: string[];\n};\n\n/**\n * Result returned by the generate function.\n */\nexport type GenerateResult = {\n namespaces: number;\n actions: number;\n events: number;\n};\n\n/**\n * Scan a project for messenger action/event types and generate documentation.\n *\n * @param options - Generation options.\n * @returns A promise resolving to counts of generated namespaces, actions, and events.\n */\nexport async function generate(\n options: GenerateOptions,\n): Promise<GenerateResult> {\n const { projectPath, outputDir, scanDirs } = options;\n\n const allItems: MessengerItemDoc[] = [];\n\n // Check which sources are available\n const existingScanDirs: string[] = [];\n for (const dir of scanDirs) {\n const abs = path.join(projectPath, dir);\n if (await directoryExists(abs)) {\n existingScanDirs.push(dir);\n }\n }\n const packagesDir = path.join(projectPath, 'packages');\n const hasPackages = await directoryExists(packagesDir);\n const nmDir = path.join(projectPath, 'node_modules', '@metamask');\n const hasNodeModules = await directoryExists(nmDir);\n\n const sources: string[] = [];\n for (const dir of existingScanDirs) {\n sources.push(`${dir}/ (.ts)`);\n }\n if (hasPackages) {\n sources.push('packages/*/src (.ts)');\n }\n if (hasNodeModules) {\n sources.push('node_modules/@metamask/*/dist (.d.cts)');\n }\n console.log(\n `Scanning ${sources.join(', ')} for Messenger action/event types...`,\n );\n\n // Scan configured source directories for .ts files\n for (const dir of existingScanDirs) {\n const abs = path.join(projectPath, dir);\n const tsFiles = await findTsFiles(abs);\n for (const file of tsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n\n // Scan packages/*/src for .ts source files (monorepo)\n if (hasPackages) {\n const entries = await fs.readdir(packagesDir, { withFileTypes: true });\n const packageDirs = entries\n .filter((dirent) => dirent.isDirectory())\n .map((dirent) => path.join(packagesDir, dirent.name, 'src'));\n\n for (const srcDir of packageDirs) {\n if (!(await directoryExists(srcDir))) {\n continue;\n }\n\n const tsFiles = await findTsFiles(srcDir);\n for (const file of tsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n }\n\n // Scan node_modules/@metamask/*/dist for .d.cts declaration files\n if (hasNodeModules) {\n const entries = await fs.readdir(nmDir, { withFileTypes: true });\n const pkgDirs = entries\n .filter((dirent) => dirent.isDirectory() || dirent.isSymbolicLink())\n .map((dirent) => path.join(nmDir, dirent.name, 'dist'));\n\n for (const distDir of pkgDirs) {\n if (!(await directoryExists(distDir))) {\n continue;\n }\n\n const dtsFiles = await findDtsFiles(distDir);\n for (const file of dtsFiles) {\n try {\n const items = await extractFromFile(file, projectPath);\n allItems.push(...items);\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(\n projectPath,\n file,\n )}: ${String(error)}`,\n );\n }\n }\n }\n }\n\n if (existingScanDirs.length === 0 && !hasPackages && !hasNodeModules) {\n throw new Error(\n `No scannable directories found in ${projectPath}. ` +\n `Looked for: ${scanDirs.join(', ')}, packages/, node_modules/@metamask/`,\n );\n }\n\n console.log(`Found ${allItems.length} messenger items total.`);\n\n // Group by namespace (part before the colon), deduplicating by typeString.\n // When duplicates exist, prefer the one with JSDoc, or from the package\n // whose name matches the namespace.\n const byNamespace = new Map<string, NamespaceGroup>();\n const seen = new Map<string, MessengerItemDoc>(); // key: typeString\n\n for (const item of allItems) {\n const existing = seen.get(item.typeString);\n if (existing) {\n // Prefer item with JSDoc, or from the \"home\" package\n const existingScore = deduplicationScore(existing);\n const newScore = deduplicationScore(item);\n if (newScore <= existingScore) {\n continue;\n }\n // Replace existing with better item\n const ns = item.typeString.split(':')[0];\n const group = byNamespace.get(ns);\n if (group) {\n const list = existing.kind === 'action' ? group.actions : group.events;\n const idx = list.indexOf(existing);\n if (idx !== -1) {\n list[idx] = item;\n }\n }\n seen.set(item.typeString, item);\n continue;\n }\n\n seen.set(item.typeString, item);\n const ns = item.typeString.split(':')[0];\n if (!byNamespace.has(ns)) {\n byNamespace.set(ns, { namespace: ns, actions: [], events: [] });\n }\n const group = byNamespace.get(ns);\n if (group) {\n if (item.kind === 'action') {\n group.actions.push(item);\n } else {\n group.events.push(item);\n }\n }\n }\n\n // Sort namespaces alphabetically, sort items within each namespace\n const namespaces = Array.from(byNamespace.values()).sort((a, b) =>\n a.namespace.localeCompare(b.namespace),\n );\n\n for (const ns of namespaces) {\n ns.actions.sort((a, b) => a.typeString.localeCompare(b.typeString));\n ns.events.sort((a, b) => a.typeString.localeCompare(b.typeString));\n }\n\n // Resolve repository base URL for source links\n const repoBaseUrl = await resolveRepoBaseUrl(projectPath);\n\n // Write output\n const docsDir = path.join(outputDir, 'docs');\n\n // Clean existing generated docs\n if (await directoryExists(docsDir)) {\n await fs.rm(docsDir, { recursive: true });\n }\n await fs.mkdir(docsDir, { recursive: true });\n\n // Generate namespace pages\n for (const ns of namespaces) {\n const nsDir = path.join(docsDir, ns.namespace);\n await fs.mkdir(nsDir, { recursive: true });\n\n if (ns.actions.length > 0) {\n await fs.writeFile(\n path.join(nsDir, 'actions.md'),\n generateNamespacePage(ns, 'action', repoBaseUrl),\n );\n }\n\n if (ns.events.length > 0) {\n await fs.writeFile(\n path.join(nsDir, 'events.md'),\n generateNamespacePage(ns, 'event', repoBaseUrl),\n );\n }\n }\n\n // Generate index page\n await fs.writeFile(\n path.join(docsDir, 'index.md'),\n generateIndexPage(namespaces),\n );\n\n // Generate sidebars\n await fs.writeFile(\n path.join(outputDir, 'sidebars.ts'),\n generateSidebars(namespaces),\n );\n\n const totalActions = namespaces.reduce(\n (sum, ns) => sum + ns.actions.length,\n 0,\n );\n const totalEvents = namespaces.reduce((sum, ns) => sum + ns.events.length, 0);\n\n console.log(`Generated docs for ${namespaces.length} namespaces.`);\n console.log(` Actions: ${totalActions}`);\n console.log(` Events: ${totalEvents}`);\n console.log(`Output: ${docsDir}/`);\n\n return {\n namespaces: namespaces.length,\n actions: totalActions,\n events: totalEvents,\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/messenger-cli",
3
- "version": "0.1.0-preview-8f51c7a3a",
3
+ "version": "0.1.0-preview-2a71f636e",
4
4
  "description": "CLI tools for the MetaMask messenger system",
5
5
  "keywords": [
6
6
  "MetaMask",