shelving 1.235.0 → 1.236.0
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.
|
@@ -5,6 +5,7 @@ import { FileExtractor } from "./FileExtractor.js";
|
|
|
5
5
|
* - Uses the TypeScript compiler API to parse the AST.
|
|
6
6
|
* - Extracts exported, public, non-`_`-prefixed declarations as `tree-documentation` children.
|
|
7
7
|
* - Overloaded declarations sharing a name are merged into a single `tree-documentation` with multiple `signatures`.
|
|
8
|
+
* - Class declarations synthesise their `signatures`, `params`, and `returns` from the constructor — `new ClassName<…>(…)` including generics, one signature per constructor overload, with `returns` set to the class type. Param descriptions come from the constructor's `@param` first, then the class's `@param`.
|
|
8
9
|
* - Top-of-file JSDoc comment becomes the file's `content`.
|
|
9
10
|
* - Sets `description` (a plain-text summary from the first JSDoc paragraph) on the file and every `tree-documentation` child.
|
|
10
11
|
* - Sets `title` on every `tree-documentation` child — `name()` for functions and methods, bare `name` for other kinds. Parent class context comes from the `class` prop ("member of …" affordance), never the title.
|
|
@@ -6,6 +6,7 @@ import { extractMarkdownProps } from "./MarkupExtractor.js";
|
|
|
6
6
|
* - Uses the TypeScript compiler API to parse the AST.
|
|
7
7
|
* - Extracts exported, public, non-`_`-prefixed declarations as `tree-documentation` children.
|
|
8
8
|
* - Overloaded declarations sharing a name are merged into a single `tree-documentation` with multiple `signatures`.
|
|
9
|
+
* - Class declarations synthesise their `signatures`, `params`, and `returns` from the constructor — `new ClassName<…>(…)` including generics, one signature per constructor overload, with `returns` set to the class type. Param descriptions come from the constructor's `@param` first, then the class's `@param`.
|
|
9
10
|
* - Top-of-file JSDoc comment becomes the file's `content`.
|
|
10
11
|
* - Sets `description` (a plain-text summary from the first JSDoc paragraph) on the file and every `tree-documentation` child.
|
|
11
12
|
* - Sets `title` on every `tree-documentation` child — `name()` for functions and methods, bare `name` for other kinds. Parent class context comes from the `class` prop ("member of …" affordance), never the title.
|
|
@@ -108,9 +109,9 @@ function _extractStatement(statement, source) {
|
|
|
108
109
|
const kind = _getKind(statement);
|
|
109
110
|
if (!kind)
|
|
110
111
|
return;
|
|
111
|
-
const
|
|
112
|
+
const signatures = _getSignatures(statement, source, name);
|
|
112
113
|
const params = _getParams(statement, source, jsDoc?.params);
|
|
113
|
-
const returns = _getReturns(statement, source, jsDoc?.returns);
|
|
114
|
+
const returns = _getReturns(statement, source, jsDoc?.returns, name);
|
|
114
115
|
const throws = jsDoc?.throws;
|
|
115
116
|
const examples = jsDoc?.examples;
|
|
116
117
|
// Heritage (`extends` / `implements`) is only meaningful for classes and interfaces.
|
|
@@ -126,7 +127,7 @@ function _extractStatement(statement, source) {
|
|
|
126
127
|
kind,
|
|
127
128
|
description: extractMarkdownProps(jsDoc?.description ?? "").description,
|
|
128
129
|
content: _buildJSDocContent(jsDoc?.description, jsDoc?.unhandled),
|
|
129
|
-
signatures
|
|
130
|
+
signatures,
|
|
130
131
|
params,
|
|
131
132
|
returns,
|
|
132
133
|
throws,
|
|
@@ -200,30 +201,60 @@ function _getKind(statement) {
|
|
|
200
201
|
if (ts.isVariableStatement(statement))
|
|
201
202
|
return "constant";
|
|
202
203
|
}
|
|
203
|
-
/** Get the text signature of a statement —
|
|
204
|
-
function
|
|
204
|
+
/** Get the text signature(s) of a statement — complete, name-prefixed declarations usable as headings. */
|
|
205
|
+
function _getSignatures(statement, source, name) {
|
|
205
206
|
if (ts.isFunctionDeclaration(statement)) {
|
|
206
207
|
const params = statement.parameters.map(p => p.getText(source)).join(", ");
|
|
207
208
|
const ret = statement.type ? statement.type.getText(source) : "void";
|
|
208
|
-
return `${name}(${params}): ${ret}
|
|
209
|
+
return [`${name}(${params}): ${ret}`];
|
|
210
|
+
}
|
|
211
|
+
if (ts.isClassDeclaration(statement)) {
|
|
212
|
+
// Synthesise `new ClassName<…>(…)` constructor signatures so a class page reads like a function's.
|
|
213
|
+
return _getConstructorSignatures(statement, source, name);
|
|
209
214
|
}
|
|
210
215
|
if (ts.isInterfaceDeclaration(statement)) {
|
|
211
216
|
// Emit `{ member; member }` — the same shape a `type` object body produces, distinguished only by the `kind` badge.
|
|
212
217
|
const members = statement.members.map(m => m.getText(source).replace(/;\s*$/, "").trim()).join("; ");
|
|
213
|
-
return members ? `{ ${members} }` : "{}";
|
|
218
|
+
return [members ? `{ ${members} }` : "{}"];
|
|
214
219
|
}
|
|
215
220
|
if (ts.isTypeAliasDeclaration(statement)) {
|
|
216
221
|
// Emit only the type body (e.g. `{ a: string }` or `string | null`) — the alias name is already the page title.
|
|
217
|
-
return statement.type.getText(source);
|
|
222
|
+
return [statement.type.getText(source)];
|
|
218
223
|
}
|
|
219
224
|
if (ts.isVariableStatement(statement)) {
|
|
220
225
|
const declaration = statement.declarationList.declarations[0];
|
|
221
226
|
if (declaration?.type)
|
|
222
|
-
return `${name}: ${declaration.type.getText(source)}
|
|
227
|
+
return [`${name}: ${declaration.type.getText(source)}`];
|
|
223
228
|
}
|
|
224
229
|
}
|
|
225
|
-
/**
|
|
230
|
+
/** Render a class's generic parameter names as `<P, R>` (names only, no constraints), or `""` when non-generic. */
|
|
231
|
+
function _getTypeParamNames(statement, source) {
|
|
232
|
+
const { typeParameters } = statement;
|
|
233
|
+
if (!typeParameters?.length)
|
|
234
|
+
return "";
|
|
235
|
+
return `<${typeParameters.map(t => t.name.getText(source)).join(", ")}>`;
|
|
236
|
+
}
|
|
237
|
+
/** Get a class's constructor declarations (overload signatures + implementation), in source order. */
|
|
238
|
+
function _getConstructors(statement) {
|
|
239
|
+
return statement.members.filter(ts.isConstructorDeclaration);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Synthesise `new ClassName<…>(…)` signatures from a class's constructor declaration(s).
|
|
243
|
+
* - Generics are included so the reader sees how they're inferred from the arguments (e.g. `new MockAPIProvider<P, R>(…)`).
|
|
244
|
+
* - Multiple constructor overloads each become a signature, same as function overloads.
|
|
245
|
+
* - A class with no explicit constructor yields a single degenerate `new ClassName()` signature.
|
|
246
|
+
*/
|
|
247
|
+
function _getConstructorSignatures(statement, source, name) {
|
|
248
|
+
const generics = _getTypeParamNames(statement, source);
|
|
249
|
+
const constructors = _getConstructors(statement);
|
|
250
|
+
if (!constructors.length)
|
|
251
|
+
return [`new ${name}${generics}()`];
|
|
252
|
+
return constructors.map(c => `new ${name}${generics}(${c.parameters.map(p => p.getText(source)).join(", ")})`);
|
|
253
|
+
}
|
|
254
|
+
/** Extract parameters from a function or class declaration, enriched with JSDoc `@param` descriptions. */
|
|
226
255
|
function _getParams(statement, source, jsDocParams) {
|
|
256
|
+
if (ts.isClassDeclaration(statement))
|
|
257
|
+
return _getConstructorParams(statement, source, jsDocParams);
|
|
227
258
|
if (!ts.isFunctionDeclaration(statement))
|
|
228
259
|
return;
|
|
229
260
|
const params = statement.parameters.map(p => {
|
|
@@ -235,8 +266,34 @@ function _getParams(statement, source, jsDocParams) {
|
|
|
235
266
|
});
|
|
236
267
|
return params.length ? params : undefined;
|
|
237
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* Extract a class's constructor parameters as `params`, mirroring the function shape.
|
|
271
|
+
* - Descriptions are sourced from the constructor's own `@param` first, falling back to the class-level `@param`.
|
|
272
|
+
* - Overloaded constructors contribute their parameters in source order, de-duplicated by identity (same as function overloads).
|
|
273
|
+
*/
|
|
274
|
+
function _getConstructorParams(statement, source, classJsDocParams) {
|
|
275
|
+
let params;
|
|
276
|
+
for (const ctor of _getConstructors(statement)) {
|
|
277
|
+
const ctorJsDocParams = _getJSDoc(ctor, source)?.params;
|
|
278
|
+
const next = ctor.parameters.map(p => {
|
|
279
|
+
const name = p.name.getText(source);
|
|
280
|
+
const type = p.type?.getText(source);
|
|
281
|
+
const optional = !!p.questionToken || !!p.initializer;
|
|
282
|
+
// Constructor-level `@param` wins over the class-level `@param` on collision.
|
|
283
|
+
const description = ctorJsDocParams?.find(d => d.name === name)?.description ?? classJsDocParams?.find(d => d.name === name)?.description;
|
|
284
|
+
return { name, type, description, optional };
|
|
285
|
+
});
|
|
286
|
+
params = _concatUnique(params, next, p => `${p.name}\0${p.type}\0${p.description}\0${p.optional}`);
|
|
287
|
+
}
|
|
288
|
+
return params?.length ? params : undefined;
|
|
289
|
+
}
|
|
238
290
|
/** Extract return entries — combines the signature return type with any `@returns` descriptions. */
|
|
239
|
-
function _getReturns(statement, source, jsDocReturns) {
|
|
291
|
+
function _getReturns(statement, source, jsDocReturns, name) {
|
|
292
|
+
if (ts.isClassDeclaration(statement)) {
|
|
293
|
+
// A constructor returns an instance of the class, including its generics (e.g. `ChoiceSchema<T>`).
|
|
294
|
+
const type = `${name}${_getTypeParamNames(statement, source)}`;
|
|
295
|
+
return [{ type, description: jsDocReturns?.[0]?.description }];
|
|
296
|
+
}
|
|
240
297
|
if (!ts.isFunctionDeclaration(statement))
|
|
241
298
|
return jsDocReturns;
|
|
242
299
|
const type = statement.type?.getText(source);
|