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

174 lines (168 loc) 6.83 kB
'use strict'; var R = require('ramda'); var bounds = require('../../../src/utils/bounds.js'); function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R); const fetchURL = async (token, url) => { { return fetch(url); } }; const createFetchJson = (token) => (url) => fetchURL(token, url).then((response) => response.json()); const createFetchText = (token) => (url) => fetchURL(token, url).then((response) => response.text()); const baseContentUrl = (contentStage) => `https://api.content.locuslabs.com/${contentStage}`; const remapContentUrl = (url, category, contentStage, accountId, venueId, key) => { if (key === "theme" || key === "style") { return `${baseContentUrl(contentStage)}/${category}/${key}/${venueId}/${accountId}/${key}.json`; } return url.replace(/https:\/\/content.locuslabs.com/gi, baseContentUrl(contentStage)); }; const remapEachURLForContentStage = (category, files, contentStage, accountId, venueId) => R__namespace.mapObjIndexed((file, key) => remapContentUrl(file, category, contentStage, accountId, venueId, key), files); const getContentStage = (vconfig) => { const stage = vconfig.deepLinkProps ? vconfig.deepLinkProps.contentStage : null; return stage === "alpha" || stage === "beta" || stage === "prod" ? stage : null; }; const LOCALE_ALIAS_GROUPS = [ ["zh-CN", "zh-SG", "zh-Hans"], ["zh-TW", "zh-HK", "zh-MO", "zh-Hant"] ]; const getLocaleAliases = (locale) => { const group = LOCALE_ALIAS_GROUPS.find((g) => g.includes(locale)); return group ? group.filter((l) => l !== locale) : []; }; const getLocaleMatchTiers = (browserLang) => { const aliases = getLocaleAliases(browserLang); const prefix = browserLang.slice(0, 2); return [ (locale) => locale === browserLang, (locale) => aliases.includes(locale), (locale) => locale.slice(0, 2) === prefix ]; }; const findVenueForLocale = (venues, browserLang, currentVenue = null) => { for (const matches of getLocaleMatchTiers(browserLang)) { if (currentVenue && matches(currentVenue.locale)) { return currentVenue; } const venue = venues.find((v) => matches(v.locale)); if (venue) { return venue; } } return null; }; const getVenueDataFromUrls = async (vconfig, fetchJson, languagesToTry) => { const stages = { alpha: "alpha-a.locuslabs.com", beta: "beta-a.locuslabs.com", gamma: "gamma-a.locuslabs.com", prod: "a.locuslabs.com" }; const { assetStage, accountId, formatVersion } = vconfig; let { venueId } = vconfig; const stageUrl = stages[assetStage] || stages.prod; const accountUrl = `https://${stageUrl}/accounts/${accountId}`; const assetFormat = formatVersion || "v5"; const venueList = vconfig.dataFetch && globalThis[vconfig.dataFetch] && globalThis[vconfig.dataFetch].getFiles ? await globalThis[vconfig.dataFetch].getFiles(vconfig) : await fetchJson(`${accountUrl}/${assetFormat}.json`); const venueCode = venueList[venueId] ? venueList[venueId].venueCode : null; if (venueCode) { const venuesWithSameVenueCode = Object.values(venueList).filter((v) => v.venueCode === venueCode); const currentVenue = venueList[venueId]; for (const browserLang of languagesToTry) { const venue = findVenueForLocale(venuesWithSameVenueCode, browserLang, currentVenue); if (venue) { venueId = venue.id; vconfig.venueId = `${venueId}`; break; } } } if (!venueList[venueId]) { throw Error(`Attempt to access venue ${venueId} which is not within venue list: ${Object.keys(venueList)}`); } const files = venueList[venueId].files; const fetchedData = vconfig.dataFetch && globalThis[vconfig.dataFetch] && globalThis[vconfig.dataFetch].getVenueData ? await globalThis[vconfig.dataFetch].getVenueData(vconfig) : await fetchJson(files.venueData); const venueData = fetchedData[venueId]; if (venueData.tileServerAuthInfo) { embellishTilemapVenueData(venueData); } venueData.venueList = venueList; const contentStage = getContentStage(vconfig); venueData.files = contentStage ? remapEachURLForContentStage(venueData.category, files, contentStage, accountId, venueId) : files; return venueData; }; const buildStructures = (venueData) => { const { structureOrder, structures } = venueData; return structureOrder.map((structureId) => { const structure = structures[structureId]; Object.values(structure.levels).forEach((level) => level.bounds = bounds.findBoundsOfCoordinates(level.boundsPolygon)); const bounds$1 = bounds.findBoundsOfCoordinates(structure.boundsPolygon); return { ...structure, bounds: bounds$1 }; }); }; function embellishTilemapVenueData(venueData) { const additionalFields = { defaultOrdinal: 0, // this and below override the venue data defaultStructureId: "singleBuilding", formatVersion: "v5", // Note: this structures object does not represent the "buildingsAndLevels" as // managed within this app. This is a mock structure for the purposes of rendering // a tiled map. It is always a single building, single floor. If user switches // buildings or floors, it unmounts this map and remounts a new map with that building/floor structures: { singleBuilding: { name: "singleBuilding", boundsPolygon: [], defaultLevelId: "singleLevel", id: "singleBuilding", levels: { singleLevel: { boundsPolygon: [], clfloor: 0, details: "", id: "singleLevel", name: "singleLevel", ordinal: 0 } } } }, structureOrder: ["singleBuilding"] }; for (const key in additionalFields) { venueData[key] = additionalFields[key]; } } const between = (val, lim1, lim2) => val > lim1 ? val <= lim2 : (val2) => lim2; const swapFirstTwoItems = ([c1, c2, ...c3]) => [c2, c1, ...c3]; const normalizeCoords = (coords, venueBounds) => { if (!coords || !Array.isArray(coords) || coords.length < 1) { return coords; } if (between(coords[0][0], venueBounds.ne.lng, venueBounds.sw.lng)) { return coords; } return coords.map(swapFirstTwoItems); }; exports.buildStructures = buildStructures; exports.createFetchJson = createFetchJson; exports.createFetchText = createFetchText; exports.findVenueForLocale = findVenueForLocale; exports.getVenueDataFromUrls = getVenueDataFromUrls; exports.normalizeCoords = normalizeCoords;