@@ -7,6 +7,9 @@ const { stat, readFile, writeFile } = require('fs/promises');
77const { join : joinPath } = require ( 'path' ) ;
88const { spawn } = require ( 'child_process' ) ;
99
10+ const { ApiModel } = require ( '@microsoft/api-extractor-model' ) ;
11+ const { inspect } = require ( 'util' ) ;
12+
1013class APIPrinterError extends Error { }
1114
1215const readJSON = async filePath => JSON . parse ( await readFile ( filePath , { encoding : 'utf8' } ) ) ;
@@ -28,11 +31,6 @@ const API_CONFIG = joinPath(DRIVER_REPO_DIR, 'api-extractor.json');
2831const DOC_MODEL = joinPath ( DRIVER_REPO_DIR , 'etc/api.json' ) ;
2932
3033async function getDriverAPI ( ) {
31- const apiExists = await stat ( DOC_MODEL ) . then ( statRes => statRes . isFile ( ) ) ;
32- if ( apiExists ) {
33- return await readJSON ( DOC_MODEL ) ;
34- }
35-
3634 const repoExists = await stat ( DRIVER_REPO_DIR ) . then ( statRes => statRes . isDirectory ( ) ) ;
3735 if ( ! repoExists ) {
3836 throw new APIPrinterError ( 'You must clone the driver repo next to this script' ) ;
@@ -50,33 +48,56 @@ async function getDriverAPI() {
5048 return await readJSON ( DOC_MODEL ) ;
5149}
5250
53- async function main ( ) {
54- const api = await getDriverAPI ( ) ;
55-
56- const packageMembers = api . members [ 0 ] . members ;
57-
58- for ( const classDescription of packageMembers . filter ( m => m . kind === 'Class' ) ) {
59- const className = classDescription . name ;
60- const methodsPrinted = new Set ( ) ;
61- for ( const methodDescription of classDescription . members . filter ( m => m . kind === 'Method' ) ) {
62- /** @type {string } */
63- const returnType = methodDescription . excerptTokens
64- . slice (
65- methodDescription . returnTypeTokenRange . startIndex ,
66- methodDescription . returnTypeTokenRange . endIndex
67- )
68- . map ( token => token . text . replaceAll ( '\n' , '' ) . replace ( / \s \s + / g, ' ' ) )
69- . join ( '' ) ;
70- if ( returnType . includes ( 'Promise<' ) && ! methodsPrinted . has ( methodDescription . name ) ) {
71- methodsPrinted . add ( methodDescription . name ) ;
72- const apiString = `${ className } .${ methodDescription . name } (): ${ returnType } ` ;
73- console . log ( apiString ) ;
51+ /**
52+ * @param {string[] } args
53+ */
54+ async function main ( args ) {
55+ if ( args . includes ( 'build:api' ) ) {
56+ return await getDriverAPI ( ) ;
57+ }
58+ const apiModel = new ApiModel ( ) ;
59+ const apiPackage = apiModel . loadPackage ( DOC_MODEL ) ;
60+
61+ const apiList = [ ] ;
62+
63+ const recursivelyWalkApi = rootMember => {
64+ if ( rootMember == null ) {
65+ return ;
66+ }
67+ const printedMethods = new Set ( ) ; // make overloads only print once
68+ for ( const member of rootMember . members ) {
69+ if ( member . kind === 'Method' ) {
70+ /** @type {string } */
71+ const returnType = member . returnTypeExcerpt . text ;
72+ if ( returnType . includes ( 'Promise<' ) && ! printedMethods . has ( member . name ) ) {
73+ apiList . push ( { className : member . parent . name , method : member . name , returnType } ) ;
74+ }
75+ printedMethods . add ( member . name ) ;
7476 }
77+ recursivelyWalkApi ( member ) ;
7578 }
76- }
79+ } ;
80+ recursivelyWalkApi ( apiPackage ) ;
81+
82+ writeFile (
83+ 'test/tools/api.new.js' , // use new in the name to not override the source of truth
84+ Buffer . from (
85+ `/* eslint-disable prettier/prettier */
86+ 'use strict';
87+
88+ module.exports = Object.create(null);
89+ Object.defineProperty(module.exports, '__esModule', { value: true });
90+
91+ module.exports.asyncApi = [
92+ ${ apiList . map ( v => inspect ( v , { depth : Infinity , breakLength : Infinity } ) ) . join ( ',\n ' ) }
93+ ];
94+ ` ,
95+ 'utf8'
96+ )
97+ ) ;
7798}
7899
79- main ( )
100+ main ( process . argv )
80101 . then ( ( ) => {
81102 process . exitCode = 0 ;
82103 } )
0 commit comments