@metamask-previews/platform-api-docs 0.1.0-preview-abca9bcea → 0.1.0-preview-8bfa290fb
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.
- package/CHANGELOG.md +0 -1
- package/dist/discovery.cjs +53 -0
- package/dist/discovery.cjs.map +1 -0
- package/dist/discovery.d.cts +22 -0
- package/dist/discovery.d.cts.map +1 -0
- package/dist/discovery.d.mts +22 -0
- package/dist/discovery.d.mts.map +1 -0
- package/dist/discovery.mjs +48 -0
- package/dist/discovery.mjs.map +1 -0
- package/dist/extraction.cjs +27 -1
- package/dist/extraction.cjs.map +1 -1
- package/dist/extraction.d.cts +10 -0
- package/dist/extraction.d.cts.map +1 -1
- package/dist/extraction.d.mts +10 -0
- package/dist/extraction.d.mts.map +1 -1
- package/dist/extraction.mjs +26 -1
- package/dist/extraction.mjs.map +1 -1
- package/dist/generate.cjs +59 -102
- package/dist/generate.cjs.map +1 -1
- package/dist/generate.d.cts.map +1 -1
- package/dist/generate.d.mts.map +1 -1
- package/dist/generate.mjs +60 -103
- package/dist/generate.mjs.map +1 -1
- package/dist/root-messenger-discovery.cjs +26 -5
- package/dist/root-messenger-discovery.cjs.map +1 -1
- package/dist/root-messenger-discovery.d.cts.map +1 -1
- package/dist/root-messenger-discovery.d.mts.map +1 -1
- package/dist/root-messenger-discovery.mjs +27 -6
- package/dist/root-messenger-discovery.mjs.map +1 -1
- package/package.json +2 -1
- package/dist/ts-project.cjs +0 -33
- package/dist/ts-project.cjs.map +0 -1
- package/dist/ts-project.d.cts +0 -12
- package/dist/ts-project.d.cts.map +0 -1
- package/dist/ts-project.d.mts +0 -12
- package/dist/ts-project.d.mts.map +0 -1
- package/dist/ts-project.mjs +0 -29
- package/dist/ts-project.mjs.map +0 -1
package/dist/generate.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.cjs","sourceRoot":"","sources":["../src/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';\nimport type { Project } from 'ts-morph';\n\nimport { extractFromSourceFile } from './extraction.js';\nimport {\n generateIndexPage,\n generateNamespacePage,\n generateSidebars,\n} from './markdown.js';\nimport type { RootCapabilitiesTypeReference } from './root-messenger-discovery.js';\nimport { discoverFromRootMessengerCapabilitiesTypes } from './root-messenger-discovery.js';\nimport { createProject } from './ts-project.js';\nimport type { MessengerCapabilityPacket, NamespaceGroup } from './types.js';\n\n/** How many skipped capability types to name before summarizing the rest. */\nconst MAX_SKIPPED_SHOWN = 10;\n\n/**\n * Options for the `scan` strategy, which reads every `*Messenger` type alias\n * in every file it can find. Used when no single messenger aggregates every\n * capability.\n */\ntype ScanStrategyOptions = {\n /** The selected strategy. */\n strategy: 'scan';\n /** Directories, relative to the project root, to scan. */\n scanDirs: string[];\n};\n\n/**\n * Options for the `root-messenger` strategy, which walks the types a\n * project declares for its root messenger capabilities instead of scanning the\n * entire repo. Used when one messenger carries every action and event.\n */\ntype RootMessengerStrategyOptions = {\n /** The selected strategy. */\n strategy: 'root-messenger';\n /** The root messenger actions type reference. */\n rootActions: RootCapabilitiesTypeReference;\n /** The root messenger events type reference. */\n rootEvents: RootCapabilitiesTypeReference;\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 /**\n * Short label identifying the project the docs were generated from (e.g.\n * \"Core\", \"Extension\"). Stamped in the index page title.\n */\n projectLabel?: string | null;\n /**\n * Git commit SHA the docs were generated from. Stamped in the index page\n * intro so engineers know how current the site is.\n */\n commitSha?: string | null;\n} & (ScanStrategyOptions | RootMessengerStrategyOptions);\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 * The set of directories available to scan for messenger types, resolved from\n * the project's filesystem layout.\n */\ntype ScanSources = {\n /** User-configured scan dirs that exist on disk (relative to projectPath). */\n scanDirs: string[];\n /** Absolute path to `packages/` if it exists, otherwise null. */\n packagesDir: string | null;\n /** Absolute path to `node_modules/@metamask/` if it exists, otherwise null. */\n nodeModulesDir: string | null;\n};\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: MessengerCapabilityPacket): 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 =\n namespacePrefix.length > 0 &&\n item.sourceFile.toLowerCase().includes(namespacePrefix)\n ? 1\n : 0;\n return jsDocScore + homeScore;\n}\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Resolve the default branch of a project's `origin` remote by reading the\n * symbolic ref `refs/remotes/origin/HEAD`. Falls back to `main` if the\n * symbolic ref isn't set (e.g. in shallow CI clones).\n *\n * @param projectPath - Absolute path to the project root.\n * @returns The default branch name (e.g. \"main\", \"master\", \"develop\").\n */\nasync function resolveDefaultBranch(projectPath: string): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\n 'git',\n ['symbolic-ref', '--short', 'refs/remotes/origin/HEAD'],\n { cwd: projectPath },\n );\n // stdout looks like \"origin/main\"; strip the leading \"origin/\".\n const trimmed = stdout.trim();\n const slash = trimmed.indexOf('/');\n return slash === -1\n ? // istanbul ignore next: defensive — `symbolic-ref --short` always\n // returns `origin/<branch>` when the symbolic ref is set; this\n // fallback only matters if git's output format ever changes.\n trimmed || 'main'\n : trimmed.slice(slash + 1);\n } catch {\n return 'main';\n }\n}\n\n/**\n * Resolve the bare GitHub repository URL for a project by reading its\n * `origin` remote.\n *\n * @param projectPath - Absolute path to the project root.\n * @returns A URL like \"https://github.com/Owner/Repo\" or null when the remote\n * isn't a GitHub URL or can't be read.\n */\nexport async function resolveRepoUrl(\n projectPath: string,\n): 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]}`;\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve the GitHub blob base URL used for per-line source links.\n *\n * Prefers the documented commit SHA when one is available so the links point\n * at the exact revision the docs were generated from; falls back to the\n * default branch otherwise.\n *\n * @param projectPath - Absolute path to the project root.\n * @param commitSha - Optional commit SHA to use as the ref. When null, the\n * default branch is used instead.\n * @returns A base URL like \"https://github.com/Owner/Repo/blob/<ref>/\" or null.\n */\nasync function resolveRepoBaseUrl(\n projectPath: string,\n commitSha: string | null,\n): Promise<string | null> {\n const repoUrl = await resolveRepoUrl(projectPath);\n if (!repoUrl) {\n return null;\n }\n const ref = commitSha ?? (await resolveDefaultBranch(projectPath));\n return `${repoUrl}/blob/${ref}/`;\n}\n\n/**\n * Discover which configured source locations actually exist on disk.\n *\n * @param projectPath - The project root path.\n * @param scanDirs - User-configured scan directories relative to projectPath.\n * @returns A ScanSources object describing the locations to scan.\n */\nasync function discoverScanSources(\n projectPath: string,\n scanDirs: string[],\n): Promise<ScanSources> {\n const existingScanDirs: string[] = [];\n for (const dir of scanDirs) {\n if (await directoryExists(path.join(projectPath, dir))) {\n existingScanDirs.push(dir);\n }\n }\n\n const packagesDir = path.join(projectPath, 'packages');\n const nodeModulesDir = path.join(projectPath, 'node_modules', '@metamask');\n\n return {\n scanDirs: existingScanDirs,\n packagesDir: (await directoryExists(packagesDir)) ? packagesDir : null,\n nodeModulesDir: (await directoryExists(nodeModulesDir))\n ? nodeModulesDir\n : null,\n };\n}\n\n/**\n * Log a human-readable description of which source locations will be scanned.\n *\n * @param sources - The resolved scan sources.\n */\nfunction logScanPlan(sources: ScanSources): void {\n const summary: string[] = [];\n for (const dir of sources.scanDirs) {\n summary.push(`${dir}/ (.ts)`);\n }\n if (sources.packagesDir) {\n summary.push('packages/*/src (.ts)');\n }\n if (sources.nodeModulesDir) {\n summary.push('node_modules/@metamask/*/dist (.d.cts)');\n }\n console.log(\n `Scanning ${summary.join(', ')} for Messenger action/event types...`,\n );\n}\n\n/**\n * Patterns excluded when scanning TypeScript sources: build output, tests, and\n * declaration files (which are only read under `node_modules/@metamask`, via\n * the separate set below).\n *\n * Every pattern is anchored to `root` rather than written as a bare\n * `!**/*.test.ts`. A matcher resolves an unanchored negation against the\n * process's working directory, not against the pattern it accompanies, so an\n * unanchored exclusion silently stops excluding anything the moment the scanned\n * path falls outside the working directory — which is the normal case, since\n * this runs from wherever the consumer invoked it.\n *\n * `contentRoot` must be the directory the matched *files* live under, not an\n * ancestor of it. Anchoring at `packages/` rather than `packages/*/src` would\n * make the first path segment a package name, so a workspace package called\n * `test` or `dist` would match `test/**` and be dropped whole.\n *\n * @param contentRoot - Resolved directory, or directory glob, that the matched\n * files live directly under.\n * @returns The exclusion patterns.\n */\nfunction buildTsSourceExclusions(contentRoot: string): string[] {\n return [\n 'node_modules/**',\n 'dist/**',\n '__tests__/**',\n 'tests/**',\n 'test/**',\n '__mocks__/**',\n '*.test.ts',\n '*.test-d.ts',\n '*.spec.ts',\n '*.d.ts',\n ].map((pattern) => `!${contentRoot}/**/${pattern}`);\n}\n\n/**\n * Add every file matching a set of glob patterns to the project, in a stable\n * order.\n *\n * ts-morph promises nothing about the order it returns matches in, and\n * deduplication downstream keeps the first of two equally-scored items, so an\n * unsorted list would let the filesystem decide which source link a capability\n * gets.\n *\n * Ordering is by code unit rather than `localeCompare`, which collates\n * differently depending on the locale the process happens to run under.\n *\n * @param project - The shared ts-morph project.\n * @param patterns - Glob patterns to match, including `!` exclusions.\n * @returns The added source files, sorted by path.\n */\nfunction addSourceFiles(\n project: Project,\n patterns: string[],\n): ReturnType<Project['addSourceFilesAtPaths']> {\n return project.addSourceFilesAtPaths(patterns).sort(\n (fileA, fileB) =>\n // Subtracting the two comparisons keeps this branchless, so it reads\n // the same whichever order the matcher happened to return.\n Number(fileA.getFilePath() > fileB.getFilePath()) -\n Number(fileA.getFilePath() < fileB.getFilePath()),\n );\n}\n\n/**\n * Build a glob pattern from a directory path.\n *\n * Two things have to be true of the result. Glob syntax is always\n * forward-slashed, including on Windows, where `path.join` would produce\n * backslashes that a matcher reads as escapes. And the path must be fully\n * resolved: the matcher does not follow a symlinked *ancestor* of the pattern,\n * so a project under `/tmp` or `/var` on macOS (both symlinks) would match\n * nothing at all.\n *\n * @param segments - Path segments to join.\n * @returns The joined, resolved path with forward slashes.\n */\nasync function toGlobPath(...segments: string[]): Promise<string> {\n // Safe to resolve without a fallback: `discoverScanSources` has already\n // confirmed every directory reaching this point exists.\n const resolved = await fs.realpath(path.join(...segments));\n return resolved.replace(/\\\\/gu, '/');\n}\n\n/**\n * Scan every source location described by `sources` (scan directories first,\n * then workspace packages, then published declaration files) and return all\n * extracted messenger items.\n *\n * A single ts-morph Project is shared across every file so the type checker can\n * resolve cross-file references (e.g. a `*Messenger` declaration in one file\n * walking through an imported umbrella union into an auto-generated\n * `*-method-action-types.ts` sibling).\n *\n * @param projectPath - The project root path.\n * @param sources - The set of source locations to scan.\n * @returns A flat list of all extracted messenger items.\n */\nasync function scanSources(\n projectPath: string,\n sources: ScanSources,\n): Promise<MessengerCapabilityPacket[]> {\n const project = createProject();\n const sourceFiles = [];\n\n for (const dir of sources.scanDirs) {\n const root = await toGlobPath(projectPath, dir);\n sourceFiles.push(\n ...addSourceFiles(project, [\n `${root}/**/*.ts`,\n ...buildTsSourceExclusions(root),\n ]),\n );\n }\n\n if (sources.packagesDir) {\n const root = await toGlobPath(sources.packagesDir);\n // Anchored at each package's `src`, not at `packages` itself, so a package\n // whose name collides with an exclusion (`test`, `dist`) isn't dropped.\n const contentRoot = `${root}/*/src`;\n sourceFiles.push(\n ...addSourceFiles(project, [\n `${contentRoot}/**/*.ts`,\n ...buildTsSourceExclusions(contentRoot),\n ]),\n );\n }\n\n if (sources.nodeModulesDir) {\n const root = await toGlobPath(sources.nodeModulesDir);\n sourceFiles.push(...addSourceFiles(project, [`${root}/*/dist/**/*.d.cts`]));\n }\n\n // Matched paths are fully resolved, so the root they are made relative to\n // has to be resolved the same way or every source link becomes a `../..`\n // walk out of the project.\n const resolvedProjectPath = await fs.realpath(projectPath);\n\n const allItems: MessengerCapabilityPacket[] = [];\n for (const sourceFile of sourceFiles) {\n allItems.push(...extractFromSourceFile(sourceFile, resolvedProjectPath));\n }\n return allItems;\n}\n\n/**\n * Replace a previously-seen item in its existing namespace group with a\n * higher-scoring duplicate. Handles the case where the duplicate is a\n * different kind (action vs event) by moving it between lists.\n *\n * @param byNamespace - Map of namespace to its group.\n * @param previous - The previously stored item.\n * @param replacement - The new item to replace it with.\n */\nfunction replaceDuplicateInGroup(\n byNamespace: Map<string, NamespaceGroup>,\n previous: MessengerCapabilityPacket,\n replacement: MessengerCapabilityPacket,\n): void {\n const namespace = replacement.typeString.split(':')[0];\n const group = byNamespace.get(namespace);\n // istanbul ignore next: `previous` and `replacement` have the same\n // typeString, so they share a namespace, and we always insert the\n // namespace into `byNamespace` before recording the original entry.\n if (!group) {\n return;\n }\n const previousList =\n previous.kind === 'action' ? group.actions : group.events;\n const index = previousList.indexOf(previous);\n // istanbul ignore next: `previous` was added to its kind's list by\n // `groupByNamespace` before being recorded in `seen`, so it is always\n // present when we look it up here.\n if (index === -1) {\n return;\n }\n if (previous.kind === replacement.kind) {\n previousList[index] = replacement;\n } else {\n previousList.splice(index, 1);\n const newList =\n replacement.kind === 'action' ? group.actions : group.events;\n newList.push(replacement);\n }\n}\n\n/**\n * Group items by namespace, deduplicating duplicate typeStrings using\n * `deduplicationScore`. Returns groups sorted alphabetically by namespace,\n * with each group's items sorted alphabetically by typeString.\n *\n * @param items - The full list of extracted items.\n * @returns The deduplicated and sorted namespace groups.\n */\nfunction groupByNamespace(\n items: MessengerCapabilityPacket[],\n): NamespaceGroup[] {\n const byNamespace = new Map<string, NamespaceGroup>();\n const seen = new Map<string, MessengerCapabilityPacket>();\n\n for (const item of items) {\n const existing = seen.get(item.typeString);\n if (existing) {\n if (deduplicationScore(item) <= deduplicationScore(existing)) {\n continue;\n }\n replaceDuplicateInGroup(byNamespace, existing, item);\n seen.set(item.typeString, item);\n continue;\n }\n\n seen.set(item.typeString, item);\n const namespace = item.typeString.split(':')[0];\n let group = byNamespace.get(namespace);\n if (!group) {\n group = { namespace, actions: [], events: [] };\n byNamespace.set(namespace, group);\n }\n if (item.kind === 'action') {\n group.actions.push(item);\n } else {\n group.events.push(item);\n }\n }\n\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 return namespaces;\n}\n\n/**\n * Write generated docs (namespace pages, index page, sidebars) to disk,\n * replacing any existing `docs/` directory.\n *\n * @param namespaces - The grouped namespaces to render.\n * @param outputDir - The root output directory.\n * @param repoBaseUrl - GitHub blob base URL for source links, or null.\n * @param indexOptions - Options stamped on the index page header.\n * @param indexOptions.projectLabel - Short label identifying the project.\n * @param indexOptions.commitSha - Git commit SHA the docs were generated from.\n * @returns Promise that resolves once all files are written.\n */\nasync function writeOutput(\n namespaces: NamespaceGroup[],\n outputDir: string,\n repoBaseUrl: string | null,\n indexOptions: {\n projectLabel?: string | null;\n commitSha?: string | null;\n },\n): Promise<void> {\n const docsDir = path.join(outputDir, 'docs');\n\n if (await directoryExists(docsDir)) {\n await fs.rm(docsDir, { recursive: true });\n }\n await fs.mkdir(docsDir, { recursive: true });\n\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 await fs.writeFile(\n path.join(docsDir, 'index.md'),\n generateIndexPage(namespaces, indexOptions),\n );\n\n await fs.writeFile(\n path.join(outputDir, 'sidebars.ts'),\n generateSidebars(namespaces),\n );\n}\n\n/**\n * Collect capabilities by scanning the project's files.\n *\n * @param projectPath - The project root path.\n * @param scanDirs - Directories (relative to projectPath) to scan.\n * @returns The extracted capabilities.\n * @throws If the project has no scannable directories at all.\n */\nasync function collectByScanning(\n projectPath: string,\n scanDirs: string[],\n): Promise<MessengerCapabilityPacket[]> {\n const sources = await discoverScanSources(projectPath, scanDirs);\n\n if (\n sources.scanDirs.length === 0 &&\n !sources.packagesDir &&\n !sources.nodeModulesDir\n ) {\n throw new Error(\n `No scannable directories found in ${projectPath}. ` +\n `Looked for: ${scanDirs.join(', ')}, packages/, node_modules/@metamask/`,\n );\n }\n\n logScanPlan(sources);\n\n return await scanSources(projectPath, sources);\n}\n\n/**\n * Using the project's root messenger capability collection types as\n * entrypoints, collect the constituent individual capability types and package\n * them so that they can be displayed within the documentation site.\n *\n * @param projectPath - The project root path.\n * @param options - The root-messenger strategy options.\n * @returns The extracted capabilities.\n */\nfunction collectFromRootMessengerCapabilities(\n projectPath: string,\n options: RootMessengerStrategyOptions,\n): MessengerCapabilityPacket[] {\n const { rootActions, rootEvents } = options;\n\n console.log(\n `Resolving actions from ${rootActions.filePath}#${rootActions.typeName} ` +\n `and events from ${rootEvents.filePath}#${rootEvents.typeName}...`,\n );\n\n const { capabilityPackets, skippedCapabilities } =\n discoverFromRootMessengerCapabilitiesTypes({\n projectPath,\n rootActionsTypeReference: rootActions,\n rootEventsTypeReference: rootEvents,\n });\n\n // Report rather than drop silently: a jump in any of these usually means the\n // project changed how it declares its capabilities.\n warnSkipped(\n 'declared inline, with no name to document',\n skippedCapabilities.unnamedCapabilities,\n );\n warnSkipped(\n 'whose shape could not be read',\n skippedCapabilities.unextractableCapabilities,\n );\n\n // If both capability collection types resolve to nothing, it's always a\n // misconfiguration (a wrong type name, or imports that didn't resolve).\n // Failing here matters because generation would otherwise replace an existing\n // docs directory with an empty one and exit successfully.\n if (capabilityPackets.length === 0) {\n throw new Error(\n `No messenger actions or events found in ` +\n `${rootActions.filePath}#${rootActions.typeName} or ` +\n `${rootEvents.filePath}#${rootEvents.typeName}. ` +\n `Check that these types name the collections carrying every ` +\n `capability, and that their imports resolve.`,\n );\n }\n\n return capabilityPackets;\n}\n\n/**\n * Warn about capability types that couldn't be documented, naming them so the\n * warning is actionable.\n *\n * @param description - Why they were skipped, as a noun phrase.\n * @param labels - Labels identifying each skipped type.\n */\nfunction warnSkipped(description: string, labels: string[]): void {\n if (labels.length === 0) {\n return;\n }\n\n const shown = labels.slice(0, MAX_SKIPPED_SHOWN);\n const remaining = labels.length - shown.length;\n console.warn(\n `Warning: skipped ${labels.length} capability ` +\n `${labels.length === 1 ? 'type' : 'types'} ${description}: ` +\n `${shown.join(', ')}${remaining > 0 ? `, and ${remaining} more` : ''}`,\n );\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, projectLabel, commitSha } = options;\n\n const allItems =\n options.strategy === 'root-messenger'\n ? collectFromRootMessengerCapabilities(projectPath, options)\n : await collectByScanning(projectPath, options.scanDirs);\n\n console.log(\n `Found ${allItems.length} messenger ${allItems.length === 1 ? 'item' : 'items'} total.`,\n );\n\n const namespaces = groupByNamespace(allItems);\n const repoBaseUrl = await resolveRepoBaseUrl(projectPath, commitSha ?? null);\n\n await writeOutput(namespaces, outputDir, repoBaseUrl, {\n projectLabel,\n commitSha,\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(\n `Generated docs for ${namespaces.length} ${namespaces.length === 1 ? 'namespace' : 'namespaces'}.`,\n );\n console.log(` Actions: ${totalActions}`);\n console.log(` Events: ${totalEvents}`);\n console.log(`Output: ${path.join(outputDir, 'docs')}/`);\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/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';\nimport type { Project } from 'ts-morph';\n\nimport { findDtsFiles, findTsFiles } from './discovery.js';\nimport {\n createExtractionProject,\n extractFromSourceFile,\n} from './extraction.js';\nimport {\n generateIndexPage,\n generateNamespacePage,\n generateSidebars,\n} from './markdown.js';\nimport type { RootCapabilitiesTypeReference } from './root-messenger-discovery.js';\nimport { discoverFromRootMessengerCapabilitiesTypes } from './root-messenger-discovery.js';\nimport type { MessengerCapabilityPacket, NamespaceGroup } from './types.js';\n\n/** How many skipped capability types to name before summarizing the rest. */\nconst MAX_SKIPPED_SHOWN = 10;\n\n/**\n * Options for the `scan` strategy, which reads every `*Messenger` type alias\n * in every file it can find. Used when no single messenger aggregates every\n * capability.\n */\ntype ScanStrategyOptions = {\n /** The selected strategy. */\n strategy: 'scan';\n /** Directories, relative to the project root, to scan. */\n scanDirs: string[];\n};\n\n/**\n * Options for the `root-messenger` strategy, which walks the types a\n * project declares for its root messenger capabilities instead of scanning the\n * entire repo. Used when one messenger carries every action and event.\n */\ntype RootMessengerStrategyOptions = {\n /** The selected strategy. */\n strategy: 'root-messenger';\n /** The root messenger actions type reference. */\n rootActions: RootCapabilitiesTypeReference;\n /** The root messenger events type reference. */\n rootEvents: RootCapabilitiesTypeReference;\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 /**\n * Short label identifying the project the docs were generated from (e.g.\n * \"Core\", \"Extension\"). Stamped in the index page title.\n */\n projectLabel?: string | null;\n /**\n * Git commit SHA the docs were generated from. Stamped in the index page\n * intro so engineers know how current the site is.\n */\n commitSha?: string | null;\n} & (ScanStrategyOptions | RootMessengerStrategyOptions);\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 * The set of directories available to scan for messenger types, resolved from\n * the project's filesystem layout.\n */\ntype ScanSources = {\n /** User-configured scan dirs that exist on disk (relative to projectPath). */\n scanDirs: string[];\n /** Absolute path to `packages/` if it exists, otherwise null. */\n packagesDir: string | null;\n /** Absolute path to `node_modules/@metamask/` if it exists, otherwise null. */\n nodeModulesDir: string | null;\n};\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: MessengerCapabilityPacket): 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 =\n namespacePrefix.length > 0 &&\n item.sourceFile.toLowerCase().includes(namespacePrefix)\n ? 1\n : 0;\n return jsDocScore + homeScore;\n}\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Resolve the default branch of a project's `origin` remote by reading the\n * symbolic ref `refs/remotes/origin/HEAD`. Falls back to `main` if the\n * symbolic ref isn't set (e.g. in shallow CI clones).\n *\n * @param projectPath - Absolute path to the project root.\n * @returns The default branch name (e.g. \"main\", \"master\", \"develop\").\n */\nasync function resolveDefaultBranch(projectPath: string): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\n 'git',\n ['symbolic-ref', '--short', 'refs/remotes/origin/HEAD'],\n { cwd: projectPath },\n );\n // stdout looks like \"origin/main\"; strip the leading \"origin/\".\n const trimmed = stdout.trim();\n const slash = trimmed.indexOf('/');\n return slash === -1\n ? // istanbul ignore next: defensive — `symbolic-ref --short` always\n // returns `origin/<branch>` when the symbolic ref is set; this\n // fallback only matters if git's output format ever changes.\n trimmed || 'main'\n : trimmed.slice(slash + 1);\n } catch {\n return 'main';\n }\n}\n\n/**\n * Resolve the bare GitHub repository URL for a project by reading its\n * `origin` remote.\n *\n * @param projectPath - Absolute path to the project root.\n * @returns A URL like \"https://github.com/Owner/Repo\" or null when the remote\n * isn't a GitHub URL or can't be read.\n */\nexport async function resolveRepoUrl(\n projectPath: string,\n): 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]}`;\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve the GitHub blob base URL used for per-line source links.\n *\n * Prefers the documented commit SHA when one is available so the links point\n * at the exact revision the docs were generated from; falls back to the\n * default branch otherwise.\n *\n * @param projectPath - Absolute path to the project root.\n * @param commitSha - Optional commit SHA to use as the ref. When null, the\n * default branch is used instead.\n * @returns A base URL like \"https://github.com/Owner/Repo/blob/<ref>/\" or null.\n */\nasync function resolveRepoBaseUrl(\n projectPath: string,\n commitSha: string | null,\n): Promise<string | null> {\n const repoUrl = await resolveRepoUrl(projectPath);\n if (!repoUrl) {\n return null;\n }\n const ref = commitSha ?? (await resolveDefaultBranch(projectPath));\n return `${repoUrl}/blob/${ref}/`;\n}\n\n/**\n * Discover which configured source locations actually exist on disk.\n *\n * @param projectPath - The project root path.\n * @param scanDirs - User-configured scan directories relative to projectPath.\n * @returns A ScanSources object describing the locations to scan.\n */\nasync function discoverScanSources(\n projectPath: string,\n scanDirs: string[],\n): Promise<ScanSources> {\n const existingScanDirs: string[] = [];\n for (const dir of scanDirs) {\n if (await directoryExists(path.join(projectPath, dir))) {\n existingScanDirs.push(dir);\n }\n }\n\n const packagesDir = path.join(projectPath, 'packages');\n const nodeModulesDir = path.join(projectPath, 'node_modules', '@metamask');\n\n return {\n scanDirs: existingScanDirs,\n packagesDir: (await directoryExists(packagesDir)) ? packagesDir : null,\n nodeModulesDir: (await directoryExists(nodeModulesDir))\n ? nodeModulesDir\n : null,\n };\n}\n\n/**\n * Log a human-readable description of which source locations will be scanned.\n *\n * @param sources - The resolved scan sources.\n */\nfunction logScanPlan(sources: ScanSources): void {\n const summary: string[] = [];\n for (const dir of sources.scanDirs) {\n summary.push(`${dir}/ (.ts)`);\n }\n if (sources.packagesDir) {\n summary.push('packages/*/src (.ts)');\n }\n if (sources.nodeModulesDir) {\n summary.push('node_modules/@metamask/*/dist (.d.cts)');\n }\n console.log(\n `Scanning ${summary.join(', ')} for Messenger action/event types...`,\n );\n}\n\n/**\n * Run extraction against every file in a single directory, logging and\n * swallowing per-file failures. All files are added to the shared `project`\n * up front so the type checker can resolve cross-file references when the\n * walker descends into imported types.\n *\n * @param project - The shared ts-morph project.\n * @param directory - The directory to scan.\n * @param projectPath - The project root, used for relative path display.\n * @param findFiles - The function used to enumerate files in the directory.\n * @returns The list of extracted messenger items.\n */\nasync function extractFromDirectory(\n project: Project,\n directory: string,\n projectPath: string,\n findFiles: (dir: string) => Promise<string[]>,\n): Promise<MessengerCapabilityPacket[]> {\n const items: MessengerCapabilityPacket[] = [];\n const files = await findFiles(directory);\n for (const file of files) {\n try {\n const sourceFile =\n project.getSourceFile(file) ?? project.addSourceFileAtPath(file);\n items.push(...extractFromSourceFile(sourceFile, projectPath));\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(projectPath, file)}`,\n );\n console.warn(error);\n }\n }\n return items;\n}\n\n/**\n * Enumerate the subdirectories of a parent directory that match the expected\n * layout (e.g., `packages/*/src` or `node_modules/@metamask/*/dist`), keeping\n * only those that actually exist.\n *\n * @param parentDir - The parent directory to enumerate.\n * @param subPath - The trailing path component appended to each entry.\n * @param includeSymlinks - Whether to include symbolic links (true for\n * node_modules where workspaces are symlinked).\n * @returns The list of absolute paths to existing target subdirectories.\n */\nasync function listTargetSubdirectories(\n parentDir: string,\n subPath: string,\n includeSymlinks: boolean,\n): Promise<string[]> {\n const entries = await fs.readdir(parentDir, { withFileTypes: true });\n const candidates = entries\n .filter(\n (entry) =>\n entry.isDirectory() || (includeSymlinks && entry.isSymbolicLink()),\n )\n .map((entry) => path.join(parentDir, entry.name, subPath));\n\n const existing: string[] = [];\n for (const candidate of candidates) {\n if (await directoryExists(candidate)) {\n existing.push(candidate);\n }\n }\n return existing;\n}\n\n/**\n * Scan every source location described by `sources` and return all extracted\n * messenger items. A single ts-morph Project is shared across every file so\n * the type checker can resolve cross-file references (e.g. a `*Messenger`\n * declaration in one file walking through an imported umbrella union into\n * an auto-generated `*-method-action-types.ts` sibling).\n *\n * @param projectPath - The project root path.\n * @param sources - The set of source locations to scan.\n * @returns A flat list of all extracted messenger items.\n */\nasync function scanSources(\n projectPath: string,\n sources: ScanSources,\n): Promise<MessengerCapabilityPacket[]> {\n const project = createExtractionProject();\n const allItems: MessengerCapabilityPacket[] = [];\n\n for (const dir of sources.scanDirs) {\n allItems.push(\n ...(await extractFromDirectory(\n project,\n path.join(projectPath, dir),\n projectPath,\n findTsFiles,\n )),\n );\n }\n\n if (sources.packagesDir) {\n const srcDirs = await listTargetSubdirectories(\n sources.packagesDir,\n 'src',\n false,\n );\n for (const srcDir of srcDirs) {\n allItems.push(\n ...(await extractFromDirectory(\n project,\n srcDir,\n projectPath,\n findTsFiles,\n )),\n );\n }\n }\n\n if (sources.nodeModulesDir) {\n const distDirs = await listTargetSubdirectories(\n sources.nodeModulesDir,\n 'dist',\n true,\n );\n for (const distDir of distDirs) {\n allItems.push(\n ...(await extractFromDirectory(\n project,\n distDir,\n projectPath,\n findDtsFiles,\n )),\n );\n }\n }\n\n return allItems;\n}\n\n/**\n * Replace a previously-seen item in its existing namespace group with a\n * higher-scoring duplicate. Handles the case where the duplicate is a\n * different kind (action vs event) by moving it between lists.\n *\n * @param byNamespace - Map of namespace to its group.\n * @param previous - The previously stored item.\n * @param replacement - The new item to replace it with.\n */\nfunction replaceDuplicateInGroup(\n byNamespace: Map<string, NamespaceGroup>,\n previous: MessengerCapabilityPacket,\n replacement: MessengerCapabilityPacket,\n): void {\n const namespace = replacement.typeString.split(':')[0];\n const group = byNamespace.get(namespace);\n // istanbul ignore next: `previous` and `replacement` have the same\n // typeString, so they share a namespace, and we always insert the\n // namespace into `byNamespace` before recording the original entry.\n if (!group) {\n return;\n }\n const previousList =\n previous.kind === 'action' ? group.actions : group.events;\n const index = previousList.indexOf(previous);\n // istanbul ignore next: `previous` was added to its kind's list by\n // `groupByNamespace` before being recorded in `seen`, so it is always\n // present when we look it up here.\n if (index === -1) {\n return;\n }\n if (previous.kind === replacement.kind) {\n previousList[index] = replacement;\n } else {\n previousList.splice(index, 1);\n const newList =\n replacement.kind === 'action' ? group.actions : group.events;\n newList.push(replacement);\n }\n}\n\n/**\n * Group items by namespace, deduplicating duplicate typeStrings using\n * `deduplicationScore`. Returns groups sorted alphabetically by namespace,\n * with each group's items sorted alphabetically by typeString.\n *\n * @param items - The full list of extracted items.\n * @returns The deduplicated and sorted namespace groups.\n */\nfunction groupByNamespace(\n items: MessengerCapabilityPacket[],\n): NamespaceGroup[] {\n const byNamespace = new Map<string, NamespaceGroup>();\n const seen = new Map<string, MessengerCapabilityPacket>();\n\n for (const item of items) {\n const existing = seen.get(item.typeString);\n if (existing) {\n if (deduplicationScore(item) <= deduplicationScore(existing)) {\n continue;\n }\n replaceDuplicateInGroup(byNamespace, existing, item);\n seen.set(item.typeString, item);\n continue;\n }\n\n seen.set(item.typeString, item);\n const namespace = item.typeString.split(':')[0];\n let group = byNamespace.get(namespace);\n if (!group) {\n group = { namespace, actions: [], events: [] };\n byNamespace.set(namespace, group);\n }\n if (item.kind === 'action') {\n group.actions.push(item);\n } else {\n group.events.push(item);\n }\n }\n\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 return namespaces;\n}\n\n/**\n * Write generated docs (namespace pages, index page, sidebars) to disk,\n * replacing any existing `docs/` directory.\n *\n * @param namespaces - The grouped namespaces to render.\n * @param outputDir - The root output directory.\n * @param repoBaseUrl - GitHub blob base URL for source links, or null.\n * @param indexOptions - Options stamped on the index page header.\n * @param indexOptions.projectLabel - Short label identifying the project.\n * @param indexOptions.commitSha - Git commit SHA the docs were generated from.\n * @returns Promise that resolves once all files are written.\n */\nasync function writeOutput(\n namespaces: NamespaceGroup[],\n outputDir: string,\n repoBaseUrl: string | null,\n indexOptions: {\n projectLabel?: string | null;\n commitSha?: string | null;\n },\n): Promise<void> {\n const docsDir = path.join(outputDir, 'docs');\n\n if (await directoryExists(docsDir)) {\n await fs.rm(docsDir, { recursive: true });\n }\n await fs.mkdir(docsDir, { recursive: true });\n\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 await fs.writeFile(\n path.join(docsDir, 'index.md'),\n generateIndexPage(namespaces, indexOptions),\n );\n\n await fs.writeFile(\n path.join(outputDir, 'sidebars.ts'),\n generateSidebars(namespaces),\n );\n}\n\n/**\n * Collect capabilities by scanning the project's files.\n *\n * @param projectPath - The project root path.\n * @param scanDirs - Directories (relative to projectPath) to scan.\n * @returns The extracted capabilities.\n * @throws If the project has no scannable directories at all.\n */\nasync function collectByScanning(\n projectPath: string,\n scanDirs: string[],\n): Promise<MessengerCapabilityPacket[]> {\n const sources = await discoverScanSources(projectPath, scanDirs);\n\n if (\n sources.scanDirs.length === 0 &&\n !sources.packagesDir &&\n !sources.nodeModulesDir\n ) {\n throw new Error(\n `No scannable directories found in ${projectPath}. ` +\n `Looked for: ${scanDirs.join(', ')}, packages/, node_modules/@metamask/`,\n );\n }\n\n logScanPlan(sources);\n\n return await scanSources(projectPath, sources);\n}\n\n/**\n * Using the project's root messenger capability collection types as\n * entrypoints, collect the constituent individual capability types and package\n * them so that they can be displayed within the documentation site.\n *\n * @param projectPath - The project root path.\n * @param options - The root-messenger strategy options.\n * @returns The extracted capabilities.\n */\nfunction collectFromRootMessengerCapabilities(\n projectPath: string,\n options: RootMessengerStrategyOptions,\n): MessengerCapabilityPacket[] {\n const { rootActions, rootEvents } = options;\n\n console.log(\n `Resolving actions from ${rootActions.filePath}#${rootActions.typeName} ` +\n `and events from ${rootEvents.filePath}#${rootEvents.typeName}...`,\n );\n\n const { capabilityPackets, skippedCapabilities } =\n discoverFromRootMessengerCapabilitiesTypes({\n projectPath,\n rootActionsTypeReference: rootActions,\n rootEventsTypeReference: rootEvents,\n });\n\n // Report rather than drop silently: a jump in any of these usually means the\n // project changed how it declares its capabilities.\n warnSkipped(\n 'declared inline, with no name to document',\n skippedCapabilities.unnamedCapabilities,\n );\n warnSkipped(\n 'whose shape could not be read',\n skippedCapabilities.unextractableCapabilities,\n );\n\n // If both capability collection types resolve to nothing, it's always a\n // misconfiguration (a wrong type name, or imports that didn't resolve).\n // Failing here matters because generation would otherwise replace an existing\n // docs directory with an empty one and exit successfully.\n if (capabilityPackets.length === 0) {\n throw new Error(\n `No messenger actions or events found in ` +\n `${rootActions.filePath}#${rootActions.typeName} or ` +\n `${rootEvents.filePath}#${rootEvents.typeName}. ` +\n `Check that these types name the collections carrying every ` +\n `capability, and that their imports resolve.`,\n );\n }\n\n return capabilityPackets;\n}\n\n/**\n * Warn about capability types that couldn't be documented, naming them so the\n * warning is actionable.\n *\n * @param description - Why they were skipped, as a noun phrase.\n * @param labels - Labels identifying each skipped type.\n */\nfunction warnSkipped(description: string, labels: string[]): void {\n if (labels.length === 0) {\n return;\n }\n\n const shown = labels.slice(0, MAX_SKIPPED_SHOWN);\n const remaining = labels.length - shown.length;\n console.warn(\n `Warning: skipped ${labels.length} capability ` +\n `${labels.length === 1 ? 'type' : 'types'} ${description}: ` +\n `${shown.join(', ')}${remaining > 0 ? `, and ${remaining} more` : ''}`,\n );\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, projectLabel, commitSha } = options;\n\n const allItems =\n options.strategy === 'root-messenger'\n ? collectFromRootMessengerCapabilities(projectPath, options)\n : await collectByScanning(projectPath, options.scanDirs);\n\n console.log(\n `Found ${allItems.length} messenger ${allItems.length === 1 ? 'item' : 'items'} total.`,\n );\n\n const namespaces = groupByNamespace(allItems);\n const repoBaseUrl = await resolveRepoBaseUrl(projectPath, commitSha ?? null);\n\n await writeOutput(namespaces, outputDir, repoBaseUrl, {\n projectLabel,\n commitSha,\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(\n `Generated docs for ${namespaces.length} ${namespaces.length === 1 ? 'namespace' : 'namespaces'}.`,\n );\n console.log(` Actions: ${totalActions}`);\n console.log(` Events: ${totalEvents}`);\n console.log(`Output: ${path.join(outputDir, 'docs')}/`);\n\n return {\n namespaces: namespaces.length,\n actions: totalActions,\n events: totalEvents,\n };\n}\n"]}
|
package/dist/generate.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.cts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate.d.cts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,6BAA6B,EAAE,uCAAsC;AAOnF;;;;GAIG;AACH,KAAK,mBAAmB,GAAG;IACzB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,KAAK,4BAA4B,GAAG;IAClC,6BAA6B;IAC7B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,iDAAiD;IACjD,WAAW,EAAE,6BAA6B,CAAC;IAC3C,gDAAgD;IAChD,UAAU,EAAE,6BAA6B,CAAC;CAC3C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,CAAC,mBAAmB,GAAG,4BAA4B,CAAC,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAmEF;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuBxB;AAqdD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAsCzB"}
|
package/dist/generate.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.mts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate.d.mts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,6BAA6B,EAAE,uCAAsC;AAOnF;;;;GAIG;AACH,KAAK,mBAAmB,GAAG;IACzB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,KAAK,4BAA4B,GAAG;IAClC,6BAA6B;IAC7B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,iDAAiD;IACjD,WAAW,EAAE,6BAA6B,CAAC;IAC3C,gDAAgD;IAChD,UAAU,EAAE,6BAA6B,CAAC;CAC3C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,CAAC,mBAAmB,GAAG,4BAA4B,CAAC,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAmEF;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuBxB;AAqdD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAsCzB"}
|
package/dist/generate.mjs
CHANGED
|
@@ -3,10 +3,10 @@ import { execFile } from "node:child_process";
|
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import { promisify } from "node:util";
|
|
6
|
-
import {
|
|
6
|
+
import { findDtsFiles, findTsFiles } from "./discovery.mjs";
|
|
7
|
+
import { createExtractionProject, extractFromSourceFile } from "./extraction.mjs";
|
|
7
8
|
import { generateIndexPage, generateNamespacePage, generateSidebars } from "./markdown.mjs";
|
|
8
9
|
import { discoverFromRootMessengerCapabilitiesTypes } from "./root-messenger-discovery.mjs";
|
|
9
|
-
import { createProject } from "./ts-project.mjs";
|
|
10
10
|
/** How many skipped capability types to name before summarizing the rest. */
|
|
11
11
|
const MAX_SKIPPED_SHOWN = 10;
|
|
12
12
|
/**
|
|
@@ -141,127 +141,84 @@ function logScanPlan(sources) {
|
|
|
141
141
|
console.log(`Scanning ${summary.join(', ')} for Messenger action/event types...`);
|
|
142
142
|
}
|
|
143
143
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* the
|
|
147
|
-
*
|
|
148
|
-
* Every pattern is anchored to `root` rather than written as a bare
|
|
149
|
-
* `!**/*.test.ts`. A matcher resolves an unanchored negation against the
|
|
150
|
-
* process's working directory, not against the pattern it accompanies, so an
|
|
151
|
-
* unanchored exclusion silently stops excluding anything the moment the scanned
|
|
152
|
-
* path falls outside the working directory — which is the normal case, since
|
|
153
|
-
* this runs from wherever the consumer invoked it.
|
|
154
|
-
*
|
|
155
|
-
* `contentRoot` must be the directory the matched *files* live under, not an
|
|
156
|
-
* ancestor of it. Anchoring at `packages/` rather than `packages/*/src` would
|
|
157
|
-
* make the first path segment a package name, so a workspace package called
|
|
158
|
-
* `test` or `dist` would match `test/**` and be dropped whole.
|
|
159
|
-
*
|
|
160
|
-
* @param contentRoot - Resolved directory, or directory glob, that the matched
|
|
161
|
-
* files live directly under.
|
|
162
|
-
* @returns The exclusion patterns.
|
|
163
|
-
*/
|
|
164
|
-
function buildTsSourceExclusions(contentRoot) {
|
|
165
|
-
return [
|
|
166
|
-
'node_modules/**',
|
|
167
|
-
'dist/**',
|
|
168
|
-
'__tests__/**',
|
|
169
|
-
'tests/**',
|
|
170
|
-
'test/**',
|
|
171
|
-
'__mocks__/**',
|
|
172
|
-
'*.test.ts',
|
|
173
|
-
'*.test-d.ts',
|
|
174
|
-
'*.spec.ts',
|
|
175
|
-
'*.d.ts',
|
|
176
|
-
].map((pattern) => `!${contentRoot}/**/${pattern}`);
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Add every file matching a set of glob patterns to the project, in a stable
|
|
180
|
-
* order.
|
|
181
|
-
*
|
|
182
|
-
* ts-morph promises nothing about the order it returns matches in, and
|
|
183
|
-
* deduplication downstream keeps the first of two equally-scored items, so an
|
|
184
|
-
* unsorted list would let the filesystem decide which source link a capability
|
|
185
|
-
* gets.
|
|
186
|
-
*
|
|
187
|
-
* Ordering is by code unit rather than `localeCompare`, which collates
|
|
188
|
-
* differently depending on the locale the process happens to run under.
|
|
144
|
+
* Run extraction against every file in a single directory, logging and
|
|
145
|
+
* swallowing per-file failures. All files are added to the shared `project`
|
|
146
|
+
* up front so the type checker can resolve cross-file references when the
|
|
147
|
+
* walker descends into imported types.
|
|
189
148
|
*
|
|
190
149
|
* @param project - The shared ts-morph project.
|
|
191
|
-
* @param
|
|
192
|
-
* @
|
|
150
|
+
* @param directory - The directory to scan.
|
|
151
|
+
* @param projectPath - The project root, used for relative path display.
|
|
152
|
+
* @param findFiles - The function used to enumerate files in the directory.
|
|
153
|
+
* @returns The list of extracted messenger items.
|
|
193
154
|
*/
|
|
194
|
-
function
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
155
|
+
async function extractFromDirectory(project, directory, projectPath, findFiles) {
|
|
156
|
+
const items = [];
|
|
157
|
+
const files = await findFiles(directory);
|
|
158
|
+
for (const file of files) {
|
|
159
|
+
try {
|
|
160
|
+
const sourceFile = project.getSourceFile(file) ?? project.addSourceFileAtPath(file);
|
|
161
|
+
items.push(...extractFromSourceFile(sourceFile, projectPath));
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
console.warn(`Warning: failed to parse ${path.relative(projectPath, file)}`);
|
|
165
|
+
console.warn(error);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return items;
|
|
200
169
|
}
|
|
201
170
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
* forward-slashed, including on Windows, where `path.join` would produce
|
|
206
|
-
* backslashes that a matcher reads as escapes. And the path must be fully
|
|
207
|
-
* resolved: the matcher does not follow a symlinked *ancestor* of the pattern,
|
|
208
|
-
* so a project under `/tmp` or `/var` on macOS (both symlinks) would match
|
|
209
|
-
* nothing at all.
|
|
171
|
+
* Enumerate the subdirectories of a parent directory that match the expected
|
|
172
|
+
* layout (e.g., `packages/*/src` or `node_modules/@metamask/*/dist`), keeping
|
|
173
|
+
* only those that actually exist.
|
|
210
174
|
*
|
|
211
|
-
* @param
|
|
212
|
-
* @
|
|
175
|
+
* @param parentDir - The parent directory to enumerate.
|
|
176
|
+
* @param subPath - The trailing path component appended to each entry.
|
|
177
|
+
* @param includeSymlinks - Whether to include symbolic links (true for
|
|
178
|
+
* node_modules where workspaces are symlinked).
|
|
179
|
+
* @returns The list of absolute paths to existing target subdirectories.
|
|
213
180
|
*/
|
|
214
|
-
async function
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
181
|
+
async function listTargetSubdirectories(parentDir, subPath, includeSymlinks) {
|
|
182
|
+
const entries = await fs.readdir(parentDir, { withFileTypes: true });
|
|
183
|
+
const candidates = entries
|
|
184
|
+
.filter((entry) => entry.isDirectory() || (includeSymlinks && entry.isSymbolicLink()))
|
|
185
|
+
.map((entry) => path.join(parentDir, entry.name, subPath));
|
|
186
|
+
const existing = [];
|
|
187
|
+
for (const candidate of candidates) {
|
|
188
|
+
if (await directoryExists(candidate)) {
|
|
189
|
+
existing.push(candidate);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return existing;
|
|
219
193
|
}
|
|
220
194
|
/**
|
|
221
|
-
* Scan every source location described by `sources`
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
* resolve cross-file references (e.g. a `*Messenger` declaration in one file
|
|
227
|
-
* walking through an imported umbrella union into an auto-generated
|
|
228
|
-
* `*-method-action-types.ts` sibling).
|
|
195
|
+
* Scan every source location described by `sources` and return all extracted
|
|
196
|
+
* messenger items. A single ts-morph Project is shared across every file so
|
|
197
|
+
* the type checker can resolve cross-file references (e.g. a `*Messenger`
|
|
198
|
+
* declaration in one file walking through an imported umbrella union into
|
|
199
|
+
* an auto-generated `*-method-action-types.ts` sibling).
|
|
229
200
|
*
|
|
230
201
|
* @param projectPath - The project root path.
|
|
231
202
|
* @param sources - The set of source locations to scan.
|
|
232
203
|
* @returns A flat list of all extracted messenger items.
|
|
233
204
|
*/
|
|
234
205
|
async function scanSources(projectPath, sources) {
|
|
235
|
-
const project =
|
|
236
|
-
const
|
|
206
|
+
const project = createExtractionProject();
|
|
207
|
+
const allItems = [];
|
|
237
208
|
for (const dir of sources.scanDirs) {
|
|
238
|
-
|
|
239
|
-
sourceFiles.push(...addSourceFiles(project, [
|
|
240
|
-
`${root}/**/*.ts`,
|
|
241
|
-
...buildTsSourceExclusions(root),
|
|
242
|
-
]));
|
|
209
|
+
allItems.push(...(await extractFromDirectory(project, path.join(projectPath, dir), projectPath, findTsFiles)));
|
|
243
210
|
}
|
|
244
211
|
if (sources.packagesDir) {
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
sourceFiles.push(...addSourceFiles(project, [
|
|
250
|
-
`${contentRoot}/**/*.ts`,
|
|
251
|
-
...buildTsSourceExclusions(contentRoot),
|
|
252
|
-
]));
|
|
212
|
+
const srcDirs = await listTargetSubdirectories(sources.packagesDir, 'src', false);
|
|
213
|
+
for (const srcDir of srcDirs) {
|
|
214
|
+
allItems.push(...(await extractFromDirectory(project, srcDir, projectPath, findTsFiles)));
|
|
215
|
+
}
|
|
253
216
|
}
|
|
254
217
|
if (sources.nodeModulesDir) {
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
// has to be resolved the same way or every source link becomes a `../..`
|
|
260
|
-
// walk out of the project.
|
|
261
|
-
const resolvedProjectPath = await fs.realpath(projectPath);
|
|
262
|
-
const allItems = [];
|
|
263
|
-
for (const sourceFile of sourceFiles) {
|
|
264
|
-
allItems.push(...extractFromSourceFile(sourceFile, resolvedProjectPath));
|
|
218
|
+
const distDirs = await listTargetSubdirectories(sources.nodeModulesDir, 'dist', true);
|
|
219
|
+
for (const distDir of distDirs) {
|
|
220
|
+
allItems.push(...(await extractFromDirectory(project, distDir, projectPath, findDtsFiles)));
|
|
221
|
+
}
|
|
265
222
|
}
|
|
266
223
|
return allItems;
|
|
267
224
|
}
|
package/dist/generate.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.mjs","sourceRoot":"","sources":["../src/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';\nimport type { Project } from 'ts-morph';\n\nimport { extractFromSourceFile } from './extraction.js';\nimport {\n generateIndexPage,\n generateNamespacePage,\n generateSidebars,\n} from './markdown.js';\nimport type { RootCapabilitiesTypeReference } from './root-messenger-discovery.js';\nimport { discoverFromRootMessengerCapabilitiesTypes } from './root-messenger-discovery.js';\nimport { createProject } from './ts-project.js';\nimport type { MessengerCapabilityPacket, NamespaceGroup } from './types.js';\n\n/** How many skipped capability types to name before summarizing the rest. */\nconst MAX_SKIPPED_SHOWN = 10;\n\n/**\n * Options for the `scan` strategy, which reads every `*Messenger` type alias\n * in every file it can find. Used when no single messenger aggregates every\n * capability.\n */\ntype ScanStrategyOptions = {\n /** The selected strategy. */\n strategy: 'scan';\n /** Directories, relative to the project root, to scan. */\n scanDirs: string[];\n};\n\n/**\n * Options for the `root-messenger` strategy, which walks the types a\n * project declares for its root messenger capabilities instead of scanning the\n * entire repo. Used when one messenger carries every action and event.\n */\ntype RootMessengerStrategyOptions = {\n /** The selected strategy. */\n strategy: 'root-messenger';\n /** The root messenger actions type reference. */\n rootActions: RootCapabilitiesTypeReference;\n /** The root messenger events type reference. */\n rootEvents: RootCapabilitiesTypeReference;\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 /**\n * Short label identifying the project the docs were generated from (e.g.\n * \"Core\", \"Extension\"). Stamped in the index page title.\n */\n projectLabel?: string | null;\n /**\n * Git commit SHA the docs were generated from. Stamped in the index page\n * intro so engineers know how current the site is.\n */\n commitSha?: string | null;\n} & (ScanStrategyOptions | RootMessengerStrategyOptions);\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 * The set of directories available to scan for messenger types, resolved from\n * the project's filesystem layout.\n */\ntype ScanSources = {\n /** User-configured scan dirs that exist on disk (relative to projectPath). */\n scanDirs: string[];\n /** Absolute path to `packages/` if it exists, otherwise null. */\n packagesDir: string | null;\n /** Absolute path to `node_modules/@metamask/` if it exists, otherwise null. */\n nodeModulesDir: string | null;\n};\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: MessengerCapabilityPacket): 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 =\n namespacePrefix.length > 0 &&\n item.sourceFile.toLowerCase().includes(namespacePrefix)\n ? 1\n : 0;\n return jsDocScore + homeScore;\n}\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Resolve the default branch of a project's `origin` remote by reading the\n * symbolic ref `refs/remotes/origin/HEAD`. Falls back to `main` if the\n * symbolic ref isn't set (e.g. in shallow CI clones).\n *\n * @param projectPath - Absolute path to the project root.\n * @returns The default branch name (e.g. \"main\", \"master\", \"develop\").\n */\nasync function resolveDefaultBranch(projectPath: string): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\n 'git',\n ['symbolic-ref', '--short', 'refs/remotes/origin/HEAD'],\n { cwd: projectPath },\n );\n // stdout looks like \"origin/main\"; strip the leading \"origin/\".\n const trimmed = stdout.trim();\n const slash = trimmed.indexOf('/');\n return slash === -1\n ? // istanbul ignore next: defensive — `symbolic-ref --short` always\n // returns `origin/<branch>` when the symbolic ref is set; this\n // fallback only matters if git's output format ever changes.\n trimmed || 'main'\n : trimmed.slice(slash + 1);\n } catch {\n return 'main';\n }\n}\n\n/**\n * Resolve the bare GitHub repository URL for a project by reading its\n * `origin` remote.\n *\n * @param projectPath - Absolute path to the project root.\n * @returns A URL like \"https://github.com/Owner/Repo\" or null when the remote\n * isn't a GitHub URL or can't be read.\n */\nexport async function resolveRepoUrl(\n projectPath: string,\n): 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]}`;\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve the GitHub blob base URL used for per-line source links.\n *\n * Prefers the documented commit SHA when one is available so the links point\n * at the exact revision the docs were generated from; falls back to the\n * default branch otherwise.\n *\n * @param projectPath - Absolute path to the project root.\n * @param commitSha - Optional commit SHA to use as the ref. When null, the\n * default branch is used instead.\n * @returns A base URL like \"https://github.com/Owner/Repo/blob/<ref>/\" or null.\n */\nasync function resolveRepoBaseUrl(\n projectPath: string,\n commitSha: string | null,\n): Promise<string | null> {\n const repoUrl = await resolveRepoUrl(projectPath);\n if (!repoUrl) {\n return null;\n }\n const ref = commitSha ?? (await resolveDefaultBranch(projectPath));\n return `${repoUrl}/blob/${ref}/`;\n}\n\n/**\n * Discover which configured source locations actually exist on disk.\n *\n * @param projectPath - The project root path.\n * @param scanDirs - User-configured scan directories relative to projectPath.\n * @returns A ScanSources object describing the locations to scan.\n */\nasync function discoverScanSources(\n projectPath: string,\n scanDirs: string[],\n): Promise<ScanSources> {\n const existingScanDirs: string[] = [];\n for (const dir of scanDirs) {\n if (await directoryExists(path.join(projectPath, dir))) {\n existingScanDirs.push(dir);\n }\n }\n\n const packagesDir = path.join(projectPath, 'packages');\n const nodeModulesDir = path.join(projectPath, 'node_modules', '@metamask');\n\n return {\n scanDirs: existingScanDirs,\n packagesDir: (await directoryExists(packagesDir)) ? packagesDir : null,\n nodeModulesDir: (await directoryExists(nodeModulesDir))\n ? nodeModulesDir\n : null,\n };\n}\n\n/**\n * Log a human-readable description of which source locations will be scanned.\n *\n * @param sources - The resolved scan sources.\n */\nfunction logScanPlan(sources: ScanSources): void {\n const summary: string[] = [];\n for (const dir of sources.scanDirs) {\n summary.push(`${dir}/ (.ts)`);\n }\n if (sources.packagesDir) {\n summary.push('packages/*/src (.ts)');\n }\n if (sources.nodeModulesDir) {\n summary.push('node_modules/@metamask/*/dist (.d.cts)');\n }\n console.log(\n `Scanning ${summary.join(', ')} for Messenger action/event types...`,\n );\n}\n\n/**\n * Patterns excluded when scanning TypeScript sources: build output, tests, and\n * declaration files (which are only read under `node_modules/@metamask`, via\n * the separate set below).\n *\n * Every pattern is anchored to `root` rather than written as a bare\n * `!**/*.test.ts`. A matcher resolves an unanchored negation against the\n * process's working directory, not against the pattern it accompanies, so an\n * unanchored exclusion silently stops excluding anything the moment the scanned\n * path falls outside the working directory — which is the normal case, since\n * this runs from wherever the consumer invoked it.\n *\n * `contentRoot` must be the directory the matched *files* live under, not an\n * ancestor of it. Anchoring at `packages/` rather than `packages/*/src` would\n * make the first path segment a package name, so a workspace package called\n * `test` or `dist` would match `test/**` and be dropped whole.\n *\n * @param contentRoot - Resolved directory, or directory glob, that the matched\n * files live directly under.\n * @returns The exclusion patterns.\n */\nfunction buildTsSourceExclusions(contentRoot: string): string[] {\n return [\n 'node_modules/**',\n 'dist/**',\n '__tests__/**',\n 'tests/**',\n 'test/**',\n '__mocks__/**',\n '*.test.ts',\n '*.test-d.ts',\n '*.spec.ts',\n '*.d.ts',\n ].map((pattern) => `!${contentRoot}/**/${pattern}`);\n}\n\n/**\n * Add every file matching a set of glob patterns to the project, in a stable\n * order.\n *\n * ts-morph promises nothing about the order it returns matches in, and\n * deduplication downstream keeps the first of two equally-scored items, so an\n * unsorted list would let the filesystem decide which source link a capability\n * gets.\n *\n * Ordering is by code unit rather than `localeCompare`, which collates\n * differently depending on the locale the process happens to run under.\n *\n * @param project - The shared ts-morph project.\n * @param patterns - Glob patterns to match, including `!` exclusions.\n * @returns The added source files, sorted by path.\n */\nfunction addSourceFiles(\n project: Project,\n patterns: string[],\n): ReturnType<Project['addSourceFilesAtPaths']> {\n return project.addSourceFilesAtPaths(patterns).sort(\n (fileA, fileB) =>\n // Subtracting the two comparisons keeps this branchless, so it reads\n // the same whichever order the matcher happened to return.\n Number(fileA.getFilePath() > fileB.getFilePath()) -\n Number(fileA.getFilePath() < fileB.getFilePath()),\n );\n}\n\n/**\n * Build a glob pattern from a directory path.\n *\n * Two things have to be true of the result. Glob syntax is always\n * forward-slashed, including on Windows, where `path.join` would produce\n * backslashes that a matcher reads as escapes. And the path must be fully\n * resolved: the matcher does not follow a symlinked *ancestor* of the pattern,\n * so a project under `/tmp` or `/var` on macOS (both symlinks) would match\n * nothing at all.\n *\n * @param segments - Path segments to join.\n * @returns The joined, resolved path with forward slashes.\n */\nasync function toGlobPath(...segments: string[]): Promise<string> {\n // Safe to resolve without a fallback: `discoverScanSources` has already\n // confirmed every directory reaching this point exists.\n const resolved = await fs.realpath(path.join(...segments));\n return resolved.replace(/\\\\/gu, '/');\n}\n\n/**\n * Scan every source location described by `sources` (scan directories first,\n * then workspace packages, then published declaration files) and return all\n * extracted messenger items.\n *\n * A single ts-morph Project is shared across every file so the type checker can\n * resolve cross-file references (e.g. a `*Messenger` declaration in one file\n * walking through an imported umbrella union into an auto-generated\n * `*-method-action-types.ts` sibling).\n *\n * @param projectPath - The project root path.\n * @param sources - The set of source locations to scan.\n * @returns A flat list of all extracted messenger items.\n */\nasync function scanSources(\n projectPath: string,\n sources: ScanSources,\n): Promise<MessengerCapabilityPacket[]> {\n const project = createProject();\n const sourceFiles = [];\n\n for (const dir of sources.scanDirs) {\n const root = await toGlobPath(projectPath, dir);\n sourceFiles.push(\n ...addSourceFiles(project, [\n `${root}/**/*.ts`,\n ...buildTsSourceExclusions(root),\n ]),\n );\n }\n\n if (sources.packagesDir) {\n const root = await toGlobPath(sources.packagesDir);\n // Anchored at each package's `src`, not at `packages` itself, so a package\n // whose name collides with an exclusion (`test`, `dist`) isn't dropped.\n const contentRoot = `${root}/*/src`;\n sourceFiles.push(\n ...addSourceFiles(project, [\n `${contentRoot}/**/*.ts`,\n ...buildTsSourceExclusions(contentRoot),\n ]),\n );\n }\n\n if (sources.nodeModulesDir) {\n const root = await toGlobPath(sources.nodeModulesDir);\n sourceFiles.push(...addSourceFiles(project, [`${root}/*/dist/**/*.d.cts`]));\n }\n\n // Matched paths are fully resolved, so the root they are made relative to\n // has to be resolved the same way or every source link becomes a `../..`\n // walk out of the project.\n const resolvedProjectPath = await fs.realpath(projectPath);\n\n const allItems: MessengerCapabilityPacket[] = [];\n for (const sourceFile of sourceFiles) {\n allItems.push(...extractFromSourceFile(sourceFile, resolvedProjectPath));\n }\n return allItems;\n}\n\n/**\n * Replace a previously-seen item in its existing namespace group with a\n * higher-scoring duplicate. Handles the case where the duplicate is a\n * different kind (action vs event) by moving it between lists.\n *\n * @param byNamespace - Map of namespace to its group.\n * @param previous - The previously stored item.\n * @param replacement - The new item to replace it with.\n */\nfunction replaceDuplicateInGroup(\n byNamespace: Map<string, NamespaceGroup>,\n previous: MessengerCapabilityPacket,\n replacement: MessengerCapabilityPacket,\n): void {\n const namespace = replacement.typeString.split(':')[0];\n const group = byNamespace.get(namespace);\n // istanbul ignore next: `previous` and `replacement` have the same\n // typeString, so they share a namespace, and we always insert the\n // namespace into `byNamespace` before recording the original entry.\n if (!group) {\n return;\n }\n const previousList =\n previous.kind === 'action' ? group.actions : group.events;\n const index = previousList.indexOf(previous);\n // istanbul ignore next: `previous` was added to its kind's list by\n // `groupByNamespace` before being recorded in `seen`, so it is always\n // present when we look it up here.\n if (index === -1) {\n return;\n }\n if (previous.kind === replacement.kind) {\n previousList[index] = replacement;\n } else {\n previousList.splice(index, 1);\n const newList =\n replacement.kind === 'action' ? group.actions : group.events;\n newList.push(replacement);\n }\n}\n\n/**\n * Group items by namespace, deduplicating duplicate typeStrings using\n * `deduplicationScore`. Returns groups sorted alphabetically by namespace,\n * with each group's items sorted alphabetically by typeString.\n *\n * @param items - The full list of extracted items.\n * @returns The deduplicated and sorted namespace groups.\n */\nfunction groupByNamespace(\n items: MessengerCapabilityPacket[],\n): NamespaceGroup[] {\n const byNamespace = new Map<string, NamespaceGroup>();\n const seen = new Map<string, MessengerCapabilityPacket>();\n\n for (const item of items) {\n const existing = seen.get(item.typeString);\n if (existing) {\n if (deduplicationScore(item) <= deduplicationScore(existing)) {\n continue;\n }\n replaceDuplicateInGroup(byNamespace, existing, item);\n seen.set(item.typeString, item);\n continue;\n }\n\n seen.set(item.typeString, item);\n const namespace = item.typeString.split(':')[0];\n let group = byNamespace.get(namespace);\n if (!group) {\n group = { namespace, actions: [], events: [] };\n byNamespace.set(namespace, group);\n }\n if (item.kind === 'action') {\n group.actions.push(item);\n } else {\n group.events.push(item);\n }\n }\n\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 return namespaces;\n}\n\n/**\n * Write generated docs (namespace pages, index page, sidebars) to disk,\n * replacing any existing `docs/` directory.\n *\n * @param namespaces - The grouped namespaces to render.\n * @param outputDir - The root output directory.\n * @param repoBaseUrl - GitHub blob base URL for source links, or null.\n * @param indexOptions - Options stamped on the index page header.\n * @param indexOptions.projectLabel - Short label identifying the project.\n * @param indexOptions.commitSha - Git commit SHA the docs were generated from.\n * @returns Promise that resolves once all files are written.\n */\nasync function writeOutput(\n namespaces: NamespaceGroup[],\n outputDir: string,\n repoBaseUrl: string | null,\n indexOptions: {\n projectLabel?: string | null;\n commitSha?: string | null;\n },\n): Promise<void> {\n const docsDir = path.join(outputDir, 'docs');\n\n if (await directoryExists(docsDir)) {\n await fs.rm(docsDir, { recursive: true });\n }\n await fs.mkdir(docsDir, { recursive: true });\n\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 await fs.writeFile(\n path.join(docsDir, 'index.md'),\n generateIndexPage(namespaces, indexOptions),\n );\n\n await fs.writeFile(\n path.join(outputDir, 'sidebars.ts'),\n generateSidebars(namespaces),\n );\n}\n\n/**\n * Collect capabilities by scanning the project's files.\n *\n * @param projectPath - The project root path.\n * @param scanDirs - Directories (relative to projectPath) to scan.\n * @returns The extracted capabilities.\n * @throws If the project has no scannable directories at all.\n */\nasync function collectByScanning(\n projectPath: string,\n scanDirs: string[],\n): Promise<MessengerCapabilityPacket[]> {\n const sources = await discoverScanSources(projectPath, scanDirs);\n\n if (\n sources.scanDirs.length === 0 &&\n !sources.packagesDir &&\n !sources.nodeModulesDir\n ) {\n throw new Error(\n `No scannable directories found in ${projectPath}. ` +\n `Looked for: ${scanDirs.join(', ')}, packages/, node_modules/@metamask/`,\n );\n }\n\n logScanPlan(sources);\n\n return await scanSources(projectPath, sources);\n}\n\n/**\n * Using the project's root messenger capability collection types as\n * entrypoints, collect the constituent individual capability types and package\n * them so that they can be displayed within the documentation site.\n *\n * @param projectPath - The project root path.\n * @param options - The root-messenger strategy options.\n * @returns The extracted capabilities.\n */\nfunction collectFromRootMessengerCapabilities(\n projectPath: string,\n options: RootMessengerStrategyOptions,\n): MessengerCapabilityPacket[] {\n const { rootActions, rootEvents } = options;\n\n console.log(\n `Resolving actions from ${rootActions.filePath}#${rootActions.typeName} ` +\n `and events from ${rootEvents.filePath}#${rootEvents.typeName}...`,\n );\n\n const { capabilityPackets, skippedCapabilities } =\n discoverFromRootMessengerCapabilitiesTypes({\n projectPath,\n rootActionsTypeReference: rootActions,\n rootEventsTypeReference: rootEvents,\n });\n\n // Report rather than drop silently: a jump in any of these usually means the\n // project changed how it declares its capabilities.\n warnSkipped(\n 'declared inline, with no name to document',\n skippedCapabilities.unnamedCapabilities,\n );\n warnSkipped(\n 'whose shape could not be read',\n skippedCapabilities.unextractableCapabilities,\n );\n\n // If both capability collection types resolve to nothing, it's always a\n // misconfiguration (a wrong type name, or imports that didn't resolve).\n // Failing here matters because generation would otherwise replace an existing\n // docs directory with an empty one and exit successfully.\n if (capabilityPackets.length === 0) {\n throw new Error(\n `No messenger actions or events found in ` +\n `${rootActions.filePath}#${rootActions.typeName} or ` +\n `${rootEvents.filePath}#${rootEvents.typeName}. ` +\n `Check that these types name the collections carrying every ` +\n `capability, and that their imports resolve.`,\n );\n }\n\n return capabilityPackets;\n}\n\n/**\n * Warn about capability types that couldn't be documented, naming them so the\n * warning is actionable.\n *\n * @param description - Why they were skipped, as a noun phrase.\n * @param labels - Labels identifying each skipped type.\n */\nfunction warnSkipped(description: string, labels: string[]): void {\n if (labels.length === 0) {\n return;\n }\n\n const shown = labels.slice(0, MAX_SKIPPED_SHOWN);\n const remaining = labels.length - shown.length;\n console.warn(\n `Warning: skipped ${labels.length} capability ` +\n `${labels.length === 1 ? 'type' : 'types'} ${description}: ` +\n `${shown.join(', ')}${remaining > 0 ? `, and ${remaining} more` : ''}`,\n );\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, projectLabel, commitSha } = options;\n\n const allItems =\n options.strategy === 'root-messenger'\n ? collectFromRootMessengerCapabilities(projectPath, options)\n : await collectByScanning(projectPath, options.scanDirs);\n\n console.log(\n `Found ${allItems.length} messenger ${allItems.length === 1 ? 'item' : 'items'} total.`,\n );\n\n const namespaces = groupByNamespace(allItems);\n const repoBaseUrl = await resolveRepoBaseUrl(projectPath, commitSha ?? null);\n\n await writeOutput(namespaces, outputDir, repoBaseUrl, {\n projectLabel,\n commitSha,\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(\n `Generated docs for ${namespaces.length} ${namespaces.length === 1 ? 'namespace' : 'namespaces'}.`,\n );\n console.log(` Actions: ${totalActions}`);\n console.log(` Events: ${totalEvents}`);\n console.log(`Output: ${path.join(outputDir, 'docs')}/`);\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/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';\nimport type { Project } from 'ts-morph';\n\nimport { findDtsFiles, findTsFiles } from './discovery.js';\nimport {\n createExtractionProject,\n extractFromSourceFile,\n} from './extraction.js';\nimport {\n generateIndexPage,\n generateNamespacePage,\n generateSidebars,\n} from './markdown.js';\nimport type { RootCapabilitiesTypeReference } from './root-messenger-discovery.js';\nimport { discoverFromRootMessengerCapabilitiesTypes } from './root-messenger-discovery.js';\nimport type { MessengerCapabilityPacket, NamespaceGroup } from './types.js';\n\n/** How many skipped capability types to name before summarizing the rest. */\nconst MAX_SKIPPED_SHOWN = 10;\n\n/**\n * Options for the `scan` strategy, which reads every `*Messenger` type alias\n * in every file it can find. Used when no single messenger aggregates every\n * capability.\n */\ntype ScanStrategyOptions = {\n /** The selected strategy. */\n strategy: 'scan';\n /** Directories, relative to the project root, to scan. */\n scanDirs: string[];\n};\n\n/**\n * Options for the `root-messenger` strategy, which walks the types a\n * project declares for its root messenger capabilities instead of scanning the\n * entire repo. Used when one messenger carries every action and event.\n */\ntype RootMessengerStrategyOptions = {\n /** The selected strategy. */\n strategy: 'root-messenger';\n /** The root messenger actions type reference. */\n rootActions: RootCapabilitiesTypeReference;\n /** The root messenger events type reference. */\n rootEvents: RootCapabilitiesTypeReference;\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 /**\n * Short label identifying the project the docs were generated from (e.g.\n * \"Core\", \"Extension\"). Stamped in the index page title.\n */\n projectLabel?: string | null;\n /**\n * Git commit SHA the docs were generated from. Stamped in the index page\n * intro so engineers know how current the site is.\n */\n commitSha?: string | null;\n} & (ScanStrategyOptions | RootMessengerStrategyOptions);\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 * The set of directories available to scan for messenger types, resolved from\n * the project's filesystem layout.\n */\ntype ScanSources = {\n /** User-configured scan dirs that exist on disk (relative to projectPath). */\n scanDirs: string[];\n /** Absolute path to `packages/` if it exists, otherwise null. */\n packagesDir: string | null;\n /** Absolute path to `node_modules/@metamask/` if it exists, otherwise null. */\n nodeModulesDir: string | null;\n};\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: MessengerCapabilityPacket): 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 =\n namespacePrefix.length > 0 &&\n item.sourceFile.toLowerCase().includes(namespacePrefix)\n ? 1\n : 0;\n return jsDocScore + homeScore;\n}\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Resolve the default branch of a project's `origin` remote by reading the\n * symbolic ref `refs/remotes/origin/HEAD`. Falls back to `main` if the\n * symbolic ref isn't set (e.g. in shallow CI clones).\n *\n * @param projectPath - Absolute path to the project root.\n * @returns The default branch name (e.g. \"main\", \"master\", \"develop\").\n */\nasync function resolveDefaultBranch(projectPath: string): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\n 'git',\n ['symbolic-ref', '--short', 'refs/remotes/origin/HEAD'],\n { cwd: projectPath },\n );\n // stdout looks like \"origin/main\"; strip the leading \"origin/\".\n const trimmed = stdout.trim();\n const slash = trimmed.indexOf('/');\n return slash === -1\n ? // istanbul ignore next: defensive — `symbolic-ref --short` always\n // returns `origin/<branch>` when the symbolic ref is set; this\n // fallback only matters if git's output format ever changes.\n trimmed || 'main'\n : trimmed.slice(slash + 1);\n } catch {\n return 'main';\n }\n}\n\n/**\n * Resolve the bare GitHub repository URL for a project by reading its\n * `origin` remote.\n *\n * @param projectPath - Absolute path to the project root.\n * @returns A URL like \"https://github.com/Owner/Repo\" or null when the remote\n * isn't a GitHub URL or can't be read.\n */\nexport async function resolveRepoUrl(\n projectPath: string,\n): 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]}`;\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve the GitHub blob base URL used for per-line source links.\n *\n * Prefers the documented commit SHA when one is available so the links point\n * at the exact revision the docs were generated from; falls back to the\n * default branch otherwise.\n *\n * @param projectPath - Absolute path to the project root.\n * @param commitSha - Optional commit SHA to use as the ref. When null, the\n * default branch is used instead.\n * @returns A base URL like \"https://github.com/Owner/Repo/blob/<ref>/\" or null.\n */\nasync function resolveRepoBaseUrl(\n projectPath: string,\n commitSha: string | null,\n): Promise<string | null> {\n const repoUrl = await resolveRepoUrl(projectPath);\n if (!repoUrl) {\n return null;\n }\n const ref = commitSha ?? (await resolveDefaultBranch(projectPath));\n return `${repoUrl}/blob/${ref}/`;\n}\n\n/**\n * Discover which configured source locations actually exist on disk.\n *\n * @param projectPath - The project root path.\n * @param scanDirs - User-configured scan directories relative to projectPath.\n * @returns A ScanSources object describing the locations to scan.\n */\nasync function discoverScanSources(\n projectPath: string,\n scanDirs: string[],\n): Promise<ScanSources> {\n const existingScanDirs: string[] = [];\n for (const dir of scanDirs) {\n if (await directoryExists(path.join(projectPath, dir))) {\n existingScanDirs.push(dir);\n }\n }\n\n const packagesDir = path.join(projectPath, 'packages');\n const nodeModulesDir = path.join(projectPath, 'node_modules', '@metamask');\n\n return {\n scanDirs: existingScanDirs,\n packagesDir: (await directoryExists(packagesDir)) ? packagesDir : null,\n nodeModulesDir: (await directoryExists(nodeModulesDir))\n ? nodeModulesDir\n : null,\n };\n}\n\n/**\n * Log a human-readable description of which source locations will be scanned.\n *\n * @param sources - The resolved scan sources.\n */\nfunction logScanPlan(sources: ScanSources): void {\n const summary: string[] = [];\n for (const dir of sources.scanDirs) {\n summary.push(`${dir}/ (.ts)`);\n }\n if (sources.packagesDir) {\n summary.push('packages/*/src (.ts)');\n }\n if (sources.nodeModulesDir) {\n summary.push('node_modules/@metamask/*/dist (.d.cts)');\n }\n console.log(\n `Scanning ${summary.join(', ')} for Messenger action/event types...`,\n );\n}\n\n/**\n * Run extraction against every file in a single directory, logging and\n * swallowing per-file failures. All files are added to the shared `project`\n * up front so the type checker can resolve cross-file references when the\n * walker descends into imported types.\n *\n * @param project - The shared ts-morph project.\n * @param directory - The directory to scan.\n * @param projectPath - The project root, used for relative path display.\n * @param findFiles - The function used to enumerate files in the directory.\n * @returns The list of extracted messenger items.\n */\nasync function extractFromDirectory(\n project: Project,\n directory: string,\n projectPath: string,\n findFiles: (dir: string) => Promise<string[]>,\n): Promise<MessengerCapabilityPacket[]> {\n const items: MessengerCapabilityPacket[] = [];\n const files = await findFiles(directory);\n for (const file of files) {\n try {\n const sourceFile =\n project.getSourceFile(file) ?? project.addSourceFileAtPath(file);\n items.push(...extractFromSourceFile(sourceFile, projectPath));\n } catch (error) {\n console.warn(\n `Warning: failed to parse ${path.relative(projectPath, file)}`,\n );\n console.warn(error);\n }\n }\n return items;\n}\n\n/**\n * Enumerate the subdirectories of a parent directory that match the expected\n * layout (e.g., `packages/*/src` or `node_modules/@metamask/*/dist`), keeping\n * only those that actually exist.\n *\n * @param parentDir - The parent directory to enumerate.\n * @param subPath - The trailing path component appended to each entry.\n * @param includeSymlinks - Whether to include symbolic links (true for\n * node_modules where workspaces are symlinked).\n * @returns The list of absolute paths to existing target subdirectories.\n */\nasync function listTargetSubdirectories(\n parentDir: string,\n subPath: string,\n includeSymlinks: boolean,\n): Promise<string[]> {\n const entries = await fs.readdir(parentDir, { withFileTypes: true });\n const candidates = entries\n .filter(\n (entry) =>\n entry.isDirectory() || (includeSymlinks && entry.isSymbolicLink()),\n )\n .map((entry) => path.join(parentDir, entry.name, subPath));\n\n const existing: string[] = [];\n for (const candidate of candidates) {\n if (await directoryExists(candidate)) {\n existing.push(candidate);\n }\n }\n return existing;\n}\n\n/**\n * Scan every source location described by `sources` and return all extracted\n * messenger items. A single ts-morph Project is shared across every file so\n * the type checker can resolve cross-file references (e.g. a `*Messenger`\n * declaration in one file walking through an imported umbrella union into\n * an auto-generated `*-method-action-types.ts` sibling).\n *\n * @param projectPath - The project root path.\n * @param sources - The set of source locations to scan.\n * @returns A flat list of all extracted messenger items.\n */\nasync function scanSources(\n projectPath: string,\n sources: ScanSources,\n): Promise<MessengerCapabilityPacket[]> {\n const project = createExtractionProject();\n const allItems: MessengerCapabilityPacket[] = [];\n\n for (const dir of sources.scanDirs) {\n allItems.push(\n ...(await extractFromDirectory(\n project,\n path.join(projectPath, dir),\n projectPath,\n findTsFiles,\n )),\n );\n }\n\n if (sources.packagesDir) {\n const srcDirs = await listTargetSubdirectories(\n sources.packagesDir,\n 'src',\n false,\n );\n for (const srcDir of srcDirs) {\n allItems.push(\n ...(await extractFromDirectory(\n project,\n srcDir,\n projectPath,\n findTsFiles,\n )),\n );\n }\n }\n\n if (sources.nodeModulesDir) {\n const distDirs = await listTargetSubdirectories(\n sources.nodeModulesDir,\n 'dist',\n true,\n );\n for (const distDir of distDirs) {\n allItems.push(\n ...(await extractFromDirectory(\n project,\n distDir,\n projectPath,\n findDtsFiles,\n )),\n );\n }\n }\n\n return allItems;\n}\n\n/**\n * Replace a previously-seen item in its existing namespace group with a\n * higher-scoring duplicate. Handles the case where the duplicate is a\n * different kind (action vs event) by moving it between lists.\n *\n * @param byNamespace - Map of namespace to its group.\n * @param previous - The previously stored item.\n * @param replacement - The new item to replace it with.\n */\nfunction replaceDuplicateInGroup(\n byNamespace: Map<string, NamespaceGroup>,\n previous: MessengerCapabilityPacket,\n replacement: MessengerCapabilityPacket,\n): void {\n const namespace = replacement.typeString.split(':')[0];\n const group = byNamespace.get(namespace);\n // istanbul ignore next: `previous` and `replacement` have the same\n // typeString, so they share a namespace, and we always insert the\n // namespace into `byNamespace` before recording the original entry.\n if (!group) {\n return;\n }\n const previousList =\n previous.kind === 'action' ? group.actions : group.events;\n const index = previousList.indexOf(previous);\n // istanbul ignore next: `previous` was added to its kind's list by\n // `groupByNamespace` before being recorded in `seen`, so it is always\n // present when we look it up here.\n if (index === -1) {\n return;\n }\n if (previous.kind === replacement.kind) {\n previousList[index] = replacement;\n } else {\n previousList.splice(index, 1);\n const newList =\n replacement.kind === 'action' ? group.actions : group.events;\n newList.push(replacement);\n }\n}\n\n/**\n * Group items by namespace, deduplicating duplicate typeStrings using\n * `deduplicationScore`. Returns groups sorted alphabetically by namespace,\n * with each group's items sorted alphabetically by typeString.\n *\n * @param items - The full list of extracted items.\n * @returns The deduplicated and sorted namespace groups.\n */\nfunction groupByNamespace(\n items: MessengerCapabilityPacket[],\n): NamespaceGroup[] {\n const byNamespace = new Map<string, NamespaceGroup>();\n const seen = new Map<string, MessengerCapabilityPacket>();\n\n for (const item of items) {\n const existing = seen.get(item.typeString);\n if (existing) {\n if (deduplicationScore(item) <= deduplicationScore(existing)) {\n continue;\n }\n replaceDuplicateInGroup(byNamespace, existing, item);\n seen.set(item.typeString, item);\n continue;\n }\n\n seen.set(item.typeString, item);\n const namespace = item.typeString.split(':')[0];\n let group = byNamespace.get(namespace);\n if (!group) {\n group = { namespace, actions: [], events: [] };\n byNamespace.set(namespace, group);\n }\n if (item.kind === 'action') {\n group.actions.push(item);\n } else {\n group.events.push(item);\n }\n }\n\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 return namespaces;\n}\n\n/**\n * Write generated docs (namespace pages, index page, sidebars) to disk,\n * replacing any existing `docs/` directory.\n *\n * @param namespaces - The grouped namespaces to render.\n * @param outputDir - The root output directory.\n * @param repoBaseUrl - GitHub blob base URL for source links, or null.\n * @param indexOptions - Options stamped on the index page header.\n * @param indexOptions.projectLabel - Short label identifying the project.\n * @param indexOptions.commitSha - Git commit SHA the docs were generated from.\n * @returns Promise that resolves once all files are written.\n */\nasync function writeOutput(\n namespaces: NamespaceGroup[],\n outputDir: string,\n repoBaseUrl: string | null,\n indexOptions: {\n projectLabel?: string | null;\n commitSha?: string | null;\n },\n): Promise<void> {\n const docsDir = path.join(outputDir, 'docs');\n\n if (await directoryExists(docsDir)) {\n await fs.rm(docsDir, { recursive: true });\n }\n await fs.mkdir(docsDir, { recursive: true });\n\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 await fs.writeFile(\n path.join(docsDir, 'index.md'),\n generateIndexPage(namespaces, indexOptions),\n );\n\n await fs.writeFile(\n path.join(outputDir, 'sidebars.ts'),\n generateSidebars(namespaces),\n );\n}\n\n/**\n * Collect capabilities by scanning the project's files.\n *\n * @param projectPath - The project root path.\n * @param scanDirs - Directories (relative to projectPath) to scan.\n * @returns The extracted capabilities.\n * @throws If the project has no scannable directories at all.\n */\nasync function collectByScanning(\n projectPath: string,\n scanDirs: string[],\n): Promise<MessengerCapabilityPacket[]> {\n const sources = await discoverScanSources(projectPath, scanDirs);\n\n if (\n sources.scanDirs.length === 0 &&\n !sources.packagesDir &&\n !sources.nodeModulesDir\n ) {\n throw new Error(\n `No scannable directories found in ${projectPath}. ` +\n `Looked for: ${scanDirs.join(', ')}, packages/, node_modules/@metamask/`,\n );\n }\n\n logScanPlan(sources);\n\n return await scanSources(projectPath, sources);\n}\n\n/**\n * Using the project's root messenger capability collection types as\n * entrypoints, collect the constituent individual capability types and package\n * them so that they can be displayed within the documentation site.\n *\n * @param projectPath - The project root path.\n * @param options - The root-messenger strategy options.\n * @returns The extracted capabilities.\n */\nfunction collectFromRootMessengerCapabilities(\n projectPath: string,\n options: RootMessengerStrategyOptions,\n): MessengerCapabilityPacket[] {\n const { rootActions, rootEvents } = options;\n\n console.log(\n `Resolving actions from ${rootActions.filePath}#${rootActions.typeName} ` +\n `and events from ${rootEvents.filePath}#${rootEvents.typeName}...`,\n );\n\n const { capabilityPackets, skippedCapabilities } =\n discoverFromRootMessengerCapabilitiesTypes({\n projectPath,\n rootActionsTypeReference: rootActions,\n rootEventsTypeReference: rootEvents,\n });\n\n // Report rather than drop silently: a jump in any of these usually means the\n // project changed how it declares its capabilities.\n warnSkipped(\n 'declared inline, with no name to document',\n skippedCapabilities.unnamedCapabilities,\n );\n warnSkipped(\n 'whose shape could not be read',\n skippedCapabilities.unextractableCapabilities,\n );\n\n // If both capability collection types resolve to nothing, it's always a\n // misconfiguration (a wrong type name, or imports that didn't resolve).\n // Failing here matters because generation would otherwise replace an existing\n // docs directory with an empty one and exit successfully.\n if (capabilityPackets.length === 0) {\n throw new Error(\n `No messenger actions or events found in ` +\n `${rootActions.filePath}#${rootActions.typeName} or ` +\n `${rootEvents.filePath}#${rootEvents.typeName}. ` +\n `Check that these types name the collections carrying every ` +\n `capability, and that their imports resolve.`,\n );\n }\n\n return capabilityPackets;\n}\n\n/**\n * Warn about capability types that couldn't be documented, naming them so the\n * warning is actionable.\n *\n * @param description - Why they were skipped, as a noun phrase.\n * @param labels - Labels identifying each skipped type.\n */\nfunction warnSkipped(description: string, labels: string[]): void {\n if (labels.length === 0) {\n return;\n }\n\n const shown = labels.slice(0, MAX_SKIPPED_SHOWN);\n const remaining = labels.length - shown.length;\n console.warn(\n `Warning: skipped ${labels.length} capability ` +\n `${labels.length === 1 ? 'type' : 'types'} ${description}: ` +\n `${shown.join(', ')}${remaining > 0 ? `, and ${remaining} more` : ''}`,\n );\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, projectLabel, commitSha } = options;\n\n const allItems =\n options.strategy === 'root-messenger'\n ? collectFromRootMessengerCapabilities(projectPath, options)\n : await collectByScanning(projectPath, options.scanDirs);\n\n console.log(\n `Found ${allItems.length} messenger ${allItems.length === 1 ? 'item' : 'items'} total.`,\n );\n\n const namespaces = groupByNamespace(allItems);\n const repoBaseUrl = await resolveRepoBaseUrl(projectPath, commitSha ?? null);\n\n await writeOutput(namespaces, outputDir, repoBaseUrl, {\n projectLabel,\n commitSha,\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(\n `Generated docs for ${namespaces.length} ${namespaces.length === 1 ? 'namespace' : 'namespaces'}.`,\n );\n console.log(` Actions: ${totalActions}`);\n console.log(` Events: ${totalEvents}`);\n console.log(`Output: ${path.join(outputDir, 'docs')}/`);\n\n return {\n namespaces: namespaces.length,\n actions: totalActions,\n events: totalEvents,\n };\n}\n"]}
|