UNPKG

@themost/web

Version:

MOST Web Framework 2.0 - Web Server Module

199 lines (183 loc) 6.38 kB
/** * @license * MOST Web Framework 2.0 Codename Blueshift * Copyright (c) 2017, THEMOST LP All rights reserved * * Use of this source code is governed by an BSD-3-Clause license that can be * found in the LICENSE file at https://themost.io/license */ /// var LangUtils = require('@themost/common/utils').LangUtils; var HttpViewEngine = require('../types').HttpViewEngine; var _ = require('lodash'); var fs = require('fs'); var DirectiveEngine = require('./../handlers/directive').DirectiveEngine; var PostExecuteResultArgs = require('./../handlers/directive').PostExecuteResultArgs; var HttpViewContext = require('./../mvc').HttpViewContext; var HttpViewResult = require('./../mvc').HttpViewResult; var HttpNotFoundError = require('@themost/common').HttpNotFoundError; var Args = require('@themost/common').Args; /** * A standalone application for implementing NgEngine under native environments * @constructor */ function NgApplication() { // set services Object.defineProperty(this, 'services', { value: {} }); } NgApplication.prototype.hasService = function(serviceCtor) { Args.notFunction(serviceCtor,"Service constructor"); return this.services.hasOwnProperty(serviceCtor.name); }; NgApplication.prototype.useService = function(serviceCtor) { Args.notFunction(serviceCtor,"Service constructor"); this.services[serviceCtor.name] = new serviceCtor(this); return this; }; NgApplication.prototype.getService = function(serviceCtor) { Args.notFunction(serviceCtor,"Service constructor"); return this.services[serviceCtor.name]; }; // noinspection JSClosureCompilerSyntax /** * A standalone context for implementing NgEngine under native environments * @constructor * @augments HttpContext */ function NgContext() { this.application = null; this.request = null; this.response = null; } NgContext.prototype.getApplication = function() { return this.application; }; // noinspection JSClosureCompilerSyntax /** * @class * @constructor * @param {HttpContext=} context * @augments HttpViewEngine */ function NgEngine(context) { NgEngine.super_.bind(this)(context); } LangUtils.inherits(NgEngine, HttpViewEngine); /** * * @param {string} filename * @param {*=} data * @param {Function=} callback */ NgEngine.prototype.render = function(filename, data, callback) { var self = this; var template = (self.context.request && self.context.request.route && self.context.request.route.template) || (self.context.request && self.context.request.routeData && self.context.request.routeData.template); var controller = self.context.request && self.context.request.route && self.context.request.route.controller; function renderFile(file, view, data, done) { fs.readFile(file,'utf-8', function(err, str) { try { if (err) { if (err.code === 'ENOENT') { //throw not found exception return done(new HttpNotFoundError('View cannot be found.')); } return done(err); } var viewContext = new HttpViewContext(self.getContext()); viewContext.body = str; viewContext.data = data; viewContext.templatePath = view; var directiveHandler = new DirectiveEngine(); var args = _.assign(new PostExecuteResultArgs(), { "context": self.getContext(), "target":viewContext }); // set bootstrap method if any directiveHandler.hasBootstrap = this.hasBootstrap; directiveHandler.postExecuteResult(args, function(err) { if (err) { return done(err); } return done(null, viewContext.body); }); } catch (err) { return done(err); } }); } if (typeof template === 'string' && typeof controller === 'string') { return HttpViewResult.resolveViewPath(self.context, controller, template, { extension: "ng" }, function(err, layout) { if (layout) { return renderFile(layout, filename, data, callback); } else { return renderFile(filename, null, data, callback); } }); } return renderFile(filename, null, data, callback); }; /** * * @param {string} str - A string which represents the template to be rendered * @param {*=} data - Any object which represents the data to be used while rendering * @returns Promise<any> */ NgEngine.prototype.renderString = function(str, data) { const self = this; return new Promise((resolve, reject) => { var viewContext = new HttpViewContext(self.getContext()); viewContext.body = str; viewContext.data = data || {}; var directiveHandler = new DirectiveEngine(); var args = Object.assign(new PostExecuteResultArgs(), { "context": self.getContext(), "target":viewContext }); // set bootstrap method if any directiveHandler.hasBootstrap = this.hasBootstrap; directiveHandler.postExecuteResult(args, function(err) { if (err) { return reject(err); } return resolve(viewContext.body); }); }); }; /** * Defines a bootstrap function for angular application * @example * this.bootstrap(function(angular) { * return angular.module('server', []); * }) * @param {Function} bootstrapFunc * @returns NgEngine */ NgEngine.prototype.bootstrap = function(bootstrapFunc) { Args.notFunction(bootstrapFunc, 'Application bootstrap should be a function'); this.hasBootstrap = bootstrapFunc; return this; }; /** * @param {HttpContext=} context * @returns {NgEngine} */ NgEngine.createInstance = function(context) { return new NgEngine(context); }; module.exports.NgEngine = NgEngine; module.exports.NgApplication = NgApplication; module.exports.NgContext = NgContext; /** * @param {HttpContext=} context * @returns {NgEngine} */ module.exports.createInstance = function(context) { return NgEngine.createInstance(context); };