UNPKG

12.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var _ = require("lodash");
4var forOf = require("object-forof");
5var util_1 = require("../util");
6var NodeDefinitionManager = /** @class */ (function () {
7 function NodeDefinitionManager(dependencyManager) {
8 /**
9 *
10 * Format:
11 *
12 * Keeps track of all known nodeDefinitions.
13 *
14 * {
15 * 'http://....': { // url in this case is the identifier
16 *
17 * fs: {
18 * readFile: <definition>
19 * writeFile: <definition>
20 * }
21 *
22 * }
23 *
24 * }
25 *
26 */
27 this.nodeDefinitions = {};
28 this.dependencyManager = dependencyManager;
29 }
30 NodeDefinitionManager.prototype.initProviderMap = function (flow, defaultProvider) {
31 if (!flow.providers) {
32 flow.providers = {};
33 }
34 if (!flow.providers['@']) {
35 flow.providers['@'] = { url: defaultProvider };
36 }
37 for (var key in flow.providers) {
38 if (flow.providers.hasOwnProperty(key)) {
39 var provider = flow.providers[key];
40 if (util_1.isRemoteProvider(provider)) {
41 if (!this.nodeDefinitions.hasOwnProperty(provider.url)) {
42 this.nodeDefinitions[provider.url] = {};
43 }
44 }
45 else if (util_1.isFSProvider(provider)) {
46 if (!this.nodeDefinitions.hasOwnProperty(provider.path)) {
47 this.nodeDefinitions[provider.path] = {};
48 }
49 }
50 }
51 }
52 };
53 /**
54 *
55 * Add node definitions
56 *
57 * Used to `statically` add nodeDefinitions.
58 *
59 * @param {String} identifier
60 * @param {Object} nodeDefs
61 * @api public
62 */
63 NodeDefinitionManager.prototype.addNodeDefinitions = function (identifier, nodeDefs) {
64 var _this = this;
65 if (Array.isArray(nodeDefs)) {
66 for (var i = 0; i < nodeDefs.length; i++) {
67 this.addNodeDefinition(identifier, nodeDefs[i]);
68 }
69 }
70 else {
71 forOf(function (_ns, _name, nodeDefinition) {
72 _this.addNodeDefinition(identifier, nodeDefinition);
73 }, nodeDefs);
74 }
75 };
76 /**
77 *
78 * Add a node definition
79 *
80 * @param {String} identifier
81 * @param {Object} nodeDef
82 * @api public
83 */
84 NodeDefinitionManager.prototype.addNodeDefinition = function (identifier, nodeDef) {
85 if (!nodeDef.hasOwnProperty('ns')) {
86 throw new Error([
87 'Nodefinition for',
88 identifier,
89 'lacks an ns property'
90 ].join(' '));
91 }
92 if (!nodeDef.hasOwnProperty('name')) {
93 throw new Error([
94 'Nodefinition for',
95 identifier,
96 'lacks an name property'
97 ].join(' '));
98 }
99 // store the provider url along with the nodeDefinition
100 // Needed for fetching back from storage.
101 nodeDef.provider = identifier;
102 if (nodeDef.type === 'flow') {
103 if (!nodeDef.providers || Object.keys(nodeDef.providers).length === 0) {
104 nodeDef.providers = {
105 '@': {
106 url: identifier
107 }
108 };
109 }
110 }
111 else {
112 this.dependencyManager.parseDependencies(nodeDef);
113 }
114 this.setNodeDefinition(identifier, nodeDef);
115 };
116 NodeDefinitionManager.prototype.setNodeDefinitions = function (nodeDefinitions) {
117 if (this.hasNodeDefinitions()) {
118 throw Error('Node Definitions already set, only use this method to prepopulate the nodeDefinitions');
119 }
120 this.nodeDefinitions = nodeDefinitions;
121 };
122 NodeDefinitionManager.prototype.hasNodeDefinitions = function (provider) {
123 if (provider) {
124 return Boolean(this.nodeDefinitions[provider]);
125 }
126 return Object.keys(this.nodeDefinitions).length > 0;
127 };
128 NodeDefinitionManager.prototype.setNodeDefinition = function (provider, nodeDefinition) {
129 var ns = nodeDefinition.ns, name = nodeDefinition.name;
130 _.set(this.nodeDefinitions, [provider, ns, name], nodeDefinition);
131 };
132 /**
133 *
134 * Check whether we have the definition
135 *
136 * @param {String} providerUrl
137 * @param {String} ns
138 * @param {String} name
139 * @api public
140 */
141 NodeDefinitionManager.prototype.hasNodeDefinition = function (providerUrl, ns, name) {
142 return this.nodeDefinitions.hasOwnProperty(providerUrl) &&
143 this.nodeDefinitions[providerUrl].hasOwnProperty(ns) &&
144 this.nodeDefinitions[providerUrl][ns].hasOwnProperty(name);
145 };
146 /**
147 * Loads the NodeDefinition for a node.
148 *
149 * In order to do so each node must know the provider url it was loaded from.
150 *
151 * This is normally not stored directly into flows, but the flow is saved with the namespaces in use.
152 *
153 * TODO: this really should just be (provider, name, ns, version) else use the load method.
154 */
155 NodeDefinitionManager.prototype.getNodeDefinition = function (node, flow) {
156 var definition = this.loadNodeDefinition(node, flow);
157 // merge the schema of the internal node.
158 if (definition.type === 'flow') {
159 this.mergeSchema(definition); // in place
160 }
161 return definition;
162 };
163 NodeDefinitionManager.prototype.loadNodeDefinition = function (node, flow) {
164 var location;
165 var provider;
166 if (node.provider &&
167 util_1.isUri(node.provider)) {
168 // it's already an url
169 location = node.provider;
170 }
171 else if (!node.provider && (!flow || !flow.providers)) {
172 // for direct additions (only @ is possible)
173 location = '@';
174 }
175 else {
176 if (!flow) {
177 throw Error('loadNodeDefinition needs a map or a node with a full provider url');
178 }
179 if (!flow.providers) {
180 throw Error('loadNodeDefinition expects flow to container .providers');
181 }
182 if (node.provider) {
183 // 'x': ..
184 provider = flow.providers[node.provider];
185 }
186 else {
187 provider = flow.providers['@'];
188 }
189 // fix: find provider by path or url, has to do with provider
190 // already resolved (sub.sub.graphs)
191 if (!provider) {
192 for (var key in flow.providers) {
193 if (_.get(flow, ['providers', key, 'url']) === node.provider ||
194 _.get(flow, ['providers', key, 'path']) === node.provider) {
195 provider = flow.providers[key];
196 }
197 }
198 if (!provider) {
199 throw Error('unable to find provider');
200 }
201 }
202 if (provider.hasOwnProperty('path')) {
203 location = provider.path;
204 }
205 else if (provider.hasOwnProperty('url')) {
206 location = provider.url;
207 }
208 else {
209 throw new Error('Do not know how to handle provider');
210 }
211 node.provider = location;
212 }
213 if (!this.hasNodeDefinition(location, node.ns, node.name)) {
214 // not sure.. node has a full url.
215 // but it's not loaded, then we ask to load the full map.
216 // which works if provider is x but not if it's already expanded.
217 console.log("NodeDefinition " + location + "->" + node.ns + ":" + node.name + " is not available.");
218 throw Error('Should load node definition');
219 // console.error('Should load node definition')
220 // proceed, but this is a bug, load() was activate before.
221 // but also hardly does anything in the context of just Loader.
222 // .. Behavior should be a hard fail, because the loader
223 // must be instructed to preload everything either using
224 // the async functions preload or load
225 /*
226 await this.load(flow, function () {
227 callback(nodeDefinitions[location][node.ns][node.name])
228 })
229
230 return false
231 */
232 }
233 return this.nodeDefinitions[location][node.ns][node.name];
234 };
235 NodeDefinitionManager.prototype.getNodeDefinitionFrom = function (provider, ns, name) {
236 if (this.hasNodeDefinition(provider, ns, name)) {
237 return this.nodeDefinitions[provider][ns][name];
238 }
239 throw Error("Unable to find node definition for " + ns + ":" + name);
240 };
241 NodeDefinitionManager.prototype.saveNodeDefinition = function (_providerLocation, _nodeDefinition) {
242 throw new Error([
243 this.constructor.name,
244 'must implement a save method'
245 ].join(' '));
246 };
247 /**
248 * Get Nodedefinitions
249 *
250 * Optionally with a provider url so it returns only the node definitions
251 * at that provider.
252 *
253 * @param {String} provider (Optional)
254 */
255 NodeDefinitionManager.prototype.getNodeDefinitions = function (provider) {
256 if (provider) {
257 return this.nodeDefinitions[provider];
258 }
259 else {
260 return this.nodeDefinitions;
261 }
262 };
263 /**
264 * Test whether all nodes used by this flow are resolvable
265 *
266 * @param {FlowDefinition} flow
267 * @returns {boolean}
268 */
269 NodeDefinitionManager.prototype.isResolved = function (flow) {
270 var seen = [];
271 for (var j = 0; j < flow.nodes.length; j++) {
272 var node = flow.nodes[j];
273 if (!this.hasNodeDefinition('@', node.ns, node.name)) {
274 return false;
275 }
276 var nodeDefinition = this.getNodeDefinitionFrom('@', node.ns, node.name);
277 var identifier = nodeDefinition.ns + ":" + nodeDefinition.name;
278 if (nodeDefinition.type === 'flow' &&
279 seen.indexOf(identifier) === -1) {
280 seen.push(identifier);
281 return this.isResolved(nodeDefinition);
282 }
283 }
284 return true;
285 };
286 NodeDefinitionManager.prototype.getUnresolved = function (flow) {
287 var self = this;
288 var unresolved = [];
289 var seen = [];
290 function resolveDefinitions(flow) {
291 for (var j = 0; j < flow.nodes.length; j++) {
292 var node = flow.nodes[j];
293 if (!self.hasNodeDefinition('@', node.ns, node.name)) {
294 unresolved.push(node);
295 }
296 else {
297 var nodeDefinition = self.getNodeDefinitionFrom('@', node.ns, node.name);
298 var identifier = nodeDefinition.ns + ":" + nodeDefinition.name;
299 if (nodeDefinition.type === 'flow' &&
300 seen.indexOf(identifier) === -1) {
301 seen.push(identifier);
302 resolveDefinitions(nodeDefinition);
303 }
304 }
305 }
306 }
307 resolveDefinitions(flow);
308 return unresolved;
309 };
310 NodeDefinitionManager.prototype.mergeSchema = function (graph) {
311 var _this = this;
312 forOf(function (type, port, externalPort) {
313 if (externalPort.hasOwnProperty('nodeId')) {
314 // TODO: should go recursive if internal node is a flow, in able to get the correct type.
315 var internalDef = _this.getNodeDefinition(util_1.findNodeWithinGraph(externalPort.nodeId, graph), graph);
316 if (!_.has(internalDef, ['ports', type, externalPort.name])) {
317 throw Error("External Port points to non-existent internal port");
318 }
319 var copy = JSON.parse(JSON.stringify(_.get(internalDef, ['ports', type, externalPort.name])));
320 copy.title = externalPort.title;
321 copy.name = externalPort.name;
322 copy.nodeId = externalPort.nodeId;
323 _.set(graph, ['ports', type, port], copy);
324 }
325 else {
326 // not pointing to an internal node. :start etc.
327 }
328 }, graph.ports);
329 };
330 return NodeDefinitionManager;
331}());
332exports.NodeDefinitionManager = NodeDefinitionManager;
333//# sourceMappingURL=NodeDefinitionManager.js.map
\No newline at end of file