[core] added typescript decorators (experimental)
This commit is contained in:
@@ -17,13 +17,15 @@
|
||||
// import React, { createContext, useContext, useState, FC } from 'react';
|
||||
import { FeatureFlagName } from '../plugin/types';
|
||||
import { FeatureFlagsApi } from '../apis/definitions/featureFlags';
|
||||
import { staticImplements } from '../../testUtils';
|
||||
|
||||
// TODO: figure out where to put implementations of APIs, both inside apps
|
||||
// but also in core/separate package.
|
||||
export class FeatureFlags implements FeatureFlagsApi {
|
||||
@staticImplements<FeatureFlagsApi>()
|
||||
export class FeatureFlags {
|
||||
private static readonly localStorageKey = 'featureFlags';
|
||||
|
||||
private static getEnabledFeatureFlags(): Set<FeatureFlagName> {
|
||||
private static getUserEnabledFeatureFlags(): Set<FeatureFlagName> {
|
||||
if (!('localStorage' in window)) {
|
||||
throw new Error(
|
||||
'Feature Flags are not supported on browsers without the Local Storage API',
|
||||
@@ -40,7 +42,9 @@ export class FeatureFlags implements FeatureFlagsApi {
|
||||
}
|
||||
}
|
||||
|
||||
private static saveFeatureFlags(flags: Set<FeatureFlagName>): void {
|
||||
private static saveUserEnabledFeatureFlags(
|
||||
flags: Set<FeatureFlagName>,
|
||||
): void {
|
||||
if (!('localStorage' in window)) {
|
||||
throw new Error(
|
||||
'Feature Flags are not supported on browsers without the Local Storage API',
|
||||
@@ -56,18 +60,18 @@ export class FeatureFlags implements FeatureFlagsApi {
|
||||
}
|
||||
|
||||
static getItem(name: FeatureFlagName): boolean {
|
||||
return this.getFeatureFlags().has(name);
|
||||
return this.getUserEnabledFeatureFlags().has(name);
|
||||
}
|
||||
|
||||
static enable(name: FeatureFlagName): void {
|
||||
const flags = this.getFeatureFlags();
|
||||
const flags = this.getUserEnabledFeatureFlags();
|
||||
flags.add(name);
|
||||
this.saveFeatureFlags(flags);
|
||||
this.saveUserEnabledFeatureFlags(flags);
|
||||
}
|
||||
|
||||
static disable(name: FeatureFlagName): void {
|
||||
const flags = this.getFeatureFlags();
|
||||
const flags = this.getUserEnabledFeatureFlags();
|
||||
flags.delete(name);
|
||||
this.saveFeatureFlags(flags);
|
||||
this.saveUserEnabledFeatureFlags(flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This utilizes an experimental TypeScript feature called decorators.
|
||||
* This was originally added to allow us to expose a FeatureFlags API
|
||||
* with static methods (for backwards compatibility primarily). It takes
|
||||
* an existing interface and applies the types to static methods in classes.
|
||||
*
|
||||
* @see https://www.typescriptlang.org/docs/handbook/decorators.html
|
||||
* @example
|
||||
* interface StaticProps {
|
||||
* append(name: string, extra: string): string;
|
||||
* reverse(name: string): string;
|
||||
* }
|
||||
*
|
||||
* @staticImplements<StaticProps>()
|
||||
* class StaticPropsClass {
|
||||
* static append(name, extra) {
|
||||
* return `${name}${extra}`;
|
||||
* }
|
||||
*
|
||||
* static reverse(name) {
|
||||
* return name.reverse();
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
export function staticImplements<T>() {
|
||||
return <U extends T>(constructor: U) => {
|
||||
constructor;
|
||||
};
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import { render } from '@testing-library/react';
|
||||
export { default as Keyboard } from './Keyboard';
|
||||
export { default as mockBreakpoint } from './mockBreakpoint';
|
||||
export * from './logCollector';
|
||||
export * from './decorators';
|
||||
|
||||
export function wrapInTestApp(Component, initialRouterEntries) {
|
||||
const Wrapper = Component instanceof Function ? Component : () => Component;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["src"],
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": false
|
||||
"noImplicitAny": false,
|
||||
"experimentalDecorators": true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user