@metamask-previews/platform-api-docs 0.1.0-preview-abca9bcea → 0.2.0-preview-0a30e47

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.
Files changed (74) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/{cli.mjs → cli.js} +10 -40
  5. package/dist/cli.js.map +1 -0
  6. package/dist/{extraction.d.cts → extraction.d.ts} +3 -3
  7. package/dist/extraction.d.ts.map +1 -0
  8. package/dist/{extraction.mjs → extraction.js} +3 -3
  9. package/dist/extraction.js.map +1 -0
  10. package/dist/{generate.d.cts → generate.d.ts} +2 -2
  11. package/dist/generate.d.ts.map +1 -0
  12. package/dist/{generate.mjs → generate.js} +10 -10
  13. package/dist/generate.js.map +1 -0
  14. package/dist/{markdown.d.cts → markdown.d.ts} +2 -2
  15. package/dist/markdown.d.ts.map +1 -0
  16. package/dist/{markdown.mjs → markdown.js} +1 -1
  17. package/dist/markdown.js.map +1 -0
  18. package/dist/{root-messenger-discovery.d.cts → root-messenger-discovery.d.ts} +2 -2
  19. package/dist/root-messenger-discovery.d.ts.map +1 -0
  20. package/dist/{root-messenger-discovery.mjs → root-messenger-discovery.js} +5 -5
  21. package/dist/root-messenger-discovery.js.map +1 -0
  22. package/dist/{ts-project.d.cts → ts-project.d.ts} +2 -2
  23. package/dist/ts-project.d.ts.map +1 -0
  24. package/dist/{ts-project.mjs → ts-project.js} +2 -2
  25. package/dist/ts-project.js.map +1 -0
  26. package/dist/{types.d.cts → types.d.ts} +1 -1
  27. package/dist/types.d.ts.map +1 -0
  28. package/dist/types.js +2 -0
  29. package/dist/types.js.map +1 -0
  30. package/package.json +12 -8
  31. package/dist/cli.cjs +0 -328
  32. package/dist/cli.cjs.map +0 -1
  33. package/dist/cli.d.cts +0 -3
  34. package/dist/cli.d.cts.map +0 -1
  35. package/dist/cli.d.mts +0 -3
  36. package/dist/cli.d.mts.map +0 -1
  37. package/dist/cli.mjs.map +0 -1
  38. package/dist/extraction.cjs +0 -754
  39. package/dist/extraction.cjs.map +0 -1
  40. package/dist/extraction.d.cts.map +0 -1
  41. package/dist/extraction.d.mts +0 -73
  42. package/dist/extraction.d.mts.map +0 -1
  43. package/dist/extraction.mjs.map +0 -1
  44. package/dist/generate.cjs +0 -505
  45. package/dist/generate.cjs.map +0 -1
  46. package/dist/generate.d.cts.map +0 -1
  47. package/dist/generate.d.mts +0 -70
  48. package/dist/generate.d.mts.map +0 -1
  49. package/dist/generate.mjs.map +0 -1
  50. package/dist/markdown.cjs +0 -239
  51. package/dist/markdown.cjs.map +0 -1
  52. package/dist/markdown.d.cts.map +0 -1
  53. package/dist/markdown.d.mts +0 -52
  54. package/dist/markdown.d.mts.map +0 -1
  55. package/dist/markdown.mjs.map +0 -1
  56. package/dist/root-messenger-discovery.cjs +0 -359
  57. package/dist/root-messenger-discovery.cjs.map +0 -1
  58. package/dist/root-messenger-discovery.d.cts.map +0 -1
  59. package/dist/root-messenger-discovery.d.mts +0 -61
  60. package/dist/root-messenger-discovery.d.mts.map +0 -1
  61. package/dist/root-messenger-discovery.mjs.map +0 -1
  62. package/dist/ts-project.cjs +0 -33
  63. package/dist/ts-project.cjs.map +0 -1
  64. package/dist/ts-project.d.cts.map +0 -1
  65. package/dist/ts-project.d.mts +0 -12
  66. package/dist/ts-project.d.mts.map +0 -1
  67. package/dist/ts-project.mjs.map +0 -1
  68. package/dist/types.cjs +0 -3
  69. package/dist/types.cjs.map +0 -1
  70. package/dist/types.d.cts.map +0 -1
  71. package/dist/types.d.mts +0 -47
  72. package/dist/types.d.mts.map +0 -1
  73. package/dist/types.mjs +0 -2
  74. package/dist/types.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-messenger-discovery.js","sourceRoot":"","sources":["../src/root-messenger-discovery.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'node:path';\nimport type {\n InterfaceDeclaration,\n Project as TsMorphProject,\n Type,\n TypeAliasDeclaration,\n} from 'ts-morph';\nimport { Node as NodeGuards } from 'ts-morph';\n\nimport {\n classifyMessengerCapabilityTypeDeclaration,\n extractFromMessengerCapabilityTypeDeclaration,\n} from './extraction.js';\nimport { createProject } from './ts-project.js';\nimport type { MessengerCapabilityPacket } from './types.js';\n\n// ---------------------------------------------------------------------------\n// The `root-messenger` strategy: resolve the types a project declares for its\n// collection of root messenger actions and events and let TypeScript walk them.\n// Each capability type found is handed to the shared extractor in\n// `extraction.ts`, so the output matches what the `scan` strategy produces.\n// ---------------------------------------------------------------------------\n\n/**\n * A reference to a type declared in a file, written as `<file>#<TypeName>`.\n *\n * The `root-messenger` strategy takes two of these on the command line — one\n * naming a collection of messenger action types, one naming a collection of\n * messenger event types — and uses them to locate the type declarations to\n * enumerate.\n */\nexport type RootCapabilitiesTypeReference = {\n /** Path to the declaring file, relative to the project root. */\n filePath: string;\n /** Name of the type alias within that file. */\n typeName: string;\n};\n\n/**\n * Labels for capability types that were found but couldn't be documented,\n * grouped by why. Labels rather than counts, so warnings can name what to fix.\n */\ntype SkippedCapabilities = {\n /**\n * Capabilities declared inline in the capability collection type, so there is\n * no name or JSDoc to document.\n */\n unnamedCapabilities: string[];\n /*\n * Capabilities that are named, but of a shape the extractor rejects.\n */\n unextractableCapabilities: string[];\n};\n\n/**\n * Split a `<file>#<TypeName>` reference into its parts, on the last `#` so\n * that paths containing a `#` still work.\n *\n * @param reference - The raw reference, e.g. `src/messenger.ts#RootActions`.\n * @returns The parsed reference.\n * @throws If the reference has no `#`, or either side of it is empty.\n */\nexport function parseRootCapabilitiesTypeReference(\n reference: string,\n): RootCapabilitiesTypeReference {\n const separatorIndex = reference.lastIndexOf('#');\n if (separatorIndex === -1) {\n throw new Error(\n `Expected a reference of the form \"<file>#<TypeName>\", got \"${reference}\".`,\n );\n }\n\n const filePath = reference.slice(0, separatorIndex);\n const typeName = reference.slice(separatorIndex + 1);\n if (filePath.length === 0 || typeName.length === 0) {\n throw new Error(\n `Expected a reference of the form \"<file>#<TypeName>\", got \"${reference}\".`,\n );\n }\n\n return { filePath, typeName };\n}\n\n/**\n * A `<file>#<TypeName>` string, passed from the command line, refers to an\n * messenger actions or events collection type. This function reads the file and\n * looks up the matching type alias.\n *\n * @param args - The arguments to this function.\n * @param args.project - The ts-morph project to load the file into.\n * @param args.projectPath - Absolute path to the project root.\n * @param args.reference - The root capability collection type reference to\n * resolve.\n * @param args.commandLineOptionName - The command-line option the reference\n * came from, used in errors.\n * @returns The type alias declaration the reference names.\n * @throws If the file can't be read or declares no such type alias.\n */\nfunction resolveMessengerCapabilitiesTypeReference({\n project,\n projectPath,\n reference,\n commandLineOptionName,\n}: {\n project: TsMorphProject;\n projectPath: string;\n reference: RootCapabilitiesTypeReference;\n commandLineOptionName: string;\n}): TypeAliasDeclaration {\n const absolutePath = path.resolve(projectPath, reference.filePath);\n\n let sourceFile;\n try {\n // `addSourceFileAtPath` is idempotent: the two references often name the\n // same file, and the second call returns the source file added by the first.\n sourceFile = project.addSourceFileAtPath(absolutePath);\n } catch {\n throw new Error(\n `Could not read ${absolutePath}, which was named by ${commandLineOptionName}.`,\n );\n }\n\n // EXAMPLES:\n // type RootMessengerActions = ...\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // type RootMessengerEvents = ...\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n const declaration = sourceFile.getTypeAlias(reference.typeName);\n if (!declaration) {\n throw new Error(\n `No type alias named \"${reference.typeName}\" in ${reference.filePath}, which was named by ${commandLineOptionName}.`,\n );\n }\n\n return declaration;\n}\n\n/**\n * Given the type of a messenger capability (e.g.\n * `NetworkControllerAddNetworkAction`) as obtained from a collection of\n * capability types (e.g. `RootMessengerActions` or `RootMessengerEvents`),\n * locate the type declaration for that capability type.\n *\n * This is not as simple as following the type to its declaration, because both\n * a collection of capability types and the capability type itself can have\n * multiple representations. So there are three strategies for finding the type:\n *\n * 1. If the capability type was declared as a type alias (e.g. `type\n * FooControllerSomeAction = { ... }`), then we need to use the symbol to\n * find the declaration.\n * 2. If the capability type was declared as an interface (e.g. `interface\n * FooControllerSomeAction { ... }`), we don't need to do this; interfaces\n * are their own declaration.\n * 3. If the capability *collection* type is not a union but merely a type alias\n * (e.g. `type RootMessengerActions = NetworkControllerAddNetworkAction`)\n * then we follow the right-hand side of the type alias.\n *\n * When none of these find a type declaration, the capability is anonymous\n * (e.g. an inline object type with no name to document) and `undefined` is\n * returned, so the caller can record it as skipped rather than document it.\n *\n * @param capabilityType - The type of the individual capability to find the\n * declaration for.\n * @param capabilityCollectionTypeDeclaration - The declaration of the whole\n * collection the capability came from (e.g. `type RootMessengerActions = ...`).\n * @param isLoneConstituent - Whether the capability collection only includes\n * one capability type.\n * @returns The type alias or interface declaration for the capability, or\n * `undefined` when the capability is anonymous.\n */\nfunction findMessengerCapabilityTypeDeclaration(\n capabilityType: Type,\n capabilityCollectionTypeDeclaration: TypeAliasDeclaration,\n isLoneConstituent: boolean,\n): TypeAliasDeclaration | InterfaceDeclaration | undefined {\n // If we have a type alias, look for its symbol.\n //\n // EXAMPLE:\n // type FooControllerSomeAction = { type: '...'; handler: () => void };\n // ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // the alias symbol names the plain symbol points at this anonymous\n // this declaration object\n //\n // But skip an alias that resolves back to the capability collection itself,\n // which is what TypeScript reports for a lone generic instantiation.\n //\n // EXAMPLE:\n // Here the alias symbol of the sole member is `Actions`, i.e.\n // `capabilityCollectionTypeDeclaration`, which is not the capability we\n // want to document:\n //\n // type Actions = Foo<Bar>;\n // ^^^^^^^ capabilityCollectionTypeDeclaration\n const typeAliasDeclarations = (\n capabilityType.getAliasSymbol()?.getDeclarations() ?? []\n ).filter((node) => node !== capabilityCollectionTypeDeclaration);\n\n // An interface has no alias symbol, being its own declaration, so fall back\n // to the plain symbol to reach it.\n // EXAMPLE:\n // interface FooControllerSomeAction { type: '...'; handler: () => void }\n // ^^^^^^^^^^^^^^^^^^^^^^^ reached via the plain symbol\n const typeDeclarations =\n typeAliasDeclarations.length > 0\n ? typeAliasDeclarations\n : (capabilityType.getSymbol()?.getDeclarations() ?? []);\n\n // Of the declarations behind whichever symbol we used, pick the type alias or\n // interface.\n // EXAMPLES:\n // type FooControllerSomeAction = { ... }\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // interface FooControllerSomeAction { ... }\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n const foundTypeDeclaration = typeDeclarations.find(\n (node): node is TypeAliasDeclaration | InterfaceDeclaration =>\n NodeGuards.isTypeAliasDeclaration(node) ||\n NodeGuards.isInterfaceDeclaration(node),\n );\n if (foundTypeDeclaration) {\n return foundTypeDeclaration;\n }\n\n // If the capability collection type has only one constituent, we can safely\n // assume it's a type alias. If, in this case, it's also generic, the\n // declaration we want is the one its type node references, so follow it.\n //\n // EXAMPLE:\n // type Actions = Foo<Bar>;\n // ^^^ follow this reference to its declaration\n //\n if (isLoneConstituent) {\n return resolveGenericCapabilityCollectionTypeDeclaration(\n capabilityCollectionTypeDeclaration,\n );\n }\n\n // If, after all of this, the capability collection is a union with an\n // anonymous constituent, we ignore it:\n //\n // EXAMPLE:\n // type Actions = FooControllerSomeAction | { type: '...'; handler: ... };\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n return undefined;\n}\n\n/**\n * Given a messenger capability collection with one constituent which is a\n * generic capability type, follow that type to find its declaration.\n *\n * A type that is aliased to a generic type is a special case we need to handle,\n * because it won't have a direct alias symbol; we need to pick out the type\n * that acts as the \"box\" in the generic (e.g. the `Foo` in `type Actions =\n * Foo<Bar>`).\n *\n * @param capabilityCollectionTypeDeclaration - The declaration for a\n * collection of capability types (e.g. `type RootMessengerActions = ...`).\n * @returns The resolved sole capability type.\n */\nfunction resolveGenericCapabilityCollectionTypeDeclaration(\n capabilityCollectionTypeDeclaration: TypeAliasDeclaration,\n): TypeAliasDeclaration | InterfaceDeclaration | undefined {\n // The root alias must reference another type by name for there to be a\n // declaration to follow.\n // EXAMPLE:\n // type Actions = Foo<Bar>;\n // ^^^^^^^^\n const typeNode = capabilityCollectionTypeDeclaration.getTypeNode();\n if (!typeNode || !NodeGuards.isTypeReference(typeNode)) {\n return undefined;\n }\n\n // Resolve the referenced name (e.g. `Foo` in `Foo<Bar>`) to its symbol.\n const localSymbol = typeNode.getTypeName().getSymbol();\n // If the type is imported from another file, ensure that when we access the\n // declaration, it's the type declaration in the other file, not the import\n // declaration in this file.\n // EXAMPLE:\n // import { Foo } from '@metamask/foo';\n // type Actions = Foo<Bar>;\n // ^^^\n const symbol = localSymbol?.getAliasedSymbol() ?? localSymbol;\n\n // Follow the reference to the type alias or interface it names.\n // EXAMPLES:\n // type Foo<T> = { ... }\n // ^^^^^^^^^^^^^^^^^^^^\n // interface Foo<T> { ... }\n // ^^^^^^^^^^^^^^^^^^^^^^^\n return symbol\n ?.getDeclarations()\n .find(\n (node): node is TypeAliasDeclaration | InterfaceDeclaration =>\n NodeGuards.isTypeAliasDeclaration(node) ||\n NodeGuards.isInterfaceDeclaration(node),\n );\n}\n\n/**\n * Render a short, single-line label for an anonymous type.\n *\n * @param type - The type to describe.\n * @param enclosingNode - Node to render the type relative to, so an aliased\n * type reads as its name rather than `import(\"<absolute path>\").Name`.\n * @returns The label.\n */\nfunction summarizeType(\n type: Type,\n enclosingNode: TypeAliasDeclaration,\n): string {\n const text = type.getText(enclosingNode).replace(/\\s+/gu, ' ');\n return text.length > 80 ? `${text.slice(0, 77)}...` : text;\n}\n\n/**\n * Walk a messenger capability collection type (e.g. `RootMessengerActions` or\n * `RootMessengerEvents`) to gather all of the consitutent capability types\n * (e.g. `NetworkControllerAddNetworkAction`), then package them so that they\n * can be displayed within the documentation.\n *\n * Messenger capabilities that cannot be extracted for some reason are captured\n * separately.\n *\n * @param args - The arguments to this function.\n * @param args.projectPath - Absolute path to the project root.\n * @param args.capabilityKind - Whether these are actions or events.\n * @param args.capabilityCollectionTypeReference - A reference to a messenger\n * capability collection type within the project, in `<file>#<TypeName>` format.\n * @param args.capabilityCollectionTypeDeclaration - The type declaration\n * representing a collection of messenger capabilities.\n * @param args.commandLineOptionName - The command-line option the reference\n * came from, used in errors.\n * @returns The extracted capabilities along with skipped capabilities.\n * @throws If the capability collection type resolved to `any` or `unknown`.\n */\nfunction extractFromMessengerCapabilitiesUnionTypeDeclaration({\n projectPath,\n capabilityKind,\n capabilityCollectionTypeReference,\n capabilityCollectionTypeDeclaration,\n commandLineOptionName,\n}: {\n projectPath: string;\n capabilityKind: 'action' | 'event';\n capabilityCollectionTypeReference: RootCapabilitiesTypeReference;\n capabilityCollectionTypeDeclaration: TypeAliasDeclaration;\n commandLineOptionName: string;\n}): {\n capabilityPackets: MessengerCapabilityPacket[];\n skippedCapabilities: SkippedCapabilities;\n} {\n const capabilityCollectionType = capabilityCollectionTypeDeclaration\n .getTypeNodeOrThrow()\n .getType();\n\n // If one or more of the constituent capabilities in the collection is `any`\n // or `unknown` — e.g. its import failed — then the type of the whole\n // collection will also be `any` or `unknown`. Fail instead of emitting a\n // catalog that looks complete but silently isn't.\n if (\n capabilityCollectionType.isAny() ||\n capabilityCollectionType.isUnknown()\n ) {\n throw new Error(\n `${capabilityCollectionTypeReference.filePath}#${capabilityCollectionTypeReference.typeName}, named by ${commandLineOptionName}, ` +\n `resolved to \\`${capabilityCollectionType.getText()}\\`. ` +\n `It's likely that an individual action or event type is also \\`${capabilityCollectionType.getText()}\\`, ` +\n `which may be due to a failed import. ` +\n `You will need to fix this first before generating docs for this project.`,\n );\n }\n\n const skippedCapabilities: SkippedCapabilities = {\n unnamedCapabilities: [],\n unextractableCapabilities: [],\n };\n\n // A project with no capabilities of this kind aliases the union to `never`.\n if (capabilityCollectionType.isNever()) {\n return {\n capabilityPackets: [],\n skippedCapabilities,\n };\n }\n\n const individualCapabilityTypes = capabilityCollectionType.isUnion()\n ? capabilityCollectionType.getUnionTypes()\n : [capabilityCollectionType];\n const capabilityPackets: MessengerCapabilityPacket[] = [];\n\n for (const capabilityType of individualCapabilityTypes) {\n const capabilityTypeDeclaration = findMessengerCapabilityTypeDeclaration(\n capabilityType,\n capabilityCollectionTypeDeclaration,\n individualCapabilityTypes.length === 1,\n );\n if (!capabilityTypeDeclaration) {\n skippedCapabilities.unnamedCapabilities.push(\n summarizeType(capabilityType, capabilityCollectionTypeDeclaration),\n );\n continue;\n }\n\n const classifiedTypeDeclaration =\n classifyMessengerCapabilityTypeDeclaration(\n capabilityTypeDeclaration,\n capabilityKind,\n );\n const capabilityPacket =\n classifiedTypeDeclaration &&\n extractFromMessengerCapabilityTypeDeclaration(\n classifiedTypeDeclaration,\n projectPath,\n );\n if (!capabilityPacket) {\n const sourceFile = capabilityTypeDeclaration\n .getSourceFile()\n .getFilePath();\n skippedCapabilities.unextractableCapabilities.push(\n `${capabilityTypeDeclaration.getName()} (${path.relative(projectPath, sourceFile)}:${capabilityTypeDeclaration.getStartLineNumber()})`,\n );\n continue;\n }\n\n capabilityPackets.push(capabilityPacket);\n }\n\n return { capabilityPackets, skippedCapabilities };\n}\n\n/**\n * Resolves `<file>#<TypeName>` references to messenger actions and events\n * collection types within the given project (e.g. `RootMessengerActions` or\n * `RootMessengerEvents`), walks the collection to gather all of the containing\n * capability types (e.g. `NetworkControllerAddNetworkAction`), then packages\n * them so that they can be displayed within the documentation site.\n *\n * @param args - The arguments to this function.\n * @param args.projectPath -Absolute path to the project to scan.\n * @param args.rootActionsTypeReference - A reference to a messenger\n * actions collection type within the project, in `<file>#<TypeName>` format.\n * @param args.rootEventsTypeReference - A reference to a messenger events\n * collection type within the project, in `<file>#<TypeName>` format.\n * @returns The extracted capabilities plus any capabilities that were skipped.\n */\nexport function discoverFromRootMessengerCapabilitiesTypes({\n projectPath,\n rootActionsTypeReference,\n rootEventsTypeReference,\n}: {\n projectPath: string;\n rootActionsTypeReference: RootCapabilitiesTypeReference;\n rootEventsTypeReference: RootCapabilitiesTypeReference;\n}): {\n capabilityPackets: MessengerCapabilityPacket[];\n skippedCapabilities: SkippedCapabilities;\n} {\n const project = createProject();\n const capabilityPacketCollections = [\n [rootActionsTypeReference, 'action', '--root-actions'],\n [rootEventsTypeReference, 'event', '--root-events'],\n ] as const;\n const allCapabilityPackets: MessengerCapabilityPacket[] = [];\n const allSkippedCapabilities: SkippedCapabilities = {\n unnamedCapabilities: [],\n unextractableCapabilities: [],\n };\n\n for (const [\n capabilitiesCollectionTypeReference,\n kind,\n commandLineOptionName,\n ] of capabilityPacketCollections) {\n const capabilitiesCollectionTypeDeclaration =\n resolveMessengerCapabilitiesTypeReference({\n project,\n projectPath,\n reference: capabilitiesCollectionTypeReference,\n commandLineOptionName,\n });\n const { capabilityPackets, skippedCapabilities } =\n extractFromMessengerCapabilitiesUnionTypeDeclaration({\n projectPath,\n capabilityKind: kind,\n capabilityCollectionTypeReference: capabilitiesCollectionTypeReference,\n capabilityCollectionTypeDeclaration:\n capabilitiesCollectionTypeDeclaration,\n commandLineOptionName,\n });\n allCapabilityPackets.push(...capabilityPackets);\n allSkippedCapabilities.unnamedCapabilities.push(\n ...skippedCapabilities.unnamedCapabilities,\n );\n allSkippedCapabilities.unextractableCapabilities.push(\n ...skippedCapabilities.unextractableCapabilities,\n );\n }\n\n return {\n capabilityPackets: allCapabilityPackets,\n skippedCapabilities: allSkippedCapabilities,\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Project } from "ts-morph";
