The entity card override example used `name: 'entity-relations'` but
the actual extension uses `name: 'relations'`.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
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
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
Skip assigning undefined keys for absent optional fields in parse,
matching the previous zod-object behavior. Make the schema getter
non-enumerable so JSON.stringify on the portable schema only
serializes parse and _fields.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
The inline snapshot was stale after the PortableSchema internal
representation changed to use lazy schema and _fields structure.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Add explicit deprecation warnings in override and makeWithOverrides when
config.schema is used, since the merged result now passes through
configSchema. Update search declarative-integration docs to use
SearchResultListItemBlueprint instead of the removed extension creator.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Pass merged config schemas via configSchema instead of config.schema in
the override method to avoid false deprecation warnings. Add type guard
for non-object inputs in parse. Add tests for defaulted field required
semantics (already correct) and invalid input types.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Route createExtension overloads through CreateExtensionOptions so that
ResolvedExtensionInputs, VerifyExtensionFactoryOutput, VerifyExtensionAttachTo,
and RequiredExtensionIds can remain @ignore without ae-forgotten-export warnings.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Add changesets for plugin-app and plugin-catalog-graph. Fix cross-style
merge test to use direct schema values with configSchema instead of
factory functions.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Add 1.50 migration section documenting the config.schema to configSchema
migration with examples for createExtension, createExtensionBlueprint,
and makeWithOverrides. Add a separate changeset for the new feature and
update the existing breaking changeset to reference the migration docs.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
The helper is no longer used internally and has been replaced by
the `configSchema` option with direct Standard Schema values.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Cover zod v3, zod v4, mixed, and merged schema error messages
with exact string assertions to document the error format produced
for missing fields, type mismatches, nested paths, and multi-field
errors.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Switch all documentation examples from the deprecated
`config: { schema: { field: z => z.type() } }` pattern to the new
`configSchema: { field: z.type() }` format using zod v4 imports.
Also update catalog-graph README to use current blueprint APIs.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Move EntityCardBlueprint and EntityContentBlueprint to the new
`configSchema` option using zod v3, and AppLanguageApi to zod v4.
Fix config schema merge in `makeWithOverrides` when mixing
`configSchema` and deprecated `config.schema` sources.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Instead of a one-time warning, emit a deprecation warning every time
an extension is created using the deprecated `config.schema` option,
including the call site location to help track down each usage.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace box-style section comments with TSDoc comments to match
the style used throughout the rest of the repository.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace the monolithic `createSchemaFromZod` approach with per-field
schema resolution via `createConfigSchema`. Each field is resolved
individually and eagerly validated for JSON Schema conversion support,
but the actual JSON Schema generation is deferred until first access.
`PortableSchema.schema` is now a lazy callable — it can still be
accessed as a property (backward compat, deprecated) or called as a
method returning `{ schema: JsonObject }` for the new API.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Remove the `ConfigFieldSchema` and `ConfigSchemaRecord` types that are
no longer needed now that `configSchema` and `config.schema` each accept
only one form. The deprecated overloads now constrain directly to the
factory signature `(zImpl: typeof z) => z.ZodType`.
Also fix pre-existing API report warnings by promoting
`ResolvedExtensionInputs`, `RequiredExtensionIds`,
`VerifyExtensionFactoryOutput`, and `VerifyExtensionAttachTo` to
`@public` and exporting them from both entry points.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Introduce a new top-level `configSchema` option for `createExtension`,
`createExtensionBlueprint`, `override`, and `makeWithOverrides` that
accepts Standard Schema values directly. The old `config.schema` form
is deprecated via function/method overloads so that the entire call
site gets editor strikethrough when matched.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Widens the TConfigSchema generic constraint in createExtension,
createExtensionBlueprint, and their override/makeWithOverrides methods
to accept both the existing zod factory form and direct Standard Schema
instances via the new ConfigFieldSchema union type.
Existing consumers are unaffected — the factory form continues to
infer concrete types through z.infer<ReturnType<...>>. Direct Standard
Schema values are accepted but infer as any in the current iteration.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Adds a mock/exploration file showing what a central Standard-Schema-based
utility could look like for decoupling the exact zod version from the
public API surface of extension config schemas.
This is not wired into anything — just saving progress on the design
exploration for per-field validation, JSON Schema generation, and
schema merging across different sources (blueprint + override) that
may use different schema libraries or zod versions.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Update the question about hosted/commercial versions of Backstage
to be vendor-neutral and link to the commercial partners page.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Remove solo.io, VMware, and Alauda as commercial partners due to
broken/irrelevant landing pages. Add Spotify for Backstage as a
partner. Sort partners alphabetically and normalize logo sizes
with per-partner height control.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Remove the deprecated alpha exports CatalogPermissionRuleInput,
CatalogPermissionExtensionPoint, and catalogPermissionExtensionPoint
from catalog-node, and remove the corresponding CatalogPermissionExtensionPointImpl,
addPermissions, and addPermissionRules from catalog-backend. Custom permission
rules and permissions are now registered via coreServices.permissionsRegistry.
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
Adds a new `Badge` component to the Backstage UI library. Badge shares the same visual appearance as `Tag` (size tokens, colors, border radius, icon slot) but renders as a plain non-interactive `<span>` with no React Aria plumbing.
Key characteristics:
- Plain DOM element — accessible text content exposed to screen readers without any role override
- Background consumer — participates in the bg context system and steps up neutral background levels (`neutral-2` → `neutral-3` → `neutral-4`) when placed inside colored containers
- Supports `icon`, `size` (`small` | `medium`, defaults to `small`), `children`, and `className` props
- Fully themeable via `BadgeDefinition`
Also includes Storybook stories and full docs-ui documentation (props table, examples, theming section, changelog).
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
Made-with: Cursor
* verify-links: catch broken anchors, directory links, and invisible characters
Enhances the link verification script to catch several categories of
broken links that were previously missed:
- Broken anchors (cross-file and same-file) by extracting heading slugs
from target documents and verifying anchors resolve
- Directory links missing index.md suffix within docs/
- Invisible/zero-width characters in URLs
- Case-sensitive anchor mismatches
Also strips fenced code blocks before scanning for links to avoid false
positives, and handles duplicate heading slug deduplication (GitHub and
Docusaurus append -1, -2, etc.).
Fixes a few newly-caught broken links in existing docs.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
* Fix CodeQL incomplete multi-character sanitization alert
Apply HTML tag stripping in a loop so that nested fragments
like <scr<script>ipt> are fully removed.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
---------
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Make `permissionsRegistry` required and `permissions` always a
`PermissionsService` in `CatalogEnvironment`. Remove the deprecated
`PermissionAuthorizer` fallback path and the `createPermissionIntegrationRouter`
fallback — catalog now exclusively uses `permissionsRegistry.addResourceType`
to register its permission resource type.
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor