diff --git a/docs/backend-system/architecture/08-naming-patterns.md b/docs/backend-system/architecture/08-naming-patterns.md index 990cc62b70..b06d52c287 100644 --- a/docs/backend-system/architecture/08-naming-patterns.md +++ b/docs/backend-system/architecture/08-naming-patterns.md @@ -11,10 +11,10 @@ As a rule, all names should be camel case, with the exceptions of plugin and mod ### Plugins -| Description | Pattern | Examples | Notes | -| ----------- | ----------------- | ------------------------------------- | --------------------------------------------------------------------- | -| export | `Plugin` | `catalogPlugin`, `userSettingsPlugin` | | -| ID | `''` | `'catalog'`, `'user-settings'` | letters, digits, dashes, and underscores only, starting with a letter | +| Description | Pattern | Examples | Notes | +| ----------- | ----------------- | ------------------------------------- | -------------------------------------------------- | +| export | `Plugin` | `catalogPlugin`, `userSettingsPlugin` | | +| ID | `''` | `'catalog'`, `'user-settings'` | letters, digits,and dashes, starting with a letter | Example: @@ -27,10 +27,10 @@ export const userSettingsPlugin = createBackendPlugin({ ### Modules -| Description | Pattern | Examples | Notes | -| ----------- | ---------------------------- | ----------------------------------- | --------------------------------------------------------------------- | -| export | `Module` | `catalogModuleGithubEntityProvider` | | -| ID | `''` | `'github-entity-provider'` | letters, digits, dashes, and underscores only, starting with a letter | +| Description | Pattern | Examples | Notes | +| ----------- | ---------------------------- | ----------------------------------- | --------------------------------------------------- | +| export | `Module` | `catalogModuleGithubEntityProvider` | | +| ID | `''` | `'github-entity-provider'` | letters, digits, and dashes, starting with a letter | Example: diff --git a/packages/backend-plugin-api/src/wiring/constants.ts b/packages/backend-plugin-api/src/wiring/constants.ts new file mode 100644 index 0000000000..b5463d10da --- /dev/null +++ b/packages/backend-plugin-api/src/wiring/constants.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2025 The Backstage Authors + * + * 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. + */ + +/** + * The pattern that IDs must match. + * + * @remarks + * ids must only contain the letters `a` through `z` and digits, in groups separated by + * dashes. Additionally, the very first character of each such group + * must be a letter, not a digit + * + * @public + */ +export const ID_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/i; +export const ID_PATTERN_OLD = /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/i; diff --git a/packages/backend-plugin-api/src/wiring/createBackendModule.ts b/packages/backend-plugin-api/src/wiring/createBackendModule.ts index 9d064d3b0d..f65e11acae 100644 --- a/packages/backend-plugin-api/src/wiring/createBackendModule.ts +++ b/packages/backend-plugin-api/src/wiring/createBackendModule.ts @@ -14,8 +14,8 @@ * limitations under the License. */ -import { CONFIG_KEY_PART_PATTERN } from '@backstage/config'; import { BackendFeature } from '../types'; +import { ID_PATTERN, ID_PATTERN_OLD } from './constants'; import { BackendModuleRegistrationPoints, InternalBackendModuleRegistration, @@ -56,9 +56,14 @@ export function createBackendModule( options: CreateBackendModuleOptions, ): BackendFeature { function getRegistrations() { - if (!CONFIG_KEY_PART_PATTERN.test(options.moduleId)) { + if (!ID_PATTERN.test(options.moduleId)) { + console.warn( + `WARNING: The moduleId '${options.moduleId}' for plugin '${options.pluginId}', will be invalid soon please must match the pattern ${ID_PATTERN} (letters, digits, and dashes only, starting with a letter)`, + ); + } + if (!ID_PATTERN_OLD.test(options.moduleId)) { throw new Error( - `Invalid moduleId '${options.moduleId}' for plugin '${options.pluginId}', must match the pattern ${CONFIG_KEY_PART_PATTERN} (letters, digits, dashes, and underscores only, starting with a letter)`, + `Invalid moduleId '${options.moduleId}' for plugin '${options.pluginId}', must match the pattern ${ID_PATTERN} (letters, digits, and dashes only, starting with a letter)`, ); } diff --git a/packages/backend-plugin-api/src/wiring/createBackendPlugin.ts b/packages/backend-plugin-api/src/wiring/createBackendPlugin.ts index e4d32197ff..d2aa633620 100644 --- a/packages/backend-plugin-api/src/wiring/createBackendPlugin.ts +++ b/packages/backend-plugin-api/src/wiring/createBackendPlugin.ts @@ -14,13 +14,13 @@ * limitations under the License. */ -import { CONFIG_KEY_PART_PATTERN } from '@backstage/config'; import { BackendFeature } from '../types'; import { BackendPluginRegistrationPoints, InternalBackendPluginRegistration, InternalBackendRegistrations, } from './types'; +import { ID_PATTERN, ID_PATTERN_OLD } from './constants'; /** * The configuration options passed to {@link createBackendPlugin}. @@ -50,9 +50,14 @@ export function createBackendPlugin( options: CreateBackendPluginOptions, ): BackendFeature { function getRegistrations() { - if (!CONFIG_KEY_PART_PATTERN.test(options.pluginId)) { + if (!ID_PATTERN.test(options.pluginId)) { + console.warn( + `WARNING: The pluginId '${options.pluginId}' will be invalid soon please must match the pattern ${ID_PATTERN} (letters, digits, and dashes only, starting with a letter)`, + ); + } + if (!ID_PATTERN_OLD.test(options.pluginId)) { throw new Error( - `Invalid pluginId '${options.pluginId}', must match the pattern ${CONFIG_KEY_PART_PATTERN} (letters, digits, dashes, and underscores only, starting with a letter)`, + `Invalid pluginId '${options.pluginId}', must match the pattern ${ID_PATTERN} (letters, digits, and dashes only, starting with a letter)`, ); }