mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Deprecate getAllFlows/getFlow/saveFlow storage functions
They were specialised versions of get/saveLibraryEntry that complicated the interface. This change removes them from localfilesystem, but the top level module checks for their existence and uses them if they are there - for backwards compatibility.
This commit is contained in:
parent
e543cc0fed
commit
b96ea36b70
@ -92,21 +92,7 @@ var storageModuleInterface = {
|
||||
},
|
||||
|
||||
/* Library Functions */
|
||||
getAllFlows: function() {
|
||||
return storageModule.getAllFlows();
|
||||
},
|
||||
getFlow: function(fn) {
|
||||
if (is_malicious(fn)) {
|
||||
return when.reject(new Error('forbidden flow name'));
|
||||
}
|
||||
return storageModule.getFlow(fn);
|
||||
},
|
||||
saveFlow: function(fn, data) {
|
||||
if (is_malicious(fn)) {
|
||||
return when.reject(new Error('forbidden flow name'));
|
||||
}
|
||||
return storageModule.saveFlow(fn, data);
|
||||
},
|
||||
|
||||
getLibraryEntry: function(type, path) {
|
||||
if (is_malicious(path)) {
|
||||
return when.reject(new Error('forbidden flow name'));
|
||||
@ -118,7 +104,78 @@ var storageModuleInterface = {
|
||||
return when.reject(new Error('forbidden flow name'));
|
||||
}
|
||||
return storageModule.saveLibraryEntry(type, path, meta, body);
|
||||
},
|
||||
|
||||
/* Deprecated functions */
|
||||
getAllFlows: function() {
|
||||
if (storageModule.hasOwnProperty("getAllFlows")) {
|
||||
return storageModule.getAllFlows();
|
||||
} else {
|
||||
return listFlows("/");
|
||||
}
|
||||
},
|
||||
getFlow: function(fn) {
|
||||
if (is_malicious(fn)) {
|
||||
return when.reject(new Error('forbidden flow name'));
|
||||
}
|
||||
if (storageModule.hasOwnProperty("getFlow")) {
|
||||
return storageModule.getFlow(fn);
|
||||
} else {
|
||||
return storageModule.getLibraryEntry("flows",fn);
|
||||
}
|
||||
|
||||
},
|
||||
saveFlow: function(fn, data) {
|
||||
if (is_malicious(fn)) {
|
||||
return when.reject(new Error('forbidden flow name'));
|
||||
}
|
||||
if (storageModule.hasOwnProperty("saveFlow")) {
|
||||
return storageModule.saveFlow(fn, data);
|
||||
} else {
|
||||
return storageModule.saveLibraryEntry("flows",fn,{},data);
|
||||
}
|
||||
}
|
||||
/* End deprecated functions */
|
||||
|
||||
}
|
||||
|
||||
|
||||
function listFlows(path) {
|
||||
return storageModule.getLibraryEntry("flows",path).then(function(res) {
|
||||
return when.promise(function(resolve) {
|
||||
var promises = [];
|
||||
res.forEach(function(r) {
|
||||
if (typeof r === "string") {
|
||||
promises.push(listFlows(path+r));
|
||||
} else {
|
||||
promises.push(when.resolve(r));
|
||||
}
|
||||
});
|
||||
var i=0;
|
||||
when.settle(promises).then(function(res2) {
|
||||
var result = {};
|
||||
res2.forEach(function(r) {
|
||||
// TODO: name||fn
|
||||
if (r.value.fn) {
|
||||
var name = r.value.name;
|
||||
if (!name) {
|
||||
name = r.value.fn.split(".")[0];
|
||||
}
|
||||
result.f = result.f || [];
|
||||
result.f.push(name);
|
||||
} else {
|
||||
result.d = result.d || {};
|
||||
result.d[res[i]] = r.value;
|
||||
//console.log(">",r.value);
|
||||
}
|
||||
i++;
|
||||
});
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = storageModuleInterface;
|
||||
|
@ -37,27 +37,6 @@ var libDir;
|
||||
var libFlowsDir;
|
||||
var globalSettingsFile;
|
||||
|
||||
function listFiles(dir) {
|
||||
var dirs = {};
|
||||
var files = [];
|
||||
var dirCount = 0;
|
||||
return nodeFn.call(fs.readdir, dir).then(function (contents) {
|
||||
contents.sort().forEach(function(fn) {
|
||||
var stats = fs.lstatSync(dir+"/"+fn);
|
||||
if (stats.isDirectory()) {
|
||||
dirCount += 1;
|
||||
dirs[fn] = listFiles(dir+"/"+fn)
|
||||
} else {
|
||||
files.push(fn.split(".")[0]);
|
||||
}
|
||||
})
|
||||
var result = {};
|
||||
if (dirCount > 0) { result.d = keys.all(dirs); }
|
||||
if (files.length > 0) { result.f = when.resolve(files); }
|
||||
return keys.all(result);
|
||||
})
|
||||
}
|
||||
|
||||
function getFileMeta(root,path) {
|
||||
var fn = fspath.join(root,path);
|
||||
var fd = fs.openSync(fn,"r");
|
||||
@ -312,30 +291,6 @@ var localfilesystem = {
|
||||
return writeFile(sessionsFile,JSON.stringify(sessions));
|
||||
},
|
||||
|
||||
getAllFlows: function() {
|
||||
return listFiles(libFlowsDir);
|
||||
},
|
||||
|
||||
getFlow: function(fn) {
|
||||
var defer = when.defer();
|
||||
var file = fspath.join(libFlowsDir,fn+".json");
|
||||
fs.exists(file, function(exists) {
|
||||
if (exists) {
|
||||
defer.resolve(nodeFn.call(fs.readFile,file,'utf8'));
|
||||
} else {
|
||||
defer.reject();
|
||||
}
|
||||
});
|
||||
return defer.promise;
|
||||
},
|
||||
|
||||
saveFlow: function(fn,data) {
|
||||
var file = fspath.join(libFlowsDir,fn+".json");
|
||||
return promiseDir(fspath.dirname(file)).then(function () {
|
||||
return writeFile(file,data);
|
||||
});
|
||||
},
|
||||
|
||||
getLibraryEntry: function(type,path) {
|
||||
var root = fspath.join(libDir,type);
|
||||
var rootPath = fspath.join(libDir,type,path);
|
||||
@ -366,6 +321,15 @@ var localfilesystem = {
|
||||
});
|
||||
return dirs.concat(files);
|
||||
});
|
||||
}).otherwise(function(err) {
|
||||
if (type === "flows" && !/\.json$/.test(path)) {
|
||||
return localfilesystem.getLibraryEntry(type,path+".json")
|
||||
.otherwise(function(e) {
|
||||
throw err;
|
||||
});
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2014 IBM Corp.
|
||||
* Copyright 2014, 2015 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
var when = require("when");
|
||||
var should = require("should");
|
||||
var storage = require("../../../red/storage/index");
|
||||
|
||||
@ -139,6 +140,81 @@ describe("red/storage/index", function() {
|
||||
calledFlagGetAllFlows.should.be.true;
|
||||
});
|
||||
|
||||
describe('respects deprecated flow library functions', function() {
|
||||
|
||||
var savePath;
|
||||
var saveContent;
|
||||
var saveMeta;
|
||||
var saveType;
|
||||
|
||||
var interfaceCheckerModule = {
|
||||
init : function (settings) {
|
||||
settings.should.be.an.Object;
|
||||
},
|
||||
getLibraryEntry : function(type, path) {
|
||||
if (type === "flows") {
|
||||
if (path == "/") {
|
||||
return when.resolve(["a",{fn:"test.json"}]);
|
||||
} else if (path == "/a") {
|
||||
return when.resolve([{fn:"test2.json"}]);
|
||||
} else if (path == "/a/test2.json") {
|
||||
return when.resolve("test content");
|
||||
}
|
||||
}
|
||||
},
|
||||
saveLibraryEntry : function(type, path, meta, body) {
|
||||
saveType = type;
|
||||
savePath = path;
|
||||
saveContent = body;
|
||||
saveMeta = meta;
|
||||
return when.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
var moduleToLoad = {
|
||||
storageModule : interfaceCheckerModule
|
||||
};
|
||||
before(function() {
|
||||
storage.init(moduleToLoad);
|
||||
});
|
||||
it('getAllFlows',function(done) {
|
||||
storage.getAllFlows().then(function (res) {
|
||||
try {
|
||||
res.should.eql({ d: { a: { f: ['test2'] } }, f: [ 'test' ] });
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('getFlow',function(done) {
|
||||
storage.getFlow("/a/test2.json").then(function(res) {
|
||||
try {
|
||||
res.should.eql("test content");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it ('saveFlow', function (done) {
|
||||
storage.saveFlow("/a/test2.json","new content").then(function(res) {
|
||||
try {
|
||||
savePath.should.eql("/a/test2.json");
|
||||
saveContent.should.eql("new content");
|
||||
saveMeta.should.eql({});
|
||||
saveType.should.eql("flows");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('handles missing settings/sessions interface', function() {
|
||||
before(function() {
|
||||
var interfaceCheckerModule = {
|
||||
|
@ -437,72 +437,6 @@ describe('LocalFileSystem', function() {
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
it('should return an empty list of library flows',function(done) {
|
||||
localfilesystem.init({userDir:userDir}).then(function() {
|
||||
localfilesystem.getAllFlows().then(function(flows) {
|
||||
flows.should.eql({});
|
||||
done();
|
||||
}).otherwise(function(err) {
|
||||
done(err);
|
||||
});
|
||||
}).otherwise(function(err) {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a valid list of library flows',function(done) {
|
||||
localfilesystem.init({userDir:userDir}).then(function() {
|
||||
var flowLib = path.join(userDir,"lib","flows");
|
||||
fs.closeSync(fs.openSync(path.join(flowLib,"A.json"),"w"));
|
||||
fs.closeSync(fs.openSync(path.join(flowLib,"B.json"),"w"));
|
||||
fs.mkdirSync(path.join(flowLib,"C"));
|
||||
fs.closeSync(fs.openSync(path.join(flowLib,"C","D.json"),"w"));
|
||||
var testFlowsList = {"d":{"C":{"f":["D"]}},"f":["A","B"]};
|
||||
|
||||
localfilesystem.getAllFlows().then(function(flows) {
|
||||
flows.should.eql(testFlowsList);
|
||||
done();
|
||||
}).otherwise(function(err) {
|
||||
done(err);
|
||||
});
|
||||
}).otherwise(function(err) {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail a non-existent flow', function(done) {
|
||||
localfilesystem.init({userDir:userDir}).then(function() {
|
||||
localfilesystem.getFlow("a/b/c.json").then(function(flow) {
|
||||
should.fail(flow,"No flow","Flow found");
|
||||
}).otherwise(function(err) {
|
||||
// err should be null, so this will pass
|
||||
done(err);
|
||||
});
|
||||
}).otherwise(function(err) {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a flow',function(done) {
|
||||
localfilesystem.init({userDir:userDir}).then(function() {
|
||||
var testflowString = JSON.stringify(testFlow);
|
||||
localfilesystem.saveFlow("a/b/c/d.json",testflowString).then(function() {
|
||||
localfilesystem.getFlow("a/b/c/d.json").then(function(flow) {
|
||||
flow.should.eql(testflowString);
|
||||
done();
|
||||
}).otherwise(function(err) {
|
||||
done(err);
|
||||
});
|
||||
}).otherwise(function(err) {
|
||||
done(err);
|
||||
});
|
||||
}).otherwise(function(err) {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an empty list of library objects',function(done) {
|
||||
localfilesystem.init({userDir:userDir}).then(function() {
|
||||
localfilesystem.getLibraryEntry('object','').then(function(flows) {
|
||||
@ -529,14 +463,19 @@ describe('LocalFileSystem', function() {
|
||||
});
|
||||
});
|
||||
|
||||
function createObjectLibrary() {
|
||||
var objLib = path.join(userDir,"lib","object");
|
||||
fs.mkdirSync(objLib);
|
||||
function createObjectLibrary(type) {
|
||||
type = type ||"object";
|
||||
var objLib = path.join(userDir,"lib",type);
|
||||
try {
|
||||
fs.mkdirSync(objLib);
|
||||
} catch(err) {
|
||||
}
|
||||
fs.mkdirSync(path.join(objLib,"A"));
|
||||
fs.mkdirSync(path.join(objLib,"B"));
|
||||
fs.mkdirSync(path.join(objLib,"B","C"));
|
||||
fs.writeFileSync(path.join(objLib,"file1.js"),"// abc: def\n// not a metaline \n\n Hi",'utf8');
|
||||
fs.writeFileSync(path.join(objLib,"B","file2.js"),"// ghi: jkl\n// not a metaline \n\n Hi",'utf8');
|
||||
fs.writeFileSync(path.join(objLib,"B","flow.json"),"Hi",'utf8');
|
||||
}
|
||||
|
||||
it('should return a directory listing of library objects',function(done) {
|
||||
@ -546,7 +485,7 @@ describe('LocalFileSystem', function() {
|
||||
localfilesystem.getLibraryEntry('object','').then(function(flows) {
|
||||
flows.should.eql([ 'A', 'B', { abc: 'def', fn: 'file1.js' } ]);
|
||||
localfilesystem.getLibraryEntry('object','B').then(function(flows) {
|
||||
flows.should.eql([ 'C', { ghi: 'jkl', fn: 'file2.js' } ]);
|
||||
flows.should.eql([ 'C', { ghi: 'jkl', fn: 'file2.js' }, { fn: 'flow.json' } ]);
|
||||
localfilesystem.getLibraryEntry('object','B/C').then(function(flows) {
|
||||
flows.should.eql([]);
|
||||
done();
|
||||
@ -564,6 +503,19 @@ describe('LocalFileSystem', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should load a flow library object with .json unspecified', function(done) {
|
||||
localfilesystem.init({userDir:userDir}).then(function() {
|
||||
createObjectLibrary("flows");
|
||||
localfilesystem.getLibraryEntry('flows','B/flow').then(function(flows) {
|
||||
flows.should.eql("Hi");
|
||||
done();
|
||||
}).otherwise(function(err) {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should return a library object',function(done) {
|
||||
localfilesystem.init({userDir:userDir}).then(function() {
|
||||
createObjectLibrary();
|
||||
@ -582,7 +534,7 @@ describe('LocalFileSystem', function() {
|
||||
localfilesystem.init({userDir:userDir}).then(function() {
|
||||
createObjectLibrary();
|
||||
localfilesystem.getLibraryEntry('object','B').then(function(flows) {
|
||||
flows.should.eql([ 'C', { ghi: 'jkl', fn: 'file2.js' } ]);
|
||||
flows.should.eql([ 'C', { ghi: 'jkl', fn: 'file2.js' }, {fn:'flow.json'} ]);
|
||||
localfilesystem.saveLibraryEntry('object','B/D/file3.js',{mno:'pqr'},"// another non meta line\n\n Hi There").then(function() {
|
||||
localfilesystem.getLibraryEntry('object','B/D').then(function(flows) {
|
||||
flows.should.eql([ { mno: 'pqr', fn: 'file3.js' } ]);
|
||||
|
Loading…
Reference in New Issue
Block a user