Repository: spotify/backstage
File: packages/backend-plugin-api/src/wiring/createBackendPlugin.ts (TypeScript)

Code before:
 * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
 */
export interface CreateBackendPluginOptions {
  /**
   * The ID of this plugin.
   *
   * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
   */
  pluginId: string;
  register(reg: BackendPluginRegistrationPoints): void;
}

/**
 * Creates a new backend plugin.
 *
 * @public
 * @see {@link https://backstage.io/docs/backend-system/architecture/plugins | The architecture of plugins}
 * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
 */
export function createBackendPlugin(
  options: CreateBackendPluginOptions,
): BackendFeature {
  function getRegistrations() {
    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 ${ID_PATTERN} (letters, digits, and dashes only, starting with a letter)`,
      );
    }

    const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =
      [];
    let init: InternalBackendPluginRegistration['init'] | undefined = undefined;

    options.register({
      registerExtensionPoint(ext, impl) {
        if (init) {
          throw new Error('registerExtensionPoint called after registerInit');
        }
        extensionPoints.push([ext, impl]);
      },
      registerInit(regInit) {
        if (init) {
          throw new Error('registerInit must only be called once');
        }
        init = {
          deps: regInit.deps,

Review comment (suggestion):
```suggestion
        `WARNING: The pluginId '${options.pluginId}' will be invalid soon, please change it to match the pattern ${ID_PATTERN} (letters, digits, and dashes only, starting with a letter)`,
```

Code after:
 * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
 */
export interface CreateBackendPluginOptions {
  /**
   * The ID of this plugin.
   *
   * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
   */
  pluginId: string;
  register(reg: BackendPluginRegistrationPoints): void;
}

/**
 * Creates a new backend plugin.
 *
 * @public
 * @see {@link https://backstage.io/docs/backend-system/architecture/plugins | The architecture of plugins}
 * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
 */
export function createBackendPlugin(
  options: CreateBackendPluginOptions,
): BackendFeature {
  if (!ID_PATTERN.test(options.pluginId)) {
    console.warn(
      `WARNING: The pluginId '${options.pluginId}' will be invalid soon, please change it to 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 ${ID_PATTERN} (letters, digits, and dashes only, starting with a letter)`,
    );
  }

  function getRegistrations() {
    const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =
      [];
    let init: InternalBackendPluginRegistration['init'] | undefined = undefined;

    options.register({
      registerExtensionPoint(ext, impl) {
        if (init) {
          throw new Error('registerExtensionPoint called after registerInit');
        }
        extensionPoints.push([ext, impl]);
      },
      registerInit(regInit) {
        if (init) {
          throw new Error('registerInit must only be called once');
        }
        init = {
          deps: regInit.deps,