Use & enforce snake_case naming convention on config.json settings (#8062)
* Document and support the established naming convention for config opts This change: * Rename `ConfigOptions` to `IConfigOptions` to match code convention/style, plus move it to a dedicated file * Update comments and surrounding documentation * Define every single documented option (from element-web's config.md) * Enable a linter to enforce the convention * Invent a translation layer for a different change to use * No attempt to fix build errors from doing this (at this stage) * Add demo of lint rule in action * Fix all obvious instances of SdkConfig case conflicts * Fix tests to use SdkConfig directly * Add docs to make unset() calling safer * Appease the linter * Update documentation to match snake_case_config * Fix more instances of square brackets off SdkConfig
This commit is contained in:
parent
09c57b228e
commit
d8a939df5d
56 changed files with 605 additions and 259 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
Copyright 2019 - 2021 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019 - 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -15,39 +15,26 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
export interface ISsoRedirectOptions {
|
||||
immediate?: boolean;
|
||||
on_welcome_page?: boolean; // eslint-disable-line camelcase
|
||||
}
|
||||
import { Optional } from "matrix-events-sdk";
|
||||
|
||||
/* eslint-disable camelcase */
|
||||
export interface ConfigOptions {
|
||||
[key: string]: any;
|
||||
import { SnakedObject } from "./utils/SnakedObject";
|
||||
import { IConfigOptions, ISsoRedirectOptions } from "./IConfigOptions";
|
||||
import { KeysWithObjectShape } from "./@types/common";
|
||||
|
||||
logout_redirect_url?: string;
|
||||
|
||||
// sso_immediate_redirect is deprecated in favour of sso_redirect_options.immediate
|
||||
sso_immediate_redirect?: boolean;
|
||||
sso_redirect_options?: ISsoRedirectOptions;
|
||||
|
||||
custom_translations_url?: string;
|
||||
}
|
||||
/* eslint-enable camelcase*/
|
||||
|
||||
export const DEFAULTS: ConfigOptions = {
|
||||
// Brand name of the app
|
||||
// see element-web config.md for docs, or the IConfigOptions interface for dev docs
|
||||
export const DEFAULTS: Partial<IConfigOptions> = {
|
||||
brand: "Element",
|
||||
// URL to a page we show in an iframe to configure integrations
|
||||
integrations_ui_url: "https://scalar.vector.im/",
|
||||
// Base URL to the REST interface of the integrations server
|
||||
integrations_rest_url: "https://scalar.vector.im/api",
|
||||
// Where to send bug reports. If not specified, bugs cannot be sent.
|
||||
bug_report_endpoint_url: null,
|
||||
// Jitsi conference options
|
||||
jitsi: {
|
||||
// Default conference domain
|
||||
preferredDomain: "meet.element.io",
|
||||
preferred_domain: "meet.element.io",
|
||||
},
|
||||
|
||||
// @ts-ignore - we deliberately use the camelCase version here so we trigger
|
||||
// the fallback behaviour. If we used the snake_case version then we'd break
|
||||
// everyone's config which has the camelCase property because our default would
|
||||
// be preferred over their config.
|
||||
desktopBuilds: {
|
||||
available: true,
|
||||
logo: require("../res/img/element-desktop-logo.svg").default,
|
||||
|
@ -56,20 +43,42 @@ export const DEFAULTS: ConfigOptions = {
|
|||
};
|
||||
|
||||
export default class SdkConfig {
|
||||
private static instance: ConfigOptions;
|
||||
private static instance: IConfigOptions;
|
||||
private static fallback: SnakedObject<IConfigOptions>;
|
||||
|
||||
private static setInstance(i: ConfigOptions) {
|
||||
private static setInstance(i: IConfigOptions) {
|
||||
SdkConfig.instance = i;
|
||||
SdkConfig.fallback = new SnakedObject(i);
|
||||
|
||||
// For debugging purposes
|
||||
window.mxReactSdkConfig = i;
|
||||
}
|
||||
|
||||
public static get() {
|
||||
return SdkConfig.instance || {};
|
||||
public static get(): IConfigOptions;
|
||||
public static get<K extends keyof IConfigOptions>(key: K, altCaseName?: string): IConfigOptions[K];
|
||||
public static get<K extends keyof IConfigOptions = never>(
|
||||
key?: K, altCaseName?: string,
|
||||
): IConfigOptions | IConfigOptions[K] {
|
||||
if (key === undefined) {
|
||||
// safe to cast as a fallback - we want to break the runtime contract in this case
|
||||
return SdkConfig.instance || <IConfigOptions>{};
|
||||
}
|
||||
return SdkConfig.fallback.get(key, altCaseName);
|
||||
}
|
||||
|
||||
public static put(cfg: ConfigOptions) {
|
||||
public static getObject<K extends KeysWithObjectShape<IConfigOptions>>(
|
||||
key: K, altCaseName?: string,
|
||||
): Optional<SnakedObject<IConfigOptions[K]>> {
|
||||
const val = SdkConfig.get(key, altCaseName);
|
||||
if (val !== null && val !== undefined) {
|
||||
return new SnakedObject(val);
|
||||
}
|
||||
|
||||
// return the same type for sensitive callers (some want `undefined` specifically)
|
||||
return val === undefined ? undefined : null;
|
||||
}
|
||||
|
||||
public static put(cfg: IConfigOptions) {
|
||||
const defaultKeys = Object.keys(DEFAULTS);
|
||||
for (let i = 0; i < defaultKeys.length; ++i) {
|
||||
if (cfg[defaultKeys[i]] === undefined) {
|
||||
|
@ -79,18 +88,21 @@ export default class SdkConfig {
|
|||
SdkConfig.setInstance(cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the config to be completely empty.
|
||||
*/
|
||||
public static unset() {
|
||||
SdkConfig.setInstance({});
|
||||
SdkConfig.setInstance(<IConfigOptions>{}); // safe to cast - defaults will be applied
|
||||
}
|
||||
|
||||
public static add(cfg: ConfigOptions) {
|
||||
public static add(cfg: Partial<IConfigOptions>) {
|
||||
const liveConfig = SdkConfig.get();
|
||||
const newConfig = Object.assign({}, liveConfig, cfg);
|
||||
SdkConfig.put(newConfig);
|
||||
}
|
||||
}
|
||||
|
||||
export function parseSsoRedirectOptions(config: ConfigOptions): ISsoRedirectOptions {
|
||||
export function parseSsoRedirectOptions(config: IConfigOptions): ISsoRedirectOptions {
|
||||
// Ignore deprecated options if the config is using new ones
|
||||
if (config.sso_redirect_options) return config.sso_redirect_options;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue