reffy 7.2.10 → 8.0.2

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.
@@ -1,36 +1,31 @@
1
- #!/usr/bin/env node
2
1
  /**
3
- * The IDL names generator takes a crawl report as input and creates a report
4
- * per referenceable IDL name, that details the complete parsed IDL structure
5
- * that defines the name across all specs.
2
+ * Post-processing module that creates an index of IDL names and a list of
3
+ * IDL extracts per IDL name.
6
4
  *
7
- * The spec checker can be called directly through:
8
- *
9
- * `node generate-idlnames.js [crawl report] [dfns] [save folder]`
10
- *
11
- * where `crawl report` is the path to the folder that contains the
12
- * `index.json` file and all other crawl results produced by specs-crawler.js,
13
- * `dfns` a param to set to "true" or "dfns" to embed dfns in the generated
14
- * report, and `save folder` is an optional folder (which must exist) where IDL
15
- * name extracts are to be saved. In the absence of this parameter, the report
16
- * is written to the console.
17
- *
18
- * When a folder is provided, the IDL name extracts are saved as a JSON
19
- * structure in an "idlnamesparsed" subfolder, and as IDL fragments in an
20
- * "idlnames" folder.
21
- *
22
- * @module checker
5
+ * The module runs at the crawl level. It depends on another post-processing
6
+ * module, namely the "idlparsed" one, which runs at the spec level (so no need
7
+ * to worry about ordering, "idlparsed" will always run before this one).
23
8
  */
24
9
 
25
10
  const fs = require('fs');
26
11
  const path = require('path');
27
- const { matchIdlDfn, getExpectedDfnFromIdlDesc } = require('./check-missing-dfns');
28
12
  const {
29
- expandCrawlResult,
13
+ matchIdlDfn,
14
+ getExpectedDfnFromIdlDesc } = require('../cli/check-missing-dfns');
15
+ const {
30
16
  isLatestLevelThatPasses,
31
- requireFromWorkingDirectory,
32
- createFolderIfNeeded
33
- } = require('../lib/util');
17
+ createFolderIfNeeded } = require('../lib/util');
18
+
19
+
20
+ /**
21
+ * Definition of the post-processing module
22
+ */
23
+ module.exports = {
24
+ dependsOn: ['idlparsed', 'dfns'],
25
+ input: 'crawl',
26
+ run: generateIdlNames,
27
+ save: saveIdlNames
28
+ };
34
29
 
35
30
 
36
31
  /**
@@ -92,12 +87,83 @@ function getRelatedDfns(desc, idlNode, results) {
92
87
  }
93
88
 
94
89
 
90
+ /**
91
+ * Save IDL names to individual JSON files in the given folder
92
+ *
93
+ * @function
94
+ * @private
95
+ * @param {Object} names Report generated by generateIdlNames
96
+ * @param {String} folder Path to folder
97
+ */
98
+ async function saveParsedIdlNames(names, folder) {
99
+ await createFolderIfNeeded(folder);
100
+ await Promise.all(Object.entries(names).map(([name, idl]) => {
101
+ const json = JSON.stringify(idl, null, 2);
102
+ const filename = path.join(folder, name + '.json');
103
+ return fs.promises.writeFile(filename, json);
104
+ }));
105
+ }
106
+
107
+
108
+
109
+ /**
110
+ * Save IDL fragments to individual text files in the given folder
111
+ *
112
+ * @function
113
+ * @private
114
+ * @param {Object} names Report generated by generateIdlNames
115
+ * @param {String} folder Path to folder
116
+ */
117
+ async function saveIdlNamesFragments(names, folder) {
118
+ function serializeNode(node) {
119
+ return `// Source: ${node.spec.title} (${node.spec.url})\n` +
120
+ node.fragment;
121
+ }
122
+
123
+ await createFolderIfNeeded(folder);
124
+ await Promise.all(Object.entries(names).map(([name, idl]) => {
125
+ const res = [];
126
+ if (idl.defined) {
127
+ res.push(serializeNode(idl.defined));
128
+ }
129
+ if (idl.extended) {
130
+ idl.extended.map(node => res.push(serializeNode(node)));
131
+ }
132
+ const filename = path.join(folder, name + '.idl');
133
+ return fs.promises.writeFile(filename, res.join('\n\n'));
134
+ }));
135
+ }
136
+
137
+
138
+ /**
139
+ * Generate an `idlnames.json` index file that contains all IDL names with
140
+ * pointers to files in idlnames and idlnamesparsed subfolder.
141
+ *
142
+ * @function
143
+ * @private
144
+ * @param {Object} names Report generated by generateIdlNames
145
+ * @param {String} folder Path to folder where index file is to be saved
146
+ */
147
+ async function saveIndex(names, folder) {
148
+ await createFolderIfNeeded(folder);
149
+ let index = {};
150
+ Object.keys(names).sort().forEach(name => {
151
+ index[name] = {
152
+ fragment: `idlnames/${name}.idl`,
153
+ parsed: `idlnamesparsed/${name}.json`
154
+ };
155
+ });
156
+ const filename = path.join(folder, 'idlnames.json');
157
+ return fs.promises.writeFile(filename, JSON.stringify(index, null, 2));
158
+ }
159
+
160
+
95
161
  /**
96
162
  * Generate a report per referenceable IDL name from the given crawl results.
97
163
  *
98
164
  * @function
99
165
  * @public
100
- * @param {Array} results The list of spec crawl results to process
166
+ * @param {Object} crawl Crawl results
101
167
  * @param {Object} options Generation options. Set "dfns" to true to embed
102
168
  * definitions in the final export.
103
169
  * @return {Object} A list indexed by referenceable IDL name that details, for
@@ -105,7 +171,7 @@ function getRelatedDfns(desc, idlNode, results) {
105
171
  * along with links to the actual definition of the terms in the specs
106
172
  * (when known).
107
173
  */
108
- function generateIdlNames(results, options = {}) {
174
+ async function generateIdlNames(crawl, options) {
109
175
  function specInfo(spec) {
110
176
  return {
111
177
  spec: {
@@ -123,8 +189,8 @@ function generateIdlNames(results, options = {}) {
123
189
  }
124
190
 
125
191
  // Only keep latest version of specs and delta specs that define some IDL
126
- results = results.filter(spec =>
127
- (spec.seriesComposition !== 'delta' && isLatestLevelThatPasses(spec, results, defineIDLContent)) ||
192
+ const results = crawl.results.filter(spec =>
193
+ (spec.seriesComposition !== 'delta' && isLatestLevelThatPasses(spec, crawl.results, defineIDLContent)) ||
128
194
  (spec.seriesComposition === 'delta' && defineIDLContent(spec)));
129
195
 
130
196
  // Add main definitions of all IDL names
@@ -302,84 +368,6 @@ function generateIdlNames(results, options = {}) {
302
368
  }
303
369
 
304
370
 
305
- async function generateIdlNamesFromPath(crawlPath, options = {}) {
306
- const crawlIndex = requireFromWorkingDirectory(path.resolve(crawlPath, 'index.json'));
307
- const crawlResults = await expandCrawlResult(crawlIndex, crawlPath, ['idlparsed', 'dfns']);
308
- return generateIdlNames(crawlResults.results, options);
309
- }
310
-
311
-
312
- /**
313
- * Save IDL names to individual JSON files in the given folder
314
- *
315
- * @function
316
- * @private
317
- * @param {Object} names Report generated by generateIdlNames
318
- * @param {String} folder Path to folder
319
- */
320
- async function saveParsedIdlNames(names, folder) {
321
- await createFolderIfNeeded(folder);
322
- await Promise.all(Object.entries(names).map(([name, idl]) => {
323
- const json = JSON.stringify(idl, null, 2);
324
- const filename = path.join(folder, name + '.json');
325
- return fs.promises.writeFile(filename, json);
326
- }));
327
- }
328
-
329
-
330
-
331
- /**
332
- * Save IDL fragments to individual text files in the given folder
333
- *
334
- * @function
335
- * @private
336
- * @param {Object} names Report generated by generateIdlNames
337
- * @param {String} folder Path to folder
338
- */
339
- async function saveIdlNamesFragments(names, folder) {
340
- function serializeNode(node) {
341
- return `// Source: ${node.spec.title} (${node.spec.url})\n` +
342
- node.fragment;
343
- }
344
-
345
- await createFolderIfNeeded(folder);
346
- await Promise.all(Object.entries(names).map(([name, idl]) => {
347
- const res = [];
348
- if (idl.defined) {
349
- res.push(serializeNode(idl.defined));
350
- }
351
- if (idl.extended) {
352
- idl.extended.map(node => res.push(serializeNode(node)));
353
- }
354
- const filename = path.join(folder, name + '.idl');
355
- return fs.promises.writeFile(filename, res.join('\n\n'));
356
- }));
357
- }
358
-
359
-
360
- /**
361
- * Generate an `idlnames.json` index file that contains all IDL names with
362
- * pointers to files in idlnames and idlnamesparsed subfolder.
363
- *
364
- * @function
365
- * @private
366
- * @param {Object} names Report generated by generateIdlNames
367
- * @param {String} folder Path to folder where index file is to be saved
368
- */
369
- async function saveIndex(names, folder) {
370
- await createFolderIfNeeded(folder);
371
- let index = {};
372
- Object.keys(names).sort().forEach(name => {
373
- index[name] = {
374
- fragment: `idlnames/${name}.idl`,
375
- parsed: `idlnamesparsed/${name}.json`
376
- };
377
- });
378
- const filename = path.join(folder, 'idlnames.json');
379
- return fs.promises.writeFile(filename, JSON.stringify(index, null, 2));
380
- }
381
-
382
-
383
371
  /**
384
372
  * Generate all IDL names exports: IDL fragments in `idlnames`, parsed
385
373
  * structures in `idlnamesparsed`, and index file.
@@ -387,44 +375,15 @@ async function saveIndex(names, folder) {
387
375
  * @function
388
376
  * @public
389
377
  * @param {Object} names Report generated by generateIdlNames
390
- * @param {String} folder Path to folder where index file is to be saved
378
+ * @param {Object} options Crawl options ("output" will be used)
391
379
  */
392
- async function saveIdlNames(names, folder) {
380
+ async function saveIdlNames(names, options) {
381
+ if (!options?.output) {
382
+ return;
383
+ }
384
+
385
+ const folder = options.output;
393
386
  await saveParsedIdlNames(names, path.join(folder, 'idlnamesparsed'));
394
387
  await saveIdlNamesFragments(names, path.join(folder, 'idlnames'));
395
388
  await saveIndex(names, folder);
396
389
  }
397
-
398
-
399
-
400
-
401
-
402
- /**************************************************
403
- Export methods for use as module
404
- **************************************************/
405
- module.exports.generateIdlNames = generateIdlNames;
406
- module.exports.saveIdlNames = saveIdlNames;
407
-
408
-
409
- /**************************************************
410
- Code run if the code is run as a stand-alone module
411
- **************************************************/
412
- if (require.main === module) {
413
- const crawlPath = process.argv[2];
414
- if (!crawlPath) {
415
- console.error('Required path to crawl results folder is missing');
416
- process.exit(2);
417
- }
418
-
419
- const dfns = process.argv[3] === 'dfns' || process.argv[3] === 'true';
420
- const savePath = process.argv[4];
421
- generateIdlNamesFromPath(crawlPath, { dfns })
422
- .then(report => {
423
- if (savePath) {
424
- return saveIdlNames(report, savePath);
425
- }
426
- else {
427
- console.log(JSON.stringify(report, null, 2));
428
- }
429
- });
430
- }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Post-processing module that creates a parsed IDL structure out of the IDL
3
+ * extract.
4
+ *
5
+ * The module runs at the spec level and generates an `idlparsed` property.
6
+ */
7
+
8
+ const webidlParser = require('../cli/parse-webidl');
9
+
10
+ module.exports = {
11
+ dependsOn: ['idl'],
12
+ input: 'spec',
13
+ property: 'idlparsed',
14
+
15
+ run: async function(spec, options) {
16
+ if (!spec?.idl) {
17
+ return spec;
18
+ }
19
+ try {
20
+ spec.idlparsed = await webidlParser.parse(spec.idl);
21
+ spec.idlparsed.hasObsoleteIdl = webidlParser.hasObsoleteIdl(spec.idl);
22
+ }
23
+ catch (err) {
24
+ // IDL content is invalid and cannot be parsed.
25
+ // Let's return the error, along with the raw IDL
26
+ // content so that it may be saved to a file.
27
+ spec.idlparsed = err.toString();
28
+ }
29
+ return spec;
30
+ }
31
+ };
@@ -1,139 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * The parsed IDL generator takes a crawl report or a single spec as input, and
4
- * generates (or re-generates if it already exists) a parsed IDL structure from
5
- * the raw IDL that the spec defines. Result is dumped to the console or saved
6
- * to the given folder.
7
- *
8
- * The parsed IDL generator is used by the crawler to create and save the parsed
9
- * IDL structures. It is also useful to re-generated the parsed IDL info when
10
- * an IDL patch has been applied to the raw IDL.
11
- *
12
- * The parsed IDL generator can be called directly through:
13
- *
14
- * `node generate-idlparsed.js [crawl report] [save folder]`
15
- *
16
- * where `crawl report` is the path to the folder that contains the
17
- * `index.json` file and all other crawl results produced by specs-crawler.js,
18
- * and `save folder` is an optional folder (which must exist) where IDL
19
- * name extracts are to be saved. In the absence of this parameter, the report
20
- * is written to the console.
21
- *
22
- * When a folder is provided, the IDL name extracts are saved as a JSON
23
- * structure in an `idlparsed` subfolder.
24
- */
25
-
26
- const fs = require('fs');
27
- const path = require('path');
28
- const webidlParser = require('../cli/parse-webidl');
29
- const {
30
- expandCrawlResult,
31
- requireFromWorkingDirectory,
32
- createFolderIfNeeded
33
- } = require('../lib/util');
34
-
35
-
36
- /**
37
- * Update the spec object in place with parsed IDL information.
38
- *
39
- * @function
40
- * @public
41
- * @param {Object} spec The spec object to update. The function looks for the
42
- * raw IDL in the `idl` property.
43
- * @return {Object} The updated spec with an `idl` property that contains the
44
- * parsed version of the IDL, and the raw IDL moved under the `idl.idl`
45
- * sub-property. Note the spec object is updated in place.
46
- */
47
- async function generateIdlParsed(spec) {
48
- if (!spec?.idl) {
49
- return spec;
50
- }
51
- try {
52
- spec.idlparsed = await webidlParser.parse(spec.idl);
53
- spec.idlparsed.hasObsoleteIdl = webidlParser.hasObsoleteIdl(spec.idl);
54
- }
55
- catch (err) {
56
- // IDL content is invalid and cannot be parsed.
57
- // Let's return the error, along with the raw IDL
58
- // content so that it may be saved to a file.
59
- spec.idlparsed = err.toString();
60
- }
61
- return spec;
62
- }
63
-
64
-
65
- async function generateIdlParsedFromPath(crawlPath) {
66
- const crawlIndex = requireFromWorkingDirectory(path.resolve(crawlPath, 'index.json'));
67
- const crawlResults = await expandCrawlResult(crawlIndex, crawlPath, ['idl']);
68
- await Promise.all(crawlResults.results.map(generateIdlParsed));
69
- return crawlResults;
70
- }
71
-
72
-
73
- /**
74
- * Generate the `idlparsed` export for the spec.
75
- *
76
- * Note that the raw IDL (under `spec.idl.idl`) gets deleted in the process.
77
- *
78
- * @function
79
- * @public
80
- * @param {Object} spec Spec object with the parsed IDL
81
- * @param {String} folder Path to root folder where `idlparsed` folder needs to
82
- * appear.
83
- * @return {String} The relative path from the root folder to the generated file
84
- */
85
- async function saveIdlParsed(spec, folder) {
86
- function specInfo(spec) {
87
- return {
88
- spec: {
89
- title: spec.title,
90
- url: spec.crawled
91
- }
92
- };
93
- }
94
-
95
- const subfolder = path.join(folder, 'idlparsed');
96
- await createFolderIfNeeded(subfolder);
97
-
98
- if (!spec?.idlparsed) {
99
- return;
100
- }
101
-
102
- const json = JSON.stringify(
103
- Object.assign(specInfo(spec), { idlparsed: spec.idlparsed }),
104
- null, 2);
105
- const filename = path.join(subfolder, spec.shortname + '.json');
106
- await fs.promises.writeFile(filename, json);
107
- return `idlparsed/${spec.shortname}.json`;
108
- }
109
-
110
-
111
- /**************************************************
112
- Export methods for use as module
113
- **************************************************/
114
- module.exports.generateIdlParsed = generateIdlParsed;
115
- module.exports.saveIdlParsed = saveIdlParsed;
116
-
117
-
118
- /**************************************************
119
- Code run if the code is run as a stand-alone module
120
- **************************************************/
121
- if (require.main === module) {
122
- const crawlPath = process.argv[2];
123
- if (!crawlPath) {
124
- console.error('Required path to crawl results folder is missing');
125
- process.exit(2);
126
- }
127
-
128
- const savePath = process.argv[3];
129
- generateIdlParsedFromPath(crawlPath)
130
- .then(report => {
131
- if (savePath) {
132
- return Promise.all(report.results.map(
133
- spec => saveIdlParsed(spec, savePath)));
134
- }
135
- else {
136
- console.log(JSON.stringify(report, null, 2));
137
- }
138
- });
139
- }