-
Notifications
You must be signed in to change notification settings - Fork 12k
/
Copy pathfile-system-engine-host.ts
115 lines (97 loc) · 3.31 KB
/
file-system-engine-host.ts
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
/**
* @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 { existsSync } from 'fs';
import { join } from 'path';
import { Observable, from, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { RuleFactory, TaskExecutor, UnregisteredTaskException } from '../src';
import { FileSystemCollectionDesc, FileSystemSchematicDesc } from './description';
import { ExportStringRef } from './export-ref';
import {
CollectionCannotBeResolvedException,
CollectionMissingSchematicsMapException,
FileSystemEngineHostBase,
SchematicMissingFieldsException,
} from './file-system-engine-host-base';
/**
* A simple EngineHost that uses a root with one directory per collection inside of it. The
* collection declaration follows the same rules as the regular FileSystemEngineHostBase.
*/
export class FileSystemEngineHost extends FileSystemEngineHostBase {
constructor(protected _root: string) { super(); }
protected _resolveCollectionPath(name: string): string {
try {
// Allow `${_root}/${name}.json` as a collection.
const maybePath = require.resolve(join(this._root, name + '.json'));
if (existsSync(maybePath)) {
return maybePath;
}
} catch (error) { }
try {
// Allow `${_root}/${name}/collection.json.
const maybePath = require.resolve(join(this._root, name, 'collection.json'));
if (existsSync(maybePath)) {
return maybePath;
}
} catch (error) { }
throw new CollectionCannotBeResolvedException(name);
}
protected _resolveReferenceString(refString: string, parentPath: string) {
// Use the same kind of export strings as NodeModule.
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;
}
hasTaskExecutor(name: string): boolean {
if (super.hasTaskExecutor(name)) {
return true;
}
try {
const maybePath = require.resolve(join(this._root, name));
if (existsSync(maybePath)) {
return true;
}
} catch {}
return false;
}
createTaskExecutor(name: string): Observable<TaskExecutor> {
if (!super.hasTaskExecutor(name)) {
try {
const path = require.resolve(join(this._root, name));
return from(import(path).then(mod => mod.default())).pipe(
catchError(() => throwError(new UnregisteredTaskException(name))),
);
} catch {}
}
return super.createTaskExecutor(name);
}
}