UNPKG

atriusmaps-node-sdk

Version:

This project provides an API to Atrius Personal Wayfinder maps within a Node environment. See the README.md for more information

167 lines (134 loc) 6.77 kB
'use strict'; var R = require('ramda'); var Zousan = require('zousan-plus'); var _package = require('../package.json.js'); var debugTools = require('./debugTools.js'); var env = require('./env.js'); var bustle = require('./extModules/bustle.js'); var log = require('./extModules/log.js'); var i18n = require('./utils/i18n.js'); function _interopNamespaceDefaultOnly (e) { return Object.freeze({ __proto__: null, default: e }); } const isBrowser = typeof window !== 'undefined'; const TRACE = false; async function setupPlugin (app, id, config) { let name = id; if (name.includes('/')) { const split = name.split('/'); name = split[split.length - 1]; } if (config.active !== undefined) { if ((config.active === false) || (config.active === 'notLocalhost' && app.env.isLocalhost())) { app.log.info(`Plugin ${id} explicitly deativated`); return null } } return import(`../plugins/${id}/src/${name}.js`) .then(pluginModule => { app.log.info(`Creating plugin ${id}`); return pluginModule.create(app, config) }) } // takes the `lang` query parameter and returns the most specific supported language // Recognizes the following optional configuration parameters: // supportedLanguages : array of supported language strings. i.e. [ "en", "en-US", "fr", "ja" ] // defaultLanguage : if all fails, use this language. default = "en" const getLang = config => { const supportedLanguages = config.supportedLanguages || ['ar', 'de', 'en', 'es', 'fr', 'hi', 'is', 'it', 'ja', 'ko', 'pl', 'pt', 'zh-Hans', 'zh-Hant']; if (typeof window !== 'undefined') { // if this is a browser... const queryParms = new URLSearchParams(location.search); // eslint-disable-next-line no-constant-condition let lang = queryParms.get('lang') || (typeof navigator ? navigator.language : null); while (lang) if (lang && supportedLanguages.includes(lang)) return lang else lang = lang.substring(0, lang.lastIndexOf('-')); } return config.defaultLanguage || 'en' }; async function loadConfig (name) { return isBrowser ? import(`./configs/${name}.json`) : import(`./configs/${name}.json.js`) // bit of a hack - but supports all versions of node. See https://gitlab.com/locuslabspublic/node-sdk/-/merge_requests/1 } async function extendConfig (config, extendsConfigs) { let newConfig = {}; const extConfigFiles = await Promise.all(extendsConfigs.map(loadConfig)); for (const extendsConfigMod of extConfigFiles) { let extendsConfig = extendsConfigMod.default; extendsConfig = extendsConfig.extends ? await extendConfig(extendsConfig, extendsConfig.extends) : extendsConfig; // enable recursive extends newConfig = R.mergeDeepRight(newConfig, extendsConfig); // default is JSON data in ES6 modules import } newConfig = R.mergeDeepRight(newConfig, config); return newConfig } // const isSimpleName = name => /^[-a-zA-Z0-9]+$/.test(name) // composed of only alphanumeric and dash const createPostProcessor = name => config => import(`./configs/postproc-${name}.js`) .then(pp => pp.process(config)); const handleConfigPostProcess = async config => config.configPostProc ? Zousan.series(config, ...config.configPostProc.map(createPostProcessor)) : config; async function create (rawConfig) { const appInstance = Object.create(null); let config = rawConfig.extends ? await extendConfig(rawConfig, rawConfig.extends) : rawConfig; // this handles error reporting, so we want it activated ASAP if (config.plugins.monitoring) await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('../_virtual/_empty_module_placeholder.js')); }).then(mon => mon.activate(config.plugins.monitoring)); config = await handleConfigPostProcess(config); const lang = getLang(config); const i18n$1 = await i18n.default(lang, { debug: config.debug }); appInstance.i18n = () => i18n$1; appInstance.gt = () => i18n$1.t.bind(i18n$1); // get translation function - don't hold this, it is bound to current lang appInstance.config = config; appInstance.plugins = {}; const appLog = log.initLog('web-engine', { enabled: !!config.debug, isBrowser, color: 'cyan', logFilter: config.logFilter, truncateObjects: !isBrowser, trace: TRACE }); appInstance.log = appLog.sublog(config.name); appInstance.bus = bustle.create({ showEvents: true, reportAllErrors: true, log: appLog }); appInstance.info = { wePkg: _package.default }; // web-engine package if (typeof window !== 'undefined') { // Prepare for non-browser environments if (config.debug) { appInstance.debug = R.map(fn => fn.bind(appInstance), debugTools); debugTools.dndGo.call(appInstance); // setup DnD by default... } else appInstance.debug = { }; // no tools unless in debug mode.. (good idea?) window._app = appInstance; if (window.document && window.document.title && config.setWindowTitle) document.title = config.name; } appInstance.env = env.buildEnv(appInstance); if (config.theme) { // the following is only needed when UI is active - which requires a theme await Zousan.evaluate( { name: 'ThemeManagerModule', value: Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('../_virtual/_empty_module_placeholder.js')); }) }, { name: 'HistoryManager', value: Promise.resolve().then(function () { return require('./historyManager.js'); }) }, { name: 'LayerManager', value: Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('../_virtual/_empty_module_placeholder.js')); }) } ).then(async ({ LayerManager, HistoryManager, ThemeManagerModule }) => { const ThemeManager = ThemeManagerModule.initThemeManager(appInstance); appInstance.themePack = await ThemeManager.buildTheme(config.theme, config.defaultTheme); LayerManager.initLayerManager(appInstance); HistoryManager.initHistoryManager(appInstance); appInstance.destroy = () => LayerManager.destroy(appInstance); }); } else appInstance.destroy = () => { }; // noop if (config.plugins) { for (const id in config.plugins) { try { const pluginConfig = config.plugins[id]; if (appInstance.plugins[id]) { throw Error(`Duplicate plugin name "${id}"`) } const plugin = await setupPlugin(appInstance, id, pluginConfig); if (plugin) appInstance.plugins[id] = plugin; } catch (e) { appLog.error('Error instantiating plugin ' + id); appLog.error(e); } } for (const id in appInstance.plugins) { appInstance.plugins[id].init(); } } return appInstance } exports.create = create;