1 | "use strict";
|
2 | var __extends = (this && this.__extends) || (function () {
|
3 | var extendStatics = function (d, b) {
|
4 | extendStatics = Object.setPrototypeOf ||
|
5 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
6 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
7 | return extendStatics(d, b);
|
8 | };
|
9 | return function (d, b) {
|
10 | extendStatics(d, b);
|
11 | function __() { this.constructor = d; }
|
12 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
13 | };
|
14 | })();
|
15 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
16 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
17 | return new (P || (P = Promise))(function (resolve, reject) {
|
18 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
19 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
20 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
21 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
22 | });
|
23 | };
|
24 | var __generator = (this && this.__generator) || function (thisArg, body) {
|
25 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
26 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
27 | function verb(n) { return function (v) { return step([n, v]); }; }
|
28 | function step(op) {
|
29 | if (f) throw new TypeError("Generator is already executing.");
|
30 | while (_) try {
|
31 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
32 | if (y = 0, t) op = [op[0] & 2, t.value];
|
33 | switch (op[0]) {
|
34 | case 0: case 1: t = op; break;
|
35 | case 4: _.label++; return { value: op[1], done: false };
|
36 | case 5: _.label++; y = op[1]; op = [0]; continue;
|
37 | case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
38 | default:
|
39 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
40 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
41 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
42 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
43 | if (t[2]) _.ops.pop();
|
44 | _.trys.pop(); continue;
|
45 | }
|
46 | op = body.call(thisArg, _);
|
47 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
48 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
49 | }
|
50 | };
|
51 | var __values = (this && this.__values) || function(o) {
|
52 | var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
53 | if (m) return m.call(o);
|
54 | if (o && typeof o.length === "number") return {
|
55 | next: function () {
|
56 | if (o && i >= o.length) o = void 0;
|
57 | return { value: o && o[i++], done: !o };
|
58 | }
|
59 | };
|
60 | throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
61 | };
|
62 | Object.defineProperty(exports, "__esModule", { value: true });
|
63 | var events = require("events");
|
64 | var _ = require("lodash");
|
65 | var forOf = require("object-forof");
|
66 | var DependencyManager_1 = require("./lib/DependencyManager");
|
67 | var util_1 = require("./util");
|
68 | var Loader = (function (_super) {
|
69 | __extends(Loader, _super);
|
70 | function Loader() {
|
71 | var _this = _super !== null && _super.apply(this, arguments) || this;
|
72 | _this.getNodeSource = Loader.prototype.getNodeDefinitionFrom;
|
73 | _this.dependencyManager = new DependencyManager_1.DependencyManager();
|
74 | _this.nodeDefinitions = {};
|
75 | return _this;
|
76 | }
|
77 | Loader.prototype.load = function (_flows, _update) {
|
78 | return __awaiter(this, void 0, void 0, function () {
|
79 | var flows, workload;
|
80 | return __generator(this, function (_a) {
|
81 | flows = Array.isArray(_flows) ? _flows : [_flows];
|
82 | workload = this.getWorkLoad(flows, '@', false);
|
83 | if (workload.length) {
|
84 | throw Error('Default loader expects all nodeDefinitions to be preloaded');
|
85 | }
|
86 | return [2, {
|
87 | dependencies: this.getDependencies(),
|
88 | nodeDefinitions: this.getNodeDefinitions(),
|
89 | }];
|
90 | });
|
91 | });
|
92 | };
|
93 | Loader.prototype.loadNodeDefinitionFrom = function (provider, ns, name) {
|
94 | return __awaiter(this, void 0, void 0, function () {
|
95 | var loadNodeResult, nodeDefinition, flow;
|
96 | return __generator(this, function (_a) {
|
97 | switch (_a.label) {
|
98 | case 0: return [4, this.loadNode({
|
99 | ns: ns,
|
100 | name: name,
|
101 | url: provider.replace('{ns}', ns).replace('{name}', name),
|
102 | providerLocation: provider,
|
103 | })];
|
104 | case 1:
|
105 | loadNodeResult = _a.sent();
|
106 | nodeDefinition = loadNodeResult.nodeDef;
|
107 | if (nodeDefinition.dependencies) {
|
108 | this.dependencyManager.parseDependencies(nodeDefinition);
|
109 | }
|
110 | this.setNodeDefinition(provider, nodeDefinition);
|
111 | if (!(nodeDefinition.type === 'flow')) return [3, 3];
|
112 | flow = nodeDefinition;
|
113 | return [4, this.load([flow])];
|
114 | case 2:
|
115 | _a.sent();
|
116 | return [2, {
|
117 | nodeDefinition: nodeDefinition,
|
118 | dependencies: util_1.loadDependencies(nodeDefinition, this.getNodeDefinitions()),
|
119 | }];
|
120 | case 3: return [2, {
|
121 | nodeDefinition: nodeDefinition,
|
122 | dependencies: util_1.loadDependencies(nodeDefinition, this.getNodeDefinitions()),
|
123 | }];
|
124 | }
|
125 | });
|
126 | });
|
127 | };
|
128 | Loader.prototype.loadNode = function (providerDef) {
|
129 | return __awaiter(this, void 0, void 0, function () {
|
130 | var providerLocation, ns, name, nodeDef;
|
131 | return __generator(this, function (_a) {
|
132 | providerLocation = providerDef.providerLocation, ns = providerDef.ns, name = providerDef.name;
|
133 | nodeDef = this.getNodeDefinitionFrom(providerLocation, ns, name);
|
134 | if (nodeDef) {
|
135 | return [2, {
|
136 | providerLocation: providerLocation,
|
137 | nodeDef: nodeDef,
|
138 | }];
|
139 | }
|
140 | throw Error("Could not load node " + ns + ":" + name + " from " + providerLocation);
|
141 | });
|
142 | });
|
143 | };
|
144 | Loader.prototype.getWorkLoad = function (flows, defaultProvider, update) {
|
145 | var _this = this;
|
146 | var willLoad = [];
|
147 | var workload = [];
|
148 | flows.forEach(function (flow) {
|
149 | var e_1, _a;
|
150 | _this.initProviderMap(flow, defaultProvider);
|
151 | try {
|
152 | for (var _b = __values(flow.nodes), _c = _b.next(); !_c.done; _c = _b.next()) {
|
153 | var node = _c.value;
|
154 | var providerLocation = void 0;
|
155 | var remote = void 0;
|
156 | var provider = node.provider ? node.provider : '@';
|
157 | if (!util_1.isProviderHandle(provider)) {
|
158 | providerLocation = provider;
|
159 | remote = true;
|
160 | }
|
161 | else {
|
162 | if (!flow.providers || !flow.providers.hasOwnProperty(provider)) {
|
163 | throw Error([
|
164 | 'Node',
|
165 | node.ns + ':' + node.name,
|
166 | 'refers to unknown provider',
|
167 | provider,
|
168 | '\n\tplease specify it in the providers section',
|
169 | ].join(' '));
|
170 | }
|
171 | if (flow.providers[provider].hasOwnProperty('path')) {
|
172 | providerLocation = flow.providers[provider].path;
|
173 | remote = false;
|
174 | }
|
175 | else if (flow.providers[provider].hasOwnProperty('url')) {
|
176 | providerLocation = flow.providers[provider].url;
|
177 | remote = true;
|
178 | }
|
179 | else {
|
180 | throw Error("Do not know how to handle: " + provider);
|
181 | }
|
182 | }
|
183 | if (!_this.hasNodeDefinition(providerLocation, node.ns, node.name) &&
|
184 | !update) {
|
185 | var location_1 = providerLocation
|
186 | .replace('{ns}', node.ns)
|
187 | .replace('{name}', node.name);
|
188 | if (willLoad.indexOf(location_1) === -1) {
|
189 | willLoad.push(location_1);
|
190 | if (remote) {
|
191 | workload.push({
|
192 | url: location_1,
|
193 | ns: node.ns,
|
194 | name: node.name,
|
195 | providerLocation: providerLocation,
|
196 | });
|
197 | }
|
198 | else {
|
199 | workload.push({
|
200 | path: location_1,
|
201 | ns: node.ns,
|
202 | name: node.name,
|
203 | providerLocation: providerLocation,
|
204 | });
|
205 | }
|
206 | }
|
207 | }
|
208 | }
|
209 | }
|
210 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
211 | finally {
|
212 | try {
|
213 | if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
214 | }
|
215 | finally { if (e_1) throw e_1.error; }
|
216 | }
|
217 | });
|
218 | return workload;
|
219 | };
|
220 | Loader.prototype.saveNodeDefinition = function (_providerLocation, _nodeDefinition) {
|
221 | throw new Error([this.constructor.name, 'must implement a save method'].join(' '));
|
222 | };
|
223 | Loader.prototype.hasDependencies = function (type) {
|
224 | return this.dependencyManager.hasDependencies(type);
|
225 | };
|
226 | Loader.prototype.getDependencies = function (type) {
|
227 | return this.dependencyManager.getDependencies(type);
|
228 | };
|
229 | Loader.prototype.setDependencies = function (dependencies) {
|
230 | return this.dependencyManager.setDependencies(dependencies);
|
231 | };
|
232 | Loader.prototype.initProviderMap = function (flow, defaultProvider) {
|
233 | if (!flow.providers) {
|
234 | flow.providers = {};
|
235 | }
|
236 | if (!flow.providers['@']) {
|
237 | flow.providers['@'] = { url: defaultProvider };
|
238 | }
|
239 | for (var key in flow.providers) {
|
240 | if (flow.providers.hasOwnProperty(key)) {
|
241 | var provider = flow.providers[key];
|
242 | if (util_1.isRemoteProvider(provider)) {
|
243 | if (!this.nodeDefinitions.hasOwnProperty(provider.url)) {
|
244 | this.nodeDefinitions[provider.url] = {};
|
245 | }
|
246 | }
|
247 | else if (util_1.isFSProvider(provider)) {
|
248 | if (!this.nodeDefinitions.hasOwnProperty(provider.path)) {
|
249 | this.nodeDefinitions[provider.path] = {};
|
250 | }
|
251 | }
|
252 | }
|
253 | }
|
254 | };
|
255 | Loader.prototype.addNodeDefinitions = function (identifier, nodeDefs) {
|
256 | var e_2, _a;
|
257 | var _this = this;
|
258 | if (Array.isArray(nodeDefs)) {
|
259 | try {
|
260 | for (var nodeDefs_1 = __values(nodeDefs), nodeDefs_1_1 = nodeDefs_1.next(); !nodeDefs_1_1.done; nodeDefs_1_1 = nodeDefs_1.next()) {
|
261 | var nodeDef = nodeDefs_1_1.value;
|
262 | this.addNodeDefinition(identifier, nodeDef);
|
263 | }
|
264 | }
|
265 | catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
266 | finally {
|
267 | try {
|
268 | if (nodeDefs_1_1 && !nodeDefs_1_1.done && (_a = nodeDefs_1.return)) _a.call(nodeDefs_1);
|
269 | }
|
270 | finally { if (e_2) throw e_2.error; }
|
271 | }
|
272 | }
|
273 | else {
|
274 | forOf(function (_ns, _name, nodeDefinition) {
|
275 | _this.addNodeDefinition(identifier, nodeDefinition);
|
276 | }, nodeDefs);
|
277 | }
|
278 | };
|
279 | Loader.prototype.addNodeDefinition = function (identifier, nodeDef) {
|
280 | if (!nodeDef.hasOwnProperty('ns')) {
|
281 | throw new Error(['Node definition for', identifier, 'lacks an ns property'].join(' '));
|
282 | }
|
283 | if (!nodeDef.hasOwnProperty('name')) {
|
284 | throw new Error(['Node definition for', identifier, 'lacks an name property'].join(' '));
|
285 | }
|
286 | nodeDef.provider = identifier;
|
287 | if (nodeDef.type === 'flow') {
|
288 | if (!nodeDef.providers || Object.keys(nodeDef.providers).length === 0) {
|
289 | nodeDef.providers = {
|
290 | '@': {
|
291 | url: identifier,
|
292 | },
|
293 | };
|
294 | }
|
295 | }
|
296 | else {
|
297 | this.dependencyManager.parseDependencies(nodeDef);
|
298 | }
|
299 | this.setNodeDefinition(identifier, nodeDef);
|
300 | };
|
301 | Loader.prototype.setNodeDefinition = function (provider, nodeDefinition) {
|
302 | var ns = nodeDefinition.ns, name = nodeDefinition.name;
|
303 | _.setWith(this.nodeDefinitions, [provider, ns, name], nodeDefinition, Object);
|
304 | };
|
305 | Loader.prototype.setNodeDefinitions = function (nodeDefinitions) {
|
306 | if (this.hasNodeDefinitions()) {
|
307 | throw Error('Node Definitions already set, only use this method to pre-populate the nodeDefinitions');
|
308 | }
|
309 | this.nodeDefinitions = nodeDefinitions;
|
310 | };
|
311 | Loader.prototype.hasNodeDefinition = function (providerUrl, ns, name) {
|
312 | return (this.nodeDefinitions.hasOwnProperty(providerUrl) &&
|
313 | this.nodeDefinitions[providerUrl].hasOwnProperty(ns) &&
|
314 | this.nodeDefinitions[providerUrl][ns].hasOwnProperty(name));
|
315 | };
|
316 | Loader.prototype.hasNodeDefinitions = function (provider) {
|
317 | if (provider) {
|
318 | return Boolean(this.nodeDefinitions[provider]);
|
319 | }
|
320 | return Object.keys(this.nodeDefinitions).length > 0;
|
321 | };
|
322 | Loader.prototype.getNodeDefinition = function (node, flow) {
|
323 | return __awaiter(this, void 0, void 0, function () {
|
324 | var definition;
|
325 | return __generator(this, function (_a) {
|
326 | switch (_a.label) {
|
327 | case 0: return [4, this.loadNodeDefinition(node, flow)];
|
328 | case 1:
|
329 | definition = _a.sent();
|
330 | if (!(definition.type === 'flow')) return [3, 3];
|
331 | return [4, this.mergeSchema(definition)];
|
332 | case 2:
|
333 | _a.sent();
|
334 | _a.label = 3;
|
335 | case 3: return [2, definition];
|
336 | }
|
337 | });
|
338 | });
|
339 | };
|
340 | Loader.prototype.resolveProvider = function (node, flow) {
|
341 | var location;
|
342 | var provider;
|
343 | if (node.provider && util_1.isUri(node.provider)) {
|
344 | location = node.provider;
|
345 | }
|
346 | else if (!node.provider && (!flow || !flow.providers)) {
|
347 | location = '@';
|
348 | }
|
349 | else {
|
350 | if (!flow) {
|
351 | throw Error('loadNodeDefinition needs a map or a node with a full provider url');
|
352 | }
|
353 | if (!flow.providers) {
|
354 | throw Error('loadNodeDefinition expects flow to container .providers');
|
355 | }
|
356 | provider = node.provider
|
357 | ?
|
358 | flow.providers[node.provider]
|
359 | : flow.providers['@'];
|
360 | if (!provider) {
|
361 | for (var key in flow.providers) {
|
362 | if (_.get(flow, ['providers', key, 'url']) === node.provider ||
|
363 | _.get(flow, ['providers', key, 'path']) === node.provider) {
|
364 | provider = flow.providers[key];
|
365 | }
|
366 | }
|
367 | if (!provider) {
|
368 | throw Error('unable to find provider');
|
369 | }
|
370 | }
|
371 | if (provider.hasOwnProperty('path')) {
|
372 | location = provider.path;
|
373 | }
|
374 | else if (provider.hasOwnProperty('url')) {
|
375 | location = provider.url;
|
376 | }
|
377 | else {
|
378 | throw new Error('Do not know how to handle provider');
|
379 | }
|
380 | }
|
381 | return location;
|
382 | };
|
383 | Loader.prototype.loadNodeDefinition = function (node, flow) {
|
384 | return __awaiter(this, void 0, void 0, function () {
|
385 | var location;
|
386 | return __generator(this, function (_a) {
|
387 | switch (_a.label) {
|
388 | case 0:
|
389 | location = this.resolveProvider(node, flow);
|
390 | if (!!this.hasNodeDefinition(location, node.ns, node.name)) return [3, 2];
|
391 | return [4, this.load(flow)];
|
392 | case 1:
|
393 | _a.sent();
|
394 | _a.label = 2;
|
395 | case 2: return [2, this.nodeDefinitions[location][node.ns][node.name]];
|
396 | }
|
397 | });
|
398 | });
|
399 | };
|
400 | Loader.prototype.getNodeDefinitionFrom = function (provider, ns, name) {
|
401 | if (this.hasNodeDefinition(provider, ns, name)) {
|
402 | return this.nodeDefinitions[provider][ns][name];
|
403 | }
|
404 | throw Error("Unable to find node definition for " + ns + ":" + name);
|
405 | };
|
406 | Loader.prototype.getNodeDefinitions = function (provider) {
|
407 | if (provider) {
|
408 | return this.nodeDefinitions[provider];
|
409 | }
|
410 | else {
|
411 | return this.nodeDefinitions;
|
412 | }
|
413 | };
|
414 | Loader.prototype.isResolved = function (flow) {
|
415 | var e_3, _a;
|
416 | var seen = [];
|
417 | try {
|
418 | for (var _b = __values(flow.nodes), _c = _b.next(); !_c.done; _c = _b.next()) {
|
419 | var node = _c.value;
|
420 | if (!this.hasNodeDefinition('@', node.ns, node.name)) {
|
421 | return false;
|
422 | }
|
423 | var nodeDefinition = this.getNodeDefinitionFrom('@', node.ns, node.name);
|
424 | var identifier = nodeDefinition.ns + ":" + nodeDefinition.name;
|
425 | if (nodeDefinition.type === 'flow' &&
|
426 | seen.indexOf(identifier) === -1) {
|
427 | seen.push(identifier);
|
428 | return this.isResolved(nodeDefinition);
|
429 | }
|
430 | }
|
431 | }
|
432 | catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
433 | finally {
|
434 | try {
|
435 | if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
436 | }
|
437 | finally { if (e_3) throw e_3.error; }
|
438 | }
|
439 | return true;
|
440 | };
|
441 | Loader.prototype.getUnresolved = function (flow) {
|
442 | var self = this;
|
443 | var unresolved = [];
|
444 | var seen = [];
|
445 | function resolveDefinitions(flowDefinition) {
|
446 | var e_4, _a;
|
447 | try {
|
448 | for (var _b = __values(flowDefinition.nodes), _c = _b.next(); !_c.done; _c = _b.next()) {
|
449 | var node = _c.value;
|
450 | if (!self.hasNodeDefinition('@', node.ns, node.name)) {
|
451 | unresolved.push(node);
|
452 | }
|
453 | else {
|
454 | var nodeDefinition = self.getNodeDefinitionFrom('@', node.ns, node.name);
|
455 | var identifier = nodeDefinition.ns + ":" + nodeDefinition.name;
|
456 | if (nodeDefinition.type === 'flow' &&
|
457 | seen.indexOf(identifier) === -1) {
|
458 | seen.push(identifier);
|
459 | resolveDefinitions(nodeDefinition);
|
460 | }
|
461 | }
|
462 | }
|
463 | }
|
464 | catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
465 | finally {
|
466 | try {
|
467 | if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
468 | }
|
469 | finally { if (e_4) throw e_4.error; }
|
470 | }
|
471 | }
|
472 | resolveDefinitions(flow);
|
473 | return unresolved;
|
474 | };
|
475 | Loader.prototype.mergeSchema = function (graph) {
|
476 | return __awaiter(this, void 0, void 0, function () {
|
477 | var _this = this;
|
478 | return __generator(this, function (_a) {
|
479 | return [2, Promise.all(forOf(function (type, port, externalPort) { return __awaiter(_this, void 0, void 0, function () {
|
480 | var internalDef, copy;
|
481 | return __generator(this, function (_a) {
|
482 | switch (_a.label) {
|
483 | case 0:
|
484 | if (!externalPort.hasOwnProperty('nodeId')) return [3, 2];
|
485 | return [4, this.getNodeDefinition(util_1.findNodeWithinGraph(externalPort.nodeId, graph), graph)];
|
486 | case 1:
|
487 | internalDef = (_a.sent());
|
488 | if (!_.has(internalDef, ['ports', type, externalPort.name])) {
|
489 | throw Error("External Port points to non-existent internal port");
|
490 | }
|
491 | copy = JSON.parse(JSON.stringify(_.get(internalDef, ['ports', type, externalPort.name])));
|
492 | copy.title = externalPort.title;
|
493 | copy.name = externalPort.name;
|
494 | copy.nodeId = externalPort.nodeId;
|
495 | _.setWith(graph, ['ports', type, port], copy, Object);
|
496 | return [2, true];
|
497 | case 2: return [2, false];
|
498 | }
|
499 | });
|
500 | }); }, graph.ports))];
|
501 | });
|
502 | });
|
503 | };
|
504 | return Loader;
|
505 | }(events.EventEmitter));
|
506 | exports.Loader = Loader;
|
507 |
|
\ | No newline at end of file |