forked from angular/angular-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnode-module-engine-host.ts
More file actions
154 lines (133 loc) · 4.48 KB
/
Copy pathnode-module-engine-host.ts
File metadata and controls
154 lines (133 loc) · 4.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
* @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
*/
import {
BaseException,
InvalidJsonCharacterException,
UnexpectedEndOfInputException,
} from '@angular-devkit/core';
import * as core from '@angular-devkit/core/node';
import { dirname, join, resolve as resolvePath } from 'path';
import { RuleFactory } from '../src';
import {
FileSystemCollectionDesc,
FileSystemSchematicDesc,
} from './description';
import { ExportStringRef } from './export-ref';
import {
CollectionCannotBeResolvedException,
CollectionMissingSchematicsMapException,
FileSystemEngineHostBase,
InvalidCollectionJsonException,
SchematicMissingFieldsException,
} from './file-system-engine-host-base';
import { readJsonFile } from './file-system-utility';
export class NodePackageDoesNotSupportSchematics extends BaseException {
constructor(name: string) {
super(`Package ${JSON.stringify(name)} was found but does not support schematics.`);
}
}
/**
* A simple EngineHost that uses NodeModules to resolve collections.
*/
export class NodeModulesEngineHost extends FileSystemEngineHostBase {
constructor() { super(); }
protected _resolvePackageJson(name: string, basedir = process.cwd()) {
return core.resolve(name, {
basedir,
checkLocal: true,
checkGlobal: true,
resolvePackageJson: true,
});
}
protected _resolvePath(name: string, basedir = process.cwd()) {
// Allow relative / absolute paths.
if (name.startsWith('.') || name.startsWith('/')) {
return resolvePath(basedir, name);
} else {
// If it's a file inside a package, resolve the package then return the file...
if (name.split('/').length > (name[0] == '@' ? 2 : 1)) {
const rest = name.split('/');
const packageName = rest.shift() + (name[0] == '@' ? '/' + rest.shift() : '');
return resolvePath(core.resolve(packageName, {
basedir,
checkLocal: true,
checkGlobal: true,
resolvePackageJson: true,
}), '..', ...rest);
}
return core.resolve(name, {
basedir,
checkLocal: true,
checkGlobal: true,
});
}
}
protected _resolveCollectionPath(name: string): string {
let collectionPath: string | undefined = undefined;
if (name.replace(/\\/g, '/').split('/').length > (name[0] == '@' ? 2 : 1)) {
try {
collectionPath = this._resolvePath(name, process.cwd());
} catch {
}
}
if (!collectionPath) {
let packageJsonPath = this._resolvePackageJson(name, process.cwd());
// If it's a file, use it as is. Otherwise append package.json to it.
if (!core.fs.isFile(packageJsonPath)) {
packageJsonPath = join(packageJsonPath, 'package.json');
}
const pkgJsonSchematics = require(packageJsonPath)['schematics'];
if (!pkgJsonSchematics || typeof pkgJsonSchematics != 'string') {
throw new NodePackageDoesNotSupportSchematics(name);
}
collectionPath = this._resolvePath(pkgJsonSchematics, dirname(packageJsonPath));
}
try {
if (collectionPath) {
readJsonFile(collectionPath);
return collectionPath;
}
} catch (e) {
if (
e instanceof InvalidJsonCharacterException || e instanceof UnexpectedEndOfInputException
) {
throw new InvalidCollectionJsonException(name, collectionPath, e);
}
}
throw new CollectionCannotBeResolvedException(name);
}
protected _resolveReferenceString(refString: string, parentPath: string) {
const ref = new ExportStringRef<RuleFactory<{}>>(refString, parentPath);
if (!ref.ref) {
return null;
}
return { ref: ref.ref, path: ref.module };
}
protected _transformCollectionDescription(
name: string,
desc: Partial<FileSystemCollectionDesc>,
): FileSystemCollectionDesc {
if (!desc.schematics || typeof desc.schematics != 'object') {
throw new CollectionMissingSchematicsMapException(name);
}
return {
...desc,
name,
} as FileSystemCollectionDesc;
}
protected _transformSchematicDescription(
name: string,
_collection: FileSystemCollectionDesc,
desc: Partial<FileSystemSchematicDesc>,
): FileSystemSchematicDesc {
if (!desc.factoryFn || !desc.path || !desc.description) {
throw new SchematicMissingFieldsException(name);
}
return desc as FileSystemSchematicDesc;
}
}