19202 Commits

Author SHA1 Message Date
Patrik Oldsberg 3210dbd638 Merge pull request #33782 from UsainBloot/feat/extension-point-middleware
feat(backend): add extensionPointFactoryMiddleware to createBackend
2026-04-15 01:00:53 +02:00
github-actions[bot] 93e643d142 Version Packages 2026-04-14 14:57:31 +00:00
Fredrik Adelöw 9f24941b49 Merge pull request #33663 from backstage/freben/catalog-model-extensions
Add catalog model layer system with JSON Schema based kind declarations
2026-04-14 16:29:01 +02:00
Fredrik Adelöw 3e291ae523 Rename schema imports to jsonSchema and remove stale changeset
Rename the JSON schema imports in kind definitions from `schema` to
`jsonSchema` to enable shorthand property syntax. Also remove the
stale scaffolder-backend changeset since that package no longer has
changes in this PR.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
2026-04-14 15:44:11 +02:00
Fredrik Adelöw 12998a965f Change model source generator to yield data array with layer entries
Change AsyncCatalogModelSourceGenerator from yielding
{ layers: CatalogModelLayer[] } to { data: Array<{ layer: CatalogModelLayer }> }
so that additional contextual data can be attached alongside each layer
in the future.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
2026-04-14 15:31:46 +02:00
Shamil Ganiev d00a44bc12 fix: use iovalkey Cluster for Valkey cluster mode
Signed-off-by: Shamil Ganiev <ganiev@pm.me>
2026-04-14 15:30:31 +03:00
Patrik Oldsberg 047a2175e3 integration: use registerMswTestHooks from backend-test-utils
Removed the test-only `registerMswTestHooks` function from `helpers.ts`
and replaced it with the shared version from `@backstage/backend-test-utils`.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-14 14:20:01 +02:00
Fredrik Adelöw c51c6eb81c Use isError from @backstage/errors instead of instanceof Error
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
2026-04-14 14:10:31 +02:00
Fredrik Adelöw ee80f3f0f9 Improve schema validation errors and clean up review fixes
- Use superRefine in jsonSchemaSchema to preserve the detailed error
  message from validateMetaSchema instead of swallowing it
- Revert CatalogModelSources to silent dedup with uniqBy since user
  layers intentionally take precedence over the default model
- Clean up unnecessary `as void` cast in ModelHolder iterator cleanup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
2026-04-14 14:07:23 +02:00
Fredrik Adelöw 173ef97b48 Address second round of PR review comments
- Close async iterators in ModelHolder after reading first value to
  prevent resource leaks
- Catch exceptions from validateMetaSchema in Zod refine predicate
  so validation errors flow through Zod's normal issue reporting
- Warn on duplicate catalog model layer IDs instead of silently
  dropping later entries
- Replace `as any` with `as JsonObject` for schema import in
  scaffolder template model layer

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
2026-04-14 13:59:39 +02:00
Fredrik Adelöw 445aefd4b9 Address PR review comments
- Remove unused deps @backstage/filter-predicates and zod-validation-error
  from catalog-model
- Deduplicate defaultCatalogEntityModel by re-exporting from the single
  source in model/defaultCatalogEntityModel.ts
- Fix typos: "Retuns"/"epxressed", "Obviopusly", "recorsively"
- Use domain-prefixed layer ID for scaffolder template model

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
2026-04-14 13:41:22 +02:00
Fredrik Adelöw 31290ca25f Add summary types and listing methods to CatalogModel
Introduce CatalogModelKindSummary, CatalogModelRelationSummary,
CatalogModelAnnotationSummary, CatalogModelLabelSummary, and
CatalogModelTagSummary as reduced views of the full model data.

Add listKinds(), listRelations(), and getMetadata() methods to
CatalogModel for retrieving these summaries. Add a new action for
fetching a markdown-formatted catalog model description, useful for
informing LLMs about the catalog structure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
2026-04-14 13:27:33 +02:00
Patrik Oldsberg d3627319a1 Merge pull request #33836 from backstage/rugvip/explore-standard-schema-decoupling
frontend-plugin-api: decouple zod dependency using Standard Schema
2026-04-14 12:27:53 +02:00
Fredrik Adelöw 742165a053 Merge pull request #33030 from backstage/sennyeya/mem-leak
fix(openapi-jest-utils): memory leak in proxy clean up
2026-04-14 10:23:29 +02:00
Patrik Oldsberg 11d7130ff4 Merge pull request #33878 from backstage/rugvip/harmonize-phantom-t-getter
backend-plugin-api: harmonize phantom .T getter behavior
2026-04-14 00:54:04 +02:00
Patrik Oldsberg 078beccb49 Merge pull request #33877 from backstage/rugvip/deduplicate-test-readiness-polling
backend-test-utils: deduplicate test readiness-polling helpers
2026-04-14 00:52:46 +02:00
Patrik Oldsberg c40568f651 Simplify phantom T props to plain null values instead of getters
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-14 00:06:53 +02:00
Patrik Oldsberg d79072b5de Update phantom T getter doc comments and expand changeset scope
Updated doc comments on ExtensionPoint.T and ServiceRef.T to reflect
that reading the value returns null rather than throwing. Expanded the
changeset to cover all three behavioral changes in the PR.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 23:10:16 +02:00
Patrik Oldsberg fb9efc3e28 Address review feedback for waitForReady and helpers
Change lastError type to unknown to match catch clause semantics,
and disconnect failed Keyv instances in attemptKeyvConnection to
avoid leaking sockets/handles during readiness polling.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 22:53:29 +02:00
Patrik Oldsberg 213ebe77cc Harmonize phantom .T getter behavior between ExtensionPoint and ServiceRef
Both `createExtensionPoint` and `createServiceRef` now consistently return
`null` from the phantom `.T` getter instead of throwing. Added `toJSON()` to
`ExtensionPoint` for parity with `ServiceRef`.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 22:40:36 +02:00
Patrik Oldsberg 8923d6def0 Drop Zod v3 support from new configSchema path
The new `configSchema` option now strictly requires StandardSchemaV1
values (e.g. Zod v4 or `zod/v4` from the Zod v3 package). Direct Zod
v3 schemas are no longer silently converted and will throw an error.

The deprecated `config.schema` callback path continues to work with
Zod v3 through a separate `createDeprecatedConfigSchema` function.

Also adds `createZodV4FilterPredicateSchema` to `@backstage/filter-predicates`
as a v4 counterpart to the now-deprecated v3 variant.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 21:38:28 +02:00
Patrik Oldsberg dd4ea5896d Remove unnecessary exports of file-local helpers
Remove the `export` keyword from functions that are only used within
their own file and are not part of any package's public API:

- `parseStringsParam` and `isOrder` in notifications-backend
- `toWeb` in backend-defaults urlReader
- `resolvePublicPath` in app-backend

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 21:29:21 +02:00
Patrik Oldsberg f44c6bd265 backend-test-utils: deduplicate test infrastructure readiness-polling helpers
Extract shared internal helpers to eliminate near-identical readiness
polling loops across database and cache test infrastructure:

- waitForReady: generic probe-until-ready loop used by both postgres
  and mysql database helpers
- attemptKeyvConnection: generic Keyv set/get probe loop used by redis,
  valkey, and memcached cache helpers
- startRedisLikeContainer: shared container-start for redis-protocol
  stores (redis and valkey)

Also normalizes cache timeout error formatting to use stringifyError
instead of template string coercion.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 20:48:35 +02:00
Fredrik Adelöw e5fcfcb2cb Add catalog model layers with JSON Schema based kind declarations
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
2026-04-13 16:54:15 +02:00
Patrik Oldsberg 0c4d91cbef Remove unused messagePatternToGlob and patternHasSubdirectories
These two internal functions in cli-module-translations were never
imported by any production code. Remove them along with their tests.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 16:50:16 +02:00
Patrik Oldsberg 68c557b381 backend-plugin-api: tighten internal any usage (#33867)
* backend-plugin-api: tighten internal any usage

Replace internal `any` type annotations with proper types:

- Use `'root' | 'plugin'` union in DepsToInstances conditional type
  and createServiceRef implementation signature
- Use Error type guard with object cast fallback in
  isDatabaseConflictError instead of `as any`

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor

* Use isError in isDatabaseConflictError

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor

* Update changeset wording per review feedback

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor

---------

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-04-13 14:58:03 +02:00
Patrik Oldsberg 4c09967317 Deduplicate frontend plugin/module extension collection logic (#33869)
Extract the shared extension resolution and duplicate-check logic from
createFrontendPlugin and createFrontendModule into a new
resolveExtensionDefinitions helper. Also fixes the duplicate extension
error message in createFrontendModule to say "Module" instead of
"Plugin".


Made-with: Cursor

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-04-13 13:58:59 +02:00
Patrik Oldsberg 9b57f709e9 Merge pull request #33866 from backstage/rugvip/assert-error-delegate-to-is-error
Have `assertError` delegate to `isError` in `@backstage/errors`
2026-04-13 13:49:37 +02:00
Patrik Oldsberg 5e8b8399f0 Merge pull request #33864 from backstage/rugvip/remove-unused-openapi-generator-constants
repo-tools: remove unused OpenAPI generator constants
2026-04-13 13:46:15 +02:00
Patrik Oldsberg e9bbbf18ea Merge pull request #33861 from backstage/rugvip/delete-orphaned-command-registry
cli: 🧹
2026-04-13 13:44:37 +02:00
Patrik Oldsberg e7c455121b Merge pull request #33860 from backstage/rugvip/delete-orphaned-lazy-ts
cli: 🧹
2026-04-13 13:44:23 +02:00
Patrik Oldsberg ca2dc15b07 repo-tools: remove unused OpenAPI generator constants
Remove the unused exported constants GENERATOR_VERSION, GENERATOR_NAME,
GENERATOR_FILE, and TS_MODULE from the OpenAPI constants module. The
TS_MODULE intermediate variable is inlined into TS_SCHEMA_PATH.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 13:19:24 +02:00
Patrik Oldsberg 608c1e5958 Have assertError delegate to isError in @backstage/errors
Simplify the assertError implementation by delegating to isError
instead of duplicating the same validation checks.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 13:19:22 +02:00
Patrik Oldsberg 8055219d27 Merge pull request #33847 from backstage/rugvip/dialog-api-open
DialogApi: Add open() method, deprecate show/showModal
2026-04-13 13:04:30 +02:00
Patrik Oldsberg 81de17eec7 cli: delete orphaned CommandRegistry.ts
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 13:04:16 +02:00
Patrik Oldsberg 42e8013b4e cli: delete orphaned lazy.ts utility
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 13:04:10 +02:00
Patrik Oldsberg 7c25059269 Merge pull request #33859 from backstage/rugvip/remove-unused-notfounderror-class
repo-tools: 🧹
2026-04-13 12:24:27 +02:00
Patrik Oldsberg 34bdd5ed7e cli-node: delete orphaned errors.ts (#33856)
Made-with: Cursor

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-04-13 12:24:14 +02:00
Patrik Oldsberg 38f2703930 backend-defaults: delete orphaned isValidUrl utility (#33857)
Made-with: Cursor

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-04-13 12:24:06 +02:00
Patrik Oldsberg a2f0c72af8 Remove unused isDev constant from CLI version module (#33858)
The `isDev` export in `packages/cli/src/wiring/version.ts` was never
imported anywhere. Remove it to reduce dead code.


Made-with: Cursor

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-04-13 12:22:04 +02:00
James Brooks 67b88815ae Fix dialog dismissal in Backstage UI (#33785)
Dismissing a dialog by clicking on the overlay doesn't work currently despite being enabled. This is because what appears to be the overlay in the UI is actually the modal content instead, as the classes are applied incorrectly. This PR fixes that by separating out the overlay from the Modal component and lifting each of the classes up one layer.

---------

Signed-off-by: James Brooks <jamesbrooks@spotify.com>
2026-04-13 11:21:56 +01:00
Fredrik Adelöw 53143805a0 Merge pull request #33789 from backstage/freben/location-uuid-names
feat(catalog): expose `entityRef` on Location type and add `PUT /locations/:id`
2026-04-13 11:38:16 +02:00
Jack Palmer 90b62c24ef fix: backend-internal eslint config
Signed-off-by: Jack Palmer <jackpalmer@spotify.com>
2026-04-13 09:57:34 +01:00
Patrik Oldsberg 8049d7bf6e repo-tools: remove unused NotFoundError class
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 09:55:59 +02:00
Patrik Oldsberg 377de3645f repo-tools: fix peer-deps check to skip unreferenced dependencies
The peer-deps verification was requiring all tracked peer dependencies
(including react-router-dom) for every package that references any of
them. Now it only requires a peer dependency if the package actually
references it or if it belongs to a group containing a referenced dep.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-13 00:53:54 +02:00
Patrik Oldsberg 25392cab00 Use StandardSchemaV1.InferOutput/InferInput utility types
Replace raw NonNullable<T['~standard']['types']>['output'] access
with the canonical StandardSchemaV1.InferOutput and InferInput
utility types for improved readability.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-12 19:17:39 +02:00
Patrik Oldsberg e4804abb44 Add DialogApi.open() and deprecate show/showModal
The existing show() and showModal() methods render dialog chrome (a
Material UI Dialog) as part of the implementation. This causes focus
trap conflicts when the caller's content uses components from a
different design library (e.g. Backstage UI).

The new open() method renders the caller's content as-is, without any
dialog chrome. The caller provides the full dialog component including
overlay, backdrop, and surface, making the API design-library-agnostic.

The deprecated show/showModal are re-implemented on top of open() with
a MUI Dialog wrapper for backward compatibility, and emit console
warnings when used.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-12 11:14:02 +02:00
Patrik Oldsberg 0ecb8225cb Merge pull request #33839 from jonkoops/deprecate-proxy-bootstrap
refactor(cli-common): deprecate `bootstrapEnvProxyAgents()` in favor of Node.js built-in proxy support
2026-04-11 12:05:55 +02:00
Aramis Sennyey 2b4f97adf7 docs: frontend plugin golden path (#33541)
* docs: frontend plugin golden path guide

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* add changeset

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* Apply suggestion from @aramissennyeydd

Signed-off-by: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com>
Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* fix template

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* fix template test

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* print stderr on failure

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* try writing directly

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* maybe this?

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* address feedback

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* fix: avoid destructuring FetchApi and fix template issues

- Use fetchApi.fetch() instead of destructuring to preserve this binding
- Add discoveryApi and fetchApi to useAsync dependency array
- Use react-use/esm/useAsync to match repo conventions
- Replace waitFor + getAllByText with findByText in error test
- Update HTTP client doc to match template changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* fix: address docs review feedback

- Use stronger guidance tone in scaffolding guide intro
- Slim down file tree to show folder structure only
- Mention that plugin path depends on chosen plugin ID
- Link to installation docs for non-discovery case
- Quote page:todo YAML key to avoid parse errors
- Remove "new" from "new frontend system" in template README

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* fix: improve error handling in e2e plugin creation

- Narrow error to non-null object before using in operator
- Also write error.stdout since tools like Jest report to stdout
- Avoid variable shadowing with outer scope stdout/stderr

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* revert: keep destructured fetch from FetchApi

Destructuring fetch from FetchApi is fine — revert to original
pattern while keeping the dependency array and other fixes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* feat: use @backstage/ui components in frontend plugin template

Replace core-components layout and table with @backstage/ui equivalents:
- Use HeaderPage and Container instead of Page, Header, Content, ContentHeader
- Use BUI Table with useTable and CellText instead of core-components Table
- Add @backstage/ui to template package.json dependencies
- Update poking-around docs to reflect BUI component usage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* fix: add example data when backend request fails

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* better logging setup

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* address feedback

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* better config driven example

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* debug logs

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* fix build failure related to unknown version

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* revert e2e run changes

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com>

* skip the discovery api for now

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* remove another ref

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com>

---------

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>
Signed-off-by: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-10 14:00:55 -04:00
Patrik Oldsberg 5b6061ac77 Address review feedback: zod import path and legacy route ref
Use explicit zod/v4 import path in tests, and remove unnecessary
convertLegacyRouteRef wrapper in catalog-graph README.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-10 16:54:06 +02:00