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
Reverts the location_entity_ref-as-locationKey change: the full mutation on
startup would compare existing rows (locationKey = url:target) against the
new values and trigger a remove+add cycle for every location. The type:target
locationKey is kept as-is to preserve the existing startup contract.
Keeps the allowedLocationTypes validation added to DefaultLocationService.updateLocation.
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
Use location_entity_ref as the locationKey in all applyMutation calls
instead of type:target. This prevents the catalog from treating a type/target
update as a remove+re-add cycle (which would temporarily prune the entity
and its descendants). The location_entity_ref never changes after creation,
so the catalog can safely upsert the entity in-place on updateLocation.
Also add allowedLocationTypes validation to updateLocation in
DefaultLocationService, matching the existing check in createLocation.
Signed-off-by: Fredrik Adelöw <freben@spotify.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
The generic is no longer needed since the interface is opaque. Type
inference is handled by createExtensionPointFactoryMiddleware instead.
Signed-off-by: Jack Palmer <jackpalmer@spotify.com>
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
Prevent updating a location to a {type, target} already used by another
location, matching the invariant enforced by createLocation. Also adds
ALLOW/DENY tests for updateLocation in AuthorizedLocationService.
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
- Make ExtensionPointFactoryMiddleware an opaque type via new
@internal/backend package using OpaqueType from @internal/opaque
- Use options object for createExtensionPointFactoryMiddleware
- Make middleware function async (returns Promise<T>)
- Remove extensionPointFactoryMiddleware from createBackend, keep only
on createSpecializedBackend
- Export defaultServiceFactories from @backstage/backend-defaults
Signed-off-by: Jack Palmer <jackpalmer@spotify.com>
Address reviewer feedback:
- Use a dedicated migrations table to avoid conflicts with the parent plugin
- Use database-native now() instead of JS Date for timestamp columns
- Use database-level interval arithmetic for cleanup retention cutoff
Signed-off-by: Erik Miller <erik.miller@gusto.com>
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
These empty `{}` files were accidentally committed during the template
directory rename and override the properly templated package.json
generated from package.json.hbs, causing E2E tests to fail.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
The new frontend system app takes longer to compile and render on
Windows CI runners. Switch from port-based to URL-based server
readiness detection and increase expect timeout to 30s to avoid
flaky failures on slow runners.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
The test was updated to use the default-app template (renamed from
next-app), but the mock version list was missing packages that this
template requires such as @backstage/core-compat-api,
@backstage/frontend-defaults, @backstage/frontend-plugin-api, and
others. Also sorted the mock entries alphabetically.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Refactor the postgres database creation retry loop to avoid an
unnecessary sleep after the final failed attempt, and improve
readability by using named variables.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>