fix(map): accept canonical gateway endpoints

This commit is contained in:
Codex
2026-07-29 17:24:46 +03:00
parent c293d748f5
commit bc1c0dd6e6
4 changed files with 132 additions and 44 deletions
@@ -7,6 +7,10 @@ import type {
MapProviderId,
MapRuntimeState,
} from "./contracts.js";
import {
parseProviderEndpoint,
type ProviderEndpoint,
} from "./providerEndpoint.js";
import {
MapRuntimeError,
applyCacheIntent,
@@ -18,19 +22,6 @@ import {
} from "./runtime.js";
type CesiumNamespace = typeof CesiumModule;
type ProviderEndpoint = {
assetId: number;
type: "IMAGERY" | "TERRAIN" | "3DTILES";
externalType?: "BING";
credentialMode: "gateway";
url?: string;
options?: {
url?: string;
mapStyle?: string;
};
attributions?: readonly unknown[];
};
export function CesiumMapRenderer({
runtimeConfigUrl,
camera,
@@ -239,29 +230,7 @@ async function fetchProviderEndpoint(
signal,
);
const expectedAssetId = configuration.assets[providerId];
const expectedType =
providerId === "imagery"
? "IMAGERY"
: providerId === "terrain"
? "TERRAIN"
: "3DTILES";
if (
document.assetId !== expectedAssetId ||
document.type !== expectedType ||
document.credentialMode !== "gateway"
) {
throw new MapRuntimeError("map_provider_contract_mismatch");
}
if (
(providerId === "imagery" &&
(document.externalType !== "BING" ||
!isEndpointOptions(document.options) ||
typeof document.options.url !== "string")) ||
(providerId !== "imagery" && typeof document.url !== "string")
) {
throw new MapRuntimeError("map_provider_contract_mismatch");
}
return document as ProviderEndpoint;
return parseProviderEndpoint(document, expectedAssetId, providerId);
}
async function attachProvider(
@@ -285,8 +254,12 @@ async function attachProvider(
});
if (providerId === "imagery") {
const provider = await Cesium.BingMapsImageryProvider.fromUrl(resource, {
key: "gateway-proxy",
// Cesium requires a key-shaped value to build Bing metadata and tile
// URLs. This is a public marker, not a credential: Map Gateway strips
// it and injects the server-owned provider key upstream.
key: "nodedc-gateway",
mapStyle: bingMapStyle(Cesium, endpoint.options?.mapStyle),
tileProtocol: "https",
});
const layer = viewer.imageryLayers.addImageryProvider(provider);
if (settings.monochrome_enabled) {
@@ -386,12 +359,6 @@ function safeErrorCode(error: unknown): string {
return error instanceof MapRuntimeError ? error.code : "map_provider_unavailable";
}
function isEndpointOptions(
value: unknown,
): value is NonNullable<ProviderEndpoint["options"]> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function tokenColor(
Cesium: CesiumNamespace,
container: HTMLElement,
@@ -0,0 +1,52 @@
import type { MapProviderId } from "./contracts.js";
import { MapRuntimeError } from "./runtime.js";
export type ProviderEndpoint = {
assetId: string;
type: "IMAGERY" | "TERRAIN" | "3DTILES";
externalType?: "BING";
credentialMode: "gateway";
url?: string;
options?: {
url?: string;
mapStyle?: string;
};
attributions: readonly unknown[];
};
export function parseProviderEndpoint(
document: Record<string, unknown>,
expectedAssetId: number,
providerId: MapProviderId,
): ProviderEndpoint {
const expectedType =
providerId === "imagery"
? "IMAGERY"
: providerId === "terrain"
? "TERRAIN"
: "3DTILES";
if (
document.assetId !== String(expectedAssetId) ||
document.type !== expectedType ||
document.credentialMode !== "gateway" ||
!Array.isArray(document.attributions)
) {
throw new MapRuntimeError("map_provider_contract_mismatch");
}
if (
(providerId === "imagery" &&
(document.externalType !== "BING" ||
!isEndpointOptions(document.options) ||
typeof document.options.url !== "string")) ||
(providerId !== "imagery" && typeof document.url !== "string")
) {
throw new MapRuntimeError("map_provider_contract_mismatch");
}
return document as ProviderEndpoint;
}
function isEndpointOptions(
value: unknown,
): value is NonNullable<ProviderEndpoint["options"]> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}