Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

noflo

Package Overview
Dependencies
Maintainers
1
Versions
91
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

noflo - npm Package Compare versions

Comparing version 1.2.1 to 1.2.2

spec/fixtures/componentloader/components/Repeat.ts

6

CHANGES.md
NoFlo ChangeLog
===============
## 1.2.2 (September 17th 2020)
* Added initial support for components written in TypeScript. Requires the `typescript` module to be installed
* NoFlo ComponentLoader can now tell the supported programming languages with the `getLanguages` method
* Components written with `setSource` now return the original untranspiled source code with `getSource` also on Node.js
## 1.2.1 (September 16th 2020)

@@ -5,0 +11,0 @@

22

lib/ComponentLoader.js

@@ -144,2 +144,7 @@ "use strict";

registerLoader.register(this, function (err) {
_this2.processing = false;
_this2.ready = true;
_this2.emit('ready', true);
if (err) {

@@ -150,7 +155,2 @@ callback(err);

_this2.processing = false;
_this2.ready = true;
_this2.emit('ready', true);
callback(null, _this2.components);

@@ -481,2 +481,14 @@ });

registerLoader.getSource(this, name, callback);
} // `getLanguages` gets a list of component programming languages supported by the `setSource`
// method on this runtime instance.
}, {
key: "getLanguages",
value: function getLanguages() {
if (!registerLoader.getLanguages) {
// This component loader doesn't support the method, default to normal JS
return ['javascript', 'es2015'];
}
return registerLoader.getLanguages();
}

@@ -483,0 +495,0 @@ }, {

@@ -17,13 +17,272 @@ "use strict";

var fbpGraph = require('fbp-graph'); // We allow components to be un-compiled CoffeeScript
var fbpGraph = require('fbp-graph');
var utils = require('../Utils'); // Type loading CoffeeScript compiler
var CoffeeScript = require('coffeescript');
var utils = require('../Utils');
var CoffeeScript;
if (typeof CoffeeScript.register !== 'undefined') {
CoffeeScript.register();
try {
// eslint-disable-next-line import/no-unresolved
CoffeeScript = require('coffeescript');
if (typeof CoffeeScript.register !== 'undefined') {
CoffeeScript.register();
}
} catch (e) {// If there is no CoffeeScript compiler installed, we simply don't support compiling
} // Try loading TypeScript compiler
var typescript;
try {
// eslint-disable-next-line import/no-unresolved,import/no-extraneous-dependencies
typescript = require('typescript');
} catch (e) {// If there is no TypeScript compiler installed, we simply don't support compiling
}
function transpileSource(packageId, name, source, language, callback) {
var src;
switch (language) {
case 'coffeescript':
{
if (!CoffeeScript) {
callback(new Error("Unsupported component source language ".concat(language, " for ").concat(packageId, "/").concat(name, ": no CoffeeScript compiler installed")));
}
try {
src = CoffeeScript.compile(source, {
bare: true
});
} catch (err) {
callback(err);
return;
}
break;
}
case 'typescript':
{
if (!typescript) {
callback(new Error("Unsupported component source language ".concat(language, " for ").concat(packageId, "/").concat(name, ": no TypeScript compiler installed")));
}
try {
src = typescript.transpile(source, {
compilerOptions: {
module: typescript.ModuleKind.CommonJS
}
});
} catch (err) {
callback(err);
return;
}
break;
}
case 'es6':
case 'es2015':
case 'js':
case 'javascript':
{
src = source;
break;
}
default:
{
callback(new Error("Unsupported component source language ".concat(language, " for ").concat(packageId, "/").concat(name)));
return;
}
}
callback(null, src);
}
function evaluateModule(baseDir, packageId, name, source, callback) {
var Module = require('module');
var implementation;
try {
// Use the Node.js module API to evaluate in the correct directory context
var modulePath = path.resolve(baseDir, "./components/".concat(name, ".js"));
var moduleImpl = new Module(modulePath, module);
moduleImpl.paths = Module._nodeModulePaths(path.dirname(modulePath));
moduleImpl.filename = modulePath;
moduleImpl._compile(source, modulePath);
implementation = moduleImpl.exports;
} catch (e) {
callback(e);
return;
}
if (typeof implementation !== 'function' && typeof implementation.getComponent !== 'function') {
callback(new Error("Provided source for ".concat(packageId, "/").concat(name, " failed to create a runnable component")));
return;
}
callback(null, implementation);
}
function registerSources(loader, packageId, name, source, language) {
if (!loader.sourcesForComponents) {
// eslint-disable-next-line no-param-reassign
loader.sourcesForComponents = {};
}
var componentName = "".concat(packageId, "/").concat(name); // eslint-disable-next-line no-param-reassign
loader.sourcesForComponents[componentName] = {
language: language,
source: source
};
}
function transpileAndRegisterForModule(loader, module, component, source, language, callback) {
transpileSource(module.name, component.name, source, language, function (transpileError, src) {
if (transpileError) {
callback(transpileError);
return;
}
var moduleBase = path.resolve(loader.baseDir, module.base);
evaluateModule(moduleBase, module.name, component.name, src, function (evalError, implementation) {
if (evalError) {
callback(evalError);
return;
}
registerSources(loader, module.name, component.name, source, language);
loader.registerComponent(module.name, component.name, implementation, callback);
});
});
}
exports.setSource = function setSource(loader, packageId, name, source, language, callback) {
transpileAndRegisterForModule(loader, {
name: packageId,
base: ''
}, {
name: name
}, source, language, callback);
};
exports.getSource = function getSource(loader, name, callback) {
var componentName = name;
var component = loader.components[name];
if (!component) {
// Try an alias
var keys = Object.keys(loader.components);
for (var i = 0; i < keys.length; i += 1) {
var key = keys[i];
if (key.split('/')[1] === name) {
component = loader.components[key];
componentName = key;
break;
}
}
if (!component) {
callback(new Error("Component ".concat(componentName, " not installed")));
return;
}
}
var nameParts = componentName.split('/');
if (nameParts.length === 1) {
nameParts[1] = nameParts[0];
nameParts[0] = '';
}
if (loader.isGraph(component)) {
if (_typeof(component) === 'object') {
if (typeof component.toJSON === 'function') {
callback(null, {
name: nameParts[1],
library: nameParts[0],
code: JSON.stringify(component.toJSON()),
language: 'json'
});
return;
}
callback(new Error("Can't provide source for ".concat(componentName, ". Not a file")));
return;
}
fbpGraph.graph.loadFile(component, function (err, graph) {
if (err) {
callback(err);
return;
}
if (!graph) {
callback(new Error('Unable to load graph'));
return;
}
callback(null, {
name: nameParts[1],
library: nameParts[0],
code: JSON.stringify(graph.toJSON()),
language: 'json'
});
});
return;
}
if (loader.sourcesForComponents && loader.sourcesForComponents[componentName]) {
callback(null, {
name: nameParts[1],
library: nameParts[0],
code: loader.sourcesForComponents[componentName].source,
language: loader.sourcesForComponents[componentName].language
});
return;
}
if (typeof component !== 'string') {
callback(new Error("Can't provide source for ".concat(componentName, ". Not a file")));
return;
}
fs.readFile(component, 'utf-8', function (err, code) {
if (err) {
callback(err);
return;
}
callback(null, {
name: nameParts[1],
library: nameParts[0],
language: utils.guessLanguageFromFilename(component),
code: code
});
});
};
exports.getLanguages = function getLanguages() {
var languages = ['javascript', 'es2015'];
if (CoffeeScript) {
languages.push('coffeescript');
}
if (typescript) {
languages.push('typescript');
}
return languages;
};
function registerCustomLoaders(loader, componentLoaders, callback) {

@@ -52,3 +311,3 @@ if (!componentLoaders.length) {

var componentLoaders = [];
compatible.forEach(function (m) {
Promise.all(compatible.map(function (m) {
if (m.icon) {

@@ -63,7 +322,39 @@ loader.setLibraryIcon(m.name, m.icon);

m.components.forEach(function (c) {
loader.registerComponent(m.name, c.name, path.resolve(loader.baseDir, c.path));
});
});
registerCustomLoaders(loader, componentLoaders, callback);
return Promise.all(m.components.map(function (c) {
return new Promise(function (resolve, reject) {
var language = utils.guessLanguageFromFilename(c.path);
if (language === 'typescript') {
// We can't require a TypeScript module, go the setSource route
fs.readFile(path.resolve(loader.baseDir, c.path), 'utf-8', function (fsErr, source) {
if (fsErr) {
reject(fsErr);
return;
}
transpileAndRegisterForModule(loader, m, c, source, language, function (err) {
if (err) {
reject(err);
return;
}
resolve();
});
});
return;
}
loader.registerComponent(m.name, c.name, path.resolve(loader.baseDir, c.path), function (err) {
if (err) {
reject(err);
return;
}
resolve();
});
});
}));
})).then(function () {
registerCustomLoaders(loader, componentLoaders, callback);
}, callback);
}

@@ -233,131 +524,2 @@

callback(null, instance);
};
exports.setSource = function setSource(loader, packageId, name, source, language, callback) {
var Module = require('module');
var src = source;
if (language === 'coffeescript') {
try {
src = CoffeeScript.compile(src, {
bare: true
});
} catch (err) {
callback(err);
return;
}
}
var implementation;
try {
// Use the Node.js module API to evaluate in the correct directory context
var modulePath = path.resolve(loader.baseDir, "./components/".concat(name, ".js"));
var moduleImpl = new Module(modulePath, module);
moduleImpl.paths = Module._nodeModulePaths(path.dirname(modulePath));
moduleImpl.filename = modulePath;
moduleImpl._compile(src, modulePath);
implementation = moduleImpl.exports;
} catch (err) {
callback(err);
return;
}
if (typeof implementation !== 'function' && typeof implementation.getComponent !== 'function') {
callback(new Error('Provided source failed to create a runnable component'));
return;
}
loader.registerComponent(packageId, name, implementation, callback);
};
exports.getSource = function getSource(loader, name, callback) {
var componentName = name;
var component = loader.components[name];
if (!component) {
// Try an alias
var keys = Object.keys(loader.components);
for (var i = 0; i < keys.length; i += 1) {
var key = keys[i];
if (key.split('/')[1] === name) {
component = loader.components[key];
componentName = key;
break;
}
}
if (!component) {
callback(new Error("Component ".concat(componentName, " not installed")));
return;
}
}
var nameParts = componentName.split('/');
if (nameParts.length === 1) {
nameParts[1] = nameParts[0];
nameParts[0] = '';
}
if (loader.isGraph(component)) {
if (_typeof(component) === 'object') {
if (typeof component.toJSON === 'function') {
callback(null, {
name: nameParts[1],
library: nameParts[0],
code: JSON.stringify(component.toJSON()),
language: 'json'
});
return;
}
callback(new Error("Can't provide source for ".concat(componentName, ". Not a file")));
return;
}
fbpGraph.graph.loadFile(component, function (err, graph) {
if (err) {
callback(err);
return;
}
if (!graph) {
callback(new Error('Unable to load graph'));
return;
}
callback(null, {
name: nameParts[1],
library: nameParts[0],
code: JSON.stringify(graph.toJSON()),
language: 'json'
});
});
return;
}
if (typeof component !== 'string') {
callback(new Error("Can't provide source for ".concat(componentName, ". Not a file")));
return;
}
fs.readFile(component, 'utf-8', function (err, code) {
if (err) {
callback(err);
return;
}
callback(null, {
name: nameParts[1],
library: nameParts[0],
language: utils.guessLanguageFromFilename(component),
code: code
});
});
};

@@ -17,2 +17,6 @@ "use strict";

if (/.*\.ts$/.test(filename)) {
return 'typescript';
}
return 'javascript';

@@ -19,0 +23,0 @@ }

@@ -11,3 +11,3 @@ {

"author": "Henri Bergius <henri.bergius@iki.fi>",
"version": "1.2.1",
"version": "1.2.2",
"license": "MIT",

@@ -22,3 +22,3 @@ "engines": {

"fbp-graph": "^0.4.0",
"fbp-manifest": "^0.2.0",
"fbp-manifest": "^0.2.2",
"get-function-params": "^2.0.6"

@@ -41,4 +41,5 @@ },

"mocha": "^7.2.0",
"noflo-component-loader": "^0.3.2",
"noflo-component-loader": "^0.3.3",
"nyc": "^15.1.0",
"typescript": "^4.0.2",
"webpack": "^4.44.1",

@@ -45,0 +46,0 @@ "webpack-cli": "^3.3.12"

@@ -379,8 +379,2 @@ /* eslint-disable

describe('reading sources', () => {
before(function () {
// getSource not implemented in webpack loader yet
if (noflo.isBrowser()) {
this.skip();
}
});
it('should be able to provide source code for a component', (done) => {

@@ -409,2 +403,7 @@ l.getSource('Graph', (err, component) => {

it('should return an error for non-file components', (done) => {
if (noflo.isBrowser()) {
// Browser runtime actually supports this via toString()
done();
return;
}
l.getSource('foo/Split', (err) => {

@@ -465,2 +464,15 @@ chai.expect(err).to.be.an('error');

});
describe('getting supported languages', () => {
it('should include the expected ones', () => {
const expectedLanguages = ['es2015', 'javascript'];
if (!noflo.isBrowser()) {
expectedLanguages.push('coffeescript');
expectedLanguages.push('typescript');
}
expectedLanguages.sort();
const supportedLanguages = l.getLanguages();
supportedLanguages.sort();
chai.expect(supportedLanguages).to.eql(expectedLanguages);
});
});
describe('writing sources', () => {

@@ -520,2 +532,13 @@ let localNofloPath;

});
it('should return sources in the same format', (done) => {
l.getSource('foo/RepeatData', (err, source) => {
if (err) {
done(err);
return;
}
chai.expect(source.language).to.equal('javascript');
chai.expect(source.code).to.equal(workingSource);
done();
});
});
it('should be able to set the source for non-ready ComponentLoader', function (done) {

@@ -529,4 +552,3 @@ this.timeout(10000);

before(function () {
// PhantomJS doesn't work with ES6
if (noflo.isBrowser()) {
if (l.getLanguages().indexOf('es2015') === -1) {
this.skip();

@@ -553,3 +575,3 @@ }

}
l.setSource('foo', 'RepeatDataES6', workingSource, 'es6', (err) => {
l.setSource('foo', 'RepeatDataES6', workingSource, 'es2015', (err) => {
if (err) {

@@ -583,8 +605,17 @@ done(err);

});
it('should return sources in the same format', (done) => {
l.getSource('foo/RepeatDataES6', (err, source) => {
if (err) {
done(err);
return;
}
chai.expect(source.language).to.equal('es2015');
chai.expect(source.code).to.equal(workingSource);
done();
});
});
});
describe('with CoffeeScript', () => {
before(function () {
// CoffeeScript tests work in browser only if we have CoffeeScript
// compiler loaded
if (noflo.isBrowser() && !window.CoffeeScript) {
if (l.getLanguages().indexOf('coffeescript') === -1) {
this.skip();

@@ -637,3 +668,79 @@ }

});
it('should return sources in the same format', (done) => {
l.getSource('foo/RepeatDataCoffee', (err, source) => {
if (err) {
done(err);
return;
}
chai.expect(source.language).to.equal('coffeescript');
chai.expect(source.code).to.equal(workingSource);
done();
});
});
});
describe('with TypeScript', () => {
before(function () {
if (l.getLanguages().indexOf('typescript') === -1) {
this.skip();
}
});
let workingSource = `\
import { Component } from 'noflo';
exports.getComponent = (): Component => {
const c = new noflo.Component();
c.inPorts.add('in');
c.outPorts.add('out');
c.process((input, output): void => {
output.sendDone(input.get('in'));
});
return c;
};
`;
it('should be able to set the source', function (done) {
this.timeout(10000);
if (!noflo.isBrowser()) {
workingSource = workingSource.replace("'noflo'", localNofloPath);
}
l.setSource('foo', 'RepeatDataTypeScript', workingSource, 'typescript', (err) => {
if (err) {
done(err);
return;
}
done();
});
});
it('should be a loadable component', (done) => {
l.load('foo/RepeatDataTypeScript', (err, inst) => {
if (err) {
done(err);
return;
}
chai.expect(inst).to.be.an('object');
chai.expect(inst.inPorts).to.contain.keys(['in']);
chai.expect(inst.outPorts).to.contain.keys(['out']);
const ins = new noflo.internalSocket.InternalSocket();
const out = new noflo.internalSocket.InternalSocket();
inst.inPorts.in.attach(ins);
inst.outPorts.out.attach(out);
out.on('ip', (ip) => {
chai.expect(ip.type).to.equal('data');
chai.expect(ip.data).to.equal('TypeScript');
done();
});
ins.send('TypeScript');
});
});
it('should return sources in the same format', (done) => {
l.getSource('foo/RepeatDataTypeScript', (err, source) => {
if (err) {
done(err);
return;
}
chai.expect(source.language).to.equal('typescript');
chai.expect(source.code).to.equal(workingSource);
done();
});
});
});
});

@@ -793,5 +900,8 @@ describe('with non-working code', () => {

});
it('should be able to load a local component', (done) => {
it('should be able to load a local JavaScript component', (done) => {
l.load('componentloader/Output', (err, instance) => {
chai.expect(err).to.be.a('null');
if (err) {
done(err);
return;
}
chai.expect(instance.description).to.equal('Output stuff');

@@ -802,5 +912,30 @@ chai.expect(instance.icon).to.equal('cloud');

});
it('should be able to load a component from a dependency', (done) => {
it('should be able to load a local CoffeeScript component', (done) => {
l.load('componentloader/RepeatAsync', (err, instance) => {
if (err) {
done(err);
return;
}
chai.expect(instance.description).to.equal('Repeat stuff async');
chai.expect(instance.icon).to.equal('forward');
done();
});
});
it('should be able to load a local TypeScript component', (done) => {
l.load('componentloader/Repeat', (err, instance) => {
if (err) {
done(err);
return;
}
chai.expect(instance.description).to.equal('Repeat stuff');
chai.expect(instance.icon).to.equal('cloud');
done();
});
});
it('should be able to load a JavaScript component from a dependency', (done) => {
l.load('example/Forward', (err, instance) => {
chai.expect(err).to.be.a('null');
if (err) {
done(err);
return;
}
chai.expect(instance.description).to.equal('Forward stuff');

@@ -811,5 +946,30 @@ chai.expect(instance.icon).to.equal('car');

});
it('should be able to load a CoffeeScript component from a dependency', (done) => {
l.load('example/RepeatAsync', (err, instance) => {
if (err) {
done(err);
return;
}
chai.expect(instance.description).to.equal('Repeat stuff async');
chai.expect(instance.icon).to.equal('forward');
done();
});
});
it('should be able to load a TypeScript component from a dependency', (done) => {
l.load('example/Repeat', (err, instance) => {
if (err) {
done(err);
return;
}
chai.expect(instance.description).to.equal('Repeat stuff');
chai.expect(instance.icon).to.equal('car');
done();
});
});
it('should be able to load a dynamically registered component from a dependency', (done) => {
l.load('example/Hello', (err, instance) => {
chai.expect(err).to.be.a('null');
if (err) {
done(err);
return;
}
chai.expect(instance.description).to.equal('Hello stuff');

@@ -822,3 +982,6 @@ chai.expect(instance.icon).to.equal('bicycle');

l.load('Graph', (err, instance) => {
chai.expect(err).to.be.a('null');
if (err) {
done(err);
return;
}
chai.expect(instance.icon).to.equal('sitemap');

@@ -907,3 +1070,6 @@ done();

l.load('componentloader/Output', (err, instance) => {
chai.expect(err).to.be.a('null');
if (err) {
done(err);
return;
}
chai.expect(instance.description).to.equal('Output stuff');

@@ -916,3 +1082,6 @@ chai.expect(instance.icon).to.equal('cloud');

l.load('example/Forward', (err, instance) => {
chai.expect(err).to.be.a('null');
if (err) {
done(err);
return;
}
chai.expect(instance.description).to.equal('Forward stuff');

@@ -925,3 +1094,6 @@ chai.expect(instance.icon).to.equal('car');

l.load('example/Hello', (err, instance) => {
chai.expect(err).to.be.a('null');
if (err) {
done(err);
return;
}
chai.expect(instance.description).to.equal('Hello stuff');

@@ -934,3 +1106,6 @@ chai.expect(instance.icon).to.equal('bicycle');

l.load('Graph', (err, instance) => {
chai.expect(err).to.be.a('null');
if (err) {
done(err);
return;
}
chai.expect(instance.icon).to.equal('sitemap');

@@ -937,0 +1112,0 @@ done();

@@ -8,10 +8,10 @@ const noflo = require('../../../../src/lib/NoFlo');

{ datatype: 'string' });
c.inPorts.add('out',
c.outPorts.add('out',
{ datatype: 'string' });
c.process = function (input, output) {
c.process((input, output) => {
const data = input.getData('in');
console.log(data);
output.sendDone({ out: data });
};
});
return c;
};

@@ -75,2 +75,5 @@ // NoFlo - Flow-Based Programming for JavaScript

registerLoader.register(this, (err) => {
this.processing = false;
this.ready = true;
this.emit('ready', true);
if (err) {

@@ -80,5 +83,2 @@ callback(err);

}
this.processing = false;
this.ready = true;
this.emit('ready', true);
callback(null, this.components);

@@ -351,2 +351,12 @@ });

// `getLanguages` gets a list of component programming languages supported by the `setSource`
// method on this runtime instance.
getLanguages() {
if (!registerLoader.getLanguages) {
// This component loader doesn't support the method, default to normal JS
return ['javascript', 'es2015'];
}
return registerLoader.getLanguages();
}
clear() {

@@ -353,0 +363,0 @@ this.components = null;

@@ -12,10 +12,234 @@ /* eslint-disable

// We allow components to be un-compiled CoffeeScript
const CoffeeScript = require('coffeescript');
const utils = require('../Utils');
if (typeof CoffeeScript.register !== 'undefined') {
CoffeeScript.register();
// Type loading CoffeeScript compiler
let CoffeeScript;
try {
// eslint-disable-next-line import/no-unresolved
CoffeeScript = require('coffeescript');
if (typeof CoffeeScript.register !== 'undefined') {
CoffeeScript.register();
}
} catch (e) {
// If there is no CoffeeScript compiler installed, we simply don't support compiling
}
// Try loading TypeScript compiler
let typescript;
try {
// eslint-disable-next-line import/no-unresolved,import/no-extraneous-dependencies
typescript = require('typescript');
} catch (e) {
// If there is no TypeScript compiler installed, we simply don't support compiling
}
function transpileSource(packageId, name, source, language, callback) {
let src;
switch (language) {
case 'coffeescript': {
if (!CoffeeScript) {
callback(new Error(`Unsupported component source language ${language} for ${packageId}/${name}: no CoffeeScript compiler installed`));
}
try {
src = CoffeeScript.compile(source, {
bare: true,
});
} catch (err) {
callback(err);
return;
}
break;
}
case 'typescript': {
if (!typescript) {
callback(new Error(`Unsupported component source language ${language} for ${packageId}/${name}: no TypeScript compiler installed`));
}
try {
src = typescript.transpile(source, {
compilerOptions: {
module: typescript.ModuleKind.CommonJS,
},
});
} catch (err) {
callback(err);
return;
}
break;
}
case 'es6':
case 'es2015':
case 'js':
case 'javascript': {
src = source;
break;
}
default: {
callback(new Error(`Unsupported component source language ${language} for ${packageId}/${name}`));
return;
}
}
callback(null, src);
}
function evaluateModule(baseDir, packageId, name, source, callback) {
const Module = require('module');
let implementation;
try {
// Use the Node.js module API to evaluate in the correct directory context
const modulePath = path.resolve(baseDir, `./components/${name}.js`);
const moduleImpl = new Module(modulePath, module);
moduleImpl.paths = Module._nodeModulePaths(path.dirname(modulePath));
moduleImpl.filename = modulePath;
moduleImpl._compile(source, modulePath);
implementation = moduleImpl.exports;
} catch (e) {
callback(e);
return;
}
if ((typeof implementation !== 'function') && (typeof implementation.getComponent !== 'function')) {
callback(new Error(`Provided source for ${packageId}/${name} failed to create a runnable component`));
return;
}
callback(null, implementation);
}
function registerSources(loader, packageId, name, source, language) {
if (!loader.sourcesForComponents) {
// eslint-disable-next-line no-param-reassign
loader.sourcesForComponents = {};
}
const componentName = `${packageId}/${name}`;
// eslint-disable-next-line no-param-reassign
loader.sourcesForComponents[componentName] = {
language,
source,
};
}
function transpileAndRegisterForModule(loader, module, component, source, language, callback) {
transpileSource(module.name, component.name, source, language, (transpileError, src) => {
if (transpileError) {
callback(transpileError);
return;
}
const moduleBase = path.resolve(loader.baseDir, module.base);
evaluateModule(moduleBase, module.name, component.name, src, (evalError, implementation) => {
if (evalError) {
callback(evalError);
return;
}
registerSources(loader, module.name, component.name, source, language);
loader.registerComponent(module.name, component.name, implementation, callback);
});
});
}
exports.setSource = function setSource(loader, packageId, name, source, language, callback) {
transpileAndRegisterForModule(loader, {
name: packageId,
base: '',
}, {
name,
}, source, language, callback);
};
exports.getSource = function getSource(loader, name, callback) {
let componentName = name;
let component = loader.components[name];
if (!component) {
// Try an alias
const keys = Object.keys(loader.components);
for (let i = 0; i < keys.length; i += 1) {
const key = keys[i];
if (key.split('/')[1] === name) {
component = loader.components[key];
componentName = key;
break;
}
}
if (!component) {
callback(new Error(`Component ${componentName} not installed`));
return;
}
}
const nameParts = componentName.split('/');
if (nameParts.length === 1) {
nameParts[1] = nameParts[0];
nameParts[0] = '';
}
if (loader.isGraph(component)) {
if (typeof component === 'object') {
if (typeof component.toJSON === 'function') {
callback(null, {
name: nameParts[1],
library: nameParts[0],
code: JSON.stringify(component.toJSON()),
language: 'json',
});
return;
}
callback(new Error(`Can't provide source for ${componentName}. Not a file`));
return;
}
fbpGraph.graph.loadFile(component, (err, graph) => {
if (err) {
callback(err);
return;
}
if (!graph) {
callback(new Error('Unable to load graph'));
return;
}
callback(null, {
name: nameParts[1],
library: nameParts[0],
code: JSON.stringify(graph.toJSON()),
language: 'json',
});
});
return;
}
if (loader.sourcesForComponents && loader.sourcesForComponents[componentName]) {
callback(null, {
name: nameParts[1],
library: nameParts[0],
code: loader.sourcesForComponents[componentName].source,
language: loader.sourcesForComponents[componentName].language,
});
return;
}
if (typeof component !== 'string') {
callback(new Error(`Can't provide source for ${componentName}. Not a file`));
return;
}
fs.readFile(component, 'utf-8', (err, code) => {
if (err) {
callback(err);
return;
}
callback(null, {
name: nameParts[1],
library: nameParts[0],
language: utils.guessLanguageFromFilename(component),
code,
});
});
};
exports.getLanguages = function getLanguages() {
const languages = ['javascript', 'es2015'];
if (CoffeeScript) {
languages.push('coffeescript');
}
if (typescript) {
languages.push('typescript');
}
return languages;
};
function registerCustomLoaders(loader, componentLoaders, callback) {

@@ -39,4 +263,6 @@ if (!componentLoaders.length) {

const componentLoaders = [];
compatible.forEach((m) => {
if (m.icon) { loader.setLibraryIcon(m.name, m.icon); }
Promise.all(compatible.map((m) => {
if (m.icon) {
loader.setLibraryIcon(m.name, m.icon);
}

@@ -48,8 +274,36 @@ if (m.noflo != null ? m.noflo.loader : undefined) {

m.components.forEach((c) => {
loader.registerComponent(m.name, c.name, path.resolve(loader.baseDir, c.path));
});
});
registerCustomLoaders(loader, componentLoaders, callback);
return Promise.all(m.components.map((c) => new Promise((resolve, reject) => {
const language = utils.guessLanguageFromFilename(c.path);
if (language === 'typescript') {
// We can't require a TypeScript module, go the setSource route
fs.readFile(path.resolve(loader.baseDir, c.path), 'utf-8', (fsErr, source) => {
if (fsErr) {
reject(fsErr);
return;
}
transpileAndRegisterForModule(loader, m, c, source, language, (err) => {
if (err) {
reject(err);
return;
}
resolve();
});
});
return;
}
loader.registerComponent(m.name, c.name, path.resolve(loader.baseDir, c.path), (err) => {
if (err) {
reject(err);
return;
}
resolve();
});
})));
}))
.then(
() => {
registerCustomLoaders(loader, componentLoaders, callback);
},
callback,
);
}

@@ -200,112 +454,1 @@

};
exports.setSource = function setSource(loader, packageId, name, source, language, callback) {
const Module = require('module');
let src = source;
if (language === 'coffeescript') {
try {
src = CoffeeScript.compile(src,
{ bare: true });
} catch (err) {
callback(err);
return;
}
}
let implementation;
try {
// Use the Node.js module API to evaluate in the correct directory context
const modulePath = path.resolve(loader.baseDir, `./components/${name}.js`);
const moduleImpl = new Module(modulePath, module);
moduleImpl.paths = Module._nodeModulePaths(path.dirname(modulePath));
moduleImpl.filename = modulePath;
moduleImpl._compile(src, modulePath);
implementation = moduleImpl.exports;
} catch (err) {
callback(err);
return;
}
if ((typeof implementation !== 'function') && (typeof implementation.getComponent !== 'function')) {
callback(new Error('Provided source failed to create a runnable component'));
return;
}
loader.registerComponent(packageId, name, implementation, callback);
};
exports.getSource = function getSource(loader, name, callback) {
let componentName = name;
let component = loader.components[name];
if (!component) {
// Try an alias
const keys = Object.keys(loader.components);
for (let i = 0; i < keys.length; i += 1) {
const key = keys[i];
if (key.split('/')[1] === name) {
component = loader.components[key];
componentName = key;
break;
}
}
if (!component) {
callback(new Error(`Component ${componentName} not installed`));
return;
}
}
const nameParts = componentName.split('/');
if (nameParts.length === 1) {
nameParts[1] = nameParts[0];
nameParts[0] = '';
}
if (loader.isGraph(component)) {
if (typeof component === 'object') {
if (typeof component.toJSON === 'function') {
callback(null, {
name: nameParts[1],
library: nameParts[0],
code: JSON.stringify(component.toJSON()),
language: 'json',
});
return;
}
callback(new Error(`Can't provide source for ${componentName}. Not a file`));
return;
}
fbpGraph.graph.loadFile(component, (err, graph) => {
if (err) {
callback(err);
return;
}
if (!graph) {
callback(new Error('Unable to load graph'));
return;
}
callback(null, {
name: nameParts[1],
library: nameParts[0],
code: JSON.stringify(graph.toJSON()),
language: 'json',
});
});
return;
}
if (typeof component !== 'string') {
callback(new Error(`Can't provide source for ${componentName}. Not a file`));
return;
}
fs.readFile(component, 'utf-8', (err, code) => {
if (err) {
callback(err);
return;
}
callback(null, {
name: nameParts[1],
library: nameParts[0],
language: utils.guessLanguageFromFilename(component),
code,
});
});
};

@@ -13,2 +13,3 @@ // NoFlo - Flow-Based Programming for JavaScript

if (/.*\.coffee$/.test(filename)) { return 'coffeescript'; }
if (/.*\.ts$/.test(filename)) { return 'typescript'; }
return 'javascript';

@@ -15,0 +16,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc