Make layers config typesafe.
This commit is contained in:
parent
00d93c33b4
commit
59ef8256e6
|
@ -3,7 +3,15 @@ import commandLineUsage from "command-line-usage";
|
||||||
import fs from "graceful-fs";
|
import fs from "graceful-fs";
|
||||||
import url from "url";
|
import url from "url";
|
||||||
import { parse } from "sparkson";
|
import { parse } from "sparkson";
|
||||||
import { Config, hasOwnProperty, Url, Version } from "./types";
|
import {
|
||||||
|
Config,
|
||||||
|
hasOwnProperty,
|
||||||
|
isLayerConfig,
|
||||||
|
isPlainObject,
|
||||||
|
isString,
|
||||||
|
Url,
|
||||||
|
Version,
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
export let config: Config = {} as Config;
|
export let config: Config = {} as Config;
|
||||||
export let version: Version = "unknown" as Version;
|
export let version: Version = "unknown" as Version;
|
||||||
|
@ -89,6 +97,24 @@ export function parseCommandLine(): void {
|
||||||
|
|
||||||
config = parse(Config, configJSON);
|
config = parse(Config, configJSON);
|
||||||
|
|
||||||
|
if (!isPlainObject(config.client.coordsSelector.layers)) {
|
||||||
|
console.error(
|
||||||
|
"Error in config.json: client.coordsSelector.layers is not an JSON object."
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [id, layerConfig] of Object.entries(
|
||||||
|
config.client.coordsSelector.layers
|
||||||
|
)) {
|
||||||
|
if (!isLayerConfig(layerConfig)) {
|
||||||
|
console.error(
|
||||||
|
`Error in config.json: client.coordsSelector.layers[${id}] is not a valid layer config.`
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function stripTrailingSlash(url: Url): Url {
|
function stripTrailingSlash(url: Url): Url {
|
||||||
return url.endsWith("/")
|
return url.endsWith("/")
|
||||||
? (url.substring(0, url.length - 1) as Url)
|
? (url.substring(0, url.length - 1) as Url)
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
import { ArrayField, Field, RawJsonField } from "sparkson";
|
import {
|
||||||
|
ArrayField,
|
||||||
|
Field,
|
||||||
|
RawJsonField,
|
||||||
|
registerStringMapper,
|
||||||
|
} from "sparkson";
|
||||||
|
|
||||||
// Types shared with the client.
|
// Types shared with the client.
|
||||||
export type TypeGuard<T> = (arg: unknown) => arg is T;
|
export type TypeGuard<T> = (arg: unknown) => arg is T;
|
||||||
|
@ -282,12 +287,50 @@ export function isCoordinatesConfig(arg: unknown): arg is CoordinatesConfig {
|
||||||
return isNumber(coords.lat) && isNumber(coords.lng);
|
return isNumber(coords.lat) && isNumber(coords.lng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type LayerOptions = {
|
||||||
|
attribution: string;
|
||||||
|
subdomains?: string;
|
||||||
|
maxZoom: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function isLayerOptions(arg: unknown): arg is LayerOptions {
|
||||||
|
if (!isPlainObject(arg)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const obj = arg as LayerOptions;
|
||||||
|
return (
|
||||||
|
isString(obj.attribution) &&
|
||||||
|
isOptional(obj.subdomains, isString) &&
|
||||||
|
isNumber(obj.maxZoom)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LayerConfig = {
|
||||||
|
name: string;
|
||||||
|
url: Url;
|
||||||
|
type: string;
|
||||||
|
layerOptions: LayerOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function isLayerConfig(arg: unknown): arg is LayerConfig {
|
||||||
|
if (!isPlainObject(arg)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const obj = arg as LayerConfig;
|
||||||
|
return (
|
||||||
|
isString(obj.name) &&
|
||||||
|
isUrl(obj.url) &&
|
||||||
|
isString(obj.type) &&
|
||||||
|
isLayerOptions(obj.layerOptions)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export class CoordinatesSelectorConfig {
|
export class CoordinatesSelectorConfig {
|
||||||
constructor(
|
constructor(
|
||||||
@Field("lat") public lat: number,
|
@Field("lat") public lat: number,
|
||||||
@Field("lng") public lng: number,
|
@Field("lng") public lng: number,
|
||||||
@Field("defaultZoom") public defaultZoom: number,
|
@Field("defaultZoom") public defaultZoom: number,
|
||||||
@RawJsonField("layers") public layers: JSONObject
|
@RawJsonField("layers") public layers: Record<string, LayerConfig>
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue