@metamask-previews/platform-api-docs 0.0.0-preview-40d5fb1e2 → 0.0.0-preview-0dfe3b334
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/dist/cli.cjs +3 -3
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs.map +1 -1
- package/dist/extraction.cjs +3 -3
- package/dist/extraction.cjs.map +1 -1
- package/dist/extraction.d.cts.map +1 -1
- package/dist/extraction.d.mts.map +1 -1
- package/dist/extraction.mjs +3 -3
- package/dist/extraction.mjs.map +1 -1
- package/dist/generate.cjs +12 -12
- 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.map +1 -1
- package/dist/markdown.cjs.map +1 -1
- package/dist/markdown.d.cts.map +1 -1
- package/dist/markdown.d.mts.map +1 -1
- package/dist/markdown.mjs.map +1 -1
- package/package.json +4 -4
package/dist/cli.cjs
CHANGED
|
@@ -32,7 +32,7 @@ const fs = __importStar(require("node:fs/promises"));
|
|
|
32
32
|
const path = __importStar(require("node:path"));
|
|
33
33
|
const npm_which_1 = __importDefault(require("npm-which"));
|
|
34
34
|
const yargs_1 = __importDefault(require("yargs"));
|
|
35
|
-
const
|
|
35
|
+
const generate_js_1 = require("./generate.cjs");
|
|
36
36
|
/**
|
|
37
37
|
* Locate the Docusaurus binary in this package's `node_modules/.bin`. Using
|
|
38
38
|
* `npm-which` lets the lookup track wherever the installed Docusaurus puts
|
|
@@ -187,9 +187,9 @@ async function main() {
|
|
|
187
187
|
? argv['project-label']
|
|
188
188
|
: null;
|
|
189
189
|
const commitSha = await resolveCommitSha(resolvedProjectPath);
|
|
190
|
-
const repoUrl = await (0,
|
|
190
|
+
const repoUrl = await (0, generate_js_1.resolveRepoUrl)(resolvedProjectPath);
|
|
191
191
|
// Step 1: Generate docs
|
|
192
|
-
await (0,
|
|
192
|
+
await (0, generate_js_1.generate)({
|
|
193
193
|
projectPath: resolvedProjectPath,
|
|
194
194
|
outputDir: resolvedOutputDir,
|
|
195
195
|
scanDirs,
|
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.cjs","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport execa from 'execa';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport npmWhich from 'npm-which';\nimport yargs from 'yargs';\n\nimport { generate, resolveRepoUrl } from './generate';\n\n/**\n * Locate the Docusaurus binary in this package's `node_modules/.bin`. Using\n * `npm-which` lets the lookup track wherever the installed Docusaurus puts\n * its binary, so a future Docusaurus upgrade can't break this path.\n *\n * @returns Absolute path to the `docusaurus` executable.\n */\nfunction resolveDocusaurus(): string {\n return npmWhich(__dirname).sync('docusaurus');\n}\n\n/**\n * Run a Docusaurus command.\n *\n * @param command - The docusaurus command (start, build, serve).\n * @param cwd - The site directory.\n * @param extraEnv - Extra environment variables passed through to the\n * Docusaurus process (e.g. `DOCS_PROJECT_LABEL`, `DOCS_COMMIT_SHA`,\n * `DOCS_REPO_URL`).\n */\nasync function runDocusaurus(\n command: string,\n cwd: string,\n extraEnv: Record<string, string> = {},\n): Promise<void> {\n await execa(resolveDocusaurus(), [command], {\n cwd,\n stdio: 'inherit',\n env: { ...process.env, ...extraEnv },\n });\n}\n\n/**\n * Copy site files into the output directory, skipping `node_modules`, `docs`,\n * and `tsconfig.json`. `docs` is owned by the doc generator and shouldn't be\n * carried over from the source `site/` directory. `tsconfig.json` extends the\n * monorepo's `tsconfig.base.json` via a relative path that only resolves from\n * the source location — it's there for IDE / lint inheritance, not for\n * Docusaurus, which uses `jiti` and doesn't consult the tsconfig at runtime.\n *\n * @param outDir - The output directory to set up.\n */\nasync function setupSite(outDir: string): Promise<void> {\n const packageDir = path.resolve(__dirname, '..');\n const siteDir = path.join(packageDir, 'site');\n const packageNodeModules = path.join(packageDir, 'node_modules');\n const skip = new Set(['node_modules', 'docs', 'tsconfig.json']);\n\n console.log(`\\nSetting up Docusaurus site in ${outDir}...`);\n\n // `fs.cp` has been available since Node 16.7 and only got the \"stable\"\n // marker in 22.3 — it's functional throughout our supported Node range\n // (`^18.18 || >=20`), even though the linter flags the older versions.\n // eslint-disable-next-line n/no-unsupported-features/node-builtins\n await fs.cp(siteDir, outDir, {\n recursive: true,\n filter: (source) => !skip.has(path.basename(source)),\n });\n\n // Symlink this package's `node_modules` into the output so the copied\n // `docusaurus.config.ts` and the rest of Docusaurus's bundling pipeline can\n // resolve their deps the same way they do in the source tree. Without it,\n // Node's resolver walks up from the output and can't reach our nested deps\n // when the package is installed as a regular dependency by an external\n // consumer (e.g. `metamask-extension`, `metamask-mobile`).\n const linkPath = path.join(outDir, 'node_modules');\n try {\n // `'junction'` works cross-platform (POSIX ignores it; Windows uses it\n // without admin) — `'dir'` would require admin on Windows.\n await fs.symlink(packageNodeModules, linkPath, 'junction');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error;\n }\n }\n\n // Write a minimal package.json so Docusaurus doesn't warn about a missing one\n const pkgJsonPath = path.join(outDir, 'package.json');\n try {\n await fs.access(pkgJsonPath);\n } catch {\n await fs.writeFile(\n pkgJsonPath,\n JSON.stringify(\n { name: 'platform-api-docs-site', private: true },\n null,\n 2,\n ),\n );\n }\n}\n\n/**\n * Resolve the short Git commit SHA the docs are being generated from.\n * Returns null when the project isn't a git repo or git isn't available.\n *\n * @param projectPath - The project root path.\n * @returns The short SHA, or null on failure.\n */\nasync function resolveCommitSha(projectPath: string): Promise<string | null> {\n try {\n const { stdout } = await execa('git', ['rev-parse', '--short', 'HEAD'], {\n cwd: projectPath,\n });\n const trimmed = stdout.trim();\n return trimmed.length > 0 ? trimmed : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Main CLI entry point.\n */\nasync function main(): Promise<void> {\n const argv = await yargs(process.argv.slice(2))\n .command(\n '$0 [project-path]',\n 'Produces documentation for the platform API, the set of actions and events available in clients through the message bus.',\n (yargsInstance) => {\n yargsInstance.positional('project-path', {\n type: 'string',\n description: 'Path to the project to scan',\n default: '.',\n });\n },\n )\n .option('build', {\n type: 'boolean',\n description:\n 'Generate platform API docs and build a production-ready site',\n default: false,\n })\n .option('serve', {\n type: 'boolean',\n description:\n 'Generate platform API docs and serve a production-ready site',\n default: false,\n })\n .option('dev', {\n type: 'boolean',\n description:\n 'Generate platform API docs and serve a development-only site',\n default: false,\n })\n .option('scan-dir', {\n type: 'string',\n array: true,\n description:\n 'Additional directories within the project to scan for messenger actions and events (note: may be specified multiple times)',\n default: [] as string[],\n })\n .option('output', {\n type: 'string',\n description: 'Output directory',\n })\n .option('project-label', {\n type: 'string',\n description:\n 'Short label identifying the project (e.g. \"Core\", \"Extension\") — stamped on the site title and headings',\n })\n .option('site-url', {\n type: 'string',\n description:\n 'Absolute URL the built site will be served from, e.g. https://metamask.github.io',\n })\n .option('site-base-url', {\n type: 'string',\n description:\n 'Path prefix the built site will be served under, e.g. /core/platform-api/',\n })\n .help().argv;\n\n const projectPathArg = argv['project-path'];\n const resolvedProjectPath = path.resolve(\n typeof projectPathArg === 'string' ? projectPathArg : '.',\n );\n const resolvedOutputDir = path.resolve(\n argv.output ?? path.join(resolvedProjectPath, '.platform-api-docs'),\n );\n const scanDirs = ['src', ...argv['scan-dir']].filter(\n (dir, index, dirs) => dirs.indexOf(dir) === index,\n );\n const projectLabel =\n typeof argv['project-label'] === 'string' &&\n argv['project-label'].length > 0\n ? argv['project-label']\n : null;\n const commitSha = await resolveCommitSha(resolvedProjectPath);\n const repoUrl = await resolveRepoUrl(resolvedProjectPath);\n\n // Step 1: Generate docs\n await generate({\n projectPath: resolvedProjectPath,\n outputDir: resolvedOutputDir,\n scanDirs,\n projectLabel,\n commitSha,\n });\n\n // Step 2: If --build, --serve, or --dev, set up and run Docusaurus\n if (argv.build || argv.serve || argv.dev) {\n await setupSite(resolvedOutputDir);\n\n // Translate CLI flags into the environment variables Docusaurus's\n // config reads. Keeping the CLI surface flag-only means consumers\n // (workflow files, package.json scripts) don't have to know how the\n // values are plumbed through to Docusaurus.\n const docusaurusEnv: Record<string, string> = {};\n if (projectLabel) {\n docusaurusEnv.DOCS_PROJECT_LABEL = projectLabel;\n }\n if (commitSha) {\n docusaurusEnv.DOCS_COMMIT_SHA = commitSha;\n }\n if (repoUrl) {\n docusaurusEnv.DOCS_REPO_URL = repoUrl;\n }\n if (typeof argv['site-url'] === 'string' && argv['site-url'].length > 0) {\n docusaurusEnv.DOCS_URL = argv['site-url'];\n }\n if (\n typeof argv['site-base-url'] === 'string' &&\n argv['site-base-url'].length > 0\n ) {\n docusaurusEnv.DOCS_BASE_URL = argv['site-base-url'];\n }\n\n if (argv.dev) {\n console.log('\\nStarting dev server...');\n await runDocusaurus('start', resolvedOutputDir, docusaurusEnv);\n } else if (argv.build || argv.serve) {\n console.log('\\nBuilding static site...');\n await runDocusaurus('build', resolvedOutputDir, docusaurusEnv);\n\n if (argv.serve) {\n console.log('\\nServing static site...');\n await runDocusaurus('serve', resolvedOutputDir, docusaurusEnv);\n }\n }\n }\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exitCode = 1;\n});\n"]}
|
|
1
|
+
{"version":3,"file":"cli.cjs","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport execa from 'execa';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport npmWhich from 'npm-which';\nimport yargs from 'yargs';\n\nimport { generate, resolveRepoUrl } from './generate.js';\n\n/**\n * Locate the Docusaurus binary in this package's `node_modules/.bin`. Using\n * `npm-which` lets the lookup track wherever the installed Docusaurus puts\n * its binary, so a future Docusaurus upgrade can't break this path.\n *\n * @returns Absolute path to the `docusaurus` executable.\n */\nfunction resolveDocusaurus(): string {\n return npmWhich(__dirname).sync('docusaurus');\n}\n\n/**\n * Run a Docusaurus command.\n *\n * @param command - The docusaurus command (start, build, serve).\n * @param cwd - The site directory.\n * @param extraEnv - Extra environment variables passed through to the\n * Docusaurus process (e.g. `DOCS_PROJECT_LABEL`, `DOCS_COMMIT_SHA`,\n * `DOCS_REPO_URL`).\n */\nasync function runDocusaurus(\n command: string,\n cwd: string,\n extraEnv: Record<string, string> = {},\n): Promise<void> {\n await execa(resolveDocusaurus(), [command], {\n cwd,\n stdio: 'inherit',\n env: { ...process.env, ...extraEnv },\n });\n}\n\n/**\n * Copy site files into the output directory, skipping `node_modules`, `docs`,\n * and `tsconfig.json`. `docs` is owned by the doc generator and shouldn't be\n * carried over from the source `site/` directory. `tsconfig.json` extends the\n * monorepo's `tsconfig.base.json` via a relative path that only resolves from\n * the source location — it's there for IDE / lint inheritance, not for\n * Docusaurus, which uses `jiti` and doesn't consult the tsconfig at runtime.\n *\n * @param outDir - The output directory to set up.\n */\nasync function setupSite(outDir: string): Promise<void> {\n const packageDir = path.resolve(__dirname, '..');\n const siteDir = path.join(packageDir, 'site');\n const packageNodeModules = path.join(packageDir, 'node_modules');\n const skip = new Set(['node_modules', 'docs', 'tsconfig.json']);\n\n console.log(`\\nSetting up Docusaurus site in ${outDir}...`);\n\n // `fs.cp` has been available since Node 16.7 and only got the \"stable\"\n // marker in 22.3 — it's functional throughout our supported Node range\n // (`^18.18 || >=20`), even though the linter flags the older versions.\n // eslint-disable-next-line n/no-unsupported-features/node-builtins\n await fs.cp(siteDir, outDir, {\n recursive: true,\n filter: (source) => !skip.has(path.basename(source)),\n });\n\n // Symlink this package's `node_modules` into the output so the copied\n // `docusaurus.config.ts` and the rest of Docusaurus's bundling pipeline can\n // resolve their deps the same way they do in the source tree. Without it,\n // Node's resolver walks up from the output and can't reach our nested deps\n // when the package is installed as a regular dependency by an external\n // consumer (e.g. `metamask-extension`, `metamask-mobile`).\n const linkPath = path.join(outDir, 'node_modules');\n try {\n // `'junction'` works cross-platform (POSIX ignores it; Windows uses it\n // without admin) — `'dir'` would require admin on Windows.\n await fs.symlink(packageNodeModules, linkPath, 'junction');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error;\n }\n }\n\n // Write a minimal package.json so Docusaurus doesn't warn about a missing one\n const pkgJsonPath = path.join(outDir, 'package.json');\n try {\n await fs.access(pkgJsonPath);\n } catch {\n await fs.writeFile(\n pkgJsonPath,\n JSON.stringify(\n { name: 'platform-api-docs-site', private: true },\n null,\n 2,\n ),\n );\n }\n}\n\n/**\n * Resolve the short Git commit SHA the docs are being generated from.\n * Returns null when the project isn't a git repo or git isn't available.\n *\n * @param projectPath - The project root path.\n * @returns The short SHA, or null on failure.\n */\nasync function resolveCommitSha(projectPath: string): Promise<string | null> {\n try {\n const { stdout } = await execa('git', ['rev-parse', '--short', 'HEAD'], {\n cwd: projectPath,\n });\n const trimmed = stdout.trim();\n return trimmed.length > 0 ? trimmed : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Main CLI entry point.\n */\nasync function main(): Promise<void> {\n const argv = await yargs(process.argv.slice(2))\n .command(\n '$0 [project-path]',\n 'Produces documentation for the platform API, the set of actions and events available in clients through the message bus.',\n (yargsInstance) => {\n yargsInstance.positional('project-path', {\n type: 'string',\n description: 'Path to the project to scan',\n default: '.',\n });\n },\n )\n .option('build', {\n type: 'boolean',\n description:\n 'Generate platform API docs and build a production-ready site',\n default: false,\n })\n .option('serve', {\n type: 'boolean',\n description:\n 'Generate platform API docs and serve a production-ready site',\n default: false,\n })\n .option('dev', {\n type: 'boolean',\n description:\n 'Generate platform API docs and serve a development-only site',\n default: false,\n })\n .option('scan-dir', {\n type: 'string',\n array: true,\n description:\n 'Additional directories within the project to scan for messenger actions and events (note: may be specified multiple times)',\n default: [] as string[],\n })\n .option('output', {\n type: 'string',\n description: 'Output directory',\n })\n .option('project-label', {\n type: 'string',\n description:\n 'Short label identifying the project (e.g. \"Core\", \"Extension\") — stamped on the site title and headings',\n })\n .option('site-url', {\n type: 'string',\n description:\n 'Absolute URL the built site will be served from, e.g. https://metamask.github.io',\n })\n .option('site-base-url', {\n type: 'string',\n description:\n 'Path prefix the built site will be served under, e.g. /core/platform-api/',\n })\n .help().argv;\n\n const projectPathArg = argv['project-path'];\n const resolvedProjectPath = path.resolve(\n typeof projectPathArg === 'string' ? projectPathArg : '.',\n );\n const resolvedOutputDir = path.resolve(\n argv.output ?? path.join(resolvedProjectPath, '.platform-api-docs'),\n );\n const scanDirs = ['src', ...argv['scan-dir']].filter(\n (dir, index, dirs) => dirs.indexOf(dir) === index,\n );\n const projectLabel =\n typeof argv['project-label'] === 'string' &&\n argv['project-label'].length > 0\n ? argv['project-label']\n : null;\n const commitSha = await resolveCommitSha(resolvedProjectPath);\n const repoUrl = await resolveRepoUrl(resolvedProjectPath);\n\n // Step 1: Generate docs\n await generate({\n projectPath: resolvedProjectPath,\n outputDir: resolvedOutputDir,\n scanDirs,\n projectLabel,\n commitSha,\n });\n\n // Step 2: If --build, --serve, or --dev, set up and run Docusaurus\n if (argv.build || argv.serve || argv.dev) {\n await setupSite(resolvedOutputDir);\n\n // Translate CLI flags into the environment variables Docusaurus's\n // config reads. Keeping the CLI surface flag-only means consumers\n // (workflow files, package.json scripts) don't have to know how the\n // values are plumbed through to Docusaurus.\n const docusaurusEnv: Record<string, string> = {};\n if (projectLabel) {\n docusaurusEnv.DOCS_PROJECT_LABEL = projectLabel;\n }\n if (commitSha) {\n docusaurusEnv.DOCS_COMMIT_SHA = commitSha;\n }\n if (repoUrl) {\n docusaurusEnv.DOCS_REPO_URL = repoUrl;\n }\n if (typeof argv['site-url'] === 'string' && argv['site-url'].length > 0) {\n docusaurusEnv.DOCS_URL = argv['site-url'];\n }\n if (\n typeof argv['site-base-url'] === 'string' &&\n argv['site-base-url'].length > 0\n ) {\n docusaurusEnv.DOCS_BASE_URL = argv['site-base-url'];\n }\n\n if (argv.dev) {\n console.log('\\nStarting dev server...');\n await runDocusaurus('start', resolvedOutputDir, docusaurusEnv);\n } else if (argv.build || argv.serve) {\n console.log('\\nBuilding static site...');\n await runDocusaurus('build', resolvedOutputDir, docusaurusEnv);\n\n if (argv.serve) {\n console.log('\\nServing static site...');\n await runDocusaurus('serve', resolvedOutputDir, docusaurusEnv);\n }\n }\n }\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exitCode = 1;\n});\n"]}
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport execa from 'execa';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport npmWhich from 'npm-which';\nimport yargs from 'yargs';\n\nimport { generate, resolveRepoUrl } from './generate';\n\n/**\n * Locate the Docusaurus binary in this package's `node_modules/.bin`. Using\n * `npm-which` lets the lookup track wherever the installed Docusaurus puts\n * its binary, so a future Docusaurus upgrade can't break this path.\n *\n * @returns Absolute path to the `docusaurus` executable.\n */\nfunction resolveDocusaurus(): string {\n return npmWhich(__dirname).sync('docusaurus');\n}\n\n/**\n * Run a Docusaurus command.\n *\n * @param command - The docusaurus command (start, build, serve).\n * @param cwd - The site directory.\n * @param extraEnv - Extra environment variables passed through to the\n * Docusaurus process (e.g. `DOCS_PROJECT_LABEL`, `DOCS_COMMIT_SHA`,\n * `DOCS_REPO_URL`).\n */\nasync function runDocusaurus(\n command: string,\n cwd: string,\n extraEnv: Record<string, string> = {},\n): Promise<void> {\n await execa(resolveDocusaurus(), [command], {\n cwd,\n stdio: 'inherit',\n env: { ...process.env, ...extraEnv },\n });\n}\n\n/**\n * Copy site files into the output directory, skipping `node_modules`, `docs`,\n * and `tsconfig.json`. `docs` is owned by the doc generator and shouldn't be\n * carried over from the source `site/` directory. `tsconfig.json` extends the\n * monorepo's `tsconfig.base.json` via a relative path that only resolves from\n * the source location — it's there for IDE / lint inheritance, not for\n * Docusaurus, which uses `jiti` and doesn't consult the tsconfig at runtime.\n *\n * @param outDir - The output directory to set up.\n */\nasync function setupSite(outDir: string): Promise<void> {\n const packageDir = path.resolve(__dirname, '..');\n const siteDir = path.join(packageDir, 'site');\n const packageNodeModules = path.join(packageDir, 'node_modules');\n const skip = new Set(['node_modules', 'docs', 'tsconfig.json']);\n\n console.log(`\\nSetting up Docusaurus site in ${outDir}...`);\n\n // `fs.cp` has been available since Node 16.7 and only got the \"stable\"\n // marker in 22.3 — it's functional throughout our supported Node range\n // (`^18.18 || >=20`), even though the linter flags the older versions.\n // eslint-disable-next-line n/no-unsupported-features/node-builtins\n await fs.cp(siteDir, outDir, {\n recursive: true,\n filter: (source) => !skip.has(path.basename(source)),\n });\n\n // Symlink this package's `node_modules` into the output so the copied\n // `docusaurus.config.ts` and the rest of Docusaurus's bundling pipeline can\n // resolve their deps the same way they do in the source tree. Without it,\n // Node's resolver walks up from the output and can't reach our nested deps\n // when the package is installed as a regular dependency by an external\n // consumer (e.g. `metamask-extension`, `metamask-mobile`).\n const linkPath = path.join(outDir, 'node_modules');\n try {\n // `'junction'` works cross-platform (POSIX ignores it; Windows uses it\n // without admin) — `'dir'` would require admin on Windows.\n await fs.symlink(packageNodeModules, linkPath, 'junction');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error;\n }\n }\n\n // Write a minimal package.json so Docusaurus doesn't warn about a missing one\n const pkgJsonPath = path.join(outDir, 'package.json');\n try {\n await fs.access(pkgJsonPath);\n } catch {\n await fs.writeFile(\n pkgJsonPath,\n JSON.stringify(\n { name: 'platform-api-docs-site', private: true },\n null,\n 2,\n ),\n );\n }\n}\n\n/**\n * Resolve the short Git commit SHA the docs are being generated from.\n * Returns null when the project isn't a git repo or git isn't available.\n *\n * @param projectPath - The project root path.\n * @returns The short SHA, or null on failure.\n */\nasync function resolveCommitSha(projectPath: string): Promise<string | null> {\n try {\n const { stdout } = await execa('git', ['rev-parse', '--short', 'HEAD'], {\n cwd: projectPath,\n });\n const trimmed = stdout.trim();\n return trimmed.length > 0 ? trimmed : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Main CLI entry point.\n */\nasync function main(): Promise<void> {\n const argv = await yargs(process.argv.slice(2))\n .command(\n '$0 [project-path]',\n 'Produces documentation for the platform API, the set of actions and events available in clients through the message bus.',\n (yargsInstance) => {\n yargsInstance.positional('project-path', {\n type: 'string',\n description: 'Path to the project to scan',\n default: '.',\n });\n },\n )\n .option('build', {\n type: 'boolean',\n description:\n 'Generate platform API docs and build a production-ready site',\n default: false,\n })\n .option('serve', {\n type: 'boolean',\n description:\n 'Generate platform API docs and serve a production-ready site',\n default: false,\n })\n .option('dev', {\n type: 'boolean',\n description:\n 'Generate platform API docs and serve a development-only site',\n default: false,\n })\n .option('scan-dir', {\n type: 'string',\n array: true,\n description:\n 'Additional directories within the project to scan for messenger actions and events (note: may be specified multiple times)',\n default: [] as string[],\n })\n .option('output', {\n type: 'string',\n description: 'Output directory',\n })\n .option('project-label', {\n type: 'string',\n description:\n 'Short label identifying the project (e.g. \"Core\", \"Extension\") — stamped on the site title and headings',\n })\n .option('site-url', {\n type: 'string',\n description:\n 'Absolute URL the built site will be served from, e.g. https://metamask.github.io',\n })\n .option('site-base-url', {\n type: 'string',\n description:\n 'Path prefix the built site will be served under, e.g. /core/platform-api/',\n })\n .help().argv;\n\n const projectPathArg = argv['project-path'];\n const resolvedProjectPath = path.resolve(\n typeof projectPathArg === 'string' ? projectPathArg : '.',\n );\n const resolvedOutputDir = path.resolve(\n argv.output ?? path.join(resolvedProjectPath, '.platform-api-docs'),\n );\n const scanDirs = ['src', ...argv['scan-dir']].filter(\n (dir, index, dirs) => dirs.indexOf(dir) === index,\n );\n const projectLabel =\n typeof argv['project-label'] === 'string' &&\n argv['project-label'].length > 0\n ? argv['project-label']\n : null;\n const commitSha = await resolveCommitSha(resolvedProjectPath);\n const repoUrl = await resolveRepoUrl(resolvedProjectPath);\n\n // Step 1: Generate docs\n await generate({\n projectPath: resolvedProjectPath,\n outputDir: resolvedOutputDir,\n scanDirs,\n projectLabel,\n commitSha,\n });\n\n // Step 2: If --build, --serve, or --dev, set up and run Docusaurus\n if (argv.build || argv.serve || argv.dev) {\n await setupSite(resolvedOutputDir);\n\n // Translate CLI flags into the environment variables Docusaurus's\n // config reads. Keeping the CLI surface flag-only means consumers\n // (workflow files, package.json scripts) don't have to know how the\n // values are plumbed through to Docusaurus.\n const docusaurusEnv: Record<string, string> = {};\n if (projectLabel) {\n docusaurusEnv.DOCS_PROJECT_LABEL = projectLabel;\n }\n if (commitSha) {\n docusaurusEnv.DOCS_COMMIT_SHA = commitSha;\n }\n if (repoUrl) {\n docusaurusEnv.DOCS_REPO_URL = repoUrl;\n }\n if (typeof argv['site-url'] === 'string' && argv['site-url'].length > 0) {\n docusaurusEnv.DOCS_URL = argv['site-url'];\n }\n if (\n typeof argv['site-base-url'] === 'string' &&\n argv['site-base-url'].length > 0\n ) {\n docusaurusEnv.DOCS_BASE_URL = argv['site-base-url'];\n }\n\n if (argv.dev) {\n console.log('\\nStarting dev server...');\n await runDocusaurus('start', resolvedOutputDir, docusaurusEnv);\n } else if (argv.build || argv.serve) {\n console.log('\\nBuilding static site...');\n await runDocusaurus('build', resolvedOutputDir, docusaurusEnv);\n\n if (argv.serve) {\n console.log('\\nServing static site...');\n await runDocusaurus('serve', resolvedOutputDir, docusaurusEnv);\n }\n }\n }\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exitCode = 1;\n});\n"]}
|
|
1
|
+
{"version":3,"file":"cli.mjs","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAEA,OAAO,MAAK,uBAAc;;AAC1B,OAAO,KAAK,EAAE,yBAAyB;AACvC,OAAO,KAAK,IAAI,kBAAkB;AAClC,OAAO,SAAQ,kBAAkB;;AACjC,OAAO,KAAK,cAAc;AAE1B,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,uBAAsB;AAEzD;;;;;;GAMG;AACH,SAAS,iBAAiB;IACxB,OAAO,QAAQ,6BAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,aAAa,CAC1B,OAAe,EACf,GAAW,EACX,WAAmC,EAAE;IAErC,MAAM,KAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE;QAC1C,GAAG;QACH,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE;KACrC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,SAAS,CAAC,MAAc;IACrC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,8BAAY,IAAI,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC9C,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;IAEhE,OAAO,CAAC,GAAG,CAAC,mCAAmC,MAAM,KAAK,CAAC,CAAC;IAE5D,uEAAuE;IACvE,uEAAuE;IACvE,uEAAuE;IACvE,mEAAmE;IACnE,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE;QAC3B,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;KACrD,CAAC,CAAC;IAEH,sEAAsE;IACtE,4EAA4E;IAC5E,0EAA0E;IAC1E,2EAA2E;IAC3E,uEAAuE;IACvE,2DAA2D;IAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnD,IAAI,CAAC;QACH,uEAAuE;QACvE,2DAA2D;QAC3D,MAAM,EAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,SAAS,CAChB,WAAW,EACX,IAAI,CAAC,SAAS,CACZ,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,IAAI,EAAE,EACjD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,gBAAgB,CAAC,WAAmB;IACjD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE;YACtE,GAAG,EAAE,WAAW;SACjB,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC5C,OAAO,CACN,mBAAmB,EACnB,0HAA0H,EAC1H,CAAC,aAAa,EAAE,EAAE;QAChB,aAAa,CAAC,UAAU,CAAC,cAAc,EAAE;YACvC,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,6BAA6B;YAC1C,OAAO,EAAE,GAAG;SACb,CAAC,CAAC;IACL,CAAC,CACF;SACA,MAAM,CAAC,OAAO,EAAE;QACf,IAAI,EAAE,SAAS;QACf,WAAW,EACT,8DAA8D;QAChE,OAAO,EAAE,KAAK;KACf,CAAC;SACD,MAAM,CAAC,OAAO,EAAE;QACf,IAAI,EAAE,SAAS;QACf,WAAW,EACT,8DAA8D;QAChE,OAAO,EAAE,KAAK;KACf,CAAC;SACD,MAAM,CAAC,KAAK,EAAE;QACb,IAAI,EAAE,SAAS;QACf,WAAW,EACT,8DAA8D;QAChE,OAAO,EAAE,KAAK;KACf,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,IAAI;QACX,WAAW,EACT,4HAA4H;QAC9H,OAAO,EAAE,EAAc;KACxB,CAAC;SACD,MAAM,CAAC,QAAQ,EAAE;QAChB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,kBAAkB;KAChC,CAAC;SACD,MAAM,CAAC,eAAe,EAAE;QACvB,IAAI,EAAE,QAAQ;QACd,WAAW,EACT,yGAAyG;KAC5G,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,IAAI,EAAE,QAAQ;QACd,WAAW,EACT,kFAAkF;KACrF,CAAC;SACD,MAAM,CAAC,eAAe,EAAE;QACvB,IAAI,EAAE,QAAQ;QACd,WAAW,EACT,2EAA2E;KAC9E,CAAC;SACD,IAAI,EAAE,CAAC,IAAI,CAAC;IAEf,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;IAC5C,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,CACtC,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAC1D,CAAC;IACF,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CACpC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,CACpE,CAAC;IACF,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAClD,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAClD,CAAC;IACF,MAAM,YAAY,GAChB,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,QAAQ;QACzC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC;QAC9B,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC;QACvB,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,mBAAmB,CAAC,CAAC;IAE1D,wBAAwB;IACxB,MAAM,QAAQ,CAAC;QACb,WAAW,EAAE,mBAAmB;QAChC,SAAS,EAAE,iBAAiB;QAC5B,QAAQ;QACR,YAAY;QACZ,SAAS;KACV,CAAC,CAAC;IAEH,mEAAmE;IACnE,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACzC,MAAM,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAEnC,kEAAkE;QAClE,kEAAkE;QAClE,oEAAoE;QACpE,4CAA4C;QAC5C,MAAM,aAAa,GAA2B,EAAE,CAAC;QACjD,IAAI,YAAY,EAAE,CAAC;YACjB,aAAa,CAAC,kBAAkB,GAAG,YAAY,CAAC;QAClD,CAAC;QACD,IAAI,SAAS,EAAE,CAAC;YACd,aAAa,CAAC,eAAe,GAAG,SAAS,CAAC;QAC5C,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,aAAa,CAAC,aAAa,GAAG,OAAO,CAAC;QACxC,CAAC;QACD,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxE,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5C,CAAC;QACD,IACE,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,QAAQ;YACzC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,EAChC,CAAC;YACD,aAAa,CAAC,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;YACxC,MAAM,aAAa,CAAC,OAAO,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;QACjE,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACzC,MAAM,aAAa,CAAC,OAAO,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;YAE/D,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;gBACxC,MAAM,aAAa,CAAC,OAAO,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\n\nimport execa from 'execa';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport npmWhich from 'npm-which';\nimport yargs from 'yargs';\n\nimport { generate, resolveRepoUrl } from './generate.js';\n\n/**\n * Locate the Docusaurus binary in this package's `node_modules/.bin`. Using\n * `npm-which` lets the lookup track wherever the installed Docusaurus puts\n * its binary, so a future Docusaurus upgrade can't break this path.\n *\n * @returns Absolute path to the `docusaurus` executable.\n */\nfunction resolveDocusaurus(): string {\n return npmWhich(__dirname).sync('docusaurus');\n}\n\n/**\n * Run a Docusaurus command.\n *\n * @param command - The docusaurus command (start, build, serve).\n * @param cwd - The site directory.\n * @param extraEnv - Extra environment variables passed through to the\n * Docusaurus process (e.g. `DOCS_PROJECT_LABEL`, `DOCS_COMMIT_SHA`,\n * `DOCS_REPO_URL`).\n */\nasync function runDocusaurus(\n command: string,\n cwd: string,\n extraEnv: Record<string, string> = {},\n): Promise<void> {\n await execa(resolveDocusaurus(), [command], {\n cwd,\n stdio: 'inherit',\n env: { ...process.env, ...extraEnv },\n });\n}\n\n/**\n * Copy site files into the output directory, skipping `node_modules`, `docs`,\n * and `tsconfig.json`. `docs` is owned by the doc generator and shouldn't be\n * carried over from the source `site/` directory. `tsconfig.json` extends the\n * monorepo's `tsconfig.base.json` via a relative path that only resolves from\n * the source location — it's there for IDE / lint inheritance, not for\n * Docusaurus, which uses `jiti` and doesn't consult the tsconfig at runtime.\n *\n * @param outDir - The output directory to set up.\n */\nasync function setupSite(outDir: string): Promise<void> {\n const packageDir = path.resolve(__dirname, '..');\n const siteDir = path.join(packageDir, 'site');\n const packageNodeModules = path.join(packageDir, 'node_modules');\n const skip = new Set(['node_modules', 'docs', 'tsconfig.json']);\n\n console.log(`\\nSetting up Docusaurus site in ${outDir}...`);\n\n // `fs.cp` has been available since Node 16.7 and only got the \"stable\"\n // marker in 22.3 — it's functional throughout our supported Node range\n // (`^18.18 || >=20`), even though the linter flags the older versions.\n // eslint-disable-next-line n/no-unsupported-features/node-builtins\n await fs.cp(siteDir, outDir, {\n recursive: true,\n filter: (source) => !skip.has(path.basename(source)),\n });\n\n // Symlink this package's `node_modules` into the output so the copied\n // `docusaurus.config.ts` and the rest of Docusaurus's bundling pipeline can\n // resolve their deps the same way they do in the source tree. Without it,\n // Node's resolver walks up from the output and can't reach our nested deps\n // when the package is installed as a regular dependency by an external\n // consumer (e.g. `metamask-extension`, `metamask-mobile`).\n const linkPath = path.join(outDir, 'node_modules');\n try {\n // `'junction'` works cross-platform (POSIX ignores it; Windows uses it\n // without admin) — `'dir'` would require admin on Windows.\n await fs.symlink(packageNodeModules, linkPath, 'junction');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error;\n }\n }\n\n // Write a minimal package.json so Docusaurus doesn't warn about a missing one\n const pkgJsonPath = path.join(outDir, 'package.json');\n try {\n await fs.access(pkgJsonPath);\n } catch {\n await fs.writeFile(\n pkgJsonPath,\n JSON.stringify(\n { name: 'platform-api-docs-site', private: true },\n null,\n 2,\n ),\n );\n }\n}\n\n/**\n * Resolve the short Git commit SHA the docs are being generated from.\n * Returns null when the project isn't a git repo or git isn't available.\n *\n * @param projectPath - The project root path.\n * @returns The short SHA, or null on failure.\n */\nasync function resolveCommitSha(projectPath: string): Promise<string | null> {\n try {\n const { stdout } = await execa('git', ['rev-parse', '--short', 'HEAD'], {\n cwd: projectPath,\n });\n const trimmed = stdout.trim();\n return trimmed.length > 0 ? trimmed : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Main CLI entry point.\n */\nasync function main(): Promise<void> {\n const argv = await yargs(process.argv.slice(2))\n .command(\n '$0 [project-path]',\n 'Produces documentation for the platform API, the set of actions and events available in clients through the message bus.',\n (yargsInstance) => {\n yargsInstance.positional('project-path', {\n type: 'string',\n description: 'Path to the project to scan',\n default: '.',\n });\n },\n )\n .option('build', {\n type: 'boolean',\n description:\n 'Generate platform API docs and build a production-ready site',\n default: false,\n })\n .option('serve', {\n type: 'boolean',\n description:\n 'Generate platform API docs and serve a production-ready site',\n default: false,\n })\n .option('dev', {\n type: 'boolean',\n description:\n 'Generate platform API docs and serve a development-only site',\n default: false,\n })\n .option('scan-dir', {\n type: 'string',\n array: true,\n description:\n 'Additional directories within the project to scan for messenger actions and events (note: may be specified multiple times)',\n default: [] as string[],\n })\n .option('output', {\n type: 'string',\n description: 'Output directory',\n })\n .option('project-label', {\n type: 'string',\n description:\n 'Short label identifying the project (e.g. \"Core\", \"Extension\") — stamped on the site title and headings',\n })\n .option('site-url', {\n type: 'string',\n description:\n 'Absolute URL the built site will be served from, e.g. https://metamask.github.io',\n })\n .option('site-base-url', {\n type: 'string',\n description:\n 'Path prefix the built site will be served under, e.g. /core/platform-api/',\n })\n .help().argv;\n\n const projectPathArg = argv['project-path'];\n const resolvedProjectPath = path.resolve(\n typeof projectPathArg === 'string' ? projectPathArg : '.',\n );\n const resolvedOutputDir = path.resolve(\n argv.output ?? path.join(resolvedProjectPath, '.platform-api-docs'),\n );\n const scanDirs = ['src', ...argv['scan-dir']].filter(\n (dir, index, dirs) => dirs.indexOf(dir) === index,\n );\n const projectLabel =\n typeof argv['project-label'] === 'string' &&\n argv['project-label'].length > 0\n ? argv['project-label']\n : null;\n const commitSha = await resolveCommitSha(resolvedProjectPath);\n const repoUrl = await resolveRepoUrl(resolvedProjectPath);\n\n // Step 1: Generate docs\n await generate({\n projectPath: resolvedProjectPath,\n outputDir: resolvedOutputDir,\n scanDirs,\n projectLabel,\n commitSha,\n });\n\n // Step 2: If --build, --serve, or --dev, set up and run Docusaurus\n if (argv.build || argv.serve || argv.dev) {\n await setupSite(resolvedOutputDir);\n\n // Translate CLI flags into the environment variables Docusaurus's\n // config reads. Keeping the CLI surface flag-only means consumers\n // (workflow files, package.json scripts) don't have to know how the\n // values are plumbed through to Docusaurus.\n const docusaurusEnv: Record<string, string> = {};\n if (projectLabel) {\n docusaurusEnv.DOCS_PROJECT_LABEL = projectLabel;\n }\n if (commitSha) {\n docusaurusEnv.DOCS_COMMIT_SHA = commitSha;\n }\n if (repoUrl) {\n docusaurusEnv.DOCS_REPO_URL = repoUrl;\n }\n if (typeof argv['site-url'] === 'string' && argv['site-url'].length > 0) {\n docusaurusEnv.DOCS_URL = argv['site-url'];\n }\n if (\n typeof argv['site-base-url'] === 'string' &&\n argv['site-base-url'].length > 0\n ) {\n docusaurusEnv.DOCS_BASE_URL = argv['site-base-url'];\n }\n\n if (argv.dev) {\n console.log('\\nStarting dev server...');\n await runDocusaurus('start', resolvedOutputDir, docusaurusEnv);\n } else if (argv.build || argv.serve) {\n console.log('\\nBuilding static site...');\n await runDocusaurus('build', resolvedOutputDir, docusaurusEnv);\n\n if (argv.serve) {\n console.log('\\nServing static site...');\n await runDocusaurus('serve', resolvedOutputDir, docusaurusEnv);\n }\n }\n }\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exitCode = 1;\n});\n"]}
|
package/dist/extraction.cjs
CHANGED
|
@@ -182,7 +182,7 @@ function findClassMethodDeclaration(typeNode) {
|
|
|
182
182
|
// Reject qualified-name type names, as we need a plain identifier to
|
|
183
183
|
// resolve the symbol.
|
|
184
184
|
// EXAMPLE:
|
|
185
|
-
// import * as somePackage from '
|
|
185
|
+
// import * as somePackage from '....js';
|
|
186
186
|
// somePackage.FooController['someMethod']
|
|
187
187
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
188
188
|
const classNameNode = objectType.getTypeName();
|
|
@@ -352,7 +352,7 @@ function recursivelyFindMessengerCapabilityTypeDeclarations(node, kind, visitedT
|
|
|
352
352
|
// Reject qualified-name type names, as we need a plain identifier to
|
|
353
353
|
// resolve the symbol.
|
|
354
354
|
// EXAMPLE:
|
|
355
|
-
// import * as somePackage from '
|
|
355
|
+
// import * as somePackage from '....js';
|
|
356
356
|
// type Actions = somePackage.FooControllerSomeAction;
|
|
357
357
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
358
358
|
if (!ts_morph_1.Node.isIdentifier(nameNode)) {
|
|
@@ -417,7 +417,7 @@ function recursivelyFindMessengerCapabilityTypeDeclarations(node, kind, visitedT
|
|
|
417
417
|
// identifier to match the constructor by name.
|
|
418
418
|
// EXAMPLE:
|
|
419
419
|
// // Bad
|
|
420
|
-
// import * as somePackage from '
|
|
420
|
+
// import * as somePackage from '....js';
|
|
421
421
|
// type FooControllerSomeAction = somePackage.ControllerGetStateAction<...>
|
|
422
422
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
423
423
|
const constructorTypeName = body.getTypeName();
|
package/dist/extraction.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extraction.cjs","sourceRoot":"","sources":["../src/extraction.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'node:path';\nimport type {\n Identifier,\n InterfaceDeclaration,\n JSDocableNode,\n JSDocTag,\n MethodDeclaration,\n Node as TsMorphNode,\n PropertySignature,\n SourceFile,\n TypeAliasDeclaration,\n TypeElementTypes,\n TypeNode,\n TypeReferenceNode,\n} from 'ts-morph';\nimport { Node as NodeGuards, Project, ts } from 'ts-morph';\n\nimport type { MessengerCapabilityPacket, DocumentedParameter } from './types';\n\n// ---------------------------------------------------------------------------\n// NOTE: `ts-morph` is used heavily in this file to parse and extract\n// information from TypeScript files. Although this library is not well\n// documented, it wraps the TypeScript AST fairly well, and you can get a good\n// sense of the AST by using this website: <https://ts-ast-viewer.com>\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// JSDoc utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Convert `{@link X}` references inside a JSDoc comment string to plain\n * backtick code spans and escape any remaining (out-of-backtick) curly braces.\n * This way the output is safe to render in a MDX document.\n *\n * @param text - The raw text to normalize.\n * @returns The text with `@link` resolved and stray braces escaped.\n */\nfunction escapeJsDocTextForMdx(text: string): string {\n const withLinksResolved = text.replace(/\\{@link\\s+([^}]+)\\}/gu, '`$1`');\n return withLinksResolved.replace(\n /`[^`]*`|(\\{)|(\\})/gu,\n (match, open: string | undefined, close: string | undefined) => {\n if (open) {\n return '\\\\{';\n }\n if (close) {\n return '\\\\}';\n }\n return match;\n },\n );\n}\n\n/**\n * Extract the comment text of a JSDoc tag — the part that comes after the tag\n * and any identifier, e.g. \"Some param\" in \"@param foo Some param\" —\n * normalizing whitespace to a single space so we can better control how it's\n * rendered within the site.\n *\n * @param tag - The JSDoc tag.\n * @returns The flattened comment text.\n */\nfunction extractJsDocTagComment(tag: JSDocTag): string {\n return (tag.getCommentText() ?? '').replace(/\\s+/gu, ' ').trim();\n}\n\n/**\n * Strip the conventional `- ` separator from the start of a `@param` tag's\n * comment.\n *\n * @param comment - The flattened comment text from a `@param` tag.\n * @returns The comment with any leading `- ` (or `– `, `— `) removed.\n */\nfunction stripJsDocParamSeparator(comment: string): string {\n return comment.replace(/^[-–—]\\s*/u, '');\n}\n\n/**\n * Extract JSDoc from a TypeScript AST node and decompose it into the parts we\n * need to render docs:\n *\n * - `description` — the body above the first tag, with `@deprecated` comments\n * appended as `**Deprecated:** <comment>` lines and normalized for MDX\n * (curly braces escaped, `{@link}` resolved),\n * - `params` — every `@param` tag in source order, with name and description,\n * - `returns` — the `@returns` tag's comment, or empty string if absent.\n *\n * Other tags (`@see`, `@throws`, `@template`, `@example`) are dropped.\n *\n * @param node - The AST node to extract JSDoc from (e.g. a type or a method).\n * @returns The decomposed JSDoc; empty strings/arrays when the node has no JSDoc.\n */\nfunction extractJsDoc(node: JSDocableNode): {\n description: string;\n params: DocumentedParameter[];\n returns: string;\n} {\n const jsDocs = node.getJsDocs();\n if (jsDocs.length === 0) {\n return { description: '', params: [], returns: '' };\n }\n\n const jsDoc = jsDocs[0];\n const descriptionBody = jsDoc.getDescription().trim();\n\n const deprecatedLines: string[] = [];\n const params: DocumentedParameter[] = [];\n let returns = '';\n\n for (const tag of jsDoc.getTags()) {\n const tagName = tag.getTagName();\n if (tagName === 'deprecated') {\n const comment = extractJsDocTagComment(tag);\n deprecatedLines.push(\n comment ? `**Deprecated:** ${comment}` : '**Deprecated:**',\n );\n } else if (tagName === 'param' && NodeGuards.isJSDocParameterTag(tag)) {\n const nameNode = tag.getNameNode();\n const paramName = nameNode.getText();\n if (!paramName) {\n continue;\n }\n const comment = extractJsDocTagComment(tag);\n params.push({\n name: paramName,\n description: escapeJsDocTextForMdx(stripJsDocParamSeparator(comment)),\n });\n } else if (tagName === 'returns' || tagName === 'return') {\n const comment = extractJsDocTagComment(tag);\n returns = escapeJsDocTextForMdx(comment);\n }\n }\n\n const description = escapeJsDocTextForMdx(\n [descriptionBody, ...deprecatedLines]\n .filter((line) => line.length > 0)\n .join('\\n'),\n );\n\n return { description, params, returns };\n}\n\n/**\n * Check whether a node has an `@deprecated` JSDoc tag.\n *\n * @param node - The AST node to check.\n * @returns True if the node has an `@deprecated` tag.\n */\nfunction hasDeprecatedJsDocTag(node: JSDocableNode): boolean {\n return node\n .getJsDocs()\n .flatMap((jsDoc) => jsDoc.getTags())\n .some((tag) => tag.getTagName() === 'deprecated');\n}\n\n// ---------------------------------------------------------------------------\n// Type-resolution helpers (powered by ts-morph's type checker)\n// ---------------------------------------------------------------------------\n\n/**\n * Locates the type that represents a method on a class (e.g.\n * `Class['method']`), which itself comes from a messenger action handler.\n *\n * @param typeNode - The node that represents the indexed access.\n * @returns The found method declaration, or null.\n */\nfunction findClassMethodDeclaration(\n typeNode: TypeNode | undefined,\n): MethodDeclaration | null {\n // Fundamental check: if we don't have `Class['method']`, we can't do anything.\n if (!NodeGuards.isIndexedAccessTypeNode(typeNode)) {\n return null;\n }\n\n // The type that represents the class being accessed.\n // EXAMPLE:\n // FooController['someMethod']\n // ^^^^^^^^^^^^^\n const objectType = typeNode.getObjectTypeNode();\n // The type that represents the property being accessed.\n // EXAMPLE:\n // FooController['someMethod']\n // ^^^^^^^^^^^^\n const indexType = typeNode.getIndexTypeNode();\n\n // To access a property on a type, it must be a type we can access properties of.\n if (\n !NodeGuards.isTypeReference(objectType) ||\n !NodeGuards.isLiteralTypeNode(indexType)\n ) {\n return null;\n }\n const indexLiteral = indexType.getLiteral();\n // Names of methods must be static strings; they cannot be template strings.\n if (\n !NodeGuards.isStringLiteral(indexLiteral) &&\n !NodeGuards.isNoSubstitutionTemplateLiteral(indexLiteral)\n ) {\n return null;\n }\n const methodName = indexLiteral.getLiteralValue();\n\n // Reject qualified-name type names, as we need a plain identifier to\n // resolve the symbol.\n // EXAMPLE:\n // import * as somePackage from '...';\n // somePackage.FooController['someMethod']\n // ^^^^^^^^^^^^^^^^^^^^^^^^^\n const classNameNode = objectType.getTypeName();\n if (!NodeGuards.isIdentifier(classNameNode)) {\n return null;\n }\n\n // Since we know we have a type reference, we can assume that we have a symbol.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const localSymbol = classNameNode.getSymbol()!;\n // If we have a type imported from another file, ensure that when we access\n // the declaration, it's the type declaration in the other file, not the\n // import declaration in this file.\n // EXAMPLE:\n // import { FooController } from '@metamask/foo-controller';\n // FooController['someMethod']\n // ^^^^^^^^^^^^^\n const symbol = localSymbol.getAliasedSymbol() ?? localSymbol;\n\n for (const declaration of symbol.getDeclarations()) {\n // We must have a class to treat the property on the object type as a\n // method.\n if (NodeGuards.isClassDeclaration(declaration)) {\n const method = declaration.getMethod(methodName);\n if (method) {\n return method;\n }\n }\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Method info\n// ---------------------------------------------------------------------------\n\n/**\n * Build the textual signature of a class method — its parameter list and\n * return type expressed as a TypeScript function type — so a handler that\n * references `Class['method']` can be rendered as `(arg: T) => R` instead of\n * the bare indexed-access syntax.\n *\n * @param method - The method declaration.\n * @returns The signature, e.g. `(id: number) => Promise<string>`.\n */\nfunction buildMethodSignature(method: MethodDeclaration): string {\n const signatureParams = method\n .getParameters()\n .map((param) => {\n const rest = param.isRestParameter() ? '...' : '';\n const paramName = param.getNameNode().getText();\n const optional = param.hasQuestionToken() ? '?' : '';\n const typeNode = param.getTypeNode();\n const paramType = typeNode ? typeNode.getText() : 'unknown';\n return `${rest}${paramName}${optional}: ${paramType}`;\n })\n .join(', ');\n\n const returnTypeNode = method.getReturnTypeNode();\n const returnType = returnTypeNode ? returnTypeNode.getText() : 'void';\n // For async methods, the declared return type already includes `Promise<>`,\n // so we don't need to wrap again.\n return `(${signatureParams}) => ${returnType}`;\n}\n\n// ---------------------------------------------------------------------------\n// Messenger discovery\n// ---------------------------------------------------------------------------\n\n/**\n * A messenger capability type whose body invokes a capability-type-constructor\n * utility such as `ControllerGetStateAction<...>` or\n * `ControllerStateChangeEvent<...>`. The walker classifies the body once when\n * it captures the declaration so the extractor can read the body's type name\n * and type arguments without re-running the AST guards.\n */\ntype ConstructorMessengerCapabilityTypeDeclaration = {\n bodyShape: 'constructor';\n kind: 'action' | 'event';\n declaration: TypeAliasDeclaration;\n body: TypeReferenceNode;\n typeName: Identifier;\n};\n\n/**\n * A messenger capability type whose declaration carries the action/event\n * shape directly — either an interface or a type alias for a type literal.\n * The extractor reads `type`, `handler`, and `payload` from the members.\n */\ntype ObjectMessengerCapabilityTypeDeclaration = {\n bodyShape: 'object';\n kind: 'action' | 'event';\n declaration: TypeAliasDeclaration | InterfaceDeclaration;\n};\n\n/**\n * Represents a type declaration (type alias or interface) for an individual\n * messenger action or event, tagged with the body shape the walker\n * identified.\n */\ntype MessengerCapabilityTypeDeclaration =\n | ConstructorMessengerCapabilityTypeDeclaration\n | ObjectMessengerCapabilityTypeDeclaration;\n\n/**\n * Represents a type alias for a messenger. Only includes nodes representing the\n * `Actions` and `Events` type parameters.\n */\ntype ParsedMessengerTypeAlias = {\n actionsTypeParameter: TypeNode;\n eventsTypeParameter: TypeNode;\n};\n\n/**\n * Looks for Messenger types in the source file (that is, those that are type\n * aliases whose names end with \"Messenger\"), then extracts the `Actions` and\n * `Events` parameters from these types.\n *\n * @param sourceFile - The TypeScript source file to scan.\n * @returns A list of objects that represent messenger types.\n */\nfunction findMessengerTypeAliases(\n sourceFile: SourceFile,\n): ParsedMessengerTypeAlias[] {\n const parsedMessengerTypeAliases: ParsedMessengerTypeAlias[] = [];\n\n for (const typeAlias of sourceFile.getTypeAliases()) {\n if (!typeAlias.getName().endsWith('Messenger')) {\n continue;\n }\n\n const body = typeAlias.getTypeNode();\n // Basic check\n if (!body || !NodeGuards.isTypeReference(body)) {\n continue;\n }\n\n const typeArgs = body.getTypeArguments();\n // Messenger types always have 3 type parameters\n // (e.g. `Messenger<'FooController', Actions, Events>`)\n if (typeArgs.length < 3) {\n continue;\n }\n\n parsedMessengerTypeAliases.push({\n actionsTypeParameter: typeArgs[1],\n eventsTypeParameter: typeArgs[2],\n });\n }\n\n return parsedMessengerTypeAliases;\n}\n\n/**\n * Walks the `Actions` and `Events` type parameters of the given messenger\n * types, extracted in a previous step, to find all type declarations (i.e.,\n * statements) that represent individual messenger actions or events.\n *\n * @param parsedMessengerTypeAliases - The list of objects representing\n * messenger types, parsed in a previous step.\n * @returns The list of type aliases that represent messenger capabilities among\n * the given messenger types.\n */\nfunction findAllMessengerCapabilityTypeDeclarations(\n parsedMessengerTypeAliases: ParsedMessengerTypeAlias[],\n): MessengerCapabilityTypeDeclaration[] {\n const allCapabilityTypeDeclarations: MessengerCapabilityTypeDeclaration[] =\n [];\n let allVisitedTypeDeclarations: Set<TsMorphNode> = new Set();\n\n for (const {\n actionsTypeParameter,\n eventsTypeParameter,\n } of parsedMessengerTypeAliases) {\n for (const [typeParameter, kind] of [\n [actionsTypeParameter, 'action'],\n [eventsTypeParameter, 'event'],\n ] as const) {\n const result = recursivelyFindMessengerCapabilityTypeDeclarations(\n typeParameter,\n kind,\n allVisitedTypeDeclarations,\n );\n allCapabilityTypeDeclarations.push(...result.capabilityTypeDeclarations);\n allVisitedTypeDeclarations = result.visitedTypeDeclarations;\n }\n }\n\n return allCapabilityTypeDeclarations;\n}\n\n/**\n * Recursively walks a `ts-morph` AST node — at first the `Actions` or `Events`\n * type parameter of a messenger type, and then a node within that parameter —\n * to find all type aliases that represent individual messenger actions or\n * events, no matter how deeply the type aliases exist in the tree or in which\n * file they are located.\n *\n * @param node - The `ts-morph` AST node to walk.\n * @param kind - Whether to tag found type aliases as 'action' or 'event'.\n * @param visitedTypeDeclarations - A variable that tracks visited type aliases\n * and prevents duplicates.\n * @returns The list of extracted messenger capability type aliases as well as\n * an updated version of `visitedTypeDeclarations`.\n */\nfunction recursivelyFindMessengerCapabilityTypeDeclarations(\n node: TsMorphNode,\n kind: 'action' | 'event',\n visitedTypeDeclarations: Set<TsMorphNode>,\n): {\n capabilityTypeDeclarations: MessengerCapabilityTypeDeclaration[];\n visitedTypeDeclarations: Set<TsMorphNode>;\n} {\n const result: {\n capabilityTypeDeclarations: MessengerCapabilityTypeDeclaration[];\n visitedTypeDeclarations: Set<TsMorphNode>;\n } = {\n capabilityTypeDeclarations: [],\n visitedTypeDeclarations: new Set([...visitedTypeDeclarations]),\n };\n\n // If `node` is a union type, walk each type within it.\n // EXAMPLES:\n // type Actions = FooControllerSomeAction | FooControllerSomeOtherAction\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // type FooControllerActions = FooControllerSomeAction | FooControllerSomeOtherAction\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (NodeGuards.isUnionTypeNode(node)) {\n for (const typeNode of node.getTypeNodes()) {\n const innerResult = recursivelyFindMessengerCapabilityTypeDeclarations(\n typeNode,\n kind,\n result.visitedTypeDeclarations,\n );\n result.capabilityTypeDeclarations.push(\n ...innerResult.capabilityTypeDeclarations,\n );\n for (const typeDeclaration of innerResult.visitedTypeDeclarations) {\n result.visitedTypeDeclarations.add(typeDeclaration);\n }\n }\n return result;\n }\n\n // If `node` is not a type reference, don't walk it.\n // EXAMPLE:\n // // Bad\n // type Actions = { ... }\n // ^^^^^^^\n // // Good\n // type Actions = FooControllerSomeAction;\n // ^^^^^^^^^^^^^^^^^^^^^^^\n // // Good\n // type Actions = ControllerGetStateAction<...>;\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (!NodeGuards.isTypeReference(node)) {\n return result;\n }\n\n const nameNode = node.getTypeName();\n\n // Reject qualified-name type names, as we need a plain identifier to\n // resolve the symbol.\n // EXAMPLE:\n // import * as somePackage from '...';\n // type Actions = somePackage.FooControllerSomeAction;\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (!NodeGuards.isIdentifier(nameNode)) {\n return result;\n }\n\n // Since we know we have a type reference, we can assume that we have a symbol.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const localSymbol = nameNode.getSymbol()!;\n // If we have a type imported from another file, ensure that when we access\n // the declaration, it's the type declaration in the other file, not the\n // import declaration in this file.\n // EXAMPLE:\n // import { FooControllerSomeAction } from '@metamask/foo-controller';\n // type Actions = FooControllerSomeAction;\n // ^^^^^^^^^^^^^^^^^^^^^^^\n const symbol = localSymbol.getAliasedSymbol() ?? localSymbol;\n\n // At this point, we have a type *reference*, but we need to find the type\n // *declaration*.\n // For instance, if we have `FooControllerSomeAction`, we need to find\n // the full `type FooControllerSomeAction = ...` statement.\n for (const declaration of symbol.getDeclarations()) {\n // Prevent duplicates\n if (result.visitedTypeDeclarations.has(declaration)) {\n continue;\n }\n result.visitedTypeDeclarations.add(declaration);\n\n // If we have a type alias, then we have to handle a few scenarios.\n // EXAMPLES:\n // type FooControllerMethodActions = ...\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // type FooControllerSomeAction = ...\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (NodeGuards.isTypeAliasDeclaration(declaration)) {\n const body = declaration.getTypeNode();\n\n // If the body is a union type or a plain type reference (not a utility\n // type), walk it.\n // EXAMPLES:\n // type FooControllerMethodActions = FooControllerSomeAction | FooControllerSomeOtherAction\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // type DelegationControllerMethodActions = DelegationControllerSignDelegationAction\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (\n body &&\n (NodeGuards.isUnionTypeNode(body) ||\n (NodeGuards.isTypeReference(body) &&\n body.getTypeArguments().length === 0))\n ) {\n const innerResult = recursivelyFindMessengerCapabilityTypeDeclarations(\n body,\n kind,\n result.visitedTypeDeclarations,\n );\n result.capabilityTypeDeclarations.push(\n ...innerResult.capabilityTypeDeclarations,\n );\n for (const typeDeclaration of innerResult.visitedTypeDeclarations) {\n result.visitedTypeDeclarations.add(typeDeclaration);\n }\n continue;\n }\n\n // A TypeReference body with type arguments is a capability-type-\n // constructor invocation (e.g. `ControllerGetStateAction<typeof name,\n // State>`). Tag it so the constructor extractor can read `body`\n // directly without re-checking its shape.\n // EXAMPLE:\n // type FooControllerSomeAction = ControllerGetStateAction<...>\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (body && NodeGuards.isTypeReference(body)) {\n // Reject qualified-name constructor type names, as we need a plain\n // identifier to match the constructor by name.\n // EXAMPLE:\n // // Bad\n // import * as somePackage from '...';\n // type FooControllerSomeAction = somePackage.ControllerGetStateAction<...>\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n const constructorTypeName = body.getTypeName();\n if (NodeGuards.isIdentifier(constructorTypeName)) {\n result.capabilityTypeDeclarations.push({\n bodyShape: 'constructor',\n kind,\n declaration,\n body,\n typeName: constructorTypeName,\n });\n }\n continue;\n }\n\n // Anything else (a type literal, intersection, conditional, …) gets\n // tagged for the literal extractor, which knows how to read members\n // off a type literal and rejects exotic shapes.\n // EXAMPLE:\n // type FooControllerSomeAction = { ... }\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n result.capabilityTypeDeclarations.push({\n bodyShape: 'object',\n kind,\n declaration,\n });\n }\n\n // Interfaces always carry their members directly — tag for the literal\n // extractor.\n // EXAMPLE:\n // interface FooControllerSomeAction { ... }\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n else if (NodeGuards.isInterfaceDeclaration(declaration)) {\n result.capabilityTypeDeclarations.push({\n bodyShape: 'object',\n kind,\n declaration,\n });\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Per-statement extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Given the declaration of a messenger capability type, extract information\n * about it (action/event type string, handler/payload arguments and return\n * type, etc.)\n *\n * @param capabilityTypeDeclaration - The statement that declared the type for a\n * messenger action or event, extracted in a previous step.\n * @param projectPath - Project root, used for computing relative source paths.\n * @returns Information that may be extracted from the messenger capability type\n * (may be `null` if the type is ineligible for extraction).\n */\nfunction extractFromMessengerCapabilityTypeDeclaration(\n capabilityTypeDeclaration: MessengerCapabilityTypeDeclaration,\n projectPath: string,\n): MessengerCapabilityPacket | null {\n if (capabilityTypeDeclaration.bodyShape === 'constructor') {\n return tryToExtractFromCapabilityTypeConstructor(\n capabilityTypeDeclaration,\n projectPath,\n );\n }\n return tryToExtractFromMessengerCapabilityTypeLiteral(\n capabilityTypeDeclaration,\n projectPath,\n );\n}\n\n/**\n * If a messenger capability type is a type alias or interface and its body is\n * a literal object type — i.e. one of:\n *\n * - `{ type: '...'; handler: ... }` (action)\n * - `{ type: '...'; payload: ... }` (event)\n *\n * then this function extracts information about the type (action/event type\n * string, handler/payload arguments and return type, etc.)\n *\n * @param capabilityTypeDeclaration - The statement that declared the type for a\n * messenger action or event, extracted in a previous step.\n * @param projectPath - Project root, used for computing relative source paths.\n * @returns The extracted capability packet, or null if the shape of the type\n * doesn't match.\n */\nfunction tryToExtractFromMessengerCapabilityTypeLiteral(\n capabilityTypeDeclaration: ObjectMessengerCapabilityTypeDeclaration,\n projectPath: string,\n): MessengerCapabilityPacket | null {\n const { declaration, kind } = capabilityTypeDeclaration;\n\n // We must have a object type alias or an interface, and the body must not be empty.\n // EXAMPLES:\n // // Good\n // type FooControllerSomeAction = {\n // type: 'FooController:getState';\n // handler: FooController['getState'];\n // }\n // // Good\n // interface FooControllerSomeAction {\n // type: 'FooController:getState';\n // handler: FooController['getState'];\n // }\n // // Bad\n // type FooControllerSomeAction = {};\n // // Bad\n // interface FooControllerSomeAction {};\n let members: TypeElementTypes[] | undefined;\n if (NodeGuards.isTypeAliasDeclaration(declaration)) {\n const body = declaration.getTypeNode();\n if (body && NodeGuards.isTypeLiteral(body)) {\n members = body.getMembers();\n }\n } else {\n members = declaration.getMembers();\n }\n if (!members) {\n return null;\n }\n\n const propertySignatures = members.filter(\n NodeGuards.isPropertySignature.bind(NodeGuards),\n );\n\n // Actions and events must have a `type`, and it must be a string.\n const typeString = getMessengerCapabilityTypeString(propertySignatures);\n if (!typeString) {\n return null;\n }\n\n // Actions must have a `handler`, and events must have a `payload`.\n const handlerOrPayloadProperty = findProperty(\n propertySignatures,\n kind === 'action' ? 'handler' : 'payload',\n );\n if (!handlerOrPayloadProperty) {\n return null;\n }\n\n const handlerOrPayloadPropertyTypeNode =\n // We can assume the property has a type; otherwise it wouldn't compile.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n handlerOrPayloadProperty.getTypeNode()!;\n let handlerOrPayloadSignature = handlerOrPayloadPropertyTypeNode\n .getText()\n .trim();\n\n const { description: jsDoc, params, returns } = extractJsDoc(declaration);\n\n // For actions that represent methods (e.g. `Class['method']`), walk the\n // handler type to find the underlying handler signature\n // (e.g. `(id: number) => Promise<string>`).\n if (kind === 'action') {\n const methodDeclaration = findClassMethodDeclaration(\n handlerOrPayloadPropertyTypeNode,\n );\n if (methodDeclaration) {\n handlerOrPayloadSignature = buildMethodSignature(methodDeclaration);\n }\n }\n\n const sourceFile = declaration.getSourceFile();\n return {\n typeName: declaration.getName(),\n typeString,\n kind,\n jsDoc,\n params,\n returns,\n handlerOrPayload: handlerOrPayloadSignature,\n sourceFile: path.relative(projectPath, sourceFile.getFilePath()),\n line: declaration.getStartLineNumber(),\n deprecated: hasDeprecatedJsDocTag(declaration),\n };\n}\n\n/**\n * Searches the property signatures of a messenger capability type alias or\n * interface to find the value of the `type` property, and then resolves it to a\n * string (assuming it is already a string or a resolvable template literal).\n *\n * @param capabilityTypeProperties - The property signatures of the messenger\n * capability type.\n * @returns The extracted capability type string, or null if `type` cannot be\n * found in the members or it is an unexpected node.\n */\nfunction getMessengerCapabilityTypeString(\n capabilityTypeProperties: PropertySignature[],\n): string | null {\n const typeProperty = findProperty(capabilityTypeProperties, 'type');\n if (!typeProperty) {\n return null;\n }\n\n // A `type` property without an explicit type wouldn't compile.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const typeNode = typeProperty.getTypeNode()!;\n\n // Ask the type checker to resolve the value of `type`. We're looking for\n // `type` to be either a string literal or template literal.\n //\n // EXAMPLES:\n // type FooControllerSomeAction = {\n // type: 'FooController:someAction';\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^\n // }\n // type FooControllerSomeAction = {\n // type: `FooController:someAction`;\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^\n // }\n // type FooControllerSomeAction = {\n // type: `${typeof CONTROLLER_NAME}:someAction`;\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // }\n const resolvedType = typeNode.getType();\n if (resolvedType.isStringLiteral()) {\n // Type assertion: There aren't any type guards we can use to narrow this\n // type further.\n const literalValue = resolvedType.getLiteralValueOrThrow() as string;\n\n // Messenger action/event types need to be namespaced.\n if (literalValue.includes(':')) {\n return literalValue;\n }\n }\n\n return null;\n}\n\n/**\n * Finds a specific property in a list of property signatures for an object\n * type.\n *\n * @param propertySignatures - The property signatures of the messenger\n * capability type.\n * @param name - The property name to find.\n * @returns The property signature, or null.\n */\nfunction findProperty(\n propertySignatures: PropertySignature[],\n name: string,\n): PropertySignature | null {\n for (const property of propertySignatures) {\n const propertyNameNode = property.getNameNode();\n if (\n !NodeGuards.isIdentifier(propertyNameNode) ||\n propertyNameNode.getText() !== name\n ) {\n continue;\n }\n\n return property;\n }\n\n return null;\n}\n\n/**\n * If a messenger capability type is a type alias for either the\n * `ControllerGetStateAction` or `ControllerStateChangeEvent` type constructors,\n * then this function extracts information about the type (action/event type\n * string, handler/payload arguments and return type, etc.)\n *\n * @param capabilityTypeDeclaration - The statement that declared the type for a\n * messenger action or event, extracted in a previous step.\n * @param projectPath - Project root, used for computing relative source paths.\n * @returns The extracted capability packet, or null if the shape of the type\n * doesn't match.\n */\nfunction tryToExtractFromCapabilityTypeConstructor(\n capabilityTypeDeclaration: ConstructorMessengerCapabilityTypeDeclaration,\n projectPath: string,\n): MessengerCapabilityPacket | null {\n const { declaration, kind, body, typeName } = capabilityTypeDeclaration;\n\n // The name of the utility type should be either `ControllerGetStateAction`\n // (for actions) or `ControllerStateChangeEvent` (for events).\n // EXAMPLES:\n // type FooControllerSomeAction = ControllerGetStateAction<...>\n // type FooControllerSomeEvent = ControllerStateChangeEvent<...>\n const expectedConstructor =\n kind === 'action'\n ? 'ControllerGetStateAction'\n : 'ControllerStateChangeEvent';\n if (typeName.getText() !== expectedConstructor) {\n return null;\n }\n\n // The utility type should take two parameters.\n // EXAMPLES:\n // type FooControllerSomeAction = ControllerGetStateAction<..., ...>\n // type FooControllerSomeEvent = ControllerStateChangeEvent<..., ...>\n const typeArgs = body.getTypeArguments();\n if (typeArgs.length < 2) {\n return null;\n }\n\n const namespaceArgType = typeArgs[0].getType();\n // The first parameter should be a string literal.\n // EXAMPLES:\n // type FooControllerSomeAction = ControllerGetStateAction<'FooController', ...>\n // type FooControllerSomeAction = ControllerGetStateAction<typeof CONTROLLER_NAME, ...>\n if (!namespaceArgType.isStringLiteral()) {\n return null;\n }\n // Type assertion: There aren't any type guards we can use to narrow this type\n // further.\n const namespace = namespaceArgType.getLiteralValueOrThrow() as string;\n\n const typeString =\n kind === 'action' ? `${namespace}:getState` : `${namespace}:stateChange`;\n const stateArgText = typeArgs[1].getText();\n const handlerOrPayload =\n kind === 'action' ? `() => ${stateArgText}` : `[${stateArgText}, Patch[]]`;\n const { description, params, returns } = extractJsDoc(declaration);\n const sourceFile = declaration.getSourceFile();\n\n return {\n typeName: declaration.getName(),\n typeString,\n kind,\n jsDoc: description,\n params,\n returns,\n handlerOrPayload,\n sourceFile: path.relative(projectPath, sourceFile.getFilePath()),\n line: declaration.getStartLineNumber(),\n deprecated: hasDeprecatedJsDocTag(declaration),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public entry points\n// ---------------------------------------------------------------------------\n\n/**\n * Create a ts-morph Project configured for messenger-docs extraction. The\n * caller should add every source file that may be referenced (directly or\n * transitively) before calling {@link extractFromSourceFile}, so the type\n * checker can resolve cross-file references.\n *\n * @returns A new ts-morph Project.\n */\nexport function createExtractionProject(): Project {\n return new Project({\n compilerOptions: {\n allowJs: false,\n noEmit: true,\n // Match the project's permissive defaults — we just need symbol\n // resolution, not full typechecking.\n strict: false,\n skipLibCheck: true,\n // Explicit module options so cross-file symbol resolution works\n // regardless of the host process's tsconfig.\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.NodeJs,\n },\n });\n}\n\n/**\n * Extract information (action/event type string, handler/payload arguments and\n * return type, etc.) about every messenger action or event type which is\n * reachable through all of a source file's `*Messenger` type declarations.\n *\n * The caller is responsible for ensuring `sourceFile` (plus any files it\n * imports from) belongs to a `ts-morph` Project so cross-file symbol resolution\n * works.\n *\n * @param sourceFile - The TypeScript source file to extract from.\n * @param projectPath - Project root, used for computing relative source paths.\n * @returns The extracted information about actions and events.\n */\nexport function extractFromSourceFile(\n sourceFile: SourceFile,\n projectPath: string,\n): MessengerCapabilityPacket[] {\n const messengerTypeAliases = findMessengerTypeAliases(sourceFile);\n\n const capabilityTypeDeclarations =\n findAllMessengerCapabilityTypeDeclarations(messengerTypeAliases);\n\n const messengerCapabilityPackets: MessengerCapabilityPacket[] = [];\n for (const capabilityTypeDeclaration of capabilityTypeDeclarations) {\n const messengerCapabilityPacket =\n extractFromMessengerCapabilityTypeDeclaration(\n capabilityTypeDeclaration,\n projectPath,\n );\n if (messengerCapabilityPacket) {\n messengerCapabilityPackets.push(messengerCapabilityPacket);\n }\n }\n return messengerCapabilityPackets;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"extraction.cjs","sourceRoot":"","sources":["../src/extraction.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAAkC;AAelC,uCAA2D;AAO3D,8EAA8E;AAC9E,qEAAqE;AACrE,uEAAuE;AACvE,8EAA8E;AAC9E,sEAAsE;AACtE,8EAA8E;AAE9E,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;;;GAOG;AACH,SAAS,qBAAqB,CAAC,IAAY;IACzC,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;IACxE,OAAO,iBAAiB,CAAC,OAAO,CAC9B,qBAAqB,EACrB,CAAC,KAAK,EAAE,IAAwB,EAAE,KAAyB,EAAE,EAAE;QAC7D,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,sBAAsB,CAAC,GAAa;IAC3C,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACnE,CAAC;AAED;;;;;;GAMG;AACH,SAAS,wBAAwB,CAAC,OAAe;IAC/C,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,YAAY,CAAC,IAAmB;IAKvC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IAChC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACtD,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,CAAC;IAEtD,MAAM,eAAe,GAAa,EAAE,CAAC;IACrC,MAAM,MAAM,GAA0B,EAAE,CAAC;IACzC,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QACjC,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;YAC5C,eAAe,CAAC,IAAI,CAClB,OAAO,CAAC,CAAC,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAC3D,CAAC;QACJ,CAAC;aAAM,IAAI,OAAO,KAAK,OAAO,IAAI,eAAU,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;YACtE,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YACnC,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,SAAS;YACX,CAAC;YACD,MAAM,OAAO,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,qBAAqB,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;aACtE,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;YACzD,MAAM,OAAO,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;YAC5C,OAAO,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,qBAAqB,CACvC,CAAC,eAAe,EAAE,GAAG,eAAe,CAAC;SAClC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC,IAAI,CAAC,IAAI,CAAC,CACd,CAAC;IAEF,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,SAAS,qBAAqB,CAAC,IAAmB;IAChD,OAAO,IAAI;SACR,SAAS,EAAE;SACX,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;SACnC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,YAAY,CAAC,CAAC;AACtD,CAAC;AAED,8EAA8E;AAC9E,+DAA+D;AAC/D,8EAA8E;AAE9E;;;;;;GAMG;AACH,SAAS,0BAA0B,CACjC,QAA8B;IAE9B,+EAA+E;IAC/E,IAAI,CAAC,eAAU,CAAC,uBAAuB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qDAAqD;IACrD,WAAW;IACX,gCAAgC;IAChC,kBAAkB;IAClB,MAAM,UAAU,GAAG,QAAQ,CAAC,iBAAiB,EAAE,CAAC;IAChD,wDAAwD;IACxD,WAAW;IACX,gCAAgC;IAChC,+BAA+B;IAC/B,MAAM,SAAS,GAAG,QAAQ,CAAC,gBAAgB,EAAE,CAAC;IAE9C,iFAAiF;IACjF,IACE,CAAC,eAAU,CAAC,eAAe,CAAC,UAAU,CAAC;QACvC,CAAC,eAAU,CAAC,iBAAiB,CAAC,SAAS,CAAC,EACxC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,YAAY,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC;IAC5C,4EAA4E;IAC5E,IACE,CAAC,eAAU,CAAC,eAAe,CAAC,YAAY,CAAC;QACzC,CAAC,eAAU,CAAC,+BAA+B,CAAC,YAAY,CAAC,EACzD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,UAAU,GAAG,YAAY,CAAC,eAAe,EAAE,CAAC;IAElD,qEAAqE;IACrE,sBAAsB;IACtB,WAAW;IACX,2CAA2C;IAC3C,4CAA4C;IAC5C,8BAA8B;IAC9B,MAAM,aAAa,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IAC/C,IAAI,CAAC,eAAU,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+EAA+E;IAC/E,oEAAoE;IACpE,MAAM,WAAW,GAAG,aAAa,CAAC,SAAS,EAAG,CAAC;IAC/C,2EAA2E;IAC3E,wEAAwE;IACxE,mCAAmC;IACnC,WAAW;IACX,8DAA8D;IAC9D,gCAAgC;IAChC,kBAAkB;IAClB,MAAM,MAAM,GAAG,WAAW,CAAC,gBAAgB,EAAE,IAAI,WAAW,CAAC;IAE7D,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,eAAe,EAAE,EAAE,CAAC;QACnD,qEAAqE;QACrE,UAAU;QACV,IAAI,eAAU,CAAC,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACjD,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,SAAS,oBAAoB,CAAC,MAAyB;IACrD,MAAM,eAAe,GAAG,MAAM;SAC3B,aAAa,EAAE;SACf,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5D,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,KAAK,SAAS,EAAE,CAAC;IACxD,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,cAAc,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAC;IAClD,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IACtE,4EAA4E;IAC5E,kCAAkC;IAClC,OAAO,IAAI,eAAe,QAAQ,UAAU,EAAE,CAAC;AACjD,CAAC;AAkDD;;;;;;;GAOG;AACH,SAAS,wBAAwB,CAC/B,UAAsB;IAEtB,MAAM,0BAA0B,GAA+B,EAAE,CAAC;IAElE,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,cAAc,EAAE,EAAE,CAAC;QACpD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,SAAS;QACX,CAAC;QAED,MAAM,IAAI,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QACrC,cAAc;QACd,IAAI,CAAC,IAAI,IAAI,CAAC,eAAU,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/C,SAAS;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACzC,gDAAgD;QAChD,uDAAuD;QACvD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,SAAS;QACX,CAAC;QAED,0BAA0B,CAAC,IAAI,CAAC;YAC9B,oBAAoB,EAAE,QAAQ,CAAC,CAAC,CAAC;YACjC,mBAAmB,EAAE,QAAQ,CAAC,CAAC,CAAC;SACjC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,0BAA0B,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,0CAA0C,CACjD,0BAAsD;IAEtD,MAAM,6BAA6B,GACjC,EAAE,CAAC;IACL,IAAI,0BAA0B,GAAqB,IAAI,GAAG,EAAE,CAAC;IAE7D,KAAK,MAAM,EACT,oBAAoB,EACpB,mBAAmB,GACpB,IAAI,0BAA0B,EAAE,CAAC;QAChC,KAAK,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI;YAClC,CAAC,oBAAoB,EAAE,QAAQ,CAAC;YAChC,CAAC,mBAAmB,EAAE,OAAO,CAAC;SACtB,EAAE,CAAC;YACX,MAAM,MAAM,GAAG,kDAAkD,CAC/D,aAAa,EACb,IAAI,EACJ,0BAA0B,CAC3B,CAAC;YACF,6BAA6B,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;YACzE,0BAA0B,GAAG,MAAM,CAAC,uBAAuB,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,OAAO,6BAA6B,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,kDAAkD,CACzD,IAAiB,EACjB,IAAwB,EACxB,uBAAyC;IAKzC,MAAM,MAAM,GAGR;QACF,0BAA0B,EAAE,EAAE;QAC9B,uBAAuB,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,uBAAuB,CAAC,CAAC;KAC/D,CAAC;IAEF,uDAAuD;IACvD,YAAY;IACZ,0EAA0E;IAC1E,0EAA0E;IAC1E,uFAAuF;IACvF,uFAAuF;IACvF,IAAI,eAAU,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YAC3C,MAAM,WAAW,GAAG,kDAAkD,CACpE,QAAQ,EACR,IAAI,EACJ,MAAM,CAAC,uBAAuB,CAC/B,CAAC;YACF,MAAM,CAAC,0BAA0B,CAAC,IAAI,CACpC,GAAG,WAAW,CAAC,0BAA0B,CAC1C,CAAC;YACF,KAAK,MAAM,eAAe,IAAI,WAAW,CAAC,uBAAuB,EAAE,CAAC;gBAClE,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,oDAAoD;IACpD,WAAW;IACX,WAAW;IACX,2BAA2B;IAC3B,2BAA2B;IAC3B,YAAY;IACZ,4CAA4C;IAC5C,2CAA2C;IAC3C,YAAY;IACZ,kDAAkD;IAClD,iDAAiD;IACjD,IAAI,CAAC,eAAU,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAEpC,qEAAqE;IACrE,sBAAsB;IACtB,WAAW;IACX,2CAA2C;IAC3C,wDAAwD;IACxD,uDAAuD;IACvD,IAAI,CAAC,eAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,+EAA+E;IAC/E,oEAAoE;IACpE,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,EAAG,CAAC;IAC1C,2EAA2E;IAC3E,wEAAwE;IACxE,mCAAmC;IACnC,WAAW;IACX,wEAAwE;IACxE,4CAA4C;IAC5C,2CAA2C;IAC3C,MAAM,MAAM,GAAG,WAAW,CAAC,gBAAgB,EAAE,IAAI,WAAW,CAAC;IAE7D,0EAA0E;IAC1E,iBAAiB;IACjB,sEAAsE;IACtE,2DAA2D;IAC3D,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,eAAe,EAAE,EAAE,CAAC;QACnD,qBAAqB;QACrB,IAAI,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YACpD,SAAS;QACX,CAAC;QACD,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAEhD,mEAAmE;QACnE,YAAY;QACZ,0CAA0C;QAC1C,yCAAyC;QACzC,uCAAuC;QACvC,sCAAsC;QACtC,IAAI,eAAU,CAAC,sBAAsB,CAAC,WAAW,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;YAEvC,uEAAuE;YACvE,kBAAkB;YAClB,YAAY;YACZ,6FAA6F;YAC7F,6FAA6F;YAC7F,sFAAsF;YACtF,sFAAsF;YACtF,IACE,IAAI;gBACJ,CAAC,eAAU,CAAC,eAAe,CAAC,IAAI,CAAC;oBAC/B,CAAC,eAAU,CAAC,eAAe,CAAC,IAAI,CAAC;wBAC/B,IAAI,CAAC,gBAAgB,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,EAC1C,CAAC;gBACD,MAAM,WAAW,GAAG,kDAAkD,CACpE,IAAI,EACJ,IAAI,EACJ,MAAM,CAAC,uBAAuB,CAC/B,CAAC;gBACF,MAAM,CAAC,0BAA0B,CAAC,IAAI,CACpC,GAAG,WAAW,CAAC,0BAA0B,CAC1C,CAAC;gBACF,KAAK,MAAM,eAAe,IAAI,WAAW,CAAC,uBAAuB,EAAE,CAAC;oBAClE,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;gBACtD,CAAC;gBACD,SAAS;YACX,CAAC;YAED,iEAAiE;YACjE,sEAAsE;YACtE,gEAAgE;YAChE,0CAA0C;YAC1C,WAAW;YACX,iEAAiE;YACjE,iEAAiE;YACjE,IAAI,IAAI,IAAI,eAAU,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7C,mEAAmE;gBACnE,+CAA+C;gBAC/C,WAAW;gBACX,WAAW;gBACX,2CAA2C;gBAC3C,6EAA6E;gBAC7E,wEAAwE;gBACxE,MAAM,mBAAmB,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC/C,IAAI,eAAU,CAAC,YAAY,CAAC,mBAAmB,CAAC,EAAE,CAAC;oBACjD,MAAM,CAAC,0BAA0B,CAAC,IAAI,CAAC;wBACrC,SAAS,EAAE,aAAa;wBACxB,IAAI;wBACJ,WAAW;wBACX,IAAI;wBACJ,QAAQ,EAAE,mBAAmB;qBAC9B,CAAC,CAAC;gBACL,CAAC;gBACD,SAAS;YACX,CAAC;YAED,oEAAoE;YACpE,oEAAoE;YACpE,gDAAgD;YAChD,WAAW;YACX,2CAA2C;YAC3C,2CAA2C;YAC3C,MAAM,CAAC,0BAA0B,CAAC,IAAI,CAAC;gBACrC,SAAS,EAAE,QAAQ;gBACnB,IAAI;gBACJ,WAAW;aACZ,CAAC,CAAC;QACL,CAAC;QAED,uEAAuE;QACvE,aAAa;QACb,WAAW;QACX,8CAA8C;QAC9C,8CAA8C;aACzC,IAAI,eAAU,CAAC,sBAAsB,CAAC,WAAW,CAAC,EAAE,CAAC;YACxD,MAAM,CAAC,0BAA0B,CAAC,IAAI,CAAC;gBACrC,SAAS,EAAE,QAAQ;gBACnB,IAAI;gBACJ,WAAW;aACZ,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,SAAS,6CAA6C,CACpD,yBAA6D,EAC7D,WAAmB;IAEnB,IAAI,yBAAyB,CAAC,SAAS,KAAK,aAAa,EAAE,CAAC;QAC1D,OAAO,yCAAyC,CAC9C,yBAAyB,EACzB,WAAW,CACZ,CAAC;IACJ,CAAC;IACD,OAAO,8CAA8C,CACnD,yBAAyB,EACzB,WAAW,CACZ,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAS,8CAA8C,CACrD,yBAAmE,EACnE,WAAmB;IAEnB,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,yBAAyB,CAAC;IAExD,oFAAoF;IACpF,YAAY;IACZ,YAAY;IACZ,qCAAqC;IACrC,sCAAsC;IACtC,0CAA0C;IAC1C,MAAM;IACN,YAAY;IACZ,wCAAwC;IACxC,sCAAsC;IACtC,0CAA0C;IAC1C,MAAM;IACN,WAAW;IACX,uCAAuC;IACvC,WAAW;IACX,0CAA0C;IAC1C,IAAI,OAAuC,CAAC;IAC5C,IAAI,eAAU,CAAC,sBAAsB,CAAC,WAAW,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;QACvC,IAAI,IAAI,IAAI,eAAU,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,WAAW,CAAC,UAAU,EAAE,CAAC;IACrC,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,MAAM,CACvC,eAAU,CAAC,mBAAmB,CAAC,IAAI,CAAC,eAAU,CAAC,CAChD,CAAC;IAEF,kEAAkE;IAClE,MAAM,UAAU,GAAG,gCAAgC,CAAC,kBAAkB,CAAC,CAAC;IACxE,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mEAAmE;IACnE,MAAM,wBAAwB,GAAG,YAAY,CAC3C,kBAAkB,EAClB,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAC1C,CAAC;IACF,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,gCAAgC;IACpC,wEAAwE;IACxE,oEAAoE;IACpE,wBAAwB,CAAC,WAAW,EAAG,CAAC;IAC1C,IAAI,yBAAyB,GAAG,gCAAgC;SAC7D,OAAO,EAAE;SACT,IAAI,EAAE,CAAC;IAEV,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IAE1E,wEAAwE;IACxE,wDAAwD;IACxD,4CAA4C;IAC5C,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,iBAAiB,GAAG,0BAA0B,CAClD,gCAAgC,CACjC,CAAC;QACF,IAAI,iBAAiB,EAAE,CAAC;YACtB,yBAAyB,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC;IAC/C,OAAO;QACL,QAAQ,EAAE,WAAW,CAAC,OAAO,EAAE;QAC/B,UAAU;QACV,IAAI;QACJ,KAAK;QACL,MAAM;QACN,OAAO;QACP,gBAAgB,EAAE,yBAAyB;QAC3C,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC;QAChE,IAAI,EAAE,WAAW,CAAC,kBAAkB,EAAE;QACtC,UAAU,EAAE,qBAAqB,CAAC,WAAW,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,gCAAgC,CACvC,wBAA6C;IAE7C,MAAM,YAAY,GAAG,YAAY,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;IACpE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+DAA+D;IAC/D,oEAAoE;IACpE,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,EAAG,CAAC;IAE7C,yEAAyE;IACzE,4DAA4D;IAC5D,EAAE;IACF,YAAY;IACZ,qCAAqC;IACrC,wCAAwC;IACxC,uCAAuC;IACvC,MAAM;IACN,qCAAqC;IACrC,wCAAwC;IACxC,uCAAuC;IACvC,MAAM;IACN,qCAAqC;IACrC,oDAAoD;IACpD,mDAAmD;IACnD,MAAM;IACN,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;IACxC,IAAI,YAAY,CAAC,eAAe,EAAE,EAAE,CAAC;QACnC,yEAAyE;QACzE,gBAAgB;QAChB,MAAM,YAAY,GAAG,YAAY,CAAC,sBAAsB,EAAY,CAAC;QAErE,sDAAsD;QACtD,IAAI,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,YAAY,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,YAAY,CACnB,kBAAuC,EACvC,IAAY;IAEZ,KAAK,MAAM,QAAQ,IAAI,kBAAkB,EAAE,CAAC;QAC1C,MAAM,gBAAgB,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QAChD,IACE,CAAC,eAAU,CAAC,YAAY,CAAC,gBAAgB,CAAC;YAC1C,gBAAgB,CAAC,OAAO,EAAE,KAAK,IAAI,EACnC,CAAC;YACD,SAAS;QACX,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,yCAAyC,CAChD,yBAAwE,EACxE,WAAmB;IAEnB,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,yBAAyB,CAAC;IAExE,2EAA2E;IAC3E,8DAA8D;IAC9D,YAAY;IACZ,iEAAiE;IACjE,kEAAkE;IAClE,MAAM,mBAAmB,GACvB,IAAI,KAAK,QAAQ;QACf,CAAC,CAAC,0BAA0B;QAC5B,CAAC,CAAC,4BAA4B,CAAC;IACnC,IAAI,QAAQ,CAAC,OAAO,EAAE,KAAK,mBAAmB,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+CAA+C;IAC/C,YAAY;IACZ,sEAAsE;IACtE,uEAAuE;IACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACzC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,gBAAgB,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/C,kDAAkD;IAClD,YAAY;IACZ,kFAAkF;IAClF,yFAAyF;IACzF,IAAI,CAAC,gBAAgB,CAAC,eAAe,EAAE,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,8EAA8E;IAC9E,WAAW;IACX,MAAM,SAAS,GAAG,gBAAgB,CAAC,sBAAsB,EAAY,CAAC;IAEtE,MAAM,UAAU,GACd,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,cAAc,CAAC;IAC3E,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAC3C,MAAM,gBAAgB,GACpB,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,YAAY,YAAY,CAAC;IAC7E,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC;IAE/C,OAAO;QACL,QAAQ,EAAE,WAAW,CAAC,OAAO,EAAE;QAC/B,UAAU;QACV,IAAI;QACJ,KAAK,EAAE,WAAW;QAClB,MAAM;QACN,OAAO;QACP,gBAAgB;QAChB,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC;QAChE,IAAI,EAAE,WAAW,CAAC,kBAAkB,EAAE;QACtC,UAAU,EAAE,qBAAqB,CAAC,WAAW,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E;;;;;;;GAOG;AACH,SAAgB,uBAAuB;IACrC,OAAO,IAAI,kBAAO,CAAC;QACjB,eAAe,EAAE;YACf,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,IAAI;YACZ,gEAAgE;YAChE,qCAAqC;YACrC,MAAM,EAAE,KAAK;YACb,YAAY,EAAE,IAAI;YAClB,gEAAgE;YAChE,6CAA6C;YAC7C,MAAM,EAAE,aAAE,CAAC,YAAY,CAAC,MAAM;YAC9B,MAAM,EAAE,aAAE,CAAC,UAAU,CAAC,MAAM;YAC5B,gBAAgB,EAAE,aAAE,CAAC,oBAAoB,CAAC,MAAM;SACjD;KACF,CAAC,CAAC;AACL,CAAC;AAhBD,0DAgBC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,qBAAqB,CACnC,UAAsB,EACtB,WAAmB;IAEnB,MAAM,oBAAoB,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAElE,MAAM,0BAA0B,GAC9B,0CAA0C,CAAC,oBAAoB,CAAC,CAAC;IAEnE,MAAM,0BAA0B,GAAgC,EAAE,CAAC;IACnE,KAAK,MAAM,yBAAyB,IAAI,0BAA0B,EAAE,CAAC;QACnE,MAAM,yBAAyB,GAC7B,6CAA6C,CAC3C,yBAAyB,EACzB,WAAW,CACZ,CAAC;QACJ,IAAI,yBAAyB,EAAE,CAAC;YAC9B,0BAA0B,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IACD,OAAO,0BAA0B,CAAC;AACpC,CAAC;AArBD,sDAqBC","sourcesContent":["import * as path from 'node:path';\nimport type {\n Identifier,\n InterfaceDeclaration,\n JSDocableNode,\n JSDocTag,\n MethodDeclaration,\n Node as TsMorphNode,\n PropertySignature,\n SourceFile,\n TypeAliasDeclaration,\n TypeElementTypes,\n TypeNode,\n TypeReferenceNode,\n} from 'ts-morph';\nimport { Node as NodeGuards, Project, ts } from 'ts-morph';\n\nimport type {\n MessengerCapabilityPacket,\n DocumentedParameter,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// NOTE: `ts-morph` is used heavily in this file to parse and extract\n// information from TypeScript files. Although this library is not well\n// documented, it wraps the TypeScript AST fairly well, and you can get a good\n// sense of the AST by using this website: <https://ts-ast-viewer.com>\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// JSDoc utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Convert `{@link X}` references inside a JSDoc comment string to plain\n * backtick code spans and escape any remaining (out-of-backtick) curly braces.\n * This way the output is safe to render in a MDX document.\n *\n * @param text - The raw text to normalize.\n * @returns The text with `@link` resolved and stray braces escaped.\n */\nfunction escapeJsDocTextForMdx(text: string): string {\n const withLinksResolved = text.replace(/\\{@link\\s+([^}]+)\\}/gu, '`$1`');\n return withLinksResolved.replace(\n /`[^`]*`|(\\{)|(\\})/gu,\n (match, open: string | undefined, close: string | undefined) => {\n if (open) {\n return '\\\\{';\n }\n if (close) {\n return '\\\\}';\n }\n return match;\n },\n );\n}\n\n/**\n * Extract the comment text of a JSDoc tag — the part that comes after the tag\n * and any identifier, e.g. \"Some param\" in \"@param foo Some param\" —\n * normalizing whitespace to a single space so we can better control how it's\n * rendered within the site.\n *\n * @param tag - The JSDoc tag.\n * @returns The flattened comment text.\n */\nfunction extractJsDocTagComment(tag: JSDocTag): string {\n return (tag.getCommentText() ?? '').replace(/\\s+/gu, ' ').trim();\n}\n\n/**\n * Strip the conventional `- ` separator from the start of a `@param` tag's\n * comment.\n *\n * @param comment - The flattened comment text from a `@param` tag.\n * @returns The comment with any leading `- ` (or `– `, `— `) removed.\n */\nfunction stripJsDocParamSeparator(comment: string): string {\n return comment.replace(/^[-–—]\\s*/u, '');\n}\n\n/**\n * Extract JSDoc from a TypeScript AST node and decompose it into the parts we\n * need to render docs:\n *\n * - `description` — the body above the first tag, with `@deprecated` comments\n * appended as `**Deprecated:** <comment>` lines and normalized for MDX\n * (curly braces escaped, `{@link}` resolved),\n * - `params` — every `@param` tag in source order, with name and description,\n * - `returns` — the `@returns` tag's comment, or empty string if absent.\n *\n * Other tags (`@see`, `@throws`, `@template`, `@example`) are dropped.\n *\n * @param node - The AST node to extract JSDoc from (e.g. a type or a method).\n * @returns The decomposed JSDoc; empty strings/arrays when the node has no JSDoc.\n */\nfunction extractJsDoc(node: JSDocableNode): {\n description: string;\n params: DocumentedParameter[];\n returns: string;\n} {\n const jsDocs = node.getJsDocs();\n if (jsDocs.length === 0) {\n return { description: '', params: [], returns: '' };\n }\n\n const jsDoc = jsDocs[0];\n const descriptionBody = jsDoc.getDescription().trim();\n\n const deprecatedLines: string[] = [];\n const params: DocumentedParameter[] = [];\n let returns = '';\n\n for (const tag of jsDoc.getTags()) {\n const tagName = tag.getTagName();\n if (tagName === 'deprecated') {\n const comment = extractJsDocTagComment(tag);\n deprecatedLines.push(\n comment ? `**Deprecated:** ${comment}` : '**Deprecated:**',\n );\n } else if (tagName === 'param' && NodeGuards.isJSDocParameterTag(tag)) {\n const nameNode = tag.getNameNode();\n const paramName = nameNode.getText();\n if (!paramName) {\n continue;\n }\n const comment = extractJsDocTagComment(tag);\n params.push({\n name: paramName,\n description: escapeJsDocTextForMdx(stripJsDocParamSeparator(comment)),\n });\n } else if (tagName === 'returns' || tagName === 'return') {\n const comment = extractJsDocTagComment(tag);\n returns = escapeJsDocTextForMdx(comment);\n }\n }\n\n const description = escapeJsDocTextForMdx(\n [descriptionBody, ...deprecatedLines]\n .filter((line) => line.length > 0)\n .join('\\n'),\n );\n\n return { description, params, returns };\n}\n\n/**\n * Check whether a node has an `@deprecated` JSDoc tag.\n *\n * @param node - The AST node to check.\n * @returns True if the node has an `@deprecated` tag.\n */\nfunction hasDeprecatedJsDocTag(node: JSDocableNode): boolean {\n return node\n .getJsDocs()\n .flatMap((jsDoc) => jsDoc.getTags())\n .some((tag) => tag.getTagName() === 'deprecated');\n}\n\n// ---------------------------------------------------------------------------\n// Type-resolution helpers (powered by ts-morph's type checker)\n// ---------------------------------------------------------------------------\n\n/**\n * Locates the type that represents a method on a class (e.g.\n * `Class['method']`), which itself comes from a messenger action handler.\n *\n * @param typeNode - The node that represents the indexed access.\n * @returns The found method declaration, or null.\n */\nfunction findClassMethodDeclaration(\n typeNode: TypeNode | undefined,\n): MethodDeclaration | null {\n // Fundamental check: if we don't have `Class['method']`, we can't do anything.\n if (!NodeGuards.isIndexedAccessTypeNode(typeNode)) {\n return null;\n }\n\n // The type that represents the class being accessed.\n // EXAMPLE:\n // FooController['someMethod']\n // ^^^^^^^^^^^^^\n const objectType = typeNode.getObjectTypeNode();\n // The type that represents the property being accessed.\n // EXAMPLE:\n // FooController['someMethod']\n // ^^^^^^^^^^^^\n const indexType = typeNode.getIndexTypeNode();\n\n // To access a property on a type, it must be a type we can access properties of.\n if (\n !NodeGuards.isTypeReference(objectType) ||\n !NodeGuards.isLiteralTypeNode(indexType)\n ) {\n return null;\n }\n const indexLiteral = indexType.getLiteral();\n // Names of methods must be static strings; they cannot be template strings.\n if (\n !NodeGuards.isStringLiteral(indexLiteral) &&\n !NodeGuards.isNoSubstitutionTemplateLiteral(indexLiteral)\n ) {\n return null;\n }\n const methodName = indexLiteral.getLiteralValue();\n\n // Reject qualified-name type names, as we need a plain identifier to\n // resolve the symbol.\n // EXAMPLE:\n // import * as somePackage from '....js';\n // somePackage.FooController['someMethod']\n // ^^^^^^^^^^^^^^^^^^^^^^^^^\n const classNameNode = objectType.getTypeName();\n if (!NodeGuards.isIdentifier(classNameNode)) {\n return null;\n }\n\n // Since we know we have a type reference, we can assume that we have a symbol.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const localSymbol = classNameNode.getSymbol()!;\n // If we have a type imported from another file, ensure that when we access\n // the declaration, it's the type declaration in the other file, not the\n // import declaration in this file.\n // EXAMPLE:\n // import { FooController } from '@metamask/foo-controller';\n // FooController['someMethod']\n // ^^^^^^^^^^^^^\n const symbol = localSymbol.getAliasedSymbol() ?? localSymbol;\n\n for (const declaration of symbol.getDeclarations()) {\n // We must have a class to treat the property on the object type as a\n // method.\n if (NodeGuards.isClassDeclaration(declaration)) {\n const method = declaration.getMethod(methodName);\n if (method) {\n return method;\n }\n }\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Method info\n// ---------------------------------------------------------------------------\n\n/**\n * Build the textual signature of a class method — its parameter list and\n * return type expressed as a TypeScript function type — so a handler that\n * references `Class['method']` can be rendered as `(arg: T) => R` instead of\n * the bare indexed-access syntax.\n *\n * @param method - The method declaration.\n * @returns The signature, e.g. `(id: number) => Promise<string>`.\n */\nfunction buildMethodSignature(method: MethodDeclaration): string {\n const signatureParams = method\n .getParameters()\n .map((param) => {\n const rest = param.isRestParameter() ? '...' : '';\n const paramName = param.getNameNode().getText();\n const optional = param.hasQuestionToken() ? '?' : '';\n const typeNode = param.getTypeNode();\n const paramType = typeNode ? typeNode.getText() : 'unknown';\n return `${rest}${paramName}${optional}: ${paramType}`;\n })\n .join(', ');\n\n const returnTypeNode = method.getReturnTypeNode();\n const returnType = returnTypeNode ? returnTypeNode.getText() : 'void';\n // For async methods, the declared return type already includes `Promise<>`,\n // so we don't need to wrap again.\n return `(${signatureParams}) => ${returnType}`;\n}\n\n// ---------------------------------------------------------------------------\n// Messenger discovery\n// ---------------------------------------------------------------------------\n\n/**\n * A messenger capability type whose body invokes a capability-type-constructor\n * utility such as `ControllerGetStateAction<...>` or\n * `ControllerStateChangeEvent<...>`. The walker classifies the body once when\n * it captures the declaration so the extractor can read the body's type name\n * and type arguments without re-running the AST guards.\n */\ntype ConstructorMessengerCapabilityTypeDeclaration = {\n bodyShape: 'constructor';\n kind: 'action' | 'event';\n declaration: TypeAliasDeclaration;\n body: TypeReferenceNode;\n typeName: Identifier;\n};\n\n/**\n * A messenger capability type whose declaration carries the action/event\n * shape directly — either an interface or a type alias for a type literal.\n * The extractor reads `type`, `handler`, and `payload` from the members.\n */\ntype ObjectMessengerCapabilityTypeDeclaration = {\n bodyShape: 'object';\n kind: 'action' | 'event';\n declaration: TypeAliasDeclaration | InterfaceDeclaration;\n};\n\n/**\n * Represents a type declaration (type alias or interface) for an individual\n * messenger action or event, tagged with the body shape the walker\n * identified.\n */\ntype MessengerCapabilityTypeDeclaration =\n | ConstructorMessengerCapabilityTypeDeclaration\n | ObjectMessengerCapabilityTypeDeclaration;\n\n/**\n * Represents a type alias for a messenger. Only includes nodes representing the\n * `Actions` and `Events` type parameters.\n */\ntype ParsedMessengerTypeAlias = {\n actionsTypeParameter: TypeNode;\n eventsTypeParameter: TypeNode;\n};\n\n/**\n * Looks for Messenger types in the source file (that is, those that are type\n * aliases whose names end with \"Messenger\"), then extracts the `Actions` and\n * `Events` parameters from these types.\n *\n * @param sourceFile - The TypeScript source file to scan.\n * @returns A list of objects that represent messenger types.\n */\nfunction findMessengerTypeAliases(\n sourceFile: SourceFile,\n): ParsedMessengerTypeAlias[] {\n const parsedMessengerTypeAliases: ParsedMessengerTypeAlias[] = [];\n\n for (const typeAlias of sourceFile.getTypeAliases()) {\n if (!typeAlias.getName().endsWith('Messenger')) {\n continue;\n }\n\n const body = typeAlias.getTypeNode();\n // Basic check\n if (!body || !NodeGuards.isTypeReference(body)) {\n continue;\n }\n\n const typeArgs = body.getTypeArguments();\n // Messenger types always have 3 type parameters\n // (e.g. `Messenger<'FooController', Actions, Events>`)\n if (typeArgs.length < 3) {\n continue;\n }\n\n parsedMessengerTypeAliases.push({\n actionsTypeParameter: typeArgs[1],\n eventsTypeParameter: typeArgs[2],\n });\n }\n\n return parsedMessengerTypeAliases;\n}\n\n/**\n * Walks the `Actions` and `Events` type parameters of the given messenger\n * types, extracted in a previous step, to find all type declarations (i.e.,\n * statements) that represent individual messenger actions or events.\n *\n * @param parsedMessengerTypeAliases - The list of objects representing\n * messenger types, parsed in a previous step.\n * @returns The list of type aliases that represent messenger capabilities among\n * the given messenger types.\n */\nfunction findAllMessengerCapabilityTypeDeclarations(\n parsedMessengerTypeAliases: ParsedMessengerTypeAlias[],\n): MessengerCapabilityTypeDeclaration[] {\n const allCapabilityTypeDeclarations: MessengerCapabilityTypeDeclaration[] =\n [];\n let allVisitedTypeDeclarations: Set<TsMorphNode> = new Set();\n\n for (const {\n actionsTypeParameter,\n eventsTypeParameter,\n } of parsedMessengerTypeAliases) {\n for (const [typeParameter, kind] of [\n [actionsTypeParameter, 'action'],\n [eventsTypeParameter, 'event'],\n ] as const) {\n const result = recursivelyFindMessengerCapabilityTypeDeclarations(\n typeParameter,\n kind,\n allVisitedTypeDeclarations,\n );\n allCapabilityTypeDeclarations.push(...result.capabilityTypeDeclarations);\n allVisitedTypeDeclarations = result.visitedTypeDeclarations;\n }\n }\n\n return allCapabilityTypeDeclarations;\n}\n\n/**\n * Recursively walks a `ts-morph` AST node — at first the `Actions` or `Events`\n * type parameter of a messenger type, and then a node within that parameter —\n * to find all type aliases that represent individual messenger actions or\n * events, no matter how deeply the type aliases exist in the tree or in which\n * file they are located.\n *\n * @param node - The `ts-morph` AST node to walk.\n * @param kind - Whether to tag found type aliases as 'action' or 'event'.\n * @param visitedTypeDeclarations - A variable that tracks visited type aliases\n * and prevents duplicates.\n * @returns The list of extracted messenger capability type aliases as well as\n * an updated version of `visitedTypeDeclarations`.\n */\nfunction recursivelyFindMessengerCapabilityTypeDeclarations(\n node: TsMorphNode,\n kind: 'action' | 'event',\n visitedTypeDeclarations: Set<TsMorphNode>,\n): {\n capabilityTypeDeclarations: MessengerCapabilityTypeDeclaration[];\n visitedTypeDeclarations: Set<TsMorphNode>;\n} {\n const result: {\n capabilityTypeDeclarations: MessengerCapabilityTypeDeclaration[];\n visitedTypeDeclarations: Set<TsMorphNode>;\n } = {\n capabilityTypeDeclarations: [],\n visitedTypeDeclarations: new Set([...visitedTypeDeclarations]),\n };\n\n // If `node` is a union type, walk each type within it.\n // EXAMPLES:\n // type Actions = FooControllerSomeAction | FooControllerSomeOtherAction\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // type FooControllerActions = FooControllerSomeAction | FooControllerSomeOtherAction\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (NodeGuards.isUnionTypeNode(node)) {\n for (const typeNode of node.getTypeNodes()) {\n const innerResult = recursivelyFindMessengerCapabilityTypeDeclarations(\n typeNode,\n kind,\n result.visitedTypeDeclarations,\n );\n result.capabilityTypeDeclarations.push(\n ...innerResult.capabilityTypeDeclarations,\n );\n for (const typeDeclaration of innerResult.visitedTypeDeclarations) {\n result.visitedTypeDeclarations.add(typeDeclaration);\n }\n }\n return result;\n }\n\n // If `node` is not a type reference, don't walk it.\n // EXAMPLE:\n // // Bad\n // type Actions = { ... }\n // ^^^^^^^\n // // Good\n // type Actions = FooControllerSomeAction;\n // ^^^^^^^^^^^^^^^^^^^^^^^\n // // Good\n // type Actions = ControllerGetStateAction<...>;\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (!NodeGuards.isTypeReference(node)) {\n return result;\n }\n\n const nameNode = node.getTypeName();\n\n // Reject qualified-name type names, as we need a plain identifier to\n // resolve the symbol.\n // EXAMPLE:\n // import * as somePackage from '....js';\n // type Actions = somePackage.FooControllerSomeAction;\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (!NodeGuards.isIdentifier(nameNode)) {\n return result;\n }\n\n // Since we know we have a type reference, we can assume that we have a symbol.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const localSymbol = nameNode.getSymbol()!;\n // If we have a type imported from another file, ensure that when we access\n // the declaration, it's the type declaration in the other file, not the\n // import declaration in this file.\n // EXAMPLE:\n // import { FooControllerSomeAction } from '@metamask/foo-controller';\n // type Actions = FooControllerSomeAction;\n // ^^^^^^^^^^^^^^^^^^^^^^^\n const symbol = localSymbol.getAliasedSymbol() ?? localSymbol;\n\n // At this point, we have a type *reference*, but we need to find the type\n // *declaration*.\n // For instance, if we have `FooControllerSomeAction`, we need to find\n // the full `type FooControllerSomeAction = ...` statement.\n for (const declaration of symbol.getDeclarations()) {\n // Prevent duplicates\n if (result.visitedTypeDeclarations.has(declaration)) {\n continue;\n }\n result.visitedTypeDeclarations.add(declaration);\n\n // If we have a type alias, then we have to handle a few scenarios.\n // EXAMPLES:\n // type FooControllerMethodActions = ...\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // type FooControllerSomeAction = ...\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (NodeGuards.isTypeAliasDeclaration(declaration)) {\n const body = declaration.getTypeNode();\n\n // If the body is a union type or a plain type reference (not a utility\n // type), walk it.\n // EXAMPLES:\n // type FooControllerMethodActions = FooControllerSomeAction | FooControllerSomeOtherAction\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // type DelegationControllerMethodActions = DelegationControllerSignDelegationAction\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (\n body &&\n (NodeGuards.isUnionTypeNode(body) ||\n (NodeGuards.isTypeReference(body) &&\n body.getTypeArguments().length === 0))\n ) {\n const innerResult = recursivelyFindMessengerCapabilityTypeDeclarations(\n body,\n kind,\n result.visitedTypeDeclarations,\n );\n result.capabilityTypeDeclarations.push(\n ...innerResult.capabilityTypeDeclarations,\n );\n for (const typeDeclaration of innerResult.visitedTypeDeclarations) {\n result.visitedTypeDeclarations.add(typeDeclaration);\n }\n continue;\n }\n\n // A TypeReference body with type arguments is a capability-type-\n // constructor invocation (e.g. `ControllerGetStateAction<typeof name,\n // State>`). Tag it so the constructor extractor can read `body`\n // directly without re-checking its shape.\n // EXAMPLE:\n // type FooControllerSomeAction = ControllerGetStateAction<...>\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n if (body && NodeGuards.isTypeReference(body)) {\n // Reject qualified-name constructor type names, as we need a plain\n // identifier to match the constructor by name.\n // EXAMPLE:\n // // Bad\n // import * as somePackage from '....js';\n // type FooControllerSomeAction = somePackage.ControllerGetStateAction<...>\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n const constructorTypeName = body.getTypeName();\n if (NodeGuards.isIdentifier(constructorTypeName)) {\n result.capabilityTypeDeclarations.push({\n bodyShape: 'constructor',\n kind,\n declaration,\n body,\n typeName: constructorTypeName,\n });\n }\n continue;\n }\n\n // Anything else (a type literal, intersection, conditional, …) gets\n // tagged for the literal extractor, which knows how to read members\n // off a type literal and rejects exotic shapes.\n // EXAMPLE:\n // type FooControllerSomeAction = { ... }\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n result.capabilityTypeDeclarations.push({\n bodyShape: 'object',\n kind,\n declaration,\n });\n }\n\n // Interfaces always carry their members directly — tag for the literal\n // extractor.\n // EXAMPLE:\n // interface FooControllerSomeAction { ... }\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n else if (NodeGuards.isInterfaceDeclaration(declaration)) {\n result.capabilityTypeDeclarations.push({\n bodyShape: 'object',\n kind,\n declaration,\n });\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Per-statement extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Given the declaration of a messenger capability type, extract information\n * about it (action/event type string, handler/payload arguments and return\n * type, etc.)\n *\n * @param capabilityTypeDeclaration - The statement that declared the type for a\n * messenger action or event, extracted in a previous step.\n * @param projectPath - Project root, used for computing relative source paths.\n * @returns Information that may be extracted from the messenger capability type\n * (may be `null` if the type is ineligible for extraction).\n */\nfunction extractFromMessengerCapabilityTypeDeclaration(\n capabilityTypeDeclaration: MessengerCapabilityTypeDeclaration,\n projectPath: string,\n): MessengerCapabilityPacket | null {\n if (capabilityTypeDeclaration.bodyShape === 'constructor') {\n return tryToExtractFromCapabilityTypeConstructor(\n capabilityTypeDeclaration,\n projectPath,\n );\n }\n return tryToExtractFromMessengerCapabilityTypeLiteral(\n capabilityTypeDeclaration,\n projectPath,\n );\n}\n\n/**\n * If a messenger capability type is a type alias or interface and its body is\n * a literal object type — i.e. one of:\n *\n * - `{ type: '...'; handler: ... }` (action)\n * - `{ type: '...'; payload: ... }` (event)\n *\n * then this function extracts information about the type (action/event type\n * string, handler/payload arguments and return type, etc.)\n *\n * @param capabilityTypeDeclaration - The statement that declared the type for a\n * messenger action or event, extracted in a previous step.\n * @param projectPath - Project root, used for computing relative source paths.\n * @returns The extracted capability packet, or null if the shape of the type\n * doesn't match.\n */\nfunction tryToExtractFromMessengerCapabilityTypeLiteral(\n capabilityTypeDeclaration: ObjectMessengerCapabilityTypeDeclaration,\n projectPath: string,\n): MessengerCapabilityPacket | null {\n const { declaration, kind } = capabilityTypeDeclaration;\n\n // We must have a object type alias or an interface, and the body must not be empty.\n // EXAMPLES:\n // // Good\n // type FooControllerSomeAction = {\n // type: 'FooController:getState';\n // handler: FooController['getState'];\n // }\n // // Good\n // interface FooControllerSomeAction {\n // type: 'FooController:getState';\n // handler: FooController['getState'];\n // }\n // // Bad\n // type FooControllerSomeAction = {};\n // // Bad\n // interface FooControllerSomeAction {};\n let members: TypeElementTypes[] | undefined;\n if (NodeGuards.isTypeAliasDeclaration(declaration)) {\n const body = declaration.getTypeNode();\n if (body && NodeGuards.isTypeLiteral(body)) {\n members = body.getMembers();\n }\n } else {\n members = declaration.getMembers();\n }\n if (!members) {\n return null;\n }\n\n const propertySignatures = members.filter(\n NodeGuards.isPropertySignature.bind(NodeGuards),\n );\n\n // Actions and events must have a `type`, and it must be a string.\n const typeString = getMessengerCapabilityTypeString(propertySignatures);\n if (!typeString) {\n return null;\n }\n\n // Actions must have a `handler`, and events must have a `payload`.\n const handlerOrPayloadProperty = findProperty(\n propertySignatures,\n kind === 'action' ? 'handler' : 'payload',\n );\n if (!handlerOrPayloadProperty) {\n return null;\n }\n\n const handlerOrPayloadPropertyTypeNode =\n // We can assume the property has a type; otherwise it wouldn't compile.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n handlerOrPayloadProperty.getTypeNode()!;\n let handlerOrPayloadSignature = handlerOrPayloadPropertyTypeNode\n .getText()\n .trim();\n\n const { description: jsDoc, params, returns } = extractJsDoc(declaration);\n\n // For actions that represent methods (e.g. `Class['method']`), walk the\n // handler type to find the underlying handler signature\n // (e.g. `(id: number) => Promise<string>`).\n if (kind === 'action') {\n const methodDeclaration = findClassMethodDeclaration(\n handlerOrPayloadPropertyTypeNode,\n );\n if (methodDeclaration) {\n handlerOrPayloadSignature = buildMethodSignature(methodDeclaration);\n }\n }\n\n const sourceFile = declaration.getSourceFile();\n return {\n typeName: declaration.getName(),\n typeString,\n kind,\n jsDoc,\n params,\n returns,\n handlerOrPayload: handlerOrPayloadSignature,\n sourceFile: path.relative(projectPath, sourceFile.getFilePath()),\n line: declaration.getStartLineNumber(),\n deprecated: hasDeprecatedJsDocTag(declaration),\n };\n}\n\n/**\n * Searches the property signatures of a messenger capability type alias or\n * interface to find the value of the `type` property, and then resolves it to a\n * string (assuming it is already a string or a resolvable template literal).\n *\n * @param capabilityTypeProperties - The property signatures of the messenger\n * capability type.\n * @returns The extracted capability type string, or null if `type` cannot be\n * found in the members or it is an unexpected node.\n */\nfunction getMessengerCapabilityTypeString(\n capabilityTypeProperties: PropertySignature[],\n): string | null {\n const typeProperty = findProperty(capabilityTypeProperties, 'type');\n if (!typeProperty) {\n return null;\n }\n\n // A `type` property without an explicit type wouldn't compile.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const typeNode = typeProperty.getTypeNode()!;\n\n // Ask the type checker to resolve the value of `type`. We're looking for\n // `type` to be either a string literal or template literal.\n //\n // EXAMPLES:\n // type FooControllerSomeAction = {\n // type: 'FooController:someAction';\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^\n // }\n // type FooControllerSomeAction = {\n // type: `FooController:someAction`;\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^\n // }\n // type FooControllerSomeAction = {\n // type: `${typeof CONTROLLER_NAME}:someAction`;\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // }\n const resolvedType = typeNode.getType();\n if (resolvedType.isStringLiteral()) {\n // Type assertion: There aren't any type guards we can use to narrow this\n // type further.\n const literalValue = resolvedType.getLiteralValueOrThrow() as string;\n\n // Messenger action/event types need to be namespaced.\n if (literalValue.includes(':')) {\n return literalValue;\n }\n }\n\n return null;\n}\n\n/**\n * Finds a specific property in a list of property signatures for an object\n * type.\n *\n * @param propertySignatures - The property signatures of the messenger\n * capability type.\n * @param name - The property name to find.\n * @returns The property signature, or null.\n */\nfunction findProperty(\n propertySignatures: PropertySignature[],\n name: string,\n): PropertySignature | null {\n for (const property of propertySignatures) {\n const propertyNameNode = property.getNameNode();\n if (\n !NodeGuards.isIdentifier(propertyNameNode) ||\n propertyNameNode.getText() !== name\n ) {\n continue;\n }\n\n return property;\n }\n\n return null;\n}\n\n/**\n * If a messenger capability type is a type alias for either the\n * `ControllerGetStateAction` or `ControllerStateChangeEvent` type constructors,\n * then this function extracts information about the type (action/event type\n * string, handler/payload arguments and return type, etc.)\n *\n * @param capabilityTypeDeclaration - The statement that declared the type for a\n * messenger action or event, extracted in a previous step.\n * @param projectPath - Project root, used for computing relative source paths.\n * @returns The extracted capability packet, or null if the shape of the type\n * doesn't match.\n */\nfunction tryToExtractFromCapabilityTypeConstructor(\n capabilityTypeDeclaration: ConstructorMessengerCapabilityTypeDeclaration,\n projectPath: string,\n): MessengerCapabilityPacket | null {\n const { declaration, kind, body, typeName } = capabilityTypeDeclaration;\n\n // The name of the utility type should be either `ControllerGetStateAction`\n // (for actions) or `ControllerStateChangeEvent` (for events).\n // EXAMPLES:\n // type FooControllerSomeAction = ControllerGetStateAction<...>\n // type FooControllerSomeEvent = ControllerStateChangeEvent<...>\n const expectedConstructor =\n kind === 'action'\n ? 'ControllerGetStateAction'\n : 'ControllerStateChangeEvent';\n if (typeName.getText() !== expectedConstructor) {\n return null;\n }\n\n // The utility type should take two parameters.\n // EXAMPLES:\n // type FooControllerSomeAction = ControllerGetStateAction<..., ...>\n // type FooControllerSomeEvent = ControllerStateChangeEvent<..., ...>\n const typeArgs = body.getTypeArguments();\n if (typeArgs.length < 2) {\n return null;\n }\n\n const namespaceArgType = typeArgs[0].getType();\n // The first parameter should be a string literal.\n // EXAMPLES:\n // type FooControllerSomeAction = ControllerGetStateAction<'FooController', ...>\n // type FooControllerSomeAction = ControllerGetStateAction<typeof CONTROLLER_NAME, ...>\n if (!namespaceArgType.isStringLiteral()) {\n return null;\n }\n // Type assertion: There aren't any type guards we can use to narrow this type\n // further.\n const namespace = namespaceArgType.getLiteralValueOrThrow() as string;\n\n const typeString =\n kind === 'action' ? `${namespace}:getState` : `${namespace}:stateChange`;\n const stateArgText = typeArgs[1].getText();\n const handlerOrPayload =\n kind === 'action' ? `() => ${stateArgText}` : `[${stateArgText}, Patch[]]`;\n const { description, params, returns } = extractJsDoc(declaration);\n const sourceFile = declaration.getSourceFile();\n\n return {\n typeName: declaration.getName(),\n typeString,\n kind,\n jsDoc: description,\n params,\n returns,\n handlerOrPayload,\n sourceFile: path.relative(projectPath, sourceFile.getFilePath()),\n line: declaration.getStartLineNumber(),\n deprecated: hasDeprecatedJsDocTag(declaration),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public entry points\n// ---------------------------------------------------------------------------\n\n/**\n * Create a ts-morph Project configured for messenger-docs extraction. The\n * caller should add every source file that may be referenced (directly or\n * transitively) before calling {@link extractFromSourceFile}, so the type\n * checker can resolve cross-file references.\n *\n * @returns A new ts-morph Project.\n */\nexport function createExtractionProject(): Project {\n return new Project({\n compilerOptions: {\n allowJs: false,\n noEmit: true,\n // Match the project's permissive defaults — we just need symbol\n // resolution, not full typechecking.\n strict: false,\n skipLibCheck: true,\n // Explicit module options so cross-file symbol resolution works\n // regardless of the host process's tsconfig.\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.NodeJs,\n },\n });\n}\n\n/**\n * Extract information (action/event type string, handler/payload arguments and\n * return type, etc.) about every messenger action or event type which is\n * reachable through all of a source file's `*Messenger` type declarations.\n *\n * The caller is responsible for ensuring `sourceFile` (plus any files it\n * imports from) belongs to a `ts-morph` Project so cross-file symbol resolution\n * works.\n *\n * @param sourceFile - The TypeScript source file to extract from.\n * @param projectPath - Project root, used for computing relative source paths.\n * @returns The extracted information about actions and events.\n */\nexport function extractFromSourceFile(\n sourceFile: SourceFile,\n projectPath: string,\n): MessengerCapabilityPacket[] {\n const messengerTypeAliases = findMessengerTypeAliases(sourceFile);\n\n const capabilityTypeDeclarations =\n findAllMessengerCapabilityTypeDeclarations(messengerTypeAliases);\n\n const messengerCapabilityPackets: MessengerCapabilityPacket[] = [];\n for (const capabilityTypeDeclaration of capabilityTypeDeclarations) {\n const messengerCapabilityPacket =\n extractFromMessengerCapabilityTypeDeclaration(\n capabilityTypeDeclaration,\n projectPath,\n );\n if (messengerCapabilityPacket) {\n messengerCapabilityPackets.push(messengerCapabilityPacket);\n }\n }\n return messengerCapabilityPackets;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extraction.d.cts","sourceRoot":"","sources":["../src/extraction.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAQV,UAAU,EAKX,iBAAiB;AAClB,OAAO,EAAsB,OAAO,EAAM,iBAAiB;AAE3D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"extraction.d.cts","sourceRoot":"","sources":["../src/extraction.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAQV,UAAU,EAKX,iBAAiB;AAClB,OAAO,EAAsB,OAAO,EAAM,iBAAiB;AAE3D,OAAO,KAAK,EACV,yBAAyB,EAE1B,oBAAmB;AA42BpB;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAgBjD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,MAAM,GAClB,yBAAyB,EAAE,CAkB7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extraction.d.mts","sourceRoot":"","sources":["../src/extraction.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAQV,UAAU,EAKX,iBAAiB;AAClB,OAAO,EAAsB,OAAO,EAAM,iBAAiB;AAE3D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"extraction.d.mts","sourceRoot":"","sources":["../src/extraction.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAQV,UAAU,EAKX,iBAAiB;AAClB,OAAO,EAAsB,OAAO,EAAM,iBAAiB;AAE3D,OAAO,KAAK,EACV,yBAAyB,EAE1B,oBAAmB;AA42BpB;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAgBjD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,MAAM,GAClB,yBAAyB,EAAE,CAkB7B"}
|
package/dist/extraction.mjs
CHANGED
|
@@ -156,7 +156,7 @@ function findClassMethodDeclaration(typeNode) {
|
|
|
156
156
|
// Reject qualified-name type names, as we need a plain identifier to
|
|
157
157
|
// resolve the symbol.
|
|
158
158
|
// EXAMPLE:
|
|
159
|
-
// import * as somePackage from '
|
|
159
|
+
// import * as somePackage from '....js';
|
|
160
160
|
// somePackage.FooController['someMethod']
|
|
161
161
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
162
162
|
const classNameNode = objectType.getTypeName();
|
|
@@ -326,7 +326,7 @@ function recursivelyFindMessengerCapabilityTypeDeclarations(node, kind, visitedT
|
|
|
326
326
|
// Reject qualified-name type names, as we need a plain identifier to
|
|
327
327
|
// resolve the symbol.
|
|
328
328
|
// EXAMPLE:
|
|
329
|
-
// import * as somePackage from '
|
|
329
|
+
// import * as somePackage from '....js';
|
|
330
330
|
// type Actions = somePackage.FooControllerSomeAction;
|
|
331
331
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
332
332
|
if (!NodeGuards.isIdentifier(nameNode)) {
|
|
@@ -391,7 +391,7 @@ function recursivelyFindMessengerCapabilityTypeDeclarations(node, kind, visitedT
|
|
|
391
391
|
// identifier to match the constructor by name.
|
|
392
392
|
// EXAMPLE:
|
|
393
393
|
// // Bad
|
|
394
|
-
// import * as somePackage from '
|
|
394
|
+
// import * as somePackage from '....js';
|
|
395
395
|
// type FooControllerSomeAction = somePackage.ControllerGetStateAction<...>
|
|
396
396
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
397
397
|
const constructorTypeName = body.getTypeName();
|