@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.
- package/CHANGELOG.md +9 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/{cli.mjs → cli.js} +10 -40
- package/dist/cli.js.map +1 -0
- package/dist/{extraction.d.cts → extraction.d.ts} +3 -3
- package/dist/extraction.d.ts.map +1 -0
- package/dist/{extraction.mjs → extraction.js} +3 -3
- package/dist/extraction.js.map +1 -0
- package/dist/{generate.d.cts → generate.d.ts} +2 -2
- package/dist/generate.d.ts.map +1 -0
- package/dist/{generate.mjs → generate.js} +10 -10
- package/dist/generate.js.map +1 -0
- package/dist/{markdown.d.cts → markdown.d.ts} +2 -2
- package/dist/markdown.d.ts.map +1 -0
- package/dist/{markdown.mjs → markdown.js} +1 -1
- package/dist/markdown.js.map +1 -0
- package/dist/{root-messenger-discovery.d.cts → root-messenger-discovery.d.ts} +2 -2
- package/dist/root-messenger-discovery.d.ts.map +1 -0
- package/dist/{root-messenger-discovery.mjs → root-messenger-discovery.js} +5 -5
- package/dist/root-messenger-discovery.js.map +1 -0
- package/dist/{ts-project.d.cts → ts-project.d.ts} +2 -2
- package/dist/ts-project.d.ts.map +1 -0
- package/dist/{ts-project.mjs → ts-project.js} +2 -2
- package/dist/ts-project.js.map +1 -0
- package/dist/{types.d.cts → types.d.ts} +1 -1
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +12 -8
- package/dist/cli.cjs +0 -328
- package/dist/cli.cjs.map +0 -1
- package/dist/cli.d.cts +0 -3
- package/dist/cli.d.cts.map +0 -1
- package/dist/cli.d.mts +0 -3
- package/dist/cli.d.mts.map +0 -1
- package/dist/cli.mjs.map +0 -1
- package/dist/extraction.cjs +0 -754
- package/dist/extraction.cjs.map +0 -1
- package/dist/extraction.d.cts.map +0 -1
- package/dist/extraction.d.mts +0 -73
- package/dist/extraction.d.mts.map +0 -1
- package/dist/extraction.mjs.map +0 -1
- package/dist/generate.cjs +0 -505
- package/dist/generate.cjs.map +0 -1
- package/dist/generate.d.cts.map +0 -1
- package/dist/generate.d.mts +0 -70
- package/dist/generate.d.mts.map +0 -1
- package/dist/generate.mjs.map +0 -1
- package/dist/markdown.cjs +0 -239
- package/dist/markdown.cjs.map +0 -1
- package/dist/markdown.d.cts.map +0 -1
- package/dist/markdown.d.mts +0 -52
- package/dist/markdown.d.mts.map +0 -1
- package/dist/markdown.mjs.map +0 -1
- package/dist/root-messenger-discovery.cjs +0 -359
- package/dist/root-messenger-discovery.cjs.map +0 -1
- package/dist/root-messenger-discovery.d.cts.map +0 -1
- package/dist/root-messenger-discovery.d.mts +0 -61
- package/dist/root-messenger-discovery.d.mts.map +0 -1
- package/dist/root-messenger-discovery.mjs.map +0 -1
- package/dist/ts-project.cjs +0 -33
- package/dist/ts-project.cjs.map +0 -1
- package/dist/ts-project.d.cts.map +0 -1
- package/dist/ts-project.d.mts +0 -12
- package/dist/ts-project.d.mts.map +0 -1
- package/dist/ts-project.mjs.map +0 -1
- package/dist/types.cjs +0 -3
- package/dist/types.cjs.map +0 -1
- package/dist/types.d.cts.map +0 -1
- package/dist/types.d.mts +0 -47
- package/dist/types.d.mts.map +0 -1
- package/dist/types.mjs +0 -2
- package/dist/types.mjs.map +0 -1
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.discoverFromRootMessengerCapabilitiesTypes = exports.parseRootCapabilitiesTypeReference = void 0;
|
|
27
|
-
const path = __importStar(require("node:path"));
|
|
28
|
-
const ts_morph_1 = require("ts-morph");
|
|
29
|
-
const extraction_js_1 = require("./extraction.cjs");
|
|
30
|
-
const ts_project_js_1 = require("./ts-project.cjs");
|
|
31
|
-
/**
|
|
32
|
-
* Split a `<file>#<TypeName>` reference into its parts, on the last `#` so
|
|
33
|
-
* that paths containing a `#` still work.
|
|
34
|
-
*
|
|
35
|
-
* @param reference - The raw reference, e.g. `src/messenger.ts#RootActions`.
|
|
36
|
-
* @returns The parsed reference.
|
|
37
|
-
* @throws If the reference has no `#`, or either side of it is empty.
|
|
38
|
-
*/
|
|
39
|
-
function parseRootCapabilitiesTypeReference(reference) {
|
|
40
|
-
const separatorIndex = reference.lastIndexOf('#');
|
|
41
|
-
if (separatorIndex === -1) {
|
|
42
|
-
throw new Error(`Expected a reference of the form "<file>#<TypeName>", got "${reference}".`);
|
|
43
|
-
}
|
|
44
|
-
const filePath = reference.slice(0, separatorIndex);
|
|
45
|
-
const typeName = reference.slice(separatorIndex + 1);
|
|
46
|
-
if (filePath.length === 0 || typeName.length === 0) {
|
|
47
|
-
throw new Error(`Expected a reference of the form "<file>#<TypeName>", got "${reference}".`);
|
|
48
|
-
}
|
|
49
|
-
return { filePath, typeName };
|
|
50
|
-
}
|
|
51
|
-
exports.parseRootCapabilitiesTypeReference = parseRootCapabilitiesTypeReference;
|
|
52
|
-
/**
|
|
53
|
-
* A `<file>#<TypeName>` string, passed from the command line, refers to an
|
|
54
|
-
* messenger actions or events collection type. This function reads the file and
|
|
55
|
-
* looks up the matching type alias.
|
|
56
|
-
*
|
|
57
|
-
* @param args - The arguments to this function.
|
|
58
|
-
* @param args.project - The ts-morph project to load the file into.
|
|
59
|
-
* @param args.projectPath - Absolute path to the project root.
|
|
60
|
-
* @param args.reference - The root capability collection type reference to
|
|
61
|
-
* resolve.
|
|
62
|
-
* @param args.commandLineOptionName - The command-line option the reference
|
|
63
|
-
* came from, used in errors.
|
|
64
|
-
* @returns The type alias declaration the reference names.
|
|
65
|
-
* @throws If the file can't be read or declares no such type alias.
|
|
66
|
-
*/
|
|
67
|
-
function resolveMessengerCapabilitiesTypeReference({ project, projectPath, reference, commandLineOptionName, }) {
|
|
68
|
-
const absolutePath = path.resolve(projectPath, reference.filePath);
|
|
69
|
-
let sourceFile;
|
|
70
|
-
try {
|
|
71
|
-
// `addSourceFileAtPath` is idempotent: the two references often name the
|
|
72
|
-
// same file, and the second call returns the source file added by the first.
|
|
73
|
-
sourceFile = project.addSourceFileAtPath(absolutePath);
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
throw new Error(`Could not read ${absolutePath}, which was named by ${commandLineOptionName}.`);
|
|
77
|
-
}
|
|
78
|
-
// EXAMPLES:
|
|
79
|
-
// type RootMessengerActions = ...
|
|
80
|
-
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
81
|
-
// type RootMessengerEvents = ...
|
|
82
|
-
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
83
|
-
const declaration = sourceFile.getTypeAlias(reference.typeName);
|
|
84
|
-
if (!declaration) {
|
|
85
|
-
throw new Error(`No type alias named "${reference.typeName}" in ${reference.filePath}, which was named by ${commandLineOptionName}.`);
|
|
86
|
-
}
|
|
87
|
-
return declaration;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Given the type of a messenger capability (e.g.
|
|
91
|
-
* `NetworkControllerAddNetworkAction`) as obtained from a collection of
|
|
92
|
-
* capability types (e.g. `RootMessengerActions` or `RootMessengerEvents`),
|
|
93
|
-
* locate the type declaration for that capability type.
|
|
94
|
-
*
|
|
95
|
-
* This is not as simple as following the type to its declaration, because both
|
|
96
|
-
* a collection of capability types and the capability type itself can have
|
|
97
|
-
* multiple representations. So there are three strategies for finding the type:
|
|
98
|
-
*
|
|
99
|
-
* 1. If the capability type was declared as a type alias (e.g. `type
|
|
100
|
-
* FooControllerSomeAction = { ... }`), then we need to use the symbol to
|
|
101
|
-
* find the declaration.
|
|
102
|
-
* 2. If the capability type was declared as an interface (e.g. `interface
|
|
103
|
-
* FooControllerSomeAction { ... }`), we don't need to do this; interfaces
|
|
104
|
-
* are their own declaration.
|
|
105
|
-
* 3. If the capability *collection* type is not a union but merely a type alias
|
|
106
|
-
* (e.g. `type RootMessengerActions = NetworkControllerAddNetworkAction`)
|
|
107
|
-
* then we follow the right-hand side of the type alias.
|
|
108
|
-
*
|
|
109
|
-
* When none of these find a type declaration, the capability is anonymous
|
|
110
|
-
* (e.g. an inline object type with no name to document) and `undefined` is
|
|
111
|
-
* returned, so the caller can record it as skipped rather than document it.
|
|
112
|
-
*
|
|
113
|
-
* @param capabilityType - The type of the individual capability to find the
|
|
114
|
-
* declaration for.
|
|
115
|
-
* @param capabilityCollectionTypeDeclaration - The declaration of the whole
|
|
116
|
-
* collection the capability came from (e.g. `type RootMessengerActions = ...`).
|
|
117
|
-
* @param isLoneConstituent - Whether the capability collection only includes
|
|
118
|
-
* one capability type.
|
|
119
|
-
* @returns The type alias or interface declaration for the capability, or
|
|
120
|
-
* `undefined` when the capability is anonymous.
|
|
121
|
-
*/
|
|
122
|
-
function findMessengerCapabilityTypeDeclaration(capabilityType, capabilityCollectionTypeDeclaration, isLoneConstituent) {
|
|
123
|
-
// If we have a type alias, look for its symbol.
|
|
124
|
-
//
|
|
125
|
-
// EXAMPLE:
|
|
126
|
-
// type FooControllerSomeAction = { type: '...'; handler: () => void };
|
|
127
|
-
// ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
128
|
-
// the alias symbol names the plain symbol points at this anonymous
|
|
129
|
-
// this declaration object
|
|
130
|
-
//
|
|
131
|
-
// But skip an alias that resolves back to the capability collection itself,
|
|
132
|
-
// which is what TypeScript reports for a lone generic instantiation.
|
|
133
|
-
//
|
|
134
|
-
// EXAMPLE:
|
|
135
|
-
// Here the alias symbol of the sole member is `Actions`, i.e.
|
|
136
|
-
// `capabilityCollectionTypeDeclaration`, which is not the capability we
|
|
137
|
-
// want to document:
|
|
138
|
-
//
|
|
139
|
-
// type Actions = Foo<Bar>;
|
|
140
|
-
// ^^^^^^^ capabilityCollectionTypeDeclaration
|
|
141
|
-
const typeAliasDeclarations = (capabilityType.getAliasSymbol()?.getDeclarations() ?? []).filter((node) => node !== capabilityCollectionTypeDeclaration);
|
|
142
|
-
// An interface has no alias symbol, being its own declaration, so fall back
|
|
143
|
-
// to the plain symbol to reach it.
|
|
144
|
-
// EXAMPLE:
|
|
145
|
-
// interface FooControllerSomeAction { type: '...'; handler: () => void }
|
|
146
|
-
// ^^^^^^^^^^^^^^^^^^^^^^^ reached via the plain symbol
|
|
147
|
-
const typeDeclarations = typeAliasDeclarations.length > 0
|
|
148
|
-
? typeAliasDeclarations
|
|
149
|
-
: (capabilityType.getSymbol()?.getDeclarations() ?? []);
|
|
150
|
-
// Of the declarations behind whichever symbol we used, pick the type alias or
|
|
151
|
-
// interface.
|
|
152
|
-
// EXAMPLES:
|
|
153
|
-
// type FooControllerSomeAction = { ... }
|
|
154
|
-
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
155
|
-
// interface FooControllerSomeAction { ... }
|
|
156
|
-
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
157
|
-
const foundTypeDeclaration = typeDeclarations.find((node) => ts_morph_1.Node.isTypeAliasDeclaration(node) ||
|
|
158
|
-
ts_morph_1.Node.isInterfaceDeclaration(node));
|
|
159
|
-
if (foundTypeDeclaration) {
|
|
160
|
-
return foundTypeDeclaration;
|
|
161
|
-
}
|
|
162
|
-
// If the capability collection type has only one constituent, we can safely
|
|
163
|
-
// assume it's a type alias. If, in this case, it's also generic, the
|
|
164
|
-
// declaration we want is the one its type node references, so follow it.
|
|
165
|
-
//
|
|
166
|
-
// EXAMPLE:
|
|
167
|
-
// type Actions = Foo<Bar>;
|
|
168
|
-
// ^^^ follow this reference to its declaration
|
|
169
|
-
//
|
|
170
|
-
if (isLoneConstituent) {
|
|
171
|
-
return resolveGenericCapabilityCollectionTypeDeclaration(capabilityCollectionTypeDeclaration);
|
|
172
|
-
}
|
|
173
|
-
// If, after all of this, the capability collection is a union with an
|
|
174
|
-
// anonymous constituent, we ignore it:
|
|
175
|
-
//
|
|
176
|
-
// EXAMPLE:
|
|
177
|
-
// type Actions = FooControllerSomeAction | { type: '...'; handler: ... };
|
|
178
|
-
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
179
|
-
return undefined;
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Given a messenger capability collection with one constituent which is a
|
|
183
|
-
* generic capability type, follow that type to find its declaration.
|
|
184
|
-
*
|
|
185
|
-
* A type that is aliased to a generic type is a special case we need to handle,
|
|
186
|
-
* because it won't have a direct alias symbol; we need to pick out the type
|
|
187
|
-
* that acts as the "box" in the generic (e.g. the `Foo` in `type Actions =
|
|
188
|
-
* Foo<Bar>`).
|
|
189
|
-
*
|
|
190
|
-
* @param capabilityCollectionTypeDeclaration - The declaration for a
|
|
191
|
-
* collection of capability types (e.g. `type RootMessengerActions = ...`).
|
|
192
|
-
* @returns The resolved sole capability type.
|
|
193
|
-
*/
|
|
194
|
-
function resolveGenericCapabilityCollectionTypeDeclaration(capabilityCollectionTypeDeclaration) {
|
|
195
|
-
// The root alias must reference another type by name for there to be a
|
|
196
|
-
// declaration to follow.
|
|
197
|
-
// EXAMPLE:
|
|
198
|
-
// type Actions = Foo<Bar>;
|
|
199
|
-
// ^^^^^^^^
|
|
200
|
-
const typeNode = capabilityCollectionTypeDeclaration.getTypeNode();
|
|
201
|
-
if (!typeNode || !ts_morph_1.Node.isTypeReference(typeNode)) {
|
|
202
|
-
return undefined;
|
|
203
|
-
}
|
|
204
|
-
// Resolve the referenced name (e.g. `Foo` in `Foo<Bar>`) to its symbol.
|
|
205
|
-
const localSymbol = typeNode.getTypeName().getSymbol();
|
|
206
|
-
// If the type is imported from another file, ensure that when we access the
|
|
207
|
-
// declaration, it's the type declaration in the other file, not the import
|
|
208
|
-
// declaration in this file.
|
|
209
|
-
// EXAMPLE:
|
|
210
|
-
// import { Foo } from '@metamask/foo';
|
|
211
|
-
// type Actions = Foo<Bar>;
|
|
212
|
-
// ^^^
|
|
213
|
-
const symbol = localSymbol?.getAliasedSymbol() ?? localSymbol;
|
|
214
|
-
// Follow the reference to the type alias or interface it names.
|
|
215
|
-
// EXAMPLES:
|
|
216
|
-
// type Foo<T> = { ... }
|
|
217
|
-
// ^^^^^^^^^^^^^^^^^^^^
|
|
218
|
-
// interface Foo<T> { ... }
|
|
219
|
-
// ^^^^^^^^^^^^^^^^^^^^^^^
|
|
220
|
-
return symbol
|
|
221
|
-
?.getDeclarations()
|
|
222
|
-
.find((node) => ts_morph_1.Node.isTypeAliasDeclaration(node) ||
|
|
223
|
-
ts_morph_1.Node.isInterfaceDeclaration(node));
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Render a short, single-line label for an anonymous type.
|
|
227
|
-
*
|
|
228
|
-
* @param type - The type to describe.
|
|
229
|
-
* @param enclosingNode - Node to render the type relative to, so an aliased
|
|
230
|
-
* type reads as its name rather than `import("<absolute path>").Name`.
|
|
231
|
-
* @returns The label.
|
|
232
|
-
*/
|
|
233
|
-
function summarizeType(type, enclosingNode) {
|
|
234
|
-
const text = type.getText(enclosingNode).replace(/\s+/gu, ' ');
|
|
235
|
-
return text.length > 80 ? `${text.slice(0, 77)}...` : text;
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Walk a messenger capability collection type (e.g. `RootMessengerActions` or
|
|
239
|
-
* `RootMessengerEvents`) to gather all of the consitutent capability types
|
|
240
|
-
* (e.g. `NetworkControllerAddNetworkAction`), then package them so that they
|
|
241
|
-
* can be displayed within the documentation.
|
|
242
|
-
*
|
|
243
|
-
* Messenger capabilities that cannot be extracted for some reason are captured
|
|
244
|
-
* separately.
|
|
245
|
-
*
|
|
246
|
-
* @param args - The arguments to this function.
|
|
247
|
-
* @param args.projectPath - Absolute path to the project root.
|
|
248
|
-
* @param args.capabilityKind - Whether these are actions or events.
|
|
249
|
-
* @param args.capabilityCollectionTypeReference - A reference to a messenger
|
|
250
|
-
* capability collection type within the project, in `<file>#<TypeName>` format.
|
|
251
|
-
* @param args.capabilityCollectionTypeDeclaration - The type declaration
|
|
252
|
-
* representing a collection of messenger capabilities.
|
|
253
|
-
* @param args.commandLineOptionName - The command-line option the reference
|
|
254
|
-
* came from, used in errors.
|
|
255
|
-
* @returns The extracted capabilities along with skipped capabilities.
|
|
256
|
-
* @throws If the capability collection type resolved to `any` or `unknown`.
|
|
257
|
-
*/
|
|
258
|
-
function extractFromMessengerCapabilitiesUnionTypeDeclaration({ projectPath, capabilityKind, capabilityCollectionTypeReference, capabilityCollectionTypeDeclaration, commandLineOptionName, }) {
|
|
259
|
-
const capabilityCollectionType = capabilityCollectionTypeDeclaration
|
|
260
|
-
.getTypeNodeOrThrow()
|
|
261
|
-
.getType();
|
|
262
|
-
// If one or more of the constituent capabilities in the collection is `any`
|
|
263
|
-
// or `unknown` — e.g. its import failed — then the type of the whole
|
|
264
|
-
// collection will also be `any` or `unknown`. Fail instead of emitting a
|
|
265
|
-
// catalog that looks complete but silently isn't.
|
|
266
|
-
if (capabilityCollectionType.isAny() ||
|
|
267
|
-
capabilityCollectionType.isUnknown()) {
|
|
268
|
-
throw new Error(`${capabilityCollectionTypeReference.filePath}#${capabilityCollectionTypeReference.typeName}, named by ${commandLineOptionName}, ` +
|
|
269
|
-
`resolved to \`${capabilityCollectionType.getText()}\`. ` +
|
|
270
|
-
`It's likely that an individual action or event type is also \`${capabilityCollectionType.getText()}\`, ` +
|
|
271
|
-
`which may be due to a failed import. ` +
|
|
272
|
-
`You will need to fix this first before generating docs for this project.`);
|
|
273
|
-
}
|
|
274
|
-
const skippedCapabilities = {
|
|
275
|
-
unnamedCapabilities: [],
|
|
276
|
-
unextractableCapabilities: [],
|
|
277
|
-
};
|
|
278
|
-
// A project with no capabilities of this kind aliases the union to `never`.
|
|
279
|
-
if (capabilityCollectionType.isNever()) {
|
|
280
|
-
return {
|
|
281
|
-
capabilityPackets: [],
|
|
282
|
-
skippedCapabilities,
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
const individualCapabilityTypes = capabilityCollectionType.isUnion()
|
|
286
|
-
? capabilityCollectionType.getUnionTypes()
|
|
287
|
-
: [capabilityCollectionType];
|
|
288
|
-
const capabilityPackets = [];
|
|
289
|
-
for (const capabilityType of individualCapabilityTypes) {
|
|
290
|
-
const capabilityTypeDeclaration = findMessengerCapabilityTypeDeclaration(capabilityType, capabilityCollectionTypeDeclaration, individualCapabilityTypes.length === 1);
|
|
291
|
-
if (!capabilityTypeDeclaration) {
|
|
292
|
-
skippedCapabilities.unnamedCapabilities.push(summarizeType(capabilityType, capabilityCollectionTypeDeclaration));
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
|
-
const classifiedTypeDeclaration = (0, extraction_js_1.classifyMessengerCapabilityTypeDeclaration)(capabilityTypeDeclaration, capabilityKind);
|
|
296
|
-
const capabilityPacket = classifiedTypeDeclaration &&
|
|
297
|
-
(0, extraction_js_1.extractFromMessengerCapabilityTypeDeclaration)(classifiedTypeDeclaration, projectPath);
|
|
298
|
-
if (!capabilityPacket) {
|
|
299
|
-
const sourceFile = capabilityTypeDeclaration
|
|
300
|
-
.getSourceFile()
|
|
301
|
-
.getFilePath();
|
|
302
|
-
skippedCapabilities.unextractableCapabilities.push(`${capabilityTypeDeclaration.getName()} (${path.relative(projectPath, sourceFile)}:${capabilityTypeDeclaration.getStartLineNumber()})`);
|
|
303
|
-
continue;
|
|
304
|
-
}
|
|
305
|
-
capabilityPackets.push(capabilityPacket);
|
|
306
|
-
}
|
|
307
|
-
return { capabilityPackets, skippedCapabilities };
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Resolves `<file>#<TypeName>` references to messenger actions and events
|
|
311
|
-
* collection types within the given project (e.g. `RootMessengerActions` or
|
|
312
|
-
* `RootMessengerEvents`), walks the collection to gather all of the containing
|
|
313
|
-
* capability types (e.g. `NetworkControllerAddNetworkAction`), then packages
|
|
314
|
-
* them so that they can be displayed within the documentation site.
|
|
315
|
-
*
|
|
316
|
-
* @param args - The arguments to this function.
|
|
317
|
-
* @param args.projectPath -Absolute path to the project to scan.
|
|
318
|
-
* @param args.rootActionsTypeReference - A reference to a messenger
|
|
319
|
-
* actions collection type within the project, in `<file>#<TypeName>` format.
|
|
320
|
-
* @param args.rootEventsTypeReference - A reference to a messenger events
|
|
321
|
-
* collection type within the project, in `<file>#<TypeName>` format.
|
|
322
|
-
* @returns The extracted capabilities plus any capabilities that were skipped.
|
|
323
|
-
*/
|
|
324
|
-
function discoverFromRootMessengerCapabilitiesTypes({ projectPath, rootActionsTypeReference, rootEventsTypeReference, }) {
|
|
325
|
-
const project = (0, ts_project_js_1.createProject)();
|
|
326
|
-
const capabilityPacketCollections = [
|
|
327
|
-
[rootActionsTypeReference, 'action', '--root-actions'],
|
|
328
|
-
[rootEventsTypeReference, 'event', '--root-events'],
|
|
329
|
-
];
|
|
330
|
-
const allCapabilityPackets = [];
|
|
331
|
-
const allSkippedCapabilities = {
|
|
332
|
-
unnamedCapabilities: [],
|
|
333
|
-
unextractableCapabilities: [],
|
|
334
|
-
};
|
|
335
|
-
for (const [capabilitiesCollectionTypeReference, kind, commandLineOptionName,] of capabilityPacketCollections) {
|
|
336
|
-
const capabilitiesCollectionTypeDeclaration = resolveMessengerCapabilitiesTypeReference({
|
|
337
|
-
project,
|
|
338
|
-
projectPath,
|
|
339
|
-
reference: capabilitiesCollectionTypeReference,
|
|
340
|
-
commandLineOptionName,
|
|
341
|
-
});
|
|
342
|
-
const { capabilityPackets, skippedCapabilities } = extractFromMessengerCapabilitiesUnionTypeDeclaration({
|
|
343
|
-
projectPath,
|
|
344
|
-
capabilityKind: kind,
|
|
345
|
-
capabilityCollectionTypeReference: capabilitiesCollectionTypeReference,
|
|
346
|
-
capabilityCollectionTypeDeclaration: capabilitiesCollectionTypeDeclaration,
|
|
347
|
-
commandLineOptionName,
|
|
348
|
-
});
|
|
349
|
-
allCapabilityPackets.push(...capabilityPackets);
|
|
350
|
-
allSkippedCapabilities.unnamedCapabilities.push(...skippedCapabilities.unnamedCapabilities);
|
|
351
|
-
allSkippedCapabilities.unextractableCapabilities.push(...skippedCapabilities.unextractableCapabilities);
|
|
352
|
-
}
|
|
353
|
-
return {
|
|
354
|
-
capabilityPackets: allCapabilityPackets,
|
|
355
|
-
skippedCapabilities: allSkippedCapabilities,
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
|
-
exports.discoverFromRootMessengerCapabilitiesTypes = discoverFromRootMessengerCapabilitiesTypes;
|
|
359
|
-
//# sourceMappingURL=root-messenger-discovery.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"root-messenger-discovery.cjs","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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"root-messenger-discovery.d.cts","sourceRoot":"","sources":["../src/root-messenger-discovery.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,yBAAyB,EAAE,oBAAmB;AAS5D;;;;;;;GAOG;AACH,MAAM,MAAM,6BAA6B,GAAG;IAC1C,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,KAAK,mBAAmB,GAAG;IACzB;;;OAGG;IACH,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAI9B,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CAChD,SAAS,EAAE,MAAM,GAChB,6BAA6B,CAiB/B;AA6VD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0CAA0C,CAAC,EACzD,WAAW,EACX,wBAAwB,EACxB,uBAAuB,GACxB,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,wBAAwB,EAAE,6BAA6B,CAAC;IACxD,uBAAuB,EAAE,6BAA6B,CAAC;CACxD,GAAG;IACF,iBAAiB,EAAE,yBAAyB,EAAE,CAAC;IAC/C,mBAAmB,EAAE,mBAAmB,CAAC;CAC1C,CA8CA"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import type { MessengerCapabilityPacket } from "./types.mjs";
|
|
2
|
-
/**
|
|
3
|
-
* A reference to a type declared in a file, written as `<file>#<TypeName>`.
|
|
4
|
-
*
|
|
5
|
-
* The `root-messenger` strategy takes two of these on the command line — one
|
|
6
|
-
* naming a collection of messenger action types, one naming a collection of
|
|
7
|
-
* messenger event types — and uses them to locate the type declarations to
|
|
8
|
-
* enumerate.
|
|
9
|
-
*/
|
|
10
|
-
export type RootCapabilitiesTypeReference = {
|
|
11
|
-
/** Path to the declaring file, relative to the project root. */
|
|
12
|
-
filePath: string;
|
|
13
|
-
/** Name of the type alias within that file. */
|
|
14
|
-
typeName: string;
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* Labels for capability types that were found but couldn't be documented,
|
|
18
|
-
* grouped by why. Labels rather than counts, so warnings can name what to fix.
|
|
19
|
-
*/
|
|
20
|
-
type SkippedCapabilities = {
|
|
21
|
-
/**
|
|
22
|
-
* Capabilities declared inline in the capability collection type, so there is
|
|
23
|
-
* no name or JSDoc to document.
|
|
24
|
-
*/
|
|
25
|
-
unnamedCapabilities: string[];
|
|
26
|
-
unextractableCapabilities: string[];
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* Split a `<file>#<TypeName>` reference into its parts, on the last `#` so
|
|
30
|
-
* that paths containing a `#` still work.
|
|
31
|
-
*
|
|
32
|
-
* @param reference - The raw reference, e.g. `src/messenger.ts#RootActions`.
|
|
33
|
-
* @returns The parsed reference.
|
|
34
|
-
* @throws If the reference has no `#`, or either side of it is empty.
|
|
35
|
-
*/
|
|
36
|
-
export declare function parseRootCapabilitiesTypeReference(reference: string): RootCapabilitiesTypeReference;
|
|
37
|
-
/**
|
|
38
|
-
* Resolves `<file>#<TypeName>` references to messenger actions and events
|
|
39
|
-
* collection types within the given project (e.g. `RootMessengerActions` or
|
|
40
|
-
* `RootMessengerEvents`), walks the collection to gather all of the containing
|
|
41
|
-
* capability types (e.g. `NetworkControllerAddNetworkAction`), then packages
|
|
42
|
-
* them so that they can be displayed within the documentation site.
|
|
43
|
-
*
|
|
44
|
-
* @param args - The arguments to this function.
|
|
45
|
-
* @param args.projectPath -Absolute path to the project to scan.
|
|
46
|
-
* @param args.rootActionsTypeReference - A reference to a messenger
|
|
47
|
-
* actions collection type within the project, in `<file>#<TypeName>` format.
|
|
48
|
-
* @param args.rootEventsTypeReference - A reference to a messenger events
|
|
49
|
-
* collection type within the project, in `<file>#<TypeName>` format.
|
|
50
|
-
* @returns The extracted capabilities plus any capabilities that were skipped.
|
|
51
|
-
*/
|
|
52
|
-
export declare function discoverFromRootMessengerCapabilitiesTypes({ projectPath, rootActionsTypeReference, rootEventsTypeReference, }: {
|
|
53
|
-
projectPath: string;
|
|
54
|
-
rootActionsTypeReference: RootCapabilitiesTypeReference;
|
|
55
|
-
rootEventsTypeReference: RootCapabilitiesTypeReference;
|
|
56
|
-
}): {
|
|
57
|
-
capabilityPackets: MessengerCapabilityPacket[];
|
|
58
|
-
skippedCapabilities: SkippedCapabilities;
|
|
59
|
-
};
|
|
60
|
-
export {};
|
|
61
|
-
//# sourceMappingURL=root-messenger-discovery.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"root-messenger-discovery.d.mts","sourceRoot":"","sources":["../src/root-messenger-discovery.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,yBAAyB,EAAE,oBAAmB;AAS5D;;;;;;;GAOG;AACH,MAAM,MAAM,6BAA6B,GAAG;IAC1C,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,KAAK,mBAAmB,GAAG;IACzB;;;OAGG;IACH,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAI9B,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CAChD,SAAS,EAAE,MAAM,GAChB,6BAA6B,CAiB/B;AA6VD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0CAA0C,CAAC,EACzD,WAAW,EACX,wBAAwB,EACxB,uBAAuB,GACxB,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,wBAAwB,EAAE,6BAA6B,CAAC;IACxD,uBAAuB,EAAE,6BAA6B,CAAC;CACxD,GAAG;IACF,iBAAiB,EAAE,yBAAyB,EAAE,CAAC;IAC/C,mBAAmB,EAAE,mBAAmB,CAAC;CAC1C,CA8CA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"root-messenger-discovery.mjs","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"]}
|
package/dist/ts-project.cjs
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createProject = void 0;
|
|
4
|
-
const ts_morph_1 = require("ts-morph");
|
|
5
|
-
/**
|
|
6
|
-
* Create a ts-morph Project configured for reading messenger capability types.
|
|
7
|
-
*
|
|
8
|
-
* Both discovery strategies share this: `scan` adds every file it can find so
|
|
9
|
-
* the checker can resolve cross-file references, while `root-messenger` adds
|
|
10
|
-
* only the entry files and lets the checker pull in the rest.
|
|
11
|
-
*
|
|
12
|
-
* @returns A new ts-morph Project.
|
|
13
|
-
*/
|
|
14
|
-
function createProject() {
|
|
15
|
-
return new ts_morph_1.Project({
|
|
16
|
-
compilerOptions: {
|
|
17
|
-
allowJs: false,
|
|
18
|
-
noEmit: true,
|
|
19
|
-
// Match the project's permissive defaults — we only need symbol
|
|
20
|
-
// resolution, not full typechecking, so a project's own strictness
|
|
21
|
-
// settings shouldn't be able to fail the docs build.
|
|
22
|
-
strict: false,
|
|
23
|
-
skipLibCheck: true,
|
|
24
|
-
// Explicit module options so cross-file symbol resolution works
|
|
25
|
-
// regardless of the host process's tsconfig.
|
|
26
|
-
target: ts_morph_1.ts.ScriptTarget.ESNext,
|
|
27
|
-
module: ts_morph_1.ts.ModuleKind.ESNext,
|
|
28
|
-
moduleResolution: ts_morph_1.ts.ModuleResolutionKind.NodeJs,
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
exports.createProject = createProject;
|
|
33
|
-
//# sourceMappingURL=ts-project.cjs.map
|
package/dist/ts-project.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ts-project.cjs","sourceRoot":"","sources":["../src/ts-project.ts"],"names":[],"mappings":";;;AAAA,uCAAuC;AAEvC;;;;;;;;GAQG;AACH,SAAgB,aAAa;IAC3B,OAAO,IAAI,kBAAO,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,aAAE,CAAC,YAAY,CAAC,MAAM;YAC9B,MAAM,EAAE,aAAE,CAAC,UAAU,CAAC,MAAM;YAC5B,gBAAgB,EAAE,aAAE,CAAC,oBAAoB,CAAC,MAAM;SACjD;KACF,CAAC,CAAC;AACL,CAAC;AAjBD,sCAiBC","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"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ts-project.d.cts","sourceRoot":"","sources":["../src/ts-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAM,iBAAiB;AAEvC;;;;;;;;GAQG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAiBvC"}
|
package/dist/ts-project.d.mts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Project } from "ts-morph";
|
|
2
|
-
/**
|
|
3
|
-
* Create a ts-morph Project configured for reading messenger capability types.
|
|
4
|
-
*
|
|
5
|
-
* Both discovery strategies share this: `scan` adds every file it can find so
|
|
6
|
-
* the checker can resolve cross-file references, while `root-messenger` adds
|
|
7
|
-
* only the entry files and lets the checker pull in the rest.
|
|
8
|
-
*
|
|
9
|
-
* @returns A new ts-morph Project.
|
|
10
|
-
*/
|
|
11
|
-
export declare function createProject(): Project;
|
|
12
|
-
//# sourceMappingURL=ts-project.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ts-project.d.mts","sourceRoot":"","sources":["../src/ts-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAM,iBAAiB;AAEvC;;;;;;;;GAQG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAiBvC"}
|
package/dist/ts-project.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ts-project.mjs","sourceRoot":"","sources":["../src/ts-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,iBAAiB;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"]}
|
package/dist/types.cjs
DELETED
package/dist/types.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs","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"]}
|