Update code to ES6

* var  ->  let / const
* [].forEach  ->  for (... of ...)
* '...' + var  ->  template strings  `...${var}`
* function  ->  arrow functions `=>`
* use === and !==  instead of == and !=
This commit is contained in:
Yuri Astrakhan
2019-12-21 14:09:20 -05:00
parent 736e8d393a
commit 7f8be27844
7 changed files with 701 additions and 733 deletions

View File

@@ -4,25 +4,25 @@
process.env.UV_THREADPOOL_SIZE =
Math.ceil(Math.max(4, require('os').cpus().length * 1.5));
var fs = require('fs'),
path = require('path');
const fs = require('fs');
const path = require('path');
var clone = require('clone'),
cors = require('cors'),
enableShutdown = require('http-shutdown'),
express = require('express'),
handlebars = require('handlebars'),
mercator = new (require('@mapbox/sphericalmercator'))(),
morgan = require('morgan');
const clone = require('clone');
const cors = require('cors');
const enableShutdown = require('http-shutdown');
const express = require('express');
const handlebars = require('handlebars');
const mercator = new (require('@mapbox/sphericalmercator'))();
const morgan = require('morgan');
var packageJson = require('../package'),
serve_font = require('./serve_font'),
serve_rendered = null,
serve_style = require('./serve_style'),
serve_data = require('./serve_data'),
utils = require('./utils');
const packageJson = require('../package');
const serve_font = require('./serve_font');
const serve_style = require('./serve_style');
const serve_data = require('./serve_data');
const utils = require('./utils');
var isLight = packageJson.name.slice(-6) == '-light';
let serve_rendered = null;
const isLight = packageJson.name.slice(-6) === '-light';
if (!isLight) {
// do not require `serve_rendered` in the light package
serve_rendered = require('./serve_rendered');
@@ -31,27 +31,27 @@ if (!isLight) {
function start(opts) {
console.log('Starting server');
var app = express().disable('x-powered-by'),
serving = {
styles: {},
rendered: {},
data: {},
fonts: {}
};
const app = express().disable('x-powered-by'),
serving = {
styles: {},
rendered: {},
data: {},
fonts: {}
};
app.enable('trust proxy');
if (process.env.NODE_ENV !== 'test') {
var defaultLogFormat = process.env.NODE_ENV == 'production' ? 'tiny' : 'dev';
var logFormat = opts.logFormat || defaultLogFormat;
const defaultLogFormat = process.env.NODE_ENV === 'production' ? 'tiny' : 'dev';
const logFormat = opts.logFormat || defaultLogFormat;
app.use(morgan(logFormat, {
stream: opts.logFile ? fs.createWriteStream(opts.logFile, { flags: 'a' }) : process.stdout,
skip: function(req, res) { return opts.silent && (res.statusCode == 200 || res.statusCode == 304) }
skip: (req, res) => opts.silent && (res.statusCode === 200 || res.statusCode === 304)
}));
}
var config = opts.config || null;
var configPath = null;
let config = opts.config || null;
let configPath = null;
if (opts.configPath) {
configPath = path.resolve(opts.configPath);
try {
@@ -67,8 +67,8 @@ function start(opts) {
process.exit(1);
}
var options = config.options || {};
var paths = options.paths || {};
const options = config.options || {};
const paths = options.paths || {};
options.paths = paths;
paths.root = path.resolve(
configPath ? path.dirname(configPath) : process.cwd(),
@@ -78,11 +78,11 @@ function start(opts) {
paths.sprites = path.resolve(paths.root, paths.sprites || '');
paths.mbtiles = path.resolve(paths.root, paths.mbtiles || '');
var startupPromises = [];
const startupPromises = [];
var checkPath = function(type) {
const checkPath = type => {
if (!fs.existsSync(paths[type])) {
console.error('The specified path for "' + type + '" does not exist (' + paths[type] + ').');
console.error(`The specified path for "${type}" does not exist (${paths[type]}).`);
process.exit(1);
}
};
@@ -97,50 +97,50 @@ function start(opts) {
} catch (e) {}
}
var data = clone(config.data || {});
const data = clone(config.data || {});
if (opts.cors) {
app.use(cors());
}
Object.keys(config.styles || {}).forEach(function(id) {
var item = config.styles[id];
if (!item.style || item.style.length == 0) {
console.log('Missing "style" property for ' + id);
return;
for (const id of Object.keys(config.styles || {})) {
const item = config.styles[id];
if (!item.style || item.style.length === 0) {
console.log(`Missing "style" property for ${id}`);
continue;
}
if (item.serve_data !== false) {
startupPromises.push(serve_style(options, serving.styles, item, id, opts.publicUrl,
function(mbtiles, fromData) {
var dataItemId;
Object.keys(data).forEach(function(id) {
(mbtiles, fromData) => {
let dataItemId;
for (const id of Object.keys(data)) {
if (fromData) {
if (id == mbtiles) {
if (id === mbtiles) {
dataItemId = id;
}
} else {
if (data[id].mbtiles == mbtiles) {
if (data[id].mbtiles === mbtiles) {
dataItemId = id;
}
}
});
}
if (dataItemId) { // mbtiles exist in the data config
return dataItemId;
} else if (fromData) {
console.log('ERROR: data "' + mbtiles + '" not found!');
console.log(`ERROR: data "${mbtiles}" not found!`);
process.exit(1);
} else {
var id = mbtiles.substr(0, mbtiles.lastIndexOf('.')) || mbtiles;
let id = mbtiles.substr(0, mbtiles.lastIndexOf('.')) || mbtiles;
while (data[id]) id += '_';
data[id] = {
'mbtiles': mbtiles
};
return id;
}
}, function(font) {
}, font => {
serving.fonts[font] = true;
}).then(function(sub) {
}).then(sub => {
app.use('/styles/', sub);
}));
}
@@ -148,16 +148,16 @@ function start(opts) {
if (serve_rendered) {
startupPromises.push(
serve_rendered(options, serving.rendered, item, id, opts.publicUrl,
function(mbtiles) {
var mbtilesFile;
Object.keys(data).forEach(function(id) {
if (id == mbtiles) {
mbtiles => {
let mbtilesFile;
for (const id of Object.keys(data)) {
if (id === mbtiles) {
mbtilesFile = data[id].mbtiles;
}
});
}
return mbtilesFile;
}
).then(function(sub) {
).then(sub => {
app.use('/styles/', sub);
})
);
@@ -165,68 +165,67 @@ function start(opts) {
item.serve_rendered = false;
}
}
});
}
startupPromises.push(
serve_font(options, serving.fonts).then(function(sub) {
serve_font(options, serving.fonts).then(sub => {
app.use('/', sub);
})
);
Object.keys(data).forEach(function(id) {
var item = data[id];
if (!item.mbtiles || item.mbtiles.length == 0) {
console.log('Missing "mbtiles" property for ' + id);
return;
for (const id of Object.keys(data)) {
const item = data[id];
if (!item.mbtiles || item.mbtiles.length === 0) {
console.log(`Missing "mbtiles" property for ${id}`);
continue;
}
startupPromises.push(
serve_data(options, serving.data, item, id, serving.styles, opts.publicUrl).then(function(sub) {
serve_data(options, serving.data, item, id, serving.styles, opts.publicUrl).then(sub => {
app.use('/data/', sub);
})
);
});
}
app.get('/styles.json', function(req, res, next) {
var result = [];
var query = req.query.key ? ('?key=' + req.query.key) : '';
Object.keys(serving.styles).forEach(function(id) {
var styleJSON = serving.styles[id];
app.get('/styles.json', (req, res, next) => {
const result = [];
const query = req.query.key ? (`?key=${req.query.key}`) : '';
for (const id of Object.keys(serving.styles)) {
const styleJSON = serving.styles[id];
result.push({
version: styleJSON.version,
name: styleJSON.name,
id: id,
url: utils.getPublicUrl(opts.publicUrl, req) +
'styles/' + id + '/style.json' + query
url: `${utils.getPublicUrl(opts.publicUrl, req)}styles/${id}/style.json${query}`
});
});
}
res.send(result);
});
var addTileJSONs = function(arr, req, type) {
Object.keys(serving[type]).forEach(function(id) {
var info = clone(serving[type][id]);
var path = '';
if (type == 'rendered') {
path = 'styles/' + id;
const addTileJSONs = (arr, req, type) => {
for (const id of Object.keys(serving[type])) {
const info = clone(serving[type][id]);
let path = '';
if (type === 'rendered') {
path = `styles/${id}`;
} else {
path = type + '/' + id;
path = `${type}/${id}`;
}
info.tiles = utils.getTileUrls(req, info.tiles, path, info.format, opts.publicUrl, {
'pbf': options.pbfAlias
});
arr.push(info);
});
}
return arr;
};
app.get('/rendered.json', function(req, res, next) {
app.get('/rendered.json', (req, res, next) => {
res.send(addTileJSONs([], req, 'rendered'));
});
app.get('/data.json', function(req, res, next) {
app.get('/data.json', (req, res, next) => {
res.send(addTileJSONs([], req, 'data'));
});
app.get('/index.json', function(req, res, next) {
app.get('/index.json', (req, res, next) => {
res.send(addTileJSONs(addTileJSONs([], req, 'rendered'), req, 'data'));
});
@@ -234,40 +233,40 @@ function start(opts) {
// serve web presentations
app.use('/', express.static(path.join(__dirname, '../public/resources')));
var templates = path.join(__dirname, '../public/templates');
var serveTemplate = function(urlPath, template, dataGetter) {
var templateFile = templates + '/' + template + '.tmpl';
if (template == 'index') {
const templates = path.join(__dirname, '../public/templates');
const serveTemplate = (urlPath, template, dataGetter) => {
let templateFile = `${templates}/${template}.tmpl`;
if (template === 'index') {
if (options.frontPage === false) {
return;
} else if (options.frontPage &&
options.frontPage.constructor === String) {
options.frontPage.constructor === String) {
templateFile = path.resolve(paths.root, options.frontPage);
}
}
startupPromises.push(new Promise(function(resolve, reject) {
fs.readFile(templateFile, function(err, content) {
startupPromises.push(new Promise((resolve, reject) => {
fs.readFile(templateFile, (err, content) => {
if (err) {
err = new Error('Template not found: ' + err.message);
err = new Error(`Template not found: ${err.message}`);
reject(err);
return;
}
var compiled = handlebars.compile(content.toString());
const compiled = handlebars.compile(content.toString());
app.use(urlPath, function(req, res, next) {
var data = {};
app.use(urlPath, (req, res, next) => {
let data = {};
if (dataGetter) {
data = dataGetter(req);
if (!data) {
return res.status(404).send('Not found');
}
}
data['server_version'] = packageJson.name + ' v' + packageJson.version;
data['server_version'] = `${packageJson.name} v${packageJson.version}`;
data['public_url'] = opts.publicUrl || '/';
data['is_light'] = isLight;
data['key_query_part'] =
req.query.key ? 'key=' + req.query.key + '&' : '';
data['key_query'] = req.query.key ? '?key=' + req.query.key : '';
req.query.key ? `key=${req.query.key}&` : '';
data['key_query'] = req.query.key ? `?key=${req.query.key}` : '';
if (template === 'wmts') res.set('Content-Type', 'text/xml');
return res.status(200).send(compiled(data));
});
@@ -276,59 +275,49 @@ function start(opts) {
}));
};
serveTemplate('/$', 'index', function(req) {
var styles = clone(config.styles || {});
Object.keys(styles).forEach(function(id) {
var style = styles[id];
serveTemplate('/$', 'index', req => {
const styles = clone(config.styles || {});
for (const id of Object.keys(styles)) {
const style = styles[id];
style.name = (serving.styles[id] || serving.rendered[id] || {}).name;
style.serving_data = serving.styles[id];
style.serving_rendered = serving.rendered[id];
if (style.serving_rendered) {
var center = style.serving_rendered.center;
const center = style.serving_rendered.center;
if (center) {
style.viewer_hash = '#' + center[2] + '/' +
center[1].toFixed(5) + '/' +
center[0].toFixed(5);
style.viewer_hash = `#${center[2]}/${center[1].toFixed(5)}/${center[0].toFixed(5)}`;
var centerPx = mercator.px([center[0], center[1]], center[2]);
style.thumbnail = center[2] + '/' +
Math.floor(centerPx[0] / 256) + '/' +
Math.floor(centerPx[1] / 256) + '.png';
const centerPx = mercator.px([center[0], center[1]], center[2]);
style.thumbnail = `${center[2]}/${Math.floor(centerPx[0] / 256)}/${Math.floor(centerPx[1] / 256)}.png`;
}
var tiles = utils.getTileUrls(
req, style.serving_rendered.tiles,
'styles/' + id, style.serving_rendered.format, opts.publicUrl);
style.xyz_link = tiles[0];
style.xyz_link = utils.getTileUrls(
req, style.serving_rendered.tiles,
`styles/${id}`, style.serving_rendered.format, opts.publicUrl)[0];
}
});
var data = clone(serving.data || {});
Object.keys(data).forEach(function(id) {
var data_ = data[id];
var center = data_.center;
}
const data = clone(serving.data || {});
for (const id of Object.keys(data)) {
const data_ = data[id];
const center = data_.center;
if (center) {
data_.viewer_hash = '#' + center[2] + '/' +
center[1].toFixed(5) + '/' +
center[0].toFixed(5);
data_.viewer_hash = `#${center[2]}/${center[1].toFixed(5)}/${center[0].toFixed(5)}`;
}
data_.is_vector = data_.format == 'pbf';
data_.is_vector = data_.format === 'pbf';
if (!data_.is_vector) {
if (center) {
var centerPx = mercator.px([center[0], center[1]], center[2]);
data_.thumbnail = center[2] + '/' +
Math.floor(centerPx[0] / 256) + '/' +
Math.floor(centerPx[1] / 256) + '.' + data_.format;
const centerPx = mercator.px([center[0], center[1]], center[2]);
data_.thumbnail = `${center[2]}/${Math.floor(centerPx[0] / 256)}/${Math.floor(centerPx[1] / 256)}.${data_.format}`;
}
var tiles = utils.getTileUrls(
req, data_.tiles, 'data/' + id, data_.format, opts.publicUrl, {
'pbf': options.pbfAlias
});
data_.xyz_link = tiles[0];
data_.xyz_link = utils.getTileUrls(
req, data_.tiles, `data/${id}`, data_.format, opts.publicUrl, {
'pbf': options.pbfAlias
})[0];
}
if (data_.filesize) {
var suffix = 'kB';
var size = parseInt(data_.filesize, 10) / 1024;
let suffix = 'kB';
let size = parseInt(data_.filesize, 10) / 1024;
if (size > 1024) {
suffix = 'MB';
size /= 1024;
@@ -337,18 +326,18 @@ function start(opts) {
suffix = 'GB';
size /= 1024;
}
data_.formatted_filesize = size.toFixed(2) + ' ' + suffix;
data_.formatted_filesize = `${size.toFixed(2)} ${suffix}`;
}
});
}
return {
styles: Object.keys(styles).length ? styles : null,
data: Object.keys(data).length ? data : null
};
});
serveTemplate('/styles/:id/$', 'viewer', function(req) {
var id = req.params.id;
var style = clone((config.styles || {})[id]);
serveTemplate('/styles/:id/$', 'viewer', req => {
const id = req.params.id;
const style = clone((config.styles || {})[id]);
if (!style) {
return null;
}
@@ -364,9 +353,9 @@ function start(opts) {
return res.redirect(301, '/styles/' + req.params.id + '/');
});
*/
serveTemplate('/styles/:id/wmts.xml', 'wmts', function(req) {
var id = req.params.id;
var wmts = clone((config.styles || {})[id]);
serveTemplate('/styles/:id/wmts.xml', 'wmts', req => {
const id = req.params.id;
const wmts = clone((config.styles || {})[id]);
if (!wmts) {
return null;
}
@@ -375,27 +364,27 @@ function start(opts) {
}
wmts.id = id;
wmts.name = (serving.styles[id] || serving.rendered[id]).name;
wmts.baseUrl = (req.get('X-Forwarded-Protocol')?req.get('X-Forwarded-Protocol'):req.protocol) + '://' + req.get('host');
wmts.baseUrl = `${req.get('X-Forwarded-Protocol') ? req.get('X-Forwarded-Protocol') : req.protocol}://${req.get('host')}`;
return wmts;
});
serveTemplate('/data/:id/$', 'data', function(req) {
var id = req.params.id;
var data = clone(serving.data[id]);
serveTemplate('/data/:id/$', 'data', req => {
const id = req.params.id;
const data = clone(serving.data[id]);
if (!data) {
return null;
}
data.id = id;
data.is_vector = data.format == 'pbf';
data.is_vector = data.format === 'pbf';
return data;
});
var startupComplete = false;
var startupPromise = Promise.all(startupPromises).then(function() {
let startupComplete = false;
const startupPromise = Promise.all(startupPromises).then(() => {
console.log('Startup complete');
startupComplete = true;
});
app.get('/health', function(req, res, next) {
app.get('/health', (req, res, next) => {
if (startupComplete) {
return res.status(200).send('OK');
} else {
@@ -403,12 +392,12 @@ function start(opts) {
}
});
var server = app.listen(process.env.PORT || opts.port, process.env.BIND || opts.bind, function() {
var address = this.address().address;
const server = app.listen(process.env.PORT || opts.port, process.env.BIND || opts.bind, function () {
let address = this.address().address;
if (address.indexOf('::') === 0) {
address = '[' + address + ']'; // literal IPv6 address
address = `[${address}]`; // literal IPv6 address
}
console.log('Listening at http://%s:%d/', address, this.address().port);
console.log(`Listening at http://${address}:${this.address().port}/`);
});
// add server.shutdown() to gracefully stop serving
@@ -421,27 +410,27 @@ function start(opts) {
};
}
module.exports = function(opts) {
var running = start(opts);
module.exports = opts => {
const running = start(opts);
running.startupPromise.catch(function(err) {
running.startupPromise.catch(err => {
console.error(err.message);
process.exit(1);
});
process.on('SIGINT', function() {
process.on('SIGINT', () => {
process.exit();
});
process.on('SIGHUP', function() {
process.on('SIGHUP', () => {
console.log('Stopping server and reloading config');
running.server.shutdown(function() {
for (var key in require.cache) {
running.server.shutdown(() => {
for (const key in require.cache) {
delete require.cache[key];
}
var restarted = start(opts);
const restarted = start(opts);
running.server = restarted.server;
running.app = restarted.app;
});