terriajs
Version:
Geospatial data visualization platform.
113 lines (98 loc) • 3.22 kB
text/typescript
import i18next from "i18next";
import { isJsonObject, JsonObject } from "../Core/Json";
import loadJson from "../Core/loadJson";
import loadWithXhr from "../Core/loadWithXhr";
import TerriaError from "../Core/TerriaError";
import Terria from "./Terria";
export const DEFAULT_MAX_SHARE_SIZE = 200 * 1024; // 200 KB
interface ShareDataServiceOptions {
terria: Terria;
url?: string;
}
/**
* Interface to the terriajs-server service for creating short share links.
* @param {*} options
*
* @alias ShareDataService
* @constructor
*/
export default class ShareDataService {
readonly terria: Terria;
url: string | undefined;
private _serverConfig: any;
constructor(options: ShareDataServiceOptions) {
this.terria = options.terria;
this.url = options.url;
}
init(serverConfig: any): void {
this.url = this.url ?? this.terria.configParameters.shareUrl ?? "share";
this._serverConfig = serverConfig;
}
get isUsable(): boolean {
return (
(this.url !== undefined &&
typeof this._serverConfig === "object" &&
typeof this._serverConfig.newShareUrlPrefix === "string") ||
this.url !== "share"
);
}
// get the raw string from serverConfig.shareMaxRequestSize
get shareMaxRequestSize(): string | undefined {
return this._serverConfig.shareMaxRequestSize;
}
// get the parsed value in bytes from the server
get shareMaxRequestSizeBytes(): number | undefined {
return this._serverConfig.shareMaxRequestSizeBytes;
}
/**
* Allocates a share token using Terria Server, storing the provided data there.
* @param shareData JSON to store.
* @return A promise for the token (which can later be resolved at /share/TOKEN).
*/
async getShareToken(shareData: any): Promise<string> {
if (!this.isUsable) {
throw TerriaError.from("`ShareDataService` is not usable");
}
try {
const result = await loadWithXhr({
url: this.url!,
method: "POST",
data: JSON.stringify(shareData),
headers: { "Content-Type": "application/json" },
responseType: "json"
});
const json = typeof result === "string" ? JSON.parse(result) : result;
return json.id;
} catch (error) {
throw TerriaError.from(error, {
title: i18next.t("models.shareData.generateErrorTitle"),
message: i18next.t("models.shareData.generateErrorMessage"),
importance: 1
});
}
}
async resolveData(token: string): Promise<JsonObject> {
if (!this.isUsable) {
throw TerriaError.from("`ShareDataService` is not usable");
}
try {
const shareJson = await loadJson(this.url + "/" + token);
if (!isJsonObject(shareJson, false)) {
throw TerriaError.from(
`Invalid server response for share ${
this.url + "/" + token
}\n\`${JSON.stringify(shareJson)}\``
);
}
return shareJson;
} catch (error) {
throw TerriaError.from(error, {
title: i18next.t("models.shareData.expandErrorTitle"),
message: i18next.t("models.shareData.expandErrorMessage", {
appName: this.terria.appName
}),
importance: 1
});
}
}
}