UNPKG

6.38 kBJavaScriptView Raw
1/**
2 * @license
3 * MOST Web Framework 2.0 Codename Blueshift
4 * Copyright (c) 2017, THEMOST LP All rights reserved
5 *
6 * Use of this source code is governed by an BSD-3-Clause license that can be
7 * found in the LICENSE file at https://themost.io/license
8 */
9///
10var LangUtils = require('@themost/common/utils').LangUtils;
11var HttpViewEngine = require('../types').HttpViewEngine;
12var _ = require('lodash');
13var fs = require('fs');
14var DirectiveEngine = require('./../handlers/directive').DirectiveEngine;
15var PostExecuteResultArgs = require('./../handlers/directive').PostExecuteResultArgs;
16var HttpViewContext = require('./../mvc').HttpViewContext;
17var HttpViewResult = require('./../mvc').HttpViewResult;
18var HttpNotFoundError = require('@themost/common').HttpNotFoundError;
19var Args = require('@themost/common').Args;
20/**
21 * A standalone application for implementing NgEngine under native environments
22 * @constructor
23 */
24function NgApplication() {
25 // set services
26 Object.defineProperty(this, 'services', {
27 value: {}
28 });
29}
30
31NgApplication.prototype.hasService = function(serviceCtor) {
32 Args.notFunction(serviceCtor,"Service constructor");
33 return this.services.hasOwnProperty(serviceCtor.name);
34};
35
36NgApplication.prototype.useService = function(serviceCtor) {
37 Args.notFunction(serviceCtor,"Service constructor");
38 this.services[serviceCtor.name] = new serviceCtor(this);
39 return this;
40};
41
42NgApplication.prototype.getService = function(serviceCtor) {
43 Args.notFunction(serviceCtor,"Service constructor");
44 return this.services[serviceCtor.name];
45};
46
47// noinspection JSClosureCompilerSyntax
48/**
49 * A standalone context for implementing NgEngine under native environments
50 * @constructor
51 * @augments HttpContext
52 */
53function NgContext() {
54 this.application = null;
55 this.request = null;
56 this.response = null;
57}
58
59NgContext.prototype.getApplication = function() {
60 return this.application;
61};
62
63// noinspection JSClosureCompilerSyntax
64/**
65 * @class
66 * @constructor
67 * @param {HttpContext=} context
68 * @augments HttpViewEngine
69 */
70function NgEngine(context) {
71 NgEngine.super_.bind(this)(context);
72}
73LangUtils.inherits(NgEngine, HttpViewEngine);
74
75/**
76 *
77 * @param {string} filename
78 * @param {*=} data
79 * @param {Function=} callback
80 */
81NgEngine.prototype.render = function(filename, data, callback) {
82 var self = this;
83
84 var template = (self.context.request && self.context.request.route && self.context.request.route.template) ||
85 (self.context.request && self.context.request.routeData && self.context.request.routeData.template);
86 var controller = self.context.request && self.context.request.route && self.context.request.route.controller;
87
88 function renderFile(file, view, data, done) {
89 fs.readFile(file,'utf-8', function(err, str) {
90 try {
91 if (err) {
92 if (err.code === 'ENOENT') {
93 //throw not found exception
94 return done(new HttpNotFoundError('View cannot be found.'));
95 }
96 return done(err);
97 }
98 var viewContext = new HttpViewContext(self.getContext());
99 viewContext.body = str;
100 viewContext.data = data;
101 viewContext.templatePath = view;
102 var directiveHandler = new DirectiveEngine();
103 var args = _.assign(new PostExecuteResultArgs(), {
104 "context": self.getContext(),
105 "target":viewContext
106 });
107 // set bootstrap method if any
108 directiveHandler.hasBootstrap = this.hasBootstrap;
109 directiveHandler.postExecuteResult(args, function(err) {
110 if (err) {
111 return done(err);
112 }
113 return done(null, viewContext.body);
114 });
115 }
116 catch (err) {
117 return done(err);
118 }
119 });
120 }
121
122 if (typeof template === 'string' && typeof controller === 'string') {
123 return HttpViewResult.resolveViewPath(self.context, controller, template, {
124 extension: "ng"
125 }, function(err, layout) {
126 if (layout) {
127 return renderFile(layout, filename, data, callback);
128 }
129 else {
130 return renderFile(filename, null, data, callback);
131 }
132 });
133 }
134 return renderFile(filename, null, data, callback);
135
136};
137
138/**
139 *
140 * @param {string} str - A string which represents the template to be rendered
141 * @param {*=} data - Any object which represents the data to be used while rendering
142 * @returns Promise<any>
143 */
144NgEngine.prototype.renderString = function(str, data) {
145 const self = this;
146 return new Promise((resolve, reject) => {
147 var viewContext = new HttpViewContext(self.getContext());
148 viewContext.body = str;
149 viewContext.data = data || {};
150 var directiveHandler = new DirectiveEngine();
151 var args = Object.assign(new PostExecuteResultArgs(), {
152 "context": self.getContext(),
153 "target":viewContext
154 });
155 // set bootstrap method if any
156 directiveHandler.hasBootstrap = this.hasBootstrap;
157 directiveHandler.postExecuteResult(args, function(err) {
158 if (err) {
159 return reject(err);
160 }
161 return resolve(viewContext.body);
162 });
163 });
164
165};
166/**
167 * Defines a bootstrap function for angular application
168 * @example
169 * this.bootstrap(function(angular) {
170 * return angular.module('server', []);
171 * })
172 * @param {Function} bootstrapFunc
173 * @returns NgEngine
174 */
175NgEngine.prototype.bootstrap = function(bootstrapFunc) {
176 Args.notFunction(bootstrapFunc, 'Application bootstrap should be a function');
177 this.hasBootstrap = bootstrapFunc;
178 return this;
179};
180
181/**
182 * @param {HttpContext=} context
183 * @returns {NgEngine}
184 */
185NgEngine.createInstance = function(context) {
186 return new NgEngine(context);
187};
188
189module.exports.NgEngine = NgEngine;
190module.exports.NgApplication = NgApplication;
191module.exports.NgContext = NgContext;
192/**
193 * @param {HttpContext=} context
194 * @returns {NgEngine}
195 */
196module.exports.createInstance = function(context) {
197 return NgEngine.createInstance(context);
198};