atriusmaps-node-sdk 3.3.1161 → 3.3.1165

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var version = "3.3.1161";
5
+ var version = "3.3.1165";
6
6
  var pkg = {
7
7
  version: version};
8
8
 
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ const LOAD_FAILURE_REASON = {
4
+ MISCONFIGURED: "misconfigured",
5
+ SESSION_EXPIRED: "sessionExpired",
6
+ ACCESS_DENIED: "accessDenied",
7
+ UNAVAILABLE: "unavailable",
8
+ LINK_EXPIRED: "linkExpired",
9
+ SERVICE_ERROR: "serviceError"
10
+ };
11
+
12
+ exports.LOAD_FAILURE_REASON = LOAD_FAILURE_REASON;
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ var constants = require('./constants.js');
4
+
5
+ const isAuthState = (value) => typeof value === "object" && value !== null && typeof value.status === "string";
6
+ const AUTH_ERROR_TO_REASON = {
7
+ misconfigured: constants.LOAD_FAILURE_REASON.MISCONFIGURED,
8
+ unavailable: constants.LOAD_FAILURE_REASON.UNAVAILABLE,
9
+ callbackFailed: constants.LOAD_FAILURE_REASON.SERVICE_ERROR,
10
+ signOutFailed: constants.LOAD_FAILURE_REASON.SERVICE_ERROR
11
+ };
12
+ const authErrorToReason = (reason) => AUTH_ERROR_TO_REASON[reason] ?? constants.LOAD_FAILURE_REASON.SERVICE_ERROR;
13
+ const awaitAuthentication = (bus, onUnauthenticated) => new Promise((resolve) => {
14
+ let settled = false;
15
+ let signInRequested = false;
16
+ const settle = (result) => {
17
+ if (!settled) {
18
+ settled = true;
19
+ unsubscribe();
20
+ resolve(result);
21
+ }
22
+ };
23
+ const handleState = (state) => {
24
+ if (state.status === "authenticated") {
25
+ settle({ ok: true });
26
+ } else if (state.status === "error") {
27
+ settle({ ok: false, reason: authErrorToReason(state.reason) });
28
+ } else if (state.status === "unauthenticated" && !settled && !signInRequested) {
29
+ signInRequested = true;
30
+ try {
31
+ onUnauthenticated?.();
32
+ } catch {
33
+ settle({ ok: false, reason: constants.LOAD_FAILURE_REASON.SERVICE_ERROR });
34
+ }
35
+ }
36
+ };
37
+ const unsubscribe = bus.on("auth/stateChanged", (payload) => {
38
+ if (isAuthState(payload)) {
39
+ handleState(payload);
40
+ }
41
+ });
42
+ bus.getFirst("auth/getState").then((current) => {
43
+ if (current === void 0) {
44
+ settle({ ok: false, reason: constants.LOAD_FAILURE_REASON.MISCONFIGURED });
45
+ } else if (isAuthState(current)) {
46
+ handleState(current);
47
+ } else {
48
+ settle({ ok: false, reason: constants.LOAD_FAILURE_REASON.SERVICE_ERROR });
49
+ }
50
+ }).catch(() => settle({ ok: false, reason: constants.LOAD_FAILURE_REASON.SERVICE_ERROR }));
51
+ });
52
+
53
+ exports.awaitAuthentication = awaitAuthentication;
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+
3
+ var constants = require('./constants.js');
4
+ var interactiveAuthGate = require('./interactiveAuthGate.js');
5
+
6
+ class VenueLoadFailedError extends Error {
7
+ reason;
8
+ constructor(reason, options) {
9
+ super(`Venue load failed: ${reason}`, options);
10
+ this.name = "VenueLoadFailedError";
11
+ this.reason = reason;
12
+ }
13
+ }
14
+ const MANIFEST_BASE_URL = "https://assets-api.locuslabs.com/prod";
15
+ const buildInteractiveManifestEndpoint = ({ accountId, venueId, assetStage }) => {
16
+ const base = MANIFEST_BASE_URL;
17
+ const path = `${base}/asset-manifest/accounts/${encodeURIComponent(accountId)}/venue/${encodeURIComponent(venueId)}`;
18
+ return assetStage ? `${path}?assetStage=${encodeURIComponent(assetStage)}&mode=interactive` : path;
19
+ };
20
+ const hop1StatusToReason = (status) => {
21
+ switch (status) {
22
+ case 401:
23
+ return constants.LOAD_FAILURE_REASON.SESSION_EXPIRED;
24
+ case 403:
25
+ return constants.LOAD_FAILURE_REASON.ACCESS_DENIED;
26
+ default:
27
+ return constants.LOAD_FAILURE_REASON.SERVICE_ERROR;
28
+ }
29
+ };
30
+ const hop2StatusToReason = (status) => {
31
+ switch (status) {
32
+ case 403:
33
+ return constants.LOAD_FAILURE_REASON.LINK_EXPIRED;
34
+ default:
35
+ return constants.LOAD_FAILURE_REASON.SERVICE_ERROR;
36
+ }
37
+ };
38
+ const loadInteractiveManifest = async ({
39
+ bus,
40
+ fetch,
41
+ manifestEndpoint
42
+ }) => {
43
+ const failClosed = async (reason) => {
44
+ await bus.send("venueData/loadFailed", { reason });
45
+ throw new VenueLoadFailedError(reason);
46
+ };
47
+ const gate = await interactiveAuthGate.awaitAuthentication(bus, () => bus.send("auth/signIn"));
48
+ if (!gate.ok) {
49
+ return failClosed(gate.reason);
50
+ }
51
+ const attempt = async (op) => {
52
+ try {
53
+ return await op();
54
+ } catch {
55
+ return failClosed(constants.LOAD_FAILURE_REASON.SERVICE_ERROR);
56
+ }
57
+ };
58
+ const token = await attempt(() => bus.getFirst("auth/getAccessToken", { forceRefresh: true }));
59
+ if (typeof token !== "string" || token === "") {
60
+ return failClosed(constants.LOAD_FAILURE_REASON.SESSION_EXPIRED);
61
+ }
62
+ const hop1 = await attempt(() => fetch(manifestEndpoint, { headers: { "x-api-key": token }, redirect: "error" }));
63
+ if (hop1.status !== 200) {
64
+ return failClosed(hop1StatusToReason(hop1.status));
65
+ }
66
+ const body = await attempt(() => hop1.json());
67
+ const signedManifestUrl = body?.data?.url;
68
+ if (typeof signedManifestUrl !== "string" || signedManifestUrl === "") {
69
+ return failClosed(constants.LOAD_FAILURE_REASON.SERVICE_ERROR);
70
+ }
71
+ const hop2 = await attempt(() => fetch(signedManifestUrl));
72
+ if (hop2.status !== 200) {
73
+ return failClosed(hop2StatusToReason(hop2.status));
74
+ }
75
+ return attempt(() => hop2.json());
76
+ };
77
+
78
+ exports.MANIFEST_BASE_URL = MANIFEST_BASE_URL;
79
+ exports.VenueLoadFailedError = VenueLoadFailedError;
80
+ exports.buildInteractiveManifestEndpoint = buildInteractiveManifestEndpoint;
81
+ exports.loadInteractiveManifest = loadInteractiveManifest;
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
4
+ const resolveAuth = (auth) => {
5
+ if (auth === void 0) {
6
+ return { mode: "public" };
7
+ }
8
+ if (!isRecord(auth)) {
9
+ return { mode: "invalid" };
10
+ }
11
+ const keyCount = Object.keys(auth).length;
12
+ if (auth.type === "kiosk") {
13
+ const { signedManifestUrl } = auth;
14
+ return keyCount === 2 && typeof signedManifestUrl === "string" && signedManifestUrl.trim() !== "" ? { mode: "kiosk", signedManifestUrl } : { mode: "invalid" };
15
+ }
16
+ if (auth.type === "interactive") {
17
+ return keyCount === 1 ? { mode: "interactive" } : { mode: "invalid" };
18
+ }
19
+ return { mode: "invalid" };
20
+ };
21
+
22
+ exports.resolveAuth = resolveAuth;
@@ -2,7 +2,10 @@
2
2
 
