1 |
|
2 |
|
3 |
|
4 |
|
5 | var fs = require('fs-extra');
|
6 | var path = require('path');
|
7 | var _ = require('lodash');
|
8 | var koa = require('koa');
|
9 | var Router = require('koa-router');
|
10 | var bs = require('browser-sync').create();
|
11 | var request = require('request');
|
12 | var Domo = require('ryuu-client-beta');
|
13 | var inquirer = require("inquirer");
|
14 | var Promise = require('bluebird');
|
15 | var body_parser = require('koa-bodyparser');
|
16 | var app = koa();
|
17 | var api = new Router();
|
18 | var portfinder = require('portfinder');
|
19 | var serve = require('koa-static');
|
20 | var mount = require('koa-mount');
|
21 | var proxyaddr = require('proxy-addr');
|
22 | var session = require('../util/session');
|
23 | var appStructure = require('../util/appStructure');
|
24 |
|
25 | portfinder.basePort = 3000;
|
26 |
|
27 | api.get('/', function *(){
|
28 | var isValidSession = yield session.check(app.domo);
|
29 | var isValidContext = true;
|
30 | var hasThumbnail = appStructure.hasThumbnail();
|
31 |
|
32 |
|
33 |
|
34 | var template = _.template(fs.readFileSync(path.resolve(__dirname + '/../server/domodev/index.html')));
|
35 |
|
36 | var manifest = fs.readJsonSync(path.resolve(process.cwd() + '/' + (app.options.manifest || 'manifest.json')));
|
37 | var sizeMultiplier = {
|
38 | width: 235,
|
39 | height: 290
|
40 | }
|
41 |
|
42 |
|
43 | var width = 235 * manifest.size.width - 10 + 'px';
|
44 | var height = 290 * manifest.size.height - 40 + 'px';
|
45 | var fullpage = manifest.fullpage;
|
46 |
|
47 | var context = yield createContext(manifest.id, manifest.mapping);
|
48 |
|
49 | if (!context){
|
50 | isValidContext = false;
|
51 | context = {id: 0};
|
52 | }
|
53 |
|
54 | var appData = yield getDomoappsData();
|
55 |
|
56 | var userId = app.options.userId || appData.user.id;
|
57 | var customerId = 1 || appData.customer;
|
58 |
|
59 | var url = `index.html?userId=${userId}&customer=${customerId}&locale=en-US&platform=desktop&context=${context.id}`;
|
60 |
|
61 | this.body = template({
|
62 | manifest,
|
63 | width,
|
64 | height,
|
65 | url,
|
66 | isValidSession,
|
67 | isValidContext,
|
68 | hasThumbnail,
|
69 | fullpage
|
70 | });
|
71 | });
|
72 |
|
73 |
|
74 | api.all('/data/*', function *(){
|
75 | var manifest = fs.readJsonSync(path.resolve(process.cwd() + '/' + (app.options.manifest || 'manifest.json')));
|
76 | var appData = yield getDomoappsData();
|
77 | var j = request.jar();
|
78 | var url = appData.url + this.request.url;
|
79 | var method = this.request.method;
|
80 |
|
81 | var headers = {
|
82 | referer: this.request.headers.referer,
|
83 | accept: this.request.headers.accept,
|
84 | 'Content-Type': this.request.headers['content-type'] || this.request.headers['Content-Type'] || 'application/json'
|
85 | };
|
86 |
|
87 |
|
88 | var body = JSON.stringify(this.request.body);
|
89 |
|
90 | if (url.indexOf("dataversions") !== -1){
|
91 | var getRawBody = require('raw-body')
|
92 | body = yield getRawBody(this.req, {
|
93 | length: this.length,
|
94 | limit: '1mb',
|
95 | encoding: this.charset
|
96 | });
|
97 | url = url.replace("/dataversions", "/dataversions/domodev");
|
98 | url += "&designId=" + manifest.id;
|
99 | var alias = url.match(/data\/(v1|v2|v3)\/(.*)\/dataversions/)[2];
|
100 | url += "&datasetId=" + _.find(manifest.mapping, {alias: alias}).dataSetId;
|
101 | }
|
102 |
|
103 | this.body = yield app.domo.processRequestRaw({
|
104 | url: url,
|
105 | method: method,
|
106 | jar: j,
|
107 | body: body,
|
108 | headers: headers
|
109 | });
|
110 | });
|
111 |
|
112 | api.all('/domo/*', function *(){
|
113 | var appData = yield getDomoappsData();
|
114 | var j = request.jar();
|
115 | var url = appData.url + this.request.url;
|
116 |
|
117 | var headers = {
|
118 | referer: this.request.headers.referer,
|
119 | accept: this.request.headers.accept,
|
120 | 'Content-Type': this.request.headers['content-type'] || this.request.headers['Content-Type'] || 'application/json'
|
121 | };
|
122 |
|
123 | this.body = yield app.domo.processRequestRaw({url: url, jar: j, headers: headers});
|
124 |
|
125 | });
|
126 |
|
127 | app.use(body_parser({
|
128 | detectJSON: function (ctx) {
|
129 | return false;
|
130 | }
|
131 | }));
|
132 | app.use(api.middleware());
|
133 | app.use(mount('/domodev', serve(path.resolve(__dirname + '/../server/domodev'))));
|
134 | app.use(mount(serve('.')));
|
135 |
|
136 | module.exports = {
|
137 | start: function(domo, options){
|
138 | return new Promise(function(resolve, reject){
|
139 |
|
140 | portfinder.getPorts(2, function (err, ports) {
|
141 | var assetsPort = ports[0];
|
142 | var dataPort = ports[1];
|
143 | app.domo = domo;
|
144 | app.options = options;
|
145 |
|
146 | session.check(app.domo)
|
147 | .then(function() {
|
148 | var external = Boolean(app.options.external);
|
149 | var middleware = external ? [] : getMiddleware();
|
150 |
|
151 | app.listen(dataPort)
|
152 |
|
153 | bs.init({
|
154 | proxy: "localhost:" + dataPort,
|
155 | port: assetsPort,
|
156 | notify: false,
|
157 | ui: false,
|
158 | logLevel: 'info',
|
159 | logPrefix: 'Domo Dev',
|
160 | online: external,
|
161 |
|
162 | files: ['**/*', '!node_modules/**/*'],
|
163 | middleware: middleware,
|
164 | });
|
165 | bs.instance.logger.info('Instance: ' + app.domo.instance);
|
166 | })
|
167 | .catch(function(e){
|
168 | reject('Session expired. Please login again using domo login.');
|
169 | })
|
170 | });
|
171 |
|
172 | });
|
173 | }
|
174 | };
|
175 |
|
176 | function getCustomer(){
|
177 | var regexp = /([\w]+)[\.|-]/;
|
178 | return app.domo.instance.match(regexp)[1];
|
179 | }
|
180 |
|
181 | function getEnv(){
|
182 | var regexp = /([-_\w]+)\.(.*)/;
|
183 | return app.domo.instance.match(regexp)[2];
|
184 | }
|
185 |
|
186 | function getMiddleware() {
|
187 | return [ function(req, res, next) {
|
188 | if (proxyaddr(req, '127.0.0.1') !== '::1') {
|
189 | Error.stackTraceLimit = 0;
|
190 | next(new Error('Access Denied'));
|
191 | } else {
|
192 | next();
|
193 | }
|
194 | }];
|
195 | }
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 | function getDomoappsData(){
|
202 | var uuid = Domo.createUUID();
|
203 |
|
204 | var options = {
|
205 | url: 'https://' + app.domo.instance + '/api/content/v1/mobile/environment'
|
206 | }
|
207 |
|
208 | return app.domo.processRequest(options)
|
209 | .then(function(res) {
|
210 | var data = JSON.parse(res);
|
211 | data.url = 'https://'+uuid+'.' + JSON.parse(res).domoappsDomain;
|
212 | return data;
|
213 | }).catch(function() {
|
214 | var data = {url: 'https://'+uuid+'.domoapps.' + getEnv()};
|
215 | return data;
|
216 | });
|
217 | }
|
218 |
|
219 | function createContext(designId, mapping){
|
220 | var options = {
|
221 | url: 'https://' + app.domo.instance + '/domoapps/apps/v2/contexts',
|
222 | method: 'POST',
|
223 | json: {designId: designId, mapping: mapping}
|
224 | };
|
225 |
|
226 | return app.domo.processRequest(options)
|
227 | .then(function(res) {
|
228 | return res[0];
|
229 | }).catch(function(err) {
|
230 | return;
|
231 | })
|
232 | }
|