88/* eslint-disable no-console */
99'use strict' ;
1010
11+ const child_process = require ( 'child_process' ) ;
1112const fs = require ( 'fs' ) ;
1213const path = require ( 'path' ) ;
14+ const temp = require ( 'temp' ) ;
1315const ts = require ( 'typescript' ) ;
1416
17+ const tmpRoot = temp . mkdirSync ( 'angular-devkit-' ) ;
1518
1619let _istanbulRequireHook = null ;
1720if ( process . env [ 'CODE_COVERAGE' ] || process . argv . indexOf ( '--code-coverage' ) !== - 1 ) {
@@ -115,11 +118,18 @@ if (!__dirname.match(new RegExp(`\\${path.sep}node_modules\\${path.sep}`))) {
115118 const oldResolve = Module . _resolveFilename ;
116119
117120 Module . _resolveFilename = function ( request , parent ) {
121+ let resolved = null ;
122+ try {
123+ resolved = oldResolve . call ( this , request , parent ) ;
124+ } catch ( _ ) { }
125+
118126 if ( request in packages ) {
119127 return packages [ request ] . main ;
120128 } else if ( builtinModules . includes ( request ) ) {
121129 // It's a native Node module.
122130 return oldResolve . call ( this , request , parent ) ;
131+ } else if ( resolved && resolved . match ( / [ \\ \/ ] n o d e _ m o d u l e s [ \\ \/ ] / ) ) {
132+ return resolved ;
123133 } else {
124134 const match = Object . keys ( packages ) . find ( pkgName => request . startsWith ( pkgName + '/' ) ) ;
125135 if ( match ) {
@@ -130,13 +140,31 @@ if (!__dirname.match(new RegExp(`\\${path.sep}node_modules\\${path.sep}`))) {
130140 // and `.ts` versions will only get the `.json` content (which wouldn't happen if the .ts was compiled to
131141 // JavaScript). We load `.ts` files first here to avoid this conflict. It's hacky, but so is the rest of this
132142 // file.
133- const resolvedPath = oldResolve . apply ( this , arguments ) ;
134- const maybeTsPath = resolvedPath . endsWith ( '.json' ) && resolvedPath . replace ( / \. j s o n $ / , '.ts' ) ;
135- if ( maybeTsPath && ! request . endsWith ( '.json' ) && fs . existsSync ( maybeTsPath ) ) {
136- return maybeTsPath ;
143+ const maybeTsPath = resolved . endsWith ( '.json' ) && resolved . replace ( / \. j s o n $ / , '.ts' ) ;
144+ if ( maybeTsPath && ! request . endsWith ( '.json' ) ) {
145+ // If the file exists, return its path. If it doesn't, run the quicktype runner on it and return the content.
146+ if ( fs . existsSync ( maybeTsPath ) ) {
147+ return maybeTsPath ;
148+ } else {
149+ // This script has the be synchronous, so we spawnSync instead of, say, requiring the runner and calling
150+ // the method directly.
151+ const tmpJsonSchemaPath = path . join ( tmpRoot , maybeTsPath . replace ( / [ ^ 0 - 9 a - z A - Z . ] / g, '_' ) ) ;
152+ try {
153+ if ( ! fs . existsSync ( tmpJsonSchemaPath ) ) {
154+ const quicktypeRunnerPath = path . join ( __dirname , '../tools/quicktype_runner.js' ) ;
155+ child_process . spawnSync ( 'node' , [ quicktypeRunnerPath , resolved , tmpJsonSchemaPath ] ) ;
156+ }
157+
158+ return tmpJsonSchemaPath ;
159+ } catch ( _ ) {
160+ // Just return resolvedPath and let Node deals with it.
161+ console . log ( _ ) ;
162+ process . exit ( 99 ) ;
163+ }
164+ }
137165 }
138166
139- return resolvedPath ;
167+ return resolved ;
140168 }
141169 }
142170 } ;
0 commit comments