3
3
  var R = require('ramda');
4
4
  var Zousan = require('zousan');
5
+ var constants = require('./constants.js');
5
6
  var fixedOffsetZones = require('./fixedOffsetZones.js');
7
+ var loadInteractiveVenue = require('./loadInteractiveVenue.js');
8
+ var resolveAuth = require('./resolveAuth.js');
6
9
  var venueLoadingUtils = require('./venueLoadingUtils.js');
7
10
 
8
11
  function _interopNamespaceDefault(e) {
@@ -36,12 +39,53 @@ async function create(app, config) {
36
39
  const getVenueDefForLang = (venueData, lang) => Object.values(venueData.venueList).filter((venueDef) => venueDef.locale === lang).sort((a, b) => countMatchedPrefix(b.id, venueData.id) - countMatchedPrefix(a.id, venueData.id)).at(0);
37
40
  const calculateBaseVenueId = (venueData) => getVenueDefForLang(venueData, "en")?.id;
38
41
  async function loadVenueData(vConfig, languagesToTry) {
42
+ const thisVenueDataLoaded = venueDataLoaded;
43
+ const thisMapDataLoaded = mapDataLoaded;
44
+ const auth = resolveAuth.resolveAuth(vConfig.auth);
45
+ try {
46
+ const venueData = await fetchVenueData(vConfig, languagesToTry, auth);
47
+ thisVenueDataLoaded.resolve(venueData);
48
+ return thisVenueDataLoaded;
49
+ } catch (err) {
50
+ if (!(err instanceof loadInteractiveVenue.VenueLoadFailedError)) {
51
+ app.bus.send("venueData/loadFailed", { reason: constants.LOAD_FAILURE_REASON.SERVICE_ERROR });
52
+ }
53
+ thisVenueDataLoaded.reject(err);
54
+ thisMapDataLoaded.reject(err);
55
+ throw err;
56
+ }
57
+ }
58
+ function createKioskManifestFetcher(authConfig) {
59
+ let forbidden = false;
60
+ const fetchManifest = venueLoadingUtils.createFetchManifestJson(authConfig, async (status) => {
61
+ forbidden = true;
62
+ await app.bus.send("venueData/authError", { reason: "signedManifestForbidden", status });
63
+ await app.bus.send("venueData/loadFailed", { reason: "linkExpired" });
64
+ });
65
+ return async (url) => {
66
+ try {
67
+ return await fetchManifest(url);
68
+ } catch (err) {
69
+ throw forbidden ? new loadInteractiveVenue.VenueLoadFailedError("linkExpired", { cause: err }) : err;
70
+ }
71
+ };
72
+ }
73
+ async function fetchVenueData(vConfig, languagesToTry, auth) {
74
+ if (auth.mode === "invalid") {
75
+ app.bus.send("venueData/loadFailed", { reason: "misconfigured" });
76
+ throw new loadInteractiveVenue.VenueLoadFailedError("misconfigured");
77
+ }
39
78
  const fetchJson = venueLoadingUtils.createFetchJson();
40
79
  const fetchText = venueLoadingUtils.createFetchText();
41
- const fetchManifestJson = venueLoadingUtils.createFetchManifestJson(
42
- vConfig.auth,
43
- (status) => app.bus.send("venueData/authError", { reason: "signedManifestForbidden", status })
44
- );
80
+ const fetchManifestJson = auth.mode === "interactive" ? () => loadInteractiveVenue.loadInteractiveManifest({
81
+ bus: app.bus,
82
+ fetch: globalThis.fetch,
83
+ manifestEndpoint: loadInteractiveVenue.buildInteractiveManifestEndpoint({
84
+ accountId: vConfig.accountId,
85
+ venueId: vConfig.venueId,
86
+ assetStage: vConfig.assetStage
87
+ })
88
+ }) : auth.mode === "kiosk" ? createKioskManifestFetcher(vConfig.auth) : venueLoadingUtils.createFetchManifestJson(vConfig.auth);
45
89
  const venueData = await venueLoadingUtils.getVenueDataFromUrls(vConfig, fetchJson, languagesToTry, fetchManifestJson);
46
90
  const { accountId, venueId } = vConfig;
47
91
  venueData.assetStage = vConfig.assetStage;
@@ -64,8 +108,7 @@ async function create(app, config) {
64
108
  })();
65
109
  }
66
110
  app.bus.send("venueData/venueDataLoaded", { venueData });
67
- venueDataLoaded.resolve(venueData);
68
- return venueDataLoaded;
111
+ return venueData;
69
112
  }
70
113
  function getDefaultOrdinal(venueData) {
71
114
  const defaultStructureId = getDefaultStructureId(venueData);
@@ -162,6 +205,7 @@ async function create(app, config) {
162
205
  return features.map(enrichFeature);
163
206
  };
164
207
  app.bus.on("venueData/loadMap", async () => {
208
+ const thisMapDataLoaded = mapDataLoaded;
165
209
  venueDataLoaded.then(async (venueData) => {
166
210
  const badgesSpriteUrl = venueData.files.spritesheet;
167
211
  const mapGlyphsUrl = venueData.files.glyphs;
@@ -194,8 +238,11 @@ async function create(app, config) {
194
238
  tileServerAuthInfo: venueData.tileServerAuthInfo
195
239
  // only defined for tile maps
196
240
  };
197
- mapDataLoaded.resolve(mapData);
241
+ thisMapDataLoaded.resolve(mapData);
198
242
  app.bus.send("venueData/mapDataLoaded", mapData);
243
+ }).catch((err) => {
244
+ thisMapDataLoaded.reject(err);
245
+ log.error("Map data load failed", err);
199
246
  });
200
247
  });
201
248
  const shouldDisplayPredicate = (building) => building.shouldDisplay == null || building.shouldDisplay;
@@ -296,7 +343,7 @@ async function create(app, config) {
296
343
  mapDataLoaded.reject(new Error("loadNewVenue called - previous loading ignored"));
297
344
  venueDataLoaded = new Zousan();
298
345
  mapDataLoaded = new Zousan();
299
- loadVenueData({ ...config, venueId, accountId, assetStage }, []).then(notifyState);
346
+ loadVenueData({ ...config, venueId, accountId, assetStage }, []).then(notifyState).catch((err) => log.error(err));
300
347
  });
