Skip to content

Commit 07d9168

Browse files
authored
docs(cypress-commands): replace typedoc (#6732)
1 parent ca4511e commit 07d9168

File tree

10 files changed

+1620
-411
lines changed

10 files changed

+1620
-411
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ lerna-debug.log
2020
!.yarn/sdks
2121
!.yarn/versions
2222

23-
packages/cypress-commands/api.json
23+
packages/cypress-commands/api-commands.json
24+
packages/cypress-commands/api-queries.json
2425

2526
packages/main/scripts/wrapperGeneration/json
2627
packages/main/tmp
Lines changed: 211 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,171 +1,256 @@
11
import { Heading, Markdown } from '@storybook/blocks';
2+
import dedent from 'dedent';
23
import { Fragment } from 'react';
34

4-
interface CommandsAndQueries {
5-
id: number;
6-
name: string;
7-
kind: number;
8-
kindString: string;
9-
flags: CommandsAndQueriesFlags;
10-
sources: Source[];
11-
signatures: Signature[];
5+
// Note: these types may be incomplete or faulty. If an error is thrown, first check if the interfaces have to be extended.
6+
interface TextNode {
7+
type: 'text';
8+
value: string;
129
}
1310

14-
// eslint-disable-next-line @typescript-eslint/no-empty-interface
15-
interface CommandsAndQueriesFlags {}
11+
interface StrongNode {
12+
type: 'strong';
13+
children: TextNode[];
14+
}
1615

17-
interface Signature {
18-
id: number;
19-
name: string;
20-
kind: number;
21-
kindString: string;
22-
flags: CommandsAndQueriesFlags;
23-
comment: SignatureComment;
24-
parameters: Parameter[];
25-
type: Type;
16+
interface InlineCodeNode {
17+
type: 'inlineCode';
18+
value: string;
2619
}
2720

28-
interface SignatureComment {
29-
summary: Summary[];
30-
blockTags: BlockTag[];
21+
interface ParagraphNode {
22+
type: 'paragraph';
23+
children: Array<TextNode | StrongNode | InlineCodeNode>;
3124
}
3225

33-
interface BlockTag {
34-
tag: string;
35-
content: Summary[];
26+
interface RootNode {
27+
type: 'root';
28+
children: ParagraphNode[];
3629
}
3730

38-
interface Summary {
39-
kind: string;
40-
text: string;
31+
interface TypeExpression {
32+
type: 'NameExpression' | 'OptionalType' | 'TypeApplication';
33+
name?: string;
34+
expression?: TypeExpression;
35+
applications?: TypeExpression[];
4136
}
4237

43-
interface Parameter {
44-
id: number;
38+
interface Tag {
39+
title: string;
40+
description?: string | RootNode;
41+
lineNumber: number;
42+
type?: TypeExpression;
43+
name?: string;
44+
default?: string;
45+
}
46+
47+
interface Loc {
48+
start: {
49+
line: number;
50+
column: number;
51+
index: number;
52+
};
53+
end: {
54+
line: number;
55+
column: number;
56+
index: number;
57+
};
58+
}
59+
60+
interface Context {
61+
loc: Loc;
62+
file: string;
63+
}
64+
65+
interface Example {
66+
description: string;
67+
}
68+
69+
interface Param {
70+
title: string;
4571
name: string;
46-
kind: number;
47-
kindString: string;
48-
flags: ParameterFlags;
49-
comment?: ParameterComment;
50-
type: Type;
72+
lineNumber: number;
73+
description: RootNode;
74+
type: TypeExpression;
75+
default?: string;
76+
}
77+
78+
interface Return {
79+
title: string;
80+
type: TypeExpression;
5181
}
5282

53-
interface ParameterComment {
54-
summary: Summary[];
83+
interface Path {
84+
name: string;
85+
kind: string;
86+
scope: string;
5587
}
5688

57-
interface ParameterFlags {
58-
isOptional?: boolean;
89+
interface Members {
90+
global: any[];
91+
inner: any[];
92+
instance: any[];
93+
events: any[];
94+
static: any[];
5995
}
6096

61-
interface Type {
62-
type: string;
97+
interface FunctionMetadata {
98+
description: RootNode;
99+
tags: Tag[];
100+
loc: Loc;
101+
context: Context;
102+
augments: any[];
103+
examples: Example[];
104+
implements: any[];
105+
params: Param[];
106+
properties: any[];
107+
returns: Return[];
108+
sees: any[];
109+
throws: any[];
110+
todos: any[];
111+
yields: any[];
63112
name: string;
64-
typeArguments?: Type[];
65-
qualifiedName?: string;
66-
package?: string;
113+
kind: 'function';
114+
memberof: string;
115+
scope: 'instance';
116+
members: Members;
117+
path: Path[];
118+
namespace: string;
67119
}
68120

69-
interface Source {
70-
fileName: string;
71-
line: number;
72-
character: number;
73-
url: string;
121+
function generateMdCodeBlock(codeStr: string) {
122+
return dedent`
123+
\`\`\`ts
124+
${codeStr}
125+
\`\`\`
126+
127+
`;
74128
}
75129

76-
function typeArgumentsString(typeArguments: Type[] | undefined) {
77-
if (!typeArguments) {
78-
return '';
79-
}
80-
return typeArguments.map((args, index, arr) => {
81-
let str = args.name;
82-
if (arr.length > 1 && index + 1 !== arr.length) {
83-
str += ', ';
130+
function generateGenericType(typeExpression: TypeExpression) {
131+
if (typeExpression) {
132+
const { expression, applications } = typeExpression;
133+
134+
if (typeof typeExpression?.name === 'string') {
135+
return typeExpression.name;
84136
}
85-
return str;
86-
});
137+
return `${expression.name}<${applications
138+
?.map((app) => {
139+
return app.name;
140+
})
141+
.join(', ')}>`;
142+
}
143+
return '';
144+
}
145+
146+
function generateParamTypes(type: Param['type']) {
147+
if (type?.name) {
148+
return type.name;
149+
}
150+
return generateGenericType(type.expression);
87151
}
88152

89-
export const CommandsAndQueries = ({ api }: { api: CommandsAndQueries[] }) => {
90-
return api.map((item) => {
91-
const { signatures } = item;
92-
const { parameters } = signatures[0];
153+
function generateExample(tags: FunctionMetadata['tags']) {
154+
const example = tags.find((tag) => tag.title === 'example');
155+
if (example && typeof example.description === 'string') {
93156
return (
94-
<Fragment key={item.name}>
95-
<Heading>{item.name}</Heading>
96-
<code>
97-
{item.name}(
98-
{parameters
99-
?.map(
100-
(param) =>
101-
`${param.name}:${param.type.name}${
102-
param.type?.typeArguments?.length ? `<${typeArgumentsString(param.type.typeArguments)}>` : ''
103-
}`
104-
)
105-
.join(', ')}
106-
):
107-
{signatures[0]?.type?.name}
108-
{`<${typeArgumentsString(signatures[0].type?.typeArguments)}>`}
109-
</code>
110-
<div>
111-
<Markdown>
112-
{signatures[0]?.comment.summary.reduce((acc, cur) => `${acc}${cur.text.replaceAll('\n', '<br>')}`, '')}
113-
</Markdown>
114-
{signatures[0]?.comment?.blockTags
115-
?.filter((blockTag) => {
116-
return blockTag.tag === '@example';
117-
})
118-
.map((example, index) => {
119-
return (
120-
<Fragment key={`${example.tag}${index}`}>
121-
{index === 0 && <b>Example</b>}
122-
<Markdown>{example.content.reduce((acc, cur) => `${acc}${cur.text}`, '')}</Markdown>
123-
</Fragment>
124-
);
157+
<>
158+
<Markdown>### Example</Markdown>
159+
<Markdown>{generateMdCodeBlock(example.description)}</Markdown>
160+
</>
161+
);
162+
}
163+
return null;
164+
}
165+
166+
function formatText(text: ParagraphNode['children'][0]) {
167+
switch (text.type) {
168+
case 'text':
169+
return text.value;
170+
case 'strong':
171+
return `**${text.children.reduce((acc, cur) => {
172+
acc += cur.value;
173+
return acc;
174+
}, '')}**`;
175+
case 'inlineCode':
176+
return `\`${text.value}\``;
177+
default:
178+
if (typeof text.value === 'string') {
179+
return text.value;
180+
}
181+
console.warn('Unknown text type!');
182+
return '';
183+
}
184+
}
185+
186+
function generateDescription(description: RootNode) {
187+
return description.children.reduce((acc, descriptionNode) => {
188+
if (descriptionNode.type === 'paragraph') {
189+
acc += descriptionNode.children.reduce((acc, p) => {
190+
acc += formatText(p);
191+
return acc;
192+
}, '');
193+
acc += '\n\n';
194+
return acc;
195+
}
196+
}, '');
197+
}
198+
199+
export const CommandsAndQueries = ({ api }: { api: FunctionMetadata[] }) => {
200+
return api
201+
.sort((a, b) => a.name.localeCompare(b.name))
202+
.map((item) => {
203+
return (
204+
<Fragment key={item.name}>
205+
<Heading>{item.name}</Heading>
206+
<code>
207+
{item.name}(
208+
{item.params
209+
?.map((param) => {
210+
return `${param.name}${param.type.type === 'OptionalType' ? '?' : ''}:${generateParamTypes(param.type)}`;
211+
})
212+
.join(', ')}
213+
):
214+
{item.returns.map(({ type }) => {
215+
return generateGenericType(type);
125216
})}
126-
{parameters?.length && (
217+
</code>
218+
<Markdown>{generateDescription(item.description)}</Markdown>
219+
{generateExample(item.tags)}
220+
{!!item.params.length && (
127221
<>
128-
<b>Parameters</b>
222+
<Markdown>### Parameters</Markdown>
129223
<table>
130224
<thead>
131225
<tr>
132-
<td>Name</td>
133-
<td>Type</td>
134-
<td>Description</td>
226+
<td>
227+
<b>Name</b>
228+
</td>
229+
<td>
230+
<b>Type</b>
231+
</td>
232+
<td>
233+
<b>Description</b>
234+
</td>
135235
</tr>
136236
</thead>
137237
<tbody>
138-
{parameters?.map((param) => (
139-
<tr key={param.name}>
140-
<td>
141-
{param.name}
142-
{param.flags?.isOptional && '?'}
143-
</td>
144-
<td>
145-
<code>
146-
{param.type?.name}
147-
{param.type?.typeArguments &&
148-
`<${param.type?.typeArguments && typeArgumentsString(param.type.typeArguments)}>`}
149-
</code>
150-
</td>
151-
<td>
152-
{param.comment?.summary.reduce((acc, cur) => `${acc}${cur.text.replaceAll('\n', '<br>')}`, '')}
153-
</td>
154-
</tr>
155-
))}
238+
{item.params.map((param) => {
239+
return (
240+
<tr key={param.name}>
241+
<td>{param.type.type === 'OptionalType' ? <i>{param.name}?</i> : param.name}</td>
242+
<td>{generateParamTypes(param.type)}</td>
243+
<td>{param?.description ? generateDescription(param.description) : '-'}</td>
244+
</tr>
245+
);
246+
})}
156247
</tbody>
157248
</table>
158249
</>
159250
)}
160-
<p>
161-
<b>Source:</b> <a href={item.sources[0].url}>{`${item.sources[0].fileName}:${item.sources[0].line}`}</a>
162-
</p>
163-
</div>
164-
<br />
165-
<br />
166-
</Fragment>
167-
);
168-
});
251+
</Fragment>
252+
);
253+
});
169254
};
170255

171256
CommandsAndQueries.displayName = 'CommandsAndQueries';

0 commit comments

Comments
 (0)