Skip to content

Commit edaa942

Browse files
committed
fix(@angular-devkit/schematics): fully resolve schematic entries within packages
Fixes: angular#17085
1 parent d29d403 commit edaa942

File tree

1 file changed

+42
-12
lines changed

1 file changed

+42
-12
lines changed

packages/angular_devkit/schematics/tools/node-module-engine-host.ts

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
InvalidJsonCharacterException,
1111
UnexpectedEndOfInputException,
1212
} from '@angular-devkit/core';
13-
import { dirname, extname, join, resolve } from 'path';
13+
import { dirname, join, resolve } from 'path';
1414
import { RuleFactory } from '../src';
1515
import {
1616
FileSystemCollectionDesc,
@@ -39,26 +39,56 @@ export class NodePackageDoesNotSupportSchematics extends BaseException {
3939
export class NodeModulesEngineHost extends FileSystemEngineHostBase {
4040
constructor(private readonly paths?: string[]) { super(); }
4141

42-
protected _resolveCollectionPath(name: string): string {
42+
private resolve(name: string, requester?: string): string {
43+
const relativeBase = requester ? dirname(requester) : process.cwd();
4344
let collectionPath: string | undefined = undefined;
44-
if (name.startsWith('.') || name.startsWith('/')) {
45-
name = resolve(name);
45+
46+
if (name.startsWith('.')) {
47+
name = resolve(relativeBase, name);
4648
}
4749

48-
if (extname(name)) {
49-
// When having an extension let's just resolve the provided path.
50-
collectionPath = require.resolve(name, { paths: this.paths });
51-
} else {
52-
const packageJsonPath = require.resolve(join(name, 'package.json'), { paths: this.paths });
50+
const resolveOptions = {
51+
paths: requester ? [dirname(requester), ...(this.paths || [])] : this.paths,
52+
};
53+
54+
// Try to resolve as a package
55+
try {
56+
const packageJsonPath = require.resolve(join(name, 'package.json'), resolveOptions);
5357
const { schematics } = require(packageJsonPath);
5458

5559
if (!schematics || typeof schematics !== 'string') {
5660
throw new NodePackageDoesNotSupportSchematics(name);
5761
}
5862

59-
collectionPath = resolve(dirname(packageJsonPath), schematics);
63+
collectionPath = this.resolve(schematics, packageJsonPath);
64+
} catch (e) {
65+
if (e.code !== 'MODULE_NOT_FOUND') {
66+
throw e;
67+
}
68+
}
69+
70+
// If not a package, try to resolve as a file
71+
if (!collectionPath) {
72+
try {
73+
collectionPath = require.resolve(name, resolveOptions);
74+
} catch (e) {
75+
if (e.code !== 'MODULE_NOT_FOUND') {
76+
throw e;
77+
}
78+
}
79+
}
80+
81+
// If not a package or a file, error
82+
if (!collectionPath) {
83+
throw new CollectionCannotBeResolvedException(name);
6084
}
6185

86+
return collectionPath;
87+
}
88+
89+
protected _resolveCollectionPath(name: string): string {
90+
const collectionPath = this.resolve(name);
91+
6292
try {
6393
readJsonFile(collectionPath);
6494

@@ -68,10 +98,10 @@ export class NodeModulesEngineHost extends FileSystemEngineHostBase {
6898
e instanceof InvalidJsonCharacterException || e instanceof UnexpectedEndOfInputException
6999
) {
70100
throw new InvalidCollectionJsonException(name, collectionPath, e);
101+
} else {
102+
throw e;
71103
}
72104
}
73-
74-
throw new CollectionCannotBeResolvedException(name);
75105
}
76106

77107
protected _resolveReferenceString(refString: string, parentPath: string) {

0 commit comments

Comments
 (0)