Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring #11

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 3 additions & 13 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

# 4 space indentation
[**/*.js]
indent_style = space
indent_size = 4

[{package.json,bower.json}]
indent_style = space
indent_size = 2
16 changes: 0 additions & 16 deletions .eslintrc

This file was deleted.

10 changes: 10 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
root: true,
env: {
node: true,
es6: true
},
extends: [
'standard'
]
}
3 changes: 2 additions & 1 deletion .mocharc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
spec: ['test/unit/', 'test/e2e/'],
require: 'test/mocha.globals.js',
recursive: true
recursive: true,
exit: true
};

2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ node_js:
- "lts/*"
cache: yarn
script:
- yarn lint && yarn test
- yarn test
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,7 @@ An example of how to use this module with grunt-contrib-connect, see this snippe
config.manifests = (config.manifests || []).concat(options.base + '/manifests/');
config = appserver.tools.unifyOptions(config);

middlewares.push(appserver.middleware.appsload(config));
middlewares.push(appserver.middleware.manifests(config));
middlewares.push(appserver.middleware.localfiles(config));
middlewares.push(appserver.middleware.proxy(config));
return middlewares;
}
Expand Down
97 changes: 41 additions & 56 deletions bin/appserver
Original file line number Diff line number Diff line change
@@ -1,43 +1,41 @@
#!/usr/bin/env node

var url = require('url');
var path = require('path');

var nopt = require('nopt');
var server = require('../lib/server');
const url = require('url')
const path = require('path')
const nopt = require('nopt')
const server = require('../lib/appserver')

nopt.invalidHandler = function (key, val) {
var messages = {
port: 'Invalid port number: ',
server: 'Invalid server URL: ',
zoneinfo: 'Invalid tzdata path: '
};
console.error((messages[key] || 'Invalid option: ' + key + '=') + val);
usage(1);
};
const messages = {
port: 'Invalid port number: ',
server: 'Invalid server URL: ',
zoneinfo: 'Invalid tzdata path: '
}
console.error((messages[key] || 'Invalid option: ' + key + '=') + val)
usage(1)
}

var options = nopt({
help: Boolean,
manifests: [path, Array],
path: String,
port: Number,
server: url,
verbose: ['local', 'remote', 'proxy', 'all', Array],
zoneinfo: path
const options = nopt({
help: Boolean,
manifests: [path, Array],
path: [path, Array],
port: Number,
server: String,
verbose: ['local', 'remote', 'proxy', 'all', Array]
}, {
h: '--help',
m: '--manifests',
p: '--port',
s: '--server',
v: '--verbose',
z: '--zoneinfo'
}, process.argv, 2);
h: '--help',
m: '--manifests',
p: '--port',
s: '--server',
v: '--verbose',
z: '--zoneinfo'
}, process.argv, 2)

if (options.help) usage(0);
if (options.help) usage(0)

function usage(exitCode) {
(exitCode ? console.error : console.log)(
'Usage: appserver [OPTION]... [PATH]...\n\n' +
function usage (exitCode) {
(exitCode ? console.error : console.log)(
'Usage: appserver [OPTION]... [PATH]...\n\n' +
' -h, --help print this help message and exit\n' +
' -m PATH, --manifests=PATH add manifests from the specified path (default:\n' +
' the "manifests" subdirectory of every file path)\n' +
Expand All @@ -47,34 +45,21 @@ function usage(exitCode) {
' -v TYPE, --verbose=TYPE print more information depending on TYPE:\n' +
' local: local files, remote: remote files,\n' +
' proxy: forwarded URLs, all: shortcut for all three\n' +
' -z PATH, --zoneinfo=PATH use timezone data from the specified path\n' +
' (default: /usr/share/zoneinfo/)\n\n' +
'Files are searched in each PATH in order and requested from the server if not\n' +
'found. If no paths are specified, the default is /var/www/appsuite/.');
process.exit(exitCode);
'found. If no paths are specified, the default is /var/www/appsuite/.')
process.exit(exitCode)
}

var prefixes = options.argv.remain.map(function (s) {
return path.resolve(s);
});
if (!prefixes.length) prefixes = [];
var manifests = options.manifests || append(prefixes, 'manifests/');
manifests.reverse();

function append(array, suffix) {
return array.map(function(prefix) {
return path.join(prefix, suffix);
});
}
options.prefixes = prefixes;
options.manifests = manifests;
options.prefixes = options.argv.remain.map(p => path.resolve(p))
options.manifests = options.manifests || options.prefixes.map(prefix => path.join(prefix, 'manifests/')).reverse()

if (options.server) {
var serverUrl = url.parse(options.server);
if (serverUrl.protocol !== 'http:' && serverUrl.protocol !== 'https:') {
console.error('Server must be an HTTP(S) URL');
usage(1);
}
// eslint-disable-next-line
const serverUrl = url.parse(options.server)
if (!/^https?:/.test(serverUrl.protocol)) {
console.error('Server must be an HTTP(S) URL')
usage(1)
}
}

server.create(options);
server.create(options)
90 changes: 67 additions & 23 deletions lib/appserver.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,69 @@
const http = require('http')
const connect = require('connect')
const bodyparser = require('body-parser')
const localManifests = require('./localManifests')
const path = require('path')
const uiMiddleware = require('@open-xchange/ui-middleware/src/middleware')

const normalizePath = (path) => {
if (path.slice(-1) !== '/') path += '/'
return path
}

function unifyOptions (options) {
options.verbose = (options.verbose || []).reduce((opt, val) => {
if (val === 'all') opt.local = opt.remote = opt.proxy = true
else opt[val] = true
return opt
}, {})
options.prefixes = [...options.prefixes].map(normalizePath)
options.manifests = [...(options.manifests || options.prefixes.map(p => path.join(p, 'manifests')))].map(normalizePath)
options.urlPath = normalizePath(options.path || '/appsuite')

// default to true, but allow custom option
options.rejectUnauthorized = options.rejectUnauthorized === undefined || options.rejectUnauthorized

if (options.server) options.server = normalizePath(options.server)
return options
}

module.exports = {
create: require('./server').create,
tools: {
unifyOptions: require('./server').unifyOptions,
mirrorFile: require('./middleware/pre_fetch').mirrorFile
},
middleware: {
appsload: require('./middleware/appsload').create,
localfiles: require('./middleware/localfiles').create,
manifests: require('./middleware/manifests').create,
mockData: require('./middleware/fixtures').create,
login: require('./middleware/login').create,
preFetch: require('./middleware/pre_fetch').create,
proxy: require('./middleware/proxy').create,
wsProxy: require('./middleware/proxy').createWSProxy,
ui: function create(options) {
const app = require('express')();
process.env.base_path = process.env.base_path || options.prefixes[0];
process.env.base_url_path = process.env.base_url_path || options.urlPath;

app.use(options.urlPath, require('@open-xchange/ui-middleware/src/middleware'));
return app;
}
create (options) {
options = unifyOptions(options)
options.localManifestCache = {}
localManifests(options).then(update => { Object.assign(options.localManifestCache, update) })

process.env.base_path = process.env.base_path || options.prefixes[0]
process.env.base_url_path = process.env.base_url_path || options.urlPath

const handler = connect()
.use(require('./middleware/pre_fetch').create(options))
.use(options.urlPath + 'api/apps/manifests', require('./middleware/manifests')(options))
.use(options.urlPath + 'api/login', require('./middleware/login')(options))
.use(options.urlPath, uiMiddleware)
.use(require('./middleware/proxy')(options))

return http.createServer(handler).listen(options.port || 8338)
},
tools: {
unifyOptions, // Used in shared-grunt-config
mirrorFile: require('./middleware/pre_fetch').mirrorFile // unused?
},
middleware: {
bodyparser,
manifests: require('./middleware/manifests'),
mockData: require('./middleware/fixtures'),
login: require('./middleware/login'),
preFetch: require('./middleware/pre_fetch').create,
proxy: require('./middleware/proxy'),
wsProxy: require('./middleware/proxyWs'),
ui: function create (options) {
const app = require('express')()
process.env.base_path = process.env.base_path || options.prefixes[0]
process.env.base_url_path = process.env.base_url_path || options.urlPath

app.use(options.urlPath, uiMiddleware)
return app
}
};
}
}
55 changes: 0 additions & 55 deletions lib/common.js

This file was deleted.

31 changes: 31 additions & 0 deletions lib/localManifests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const fs = require('fs')
const { readdir, readFile } = require('fs/promises')
const path = require('path')

module.exports = function (options) {
const manifests = options.manifests.filter(dir => {
try {
return fs.statSync(dir).isDirectory()
} catch (err) {
if (options.verbose.local) console.log(`Ignoring ${dir} as manifest directory.`)
return false
}
})

const getLocalManifests = async () => {
const localManifests = (
await Promise.all(
manifests.map(manifestDir => readdir(manifestDir)
.then(file => file
.filter(str => /\.json$/i.test(str))
.map(fileName => path.join(manifestDir, fileName))
)
)
)
).flat()
const localManifestFiles = await Promise.all(localManifests.map(file => readFile(file, 'utf-8')))
const localManifestsMap = localManifestFiles.flatMap(file => JSON.parse(file)).map(manifest => [manifest.path, manifest])
return Object.fromEntries(localManifestsMap)
}
return getLocalManifests()
}
Loading