diff --git a/etc/api/angular_devkit/core/node/_golden-api.d.ts b/etc/api/angular_devkit/core/node/_golden-api.d.ts index 67ee907754..83f64a0cbb 100644 --- a/etc/api/angular_devkit/core/node/_golden-api.d.ts +++ b/etc/api/angular_devkit/core/node/_golden-api.d.ts @@ -4,13 +4,6 @@ export declare function isDirectory(filePath: string): boolean; export declare function isFile(filePath: string): boolean; -export declare class ModuleNotFoundException extends BaseException { - readonly basePath: string; - readonly code: string; - readonly moduleName: string; - constructor(moduleName: string, basePath: string); -} - export declare class NodeJsAsyncHost implements virtualFs.Host { get capabilities(): virtualFs.HostCapabilities; delete(path: Path): Observable; @@ -47,15 +40,3 @@ export declare class NodeModuleJobRegistry {} }; - const origPrepareStackTrace = error.prepareStackTrace; - error.prepareStackTrace = (_, stack) => stack; - const stack = (new Error()).stack as {} | undefined as { getFileName(): string }[] | undefined; - error.prepareStackTrace = origPrepareStackTrace; - - return stack ? stack.map(x => x.getFileName()).filter(x => !!x) : []; -} - - -/** - * Get the global directory for node_modules. This is based on NPM code itself, and may be subject - * to change, but is relatively stable. - * @returns {string} The path to node_modules itself. - * @private - */ -function _getGlobalNodeModules() { - let globalPrefix; - - if (process.env.PREFIX) { - globalPrefix = process.env.PREFIX; - } else if (process.platform === 'win32') { - // c:\node\node.exe --> prefix=c:\node\ - globalPrefix = path.dirname(process.execPath); - } else { - // /usr/local/bin/node --> prefix=/usr/local - globalPrefix = path.dirname(path.dirname(process.execPath)); - - // destdir only is respected on Unix - const destdir = process.env.DESTDIR; - if (destdir) { - globalPrefix = path.join(destdir, globalPrefix); - } - } - - return (process.platform !== 'win32') - ? path.resolve(globalPrefix || '', 'lib', 'node_modules') - : path.resolve(globalPrefix || '', 'node_modules'); -} - - -/** @deprecated since version 8. Use `require.resolve` instead. */ -export interface ResolveOptions { - /** - * The basedir to use from which to resolve. - */ - basedir: string; - - /** - * The list of extensions to resolve. By default uses Object.keys(require.extensions). - */ - extensions?: string[]; - - /** - * An additional list of paths to look into. - */ - paths?: string[]; - - /** - * Whether or not to preserve symbolic links. If false, the actual paths pointed by - * the symbolic links will be used. This defaults to true. - */ - preserveSymlinks?: boolean; - - /** - * Whether to fallback to a global lookup if the basedir one failed. - */ - checkGlobal?: boolean; - - /** - * Whether to fallback to using the local caller's directory if the basedir failed. - */ - checkLocal?: boolean; - - /** - * Whether to only resolve and return the first package.json file found. By default, - * resolves the main field or the index of the package. - */ - resolvePackageJson?: boolean; -} - - -let _resolveHook: ((x: string, options: ResolveOptions) => string | null) | null = null; -/** @deprecated since version 8. Use `require.resolve` instead. */ -export function setResolveHook( - hook: ((x: string, options: ResolveOptions) => string | null) | null, -) { - _resolveHook = hook; -} - - -/** - * Resolve a package using a logic similar to npm require.resolve, but with more options. - * @param packageName The package name to resolve. - * @param options A list of options. See documentation of those options. - * @returns {string} Path to the index to include, or if `resolvePackageJson` option was - * passed, a path to that file. - * @throws {ModuleNotFoundException} If no module with that name was found anywhere. - * @deprecated since version 8. Use `require.resolve` instead. - */ -export function resolve(packageName: string, options: ResolveOptions): string { - if (_resolveHook) { - const maybe = _resolveHook(packageName, options); - if (maybe) { - return maybe; - } - } - - const readFileSync = fs.readFileSync; - - const extensions: string[] = options.extensions || Object.keys(require.extensions); - const basePath = options.basedir; - - options.paths = options.paths || []; - - if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[\/\\])/.test(packageName)) { - let res = path.resolve(basePath, packageName); - if (packageName === '..' || packageName.slice(-1) === '/') { - res += '/'; - } - - const m = loadAsFileSync(res) || loadAsDirectorySync(res); - if (m) { - return m; - } - } else { - const n = loadNodeModulesSync(packageName, basePath); - if (n) { - return n; - } - } - - // Fallback to checking the local (callee) node modules. - if (options.checkLocal) { - const callers = _caller(); - for (const caller of callers) { - const localDir = path.dirname(caller); - if (localDir !== options.basedir) { - try { - return resolve(packageName, { - ...options, - checkLocal: false, - checkGlobal: false, - basedir: localDir, - }); - } catch (e) { - // Just swap the basePath with the original call one. - if (!(e instanceof ModuleNotFoundException)) { - throw e; - } - } - } - } - } - - // Fallback to checking the global node modules. - if (options.checkGlobal) { - const globalDir = path.dirname(_getGlobalNodeModules()); - if (globalDir !== options.basedir) { - try { - return resolve(packageName, { - ...options, - checkLocal: false, - checkGlobal: false, - basedir: globalDir, - }); - } catch (e) { - // Just swap the basePath with the original call one. - if (!(e instanceof ModuleNotFoundException)) { - throw e; - } - } - } - } - - throw new ModuleNotFoundException(packageName, basePath); - - function loadAsFileSync(x: string): string | null { - if (isFile(x)) { - return x; - } - - return extensions.map(ex => x + ex).find(f => isFile(f)) || null; - } - - function loadAsDirectorySync(x: string): string | null { - const pkgfile = path.join(x, 'package.json'); - if (isFile(pkgfile)) { - if (options.resolvePackageJson) { - return pkgfile; - } - - try { - const body = readFileSync(pkgfile, 'UTF8'); - const pkg = JSON.parse(body); - - if (pkg['main']) { - if (pkg['main'] === '.' || pkg['main'] === './') { - pkg['main'] = 'index'; - } - - const m = loadAsFileSync(path.resolve(x, pkg['main'])); - if (m) { - return m; - } - const n = loadAsDirectorySync(path.resolve(x, pkg['main'])); - if (n) { - return n; - } - } - } catch {} - } - - return loadAsFileSync(path.join(x, '/index')); - } - - function loadNodeModulesSync(x: string, start: string): string | null { - const dirs = nodeModulesPaths(start, options); - for (const dir of dirs) { - const m = loadAsFileSync(path.join(dir, x)); - if (m) { - return m; - } - const n = loadAsDirectorySync(path.join(dir, x)); - if (n) { - return n; - } - } - - return null; - } - - function nodeModulesPaths(start: string, opts: ResolveOptions) { - const modules = ['node_modules']; - if (process.env.BAZEL_TARGET) { - // When running test under Bazel, node_modules have to be resolved - // differently. node_modules are installed in the `npm` workspace. - // For more info, see `yarn_install` rule in WORKSPACE file. - modules.push(path.join('npm', 'node_modules')); - } - - // ensure that `start` is an absolute path at this point, - // resolving against the process' current working directory - let absoluteStart = path.resolve(start); - - if (opts && opts.preserveSymlinks === false) { - try { - absoluteStart = fs.realpathSync(absoluteStart); - } catch (err) { - if (err.code !== 'ENOENT') { - throw err; - } - } - } - - let prefix = '/'; - if (/^([A-Za-z]:)/.test(absoluteStart)) { - prefix = ''; - } else if (/^\\\\/.test(absoluteStart)) { - prefix = '\\\\'; - } - - const paths = [absoluteStart]; - let parsed = path.parse(absoluteStart); - while (parsed.dir !== paths[paths.length - 1]) { - paths.push(parsed.dir); - parsed = path.parse(parsed.dir); - } - - const dirs = paths.reduce((dirs: string[], aPath: string) => { - return dirs.concat(modules.map(function (moduleDir) { - return path.join(prefix, aPath, moduleDir); - })); - }, []); - - if (process.env.NG_TEMP_MODULES_DIR) { - // When running from a temporary installations, node_modules have to be resolved - // differently and they should be prefered over others. - dirs.unshift(process.env.NG_TEMP_MODULES_DIR); - } - - return opts && opts.paths ? dirs.concat(opts.paths) : dirs; - } -} diff --git a/packages/angular_devkit/core/node/resolve_spec.ts b/packages/angular_devkit/core/node/resolve_spec.ts deleted file mode 100644 index 82d0257279..0000000000 --- a/packages/angular_devkit/core/node/resolve_spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ -// tslint:disable:no-any -// tslint:disable-next-line:no-implicit-dependencies -import { resolve } from '@angular-devkit/core/node'; - -describe('resolve', () => { - - it('works', () => { - const tslintRe = /[\\/]node_modules[\\/]tslint[\\/]lib[\\/]index.js$/; - expect(resolve('tslint', { basedir: __dirname })).toMatch(tslintRe); - - expect(() => resolve('npm', { basedir: '/' })).toThrow(); - - if (!process.env['BAZEL_TARGET']) { - expect(() => resolve('npm', { basedir: '/', checkGlobal: true })).not.toThrow(); - } - }); - -});