@metamask-previews/platform-api-docs 0.0.0-preview-3e34650c2 → 0.0.0-preview-b13d916
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +34 -1
- package/dist/cli.cjs +105 -18
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +105 -18
- package/dist/cli.mjs.map +1 -1
- package/dist/extraction.cjs +70 -44
- package/dist/extraction.cjs.map +1 -1
- package/dist/extraction.d.cts +57 -1
- package/dist/extraction.d.cts.map +1 -1
- package/dist/extraction.d.mts +57 -1
- package/dist/extraction.d.mts.map +1 -1
- package/dist/extraction.mjs +68 -44
- package/dist/extraction.mjs.map +1 -1
- package/dist/generate.cjs +74 -6
- package/dist/generate.cjs.map +1 -1
- package/dist/generate.d.cts +34 -10
- package/dist/generate.d.cts.map +1 -1
- package/dist/generate.d.mts +34 -10
- package/dist/generate.d.mts.map +1 -1
- package/dist/generate.mjs +74 -6
- package/dist/generate.mjs.map +1 -1
- package/dist/root-messenger-discovery.cjs +380 -0
- package/dist/root-messenger-discovery.cjs.map +1 -0
- package/dist/root-messenger-discovery.d.cts +61 -0
- package/dist/root-messenger-discovery.d.cts.map +1 -0
- package/dist/root-messenger-discovery.d.mts +61 -0
- package/dist/root-messenger-discovery.d.mts.map +1 -0
- package/dist/root-messenger-discovery.mjs +352 -0
- package/dist/root-messenger-discovery.mjs.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
12
|
-
- Initial release of the platform-api-docs package ([#8012](https://github.com/MetaMask/core/pull/8012))
|
|
12
|
+
- Initial release of the platform-api-docs package ([#8012](https://github.com/MetaMask/core/pull/8012), [#9913](https://github.com/MetaMask/core/pull/9913))
|
|
13
13
|
|
|
14
14
|
[Unreleased]: https://github.com/MetaMask/core/
|
package/README.md
CHANGED
|
@@ -35,12 +35,45 @@ Options:
|
|
|
35
35
|
--build Generate docs and build static site
|
|
36
36
|
--serve Generate docs, build, and serve static site
|
|
37
37
|
--dev Generate docs and start dev server with hot reload
|
|
38
|
-
--
|
|
38
|
+
--strategy <name> How to find actions and events: "scan" (default) or
|
|
39
|
+
"root-messenger" (see below)
|
|
40
|
+
--scan-dir <dir> Extra source directory to scan (repeatable; --strategy scan only)
|
|
41
|
+
--root-actions <ref> Type aliasing the union of every action, as "<file>#<TypeName>"
|
|
42
|
+
(required with --strategy root-messenger)
|
|
43
|
+
--root-events <ref> Type aliasing the union of every event, as "<file>#<TypeName>"
|
|
44
|
+
(required with --strategy root-messenger)
|
|
39
45
|
--output <dir> Output directory (default: <project-path>/.platform-api-docs)
|
|
40
46
|
--project-label <label> Short label identifying the project (e.g. "Core", "Extension")
|
|
41
47
|
--help Show this help message
|
|
42
48
|
```
|
|
43
49
|
|
|
50
|
+
## Strategies
|
|
51
|
+
|
|
52
|
+
Which strategy to use depends on whether the project has a single messenger carrying every action and event.
|
|
53
|
+
|
|
54
|
+
### `scan` (default)
|
|
55
|
+
|
|
56
|
+
Parses every TypeScript source and declaration file it can find — the scan directories, `packages/*/src`, and `node_modules/@metamask/*/dist` — and reads every `*Messenger` type alias it encounters.
|
|
57
|
+
|
|
58
|
+
Use this when no single messenger aggregates every capability, as in a monorepo of independently published packages.
|
|
59
|
+
|
|
60
|
+
### `root-messenger`
|
|
61
|
+
|
|
62
|
+
Resolves the two types the project declares for its root messenger capabilities — the collection of every action and the collection of every event — and lets the TypeScript type checker walk them. Only the files named on the command line are opened.
|
|
63
|
+
|
|
64
|
+
Use this when the project has one root messenger carrying every action and event, as a client application built on these packages does. It is substantially faster than `scan`, because it reads what the project already declares instead of re-deriving it, and it documents only what is reachable through that messenger.
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
platform-api-docs \
|
|
68
|
+
--strategy root-messenger \
|
|
69
|
+
--root-actions 'src/messenger.ts#RootActions' \
|
|
70
|
+
--root-events 'src/messenger.ts#RootEvents'
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Each reference names a type alias, written by hand or computed — the type checker resolves either.
|
|
74
|
+
|
|
75
|
+
The docs contain exactly what the named types contain, so those types should be the ones carrying every capability rather than a narrowed subset. Capability types that can't be documented are reported rather than dropped silently: those declared inline in the capability collection type (with no name or JSDoc to document), and those whose shape can't be read (most often a `type` property that isn't a namespaced string literal).
|
|
76
|
+
|
|
44
77
|
## Contributing
|
|
45
78
|
|
|
46
79
|
This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/core#readme).
|
package/dist/cli.cjs
CHANGED
|
@@ -33,6 +33,7 @@ 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
35
|
const generate_js_1 = require("./generate.cjs");
|
|
36
|
+
const root_messenger_discovery_js_1 = require("./root-messenger-discovery.cjs");
|
|
36
37
|
/**
|
|
37
38
|
* Locate the Docusaurus binary in this package's `node_modules/.bin`. Using
|
|
38
39
|
* `npm-which` lets the lookup track wherever the installed Docusaurus puts
|
|
@@ -129,10 +130,45 @@ async function resolveCommitSha(projectPath) {
|
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
132
|
/**
|
|
132
|
-
*
|
|
133
|
+
* Reject flag combinations that don't make sense, so a mistaken invocation
|
|
134
|
+
* fails instead of silently producing docs built the wrong way.
|
|
135
|
+
*
|
|
136
|
+
* Flags belonging to the strategy that wasn't selected are errors rather than
|
|
137
|
+
* ignored. Used as a yargs `.check`, so failures print alongside usage.
|
|
138
|
+
*
|
|
139
|
+
* @param argv - The parsed arguments.
|
|
140
|
+
* @param argv.strategy - The selected discovery strategy.
|
|
141
|
+
* @param argv.rootActions - The parsed root actions type reference.
|
|
142
|
+
* @param argv.rootEvents - The parsed root events type reference.
|
|
143
|
+
* @param argv.scanDir - The additional directories to scan.
|
|
144
|
+
* @returns True when the combination is valid.
|
|
133
145
|
*/
|
|
134
|
-
|
|
135
|
-
|
|
146
|
+
function checkStrategyArgs({ strategy, rootActions, rootEvents, scanDir = [], }) {
|
|
147
|
+
if (strategy !== 'root-messenger') {
|
|
148
|
+
if (rootActions !== undefined || rootEvents !== undefined) {
|
|
149
|
+
throw new Error('--root-actions and --root-events only apply to --strategy root-messenger.');
|
|
150
|
+
}
|
|
151
|
+
return { strategy: 'scan', scanDir };
|
|
152
|
+
}
|
|
153
|
+
if (rootActions === undefined || rootEvents === undefined) {
|
|
154
|
+
throw new Error('--strategy root-messenger requires both --root-actions and --root-events, ' +
|
|
155
|
+
'each written as "<file>#<TypeName>".');
|
|
156
|
+
}
|
|
157
|
+
if (scanDir.length > 0) {
|
|
158
|
+
throw new Error('--scan-dir only applies to --strategy scan; --strategy root-messenger reads ' +
|
|
159
|
+
'only the files named by --root-actions and --root-events.');
|
|
160
|
+
}
|
|
161
|
+
return { strategy, rootActions, rootEvents };
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Parse and validate CLI arguments.
|
|
165
|
+
*
|
|
166
|
+
* @param argumentsForParsing - Arguments to parse, excluding the Node and
|
|
167
|
+
* script paths.
|
|
168
|
+
* @returns Parsed arguments, discriminated by discovery strategy.
|
|
169
|
+
*/
|
|
170
|
+
async function parseArguments(argumentsForParsing = process.argv.slice(2)) {
|
|
171
|
+
const argv = await (0, yargs_1.default)(argumentsForParsing)
|
|
136
172
|
.command('$0 [project-path]', 'Produces documentation for the platform API, the set of actions and events available in clients through the message bus.', (yargsInstance) => {
|
|
137
173
|
yargsInstance.positional('project-path', {
|
|
138
174
|
type: 'string',
|
|
@@ -155,9 +191,25 @@ async function main() {
|
|
|
155
191
|
description: 'Generate platform API docs and serve a development-only site',
|
|
156
192
|
default: false,
|
|
157
193
|
})
|
|
158
|
-
.option('
|
|
194
|
+
.option('strategy', {
|
|
195
|
+
type: 'string',
|
|
196
|
+
description: 'How to find messenger actions and events. "scan" parses every source and declaration file looking for messenger types. "root-messenger" instead resolves the two types the project declares for its root messenger',
|
|
197
|
+
default: 'scan',
|
|
198
|
+
})
|
|
199
|
+
.choices('strategy', ['scan', 'root-messenger'])
|
|
200
|
+
.option('root-actions', {
|
|
159
201
|
type: 'string',
|
|
160
|
-
|
|
202
|
+
coerce: root_messenger_discovery_js_1.parseRootCapabilitiesTypeReference,
|
|
203
|
+
description: 'Type aliasing the union of every action on the root messenger, written as "<file>#<TypeName>" (required with --strategy root-messenger)',
|
|
204
|
+
})
|
|
205
|
+
.option('root-events', {
|
|
206
|
+
type: 'string',
|
|
207
|
+
coerce: root_messenger_discovery_js_1.parseRootCapabilitiesTypeReference,
|
|
208
|
+
description: 'Type aliasing the union of every event on the root messenger, written as "<file>#<TypeName>" (required with --strategy root-messenger)',
|
|
209
|
+
})
|
|
210
|
+
.option('scan-dir', {
|
|
211
|
+
type: 'array',
|
|
212
|
+
string: true,
|
|
161
213
|
description: 'Additional directories within the project to scan for messenger actions and events (note: may be specified multiple times)',
|
|
162
214
|
default: [],
|
|
163
215
|
})
|
|
@@ -177,25 +229,60 @@ async function main() {
|
|
|
177
229
|
type: 'string',
|
|
178
230
|
description: 'Path prefix the built site will be served under, e.g. /core/platform-api/',
|
|
179
231
|
})
|
|
180
|
-
.help()
|
|
181
|
-
|
|
182
|
-
const
|
|
232
|
+
.help()
|
|
233
|
+
.parse();
|
|
234
|
+
const strategyArguments = checkStrategyArgs(argv);
|
|
235
|
+
const projectPath = argv['project-path'];
|
|
236
|
+
if (typeof projectPath !== 'string') {
|
|
237
|
+
throw new Error('Expected --project-path to be a string.');
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
build: argv.build,
|
|
241
|
+
serve: argv.serve,
|
|
242
|
+
dev: argv.dev,
|
|
243
|
+
'project-path': projectPath,
|
|
244
|
+
output: argv.output,
|
|
245
|
+
'project-label': argv['project-label'],
|
|
246
|
+
'site-url': argv['site-url'],
|
|
247
|
+
'site-base-url': argv['site-base-url'],
|
|
248
|
+
...strategyArguments,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Main CLI entry point.
|
|
253
|
+
*/
|
|
254
|
+
async function main() {
|
|
255
|
+
const argv = await parseArguments();
|
|
256
|
+
const resolvedProjectPath = path.resolve(argv['project-path']);
|
|
183
257
|
const resolvedOutputDir = path.resolve(argv.output ?? path.join(resolvedProjectPath, '.platform-api-docs'));
|
|
184
|
-
const
|
|
185
|
-
const projectLabel = typeof argv['project-label'] === 'string' &&
|
|
186
|
-
argv['project-label'].length > 0
|
|
258
|
+
const projectLabel = argv['project-label'] && argv['project-label'].length > 0
|
|
187
259
|
? argv['project-label']
|
|
188
260
|
: null;
|
|
189
261
|
const commitSha = await resolveCommitSha(resolvedProjectPath);
|
|
190
262
|
const repoUrl = await (0, generate_js_1.resolveRepoUrl)(resolvedProjectPath);
|
|
191
263
|
// Step 1: Generate docs
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
264
|
+
if (argv.strategy === 'root-messenger') {
|
|
265
|
+
await (0, generate_js_1.generate)({
|
|
266
|
+
projectPath: resolvedProjectPath,
|
|
267
|
+
outputDir: resolvedOutputDir,
|
|
268
|
+
projectLabel,
|
|
269
|
+
commitSha,
|
|
270
|
+
strategy: 'root-messenger',
|
|
271
|
+
rootActions: argv.rootActions,
|
|
272
|
+
rootEvents: argv.rootEvents,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
const scanDirs = ['src', ...argv.scanDir].filter((dir, index, dirs) => dirs.indexOf(dir) === index);
|
|
277
|
+
await (0, generate_js_1.generate)({
|
|
278
|
+
projectPath: resolvedProjectPath,
|
|
279
|
+
outputDir: resolvedOutputDir,
|
|
280
|
+
projectLabel,
|
|
281
|
+
commitSha,
|
|
282
|
+
strategy: 'scan',
|
|
283
|
+
scanDirs,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
199
286
|
// Step 2: If --build, --serve, or --dev, set up and run Docusaurus
|
|
200
287
|
if (argv.build || argv.serve || argv.dev) {
|
|
201
288
|
await setupSite(resolvedOutputDir);
|
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.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"]}
|
|
1
|
+
{"version":3,"file":"cli.cjs","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,2DAA0B;AAC1B,qDAAuC;AACvC,gDAAkC;AAClC,0DAAiC;AACjC,kDAA0B;AAE1B,gDAAyD;AAEzD,gFAAmF;AAoDnF;;;;;;GAMG;AACH,SAAS,iBAAiB;IACxB,OAAO,IAAA,mBAAQ,EAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,aAAa,CAC1B,OAAe,EACf,GAAW,EACX,WAAmC,EAAE;IAErC,MAAM,IAAA,eAAK,EAAC,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,CAAC,SAAS,EAAE,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,IAAA,eAAK,EAAC,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;;;;;;;;;;;;;GAaG;AACH,SAAS,iBAAiB,CAAC,EACzB,QAAQ,EACR,WAAW,EACX,UAAU,EACV,OAAO,GAAG,EAAE,GAMb;IACC,IAAI,QAAQ,KAAK,gBAAgB,EAAE,CAAC;QAClC,IAAI,WAAW,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC1D,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IACvC,CAAC;IAED,IAAI,WAAW,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,4EAA4E;YAC1E,sCAAsC,CACzC,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,8EAA8E;YAC5E,2DAA2D,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AAC/C,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,cAAc,CAC3B,sBAAgC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAErD,MAAM,IAAI,GAAG,MAAM,IAAA,eAAK,EAAC,mBAAmB,CAAC;SAC1C,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,WAAW,EACT,oNAAoN;QACtN,OAAO,EAAE,MAAM;KAChB,CAAC;SACD,OAAO,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAU,CAAC;SACxD,MAAM,CAAC,cAAc,EAAE;QACtB,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,gEAAkC;QAC1C,WAAW,EACT,yIAAyI;KAC5I,CAAC;SACD,MAAM,CAAC,aAAa,EAAE;QACrB,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,gEAAkC;QAC1C,WAAW,EACT,wIAAwI;KAC3I,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,IAAI,EAAE,OAAO;QACb,MAAM,EAAE,IAAI;QACZ,WAAW,EACT,4HAA4H;QAC9H,OAAO,EAAE,EAAE;KACZ,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;SACN,KAAK,EAAE,CAAC;IAEX,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAElD,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;IACzC,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,cAAc,EAAE,WAAW;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC;QACtC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC;QAC5B,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC;QACtC,GAAG,iBAAiB;KACrB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;IAEpC,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IAC/D,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CACpC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,CACpE,CAAC;IACF,MAAM,YAAY,GAChB,IAAI,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC;QACvD,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,IAAA,4BAAc,EAAC,mBAAmB,CAAC,CAAC;IAE1D,wBAAwB;IACxB,IAAI,IAAI,CAAC,QAAQ,KAAK,gBAAgB,EAAE,CAAC;QACvC,MAAM,IAAA,sBAAQ,EAAC;YACb,WAAW,EAAE,mBAAmB;YAChC,SAAS,EAAE,iBAAiB;YAC5B,YAAY;YACZ,SAAS;YACT,QAAQ,EAAE,gBAAgB;YAC1B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAC9C,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAClD,CAAC;QAEF,MAAM,IAAA,sBAAQ,EAAC;YACb,WAAW,EAAE,mBAAmB;YAChC,SAAS,EAAE,iBAAiB;YAC5B,YAAY;YACZ,SAAS;YACT,QAAQ,EAAE,MAAM;YAChB,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;IAED,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';\nimport type { RootCapabilitiesTypeReference } from './root-messenger-discovery.js';\nimport { parseRootCapabilitiesTypeReference } from './root-messenger-discovery.js';\n\n/**\n * Arguments shared by both discovery strategies.\n */\ntype CommonArguments = {\n /** Whether to build the generated site. */\n build: boolean;\n /** Whether to serve the production build. */\n serve: boolean;\n /** Whether to serve the development site. */\n dev: boolean;\n /** Path to the project being documented. */\n 'project-path': string;\n /** Directory where generated documentation is written. */\n output?: string;\n /** Label displayed in the generated documentation. */\n 'project-label'?: string;\n /** URL where the generated site is served. */\n 'site-url'?: string;\n /** Base path where the generated site is served. */\n 'site-base-url'?: string;\n};\n\n/**\n * Arguments for the strategy that scans configured source directories.\n */\ntype ScanStrategyArguments = {\n /** The selected strategy. */\n strategy: 'scan';\n /** Directories, relative to the project root, to scan. */\n scanDir: string[];\n};\n\n/**\n * Arguments for the strategy that resolves a root messenger's type unions.\n */\ntype RootMessengerStrategyArguments = {\n /** The selected strategy. */\n strategy: 'root-messenger';\n /** The root messenger actions type reference. */\n rootActions: RootCapabilitiesTypeReference;\n /** The root messenger events type reference. */\n rootEvents: RootCapabilitiesTypeReference;\n};\n\n/**\n * Parsed CLI arguments, discriminated by the selected discovery strategy.\n */\ntype ParsedArguments = CommonArguments &\n (ScanStrategyArguments | RootMessengerStrategyArguments);\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 * Reject flag combinations that don't make sense, so a mistaken invocation\n * fails instead of silently producing docs built the wrong way.\n *\n * Flags belonging to the strategy that wasn't selected are errors rather than\n * ignored. Used as a yargs `.check`, so failures print alongside usage.\n *\n * @param argv - The parsed arguments.\n * @param argv.strategy - The selected discovery strategy.\n * @param argv.rootActions - The parsed root actions type reference.\n * @param argv.rootEvents - The parsed root events type reference.\n * @param argv.scanDir - The additional directories to scan.\n * @returns True when the combination is valid.\n */\nfunction checkStrategyArgs({\n strategy,\n rootActions,\n rootEvents,\n scanDir = [],\n}: {\n strategy?: 'root-messenger' | 'scan';\n rootActions?: RootCapabilitiesTypeReference;\n rootEvents?: RootCapabilitiesTypeReference;\n scanDir?: string[];\n}): ScanStrategyArguments | RootMessengerStrategyArguments {\n if (strategy !== 'root-messenger') {\n if (rootActions !== undefined || rootEvents !== undefined) {\n throw new Error(\n '--root-actions and --root-events only apply to --strategy root-messenger.',\n );\n }\n return { strategy: 'scan', scanDir };\n }\n\n if (rootActions === undefined || rootEvents === undefined) {\n throw new Error(\n '--strategy root-messenger requires both --root-actions and --root-events, ' +\n 'each written as \"<file>#<TypeName>\".',\n );\n }\n if (scanDir.length > 0) {\n throw new Error(\n '--scan-dir only applies to --strategy scan; --strategy root-messenger reads ' +\n 'only the files named by --root-actions and --root-events.',\n );\n }\n\n return { strategy, rootActions, rootEvents };\n}\n\n/**\n * Parse and validate CLI arguments.\n *\n * @param argumentsForParsing - Arguments to parse, excluding the Node and\n * script paths.\n * @returns Parsed arguments, discriminated by discovery strategy.\n */\nasync function parseArguments(\n argumentsForParsing: string[] = process.argv.slice(2),\n): Promise<ParsedArguments> {\n const argv = await yargs(argumentsForParsing)\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('strategy', {\n type: 'string',\n description:\n 'How to find messenger actions and events. \"scan\" parses every source and declaration file looking for messenger types. \"root-messenger\" instead resolves the two types the project declares for its root messenger',\n default: 'scan',\n })\n .choices('strategy', ['scan', 'root-messenger'] as const)\n .option('root-actions', {\n type: 'string',\n coerce: parseRootCapabilitiesTypeReference,\n description:\n 'Type aliasing the union of every action on the root messenger, written as \"<file>#<TypeName>\" (required with --strategy root-messenger)',\n })\n .option('root-events', {\n type: 'string',\n coerce: parseRootCapabilitiesTypeReference,\n description:\n 'Type aliasing the union of every event on the root messenger, written as \"<file>#<TypeName>\" (required with --strategy root-messenger)',\n })\n .option('scan-dir', {\n type: 'array',\n string: true,\n description:\n 'Additional directories within the project to scan for messenger actions and events (note: may be specified multiple times)',\n default: [],\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()\n .parse();\n\n const strategyArguments = checkStrategyArgs(argv);\n\n const projectPath = argv['project-path'];\n if (typeof projectPath !== 'string') {\n throw new Error('Expected --project-path to be a string.');\n }\n\n return {\n build: argv.build,\n serve: argv.serve,\n dev: argv.dev,\n 'project-path': projectPath,\n output: argv.output,\n 'project-label': argv['project-label'],\n 'site-url': argv['site-url'],\n 'site-base-url': argv['site-base-url'],\n ...strategyArguments,\n };\n}\n\n/**\n * Main CLI entry point.\n */\nasync function main(): Promise<void> {\n const argv = await parseArguments();\n\n const resolvedProjectPath = path.resolve(argv['project-path']);\n const resolvedOutputDir = path.resolve(\n argv.output ?? path.join(resolvedProjectPath, '.platform-api-docs'),\n );\n const projectLabel =\n argv['project-label'] && 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 if (argv.strategy === 'root-messenger') {\n await generate({\n projectPath: resolvedProjectPath,\n outputDir: resolvedOutputDir,\n projectLabel,\n commitSha,\n strategy: 'root-messenger',\n rootActions: argv.rootActions,\n rootEvents: argv.rootEvents,\n });\n } else {\n const scanDirs = ['src', ...argv.scanDir].filter(\n (dir, index, dirs) => dirs.indexOf(dir) === index,\n );\n\n await generate({\n projectPath: resolvedProjectPath,\n outputDir: resolvedOutputDir,\n projectLabel,\n commitSha,\n strategy: 'scan',\n scanDirs,\n });\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
CHANGED
|
@@ -31,6 +31,7 @@ import $npmWhich from "npm-which";
|
|
|
31
31
|
const npmWhich = $importDefault($npmWhich);
|
|
32
32
|
import yargs from "yargs";
|
|
33
33
|
import { generate, resolveRepoUrl } from "./generate.mjs";
|
|
34
|
+
import { parseRootCapabilitiesTypeReference } from "./root-messenger-discovery.mjs";
|
|
34
35
|
/**
|
|
35
36
|
* Locate the Docusaurus binary in this package's `node_modules/.bin`. Using
|
|
36
37
|
* `npm-which` lets the lookup track wherever the installed Docusaurus puts
|
|
@@ -127,10 +128,45 @@ async function resolveCommitSha(projectPath) {
|
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
130
|
/**
|
|
130
|
-
*
|
|
131
|
+
* Reject flag combinations that don't make sense, so a mistaken invocation
|
|
132
|
+
* fails instead of silently producing docs built the wrong way.
|
|
133
|
+
*
|
|
134
|
+
* Flags belonging to the strategy that wasn't selected are errors rather than
|
|
135
|
+
* ignored. Used as a yargs `.check`, so failures print alongside usage.
|
|
136
|
+
*
|
|
137
|
+
* @param argv - The parsed arguments.
|
|
138
|
+
* @param argv.strategy - The selected discovery strategy.
|
|
139
|
+
* @param argv.rootActions - The parsed root actions type reference.
|
|
140
|
+
* @param argv.rootEvents - The parsed root events type reference.
|
|
141
|
+
* @param argv.scanDir - The additional directories to scan.
|
|
142
|
+
* @returns True when the combination is valid.
|
|
131
143
|
*/
|
|
132
|
-
|
|
133
|
-
|
|
144
|
+
function checkStrategyArgs({ strategy, rootActions, rootEvents, scanDir = [], }) {
|
|
145
|
+
if (strategy !== 'root-messenger') {
|
|
146
|
+
if (rootActions !== undefined || rootEvents !== undefined) {
|
|
147
|
+
throw new Error('--root-actions and --root-events only apply to --strategy root-messenger.');
|
|
148
|
+
}
|
|
149
|
+
return { strategy: 'scan', scanDir };
|
|
150
|
+
}
|
|
151
|
+
if (rootActions === undefined || rootEvents === undefined) {
|
|
152
|
+
throw new Error('--strategy root-messenger requires both --root-actions and --root-events, ' +
|
|
153
|
+
'each written as "<file>#<TypeName>".');
|
|
154
|
+
}
|
|
155
|
+
if (scanDir.length > 0) {
|
|
156
|
+
throw new Error('--scan-dir only applies to --strategy scan; --strategy root-messenger reads ' +
|
|
157
|
+
'only the files named by --root-actions and --root-events.');
|
|
158
|
+
}
|
|
159
|
+
return { strategy, rootActions, rootEvents };
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Parse and validate CLI arguments.
|
|
163
|
+
*
|
|
164
|
+
* @param argumentsForParsing - Arguments to parse, excluding the Node and
|
|
165
|
+
* script paths.
|
|
166
|
+
* @returns Parsed arguments, discriminated by discovery strategy.
|
|
167
|
+
*/
|
|
168
|
+
async function parseArguments(argumentsForParsing = process.argv.slice(2)) {
|
|
169
|
+
const argv = await yargs(argumentsForParsing)
|
|
134
170
|
.command('$0 [project-path]', 'Produces documentation for the platform API, the set of actions and events available in clients through the message bus.', (yargsInstance) => {
|
|
135
171
|
yargsInstance.positional('project-path', {
|
|
136
172
|
type: 'string',
|
|
@@ -153,9 +189,25 @@ async function main() {
|
|
|
153
189
|
description: 'Generate platform API docs and serve a development-only site',
|
|
154
190
|
default: false,
|
|
155
191
|
})
|
|
156
|
-
.option('
|
|
192
|
+
.option('strategy', {
|
|
193
|
+
type: 'string',
|
|
194
|
+
description: 'How to find messenger actions and events. "scan" parses every source and declaration file looking for messenger types. "root-messenger" instead resolves the two types the project declares for its root messenger',
|
|
195
|
+
default: 'scan',
|
|
196
|
+
})
|
|
197
|
+
.choices('strategy', ['scan', 'root-messenger'])
|
|
198
|
+
.option('root-actions', {
|
|
157
199
|
type: 'string',
|
|
158
|
-
|
|
200
|
+
coerce: parseRootCapabilitiesTypeReference,
|
|
201
|
+
description: 'Type aliasing the union of every action on the root messenger, written as "<file>#<TypeName>" (required with --strategy root-messenger)',
|
|
202
|
+
})
|
|
203
|
+
.option('root-events', {
|
|
204
|
+
type: 'string',
|
|
205
|
+
coerce: parseRootCapabilitiesTypeReference,
|
|
206
|
+
description: 'Type aliasing the union of every event on the root messenger, written as "<file>#<TypeName>" (required with --strategy root-messenger)',
|
|
207
|
+
})
|
|
208
|
+
.option('scan-dir', {
|
|
209
|
+
type: 'array',
|
|
210
|
+
string: true,
|
|
159
211
|
description: 'Additional directories within the project to scan for messenger actions and events (note: may be specified multiple times)',
|
|
160
212
|
default: [],
|
|
161
213
|
})
|
|
@@ -175,25 +227,60 @@ async function main() {
|
|
|
175
227
|
type: 'string',
|
|
176
228
|
description: 'Path prefix the built site will be served under, e.g. /core/platform-api/',
|
|
177
229
|
})
|
|
178
|
-
.help()
|
|
179
|
-
|
|
180
|
-
const
|
|
230
|
+
.help()
|
|
231
|
+
.parse();
|
|
232
|
+
const strategyArguments = checkStrategyArgs(argv);
|
|
233
|
+
const projectPath = argv['project-path'];
|
|
234
|
+
if (typeof projectPath !== 'string') {
|
|
235
|
+
throw new Error('Expected --project-path to be a string.');
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
build: argv.build,
|
|
239
|
+
serve: argv.serve,
|
|
240
|
+
dev: argv.dev,
|
|
241
|
+
'project-path': projectPath,
|
|
242
|
+
output: argv.output,
|
|
243
|
+
'project-label': argv['project-label'],
|
|
244
|
+
'site-url': argv['site-url'],
|
|
245
|
+
'site-base-url': argv['site-base-url'],
|
|
246
|
+
...strategyArguments,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Main CLI entry point.
|
|
251
|
+
*/
|
|
252
|
+
async function main() {
|
|
253
|
+
const argv = await parseArguments();
|
|
254
|
+
const resolvedProjectPath = path.resolve(argv['project-path']);
|
|
181
255
|
const resolvedOutputDir = path.resolve(argv.output ?? path.join(resolvedProjectPath, '.platform-api-docs'));
|
|
182
|
-
const
|
|
183
|
-
const projectLabel = typeof argv['project-label'] === 'string' &&
|
|
184
|
-
argv['project-label'].length > 0
|
|
256
|
+
const projectLabel = argv['project-label'] && argv['project-label'].length > 0
|
|
185
257
|
? argv['project-label']
|
|
186
258
|
: null;
|
|
187
259
|
const commitSha = await resolveCommitSha(resolvedProjectPath);
|
|
188
260
|
const repoUrl = await resolveRepoUrl(resolvedProjectPath);
|
|
189
261
|
// Step 1: Generate docs
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
262
|
+
if (argv.strategy === 'root-messenger') {
|
|
263
|
+
await generate({
|
|
264
|
+
projectPath: resolvedProjectPath,
|
|
265
|
+
outputDir: resolvedOutputDir,
|
|
266
|
+
projectLabel,
|
|
267
|
+
commitSha,
|
|
268
|
+
strategy: 'root-messenger',
|
|
269
|
+
rootActions: argv.rootActions,
|
|
270
|
+
rootEvents: argv.rootEvents,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
const scanDirs = ['src', ...argv.scanDir].filter((dir, index, dirs) => dirs.indexOf(dir) === index);
|
|
275
|
+
await generate({
|
|
276
|
+
projectPath: resolvedProjectPath,
|
|
277
|
+
outputDir: resolvedOutputDir,
|
|
278
|
+
projectLabel,
|
|
279
|
+
commitSha,
|
|
280
|
+
strategy: 'scan',
|
|
281
|
+
scanDirs,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
197
284
|
// Step 2: If --build, --serve, or --dev, set up and run Docusaurus
|
|
198
285
|
if (argv.build || argv.serve || argv.dev) {
|
|
199
286
|
await setupSite(resolvedOutputDir);
|
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.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"]}
|
|
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.js';\nimport type { RootCapabilitiesTypeReference } from './root-messenger-discovery.js';\nimport { parseRootCapabilitiesTypeReference } from './root-messenger-discovery.js';\n\n/**\n * Arguments shared by both discovery strategies.\n */\ntype CommonArguments = {\n /** Whether to build the generated site. */\n build: boolean;\n /** Whether to serve the production build. */\n serve: boolean;\n /** Whether to serve the development site. */\n dev: boolean;\n /** Path to the project being documented. */\n 'project-path': string;\n /** Directory where generated documentation is written. */\n output?: string;\n /** Label displayed in the generated documentation. */\n 'project-label'?: string;\n /** URL where the generated site is served. */\n 'site-url'?: string;\n /** Base path where the generated site is served. */\n 'site-base-url'?: string;\n};\n\n/**\n * Arguments for the strategy that scans configured source directories.\n */\ntype ScanStrategyArguments = {\n /** The selected strategy. */\n strategy: 'scan';\n /** Directories, relative to the project root, to scan. */\n scanDir: string[];\n};\n\n/**\n * Arguments for the strategy that resolves a root messenger's type unions.\n */\ntype RootMessengerStrategyArguments = {\n /** The selected strategy. */\n strategy: 'root-messenger';\n /** The root messenger actions type reference. */\n rootActions: RootCapabilitiesTypeReference;\n /** The root messenger events type reference. */\n rootEvents: RootCapabilitiesTypeReference;\n};\n\n/**\n * Parsed CLI arguments, discriminated by the selected discovery strategy.\n */\ntype ParsedArguments = CommonArguments &\n (ScanStrategyArguments | RootMessengerStrategyArguments);\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 * Reject flag combinations that don't make sense, so a mistaken invocation\n * fails instead of silently producing docs built the wrong way.\n *\n * Flags belonging to the strategy that wasn't selected are errors rather than\n * ignored. Used as a yargs `.check`, so failures print alongside usage.\n *\n * @param argv - The parsed arguments.\n * @param argv.strategy - The selected discovery strategy.\n * @param argv.rootActions - The parsed root actions type reference.\n * @param argv.rootEvents - The parsed root events type reference.\n * @param argv.scanDir - The additional directories to scan.\n * @returns True when the combination is valid.\n */\nfunction checkStrategyArgs({\n strategy,\n rootActions,\n rootEvents,\n scanDir = [],\n}: {\n strategy?: 'root-messenger' | 'scan';\n rootActions?: RootCapabilitiesTypeReference;\n rootEvents?: RootCapabilitiesTypeReference;\n scanDir?: string[];\n}): ScanStrategyArguments | RootMessengerStrategyArguments {\n if (strategy !== 'root-messenger') {\n if (rootActions !== undefined || rootEvents !== undefined) {\n throw new Error(\n '--root-actions and --root-events only apply to --strategy root-messenger.',\n );\n }\n return { strategy: 'scan', scanDir };\n }\n\n if (rootActions === undefined || rootEvents === undefined) {\n throw new Error(\n '--strategy root-messenger requires both --root-actions and --root-events, ' +\n 'each written as \"<file>#<TypeName>\".',\n );\n }\n if (scanDir.length > 0) {\n throw new Error(\n '--scan-dir only applies to --strategy scan; --strategy root-messenger reads ' +\n 'only the files named by --root-actions and --root-events.',\n );\n }\n\n return { strategy, rootActions, rootEvents };\n}\n\n/**\n * Parse and validate CLI arguments.\n *\n * @param argumentsForParsing - Arguments to parse, excluding the Node and\n * script paths.\n * @returns Parsed arguments, discriminated by discovery strategy.\n */\nasync function parseArguments(\n argumentsForParsing: string[] = process.argv.slice(2),\n): Promise<ParsedArguments> {\n const argv = await yargs(argumentsForParsing)\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('strategy', {\n type: 'string',\n description:\n 'How to find messenger actions and events. \"scan\" parses every source and declaration file looking for messenger types. \"root-messenger\" instead resolves the two types the project declares for its root messenger',\n default: 'scan',\n })\n .choices('strategy', ['scan', 'root-messenger'] as const)\n .option('root-actions', {\n type: 'string',\n coerce: parseRootCapabilitiesTypeReference,\n description:\n 'Type aliasing the union of every action on the root messenger, written as \"<file>#<TypeName>\" (required with --strategy root-messenger)',\n })\n .option('root-events', {\n type: 'string',\n coerce: parseRootCapabilitiesTypeReference,\n description:\n 'Type aliasing the union of every event on the root messenger, written as \"<file>#<TypeName>\" (required with --strategy root-messenger)',\n })\n .option('scan-dir', {\n type: 'array',\n string: true,\n description:\n 'Additional directories within the project to scan for messenger actions and events (note: may be specified multiple times)',\n default: [],\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()\n .parse();\n\n const strategyArguments = checkStrategyArgs(argv);\n\n const projectPath = argv['project-path'];\n if (typeof projectPath !== 'string') {\n throw new Error('Expected --project-path to be a string.');\n }\n\n return {\n build: argv.build,\n serve: argv.serve,\n dev: argv.dev,\n 'project-path': projectPath,\n output: argv.output,\n 'project-label': argv['project-label'],\n 'site-url': argv['site-url'],\n 'site-base-url': argv['site-base-url'],\n ...strategyArguments,\n };\n}\n\n/**\n * Main CLI entry point.\n */\nasync function main(): Promise<void> {\n const argv = await parseArguments();\n\n const resolvedProjectPath = path.resolve(argv['project-path']);\n const resolvedOutputDir = path.resolve(\n argv.output ?? path.join(resolvedProjectPath, '.platform-api-docs'),\n );\n const projectLabel =\n argv['project-label'] && 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 if (argv.strategy === 'root-messenger') {\n await generate({\n projectPath: resolvedProjectPath,\n outputDir: resolvedOutputDir,\n projectLabel,\n commitSha,\n strategy: 'root-messenger',\n rootActions: argv.rootActions,\n rootEvents: argv.rootEvents,\n });\n } else {\n const scanDirs = ['src', ...argv.scanDir].filter(\n (dir, index, dirs) => dirs.indexOf(dir) === index,\n );\n\n await generate({\n projectPath: resolvedProjectPath,\n outputDir: resolvedOutputDir,\n projectLabel,\n commitSha,\n strategy: 'scan',\n scanDirs,\n });\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"]}
|