UNPKG

4.97 kBJavaScriptView Raw
1'use strict';
2
3// Small utility that resolves URIs using the application environment. On
4// CloudFoundry URIs are resolved using the route URI from the
5// VCAP_APPLICATION env variable.
6
7const _ = require('underscore');
8const vcapenv = require('abacus-vcapenv');
9
10const object = _.object;
11const map = _.map;
12const keys = _.keys;
13const some = _.some;
14
15// Setup debug log
16const debug = require('abacus-debug')('abacus-urienv');
17
18// Return the default protocol to use
19const defprotocol = () => process.browser ? window.location.protocol : 'http:';
20
21// Return the default host to use
22const defhost = () => process.browser ? window.location.hostname : 'localhost';
23
24// Return the default port to use
25const defport = () => process.browser ? window.location.port : process.env.PORT ? process.env.PORT : 9080;
26
27// Convert an alias to a value found in an environment variable
28const env = (alias) => {
29 const value = process.env[alias.replace('-', '_').toUpperCase()];
30 return value && value.includes('|') ? value.split('|') : value;
31};
32
33// Compute URLs in a hosted Cloud platform environment, using the
34// bound service instance URIs.
35const serviceInstanceURIs = (alias) => {
36 const serviceURIs = vcapenv.serviceInstancesCredentials(alias, 'uri');
37 if (serviceURIs.every((serviceURI) => /:/.test(serviceURI))) {
38 debug('Resolved %s to service instance URIs %o', alias, serviceURIs);
39 return serviceURIs;
40 }
41
42 return [];
43};
44
45const validDomain = (primaryDomain, uris) => {
46 return some(uris, (uri) => {
47 return uri.includes(primaryDomain);
48 });
49};
50
51const domain = (uris) => {
52 const primaryDomain = process.env.PRIMARY_DOMAIN;
53
54 const domain =
55 primaryDomain && validDomain(primaryDomain, uris)
56 ? primaryDomain
57 : uris[0].split('.').slice(1).join('.');
58
59 debug('Using domain: %s', domain);
60 return domain;
61};
62
63// Compute the URL of an app in a hosted Cloud platform environment, using
64// the app name and the given platform domain URI.
65const hosted = (alias, uris) => {
66 // Search for service instance
67 if (vcapenv.services()) {
68 debug('Searching in service instances %j', vcapenv.services());
69 const serviceURIs = serviceInstanceURIs(alias);
70 if (serviceURIs && serviceURIs.length > 0) return serviceURIs;
71 }
72
73 // Use the app environment
74 const resolved = env(alias) || alias;
75 if (Array.isArray(resolved) && resolved.every((r) => /:/.test(r))) {
76 debug('Resolved env alias %s to URIs %o', alias, resolved);
77 return resolved;
78 }
79 if (/:/.test(resolved)) {
80 debug('Resolved env alias %s to URI %s', alias, resolved);
81 return resolved;
82 }
83
84 const target = 'https:' + '//' + resolved + '.' + domain(uris);
85 debug('Resolved app route %s to %s', alias, target);
86 return target;
87};
88
89// Compute the URL of an app in a local environment, using a default protocol,
90// host and the given port.
91/* eslint complexity: 0 */
92const local = (alias, def) => {
93 // Use the app environment or the provided default
94 const resolved = env(alias) || def;
95 if (resolved) {
96 if (Array.isArray(resolved)) {
97 if (resolved.every((r) => /^[0-9]+$/.test(r))) {
98 const target = resolved.map((r) => defprotocol() + '//' + defhost() + ':' + r);
99 debug('Resolved alias %s to ports %o', alias, target);
100 return target;
101 }
102 debug('Resolved alias %s to URIs %o', alias, resolved);
103 return resolved;
104 }
105 if (/^[0-9]+$/.test(resolved)) {
106 const target = defprotocol() + '//' + defhost() + ':' + resolved;
107 debug('Resolved alias %s to port %s', alias, target);
108 return target;
109 }
110 debug('Resolved alias %s to URI %s', alias, resolved);
111 return resolved;
112 }
113
114 // Use default values
115 const target = defprotocol() + '//' + defhost() + (defport() !== '' ? ':' + defport() : '');
116 debug('Resolved alias %s to default %s', alias, target);
117 return target;
118};
119
120// Compute the URL of an app, use like this: resolve.url('abc',
121// 'http://localhost:1234') will return 'http://abc.bluemix.net' in an app
122// mapped to 'xyz.bluemix.net' and 'http://localhost:1234' otherwise
123const url = (alias, def) => {
124 // In a Cloud Foundry env, compute the URL using the application URI
125 const uris = (vcapenv.app() || {}).application_uris;
126 if (uris !== undefined && uris.length) return hosted(alias, uris);
127
128 // In a local env, compute the URL using defaults
129 return local(alias, def);
130};
131
132// Compute the URLs of a collection of apps, use like this: resolve({ abc:
133// 'http://localhost:1234', def: 4567, ghi: undefined })
134// will return { abc: 'http://abc.bluemix.net', def: 'http://def.bluemix.net',
135// ghi: 'http://ghi.bluemix.net' } in an app mapped to 'xyz.bluemix.net' and
136// { abc: 'http://localhost:1234', def: 'http://localhost:4567', ghi:
137// 'http://localhost:8080' } otherwise
138const resolve = (apps) => object(map(keys(apps), (k) => [k, url(k, apps[k])]));
139
140// Export our public functions
141module.exports = resolve;
142module.exports.resolve = resolve;
143module.exports.url = url;