Skip to content

Commit 35e6f58

Browse files
committed
code review (1)
1 parent 3a4b27b commit 35e6f58

File tree

7 files changed

+102
-89
lines changed

7 files changed

+102
-89
lines changed

src/generators/legacy-json-all/index.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import { writeFile } from 'node:fs/promises';
44
import { join } from 'node:path';
55

66
/**
7+
* This generator consolidates data from the `legacy-json` generator into a single
8+
* JSON file (`all.json`).
9+
*
710
* @typedef {Array<import('../legacy-json/types.d.ts').Section>} Input
811
*
912
* @type {import('../types.d.ts').GeneratorMetadata<Input, import('./types.d.ts').Output>}
@@ -20,6 +23,9 @@ export default {
2023

2124
async generate(input, { output }) {
2225
/**
26+
* The consolidated output object that will contain
27+
* combined data from all sections in the input.
28+
*
2329
* @type {import('./types.d.ts').Output}
2430
*/
2531
const generatedValue = {

src/generators/legacy-json/utils/buildSection.mjs

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ function parseListItem(child, entry) {
134134

135135
// Recursively parse nested options if a list is found within the list item
136136
const optionsNode = child.children.find(child => child.type === 'list');
137+
137138
if (optionsNode) {
138139
current.options = optionsNode.children.map(child =>
139140
parseListItem(child, entry)
@@ -175,6 +176,7 @@ function parseStability(section, nodes) {
175176
*/
176177
function parseList(section, nodes, entry) {
177178
const list = nodes[0]?.type === 'list' ? nodes.shift() : null;
179+
178180
const values = list
179181
? list.children.map(child => parseListItem(child, entry))
180182
: [];
@@ -188,7 +190,8 @@ function parseList(section, nodes, entry) {
188190
case 'property':
189191
if (values.length) {
190192
const { type, ...rest } = values[0];
191-
if (type) section.propertySigType = type;
193+
194+
section.type = type;
192195
Object.assign(section, rest);
193196
section.textRaw = `\`${section.name}\` ${section.textRaw}`;
194197
}
@@ -197,26 +200,35 @@ function parseList(section, nodes, entry) {
197200
section.params = values;
198201
break;
199202
default:
200-
if (list) nodes.unshift(list); // If the list wasn't processed, add it back for further processing
203+
// If the list wasn't processed, add it back for further processing
204+
if (list) {
205+
nodes.unshift(list);
206+
}
201207
}
202208
}
203209

210+
let lazyHTML;
211+
204212
/**
205213
* Adds a description to the section.
206214
* @param {import('../types.d.ts').Section} section - The section to add description to.
207215
* @param {Array} nodes - The AST nodes.
208216
*/
209217
function addDescription(section, nodes) {
210-
if (!nodes.length) return;
218+
if (!nodes.length) {
219+
return;
220+
}
211221

212222
if (section.desc) {
213223
section.shortDesc = section.desc;
214224
}
215225

216-
const html = getRemarkRehype();
217-
const rendered = html.stringify(
218-
html.runSync({ type: 'root', children: nodes })
226+
lazyHTML ??= getRemarkRehype();
227+
228+
const rendered = lazyHTML.stringify(
229+
lazyHTML.runSync({ type: 'root', children: nodes })
219230
);
231+
220232
section.desc = rendered || undefined;
221233
}
222234

@@ -241,32 +253,38 @@ function addAdditionalMetadata(section, parentSection, headingNode) {
241253
*/
242254
function addToParent(section, parentSection) {
243255
const pluralType = sectionTypePlurals[section.type];
256+
244257
parentSection[pluralType] = parentSection[pluralType] || [];
245258
parentSection[pluralType].push(section);
246259
}
247260

261+
const notTransferredKeys = ['textRaw', 'name', 'type', 'desc', 'miscs'];
262+
248263
/**
249-
* Promotes children to top-level if the section type is 'misc'.
264+
* Promotes children properties to the parent level if the section type is 'misc'.
265+
*
250266
* @param {import('../types.d.ts').Section} section - The section to promote.
251267
* @param {import('../types.d.ts').Section} parentSection - The parent section.
252268
*/
253269
const makeChildrenTopLevelIfMisc = (section, parentSection) => {
254-
if (section.type !== 'misc' || parentSection.type === 'misc') {
255-
return;
270+
// Only promote if the current section is of type 'misc' and the parent is not 'misc'
271+
if (section.type === 'misc' && parentSection.type !== 'misc') {
272+
Object.entries(section).forEach(([key, value]) => {
273+
// Skip keys that should not be transferred
274+
if (notTransferredKeys.includes(key)) return;
275+
276+
// Merge the section's properties into the parent section
277+
parentSection[key] = parentSection[key]
278+
? // If the parent already has this key, concatenate the values
279+
[].concat(parentSection[key], value)
280+
: // Otherwise, directly assign the section's value to the parent
281+
value;
282+
});
256283
}
284+
};
257285

258-
Object.keys(section).forEach(key => {
259-
if (['textRaw', 'name', 'type', 'desc', 'miscs'].includes(key)) {
260-
return;
261-
}
262-
if (parentSection[key]) {
263-
parentSection[key] = Array.isArray(parentSection[key])
264-
? parentSection[key].concat(section[key])
265-
: section[key];
266-
} else {
267-
parentSection[key] = section[key];
268-
}
269-
});
286+
const handleChildren = (entry, section) => {
287+
entry.hierarchyChildren?.forEach(child => handleEntry(child, section));
270288
};
271289

272290
/**
@@ -281,19 +299,10 @@ function handleEntry(entry, parentSection) {
281299
parseStability(section, nodes);
282300
parseList(section, nodes, entry);
283301
addDescription(section, nodes);
284-
entry.hierarchyChildren?.forEach(child => handleEntry(child, section));
302+
handleChildren(entry, section);
285303
addAdditionalMetadata(section, parentSection, headingNode);
286304
addToParent(section, parentSection);
287305
makeChildrenTopLevelIfMisc(section, parentSection);
288-
289-
if (section.type === 'property') {
290-
if (section.propertySigType) {
291-
section.type = section.propertySigType;
292-
delete section.propertySigType;
293-
} else {
294-
delete section.type;
295-
}
296-
}
297306
}
298307

299308
/**

src/generators/legacy-json/utils/parseSignature.mjs

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import { PARAM_EXPRESSION } from '../constants.mjs';
44

55
const OPTIONAL_LEVEL_CHANGES = { '[': 1, ']': -1, ' ': 0 };
66

7+
/**
8+
* @param {String} char
9+
* @param {Number} depth
10+
* @returns {Number}
11+
*/
12+
const updateDepth = (char, depth) =>
13+
depth + (OPTIONAL_LEVEL_CHANGES[char] || 0);
14+
715
/**
816
* @param {string} parameterName
917
* @param {number} optionalDepth
@@ -14,36 +22,34 @@ function parseNameAndOptionalStatus(parameterName, optionalDepth) {
1422
// We need to see if there's any leading brackets in front of the parameter
1523
// name. While we're doing that, we can also get the index where the
1624
// parameter's name actually starts at.
17-
let startingIdx = 0;
18-
for (; startingIdx < parameterName.length; startingIdx++) {
19-
const levelChange = OPTIONAL_LEVEL_CHANGES[parameterName[startingIdx]];
20-
21-
if (!levelChange) {
22-
break;
23-
}
24-
25-
optionalDepth += levelChange;
26-
}
2725

26+
// Find the starting index where the name begins
27+
const startingIdx = [...parameterName].findIndex(
28+
char => !OPTIONAL_LEVEL_CHANGES[char]
29+
);
30+
31+
// Update optionalDepth based on leading brackets
32+
optionalDepth = [...parameterName.slice(0, startingIdx)].reduce(
33+
updateDepth,
34+
optionalDepth
35+
);
36+
37+
// Find the ending index where the name ends
38+
const endingIdx = [...parameterName].findLastIndex(
39+
char => !OPTIONAL_LEVEL_CHANGES[char]
40+
);
41+
42+
// Update optionalDepth based on trailing brackets
43+
optionalDepth = [...parameterName.slice(endingIdx + 1)].reduce(
44+
updateDepth,
45+
optionalDepth
46+
);
47+
48+
// Extract the actual parameter name
49+
const actualName = parameterName.slice(startingIdx, endingIdx + 1);
2850
const isParameterOptional = optionalDepth > 0;
2951

30-
// Now let's check for any trailing brackets at the end of the parameter's
31-
// name. This will tell us where the parameter's name ends.
32-
let endingIdx = parameterName.length - 1;
33-
for (; endingIdx >= 0; endingIdx--) {
34-
const levelChange = OPTIONAL_LEVEL_CHANGES[parameterName[endingIdx]];
35-
if (!levelChange) {
36-
break;
37-
}
38-
39-
optionalDepth += levelChange;
40-
}
41-
42-
return [
43-
parameterName.substring(startingIdx, endingIdx + 1),
44-
optionalDepth,
45-
isParameterOptional,
46-
];
52+
return [actualName, optionalDepth, isParameterOptional];
4753
}
4854

4955
/**
@@ -55,8 +61,8 @@ function parseDefaultValue(parameterName) {
5561
* @type {string | undefined}
5662
*/
5763
let defaultValue;
58-
5964
const equalSignPos = parameterName.indexOf('=');
65+
6066
if (equalSignPos !== -1) {
6167
// We do have a default value, let's extract it
6268
defaultValue = parameterName.substring(equalSignPos).trim();
@@ -75,34 +81,29 @@ function parseDefaultValue(parameterName) {
7581
* @returns {import('../types.d.ts').Parameter}
7682
*/
7783
function findParameter(parameterName, index, markdownParameters) {
78-
let parameter = markdownParameters[index];
79-
if (parameter && parameter.name === parameterName) {
84+
const parameter = markdownParameters[index];
85+
if (parameter?.name === parameterName) {
8086
return parameter;
8187
}
8288

8389
// Method likely has multiple signatures, something like
8490
// `new Console(stdout[, stderr][, ignoreErrors])` and `new Console(options)`
8591
// Try to find the parameter that this is being shared with
86-
for (const markdownProperty of markdownParameters) {
87-
if (markdownProperty.name === parameterName) {
88-
// Found it
89-
return markdownParameters;
90-
} else if (markdownProperty.options) {
91-
for (const option of markdownProperty.options) {
92-
if (option.name === parameterName) {
93-
// Found a matching one in the parameter's options
94-
return Object.assign({}, option);
95-
}
96-
}
92+
for (const property of markdownParameters) {
93+
if (property.name === parameterName) {
94+
return property;
9795
}
98-
}
9996

100-
// At this point, we couldn't find a shared signature
101-
if (parameterName.startsWith('...')) {
102-
return { name: parameterName };
103-
} else {
104-
throw new Error(`Invalid param "${parameterName}"`);
97+
const matchingOption = property.options?.find(
98+
option => option.name === parameterName
99+
);
100+
if (matchingOption) {
101+
return { ...matchingOption };
102+
}
105103
}
104+
105+
// Default return if no matches are found
106+
return { name: parameterName };
106107
}
107108

108109
/**

src/metadata.mjs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,8 @@ const createMetadata = slugger => {
138138
internalMetadata.stability.toJSON = () =>
139139
internalMetadata.stability.children.map(node => node.data);
140140

141-
/**
142-
* @type {ApiDocMetadataEntry}
143-
*/
144-
const value = {
141+
// Returns the Metadata entry for the API doc
142+
return {
145143
api: apiDoc.stem,
146144
slug: sectionSlug,
147145
source_link,
@@ -156,15 +154,9 @@ const createMetadata = slugger => {
156154
stability: internalMetadata.stability,
157155
content: section,
158156
tags,
157+
introduced_in,
159158
rawContent: apiDoc.toString(),
160159
};
161-
162-
if (introduced_in) {
163-
value.introduced_in = introduced_in;
164-
}
165-
166-
// Returns the Metadata entry for the API doc
167-
return value;
168160
},
169161
};
170162
};

src/queries.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ const createQueries = () => {
8181
transformTypeToReferenceLink
8282
);
8383

84+
// This changes the type into a link by splitting it up
85+
// into several nodes, and adding those nodes to the
86+
// parent.
8487
const {
8588
children: [newNode],
8689
} = remark.parse(replacedTypes);

src/test/metadata.test.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ describe('createMetadata', () => {
7272
deprecated_in: undefined,
7373
heading,
7474
n_api_version: undefined,
75+
introduced_in: undefined,
7576
rawContent: '',
7677
removed_in: undefined,
7778
slug: 'test-heading',

src/utils/parser.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export const parseHeadingIntoMetadata = (heading, depth) => {
129129
return {
130130
text: heading,
131131
type,
132+
// The highest match group should be used.
132133
name: matches.filter(Boolean).at(-1),
133134
depth,
134135
};

0 commit comments

Comments
 (0)