@@ -13,6 +13,14 @@ const {
1313 showDirStats,
1414} = require ( './utils.js' ) ;
1515
16+ const entryPoints = [
17+ 'index.ts' ,
18+ 'execution/execute.ts' ,
19+ 'jsutils/instanceOf.ts' ,
20+ 'language/parser.ts' ,
21+ 'language/ast.ts' ,
22+ ] ;
23+
1624if ( require . main === module ) {
1725 fs . rmSync ( './npmDist' , { recursive : true , force : true } ) ;
1826 fs . mkdirSync ( './npmDist' ) ;
@@ -57,11 +65,21 @@ if (require.main === module) {
5765
5866 const tsProgram = ts . createProgram ( [ 'src/index.ts' ] , tsOptions , tsHost ) ;
5967 const tsResult = tsProgram . emit ( ) ;
68+
6069 assert (
6170 ! tsResult . emitSkipped ,
6271 'Fail to generate `*.d.ts` files, please run `npm run check`' ,
6372 ) ;
6473
74+ for ( const [ filename , contents ] of Object . entries (
75+ buildCjsEsmWrapper (
76+ entryPoints . map ( ( e ) => './src/' + e ) ,
77+ tsProgram ,
78+ ) ,
79+ ) ) {
80+ writeGeneratedFile ( filename , contents ) ;
81+ }
82+
6583 assert ( packageJSON . types === undefined , 'Unexpected "types" in package.json' ) ;
6684 const supportedTSVersions = Object . keys ( packageJSON . typesVersions ) ;
6785 assert (
@@ -137,3 +155,130 @@ function buildPackageJSON() {
137155
138156 return packageJSON ;
139157}
158+
159+ /**
160+ *
161+ * @param {string[] } files
162+ * @param {ts.Program } tsProgram
163+ * @returns
164+ */
165+ function buildCjsEsmWrapper ( files , tsProgram ) {
166+ /**
167+ * @type {Record<string, string> } inputFiles
168+ */
169+ const inputFiles = { } ;
170+ for ( const file of files ) {
171+ const sourceFile = tsProgram . getSourceFile ( file ) ;
172+ assert ( sourceFile , `No source file found for ${ file } ` ) ;
173+
174+ const generatedFileName = path . relative (
175+ path . dirname ( tsProgram . getRootFileNames ( ) [ 0 ] ) ,
176+ file . replace ( / \. t s $ / , '.js.mts' ) ,
177+ ) ;
178+ const exportFrom = ts . factory . createStringLiteral (
179+ './' + path . basename ( file , '.ts' ) + '.js' ,
180+ ) ;
181+
182+ /**
183+ * @type {ts.Statement[] }
184+ */
185+ const statements = [ ] ;
186+
187+ /** @type {string[] } */
188+ const exports = [ ] ;
189+
190+ /** @type {string[] } */
191+ const typeExports = [ ] ;
192+
193+ sourceFile . forEachChild ( ( node ) => {
194+ if ( ts . isExportDeclaration ( node ) ) {
195+ if ( node . exportClause && ts . isNamedExports ( node . exportClause ) ) {
196+ for ( const element of node . exportClause . elements ) {
197+ if ( node . isTypeOnly || element . isTypeOnly ) {
198+ typeExports . push ( element . name . text ) ;
199+ } else {
200+ exports . push ( element . name . text ) ;
201+ }
202+ }
203+ }
204+ } else if (
205+ node . modifiers ?. some (
206+ ( modifier ) => modifier . kind === ts . SyntaxKind . ExportKeyword ,
207+ )
208+ ) {
209+ if ( ts . isVariableStatement ( node ) ) {
210+ for ( const declaration of node . declarationList . declarations ) {
211+ if ( declaration . name && ts . isIdentifier ( declaration . name ) ) {
212+ exports . push ( declaration . name . text ) ;
213+ }
214+ }
215+ } else if (
216+ ts . isFunctionDeclaration ( node ) ||
217+ ts . isClassDeclaration ( node )
218+ ) {
219+ exports . push ( node . name . text ) ;
220+ } else if ( ts . isTypeAliasDeclaration ( node ) ) {
221+ typeExports . push ( node . name . text ) ;
222+ }
223+ }
224+ } ) ;
225+ if ( exports . length > 0 ) {
226+ statements . push (
227+ ts . factory . createExportDeclaration (
228+ undefined ,
229+ undefined ,
230+ false ,
231+ ts . factory . createNamedExports (
232+ exports . map ( ( name ) =>
233+ ts . factory . createExportSpecifier ( false , undefined , name ) ,
234+ ) ,
235+ ) ,
236+ exportFrom ,
237+ ) ,
238+ ) ;
239+ }
240+ if ( typeExports . length > 0 ) {
241+ statements . push (
242+ ts . factory . createExportDeclaration (
243+ undefined ,
244+ undefined ,
245+ true ,
246+ ts . factory . createNamedExports (
247+ typeExports . map ( ( name ) =>
248+ ts . factory . createExportSpecifier ( false , undefined , name ) ,
249+ ) ,
250+ ) ,
251+ exportFrom ,
252+ ) ,
253+ ) ;
254+ }
255+ const printer = ts . createPrinter ( { newLine : ts . NewLineKind . LineFeed } ) ;
256+ inputFiles [ generatedFileName ] = printer . printFile (
257+ ts . factory . createSourceFile (
258+ statements ,
259+ ts . factory . createToken ( ts . SyntaxKind . EndOfFileToken ) ,
260+ ts . NodeFlags . None ,
261+ ) ,
262+ ) ;
263+ }
264+ /**
265+ * @type {ts.CompilerOptions } options
266+ */
267+ const options = {
268+ ...tsProgram . getCompilerOptions ( ) ,
269+ declaration : true ,
270+ emitDeclarationOnly : false ,
271+ isolatedModules : true ,
272+ module : ts . ModuleKind . ESNext ,
273+ } ;
274+ options . outDir = options . declarationDir ;
275+ const results = { } ;
276+ const host = ts . createCompilerHost ( options ) ;
277+ host . writeFile = ( fileName , contents ) => ( results [ fileName ] = contents ) ;
278+ host . readFile = ( fileName ) => inputFiles [ fileName ] ;
279+
280+ const program = ts . createProgram ( Object . keys ( inputFiles ) , options , host ) ;
281+ program . emit ( ) ;
282+
283+ return results ;
284+ }
0 commit comments