3
0
Fork 0
xnode/lib-build/debug-server/node_lib/lib/factory-express-api.js

339 lines
10 KiB
JavaScript
Raw Permalink Normal View History

2022-11-13 00:46:38 +00:00
var logger = require('winston').loggers.get('main');
var clone = require('clone');
var fs = require('fs');
var ejs = require('ejs');
var xmlmapping = require('xml-mapping');
var rawbody = require('raw-body');
var typeis = require('type-is');
var mcrud = require('crud-mongoose');
var ncrud = require('node-crud');
var mongoose = require('mongoose');
var buildView = require('./build-view');
exports.bodyParserXml = function() {
return function(req, res, next) {
if (req._body) return next();
req.body = req.body || {};
if (!typeis(req, 'xml')) return next();
// flag as parsed
req._body = true;
// parse
rawbody(req, {
limit: options.limit || '100kb',
length: req.headers['content-length'],
encoding: 'utf8'
}, function (err, buf) {
if (err) return next(err);
if (0 == buf.length) {
return next(error(400, 'invalid xml, empty body'));
}
try {
req.body = xmlmapping.dump(buf/*, options.reviver*/);
} catch (err){
err.body = buf;
err.status = 400;
return next(err);
}
next();
})
}
}
var renderTemplateDataRead = function(tview, exportType, contentType, model, projection) {
return function(data, query, cb) {
var res = this.response;
res.set('Content-Type', contentType);
var cursor, fields;
if (query.hasOwnProperty('fields')) {
fields = query.fields;
delete query.fields;
}
delete query.export;
cursor = model.findOne(query);
cursor.select(mcrud.tools.select(projection, fields));
cursor.lean().exec(function(err,doc) {
if (err) {
cb(err || 'error in stream');
return;
}
if (doc == null) {
cb('no data'); // TODO: error is still in json...
return;
}
//var templateReadHeader = fs.readFileSync('node_code/lib/www_views/node-ff-tcrud/'+exportType+'/read-header.ejs', 'utf8');
var templateReadRecord = fs.readFileSync('node_code/lib/www_views/node-ff-tcrud/'+exportType+'/read-record.ejs', 'utf8');
//var templateReadFooter = fs.readFileSync('node_code/lib/www_views/node-ff-tcrud/'+exportType+'/read-footer.ejs', 'utf8');
res.write(ejs.render(templateReadRecord,{
tview: tview,
record: doc,
}));
res.end();
//cb(); // FIXME
});
}
}
var renderTemplateDataList = function(tview, exportType, contentType) {
return function(res, cursor, cb) {
res.set('Content-Type', contentType);
var templateHeader = fs.readFileSync('node_code/lib/www_views/node-ff-tcrud/'+exportType+'/list-header.ejs', 'utf8');
var templateRecord = fs.readFileSync('node_code/lib/www_views/node-ff-tcrud/'+exportType+'/list-record.ejs', 'utf8');
var templateFooter = fs.readFileSync('node_code/lib/www_views/node-ff-tcrud/'+exportType+'/list-footer.ejs', 'utf8');
res.write(ejs.render(templateHeader,{
tview: tview,
}));
cursor.stream()
.on('data', function(doc) {
res.write(ejs.render(templateRecord,{
tview: tview,
record: doc,
}));
})
.on('error', function(e) {
cb(e || 'error in stream');
})
.on('close', function() {
res.write(ejs.render(templateFooter,{
tview: tview,
}));
res.end();
cb();
});
};
}
exports.injectExportFormat = function(apiBase) {
return function ( req, res, next ) {
if (req.url.indexOf(apiBase) >= 0) {
if (req.url.indexOf('xml') > 0) {
req.query['export'] = 'xml';
} else if (req.url.indexOf('csv') > 0) {
req.query['export'] = 'csv';
} else if (req.url.indexOf('rss') > 0) {
req.query['export'] = 'rss';
}
if (req.url.indexOf('json') == 0) {
console.log('inject export type: '+req.query['export']);
}
}
next();
};
}
var _ = require('underscore');
var filterQueryList = function (model) {
return mcrud.parseQuery()
.defaults({ limit: '10' })
.overrides({})
.maxes({ limit: 1000 });
//.removes()
}
var filterDataUpdate = function (model) {
return mcrud.parseData()
overrides({});
//.removes('auth')
//.overrides({ updated: Date.now })
//.defaults({ 'info.gender': 'M' }))
}
function allowCrudType(tview,tcrudType) {
return tview[tcrudType].tenable; // todo add roles
}
//var rssXNodeMap = function(link,feed,data) {
// feed.addNewItem(data.net_id, link+'/ui/XNode/read/'+data._id, data.changed_data, data.net_id+' id', {});
//}
var sendRedirect = function (location) {
if (!location) {
throw new Error('no location');
}
return function(req, res) {
res.redirect(location);
};
};
var renderCrudView = function (tview) {
return function (req, res, next) {
var result = {
tview: tview,
}
res.json({
data: result
});
};
}
var renderCrudController = function (tview, thtmlPrefix, tapiPrefix) {
return function (req, res, next) {
res.set('Content-Type', 'text/javascript');
res.render('node-ff-tcrud/angular/controller',{
tview: tview,
thtmlPrefix: thtmlPrefix,
tapiPrefix: tapiPrefix,
});
};
}
var renderCrudTemplate = function (tview,paction) {
return function (req, res, next) {
res.render('node-ff-tcrud/angular/'+paction+'/'+req.params.action,{
tview: tview,
});
};
}
var buildCrud = function (server,tcrud) {
if (!tcrud.tenable || !tcrud.tmodel) {
logger.info('disabled server: '+tcrud.tid);
return;
}
var tview = buildView.createTCrudView(tcrud /*, fetchCrudRoles()*/);
var model = mongoose.model( tcrud.tmodel );
// Export tdebug
var uriDebug = tcrud.tmeta.tserver.tslug + '/' +buildView.createBaseApiUri(tview,'json') + '/_debug/';
var tcrudClone = clone(tcrud);
tcrudClone.tparent = null; // rm loop: tparent.tchilds[] = this
server.get(uriDebug + 'tview', renderCrudView(tview));
server.get(uriDebug + 'tcrud', renderCrudView(tcrudClone));
if (_.contains(tview.tmeta.tserver.texports,'json')) {
if (allowCrudType(tview,'tlist')) {
ncrud.entity(buildView.createBaseApiUri(tview,'json','tlist')).Read()
.pipe(filterQueryList(model))
.pipe(mcrud.findAll(model).stream());
}
if (allowCrudType(tview,'tcreate')) {
ncrud.entity(buildView.createBaseApiUri(tview,'json','tcreate')).Create()
.pipe(mcrud.createNew(model));
}
if (allowCrudType(tview,'tread')) {
ncrud.entity(buildView.createBaseApiUri(tview,'json','tread') + '/:_id').Read()
.pipe(mcrud.findOne(model));
}
if (allowCrudType(tview,'tedit')) {
ncrud.entity(buildView.createBaseApiUri(tview,'json','tedit') + '/:_id').Update()
.pipe(filterDataUpdate(model))
.pipe(mcrud.updateOne (model));
}
if (allowCrudType(tview,'tdelete')) {
ncrud.entity(buildView.createBaseApiUri(tview,'json','tdelete') +'/:_id').Delete()
.pipe(mcrud.removeOne(model));
}
if (allowCrudType(tview,'tcount')) {
ncrud.entity(buildView.createBaseApiUri(tview,'json','tcount')).Read()
.pipe(filterQueryList(model))
.pipe(mcrud.findAll(model).stream());
}
if (allowCrudType(tview,'tverify')) {
ncrud.entity(buildView.createBaseApiUri(tview,'json','tverify') + '/:_id').Update()
.pipe(mcrud.findOne(model));
}
}
if (_.contains(tview.tmeta.tserver.texports,'xml')) {
if (allowCrudType(tview,'tlist')) {
ncrud.entity(buildView.createBaseApiUri(tview,'xml','tlist')).Read()
.pipe(filterQueryList(model))
.pipe(mcrud.findAll(model).stream().exports({ xml: renderTemplateDataList(tview,'xml','text/xml') }));
}
if (allowCrudType(tview,'tcreate')) {
ncrud.entity(buildView.createBaseApiUri(tview,'xml','tcreate')).Create()
.pipe(mcrud.createNew(model));
}
if (allowCrudType(tview,'tread')) {
ncrud.entity(buildView.createBaseApiUri(tview,'xml','tread') +'/:_id').Read()
.pipe(renderTemplateDataRead(tview,'xml','text/xml',model));
}
if (allowCrudType(tview,'tedit')) {
ncrud.entity(buildView.createBaseApiUri(tview,'xml','tedit')+'/:_id').Update()
.pipe(filterDataUpdate(model))
.pipe(mcrud.updateOne (model));
}
if (allowCrudType(tview,'tdelete')) {
ncrud.entity(buildView.createBaseApiUri(tview,'xml','tdelete')+'/:_id').Delete()
.pipe(mcrud.removeOne (model));
}
}
if (_.contains(tview.tmeta.tserver.texports,'csv')) {
if (allowCrudType(tview,'tlist')) {
ncrud.entity(buildView.createBaseApiUri(tview,'csv','tlist')).Read()
.pipe(filterQueryList(model))
.pipe(mcrud.findAll(model).stream().exports({ csv: renderTemplateDataList(tview,'csv','text/csv') }));
}
if (allowCrudType(tview,'tread')) {
ncrud.entity(buildView.createBaseApiUri(tview,'csv','tread') +'/:_id').Read()
.pipe(renderTemplateDataRead(tview,'csv','text/csv',model));
}
}
if (_.contains(tview.tmeta.tserver.texports,'rss')) {
if (allowCrudType(tview,'tlist')) {
ncrud.entity(buildView.createBaseApiUri(tview,'rss','tlist')).Read()
.pipe(mcrud.parseQuery()
.defaults({ limit: '10' })
.maxes({ limit: 50 })
)
.pipe(mcrud.findAll(model)
.stream()
.exports({ rss: renderTemplateDataList(tview,'rss','text/xml') })
);
}
//.exports({ rss: exports.exportRss('todo',tview.xid,rssXNodeMap) })
}
if (_.contains(tview.tmeta.tserver.texports,'angular')) {
var uriPrefix = tcrud.tmeta.tserver.tslug + '/' + buildView.createBaseApiUri(tview,'angular');
var thtmlPrefix = uriPrefix + '/' + tview.tmeta.texport.angular.thtml;
var tapiPrefix = tcrud.tmeta.tserver.tslug + '/' +buildView.createBaseApiUri(tview,'json');
//server.get('/ui/include/crud/:name/:action', XViewInclude.renderTemplateCrud);
//server.get('/ui/include/js/controller/:name', XViewInclude.renderCrudController);
server.get(uriPrefix + '/thtml/crud/:action', renderCrudTemplate(tview,'thtml/crud/'));
server.get(uriPrefix + '/controller.js', renderCrudController(tview,thtmlPrefix,tapiPrefix));
//server.get(uriPrefix + '/service.js', renderCrudService(tview))
}
}
function walkViews(server,tcrud) {
//logger.debug('walk views: '+tcrud.tid);
if (tcrud.tparent) {
buildCrud(server,tcrud);
}
for (var i = 0; i < tcrud.tchilds.length; i++) {
walkViews(server,tcrud.tchilds[i]);
}
}
function buildCrudApi(server) { // todo add return function
troot = server.get('ff_root_tcrud_view');
walkViews(server,troot);
server.use(exports.injectExportFormat(troot.tmeta.tserver.tslug));
server.use(exports.bodyParserXml());
ncrud.launch(server,{
base: troot.tmeta.tserver.tslug,
cors: false,
timeoute: 10e3
});
}
module.exports = buildCrudApi;