1
+ import { Project } from 'ts-morph';
2
2
  /**
3
3
  * Create a ts-morph Project configured for reading messenger capability types.
4
4
  *
@@ -9,4 +9,4 @@ import { Project } from "ts-morph";
9
9
  * @returns A new ts-morph Project.
10
10
  */
11
11
  export declare function createProject(): Project;
12
- //# sourceMappingURL=ts-project.d.cts.map
12
+ //# sourceMappingURL=ts-project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-project.d.ts","sourceRoot":"","sources":["../src/ts-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAM,MAAM,UAAU,CAAC;AAEvC;;;;;;;;GAQG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAiBvC"}
@@ -1,4 +1,4 @@
1
- import { Project, ts } from "ts-morph";
1
+ import { Project, ts } from 'ts-morph';
2
2
  /**
3
3
  * Create a ts-morph Project configured for reading messenger capability types.
4
4
  *
@@ -26,4 +26,4 @@ export function createProject() {
26
26
  },
27
27
  });
28
28
  }
29
- //# sourceMappingURL=ts-project.mjs.map
29
+ //# sourceMappingURL=ts-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-project.js","sourceRoot":"","sources":["../src/ts-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAEvC;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,OAAO,CAAC;QACjB,eAAe,EAAE;YACf,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,IAAI;YACZ,gEAAgE;YAChE,mEAAmE;YACnE,qDAAqD;YACrD,MAAM,EAAE,KAAK;YACb,YAAY,EAAE,IAAI;YAClB,gEAAgE;YAChE,6CAA6C;YAC7C,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM;YAC9B,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM;YAC5B,gBAAgB,EAAE,EAAE,CAAC,oBAAoB,CAAC,MAAM;SACjD;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { Project, ts } from 'ts-morph';\n\n/**\n * Create a ts-morph Project configured for reading messenger capability types.\n *\n * Both discovery strategies share this: `scan` adds every file it can find so\n * the checker can resolve cross-file references, while `root-messenger` adds\n * only the entry files and lets the checker pull in the rest.\n *\n * @returns A new ts-morph Project.\n */\nexport function createProject(): Project {\n return new Project({\n compilerOptions: {\n allowJs: false,\n noEmit: true,\n // Match the project's permissive defaults — we only need symbol\n // resolution, not full typechecking, so a project's own strictness\n // settings shouldn't be able to fail the docs build.\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"]}
@@ -44,4 +44,4 @@ export type NamespaceGroup = {
44
44
  actions: MessengerCapabilityPacket[];
45
45
  events: MessengerCapabilityPacket[];
46
46
  };
47
- //# sourceMappingURL=types.d.cts.map
47
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,2FAA2F;IAC3F,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IACzB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,gBAAgB,EAAE,MAAM,CAAC;IACzB,qFAAqF;IACrF,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,yBAAyB,EAAE,CAAC;IACrC,MAAM,EAAE,yBAAyB,EAAE,CAAC;CACrC,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * A documented parameter for an action handler or event payload — name from\n * the JSDoc `@param` tag, description from the tag's comment body.\n */\nexport type DocumentedParameter = {\n name: string;\n description: string;\n};\n\n/**\n * Information about a messenger action or event extracted from its type\n * in a source file.\n */\nexport type MessengerCapabilityPacket = {\n /** The capability type's TypeScript identifier, e.g. `NetworkControllerGetStateAction`. */\n typeName: string;\n /** The capability's messenger key, e.g. `NetworkController:getState`. */\n typeString: string;\n /** Whether the capability is an action (request/response) or an event (broadcast). */\n kind: 'action' | 'event';\n /** Cleaned description body — content above the first JSDoc tag. */\n jsDoc: string;\n /**\n * Documented parameters — populated from `@param` tags, in source order.\n * For actions these describe the handler's arguments; for events they\n * describe the payload tuple's positional elements.\n */\n params: DocumentedParameter[];\n /** Documented return value — populated from a `@returns` tag, if any. */\n returns: string;\n /** Raw type text of the handler (action) or payload (event). */\n handlerOrPayload: string;\n /** Path to the file the capability was declared in, relative to the project root. */\n sourceFile: string;\n /** 1-based line number of the capability declaration. */\n line: number;\n /** Whether the capability is marked `@deprecated`. */\n deprecated: boolean;\n};\n\n/**\n * A namespace's actions and events, after dedup and sorting.\n */\nexport type NamespaceGroup = {\n namespace: string;\n actions: MessengerCapabilityPacket[];\n events: MessengerCapabilityPacket[];\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/platform-api-docs",
3
- "version": "0.1.0-preview-abca9bcea",
3
+ "version": "0.2.0-preview-0a30e47",
4
4
  "description": "Produces documentation for the platform API, the set of actions and events available in the clients through the message bus",
5
5
  "keywords": [
6
6
  "Ethereum",
@@ -15,19 +15,22 @@
15
15
  "type": "git",
16
16
  "url": "https://github.com/MetaMask/core.git"
17
17
  },
18
- "bin": "./dist/cli.mjs",
18
+ "bin": "./dist/cli.js",
19
19
  "files": [
20
20
  "dist/",
21
21
  "site/"
22
22
  ],
23
+ "type": "module",
23
24
  "sideEffects": false,
24
25
  "publishConfig": {
25
26
  "access": "public",
26
27
  "registry": "https://registry.npmjs.org/"
27
28
  },
28
29
  "scripts": {
29
- "build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references",
30
- "build:all": "ts-bridge --project tsconfig.build.json --verbose --clean",
30
+ "build": "tsc --project tsconfig.build.json",
31
+ "build:all": "tsc --build tsconfig.build.json --verbose",
32
+ "build:clean": "yarn build:only-clean && yarn build",
33
+ "build:only-clean": "rimraf './dist' './tsconfig.build.tsbuildinfo'",
31
34
  "changelog:update": "../../scripts/update-changelog.sh @metamask/platform-api-docs",
32
35
  "changelog:validate": "../../scripts/validate-changelog.sh @metamask/platform-api-docs",
33
36
  "cli": "tsx src/cli.ts",
@@ -58,19 +61,20 @@
58
61
  },
59
62
  "devDependencies": {
60
63
  "@metamask/auto-changelog": "^6.1.0",
61
- "@ts-bridge/cli": "^0.6.4",
62
64
  "@types/jest": "^30.0.0",
63
- "@types/node": "^16.18.54",
65
+ "@types/node": "^22.13.14",
64
66
  "@types/npm-which": "^3",
65
67
  "@types/react": "^19.0.0",
66
68
  "@types/yargs": "^17.0.32",
69
+ "@typescript/native": "npm:typescript@^7.0.2",
67
70
  "deepmerge": "^4.2.2",
68
71
  "jest": "^30.4.2",
72
+ "rimraf": "^5.0.5",
69
73
  "ts-jest": "^29.4.11",
70
74
  "tsx": "^4.20.5",
71
- "typescript": "~5.3.3"
75
+ "typescript": "npm:@typescript/typescript6@^6.0.2"
72
76
  },
73
77
  "engines": {
74
- "node": "^18.18 || >=20"
78
+ "node": "^22.14.0 || ^24"
75
79
  }
76
80
  }
package/dist/cli.cjs DELETED
@@ -1,328 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || function (mod) {
20
- if (mod && mod.__esModule) return mod;
21
- var result = {};
22
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
- __setModuleDefault(result, mod);
24
- return result;
25
- };
26
- var __importDefault = (this && this.__importDefault) || function (mod) {
27
- return (mod && mod.__esModule) ? mod : { "default": mod };
28
- };
29
- Object.defineProperty(exports, "__esModule", { value: true });
30
- const execa_1 = __importDefault(require("execa/index.js"));
31
- const fs = __importStar(require("node:fs/promises"));
32
- const path = __importStar(require("node:path"));
33
- const npm_which_1 = __importDefault(require("npm-which"));
34
- const yargs_1 = __importDefault(require("yargs"));
35
- const generate_js_1 = require("./generate.cjs");
36
- const root_messenger_discovery_js_1 = require("./root-messenger-discovery.cjs");
37
- /**
38
- * Locate the Docusaurus binary in this package's `node_modules/.bin`. Using
39
- * `npm-which` lets the lookup track wherever the installed Docusaurus puts
40
- * its binary, so a future Docusaurus upgrade can't break this path.
41
- *
42
- * @returns Absolute path to the `docusaurus` executable.
43
- */
44
- function resolveDocusaurus() {
45
- return (0, npm_which_1.default)(__dirname).sync('docusaurus');
46
- }
47
- /**
48
- * Run a Docusaurus command.
49
- *
50
- * @param command - The docusaurus command (start, build, serve).
51
- * @param cwd - The site directory.
52
- * @param extraEnv - Extra environment variables passed through to the
53
- * Docusaurus process (e.g. `DOCS_PROJECT_LABEL`, `DOCS_COMMIT_SHA`,
54
- * `DOCS_REPO_URL`).
55
- */
56
- async function runDocusaurus(command, cwd, extraEnv = {}) {
57
- await (0, execa_1.default)(resolveDocusaurus(), [command], {
58
- cwd,
59
- stdio: 'inherit',
60
- env: { ...process.env, ...extraEnv },
61
- });
62
- }
63
- /**
64
- * Copy site files into the output directory, skipping `node_modules`, `docs`,
65
- * and `tsconfig.json`. `docs` is owned by the doc generator and shouldn't be
66
- * carried over from the source `site/` directory. `tsconfig.json` extends the
67
- * monorepo's `tsconfig.base.json` via a relative path that only resolves from
68
- * the source location — it's there for IDE / lint inheritance, not for
69
- * Docusaurus, which uses `jiti` and doesn't consult the tsconfig at runtime.
70
- *
71
- * @param outDir - The output directory to set up.
72
- */
73
- async function setupSite(outDir) {
74
- const packageDir = path.resolve(__dirname, '..');
75
- const siteDir = path.join(packageDir, 'site');
76
- const packageNodeModules = path.join(packageDir, 'node_modules');
77
- const skip = new Set(['node_modules', 'docs', 'tsconfig.json']);
78
- console.log(`\nSetting up Docusaurus site in ${outDir}...`);
79
- // `fs.cp` has been available since Node 16.7 and only got the "stable"
80
- // marker in 22.3 — it's functional throughout our supported Node range
81
- // (`^18.18 || >=20`), even though the linter flags the older versions.
82
- // eslint-disable-next-line n/no-unsupported-features/node-builtins
83
- await fs.cp(siteDir, outDir, {
84
- recursive: true,
85
- filter: (source) => !skip.has(path.basename(source)),
86
- });
87
- // Symlink this package's `node_modules` into the output so the copied
88
- // `docusaurus.config.ts` and the rest of Docusaurus's bundling pipeline can
89
- // resolve their deps the same way they do in the source tree. Without it,
90
- // Node's resolver walks up from the output and can't reach our nested deps
91
- // when the package is installed as a regular dependency by an external
92
- // consumer (e.g. `metamask-extension`, `metamask-mobile`).
93
- const linkPath = path.join(outDir, 'node_modules');
94
- try {
95
- // `'junction'` works cross-platform (POSIX ignores it; Windows uses it
96
- // without admin) — `'dir'` would require admin on Windows.
97
- await fs.symlink(packageNodeModules, linkPath, 'junction');
98
- }
99
- catch (error) {
100
- if (error.code !== 'EEXIST') {
101
- throw error;
102
- }
103
- }
104
- // Write a minimal package.json so Docusaurus doesn't warn about a missing one
105
- const pkgJsonPath = path.join(outDir, 'package.json');
106
- try {
107
- await fs.access(pkgJsonPath);
108
- }
109
- catch {
110
- await fs.writeFile(pkgJsonPath, JSON.stringify({ name: 'platform-api-docs-site', private: true }, null, 2));
111
- }
112
- }
113
- /**
114
- * Resolve the short Git commit SHA the docs are being generated from.
115
- * Returns null when the project isn't a git repo or git isn't available.
116
- *
117
- * @param projectPath - The project root path.
118
- * @returns The short SHA, or null on failure.
119
- */
120
- async function resolveCommitSha(projectPath) {
121
- try {
122
- const { stdout } = await (0, execa_1.default)('git', ['rev-parse', '--short', 'HEAD'], {
123
- cwd: projectPath,
124
- });
125
- const trimmed = stdout.trim();
126
- return trimmed.length > 0 ? trimmed : null;
127
- }
128
- catch {
129
- return null;
130
- }
131
- }
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.
145
- */
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)
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) => {
173
- yargsInstance.positional('project-path', {
174
- type: 'string',
175
- description: 'Path to the project to scan',
176
- default: '.',
177
- });
178
- })
179
- .option('build', {
180
- type: 'boolean',
181
- description: 'Generate platform API docs and build a production-ready site',
182
- default: false,
183
- })
184
- .option('serve', {
185
- type: 'boolean',
186
- description: 'Generate platform API docs and serve a production-ready site',
187
- default: false,
188
- })
189
- .option('dev', {
190
- type: 'boolean',
191
- description: 'Generate platform API docs and serve a development-only site',
192
- default: false,
193
- })
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', {
201
- type: 'string',
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,
213
- description: 'Additional directories within the project to scan for messenger actions and events (note: may be specified multiple times)',
214
- default: [],
215
- })
216
- .option('output', {
217
- type: 'string',
218
- description: 'Output directory',
219
- })
220
- .option('project-label', {
221
- type: 'string',
222
- description: 'Short label identifying the project (e.g. "Core", "Extension") — stamped on the site title and headings',
223
- })
224
- .option('site-url', {
225
- type: 'string',
226
- description: 'Absolute URL the built site will be served from, e.g. https://metamask.github.io',
227
- })
228
- .option('site-base-url', {
229
- type: 'string',
230
- description: 'Path prefix the built site will be served under, e.g. /core/platform-api/',
231
- })
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']);
257
- const resolvedOutputDir = path.resolve(argv.output ?? path.join(resolvedProjectPath, '.platform-api-docs'));
258
- const projectLabel = argv['project-label'] && argv['project-label'].length > 0
259
- ? argv['project-label']
260
- : null;
261
- const commitSha = await resolveCommitSha(resolvedProjectPath);
262
- const repoUrl = await (0, generate_js_1.resolveRepoUrl)(resolvedProjectPath);
263
- // Step 1: Generate docs
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
- }
286
- // Step 2: If --build, --serve, or --dev, set up and run Docusaurus
287
- if (argv.build || argv.serve || argv.dev) {
288
- await setupSite(resolvedOutputDir);
289
- // Translate CLI flags into the environment variables Docusaurus's
290
- // config reads. Keeping the CLI surface flag-only means consumers
291
- // (workflow files, package.json scripts) don't have to know how the
292
- // values are plumbed through to Docusaurus.
293
- const docusaurusEnv = {};
294
- if (projectLabel) {
295
- docusaurusEnv.DOCS_PROJECT_LABEL = projectLabel;
296
- }
297
- if (commitSha) {
298
- docusaurusEnv.DOCS_COMMIT_SHA = commitSha;
299
- }
300
- if (repoUrl) {
301
- docusaurusEnv.DOCS_REPO_URL = repoUrl;
302
- }
303
- if (typeof argv['site-url'] === 'string' && argv['site-url'].length > 0) {
304
- docusaurusEnv.DOCS_URL = argv['site-url'];
305
- }
306
- if (typeof argv['site-base-url'] === 'string' &&
307
- argv['site-base-url'].length > 0) {
308
- docusaurusEnv.DOCS_BASE_URL = argv['site-base-url'];
309
- }
310
- if (argv.dev) {
311
- console.log('\nStarting dev server...');
312
- await runDocusaurus('start', resolvedOutputDir, docusaurusEnv);
313
- }
314
- else if (argv.build || argv.serve) {
315
- console.log('\nBuilding static site...');
316
- await runDocusaurus('build', resolvedOutputDir, docusaurusEnv);
317
- if (argv.serve) {
318
- console.log('\nServing static site...');
319
- await runDocusaurus('serve', resolvedOutputDir, docusaurusEnv);
320
- }
321
- }
322
- }
323
- }
324
- main().catch((error) => {
325
- console.error(error);
326
- process.exitCode = 1;
327
- });
328
- //# sourceMappingURL=cli.cjs.map
package/dist/cli.cjs.map DELETED
@@ -1 +0,0 @@
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';\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.d.cts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=cli.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.d.cts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.d.mts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=cli.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.d.mts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}