refactor: native feature management (#2350)
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
import { EditorFeatureDescription } from './EditorFeatureDescription'
|
||||
import { ThemeFeatureDescription } from './ThemeFeatureDescription'
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
import { IframeComponentFeatureDescription } from './IframeComponentFeatureDescription'
|
||||
import { ClientFeatureDescription } from './ClientFeatureDescription'
|
||||
import { ServerFeatureDescription } from './ServerFeatureDescription'
|
||||
|
||||
export type AnyFeatureDescription =
|
||||
| ComponentFeatureDescription
|
||||
| EditorFeatureDescription
|
||||
| ThemeFeatureDescription
|
||||
| IframeComponentFeatureDescription
|
||||
| ClientFeatureDescription
|
||||
| ServerFeatureDescription
|
||||
@@ -0,0 +1,24 @@
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from './FeatureIdentifier'
|
||||
import { ComponentFlag } from '../Component/ComponentFlag'
|
||||
import { RoleFields } from './RoleFields'
|
||||
|
||||
export type BaseFeatureDescription = RoleFields & {
|
||||
deletion_warning?: string
|
||||
deprecated?: boolean
|
||||
deprecation_message?: string
|
||||
description?: string
|
||||
expires_at?: number
|
||||
|
||||
/** Whether the client controls availability of this feature (such as the dark theme) */
|
||||
clientControlled?: boolean
|
||||
|
||||
flags?: ComponentFlag[]
|
||||
identifier: FeatureIdentifier
|
||||
marketing_url?: string
|
||||
name: string
|
||||
no_expire?: boolean
|
||||
no_mobile?: boolean
|
||||
thumbnail_url?: string
|
||||
permission_name: PermissionName
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from './FeatureIdentifier'
|
||||
import { RoleFields } from './RoleFields'
|
||||
|
||||
export type ClientFeatureDescription = RoleFields & {
|
||||
identifier: FeatureIdentifier
|
||||
permission_name: PermissionName
|
||||
description: string
|
||||
name: string
|
||||
deprecated?: boolean
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { ComponentArea } from '../Component/ComponentArea'
|
||||
import { BaseFeatureDescription } from './BaseFeatureDescription'
|
||||
|
||||
export type ComponentFeatureDescription = BaseFeatureDescription & {
|
||||
/** The relative path of the index.html file or the main css file if theme, within the component folder itself */
|
||||
index_path: string
|
||||
content_type: string
|
||||
area: ComponentArea
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { NoteType } from '../Component/NoteType'
|
||||
import { BaseFeatureDescription } from './BaseFeatureDescription'
|
||||
|
||||
export type EditorFeatureDescription = BaseFeatureDescription & {
|
||||
file_type: 'txt' | 'html' | 'md' | 'json'
|
||||
/** Whether an editor is interchangable with another editor that has the same file_type */
|
||||
interchangeable: boolean
|
||||
note_type: NoteType
|
||||
spellcheckControl: boolean
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
import { ComponentPermission } from '../Component/ComponentPermission'
|
||||
import { ComponentArea } from '../Component/ComponentArea'
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from './FeatureIdentifier'
|
||||
import { ComponentFlag } from '../Component/ComponentFlag'
|
||||
import { NoteType } from '../Component/NoteType'
|
||||
import { ThemeDockIcon } from '../Component/ThemeDockIcon'
|
||||
|
||||
type RoleFields = {
|
||||
/** Server populated */
|
||||
role_name?: string
|
||||
|
||||
/** Statically populated. Non-influencing; used as a reference by other static consumers (such as email service) */
|
||||
availableInRoles: string[]
|
||||
}
|
||||
|
||||
export type BaseFeatureDescription = RoleFields & {
|
||||
deletion_warning?: string
|
||||
deprecated?: boolean
|
||||
deprecation_message?: string
|
||||
description?: string
|
||||
expires_at?: number
|
||||
|
||||
/** Whether the client controls availability of this feature (such as the dark theme) */
|
||||
clientControlled?: boolean
|
||||
|
||||
flags?: ComponentFlag[]
|
||||
identifier: FeatureIdentifier
|
||||
marketing_url?: string
|
||||
name?: string
|
||||
no_expire?: boolean
|
||||
no_mobile?: boolean
|
||||
thumbnail_url?: string
|
||||
permission_name: PermissionName
|
||||
}
|
||||
|
||||
export type ServerFeatureDescription = RoleFields & {
|
||||
name?: string
|
||||
identifier: FeatureIdentifier
|
||||
permission_name: PermissionName
|
||||
}
|
||||
|
||||
export type ClientFeatureDescription = RoleFields & {
|
||||
identifier: FeatureIdentifier
|
||||
permission_name: PermissionName
|
||||
description: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export type ComponentFeatureDescription = BaseFeatureDescription & {
|
||||
/** The relative path of the index.html file or the main css file if theme, within the component folder itself */
|
||||
index_path: string
|
||||
content_type: string
|
||||
area: ComponentArea
|
||||
}
|
||||
|
||||
export type ThirdPartyFeatureDescription = ComponentFeatureDescription & {
|
||||
url: string
|
||||
}
|
||||
|
||||
export type IframeComponentFeatureDescription = ComponentFeatureDescription & {
|
||||
component_permissions: ComponentPermission[]
|
||||
}
|
||||
|
||||
export type EditorFeatureDescription = IframeComponentFeatureDescription & {
|
||||
file_type: 'txt' | 'html' | 'md' | 'json'
|
||||
/** Whether an editor is interchangable with another editor that has the same file_type */
|
||||
interchangeable: boolean
|
||||
note_type: NoteType
|
||||
spellcheckControl?: boolean
|
||||
}
|
||||
|
||||
export type ThemeFeatureDescription = ComponentFeatureDescription & {
|
||||
/** Some themes can be layered on top of other themes */
|
||||
layerable?: boolean
|
||||
dock_icon?: ThemeDockIcon
|
||||
isDark?: boolean
|
||||
}
|
||||
|
||||
export type FeatureDescription = BaseFeatureDescription &
|
||||
Partial<ComponentFeatureDescription & EditorFeatureDescription & ThemeFeatureDescription>
|
||||
@@ -1,14 +1,51 @@
|
||||
import { FeatureDescription } from './FeatureDescription'
|
||||
import { AnyFeatureDescription } from './AnyFeatureDescription'
|
||||
import { ThemeFeatureDescription } from './ThemeFeatureDescription'
|
||||
import { EditorFeatureDescription } from './EditorFeatureDescription'
|
||||
import { FeatureIdentifier } from './FeatureIdentifier'
|
||||
import { serverFeatures } from '../Lists/ServerFeatures'
|
||||
import { clientFeatures } from '../Lists/ClientFeatures'
|
||||
import { GetDeprecatedFeatures } from '../Lists/DeprecatedFeatures'
|
||||
import { experimentalFeatures } from '../Lists/ExperimentalFeatures'
|
||||
import { IframeEditors } from '../Lists/IframeEditors'
|
||||
import { themes } from '../Lists/Themes'
|
||||
import { nativeEditors } from '../Lists/NativeEditors'
|
||||
|
||||
export function GetFeatures(): FeatureDescription[] {
|
||||
return [...serverFeatures(), ...clientFeatures(), ...experimentalFeatures(), ...GetDeprecatedFeatures()]
|
||||
export function GetFeatures(): AnyFeatureDescription[] {
|
||||
return [
|
||||
...serverFeatures(),
|
||||
...clientFeatures(),
|
||||
...themes(),
|
||||
...nativeEditors(),
|
||||
...IframeEditors(),
|
||||
...experimentalFeatures(),
|
||||
...GetDeprecatedFeatures(),
|
||||
]
|
||||
}
|
||||
|
||||
export function FindNativeFeature(identifier: FeatureIdentifier): FeatureDescription | undefined {
|
||||
return GetFeatures().find((f) => f.identifier === identifier)
|
||||
export function FindNativeFeature<T extends AnyFeatureDescription>(identifier: FeatureIdentifier): T | undefined {
|
||||
return GetFeatures().find((f) => f.identifier === identifier) as T
|
||||
}
|
||||
|
||||
export function FindNativeTheme(identifier: FeatureIdentifier): ThemeFeatureDescription | undefined {
|
||||
return themes().find((t) => t.identifier === identifier)
|
||||
}
|
||||
|
||||
export function GetIframeAndNativeEditors(): EditorFeatureDescription[] {
|
||||
return [...IframeEditors(), ...nativeEditors()]
|
||||
}
|
||||
|
||||
export function GetSuperNoteFeature(): EditorFeatureDescription {
|
||||
return FindNativeFeature(FeatureIdentifier.SuperEditor) as EditorFeatureDescription
|
||||
}
|
||||
|
||||
export function GetPlainNoteFeature(): EditorFeatureDescription {
|
||||
return FindNativeFeature(FeatureIdentifier.PlainEditor) as EditorFeatureDescription
|
||||
}
|
||||
|
||||
export function GetNativeThemes(): ThemeFeatureDescription[] {
|
||||
return themes()
|
||||
}
|
||||
|
||||
export function GetDarkThemeFeature(): ThemeFeatureDescription {
|
||||
return themes().find((t) => t.identifier === FeatureIdentifier.DarkTheme) as ThemeFeatureDescription
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { ComponentPermission } from '../Component/ComponentPermission'
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
import { EditorFeatureDescription } from './EditorFeatureDescription'
|
||||
|
||||
export type IframeComponentFeatureDescription = (EditorFeatureDescription & ComponentFeatureDescription) & {
|
||||
component_permissions: ComponentPermission[]
|
||||
}
|
||||
7
packages/features/src/Domain/Feature/RoleFields.ts
Normal file
7
packages/features/src/Domain/Feature/RoleFields.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export type RoleFields = {
|
||||
/** Server populated */
|
||||
role_name?: string
|
||||
|
||||
/** Statically populated. Non-influencing; used as a reference by other static consumers (such as email service) */
|
||||
availableInRoles: string[]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from './FeatureIdentifier'
|
||||
import { RoleFields } from './RoleFields'
|
||||
|
||||
export type ServerFeatureDescription = RoleFields & {
|
||||
name: string
|
||||
description?: string
|
||||
identifier: FeatureIdentifier
|
||||
permission_name: PermissionName
|
||||
deprecated?: boolean
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { ThemeDockIcon } from '../Component/ThemeDockIcon'
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
|
||||
export type ThemeFeatureDescription = ComponentFeatureDescription & {
|
||||
/** Some themes can be layered on top of other themes */
|
||||
layerable?: boolean
|
||||
dock_icon?: ThemeDockIcon
|
||||
isDark?: boolean
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
|
||||
export type ThirdPartyFeatureDescription = ComponentFeatureDescription & {
|
||||
url: string
|
||||
}
|
||||
28
packages/features/src/Domain/Feature/TypeGuards.ts
Normal file
28
packages/features/src/Domain/Feature/TypeGuards.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
import { AnyFeatureDescription } from './AnyFeatureDescription'
|
||||
import { ThemeFeatureDescription } from './ThemeFeatureDescription'
|
||||
import { EditorFeatureDescription } from './EditorFeatureDescription'
|
||||
import { IframeComponentFeatureDescription } from './IframeComponentFeatureDescription'
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
import { ComponentArea } from '../Component/ComponentArea'
|
||||
|
||||
export function isThemeFeatureDescription(feature: AnyFeatureDescription): feature is ThemeFeatureDescription {
|
||||
return 'content_type' in feature && feature.content_type === ContentType.TYPES.Theme
|
||||
}
|
||||
|
||||
export function isIframeComponentFeatureDescription(
|
||||
feature: AnyFeatureDescription,
|
||||
): feature is IframeComponentFeatureDescription {
|
||||
return (
|
||||
'content_type' in feature &&
|
||||
feature.content_type === ContentType.TYPES.Component &&
|
||||
[ComponentArea.Editor, ComponentArea.EditorStack].includes(feature.area)
|
||||
)
|
||||
}
|
||||
|
||||
export function isEditorFeatureDescription(feature: AnyFeatureDescription): feature is EditorFeatureDescription {
|
||||
return (
|
||||
(feature as EditorFeatureDescription).note_type != undefined ||
|
||||
(feature as ComponentFeatureDescription).area === ComponentArea.Editor
|
||||
)
|
||||
}
|
||||
10
packages/features/src/Domain/Feature/UIFeatureDescription.ts
Normal file
10
packages/features/src/Domain/Feature/UIFeatureDescription.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
import { EditorFeatureDescription } from './EditorFeatureDescription'
|
||||
import { IframeComponentFeatureDescription } from './IframeComponentFeatureDescription'
|
||||
import { ThemeFeatureDescription } from './ThemeFeatureDescription'
|
||||
|
||||
export type UIFeatureDescriptionTypes =
|
||||
| IframeComponentFeatureDescription
|
||||
| ThemeFeatureDescription
|
||||
| EditorFeatureDescription
|
||||
| ComponentFeatureDescription
|
||||
Reference in New Issue
Block a user