301
348
  app.bus.on("venueData/getPoiImageUrl", ({ imageName, size }) => {
302
349
  return `https://img.locuslabs.com/resize/${config.accountId}/png/transparent/${size}contain/poi/${imageName}`;
@@ -117,10 +117,12 @@ const getVenueDataFromUrls = async (vconfig, fetchJson, languagesToTry, fetchMan
117
117
  const accountUrl = `https://${stageUrl}/accounts/${accountId}`;
118
118
  const assetFormat = formatVersion || "v5";
119
119
  const usesKioskAuth = vconfig.auth?.type === "kiosk";
120
+ const usesInteractiveAuth = vconfig.auth?.type === "interactive";
121
+ const usesSecureManifest = usesKioskAuth || usesInteractiveAuth;
120
122
  if (usesKioskAuth && (typeof vconfig.auth.signedManifestUrl !== "string" || !vconfig.auth.signedManifestUrl.trim())) {
121
123
  throw new Error("Kiosk auth requires a non-empty signedManifestUrl");
122
124
  }
123
- const venueList = !usesKioskAuth && vconfig.dataFetch && globalThis[vconfig.dataFetch] && globalThis[vconfig.dataFetch].getFiles ? await globalThis[vconfig.dataFetch].getFiles(vconfig) : await fetchManifestJson(usesKioskAuth ? vconfig.auth.signedManifestUrl : `${accountUrl}/${assetFormat}.json`);
125
+ const venueList = !usesSecureManifest && vconfig.dataFetch && globalThis[vconfig.dataFetch] && globalThis[vconfig.dataFetch].getFiles ? await globalThis[vconfig.dataFetch].getFiles(vconfig) : await fetchManifestJson(usesKioskAuth ? vconfig.auth.signedManifestUrl : `${accountUrl}/${assetFormat}.json`);
124
126
  const venueCode = venueList[venueId] ? venueList[venueId].venueCode : null;
125
127
  if (venueCode) {
126
128
  const venuesWithSameVenueCode = Object.values(venueList).filter((v) => v.venueCode === venueCode);
@@ -138,7 +140,7 @@ const getVenueDataFromUrls = async (vconfig, fetchJson, languagesToTry, fetchMan
138
140
  throw Error(`Attempt to access venue ${venueId} which is not within venue list: ${Object.keys(venueList)}`);
139
141
  }
140
142
  const files = venueList[venueId].files;
141
- const fetchedData = !usesKioskAuth && vconfig.dataFetch && globalThis[vconfig.dataFetch] && globalThis[vconfig.dataFetch].getVenueData ? await globalThis[vconfig.dataFetch].getVenueData(vconfig) : await fetchJson(files.venueData);
143
+ const fetchedData = !usesSecureManifest && vconfig.dataFetch && globalThis[vconfig.dataFetch] && globalThis[vconfig.dataFetch].getVenueData ? await globalThis[vconfig.dataFetch].getVenueData(vconfig) : await fetchJson(files.venueData);
142
144
  const venueData = fetchedData[venueId];
143
145
  if (venueData.tileServerAuthInfo) {
144
146
  embellishTilemapVenueData(venueData);
@@ -1 +1 @@
1
- var a="3.3.1161",e={version:a};export{e as default,a as version};
1
+ var a="3.3.1165",e={version:a};export{e as default,a as version};
@@ -0,0 +1 @@
1
+ const E={MISCONFIGURED:"misconfigured",SESSION_EXPIRED:"sessionExpired",ACCESS_DENIED:"accessDenied",UNAVAILABLE:"unavailable",LINK_EXPIRED:"linkExpired",SERVICE_ERROR:"serviceError"};export{E as LOAD_FAILURE_REASON};
@@ -0,0 +1 @@
1
+ import{LOAD_FAILURE_REASON as t}from"./constants.js";const e=t=>"object"==typeof t&&null!==t&&"string"==typeof t.status,a={misconfigured:t.MISCONFIGURED,unavailable:t.UNAVAILABLE,callbackFailed:t.SERVICE_ERROR,signOutFailed:t.SERVICE_ERROR},s=(s,o)=>new Promise(R=>{let n=!1,E=!1;const r=t=>{n||(n=!0,c(),R(t))},i=e=>{if("authenticated"===e.status)r({ok:!0});else if("error"===e.status)r({ok:!1,reason:(s=e.reason,a[s]??t.SERVICE_ERROR)});else if("unauthenticated"===e.status&&!n&&!E){E=!0;try{o?.()}catch{r({ok:!1,reason:t.SERVICE_ERROR})}}var s},c=s.on("auth/stateChanged",t=>{e(t)&&i(t)});s.getFirst("auth/getState").then(a=>{void 0===a?r({ok:!1,reason:t.MISCONFIGURED}):e(a)?i(a):r({ok:!1,reason:t.SERVICE_ERROR})}).catch(()=>r({ok:!1,reason:t.SERVICE_ERROR}))});export{s as awaitAuthentication};
@@ -0,0 +1 @@
1
+ import{LOAD_FAILURE_REASON as t}from"./constants.js";import{awaitAuthentication as e}from"./interactiveAuthGate.js";class s extends Error{reason;constructor(t,e){super(`Venue load failed: ${t}`,e),this.name="VenueLoadFailedError",this.reason=t}}const n="https://assets-api.locuslabs.com/prod",a=({accountId:t,venueId:e,assetStage:s})=>{const a=`${n}/asset-manifest/accounts/${encodeURIComponent(t)}/venue/${encodeURIComponent(e)}`;return s?`${a}?assetStage=${encodeURIComponent(s)}&mode=interactive`:a},r=async({bus:n,fetch:a,manifestEndpoint:r})=>{const o=async t=>{throw await n.send("venueData/loadFailed",{reason:t}),new s(t)},c=await e(n,()=>n.send("auth/signIn"));if(!c.ok)return o(c.reason);const i=async e=>{try{return await e()}catch{return o(t.SERVICE_ERROR)}},u=await i(()=>n.getFirst("auth/getAccessToken",{forceRefresh:!0}));if("string"!=typeof u||""===u)return o(t.SESSION_EXPIRED);const E=await i(()=>a(r,{headers:{"x-api-key":u},redirect:"error"}));if(200!==E.status)return o((e=>{switch(e){case 401:return t.SESSION_EXPIRED;case 403:return t.ACCESS_DENIED;default:return t.SERVICE_ERROR}})(E.status));const R=await i(()=>E.json()),d=R?.data?.url;if("string"!=typeof d||""===d)return o(t.SERVICE_ERROR);const I=await i(()=>a(d));return 200!==I.status?o(403===I.status?t.LINK_EXPIRED:t.SERVICE_ERROR):i(()=>I.json())};export{n as MANIFEST_BASE_URL,s as VenueLoadFailedError,a as buildInteractiveManifestEndpoint,r as loadInteractiveManifest};
@@ -0,0 +1 @@
1
+ const e=e=>{if(void 0===e)return{mode:"public"};if("object"!=typeof(i=e)||null===i||Array.isArray(i))return{mode:"invalid"};var i;const t=Object.keys(e).length;if("kiosk"===e.type){const{signedManifestUrl:i}=e;return 2===t&&"string"==typeof i&&""!==i.trim()?{mode:"kiosk",signedManifestUrl:i}:{mode:"invalid"}}return"interactive"===e.type&&1===t?{mode:"interactive"}:{mode:"invalid"}};export{e as resolveAuth};
@@ -1 +1 @@
1
- import*as e from"ramda";import t from"zousan";import{resolveVenueTimezone as a}from"./fixedOffsetZones.js";import{fetchStyleDoc as n,normalizeCoords as s,getVenueDataFromUrls as r,buildStructures as o,createFetchJson as u,createFetchText as i,createFetchManifestJson as d}from"./venueLoadingUtils.js";async function l(l,c){const p=l.log.sublog("venueDataLoader");let v=new t,g=new t;const f=new t;l.bus.on("system/readywhenyouare",()=>f);const b=t=>t.defaultStructureId||e.path(["structureOrder",0],t)||e.path(["selectorOrder",0],t)||e.pipe(e.prop("structures"),Object.values,e.path([0,"id"]))(t),m=(e,t)=>e.split("").reduce((a,n,s)=>e.substring(0,s+1)===t.substring(0,s+1)?s:a,-1)+1,h=e=>((e,t)=>Object.values(e.venueList).filter(e=>e.locale===t).sort((t,a)=>m(a.id,e.id)-m(t.id,e.id)).at(0))(e,"en")?.id;async function y(t,a){const n=u(),s=i(),c=d(t.auth,e=>l.bus.send("venueData/authError",{reason:"signedManifestForbidden",status:e})),p=await r(t,n,a,c),{accountId:g,venueId:f}=t;return p.assetStage=t.assetStage,p.defaultOrdinal=p.defaultOrdinal||function(t){const a=b(t),n=Object.values(t.structures).find(e.propEq(a,"id"));return n.levels[n.defaultLevelId].ordinal}(p),p.structures=o(p),p.baseVenueId=h(p),p.getTranslatedContentPath=e=>`https://content.locuslabs.com/${p.category}/${e}/${f}/${g}`,p.fetchJson=n,p.fetchText=s,l.config.debug&&l.env.isBrowser&&(window._venueData=p),p.queueTypes&&(p.securityQueueTypes=(()=>{const e=p.queueTypes.find(e=>"SecurityLane"===e.id);return e?e.subtypes.map(e=>e.id):[]})()),l.bus.send("venueData/venueDataLoaded",{venueData:p}),v.resolve(p),v}function D(e){const t={id:"venueDataLoader"};return e.id!==c.venueId&&(t.vid=e.id),t.lang=l.i18n().language,"prod"!==e.assetStage&&(t.stage=e.assetStage),l.bus.send("deepLinking/notifyState",t),e}l.bus.on("debugTools/fileDrop",async({file:e,content:t})=>{if("application/json"===e.type){const e=JSON.parse(t);if(e.basemap&&e["basemap.venue"])return n=JSON.parse(t),void l.bus.send("map/replaceTheme",{theme:n});if(e.metadata&&e.metadata["mapbox:type"])return a=t,void l.bus.send("map/replaceStyle",{styleSrc:a})}var a,n});async function I(e){const t={...e},a=await l.bus.get("poi/getAll");return Object.values(t).forEach(e=>e.filter(e=>"poi"===e.properties.aiLayer&&"Point"===e.geometry.type).forEach(e=>{const t=a[e.properties.id];t?t.mapLabel?e.properties.text=t.mapLabel:!1!==c.copyPOINamesToMap&&(e.properties.text=function(e){let t=e.name;return c.poiMapNameXForm?(Object.keys(c.poiMapNameXForm).filter(t=>((e,t)=>e===t||0===e.indexOf(t+"."))(e.category,t)).forEach(e=>{c.poiMapNameXForm[e].forEach(e=>t=t.replace(new RegExp(e.replace),e.with))}),t):t}(t)):p.warn(`Unknown poi in style: ${e.properties.id}`)})),t}async function w(a){return e.pipe(e.prop("structures"),e.map(e.prop("levels")),e.chain(e.keys),e.prepend(a.id),e.map(e=>a.files.geoJson.replace("${geoJsonId}",e)),e.map(a.fetchJson),e.map(e.andThen(e=>[e.id,O(e.id,e.features,a.id,a.structures)])),e=>t.all(e),e.andThen(e.fromPairs))(a)}const O=(t,a,n,s)=>{const r=t.replace(/-[^-]*$/,""),o=r===n?"landscape-background":`ordinal: ${s.find(e.hasPath(["levels",t])).levels[t].ordinal}`;return a.map(a=>{var s,u,i;return s="properties",u={venueId:n,structureId:r,ordinalId:o,levelId:t},i=a,a=e.over(e.lensProp(s),t=>e.mergeRight(t||{},u),i),a=e.assoc("id",a.properties.subid,a)})};l.bus.on("venueData/loadMap",async()=>{v.then(async e=>{const t=e.files.spritesheet,a=e.files.glyphs,{id:s,bounds:r,structures:o,venueCenter:u,venueRadius:i,defaultOrdinal:d}=e,[p,v,f]=await Promise.all([n(e.baseVenueId,e.category),e.fetchJson(e.files.theme),e.venueList[s].mapTokens?Promise.resolve({[s]:[]}):w(e).then(I)]),b={mapFeatures:f,mapStyleSource:p,mapTheme:v,badgesSpriteUrl:t,mapGlyphsUrl:a,structures:o,defaultOrdinal:d,venueBounds:{n:r.ne.lat,s:r.sw.lat,e:r.ne.lng,w:r.sw.lng},venueId:s,venueCenter:u,venueRadius:i,accountId:c.accountId,secure:void 0!==c.auth,tileServerAuthInfo:e.tileServerAuthInfo};g.resolve(b),l.bus.send("venueData/mapDataLoaded",b)})});const S=e=>null==e.shouldDisplay||e.shouldDisplay;l.bus.on("venueData/loadBuildingSelectorData",()=>v.then(async t=>{const a={buildings:t.structures.filter(S).map(e.evolve({levels:e.pipe(e.values,e.sortWith([e.descend(e.prop("ordinal"))]))})),structureOrder:t.structureOrder,selectorOrder:t.selectorOrder};return l.bus.send("venueData/buildingSelectorDataLoaded",a),a})),l.bus.on("venueData/normalizeCoords",({coords:e})=>v.then(t=>s(e,t.bounds)));const T={edges:[],nodes:[]};l.bus.on("venueData/loadNavGraph",async()=>v.then(async e=>{const t={navGraphData:e.files.nav?await e.fetchJson(e.files.nav):T,structures:e.structures};return l.bus.send("venueData/navGraphLoaded",t),t})),l.bus.on("venueData/loadPoiData",async()=>v.then(async e=>{const t=c.useOldDataModel?e.files.poisOld||e.files.pois:e.files.pois||e.files.poisOld;if(t){const a=await e.fetchJson(t);l.bus.send("venueData/poiDataLoaded",{pois:a,structures:e.structures})}})),l.bus.on("venueData/getVenueCenter",async()=>v.then(async e=>({lat:e.venueCenter[0],lng:e.venueCenter[1],ordinal:0}))),l.bus.on("venueData/getContentUrl",({type:e,name:t=""})=>v.then(a=>a.files[e]+t)),l.bus.on("venueData/getFloorIdToNameMap",()=>v.then(e.pipe(e.prop("structures"),e.map(e.prop("levels")),e.chain(e.values),e.map(e.props(["id","name"])),e.fromPairs))),l.bus.on("venueData/getFloorIdName",({floorId:t})=>v.then(async a=>{const n=e.pipe(e.values,e.find(e.hasPath(["levels",t])))(a.structures);return n?{structureId:n.id,structureName:n.name,floorName:n.levels[t].name}:null}));const P=(t,a)=>()=>v.then(e.pipe(e.prop(t),e.defaultTo(a)));function L(e,t){const a=N(t);if(a.includes(e))return e;const n=e.split("-").slice(1).join("-");return a.find(e=>new RegExp(`${t.baseVenueId}.?.?-${n}`).test(e))}l.bus.on("venueData/getVenueData",()=>v),l.bus.on("venueData/getVenueName",P("name")),l.bus.on("venueData/getVenueCategory",P("category")),l.bus.on("venueData/getVenueTimezone",()=>v.then(e=>a(e.tz))),l.bus.on("venueData/getAccountId",()=>c.accountId),l.bus.on("venueData/getVenueId",P("id")),l.bus.on("venueData/getPositioningSupported",P("positioningSupported")),l.bus.on("venueData/getStructures",P("structures")),l.bus.on("venueData/loadNewVenue",async({venueId:e,accountId:a,assetStage:n=c.assetStage})=>{v.reject(new Error("loadNewVenue called - previous loading ignored")),g.reject(new Error("loadNewVenue called - previous loading ignored")),v=new t,g=new t,y({...c,venueId:e,accountId:a,assetStage:n},[]).then(D)}),l.bus.on("venueData/getPoiImageUrl",({imageName:e,size:t})=>`https://img.locuslabs.com/resize/${c.accountId}/png/transparent/${t}contain/poi/${e}`),l.bus.on("venueData/getDistributionId",()=>v.then(e=>`${e.baseVenueId}-${c.accountId}`)),l.bus.on("venueData/getCustomKeywords",()=>v.then(e=>{const t=c.useOldDataModel&&e.files.searchOld||e.files.search;return e.fetchJson(t)})),l.bus.on("venueData/isGrabEnabled",P("enableGrab")),l.bus.on("venueData/getGrabPoiIds",P("grabPoiIds",[])),l.bus.on("venueData/getAssetsTimestamp",P("version")),l.bus.on("venueData/getTranslatedFloorId",async({floorId:e})=>v.then(t=>L(e,t)));const N=e=>e.structures.reduce((e,t)=>e.concat(Object.keys(t.levels)),[]);l.bus.on("venueData/getQueueTypes",()=>v.then(e=>{const t=["tsapre","clear","globalEntry"];return e.queueTypes?e.queueTypes.reduce((e,a)=>{const{id:n,subtypes:s}=a,r=s.map(e=>{const a=t.includes(e.id)&&`security-logo-${e.id.toLowerCase()}`;return{...e,imageId:a}});return e[n]=r,e},{}):{}}));return{init:async()=>{const e=c.deepLinkProps||{},t="undefined"==typeof window?null:new URLSearchParams(window.location.search).get("lang"),a=e.lang??t,n="undefined"==typeof window?[]:[...navigator.languages],s=a?[]:n,r=e.vid||c.venueId,o=c.useDynamicUrlParams&&e.stage?e.stage:c.assetStage,u=e.accountId||("alpha"===o?"A1VPTJKREFJWX5":c.accountId);y({...c,venueId:r,accountId:u,assetStage:o},s).then(D).catch(e=>p.error("Initial venue load failed",e)).finally(()=>f.resolve(!0))},runTest:async({testRoutine:e,reset:a=!1,venueData:n=null})=>{let s,r;return(a||n)&&(v=new t,g=new t),n&&(v=t.resolve(n)),await e(),v.v&&(s=await v),g.v&&(r=await g),{venueDataObj:s,mapDataObj:r}},internal:{calculateBaseVenueId:h,getDefaultStructureId:b,getTranslatedFloorId:L,setConfigProperty:(e,t)=>{c[e]=t}}}}export{l as create};
1
+ import*as e from"ramda";import t from"zousan";import{LOAD_FAILURE_REASON as a}from"./constants.js";import{resolveVenueTimezone as n}from"./fixedOffsetZones.js";import{VenueLoadFailedError as s,loadInteractiveManifest as r,buildInteractiveManifestEndpoint as o}from"./loadInteractiveVenue.js";import{resolveAuth as u}from"./resolveAuth.js";import{fetchStyleDoc as i,normalizeCoords as d,createFetchManifestJson as c,getVenueDataFromUrls as l,buildStructures as p,createFetchJson as v,createFetchText as g}from"./venueLoadingUtils.js";async function f(f,m){const b=f.log.sublog("venueDataLoader");let h=new t,y=new t;const D=new t;f.bus.on("system/readywhenyouare",()=>D);const I=t=>t.defaultStructureId||e.path(["structureOrder",0],t)||e.path(["selectorOrder",0],t)||e.pipe(e.prop("structures"),Object.values,e.path([0,"id"]))(t),w=(e,t)=>e.split("").reduce((a,n,s)=>e.substring(0,s+1)===t.substring(0,s+1)?s:a,-1)+1,S=e=>((e,t)=>Object.values(e.venueList).filter(e=>e.locale===t).sort((t,a)=>w(a.id,e.id)-w(t.id,e.id)).at(0))(e,"en")?.id;async function O(t,n){const i=h,d=y,m=u(t.auth);try{const a=await async function(t,a,n){if("invalid"===n.mode)throw f.bus.send("venueData/loadFailed",{reason:"misconfigured"}),new s("misconfigured");const u=v(),i=g(),d="interactive"===n.mode?()=>r({bus:f.bus,fetch:globalThis.fetch,manifestEndpoint:o({accountId:t.accountId,venueId:t.venueId,assetStage:t.assetStage})}):"kiosk"===n.mode?function(e){let t=!1;const a=c(e,async e=>{t=!0,await f.bus.send("venueData/authError",{reason:"signedManifestForbidden",status:e}),await f.bus.send("venueData/loadFailed",{reason:"linkExpired"})});return async e=>{try{return await a(e)}catch(e){throw t?new s("linkExpired",{cause:e}):e}}}(t.auth):c(t.auth),m=await l(t,u,a,d),{accountId:b,venueId:h}=t;m.assetStage=t.assetStage,m.defaultOrdinal=m.defaultOrdinal||function(t){const a=I(t),n=Object.values(t.structures).find(e.propEq(a,"id"));return n.levels[n.defaultLevelId].ordinal}(m),m.structures=p(m),m.baseVenueId=S(m),m.getTranslatedContentPath=e=>`https://content.locuslabs.com/${m.category}/${e}/${h}/${b}`,m.fetchJson=u,m.fetchText=i,f.config.debug&&f.env.isBrowser&&(window._venueData=m);m.queueTypes&&(m.securityQueueTypes=(()=>{const e=m.queueTypes.find(e=>"SecurityLane"===e.id);return e?e.subtypes.map(e=>e.id):[]})());return f.bus.send("venueData/venueDataLoaded",{venueData:m}),m}(t,n,m);return i.resolve(a),i}catch(e){throw e instanceof s||f.bus.send("venueData/loadFailed",{reason:a.SERVICE_ERROR}),i.reject(e),d.reject(e),e}}function T(e){const t={id:"venueDataLoader"};return e.id!==m.venueId&&(t.vid=e.id),t.lang=f.i18n().language,"prod"!==e.assetStage&&(t.stage=e.assetStage),f.bus.send("deepLinking/notifyState",t),e}f.bus.on("debugTools/fileDrop",async({file:e,content:t})=>{if("application/json"===e.type){const e=JSON.parse(t);if(e.basemap&&e["basemap.venue"])return n=JSON.parse(t),void f.bus.send("map/replaceTheme",{theme:n});if(e.metadata&&e.metadata["mapbox:type"])return a=t,void f.bus.send("map/replaceStyle",{styleSrc:a})}var a,n});async function j(e){const t={...e},a=await f.bus.get("poi/getAll");return Object.values(t).forEach(e=>e.filter(e=>"poi"===e.properties.aiLayer&&"Point"===e.geometry.type).forEach(e=>{const t=a[e.properties.id];t?t.mapLabel?e.properties.text=t.mapLabel:!1!==m.copyPOINamesToMap&&(e.properties.text=function(e){let t=e.name;return m.poiMapNameXForm?(Object.keys(m.poiMapNameXForm).filter(t=>((e,t)=>e===t||0===e.indexOf(t+"."))(e.category,t)).forEach(e=>{m.poiMapNameXForm[e].forEach(e=>t=t.replace(new RegExp(e.replace),e.with))}),t):t}(t)):b.warn(`Unknown poi in style: ${e.properties.id}`)})),t}async function P(a){return e.pipe(e.prop("structures"),e.map(e.prop("levels")),e.chain(e.keys),e.prepend(a.id),e.map(e=>a.files.geoJson.replace("${geoJsonId}",e)),e.map(a.fetchJson),e.map(e.andThen(e=>[e.id,E(e.id,e.features,a.id,a.structures)])),e=>t.all(e),e.andThen(e.fromPairs))(a)}const E=(t,a,n,s)=>{const r=t.replace(/-[^-]*$/,""),o=r===n?"landscape-background":`ordinal: ${s.find(e.hasPath(["levels",t])).levels[t].ordinal}`;return a.map(a=>{var s,u,i;return s="properties",u={venueId:n,structureId:r,ordinalId:o,levelId:t},i=a,a=e.over(e.lensProp(s),t=>e.mergeRight(t||{},u),i),a=e.assoc("id",a.properties.subid,a)})};f.bus.on("venueData/loadMap",async()=>{const e=y;h.then(async t=>{const a=t.files.spritesheet,n=t.files.glyphs,{id:s,bounds:r,structures:o,venueCenter:u,venueRadius:d,defaultOrdinal:c}=t,[l,p,v]=await Promise.all([i(t.baseVenueId,t.category),t.fetchJson(t.files.theme),t.venueList[s].mapTokens?Promise.resolve({[s]:[]}):P(t).then(j)]),g={mapFeatures:v,mapStyleSource:l,mapTheme:p,badgesSpriteUrl:a,mapGlyphsUrl:n,structures:o,defaultOrdinal:c,venueBounds:{n:r.ne.lat,s:r.sw.lat,e:r.ne.lng,w:r.sw.lng},venueId:s,venueCenter:u,venueRadius:d,accountId:m.accountId,secure:void 0!==m.auth,tileServerAuthInfo:t.tileServerAuthInfo};e.resolve(g),f.bus.send("venueData/mapDataLoaded",g)}).catch(t=>{e.reject(t),b.error("Map data load failed",t)})});const L=e=>null==e.shouldDisplay||e.shouldDisplay;f.bus.on("venueData/loadBuildingSelectorData",()=>h.then(async t=>{const a={buildings:t.structures.filter(L).map(e.evolve({levels:e.pipe(e.values,e.sortWith([e.descend(e.prop("ordinal"))]))})),structureOrder:t.structureOrder,selectorOrder:t.selectorOrder};return f.bus.send("venueData/buildingSelectorDataLoaded",a),a})),f.bus.on("venueData/normalizeCoords",({coords:e})=>h.then(t=>d(e,t.bounds)));const V={edges:[],nodes:[]};f.bus.on("venueData/loadNavGraph",async()=>h.then(async e=>{const t={navGraphData:e.files.nav?await e.fetchJson(e.files.nav):V,structures:e.structures};return f.bus.send("venueData/navGraphLoaded",t),t})),f.bus.on("venueData/loadPoiData",async()=>h.then(async e=>{const t=m.useOldDataModel?e.files.poisOld||e.files.pois:e.files.pois||e.files.poisOld;if(t){const a=await e.fetchJson(t);f.bus.send("venueData/poiDataLoaded",{pois:a,structures:e.structures})}})),f.bus.on("venueData/getVenueCenter",async()=>h.then(async e=>({lat:e.venueCenter[0],lng:e.venueCenter[1],ordinal:0}))),f.bus.on("venueData/getContentUrl",({type:e,name:t=""})=>h.then(a=>a.files[e]+t)),f.bus.on("venueData/getFloorIdToNameMap",()=>h.then(e.pipe(e.prop("structures"),e.map(e.prop("levels")),e.chain(e.values),e.map(e.props(["id","name"])),e.fromPairs))),f.bus.on("venueData/getFloorIdName",({floorId:t})=>h.then(async a=>{const n=e.pipe(e.values,e.find(e.hasPath(["levels",t])))(a.structures);return n?{structureId:n.id,structureName:n.name,floorName:n.levels[t].name}:null}));const N=(t,a)=>()=>h.then(e.pipe(e.prop(t),e.defaultTo(a)));function $(e,t){const a=C(t);if(a.includes(e))return e;const n=e.split("-").slice(1).join("-");return a.find(e=>new RegExp(`${t.baseVenueId}.?.?-${n}`).test(e))}f.bus.on("venueData/getVenueData",()=>h),f.bus.on("venueData/getVenueName",N("name")),f.bus.on("venueData/getVenueCategory",N("category")),f.bus.on("venueData/getVenueTimezone",()=>h.then(e=>n(e.tz))),f.bus.on("venueData/getAccountId",()=>m.accountId),f.bus.on("venueData/getVenueId",N("id")),f.bus.on("venueData/getPositioningSupported",N("positioningSupported")),f.bus.on("venueData/getStructures",N("structures")),f.bus.on("venueData/loadNewVenue",async({venueId:e,accountId:a,assetStage:n=m.assetStage})=>{h.reject(new Error("loadNewVenue called - previous loading ignored")),y.reject(new Error("loadNewVenue called - previous loading ignored")),h=new t,y=new t,O({...m,venueId:e,accountId:a,assetStage:n},[]).then(T).catch(e=>b.error(e))}),f.bus.on("venueData/getPoiImageUrl",({imageName:e,size:t})=>`https://img.locuslabs.com/resize/${m.accountId}/png/transparent/${t}contain/poi/${e}`),f.bus.on("venueData/getDistributionId",()=>h.then(e=>`${e.baseVenueId}-${m.accountId}`)),f.bus.on("venueData/getCustomKeywords",()=>h.then(e=>{const t=m.useOldDataModel&&e.files.searchOld||e.files.search;return e.fetchJson(t)})),f.bus.on("venueData/isGrabEnabled",N("enableGrab")),f.bus.on("venueData/getGrabPoiIds",N("grabPoiIds",[])),f.bus.on("venueData/getAssetsTimestamp",N("version")),f.bus.on("venueData/getTranslatedFloorId",async({floorId:e})=>h.then(t=>$(e,t)));const C=e=>e.structures.reduce((e,t)=>e.concat(Object.keys(t.levels)),[]);f.bus.on("venueData/getQueueTypes",()=>h.then(e=>{const t=["tsapre","clear","globalEntry"];return e.queueTypes?e.queueTypes.reduce((e,a)=>{const{id:n,subtypes:s}=a,r=s.map(e=>{const a=t.includes(e.id)&&`security-logo-${e.id.toLowerCase()}`;return{...e,imageId:a}});return e[n]=r,e},{}):{}}));return{init:async()=>{const e=m.deepLinkProps||{},t="undefined"==typeof window?null:new URLSearchParams(window.location.search).get("lang"),a=e.lang??t,n="undefined"==typeof window?[]:[...navigator.languages],s=a?[]:n,r=e.vid||m.venueId,o=m.useDynamicUrlParams&&e.stage?e.stage:m.assetStage,u=e.accountId||("alpha"===o?"A1VPTJKREFJWX5":m.accountId);O({...m,venueId:r,accountId:u,assetStage:o},s).then(T).catch(e=>b.error("Initial venue load failed",e)).finally(()=>D.resolve(!0))},runTest:async({testRoutine:e,reset:a=!1,venueData:n=null})=>{let s,r;return(a||n)&&(h=new t,y=new t),n&&(h=t.resolve(n)),await e(),h.v&&(s=await h),y.v&&(r=await y),{venueDataObj:s,mapDataObj:r}},internal:{calculateBaseVenueId:S,getDefaultStructureId:I,getTranslatedFloorId:$,setConfigProperty:(e,t)=>{m[e]=t}}}}export{f as create};
@@ -1 +1 @@
1
- import*as e from"ramda";import{findBoundsOfCoordinates as t}from"../../../src/utils/bounds.js";const n=async(e,t)=>e?fetch(t,{headers:{Authorization:e}}):fetch(t),s=e=>t=>n(e,t).then(e=>e.json()),a=e=>t=>n(e,t).then(e=>e.text()),o=(e,t)=>async n=>{const s=await fetch(n);if("kiosk"===e?.type&&403===s.status)throw await(t?.(s.status)),new Error(`Kiosk signed manifest request was forbidden (${s.status}); the signed URL may have expired.`);return s.json()},r=(e,t)=>n(null,`https://style.maps.atrius.com/v2/style?venueId=${e}&category=${t}`).then(e=>e.json()).then(e=>e.data),l=e=>`https://api.content.locuslabs.com/${e}`,i=e=>{if("string"!=typeof e)return!1;try{const t=new URL(e).searchParams;return["Expires","Signature","Key-Pair-Id"].every(e=>t.has(e))}catch{return!1}},u=(t,n,s,a,o)=>e.mapObjIndexed((e,n)=>((e,t,n,s,a,o)=>i(e)?e:"theme"===o||"style"===o?`${l(n)}/${t}/${o}/${a}/${s}/${o}.json`:e.replace(/https:\/\/content.locuslabs.com/gi,l(n)))(e,t,s,a,o,n),n),c=[["zh-CN","zh-SG","zh-Hans"],["zh-TW","zh-HK","zh-MO","zh-Hant"]],d=e=>{const t=(e=>{const t=c.find(t=>t.includes(e));return t?t.filter(t=>t!==e):[]})(e),n=e.slice(0,2);return[t=>t===e,e=>t.includes(e),e=>e.slice(0,2)===n]},h=(e,t,n=null)=>{for(const s of d(t)){if(n&&s(n.locale))return n;const t=e.find(e=>s(e.locale));if(t)return t}return null},g=async(e,t,n,s=t)=>{const a={alpha:"alpha-a.locuslabs.com",beta:"beta-a.locuslabs.com",gamma:"gamma-a.locuslabs.com",prod:"a.locuslabs.com"},{assetStage:o,accountId:r,formatVersion:l}=e;let{venueId:i}=e;const c=`https://${a[o]||a.prod}/accounts/${r}`,d=l||"v5",g="kiosk"===e.auth?.type;if(g&&("string"!=typeof e.auth.signedManifestUrl||!e.auth.signedManifestUrl.trim()))throw new Error("Kiosk auth requires a non-empty signedManifestUrl");const f=!g&&e.dataFetch&&globalThis[e.dataFetch]&&globalThis[e.dataFetch].getFiles?await globalThis[e.dataFetch].getFiles(e):await s(g?e.auth.signedManifestUrl:`${c}/${d}.json`),m=f[i]?f[i].venueCode:null;if(m){const t=Object.values(f).filter(e=>e.venueCode===m),s=f[i];for(const a of n){const n=h(t,a,s);if(n){i=n.id,e.venueId=`${i}`;break}}}if(!f[i])throw Error(`Attempt to access venue ${i} which is not within venue list: ${Object.keys(f)}`);const p=f[i].files,b=(!g&&e.dataFetch&&globalThis[e.dataFetch]&&globalThis[e.dataFetch].getVenueData?await globalThis[e.dataFetch].getVenueData(e):await t(p.venueData))[i];b.tileServerAuthInfo&&function(e){const t={defaultOrdinal:0,defaultStructureId:"singleBuilding",formatVersion:"v5",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 n in t)e[n]=t[n]}(b),b.venueList=f;const v=(e=>{const t=e.deepLinkProps?e.deepLinkProps.contentStage:null;return"alpha"===t||"beta"===t||"prod"===t?t:null})(e);return b.files=v?u(b.category,p,v,r,i):p,b},f=e=>{const{structureOrder:n,structures:s}=e;return n.map(e=>{const n=s[e];Object.values(n.levels).forEach(e=>e.bounds=t(e.boundsPolygon));const a=t(n.boundsPolygon);return{...n,bounds:a}})};const m=([e,t,...n])=>[t,e,...n],p=(e,t)=>{return!e||!Array.isArray(e)||e.length<1?e:(n=e[0][0],s=t.ne.lng,a=t.sw.lng,n>=Math.min(s,a)&&n<=Math.max(s,a)?e:e.map(m));var n,s,a};export{f as buildStructures,s as createFetchJson,o as createFetchManifestJson,a as createFetchText,r as fetchStyleDoc,h as findVenueForLocale,g as getVenueDataFromUrls,p as normalizeCoords};
1
+ import*as e from"ramda";import{findBoundsOfCoordinates as t}from"../../../src/utils/bounds.js";const n=async(e,t)=>e?fetch(t,{headers:{Authorization:e}}):fetch(t),s=e=>t=>n(e,t).then(e=>e.json()),a=e=>t=>n(e,t).then(e=>e.text()),o=(e,t)=>async n=>{const s=await fetch(n);if("kiosk"===e?.type&&403===s.status)throw await(t?.(s.status)),new Error(`Kiosk signed manifest request was forbidden (${s.status}); the signed URL may have expired.`);return s.json()},r=(e,t)=>n(null,`https://style.maps.atrius.com/v2/style?venueId=${e}&category=${t}`).then(e=>e.json()).then(e=>e.data),i=e=>`https://api.content.locuslabs.com/${e}`,l=e=>{if("string"!=typeof e)return!1;try{const t=new URL(e).searchParams;return["Expires","Signature","Key-Pair-Id"].every(e=>t.has(e))}catch{return!1}},u=(t,n,s,a,o)=>e.mapObjIndexed((e,n)=>((e,t,n,s,a,o)=>l(e)?e:"theme"===o||"style"===o?`${i(n)}/${t}/${o}/${a}/${s}/${o}.json`:e.replace(/https:\/\/content.locuslabs.com/gi,i(n)))(e,t,s,a,o,n),n),c=[["zh-CN","zh-SG","zh-Hans"],["zh-TW","zh-HK","zh-MO","zh-Hant"]],d=e=>{const t=(e=>{const t=c.find(t=>t.includes(e));return t?t.filter(t=>t!==e):[]})(e),n=e.slice(0,2);return[t=>t===e,e=>t.includes(e),e=>e.slice(0,2)===n]},h=(e,t,n=null)=>{for(const s of d(t)){if(n&&s(n.locale))return n;const t=e.find(e=>s(e.locale));if(t)return t}return null},g=async(e,t,n,s=t)=>{const a={alpha:"alpha-a.locuslabs.com",beta:"beta-a.locuslabs.com",gamma:"gamma-a.locuslabs.com",prod:"a.locuslabs.com"},{assetStage:o,accountId:r,formatVersion:i}=e;let{venueId:l}=e;const c=`https://${a[o]||a.prod}/accounts/${r}`,d=i||"v5",g="kiosk"===e.auth?.type,f="interactive"===e.auth?.type,m=g||f;if(g&&("string"!=typeof e.auth.signedManifestUrl||!e.auth.signedManifestUrl.trim()))throw new Error("Kiosk auth requires a non-empty signedManifestUrl");const p=!m&&e.dataFetch&&globalThis[e.dataFetch]&&globalThis[e.dataFetch].getFiles?await globalThis[e.dataFetch].getFiles(e):await s(g?e.auth.signedManifestUrl:`${c}/${d}.json`),b=p[l]?p[l].venueCode:null;if(b){const t=Object.values(p).filter(e=>e.venueCode===b),s=p[l];for(const a of n){const n=h(t,a,s);if(n){l=n.id,e.venueId=`${l}`;break}}}if(!p[l])throw Error(`Attempt to access venue ${l} which is not within venue list: ${Object.keys(p)}`);const v=p[l].files,y=(!m&&e.dataFetch&&globalThis[e.dataFetch]&&globalThis[e.dataFetch].getVenueData?await globalThis[e.dataFetch].getVenueData(e):await t(v.venueData))[l];y.tileServerAuthInfo&&function(e){const t={defaultOrdinal:0,defaultStructureId:"singleBuilding",formatVersion:"v5",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 n in t)e[n]=t[n]}(y),y.venueList=p;const $=(e=>{const t=e.deepLinkProps?e.deepLinkProps.contentStage:null;return"alpha"===t||"beta"===t||"prod"===t?t:null})(e);return y.files=$?u(y.category,v,$,r,l):v,y},f=e=>{const{structureOrder:n,structures:s}=e;return n.map(e=>{const n=s[e];Object.values(n.levels).forEach(e=>e.bounds=t(e.boundsPolygon));const a=t(n.boundsPolygon);return{...n,bounds:a}})};const m=([e,t,...n])=>[t,e,...n],p=(e,t)=>{return!e||!Array.isArray(e)||e.length<1?e:(n=e[0][0],s=t.ne.lng,a=t.sw.lng,n>=Math.min(s,a)&&n<=Math.max(s,a)?e:e.map(m));var n,s,a};export{f as buildStructures,s as createFetchJson,o as createFetchManifestJson,a as createFetchText,r as fetchStyleDoc,h as findVenueForLocale,g as getVenueDataFromUrls,p as normalizeCoords};
@@ -1 +1 @@
1
- import{prop as t,identity as n,path as i}from"ramda";function r(t){return m(t.map(i(["position","lat"])).filter(n),t.map(i(["position","lng"])).filter(n))}function a(i){return m(i.map(t(0)).filter(n),i.map(t(1)).filter(n))}function m(t,n){return{n:Math.max(...t),s:Math.min(...t),e:Math.max(...n),w:Math.min(...n)}}export{a as findBoundsOfCoordinates,r as findBoundsOfWaypoints};
1
+ import{path as t,identity as n,prop as i}from"ramda";function r(i){return m(i.map(t(["position","lat"])).filter(n),i.map(t(["position","lng"])).filter(n))}function a(t){return m(t.map(i(0)).filter(n),t.map(i(1)).filter(n))}function m(t,n){return{n:Math.max(...t),s:Math.min(...t),e:Math.max(...n),w:Math.min(...n)}}export{a as findBoundsOfCoordinates,r as findBoundsOfWaypoints};
@@ -181,6 +181,19 @@ export type BusAuthState = {
181
181
  status: 'error';
182
182
  reason: BusAuthErrorReason;
183
183
  };
184
+ export type BusAuthFormErrorCode = 'invalidCredentials' | 'invalidCode' | 'invalidPassword' | 'rateLimited' | 'unsupportedChallenge' | 'unavailable';
185
+ export type BusAuthFormResult = {
186
+ ok: true;
187
+ } | {
188
+ ok: false;
189
+ error: BusAuthFormErrorCode;
190
+ };
191
+ export type BusAuthCredentialController = {
192
+ signInWithRedirect: () => Promise<BusAuthFormResult>;
193
+ signIn: (email: string, password: string) => Promise<BusAuthFormResult>;
194
+ resetPassword: (email: string) => Promise<BusAuthFormResult>;
195
+ confirmNewPassword: (email: string, code: string, newPassword: string) => Promise<BusAuthFormResult>;
196
+ };
184
197
  export type BusVenueLoadFailureReason = 'misconfigured' | 'sessionExpired' | 'accessDenied' | 'unavailable' | 'linkExpired' | 'serviceError';
185
198
  export interface BusEventMap {
186
199
  'map/updateRoutePreviewInsets': BusEventDefinition<{
@@ -426,6 +439,7 @@ export interface BusEventMap {
426
439
  'auth/stateChanged': BusEventDefinition<BusAuthState, unknown>;
427
440
  'auth/signIn': BusEventDefinition<undefined, unknown>;
428
441
  'auth/signOut': BusEventDefinition<undefined, unknown>;
442
+ 'auth/getCredentialController': BusEventDefinition<undefined, BusAuthCredentialController>;
429
443
  'auth/getAccessToken': BusEventDefinition<{
430
444
  forceRefresh?: boolean;
431
445
  } | undefined, string | null>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atriusmaps-node-sdk",
3
- "version": "3.3.1161",
3
+ "version": "3.3.1165",
4
4
  "description": "This project provides an API to Atrius Personal Wayfinder maps within a Node environment. See the README.md for more information",
5
5
  "keywords": [
6
6
  "acuitybrands",