1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | Object.defineProperty(exports, "__esModule", { value: true });
|
10 | exports.SchematicEngine = exports.TaskScheduler = exports.CollectionImpl = exports.UnknownTaskDependencyException = exports.UnregisteredTaskException = exports.SchematicEngineConflictingException = exports.PrivateSchematicException = exports.UnknownSchematicException = exports.CircularCollectionException = exports.UnknownCollectionException = exports.UnknownUrlSourceProtocol = void 0;
|
11 | const core_1 = require("@angular-devkit/core");
|
12 | const rxjs_1 = require("rxjs");
|
13 | const operators_1 = require("rxjs/operators");
|
14 | const interface_1 = require("../tree/interface");
|
15 | const null_1 = require("../tree/null");
|
16 | const static_1 = require("../tree/static");
|
17 | const schematic_1 = require("./schematic");
|
18 | class UnknownUrlSourceProtocol extends core_1.BaseException {
|
19 | constructor(url) {
|
20 | super(`Unknown Protocol on url "${url}".`);
|
21 | }
|
22 | }
|
23 | exports.UnknownUrlSourceProtocol = UnknownUrlSourceProtocol;
|
24 | class UnknownCollectionException extends core_1.BaseException {
|
25 | constructor(name) {
|
26 | super(`Unknown collection "${name}".`);
|
27 | }
|
28 | }
|
29 | exports.UnknownCollectionException = UnknownCollectionException;
|
30 | class CircularCollectionException extends core_1.BaseException {
|
31 | constructor(name) {
|
32 | super(`Circular collection reference "${name}".`);
|
33 | }
|
34 | }
|
35 | exports.CircularCollectionException = CircularCollectionException;
|
36 | class UnknownSchematicException extends core_1.BaseException {
|
37 | constructor(name, collection) {
|
38 | super(`Schematic "${name}" not found in collection "${collection.name}".`);
|
39 | }
|
40 | }
|
41 | exports.UnknownSchematicException = UnknownSchematicException;
|
42 | class PrivateSchematicException extends core_1.BaseException {
|
43 | constructor(name, collection) {
|
44 | super(`Schematic "${name}" not found in collection "${collection.name}".`);
|
45 | }
|
46 | }
|
47 | exports.PrivateSchematicException = PrivateSchematicException;
|
48 | class SchematicEngineConflictingException extends core_1.BaseException {
|
49 | constructor() {
|
50 | super(`A schematic was called from a different engine as its parent.`);
|
51 | }
|
52 | }
|
53 | exports.SchematicEngineConflictingException = SchematicEngineConflictingException;
|
54 | class UnregisteredTaskException extends core_1.BaseException {
|
55 | constructor(name, schematic) {
|
56 | const addendum = schematic ? ` in schematic "${schematic.name}"` : '';
|
57 | super(`Unregistered task "${name}"${addendum}.`);
|
58 | }
|
59 | }
|
60 | exports.UnregisteredTaskException = UnregisteredTaskException;
|
61 | class UnknownTaskDependencyException extends core_1.BaseException {
|
62 | constructor(id) {
|
63 | super(`Unknown task dependency [ID: ${id.id}].`);
|
64 | }
|
65 | }
|
66 | exports.UnknownTaskDependencyException = UnknownTaskDependencyException;
|
67 | class CollectionImpl {
|
68 | constructor(_description, _engine, baseDescriptions) {
|
69 | this._description = _description;
|
70 | this._engine = _engine;
|
71 | this.baseDescriptions = baseDescriptions;
|
72 | }
|
73 | get description() {
|
74 | return this._description;
|
75 | }
|
76 | get name() {
|
77 | return this.description.name || '<unknown>';
|
78 | }
|
79 | createSchematic(name, allowPrivate = false) {
|
80 | return this._engine.createSchematic(name, this, allowPrivate);
|
81 | }
|
82 | listSchematicNames(includeHidden) {
|
83 | return this._engine.listSchematicNames(this, includeHidden);
|
84 | }
|
85 | }
|
86 | exports.CollectionImpl = CollectionImpl;
|
87 | class TaskScheduler {
|
88 | constructor(_context) {
|
89 | this._context = _context;
|
90 | this._queue = new core_1.PriorityQueue((x, y) => x.priority - y.priority);
|
91 | this._taskIds = new Map();
|
92 | }
|
93 | _calculatePriority(dependencies) {
|
94 | if (dependencies.size === 0) {
|
95 | return 0;
|
96 | }
|
97 | const prio = [...dependencies].reduce((prio, task) => prio + task.priority, 1);
|
98 | return prio;
|
99 | }
|
100 | _mapDependencies(dependencies) {
|
101 | if (!dependencies) {
|
102 | return new Set();
|
103 | }
|
104 | const tasks = dependencies.map((dep) => {
|
105 | const task = this._taskIds.get(dep);
|
106 | if (!task) {
|
107 | throw new UnknownTaskDependencyException(dep);
|
108 | }
|
109 | return task;
|
110 | });
|
111 | return new Set(tasks);
|
112 | }
|
113 | schedule(taskConfiguration) {
|
114 | const dependencies = this._mapDependencies(taskConfiguration.dependencies);
|
115 | const priority = this._calculatePriority(dependencies);
|
116 | const task = {
|
117 | id: TaskScheduler._taskIdCounter++,
|
118 | priority,
|
119 | configuration: taskConfiguration,
|
120 | context: this._context,
|
121 | };
|
122 | this._queue.push(task);
|
123 | const id = { id: task.id };
|
124 | this._taskIds.set(id, task);
|
125 | return id;
|
126 | }
|
127 | finalize() {
|
128 | const tasks = this._queue.toArray();
|
129 | this._queue.clear();
|
130 | this._taskIds.clear();
|
131 | return tasks;
|
132 | }
|
133 | }
|
134 | exports.TaskScheduler = TaskScheduler;
|
135 | TaskScheduler._taskIdCounter = 1;
|
136 | class SchematicEngine {
|
137 | constructor(_host, _workflow) {
|
138 | this._host = _host;
|
139 | this._workflow = _workflow;
|
140 | this._collectionCache = new Map();
|
141 | this._schematicCache = new WeakMap();
|
142 | this._taskSchedulers = new Array();
|
143 | }
|
144 | get workflow() {
|
145 | return this._workflow || null;
|
146 | }
|
147 | get defaultMergeStrategy() {
|
148 | return this._host.defaultMergeStrategy || interface_1.MergeStrategy.Default;
|
149 | }
|
150 | createCollection(name, requester) {
|
151 | let collection = this._collectionCache.get(name);
|
152 | if (collection) {
|
153 | return collection;
|
154 | }
|
155 | const [description, bases] = this._createCollectionDescription(name, requester === null || requester === void 0 ? void 0 : requester.description);
|
156 | collection = new CollectionImpl(description, this, bases);
|
157 | this._collectionCache.set(name, collection);
|
158 | this._schematicCache.set(collection, new Map());
|
159 | return collection;
|
160 | }
|
161 | _createCollectionDescription(name, requester, parentNames) {
|
162 | const description = this._host.createCollectionDescription(name, requester);
|
163 | if (!description) {
|
164 | throw new UnknownCollectionException(name);
|
165 | }
|
166 | if (parentNames && parentNames.has(description.name)) {
|
167 | throw new CircularCollectionException(name);
|
168 | }
|
169 | const bases = new Array();
|
170 | if (description.extends) {
|
171 | parentNames = (parentNames || new Set()).add(description.name);
|
172 | for (const baseName of description.extends) {
|
173 | const [base, baseBases] = this._createCollectionDescription(baseName, description, new Set(parentNames));
|
174 | bases.unshift(base, ...baseBases);
|
175 | }
|
176 | }
|
177 | return [description, bases];
|
178 | }
|
179 | createContext(schematic, parent, executionOptions) {
|
180 |
|
181 | if (parent && parent.engine && parent.engine !== this) {
|
182 | throw new SchematicEngineConflictingException();
|
183 | }
|
184 | let interactive = true;
|
185 | if (executionOptions && executionOptions.interactive != undefined) {
|
186 | interactive = executionOptions.interactive;
|
187 | }
|
188 | else if (parent && parent.interactive != undefined) {
|
189 | interactive = parent.interactive;
|
190 | }
|
191 | let context = {
|
192 | debug: (parent && parent.debug) || false,
|
193 | engine: this,
|
194 | logger: (parent && parent.logger && parent.logger.createChild(schematic.description.name)) ||
|
195 | new core_1.logging.NullLogger(),
|
196 | schematic,
|
197 | strategy: parent && parent.strategy !== undefined ? parent.strategy : this.defaultMergeStrategy,
|
198 | interactive,
|
199 | addTask,
|
200 | };
|
201 | const maybeNewContext = this._host.transformContext(context);
|
202 | if (maybeNewContext) {
|
203 | context = maybeNewContext;
|
204 | }
|
205 | const taskScheduler = new TaskScheduler(context);
|
206 | const host = this._host;
|
207 | this._taskSchedulers.push(taskScheduler);
|
208 | function addTask(task, dependencies) {
|
209 | const config = task.toConfiguration();
|
210 | if (!host.hasTaskExecutor(config.name)) {
|
211 | throw new UnregisteredTaskException(config.name, schematic.description);
|
212 | }
|
213 | config.dependencies = config.dependencies || [];
|
214 | if (dependencies) {
|
215 | config.dependencies.unshift(...dependencies);
|
216 | }
|
217 | return taskScheduler.schedule(config);
|
218 | }
|
219 | return context;
|
220 | }
|
221 | createSchematic(name, collection, allowPrivate = false) {
|
222 | const schematicMap = this._schematicCache.get(collection);
|
223 | let schematic = schematicMap === null || schematicMap === void 0 ? void 0 : schematicMap.get(name);
|
224 | if (schematic) {
|
225 | return schematic;
|
226 | }
|
227 | let collectionDescription = collection.description;
|
228 | let description = this._host.createSchematicDescription(name, collection.description);
|
229 | if (!description) {
|
230 | if (collection.baseDescriptions) {
|
231 | for (const base of collection.baseDescriptions) {
|
232 | description = this._host.createSchematicDescription(name, base);
|
233 | if (description) {
|
234 | collectionDescription = base;
|
235 | break;
|
236 | }
|
237 | }
|
238 | }
|
239 | if (!description) {
|
240 |
|
241 | throw new UnknownSchematicException(name, collection.description);
|
242 | }
|
243 | }
|
244 | if (description.private && !allowPrivate) {
|
245 | throw new PrivateSchematicException(name, collection.description);
|
246 | }
|
247 | const factory = this._host.getSchematicRuleFactory(description, collectionDescription);
|
248 | schematic = new schematic_1.SchematicImpl(description, factory, collection, this);
|
249 | schematicMap === null || schematicMap === void 0 ? void 0 : schematicMap.set(name, schematic);
|
250 | return schematic;
|
251 | }
|
252 | listSchematicNames(collection, includeHidden) {
|
253 | const names = this._host.listSchematicNames(collection.description, includeHidden);
|
254 | if (collection.baseDescriptions) {
|
255 | for (const base of collection.baseDescriptions) {
|
256 | names.push(...this._host.listSchematicNames(base, includeHidden));
|
257 | }
|
258 | }
|
259 |
|
260 | return [...new Set(names)].sort();
|
261 | }
|
262 | transformOptions(schematic, options, context) {
|
263 | return this._host.transformOptions(schematic.description, options, context);
|
264 | }
|
265 | createSourceFromUrl(url, context) {
|
266 | switch (url.protocol) {
|
267 | case 'null:':
|
268 | return () => new null_1.NullTree();
|
269 | case 'empty:':
|
270 | return () => (0, static_1.empty)();
|
271 | default:
|
272 | const hostSource = this._host.createSourceFromUrl(url, context);
|
273 | if (!hostSource) {
|
274 | throw new UnknownUrlSourceProtocol(url.toString());
|
275 | }
|
276 | return hostSource;
|
277 | }
|
278 | }
|
279 | executePostTasks() {
|
280 | const executors = new Map();
|
281 | const taskObservable = (0, rxjs_1.from)(this._taskSchedulers).pipe((0, operators_1.concatMap)((scheduler) => scheduler.finalize()), (0, operators_1.concatMap)((task) => {
|
282 | const { name, options } = task.configuration;
|
283 | const executor = executors.get(name);
|
284 | if (executor) {
|
285 | return executor(options, task.context);
|
286 | }
|
287 | return this._host.createTaskExecutor(name).pipe((0, operators_1.concatMap)((executor) => {
|
288 | executors.set(name, executor);
|
289 | return executor(options, task.context);
|
290 | }));
|
291 | }));
|
292 | return taskObservable;
|
293 | }
|
294 | }
|
295 | exports.SchematicEngine = SchematicEngine;
|