diff --git a/.changeset/ten-houses-attack.md b/.changeset/ten-houses-attack.md new file mode 100644 index 0000000000..9bb1ad2565 --- /dev/null +++ b/.changeset/ten-houses-attack.md @@ -0,0 +1,15 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +'@backstage/plugin-scaffolder-backend-module-rails': patch +'@backstage/plugin-permission-backend': patch +'@backstage/plugin-permission-common': patch +'@backstage/core-components': patch +'@backstage/core-plugin-api': patch +'@backstage/plugin-devtools-common': patch +'@backstage/plugin-search-backend': patch +'@backstage/core-app-api': patch +'@backstage/plugin-catalog-graph': patch +'@backstage/cli': patch +--- + +Convert all enums to erasable-syntax compliant patterns diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index f4091717b5..d4d66391b4 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -568,3 +568,4 @@ Zolotusky zoomable zsh resizable +enums diff --git a/packages/cli/src/modules/build/lib/builder/types.ts b/packages/cli/src/modules/build/lib/builder/types.ts index 937bd157c9..f80d0d1306 100644 --- a/packages/cli/src/modules/build/lib/builder/types.ts +++ b/packages/cli/src/modules/build/lib/builder/types.ts @@ -13,13 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ import { BackstagePackage, BackstagePackageJson } from '@backstage/cli-node'; -export enum Output { - esm, - cjs, - types, +export const Output = { + esm: 0, + cjs: 1, + types: 2, +} as const; + +/** + * @public + */ +export type Output = (typeof Output)[keyof typeof Output]; + +/** + * @public + */ +export namespace Output { + export type esm = typeof Output.esm; + export type cjs = typeof Output.cjs; + export type types = typeof Output.types; } export type BuildOptions = { diff --git a/packages/core-app-api/src/apis/system/ApiFactoryRegistry.ts b/packages/core-app-api/src/apis/system/ApiFactoryRegistry.ts index 5f56793cae..1824937a02 100644 --- a/packages/core-app-api/src/apis/system/ApiFactoryRegistry.ts +++ b/packages/core-app-api/src/apis/system/ApiFactoryRegistry.ts @@ -31,11 +31,11 @@ export type ApiFactoryScope = | 'app' // Factories registered in the app, overriding default ones | 'static'; // APIs that can't be overridden, e.g. config -enum ScopePriority { - default = 10, - app = 50, - static = 100, -} +const ScopePriority = { + default: 10, + app: 50, + static: 100, +} as const; type FactoryTuple = { priority: number; diff --git a/packages/core-components/report.api.md b/packages/core-components/report.api.md index 9c9992deff..02fbb04805 100644 --- a/packages/core-components/report.api.md +++ b/packages/core-components/report.api.md @@ -283,11 +283,18 @@ export interface DependencyGraphProps // @public export namespace DependencyGraphTypes { - export enum Alignment { - DOWN_LEFT = 'DL', - DOWN_RIGHT = 'DR', - UP_LEFT = 'UL', - UP_RIGHT = 'UR', + // (undocumented) + export type Alignment = (typeof Alignment)[keyof typeof Alignment]; + // (undocumented) + export namespace Alignment { + // (undocumented) + export type DOWN_LEFT = typeof Alignment.DOWN_LEFT; + // (undocumented) + export type DOWN_RIGHT = typeof Alignment.DOWN_RIGHT; + // (undocumented) + export type UP_LEFT = typeof Alignment.UP_LEFT; + // (undocumented) + export type UP_RIGHT = typeof Alignment.UP_RIGHT; } export type DependencyEdge = T & { from: string; @@ -298,25 +305,54 @@ export namespace DependencyGraphTypes { export type DependencyNode = T & { id: string; }; - export enum Direction { - BOTTOM_TOP = 'BT', - LEFT_RIGHT = 'LR', - RIGHT_LEFT = 'RL', - TOP_BOTTOM = 'TB', - } - export enum LabelPosition { + // (undocumented) + export type Direction = (typeof Direction)[keyof typeof Direction]; + // (undocumented) + export namespace Direction { // (undocumented) - CENTER = 'c', + export type BOTTOM_TOP = typeof Direction.BOTTOM_TOP; // (undocumented) - LEFT = 'l', + export type LEFT_RIGHT = typeof Direction.LEFT_RIGHT; // (undocumented) - RIGHT = 'r', + export type RIGHT_LEFT = typeof Direction.RIGHT_LEFT; + // (undocumented) + export type TOP_BOTTOM = typeof Direction.TOP_BOTTOM; } - export enum Ranker { - LONGEST_PATH = 'longest-path', - NETWORK_SIMPLEX = 'network-simplex', - TIGHT_TREE = 'tight-tree', + // (undocumented) + export type LabelPosition = + (typeof LabelPosition)[keyof typeof LabelPosition]; + // (undocumented) + export namespace LabelPosition { + // (undocumented) + export type CENTER = typeof LabelPosition.CENTER; + // (undocumented) + export type LEFT = typeof LabelPosition.LEFT; + // (undocumented) + export type RIGHT = typeof LabelPosition.RIGHT; } + const Direction: { + readonly TOP_BOTTOM: 'TB'; + readonly BOTTOM_TOP: 'BT'; + readonly LEFT_RIGHT: 'LR'; + readonly RIGHT_LEFT: 'RL'; + }; + // (undocumented) + export type Ranker = (typeof Ranker)[keyof typeof Ranker]; + // (undocumented) + export namespace Ranker { + // (undocumented) + export type LONGEST_PATH = typeof Ranker.LONGEST_PATH; + // (undocumented) + export type NETWORK_SIMPLEX = typeof Ranker.NETWORK_SIMPLEX; + // (undocumented) + export type TIGHT_TREE = typeof Ranker.TIGHT_TREE; + } + const Alignment: { + readonly UP_LEFT: 'UL'; + readonly UP_RIGHT: 'UR'; + readonly DOWN_LEFT: 'DL'; + readonly DOWN_RIGHT: 'DR'; + }; export type RenderEdgeFunction = ( props: RenderEdgeProps, ) => ReactNode; @@ -344,12 +380,22 @@ export namespace DependencyGraphTypes { name?: string | undefined; }; }; + const Ranker: { + readonly NETWORK_SIMPLEX: 'network-simplex'; + readonly TIGHT_TREE: 'tight-tree'; + readonly LONGEST_PATH: 'longest-path'; + }; export type RenderLabelFunction = ( props: RenderLabelProps, ) => ReactNode; export type RenderLabelProps = { edge: DependencyEdge; }; + const LabelPosition: { + readonly LEFT: 'l'; + readonly RIGHT: 'r'; + readonly CENTER: 'c'; + }; export type RenderNodeFunction = ( props: RenderNodeProps, ) => ReactNode; diff --git a/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx b/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx index 4b99402c3a..a4ef0ac682 100644 --- a/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx +++ b/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx @@ -79,7 +79,7 @@ export interface DependencyGraphProps */ nodes: Types.DependencyNode[]; /** - * Graph {@link DependencyGraphTypes.Direction | direction} + * Graph {@link DependencyGraphTypes.(Direction:namespace) | direction} * * @remarks * @@ -87,7 +87,7 @@ export interface DependencyGraphProps */ direction?: Types.Direction; /** - * Node {@link DependencyGraphTypes.Alignment | alignment} + * Node {@link DependencyGraphTypes.(Alignment:namespace) | alignment} */ align?: Types.Alignment; /** @@ -135,7 +135,7 @@ export interface DependencyGraphProps */ acyclicer?: 'greedy'; /** - * {@link DependencyGraphTypes.Ranker | Algorithm} used to rank nodes + * {@link DependencyGraphTypes.(Ranker:namespace) | Algorithm} used to rank nodes * * @remarks * @@ -143,7 +143,7 @@ export interface DependencyGraphProps */ ranker?: Types.Ranker; /** - * {@link DependencyGraphTypes.LabelPosition | Position} of label in relation to edge + * {@link DependencyGraphTypes.(LabelPosition:namespace) | Position} of label in relation to edge * * @remarks * diff --git a/packages/core-components/src/components/DependencyGraph/types.ts b/packages/core-components/src/components/DependencyGraph/types.ts index 4436f8d1aa..6a75df27b5 100644 --- a/packages/core-components/src/components/DependencyGraph/types.ts +++ b/packages/core-components/src/components/DependencyGraph/types.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ /** * Types used to customize and provide data to {@link DependencyGraph} @@ -134,23 +136,38 @@ export namespace DependencyGraphTypes { * * @public */ - export enum Direction { + export const Direction = { /** * Top to Bottom */ - TOP_BOTTOM = 'TB', + TOP_BOTTOM: 'TB', /** * Bottom to Top */ - BOTTOM_TOP = 'BT', + BOTTOM_TOP: 'BT', /** * Left to Right */ - LEFT_RIGHT = 'LR', + LEFT_RIGHT: 'LR', /** * Right to Left */ - RIGHT_LEFT = 'RL', + RIGHT_LEFT: 'RL', + } as const; + + /** + * @public + */ + export type Direction = (typeof Direction)[keyof typeof Direction]; + + /** + * @public + */ + export namespace Direction { + export type TOP_BOTTOM = typeof Direction.TOP_BOTTOM; + export type BOTTOM_TOP = typeof Direction.BOTTOM_TOP; + export type LEFT_RIGHT = typeof Direction.LEFT_RIGHT; + export type RIGHT_LEFT = typeof Direction.RIGHT_LEFT; } /** @@ -158,23 +175,38 @@ export namespace DependencyGraphTypes { * * @public */ - export enum Alignment { + export const Alignment = { /** * Up Left */ - UP_LEFT = 'UL', + UP_LEFT: 'UL', /** * Up Right */ - UP_RIGHT = 'UR', + UP_RIGHT: 'UR', /** * Down Left */ - DOWN_LEFT = 'DL', + DOWN_LEFT: 'DL', /** * Down Right */ - DOWN_RIGHT = 'DR', + DOWN_RIGHT: 'DR', + } as const; + + /** + * @public + */ + export type Alignment = (typeof Alignment)[keyof typeof Alignment]; + + /** + * @public + */ + export namespace Alignment { + export type UP_LEFT = typeof Alignment.UP_LEFT; + export type UP_RIGHT = typeof Alignment.UP_RIGHT; + export type DOWN_LEFT = typeof Alignment.DOWN_LEFT; + export type DOWN_RIGHT = typeof Alignment.DOWN_RIGHT; } /** @@ -182,15 +214,15 @@ export namespace DependencyGraphTypes { * * @public */ - export enum Ranker { + export const Ranker = { /** * {@link https://en.wikipedia.org/wiki/Network_simplex_algorithm | Network Simplex} algorithm */ - NETWORK_SIMPLEX = 'network-simplex', + NETWORK_SIMPLEX: 'network-simplex', /** * Tight Tree algorithm */ - TIGHT_TREE = 'tight-tree', + TIGHT_TREE: 'tight-tree', /** * Longest path algorithm * @@ -198,7 +230,21 @@ export namespace DependencyGraphTypes { * * Simplest and fastest */ - LONGEST_PATH = 'longest-path', + LONGEST_PATH: 'longest-path', + } as const; + + /** + * @public + */ + export type Ranker = (typeof Ranker)[keyof typeof Ranker]; + + /** + * @public + */ + export namespace Ranker { + export type NETWORK_SIMPLEX = typeof Ranker.NETWORK_SIMPLEX; + export type TIGHT_TREE = typeof Ranker.TIGHT_TREE; + export type LONGEST_PATH = typeof Ranker.LONGEST_PATH; } /** @@ -206,9 +252,24 @@ export namespace DependencyGraphTypes { * * @public */ - export enum LabelPosition { - LEFT = 'l', - RIGHT = 'r', - CENTER = 'c', + export const LabelPosition = { + LEFT: 'l', + RIGHT: 'r', + CENTER: 'c', + } as const; + + /** + * @public + */ + export type LabelPosition = + (typeof LabelPosition)[keyof typeof LabelPosition]; + + /** + * @public + */ + export namespace LabelPosition { + export type LEFT = typeof LabelPosition.LEFT; + export type RIGHT = typeof LabelPosition.RIGHT; + export type CENTER = typeof LabelPosition.CENTER; } } diff --git a/packages/core-components/src/layout/Sidebar/Bar.tsx b/packages/core-components/src/layout/Sidebar/Bar.tsx index 00fe6f96ae..bfa1e15d5e 100644 --- a/packages/core-components/src/layout/Sidebar/Bar.tsx +++ b/packages/core-components/src/layout/Sidebar/Bar.tsx @@ -97,11 +97,11 @@ const useStyles = makeStyles( { name: 'BackstageSidebar' }, ); -enum State { - Closed, - Idle, - Open, -} +const State = { + Closed: 0, + Idle: 1, + Open: 2, +} as const; /** @public */ export type SidebarProps = { @@ -144,7 +144,9 @@ const DesktopSidebar = (props: DesktopSidebarProps) => { theme => theme.breakpoints.down('md'), { noSsr: true }, ); - const [state, setState] = useState(State.Closed); + const [state, setState] = useState<(typeof State)[keyof typeof State]>( + State.Closed, + ); const hoverTimerRef = useRef(); const { isPinned, toggleSidebarPinState } = useSidebarPinState(); diff --git a/packages/core-components/src/layout/Sidebar/localStorage.ts b/packages/core-components/src/layout/Sidebar/localStorage.ts index 78ec355306..b62252e1df 100644 --- a/packages/core-components/src/layout/Sidebar/localStorage.ts +++ b/packages/core-components/src/layout/Sidebar/localStorage.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -enum LocalStorageKeys { - SIDEBAR_PIN_STATE = 'sidebarPinState', -} +const LocalStorageKeys = { + SIDEBAR_PIN_STATE: 'sidebarPinState', +} as const; export const LocalStorage = { getSidebarPinState(): boolean { diff --git a/packages/core-plugin-api/report.api.md b/packages/core-plugin-api/report.api.md index b40088dc78..e1b1a243df 100644 --- a/packages/core-plugin-api/report.api.md +++ b/packages/core-plugin-api/report.api.md @@ -461,9 +461,21 @@ export type FeatureFlagsSaveOptions = { }; // @public -export enum FeatureFlagState { - Active = 1, - None = 0, +export const FeatureFlagState: { + readonly None: 0; + readonly Active: 1; +}; + +// @public (undocumented) +export type FeatureFlagState = + (typeof FeatureFlagState)[keyof typeof FeatureFlagState]; + +// @public (undocumented) +export namespace FeatureFlagState { + // (undocumented) + export type Active = typeof FeatureFlagState.Active; + // (undocumented) + export type None = typeof FeatureFlagState.None; } // @public @@ -696,9 +708,20 @@ export type SessionApi = { }; // @public -export enum SessionState { - SignedIn = 'SignedIn', - SignedOut = 'SignedOut', +export const SessionState: { + readonly SignedIn: 'SignedIn'; + readonly SignedOut: 'SignedOut'; +}; + +// @public (undocumented) +export type SessionState = (typeof SessionState)[keyof typeof SessionState]; + +// @public (undocumented) +export namespace SessionState { + // (undocumented) + export type SignedIn = typeof SessionState.SignedIn; + // (undocumented) + export type SignedOut = typeof SessionState.SignedOut; } // @public diff --git a/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts b/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts index 66260afa32..d4429975cc 100644 --- a/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ import { ApiRef, createApiRef } from '../system'; @@ -32,15 +34,29 @@ export type FeatureFlag = { * * @public */ -export enum FeatureFlagState { +export const FeatureFlagState = { /** * Feature flag inactive (disabled). */ - None = 0, + None: 0, /** * Feature flag active (enabled). */ - Active = 1, + Active: 1, +} as const; + +/** + * @public + */ +export type FeatureFlagState = + (typeof FeatureFlagState)[keyof typeof FeatureFlagState]; + +/** + * @public + */ +export namespace FeatureFlagState { + export type None = typeof FeatureFlagState.None; + export type Active = typeof FeatureFlagState.Active; } /** diff --git a/packages/core-plugin-api/src/apis/definitions/auth.ts b/packages/core-plugin-api/src/apis/definitions/auth.ts index f8686cb128..9a0ddcd958 100644 --- a/packages/core-plugin-api/src/apis/definitions/auth.ts +++ b/packages/core-plugin-api/src/apis/definitions/auth.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ import { ApiRef, createApiRef } from '../system'; import { IconComponent } from '../../icons/types'; @@ -269,15 +271,28 @@ export type ProfileInfo = { * * @public */ -export enum SessionState { +export const SessionState = { /** * User signed in. */ - SignedIn = 'SignedIn', + SignedIn: 'SignedIn', /** * User not signed in. */ - SignedOut = 'SignedOut', + SignedOut: 'SignedOut', +} as const; + +/** + * @public + */ +export type SessionState = (typeof SessionState)[keyof typeof SessionState]; + +/** + * @public + */ +export namespace SessionState { + export type SignedIn = typeof SessionState.SignedIn; + export type SignedOut = typeof SessionState.SignedOut; } /** diff --git a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx index 479ad3161d..dfe728da86 100644 --- a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx +++ b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx @@ -49,15 +49,15 @@ const useStyles = makeStyles((theme: Theme) => ({ }, })); -enum Themes { - LIGHT = 'light', - DARK = 'dark', -} +const Themes = { + LIGHT: 'light', + DARK: 'dark', +} as const; export const TechDocsThemeToggle = () => { const appThemeApi = useApi(appThemeApiRef); const classes = useStyles(); - const [theme, setTheme] = useState( + const [theme, setTheme] = useState<(typeof Themes)[keyof typeof Themes]>( appThemeApi.getActiveThemeId() === Themes.DARK ? Themes.DARK : Themes.LIGHT, ); diff --git a/plugins/catalog-graph/report-alpha.api.md b/plugins/catalog-graph/report-alpha.api.md index edf84e936a..40cb136268 100644 --- a/plugins/catalog-graph/report-alpha.api.md +++ b/plugins/catalog-graph/report-alpha.api.md @@ -6,7 +6,6 @@ import { AnyApiFactory } from '@backstage/frontend-plugin-api'; import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; import { ApiFactory } from '@backstage/frontend-plugin-api'; -import { Direction } from '@backstage/plugin-catalog-graph'; import { Entity } from '@backstage/catalog-model'; import { EntityCardType } from '@backstage/plugin-catalog-react/alpha'; import { EntityPredicate } from '@backstage/plugin-catalog-react/alpha'; @@ -83,7 +82,7 @@ const _default: OverridableFrontendPlugin< maxDepth: number | undefined; unidirectional: boolean | undefined; mergeRelations: boolean | undefined; - direction: Direction | undefined; + direction: 'TB' | 'BT' | 'LR' | 'RL' | undefined; relationPairs: [string, string][] | undefined; zoom: 'disabled' | 'enabled' | 'enable-on-click' | undefined; curve: 'curveStepBefore' | 'curveMonotoneX' | undefined; @@ -96,7 +95,7 @@ const _default: OverridableFrontendPlugin< configInput: { height?: number | undefined; curve?: 'curveStepBefore' | 'curveMonotoneX' | undefined; - direction?: Direction | undefined; + direction?: 'TB' | 'BT' | 'LR' | 'RL' | undefined; zoom?: 'disabled' | 'enabled' | 'enable-on-click' | undefined; title?: string | undefined; relations?: string[] | undefined; @@ -157,7 +156,7 @@ const _default: OverridableFrontendPlugin< maxDepth: number | undefined; unidirectional: boolean | undefined; mergeRelations: boolean | undefined; - direction: Direction | undefined; + direction: 'TB' | 'BT' | 'LR' | 'RL' | undefined; showFilters: boolean | undefined; curve: 'curveStepBefore' | 'curveMonotoneX' | undefined; kinds: string[] | undefined; @@ -169,7 +168,7 @@ const _default: OverridableFrontendPlugin< }; configInput: { curve?: 'curveStepBefore' | 'curveMonotoneX' | undefined; - direction?: Direction | undefined; + direction?: 'TB' | 'BT' | 'LR' | 'RL' | undefined; zoom?: 'disabled' | 'enabled' | 'enable-on-click' | undefined; relations?: string[] | undefined; rootEntityRefs?: string[] | undefined; diff --git a/plugins/catalog-graph/report.api.md b/plugins/catalog-graph/report.api.md index b7621d05ef..dca431e588 100644 --- a/plugins/catalog-graph/report.api.md +++ b/plugins/catalog-graph/report.api.md @@ -113,11 +113,26 @@ export type DefaultRelationsInclude = { }; // @public -export enum Direction { - BOTTOM_TOP = 'BT', - LEFT_RIGHT = 'LR', - RIGHT_LEFT = 'RL', - TOP_BOTTOM = 'TB', +export const Direction: { + readonly TOP_BOTTOM: 'TB'; + readonly BOTTOM_TOP: 'BT'; + readonly LEFT_RIGHT: 'LR'; + readonly RIGHT_LEFT: 'RL'; +}; + +// @public (undocumented) +export type Direction = (typeof Direction)[keyof typeof Direction]; + +// @public (undocumented) +export namespace Direction { + // (undocumented) + export type BOTTOM_TOP = typeof Direction.BOTTOM_TOP; + // (undocumented) + export type LEFT_RIGHT = typeof Direction.LEFT_RIGHT; + // (undocumented) + export type RIGHT_LEFT = typeof Direction.RIGHT_LEFT; + // (undocumented) + export type TOP_BOTTOM = typeof Direction.TOP_BOTTOM; } // @public diff --git a/plugins/catalog-graph/src/lib/types/graph.ts b/plugins/catalog-graph/src/lib/types/graph.ts index 6b6061caaf..be4567313d 100644 --- a/plugins/catalog-graph/src/lib/types/graph.ts +++ b/plugins/catalog-graph/src/lib/types/graph.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ import { DependencyGraphTypes } from '@backstage/core-components'; import { MouseEventHandler } from 'react'; @@ -107,21 +109,36 @@ export type EntityNode = DependencyGraphTypes.DependencyNode; * * @public */ -export enum Direction { +export const Direction = { /** * Top to bottom. */ - TOP_BOTTOM = 'TB', + TOP_BOTTOM: 'TB', /** * Bottom to top. */ - BOTTOM_TOP = 'BT', + BOTTOM_TOP: 'BT', /** * Left to right. */ - LEFT_RIGHT = 'LR', + LEFT_RIGHT: 'LR', /** * Right to left. */ - RIGHT_LEFT = 'RL', + RIGHT_LEFT: 'RL', +} as const; + +/** + * @public + */ +export type Direction = (typeof Direction)[keyof typeof Direction]; + +/** + * @public + */ +export namespace Direction { + export type TOP_BOTTOM = typeof Direction.TOP_BOTTOM; + export type BOTTOM_TOP = typeof Direction.BOTTOM_TOP; + export type LEFT_RIGHT = typeof Direction.LEFT_RIGHT; + export type RIGHT_LEFT = typeof Direction.RIGHT_LEFT; } diff --git a/plugins/devtools-common/report.api.md b/plugins/devtools-common/report.api.md index 83af75d11a..25743fce7f 100644 --- a/plugins/devtools-common/report.api.md +++ b/plugins/devtools-common/report.api.md @@ -61,11 +61,21 @@ export type ExternalDependency = { }; // @public (undocumented) -export enum ExternalDependencyStatus { +export const ExternalDependencyStatus: { + readonly healthy: 'Healthy'; + readonly unhealthy: 'Unhealthy'; +}; + +// @public (undocumented) +export type ExternalDependencyStatus = + (typeof ExternalDependencyStatus)[keyof typeof ExternalDependencyStatus]; + +// @public (undocumented) +export namespace ExternalDependencyStatus { // (undocumented) - healthy = 'Healthy', + export type healthy = typeof ExternalDependencyStatus.healthy; // (undocumented) - unhealthy = 'Unhealthy', + export type unhealthy = typeof ExternalDependencyStatus.unhealthy; } // @public (undocumented) diff --git a/plugins/devtools-common/src/types.ts b/plugins/devtools-common/src/types.ts index 75644ece26..f1e60d9c2d 100644 --- a/plugins/devtools-common/src/types.ts +++ b/plugins/devtools-common/src/types.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ import { JsonValue } from '@backstage/types'; @@ -48,9 +50,23 @@ export type PackageDependency = { }; /** @public */ -export enum ExternalDependencyStatus { - healthy = 'Healthy', - unhealthy = 'Unhealthy', +export const ExternalDependencyStatus = { + healthy: 'Healthy', + unhealthy: 'Unhealthy', +} as const; + +/** + * @public + */ +export type ExternalDependencyStatus = + (typeof ExternalDependencyStatus)[keyof typeof ExternalDependencyStatus]; + +/** + * @public + */ +export namespace ExternalDependencyStatus { + export type healthy = typeof ExternalDependencyStatus.healthy; + export type unhealthy = typeof ExternalDependencyStatus.unhealthy; } /** @public */ diff --git a/plugins/permission-backend/src/service/router.test.ts b/plugins/permission-backend/src/service/router.test.ts index 386ae694ed..fe2b880d21 100644 --- a/plugins/permission-backend/src/service/router.test.ts +++ b/plugins/permission-backend/src/service/router.test.ts @@ -41,8 +41,8 @@ const mockApplyConditions: jest.MockedFunction< id: decision.id, result: (decision.conditions as any).params[0] === 'yes' - ? (AuthorizeResult.ALLOW as const) - : (AuthorizeResult.DENY as const), + ? AuthorizeResult.ALLOW + : AuthorizeResult.DENY, })), ); diff --git a/plugins/permission-common/report.api.md b/plugins/permission-common/report.api.md index ff3c03efb5..e09e56576e 100644 --- a/plugins/permission-common/report.api.md +++ b/plugins/permission-common/report.api.md @@ -37,10 +37,24 @@ export type AuthorizeRequestOptions = { }; // @public -export enum AuthorizeResult { - ALLOW = 'ALLOW', - CONDITIONAL = 'CONDITIONAL', - DENY = 'DENY', +export const AuthorizeResult: { + readonly DENY: 'DENY'; + readonly ALLOW: 'ALLOW'; + readonly CONDITIONAL: 'CONDITIONAL'; +}; + +// @public (undocumented) +export type AuthorizeResult = + (typeof AuthorizeResult)[keyof typeof AuthorizeResult]; + +// @public (undocumented) +export namespace AuthorizeResult { + // (undocumented) + export type ALLOW = typeof AuthorizeResult.ALLOW; + // (undocumented) + export type CONDITIONAL = typeof AuthorizeResult.CONDITIONAL; + // (undocumented) + export type DENY = typeof AuthorizeResult.DENY; } // @public diff --git a/plugins/permission-common/src/PermissionClient.ts b/plugins/permission-common/src/PermissionClient.ts index 61adc9279a..f801ba2a4b 100644 --- a/plugins/permission-common/src/PermissionClient.ts +++ b/plugins/permission-common/src/PermissionClient.ts @@ -146,7 +146,7 @@ export class PermissionClient implements PermissionEvaluator { options?: PermissionClientRequestOptions, ): Promise { if (!this.enabled) { - return requests.map(_ => ({ result: AuthorizeResult.ALLOW as const })); + return requests.map(_ => ({ result: AuthorizeResult.ALLOW })); } if (this.enableBatchedRequests) { @@ -168,7 +168,7 @@ export class PermissionClient implements PermissionEvaluator { options?: PermissionClientRequestOptions, ): Promise { if (!this.enabled) { - return queries.map(_ => ({ result: AuthorizeResult.ALLOW as const })); + return queries.map(_ => ({ result: AuthorizeResult.ALLOW })); } return this.makeRequest(queries, queryPermissionResponseSchema, options); diff --git a/plugins/permission-common/src/types/api.ts b/plugins/permission-common/src/types/api.ts index f70bd2d890..9bcec019be 100644 --- a/plugins/permission-common/src/types/api.ts +++ b/plugins/permission-common/src/types/api.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ import { JsonPrimitive } from '@backstage/types'; import { Permission, ResourcePermission } from './permission'; @@ -36,19 +38,34 @@ export type PermissionMessageBatch = { * The result of an authorization request. * @public */ -export enum AuthorizeResult { +export const AuthorizeResult = { /** * The authorization request is denied. */ - DENY = 'DENY', + DENY: 'DENY', /** * The authorization request is allowed. */ - ALLOW = 'ALLOW', + ALLOW: 'ALLOW', /** * The authorization request is allowed if the provided conditions are met. */ - CONDITIONAL = 'CONDITIONAL', + CONDITIONAL: 'CONDITIONAL', +} as const; + +/** + * @public + */ +export type AuthorizeResult = + (typeof AuthorizeResult)[keyof typeof AuthorizeResult]; + +/** + * @public + */ +export namespace AuthorizeResult { + export type ALLOW = typeof AuthorizeResult.ALLOW; + export type DENY = typeof AuthorizeResult.DENY; + export type CONDITIONAL = typeof AuthorizeResult.CONDITIONAL; } /** diff --git a/plugins/scaffolder-backend-module-gitlab/report.api.md b/plugins/scaffolder-backend-module-gitlab/report.api.md index 1c4ce80995..1da4c704b1 100644 --- a/plugins/scaffolder-backend-module-gitlab/report.api.md +++ b/plugins/scaffolder-backend-module-gitlab/report.api.md @@ -46,7 +46,7 @@ export const createGitlabIssueAction: (options: { discussionToResolve?: string | undefined; epicId?: number | undefined; labels?: string | undefined; - issueType?: IssueType | undefined; + issueType?: 'issue' | 'task' | 'incident' | 'test_case' | undefined; mergeRequestToResolveDiscussionsOf?: number | undefined; milestoneId?: number | undefined; weight?: number | undefined; @@ -275,11 +275,11 @@ export const editGitlabIssueAction: (options: { discussionLocked?: boolean | undefined; dueDate?: string | undefined; epicId?: number | undefined; - issueType?: IssueType | undefined; + issueType?: 'issue' | 'task' | 'incident' | 'test_case' | undefined; labels?: string | undefined; milestoneId?: number | undefined; removeLabels?: string | undefined; - stateEvent?: IssueStateEvent | undefined; + stateEvent?: 'close' | 'reopen' | undefined; title?: string | undefined; updatedAt?: string | undefined; weight?: number | undefined; @@ -301,22 +301,43 @@ const gitlabModule: BackendFeature; export default gitlabModule; // @public -export enum IssueStateEvent { +export const IssueStateEvent: { + readonly CLOSE: 'close'; + readonly REOPEN: 'reopen'; +}; + +// @public (undocumented) +export type IssueStateEvent = + (typeof IssueStateEvent)[keyof typeof IssueStateEvent]; + +// @public (undocumented) +export namespace IssueStateEvent { // (undocumented) - CLOSE = 'close', + export type CLOSE = typeof IssueStateEvent.CLOSE; // (undocumented) - REOPEN = 'reopen', + export type REOPEN = typeof IssueStateEvent.REOPEN; } // @public -export enum IssueType { +export const IssueType: { + readonly ISSUE: 'issue'; + readonly INCIDENT: 'incident'; + readonly TEST: 'test_case'; + readonly TASK: 'task'; +}; + +// @public (undocumented) +export type IssueType = (typeof IssueType)[keyof typeof IssueType]; + +// @public (undocumented) +export namespace IssueType { // (undocumented) - INCIDENT = 'incident', + export type INCIDENT = typeof IssueType.INCIDENT; // (undocumented) - ISSUE = 'issue', + export type ISSUE = typeof IssueType.ISSUE; // (undocumented) - TASK = 'task', + export type TASK = typeof IssueType.TASK; // (undocumented) - TEST = 'test_case', + export type TEST = typeof IssueType.TEST; } ``` diff --git a/plugins/scaffolder-backend-module-gitlab/src/commonGitlabConfig.ts b/plugins/scaffolder-backend-module-gitlab/src/commonGitlabConfig.ts index 5d0528bad4..5e8d92338e 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/commonGitlabConfig.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/commonGitlabConfig.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ import { z } from 'zod'; @@ -35,11 +37,26 @@ export const commonGitlabConfigExample = { * * @public */ -export enum IssueType { - ISSUE = 'issue', - INCIDENT = 'incident', - TEST = 'test_case', - TASK = 'task', +export const IssueType = { + ISSUE: 'issue', + INCIDENT: 'incident', + TEST: 'test_case', + TASK: 'task', +} as const; + +/** + * @public + */ +export type IssueType = (typeof IssueType)[keyof typeof IssueType]; + +/** + * @public + */ +export namespace IssueType { + export type ISSUE = typeof IssueType.ISSUE; + export type INCIDENT = typeof IssueType.INCIDENT; + export type TEST = typeof IssueType.TEST; + export type TASK = typeof IssueType.TASK; } /** @@ -47,7 +64,21 @@ export enum IssueType { * * @public */ -export enum IssueStateEvent { - CLOSE = 'close', - REOPEN = 'reopen', +export const IssueStateEvent = { + CLOSE: 'close', + REOPEN: 'reopen', +} as const; + +/** + * @public + */ +export type IssueStateEvent = + (typeof IssueStateEvent)[keyof typeof IssueStateEvent]; + +/** + * @public + */ +export namespace IssueStateEvent { + export type CLOSE = typeof IssueStateEvent.CLOSE; + export type REOPEN = typeof IssueStateEvent.REOPEN; } diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/railsArgumentResolver.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/railsArgumentResolver.ts index bcfc8cc487..3887c405ae 100644 --- a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/railsArgumentResolver.ts +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/railsArgumentResolver.ts @@ -16,39 +16,39 @@ import { sep as separatorPath } from 'path'; -enum Webpacker { - react = 'react', - vue = 'vue', - angular = 'angular', - elm = 'elm', - stimulus = 'stimulus', -} +const Webpacker = { + react: 'react', + vue: 'vue', + angular: 'angular', + elm: 'elm', + stimulus: 'stimulus', +} as const; -enum Database { - mysql = 'mysql', - postgresql = 'postgresql', - sqlite3 = 'sqlite3', - oracle = 'oracle', - sqlserver = 'sqlserver', - jdbcmysql = 'jdbcmysql', - jdbcsqlite3 = 'jdbcsqlite3', - jdbcpostgresql = 'jdbcpostgresql', - jdbc = 'jdbc', -} +const Database = { + mysql: 'mysql', + postgresql: 'postgresql', + sqlite3: 'sqlite3', + oracle: 'oracle', + sqlserver: 'sqlserver', + jdbcmysql: 'jdbcmysql', + jdbcsqlite3: 'jdbcsqlite3', + jdbcpostgresql: 'jdbcpostgresql', + jdbc: 'jdbc', +} as const; -enum RailsVersion { - dev = 'dev', - edge = 'edge', - master = 'master', - fromImage = 'fromImage', -} +const RailsVersion = { + dev: 'dev', + edge: 'edge', + master: 'master', + fromImage: 'fromImage', +} as const; export type RailsRunOptions = { api?: boolean; - database?: Database; + database?: (typeof Database)[keyof typeof Database]; force?: boolean; minimal?: boolean; - railsVersion?: RailsVersion; + railsVersion?: (typeof RailsVersion)[keyof typeof RailsVersion]; skipActionCable?: boolean; skipActionMailbox?: boolean; skipActionMailer?: boolean; @@ -59,7 +59,7 @@ export type RailsRunOptions = { skipWebpackInstall?: boolean; skipActiveRecord?: boolean; template?: string; - webpacker?: Webpacker; + webpacker?: (typeof Webpacker)[keyof typeof Webpacker]; }; export const railsArgumentResolver = ( @@ -119,7 +119,9 @@ export const railsArgumentResolver = ( if ( options?.webpacker && - Object.values(Webpacker).includes(options?.webpacker as Webpacker) + Object.values(Webpacker).includes( + options?.webpacker as (typeof Webpacker)[keyof typeof Webpacker], + ) ) { argumentsToRun.push('--webpack'); argumentsToRun.push(options.webpacker); @@ -127,7 +129,9 @@ export const railsArgumentResolver = ( if ( options?.database && - Object.values(Database).includes(options?.database as Database) + Object.values(Database).includes( + options?.database as (typeof Database)[keyof typeof Database], + ) ) { argumentsToRun.push('--database'); argumentsToRun.push(options.database); @@ -135,7 +139,9 @@ export const railsArgumentResolver = ( if ( options?.railsVersion !== RailsVersion.fromImage && - Object.values(RailsVersion).includes(options?.railsVersion as RailsVersion) + Object.values(RailsVersion).includes( + options?.railsVersion as (typeof RailsVersion)[keyof typeof RailsVersion], + ) ) { argumentsToRun.push(`--${options.railsVersion}`); } diff --git a/plugins/search-backend/src/service/AuthorizedSearchEngine.ts b/plugins/search-backend/src/service/AuthorizedSearchEngine.ts index b14e8d33d5..ed65e1b684 100644 --- a/plugins/search-backend/src/service/AuthorizedSearchEngine.ts +++ b/plugins/search-backend/src/service/AuthorizedSearchEngine.ts @@ -136,7 +136,7 @@ export class AuthorizedSearchEngine implements SearchEngine { // No permission configured for this document type - always allow. if (!permission) { - return { result: AuthorizeResult.ALLOW as const }; + return { result: AuthorizeResult.ALLOW }; } // Resource permission supplied, so we need to check for conditional decisions.