diff --git a/cypress/e2e/modals.cy.ts b/cypress/e2e/modals.cy.ts index ec3e4d77..02cb244f 100644 --- a/cypress/e2e/modals.cy.ts +++ b/cypress/e2e/modals.cy.ts @@ -160,6 +160,18 @@ describe("modals", () => { ).shouldInclude({ "maputnik:thunderforest_access_token": apiKey }); }); + it("stadia access token", () => { + let apiKey = "testing123"; + when.setValue( + "modal:settings.maputnik:stadia_access_token", + apiKey + ); + when.click("modal:settings.name"); + then( + get.styleFromLocalStorage().then((style) => style.metadata) + ).shouldInclude({ "maputnik:stadia_access_token": apiKey }); + }); + it("style renderer", () => { cy.on("uncaught:exception", () => false); // this is due to the fact that this is an invalid style for openlayers when.select("modal:settings.maputnik:renderer", "ol"); diff --git a/src/components/ModalExport.tsx b/src/components/ModalExport.tsx index bc75e172..f3c85783 100644 --- a/src/components/ModalExport.tsx +++ b/src/components/ModalExport.tsx @@ -137,6 +137,12 @@ class ModalExportInternal extends React.Component { value={(this.props.mapStyle.metadata || {} as any)['maputnik:thunderforest_access_token']} onChange={this.changeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")} /> +
diff --git a/src/components/ModalSettings.tsx b/src/components/ModalSettings.tsx index 1989c4c8..991e8804 100644 --- a/src/components/ModalSettings.tsx +++ b/src/components/ModalSettings.tsx @@ -156,6 +156,14 @@ class ModalSettingsInternal extends React.Component onChange={onChangeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")} /> + + ({ label: t("Thunderforest Access Token"), doc: t("Public access token for Thunderforest services.") }, + stadia_access_token: { + label: t("Stadia Maps API Key"), + doc: t("API key for Stadia Maps.") + }, style_renderer: { label: t("Style Renderer"), doc: t("Choose the default Maputnik renderer for this style."), diff --git a/src/libs/style.ts b/src/libs/style.ts index 1c71ae93..9192582b 100644 --- a/src/libs/style.ts +++ b/src/libs/style.ts @@ -55,10 +55,6 @@ function indexOfLayer(layers: LayerSpecification[], layerId: string) { } function getAccessToken(sourceName: string, mapStyle: StyleSpecification, opts: {allowFallback?: boolean}) { - if(sourceName === "thunderforest_transport" || sourceName === "thunderforest_outdoors") { - sourceName = "thunderforest" - } - const metadata = mapStyle.metadata || {} as any; let accessToken = metadata[`maputnik:${sourceName}_access_token`] @@ -74,7 +70,24 @@ function replaceSourceAccessToken(mapStyle: StyleSpecification, sourceName: stri if(!source) return mapStyle if(!("url" in source) || !source.url) return mapStyle - const accessToken = getAccessToken(sourceName, mapStyle, opts) + let authSourceName = sourceName + let setAccessToken = (url: string) => url.replace('{key}', accessToken) + if(sourceName === "thunderforest_transport" || sourceName === "thunderforest_outdoors") { + authSourceName = "thunderforest" + } + else if (("url" in source) && source.url?.match(/\.stadiamaps\.com/)) { + // A few weird things here worth commenting on... + // + // 1. The code currently assumes openmaptiles == MapTiler, + // so we need to check the source URL. + // 2. Stadia Maps does not always require an API key, + // so there is no placeholder in our styles. + // We append it at the end during exporting if necessary. + authSourceName = "stadia" + setAccessToken = (url: string) => `${url}?api_key=${accessToken}` + } + + const accessToken = getAccessToken(authSourceName, mapStyle, opts) if(!accessToken) { // Early exit. @@ -85,7 +98,7 @@ function replaceSourceAccessToken(mapStyle: StyleSpecification, sourceName: stri ...mapStyle.sources, [sourceName]: { ...source, - url: source.url.replace('{key}', accessToken) + url: setAccessToken(source.url) } } const changedStyle = { @@ -120,6 +133,8 @@ function stripAccessTokens(mapStyle: StyleSpecification) { ...mapStyle.metadata as any }; delete changedMetadata['maputnik:openmaptiles_access_token']; + delete changedMetadata['maputnik:thunderforest_access_token']; + delete changedMetadata['maputnik:stadia_access_token']; return { ...mapStyle, metadata: changedMetadata