diff --git a/bundle/src/images.js b/bundle/src/images.js index 2b81a297..ee1d313e 100644 --- a/bundle/src/images.js +++ b/bundle/src/images.js @@ -1,7 +1,9 @@ const Main = require('apr-main'); const CloudApiGql = require('cloudapi-gql'); const Url = require('url'); + const Server = require('./server'); +const Ui = require('my-joy-images'); const { PORT = 4003, @@ -25,19 +27,24 @@ Main(async () => { BASE_URL }); - await server.register({ - plugin: CloudApiGql, - options: { - authStrategy: 'sso', - keyPath, - keyId, - apiBaseUrl, - dcName + await server.register([ + { + plugin: CloudApiGql, + options: { + authStrategy: 'sso', + keyPath, + keyId, + apiBaseUrl, + dcName + }, + routes: { + prefix: `/${PREFIX}` + } }, - routes: { - prefix: `/${PREFIX}` + { + plugin: Ui } - }); + ]); await server.start(); }); diff --git a/bundle/src/instances.js b/bundle/src/instances.js index 7b237131..3fbcb4ee 100644 --- a/bundle/src/instances.js +++ b/bundle/src/instances.js @@ -1,7 +1,9 @@ const Main = require('apr-main'); const CloudApiGql = require('cloudapi-gql'); const Url = require('url'); + const Server = require('./server'); +const Ui = require('my-joy-instances'); const { PORT = 4002, @@ -25,19 +27,24 @@ Main(async () => { BASE_URL }); - await server.register({ - plugin: CloudApiGql, - options: { - authStrategy: 'sso', - keyPath, - keyId, - apiBaseUrl, - dcName + await server.register([ + { + plugin: CloudApiGql, + options: { + authStrategy: 'sso', + keyPath, + keyId, + apiBaseUrl, + dcName + }, + routes: { + prefix: `/${PREFIX}` + } }, - routes: { - prefix: `/${PREFIX}` + { + plugin: Ui } - }); + ]); await server.start(); }); diff --git a/bundle/src/navigation.js b/bundle/src/navigation.js index 380e8213..94f7eee1 100644 --- a/bundle/src/navigation.js +++ b/bundle/src/navigation.js @@ -1,7 +1,9 @@ const Main = require('apr-main'); const Nav = require('hapi-webconsole-nav'); const Url = require('url'); + const Server = require('./server'); +const Ui = require('my-joy-navigation'); const Regions = require('../data/regions'); const Categories = require('../data/categories'); @@ -30,22 +32,27 @@ Main(async () => { BASE_URL }); - await server.register({ - plugin: Nav, - options: { - keyPath, - keyId, - apiBaseUrl, - dcName, - baseUrl, - regions: Regions, - accountServices: Account, - categories: Categories + await server.register([ + { + plugin: Nav, + options: { + keyPath, + keyId, + apiBaseUrl, + dcName, + baseUrl, + regions: Regions, + accountServices: Account, + categories: Categories + }, + routes: { + prefix: `/${PREFIX}` + } }, - routes: { - prefix: `/${PREFIX}` + { + plugin: Ui } - }); + ]); await server.start(); }); diff --git a/package.json b/package.json index 2535a93a..acf2dcbe 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "repository": "github:yldio/joyent-portal", "scripts": { "dev": "lerna run dev --parallel --stream", + "ssr": "npm run build:bundle; lerna run dev --scope joyent-portal-bundle --stream", "test": "redrun -s build:test test:run", "test:ci": "CI=1 redrun -s build:test test:ci:run", "lint": "lerna run lint --stream", diff --git a/packages/my-joy-images/lib/index.js b/packages/my-joy-images/lib/index.js index 73637eb3..d0d9d06a 100644 --- a/packages/my-joy-images/lib/index.js +++ b/packages/my-joy-images/lib/index.js @@ -1,3 +1,4 @@ +const Boom = require('boom'); const Inert = require('inert'); const Path = require('path'); const RenderReact = require('hapi-render-react'); @@ -8,8 +9,21 @@ const Fs = require('mz/fs'); const { NAMESPACE = 'images' } = process.env; exports.register = async server => { + let manifest = {}; + + try { + manifest = require('../build/asset-manifest.json'); + } catch (err) { + if (NODE_ENV === 'production') { + throw err; + } else { + console.error(err); + } + } + const relativeTo = Path.join(__dirname, 'app'); - const buildRoot = Path.join(__dirname, `../build/${NAMESPACE}/static/`); + const buildRoot = Path.join(__dirname, '../build'); + const buildStatic = Path.join(buildRoot, `${NAMESPACE}`); const publicRoot = Path.join(__dirname, `../public/static/`); await server.register([ @@ -56,15 +70,41 @@ exports.register = async server => { const { params } = request; const { rest } = params; - const publicPathname = Path.join(publicRoot, rest); - const buildPathname = Path.join(buildRoot, rest); + if (!rest) { + return Boom.notFound(); + } - const [err] = await Intercept( + const publicPathname = Path.join(publicRoot, rest); + const [err1] = await Intercept( Fs.access(publicPathname, Fs.constants.R_OK) ); - const file = err ? buildPathname : publicPathname; - return h.file(file, { confine: false }); + if (!err1) { + return h.file(publicPathname, { + confine: publicRoot + }); + } + + const filename = manifest[rest]; + if (!filename) { + return Boom.notFound(); + } + + const buildMapPathname = Path.join(buildRoot, filename); + const [err2] = await Intercept( + Fs.access(buildMapPathname, Fs.constants.R_OK) + ); + + if (!err2) { + return h.file(buildMapPathname, { + confine: buildStatic + }); + } + + const buildPathname = Path.join(buildStatic, rest); + return h.file(buildPathname, { + confine: buildStatic + }); } }, { diff --git a/packages/my-joy-images/package.json b/packages/my-joy-images/package.json index ac66a89c..ccd520ad 100644 --- a/packages/my-joy-images/package.json +++ b/packages/my-joy-images/package.json @@ -26,6 +26,7 @@ "apollo-link-http": "^1.5.3", "apr-intercept": "^3.0.3", "apr-reduce": "^3.0.3", + "boom": "^7.2.0", "cross-fetch": "^2.1.0", "date-fns": "^1.29.0", "declarative-redux-form": "^2.0.8", @@ -33,7 +34,7 @@ "force-array": "^3.1.0", "fuse.js": "^3.2.0", "hapi-render-react": "^2.5.2", - "hapi-render-react-joyent-document": "^7.0.1", + "hapi-render-react-joyent-document": "^7.1.0", "inert": "^5.1.0", "joyent-logo-assets": "^1.1.0", "joyent-react-styled-flexboxgrid": "^2.2.3", diff --git a/packages/my-joy-images/public/index.html b/packages/my-joy-images/public/index.html deleted file mode 100644 index 94f53067..00000000 --- a/packages/my-joy-images/public/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - My Joyent Images β - - - -
- - - diff --git a/packages/my-joy-images/src/html.js b/packages/my-joy-images/src/html.js index d6a0c1ca..bc84827e 100644 --- a/packages/my-joy-images/src/html.js +++ b/packages/my-joy-images/src/html.js @@ -1,11 +1,19 @@ const React = require('react'); -module.exports = ({ htmlAttrs = {}, bodyAttrs = {}, head = [], children = null }) => ( +module.exports = ({ + htmlAttrs = {}, + bodyAttrs = {}, + head = [], + children = null +}) => ( - - - + + + {head} diff --git a/packages/my-joy-instances/lib/index.js b/packages/my-joy-instances/lib/index.js index 86966da7..28e9ccd1 100644 --- a/packages/my-joy-instances/lib/index.js +++ b/packages/my-joy-instances/lib/index.js @@ -1,3 +1,4 @@ +const Boom = require('boom'); const Inert = require('inert'); const Path = require('path'); const RenderReact = require('hapi-render-react'); @@ -6,11 +7,24 @@ const Url = require('url'); const Intercept = require('apr-intercept'); const Fs = require('mz/fs'); -const { NAMESPACE = 'instances' } = process.env; +const { NAMESPACE = 'instances', NODE_ENV = 'development' } = process.env; exports.register = async server => { + let manifest = {}; + + try { + manifest = require('../build/asset-manifest.json'); + } catch (err) { + if (NODE_ENV === 'production') { + throw err; + } else { + console.error(err); + } + } + const relativeTo = Path.join(__dirname, 'app'); - const buildRoot = Path.join(__dirname, `../build/${NAMESPACE}/static/`); + const buildRoot = Path.join(__dirname, '../build'); + const buildStatic = Path.join(buildRoot, `${NAMESPACE}`); const publicRoot = Path.join(__dirname, `../public/static/`); await server.register([ @@ -57,15 +71,41 @@ exports.register = async server => { const { params } = request; const { rest } = params; - const publicPathname = Path.join(publicRoot, rest); - const buildPathname = Path.join(buildRoot, rest); + if (!rest) { + return Boom.notFound(); + } - const [err] = await Intercept( + const publicPathname = Path.join(publicRoot, rest); + const [err1] = await Intercept( Fs.access(publicPathname, Fs.constants.R_OK) ); - const file = err ? buildPathname : publicPathname; - return h.file(file, { confine: false }); + if (!err1) { + return h.file(publicPathname, { + confine: publicRoot + }); + } + + const filename = manifest[rest]; + if (!filename) { + return Boom.notFound(); + } + + const buildMapPathname = Path.join(buildRoot, filename); + const [err2] = await Intercept( + Fs.access(buildMapPathname, Fs.constants.R_OK) + ); + + if (!err2) { + return h.file(buildMapPathname, { + confine: buildStatic + }); + } + + const buildPathname = Path.join(buildStatic, rest); + return h.file(buildPathname, { + confine: buildStatic + }); } }, { diff --git a/packages/my-joy-instances/package.json b/packages/my-joy-instances/package.json index 8f1b3a12..89de29ad 100644 --- a/packages/my-joy-instances/package.json +++ b/packages/my-joy-instances/package.json @@ -25,6 +25,7 @@ "apollo-link-http": "^1.5.3", "apr-intercept": "^3.0.3", "apr-reduce": "^3.0.3", + "boom": "^7.2.0", "bytes": "^3.0.0", "clipboard-copy": "^2.0.0", "constant-case": "^2.0.0", @@ -34,7 +35,7 @@ "exenv": "^1.2.2", "fuse.js": "^3.2.0", "hapi-render-react": "^2.5.2", - "hapi-render-react-joyent-document": "^7.0.1", + "hapi-render-react-joyent-document": "^7.1.0", "inert": "^5.1.0", "joyent-logo-assets": "^1.1.0", "joyent-manifest-editor": "^1.4.0", diff --git a/packages/my-joy-instances/src/html.js b/packages/my-joy-instances/src/html.js index d6a0c1ca..fce1302f 100644 --- a/packages/my-joy-instances/src/html.js +++ b/packages/my-joy-instances/src/html.js @@ -1,18 +1,27 @@ const React = require('react'); -module.exports = ({ htmlAttrs = {}, bodyAttrs = {}, head = [], children = null }) => ( +module.exports = ({ + htmlAttrs = {}, + bodyAttrs = {}, + head = [], + children = null +}) => ( - - - + + + + {head}