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
JavaScript
;
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;