var debug = require('debug')('ff:tcrud:build:server:api'); var clone = require('clone'); var Fontmin = require('fontmin'); var fs = require('fs'); var configTCrud = require('./tcrud-config'); var configRegistry = require('./config-registry'); var buildServerApiUrl = require('./build-server-api-url'); var buildServerExpress = require('./build-server-express'); var mod = (function () { var renderTemplate = function(pluginSlug,templateFile, contentType) { var renderFile = 'node-ff-tcrud/'+pluginSlug+'/'+templateFile; var troot = configTCrud.getRootTEntity(); return function (req, res, next) { res.set('Content-Type', contentType); res.render(renderFile,{ troot: troot, query: req.query }); }; } var hostTemplate = function(ctx, templateFile, contentType, skipReg) { var pluginKey = ctx.tplugin.tmeta.key; var apiPath = buildServerApiUrl.createSlugApiPluginBase(pluginKey,templateFile); debug('hostTemplate apiPath: '+apiPath+' templateFile: '+templateFile+' content-Type: '+contentType); ctx.server.get(apiPath, renderTemplate(pluginKey,templateFile, contentType)); // TODO: check sluging if (skipReg !== undefined) { return; } if (contentType.indexOf('css') !== -1) { configRegistry.registrateClientResource(apiPath,'css'); } if (contentType.indexOf('javascript') !== -1) { configRegistry.registrateClientResource(apiPath,'js'); } // TODO: no (t)html resources for caching ? } var filterContent = function(data,regexData) { if (regexData === undefined) { return data; } data = ''+data; var regexList = Object.keys(regexData); for (var i = 0; i < regexList.length; i++) { var regex = new RegExp(regexList[i],'gm'); var regexReplace = regexData[regexList[i]]; data = data.replace(regex,regexReplace); } return data; }; var hostFile = function (ctx,opt,basePath,optContentTypeHint) { if (opt === undefined) { throw new Error('No options given'); } if (opt.file === undefined) { throw new Error('No file option given'); } if (optContentTypeHint !== undefined) { if (optContentTypeHint === 'js') { opt.contentType = 'text/javascript'; } else { opt.contentType = 'text/css'; } } if (opt.fileCharset === undefined) { opt.fileCharset = 'utf8'; } if (opt.contentType === undefined) { opt.contentType = 'text/html'; } if (opt.registrate === undefined) { opt.registrate = true; } var file = basePath; if (opt.path !== undefined) { file = file + opt.path; } file = file + '/' + opt.file; debug('read host file: '+file); var fileContent = fs.readFileSync(file, opt.fileCharset); if (opt.filterFn !== undefined) { fileContent = opt.filterFn(fileContent); } var serverContent = filterContent(fileContent, opt.filterRegex); var serverContentType = opt.contentType; var apiPath = buildServerApiUrl.createSlugApiPluginBase(ctx.tplugin.tmeta.key,opt.file); ctx.server.get(apiPath, function(req, res) { res.set('Content-Type', serverContentType); res.send(serverContent); }); if (opt.registrate && opt.contentType === 'text/javascript') { configRegistry.registrateClientResource(apiPath,'js'); } if (opt.registrate && opt.contentType === 'text/css') { configRegistry.registrateClientResource(apiPath,'css'); } }; // FIXME: a bit hacky and not compleet or ready... var hostFileCssFont = function(ctx,opt,basePath) { if (opt === undefined) { throw new Error('No options given'); } if (opt.file === undefined) { throw new Error('No file option given'); } var filename = basePath; if (opt.path !== undefined) { filename += opt.path; } filename += opt.file; var fontmin = new Fontmin() fontmin.src(fs.readFileSync(filename)); if (filename.toLowerCase().indexOf('.otf') > 0) { fontmin.use(Fontmin.otf2ttf()); } //.use(Fontmin.otf2ttf()).use(Fontmin.ttf2woff()); // slow... fontmin.run(function (err, files, stream) { var fontBuffer = files[0].contents; debug('fond build done..'+files.length); debug('fond build done..'+Object.keys(files[0])); var fontStr = fontBuffer.toString('base64'); var fontWeight = ''; if (opt.fontWeight !== undefined) { fontWeight = '\tfont-weight: '+opt.fontWeight+';\n'; } var result = '\n'+ '@font-face {\n'+ ' font-family: "'+opt.fontFamily+'";\n'+ ' src: url("data:font/ttf;charset=utf-8;base64,'+fontStr+'") format("truetype");\n'+ fontWeight+ '}\n'; ///' src: url("data:font/ttf;charset=utf-8;base64,'+fontStr+'") format("truetype");\n'+ //cb(result); // ' font-style: normal;\n'+ //font/opentype //' src: url("data:application/x-font-woff;charset=utf-8;base64,'+fontData+'") format("woff");\n'+ ctx.server.get(apiPath, function(req, res) { res.set('Content-Type', 'text/css'); res.write(result); res.end(); }); }); // TODO: async build path ? var apiPath = ctx.createSlugApiPluginBase(opt.file); ctx.registrateClientCSSDataResource(apiPath); } var buildCrudApi = function(server) { var troot = configTCrud.getRootTEntity(); var ctx = { server: server, troot: troot, registrateMenu: function(menu,key) { if (menu['items'] === undefined) { menu['items'] = []; } configRegistry.getMasterConfig().rootTMenu[key] = menu; }, registrateMenuItem: function(menuItem,key) { configRegistry.getMasterConfig().rootTMenu[key].items.push(menuItem); }, registrateClientJSResource: function(clientResource) { return configRegistry.registrateClientResource(clientResource,'js'); }, registrateClientCSSResource: function(clientResource) { return configRegistry.registrateClientResource(clientResource,'css'); }, registrateClientCSSDataResource: function(clientResource) { return configRegistry.registrateClientResource(clientResource,'dss'); }, createSlugApiServerBase: function(postfix) { return buildServerApiUrl.createSlugApiServerBase(ctx.tplugin.tmeta.key,postfix); }, createSlugApiPluginBase: function(postfix) { return buildServerApiUrl.createSlugApiPluginBase(ctx.tplugin.tmeta.key,postfix); }, hostFileCSSLocal: function (opt) { hostFile(ctx,opt,ctx.tplugin.tmeta.localDir,'css'); }, hostFileJSLocal: function (opt) { hostFile(ctx,opt,ctx.tplugin.tmeta.localDir,'js'); }, hostFileCSSFontNodeModule: function (opt) { hostFileCssFont(ctx,opt,__dirname+'/../node_modules/'); }, hostFileCSSNodeModule: function (opt) { hostFile(ctx,opt,__dirname+'/../node_modules/','css'); }, hostFileJSNodeModule: function (opt) { hostFile(ctx,opt,__dirname+'/../node_modules/','js'); }, hostTemplateJS: function(templateFile, skipReg) { hostTemplate(ctx,templateFile, 'text/javascript', skipReg); }, hostTemplateHTML: function(templateFile, skipReg) { hostTemplate(ctx,templateFile, 'text/html', skipReg); }, hostTemplateCSS: function(templateFile, skipReg) { hostTemplate(ctx,templateFile, 'text/css', skipReg); }, renderRedirect: buildServerExpress.renderRedirect, renderFunctionJSON: buildServerExpress.renderFunctionJSON, renderTemplate: function (templateFile, contentType) { return renderTemplate(ctx.tplugin.tmeta.key,templateFile, contentType); } } buildServerExpress.saveRoutes(server); configRegistry.pluginCall('configServer',ctx, function(plugin) { buildServerExpress.saveRoutes(server); Array.prototype.push.apply(plugin['troutes'],buildServerExpress.getRoutesDiff(server)); }); } return function BuildServerApi() { this.build = function(server) { debug('buildServerApi'); configRegistry.assertPhaseServer(); var cors = require('cors'); server.use(cors({credentials: true, origin: '*'})); //troot.tmeta.tserver.tapi.cors buildCrudApi(server); }; }; })(); module.exports = new mod();