From 21b66b184dc88f744c69ead1744f4b4d5de4ff0a Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 23 Jul 2024 12:37:43 +0200 Subject: [PATCH] chore: initial experiments Signed-off-by: blam wip Signed-off-by: blam wip2 Signed-off-by: blam wip3 Signed-off-by: blam wip3 Signed-off-by: blam --- packages/frontend-plugin-api/api-report.md | 41 ++++++--- .../src/extensions/IconBundleBlueprint.ts | 36 ++++++++ .../src/wiring/createExtension.ts | 18 +++- .../src/wiring/createExtensionBlueprint.ts | 92 ++++++++++++++----- .../src/app/createExtensionTester.tsx | 4 +- plugins/catalog-graph/api-report-alpha.md | 72 +++++++++++++++ plugins/catalog-graph/src/alpha.tsx | 79 ++++++++++++---- plugins/catalog-react/api-report-alpha.md | 56 +++++++++-- plugins/catalog-react/src/alpha.tsx | 51 ++++++++++ plugins/catalog/api-report-alpha.md | 35 ++++++- plugins/catalog/src/alpha/index.ts | 2 + plugins/search-react/api-report-alpha.md | 3 +- plugins/search/api-report-alpha.md | 26 ++++-- plugins/techdocs/api-report-alpha.md | 18 ++-- plugins/user-settings/api-report-alpha.md | 10 +- 15 files changed, 456 insertions(+), 87 deletions(-) diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index d6a91c0c99..0c7c3b1d92 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -89,6 +89,7 @@ import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { vmwareCloudAuthApiRef } from '@backstage/core-plugin-api'; import { withApis } from '@backstage/core-plugin-api'; import { z } from 'zod'; +import { ZodObject } from 'zod'; import { ZodSchema } from 'zod'; import { ZodTypeDef } from 'zod'; @@ -391,7 +392,7 @@ export function createApiExtension< configSchema?: PortableSchema; inputs?: TInputs; }, -): ExtensionDefinition; +): ExtensionDefinition>; // @public (undocumented) export namespace createApiExtension { @@ -487,7 +488,7 @@ export function createComponentExtension< inputs: Expand>; }) => ComponentType; }; -}): ExtensionDefinition; +}): ExtensionDefinition>; // @public (undocumented) export namespace createComponentExtension { @@ -511,10 +512,11 @@ export function createComponentRef(options: { export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, - TConfig = never, + TConfigSchema extends z.ZodObject, + TConfig extends z.infer, >( - options: CreateExtensionOptions, -): ExtensionDefinition; + options: CreateExtensionOptions, +): ExtensionDefinition; // @public export function createExtensionBlueprint< @@ -605,7 +607,8 @@ export function createExtensionInput< export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, - TConfig, + TConfigSchema extends z.ZodObject, + TConfig extends z.infer, > { // (undocumented) attachTo: { @@ -613,6 +616,10 @@ export interface CreateExtensionOptions< input: string; }; // (undocumented) + config?: { + schema: (context: { z: typeof z }) => TConfigSchema; + }; + // @deprecated (undocumented) configSchema?: PortableSchema; // (undocumented) disabled?: boolean; @@ -672,9 +679,12 @@ export function createNavItemExtension(options: { routeRef: RouteRef; title: string; icon: IconComponent_2; -}): ExtensionDefinition<{ - title: string; -}>; +}): ExtensionDefinition< + { + title: string; + }, + ZodObject +>; // @public (undocumented) export namespace createNavItemExtension { @@ -696,7 +706,7 @@ export function createNavLogoExtension(options: { namespace?: string; logoIcon: JSX.Element; logoFull: JSX.Element; -}): ExtensionDefinition; +}): ExtensionDefinition>; // @public (undocumented) export namespace createNavLogoExtension { @@ -851,7 +861,7 @@ export function createSubRouteRef< // @public (undocumented) export function createThemeExtension( theme: AppTheme, -): ExtensionDefinition; +): ExtensionDefinition>; // @public (undocumented) export namespace createThemeExtension { @@ -867,7 +877,7 @@ export namespace createThemeExtension { export function createTranslationExtension(options: { name?: string; resource: TranslationResource | TranslationMessages; -}): ExtensionDefinition; +}): ExtensionDefinition>; // @public (undocumented) export namespace createTranslationExtension { @@ -1011,7 +1021,10 @@ export type ExtensionDataValues = { }; // @public (undocumented) -export interface ExtensionDefinition { +export interface ExtensionDefinition< + TConfig, + TConfigSchema extends z.ZodObject = any, +> { // (undocumented) $$type: '@backstage/ExtensionDefinition'; // (undocumented) @@ -1022,6 +1035,8 @@ export interface ExtensionDefinition { // (undocumented) readonly configSchema?: PortableSchema; // (undocumented) + readonly configSchema2?: TConfigSchema; + // (undocumented) readonly disabled: boolean; // (undocumented) readonly kind?: string; diff --git a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts index 2ad1404102..aba3303f2f 100644 --- a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts +++ b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts @@ -33,3 +33,39 @@ export const IconBundleBlueprint = createExtensionBlueprint({ icons: iconsDataRef, }, }); + +IconBundleBlueprint.make({ + name: 'asd', + params: { + icons: { + 'icon-name': () => null, + }, + }, +}); + +IconBundleBlueprint.make({ + name: 'asd', + params: { + icons: { + 'icon-name': () => null, + }, + }, +}); + +IconBundleBlueprint.make({ + name: 'asd', + factory() { + return { + icons: { + 'icon-name': () => null, + }, + }; + }, +}); + +IconBundleBlueprint.make({ + name: 'asd', + factory(f) { + return f({ icons: { 'icon-name': () => null } }); + }, +}); diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index e87f3a638e..3733e44957 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -19,7 +19,7 @@ import { PortableSchema } from '../schema'; import { Expand } from '../types'; import { ExtensionDataRef } from './createExtensionDataRef'; import { ExtensionInput } from './createExtensionInput'; - +import { z } from 'zod'; /** @public */ export type AnyExtensionDataMap = { [name in string]: ExtensionDataRef; @@ -82,6 +82,7 @@ export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, > { kind?: string; namespace?: string; @@ -90,7 +91,11 @@ export interface CreateExtensionOptions< disabled?: boolean; inputs?: TInputs; output: TOutput; + /** @deprecated - use `config.schema` instead */ configSchema?: PortableSchema; + config?: { + schema: TConfigSchema; + }; factory(context: { node: AppNode; config: TConfig; @@ -99,7 +104,7 @@ export interface CreateExtensionOptions< } /** @public */ -export interface ExtensionDefinition { +export interface ExtensionDefinition { $$type: '@backstage/ExtensionDefinition'; readonly kind?: string; readonly namespace?: string; @@ -107,6 +112,9 @@ export interface ExtensionDefinition { readonly attachTo: { id: string; input: string }; readonly disabled: boolean; readonly configSchema?: PortableSchema; + readonly config?: { + schema: TConfigSchema; + }; } /** @internal */ @@ -144,9 +152,10 @@ export function toInternalExtensionDefinition( export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, - TConfig = never, + TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, >( - options: CreateExtensionOptions, + options: CreateExtensionOptions, ): ExtensionDefinition { return { $$type: '@backstage/ExtensionDefinition', @@ -159,6 +168,7 @@ export function createExtension< inputs: options.inputs ?? {}, output: options.output, configSchema: options.configSchema, + config: options.config, factory({ inputs, ...rest }) { // TODO: Simplify this, but TS wouldn't infer the input type for some reason return options.factory({ diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index fb9081f7f8..61227c7dc1 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -15,7 +15,6 @@ */ import { AppNode } from '../apis'; -import { PortableSchema } from '../schema'; import { Expand } from '../types'; import { AnyExtensionDataMap, @@ -25,6 +24,7 @@ import { ResolvedExtensionInputs, createExtension, } from './createExtension'; +import { z } from 'zod'; /** * @public @@ -33,7 +33,7 @@ export interface CreateExtensionBlueprintOptions< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap, > { kind: string; @@ -42,12 +42,16 @@ export interface CreateExtensionBlueprintOptions< disabled?: boolean; inputs?: TInputs; output: TOutput; - configSchema?: PortableSchema; + config?: { + schema: TConfigSchema; + }; factory( params: TParams, context: { node: AppNode; - config: TConfig; + config: { + [key in keyof TConfigSchema]: z.infer>; + }; inputs: Expand>; }, ): Expand>; @@ -62,7 +66,7 @@ export interface ExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap, > { dataRefs: TDataRefs; @@ -73,7 +77,11 @@ export interface ExtensionBlueprint< * You must either pass `params` directly, or define a `factory` that can * optionally call the original factory with the same params. */ - make( + make< + TExtensionConfigSchema extends { + [key: string]: (zImpl: typeof z) => z.ZodTypeAny; + }, + >( args: { namespace?: string; name?: string; @@ -81,20 +89,30 @@ export interface ExtensionBlueprint< disabled?: boolean; inputs?: TInputs; output?: TOutput; - configSchema?: PortableSchema; + config?: { + schema: TExtensionConfigSchema; + }; } & ( | { factory( originalFactory: ( params: TParams, context?: { - config?: TConfig; + config?: { + [key in keyof TConfigSchema]: z.infer< + ReturnType + >; + }; inputs?: Expand>; }, ) => Expand>, context: { node: AppNode; - config: TConfig; + config: { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }; inputs: Expand>; }, ): Expand>; @@ -103,7 +121,14 @@ export interface ExtensionBlueprint< params: TParams; } ), - ): ExtensionDefinition; + ): ExtensionDefinition< + { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }, + TExtensionConfigSchema + >; } /** @@ -113,7 +138,7 @@ class ExtensionBlueprintImpl< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap, > { constructor( @@ -121,7 +146,7 @@ class ExtensionBlueprintImpl< TParams, TInputs, TOutput, - TConfig, + TConfigSchema, TDataRefs >, ) { @@ -130,30 +155,49 @@ class ExtensionBlueprintImpl< dataRefs: TDataRefs; - public make(args: { + public make< + TExtensionConfigSchema extends TConfigSchema = TConfigSchema, + >(args: { namespace?: string; name?: string; attachTo?: { id: string; input: string }; disabled?: boolean; inputs?: TInputs; output?: TOutput; - configSchema?: PortableSchema; params?: TParams; + config?: { + schema: TConfigSchema; + }; factory?( originalFactory: ( params: TParams, context?: { - config?: TConfig; + config?: { + [key in keyof TConfigSchema]: z.infer< + ReturnType + >; + }; inputs?: Expand>; }, ) => Expand>, context: { node: AppNode; - config: TConfig; + config: { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }; inputs: Expand>; }, ): Expand>; - }): ExtensionDefinition { + }): ExtensionDefinition< + { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }, + TExtensionConfigSchema + > { return createExtension({ kind: this.options.kind, namespace: args.namespace ?? this.options.namespace, @@ -162,14 +206,18 @@ class ExtensionBlueprintImpl< disabled: args.disabled ?? this.options.disabled, inputs: args.inputs ?? this.options.inputs, output: args.output ?? this.options.output, - configSchema: args.configSchema ?? this.options.configSchema, // TODO: some config merging or smth + config: args.config, factory: ({ node, config, inputs }) => { if (args.factory) { return args.factory( ( innerParams: TParams, innerContext?: { - config?: TConfig; + config?: { + [key in keyof TConfigSchema]: z.infer< + ReturnType + >; + }; inputs?: Expand>; }, ) => @@ -207,16 +255,16 @@ export function createExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap = never, >( options: CreateExtensionBlueprintOptions< TParams, TInputs, TOutput, - TConfig, + TConfigSchema, TDataRefs >, -): ExtensionBlueprint { +): ExtensionBlueprint { return new ExtensionBlueprintImpl(options); } diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index a98879fbba..d6be346002 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -102,11 +102,11 @@ export class ExtensionTester { ...output, path: coreExtensionData.routePath, }, - factory: params => ({ + factory: (params: any) => ({ ...factory(params), path: '/', }), - }); + } as any); tester.add(extension, options); return tester; } diff --git a/plugins/catalog-graph/api-report-alpha.md b/plugins/catalog-graph/api-report-alpha.md index 3895f12fcf..afd03965ae 100644 --- a/plugins/catalog-graph/api-report-alpha.md +++ b/plugins/catalog-graph/api-report-alpha.md @@ -4,8 +4,76 @@ ```ts import { BackstagePlugin } from '@backstage/frontend-plugin-api'; +import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; +import { objectUtil } from 'zod'; import { RouteRef } from '@backstage/frontend-plugin-api'; +import { ZodArray } from 'zod'; +import { ZodBoolean } from 'zod'; +import { ZodEnum } from 'zod'; +import { ZodNativeEnum } from 'zod'; +import { ZodNumber } from 'zod'; +import { ZodOptional } from 'zod'; +import { ZodString } from 'zod'; +import { ZodTuple } from 'zod'; + +// Warning: (ae-missing-release-tag) "CatalogGraphEntityCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const CatalogGraphEntityCard: ExtensionDefinition< + { + filter?: string | undefined; + height?: number | undefined; + curve?: 'curveStepBefore' | 'curveMonotoneX' | undefined; + direction?: Direction | undefined; + title?: string | undefined; + zoom?: 'disabled' | 'enabled' | 'enable-on-click' | undefined; + relations?: string[] | undefined; + maxDepth?: number | undefined; + kinds?: string[] | undefined; + unidirectional?: boolean | undefined; + mergeRelations?: boolean | undefined; + relationPairs?: [string, string][] | undefined; + }, + objectUtil.extendShape< + objectUtil.extendShape< + { + filter: ZodOptional; + }, + { + title: ZodOptional; + height: ZodOptional; + } + >, + { + kinds: ZodOptional>; + relations: ZodOptional>; + maxDepth: ZodOptional; + unidirectional: ZodOptional; + mergeRelations: ZodOptional; + direction: ZodOptional>; + relationPairs: ZodOptional< + ZodArray, 'many'> + >; + zoom: ZodOptional>; + curve: ZodOptional>; + } + >, + { + filter?: string | undefined; + height?: number | undefined; + curve?: 'curveStepBefore' | 'curveMonotoneX' | undefined; + direction?: Direction | undefined; + title?: string | undefined; + zoom?: 'disabled' | 'enabled' | 'enable-on-click' | undefined; + relations?: string[] | undefined; + maxDepth?: number | undefined; + kinds?: string[] | undefined; + unidirectional?: boolean | undefined; + mergeRelations?: boolean | undefined; + relationPairs?: [string, string][] | undefined; + } +>; // @public (undocumented) const _default: BackstagePlugin< @@ -25,5 +93,9 @@ const _default: BackstagePlugin< >; export default _default; +// Warnings were encountered during analysis: +// +// src/alpha.d.ts:6:5 - (ae-forgotten-export) The symbol "Direction" needs to be exported by the entry point alpha.d.ts + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-graph/src/alpha.tsx b/plugins/catalog-graph/src/alpha.tsx index 6d8429332e..cf663406fa 100644 --- a/plugins/catalog-graph/src/alpha.tsx +++ b/plugins/catalog-graph/src/alpha.tsx @@ -24,7 +24,7 @@ import { compatWrapper, convertLegacyRouteRef, } from '@backstage/core-compat-api'; -import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; +import { EntityCardBlueprint } from '@backstage/plugin-catalog-react/alpha'; import { catalogGraphRouteRef, catalogEntityRouteRef } from './routes'; import { Direction } from './components'; @@ -46,24 +46,67 @@ function getEntityGraphRelationsConfigSchema( }); } -const CatalogGraphEntityCard = createEntityCardExtension({ +export const CatalogGraphEntityCard = EntityCardBlueprint.make({ name: 'relations', - configSchema: createSchemaFromZod(z => - z - .object({ - // Filter is a config required to all entity cards - filter: z.string().optional(), - title: z.string().optional(), - height: z.number().optional(), - // Skipping a "variant" config for now, defaulting to "gridItem" in the component - // For more details, see this comment: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252 - }) - .merge(getEntityGraphRelationsConfigSchema(z)), - ), - loader: async ({ config: { filter, ...props } }) => - import('./components/CatalogGraphCard').then(m => - compatWrapper(), - ), + // configSchema: origSchema => + // createSchemaFromZod(z => + // z + // .object({ + // // Filter is a config required to all entity cards + // // filter: z.string().optional(), + // title: z.string().optional(), + // height: z.number().optional(), + // // Skipping a "variant" config for now, defaulting to "gridItem" in the component + // // For more details, see this comment: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252 + // }) + // .merge(getEntityGraphRelationsConfigSchema(z)) + // .merge(origSchema), + // ), + + // config: { + // schema: ({ z, parent }) => + // parent + // .merge({ + // title: z.string().optional(), + // height: z.number().optional(), + // }) + // .merge(getEntityGraphRelationsConfigSchema(z)), + // }, + + // config: { + // schema: ({ z, parent }) => + // parent + // .extend({ + // title: z.string().optional(), + // height: z.number().optional(), + // }) + // .merge(getEntityGraphRelationsConfigSchema(z)), + // // .merge(parent) + // }, + + // TODO: implement this and check the types. 👋 zod types. + config: { + schema: { + title: z => z.string().optional(), + height: z => z.number().optional(), + }, + }, + + // config: { + // schema: z => ({ + // title: z.string().optional(), + // height: z.number().optional(), + // }), + // }, + + factory(origFactory, { config: { filter: _, ...props } }) { + return origFactory({ + loader: async () => + import('./components/CatalogGraphCard').then(m => + compatWrapper(), + ), + }); + }, }); const CatalogGraphPage = createPageExtension({ diff --git a/plugins/catalog-react/api-report-alpha.md b/plugins/catalog-react/api-report-alpha.md index d2bfb29458..ccf8205f59 100644 --- a/plugins/catalog-react/api-report-alpha.md +++ b/plugins/catalog-react/api-report-alpha.md @@ -3,17 +3,20 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -/// - import { AnyExtensionInputMap } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { Entity } from '@backstage/catalog-model'; +import { ExtensionBlueprint } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { PortableSchema } from '@backstage/frontend-plugin-api'; +import { default as React_2 } from 'react'; import { ResolvedExtensionInputs } from '@backstage/frontend-plugin-api'; import { ResourcePermission } from '@backstage/plugin-permission-common'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; +import { ZodOptional } from 'zod'; +import { ZodRawShape } from 'zod'; +import { ZodString } from 'zod'; // @alpha (undocumented) export const catalogExtensionData: { @@ -115,7 +118,7 @@ export function createEntityCardExtension< config: TConfig; inputs: Expand>; }) => Promise; -}): ExtensionDefinition; +}): ExtensionDefinition; // @alpha (undocumented) export function createEntityContentExtension< @@ -138,11 +141,48 @@ export function createEntityContentExtension< loader: (options: { inputs: Expand>; }) => Promise; -}): ExtensionDefinition<{ - title: string; - path: string; - filter?: string | undefined; -}>; +}): ExtensionDefinition< + { + title: string; + path: string; + filter?: string | undefined; + }, + ZodRawShape +>; + +// @alpha (undocumented) +export const EntityCardBlueprint: ExtensionBlueprint< + { + filter?: string | ((entity: Entity) => boolean) | undefined; + loader: () => Promise; + }, + AnyExtensionInputMap, + { + element: ConfigurableExtensionDataRef< + 'core.reactElement', + React_2.JSX.Element, + {} + >; + filterFunction: ConfigurableExtensionDataRef< + 'catalog.entity-filter-function', + (entity: Entity) => boolean, + ((entity: Entity) => boolean) & { + optional: true; + } + >; + filterExpression: ConfigurableExtensionDataRef< + 'catalog.entity-filter-expression', + string, + string & { + optional: true; + } + >; + }, + { + filter: ZodOptional; + }, + never +>; // @alpha export function isOwnerOf(owner: Entity, entity: Entity): boolean; diff --git a/plugins/catalog-react/src/alpha.tsx b/plugins/catalog-react/src/alpha.tsx index e81b8e5ebf..f397c76ce0 100644 --- a/plugins/catalog-react/src/alpha.tsx +++ b/plugins/catalog-react/src/alpha.tsx @@ -22,6 +22,7 @@ import { RouteRef, coreExtensionData, createExtension, + createExtensionBlueprint, createExtensionDataRef, createSchemaFromZod, } from '@backstage/frontend-plugin-api'; @@ -47,6 +48,49 @@ export const catalogExtensionData = { }), }; +/** @alpha */ +export const EntityCardBlueprint = createExtensionBlueprint({ + kind: 'entity-card', + attachTo: { id: 'entity-content:catalog/overview', input: 'cards' }, + // configSchema: createSchemaFromZod(z => + // z.object({ + // filter: z.string().optional(), + // }), + // ), + config: { + schema: { + filter: z => z.string().optional(), + }, + }, + output: { + element: coreExtensionData.reactElement, + filterFunction: catalogExtensionData.entityFilterFunction.optional(), + filterExpression: catalogExtensionData.entityFilterExpression.optional(), + }, + factory( + params: { + filter?: + | typeof catalogExtensionData.entityFilterFunction.T + | typeof catalogExtensionData.entityFilterExpression.T; + loader: () => Promise; + }, + { node, config }, + ) { + const ExtensionComponent = lazy(() => + params.loader().then(element => ({ default: () => element })), + ); + + return { + element: ( + + + + ), + ...mergeFilters({ config, options: params }), + }; + }, +}); + // TODO: Figure out how to merge with provided config schema /** @alpha */ export function createEntityCardExtension< @@ -154,6 +198,13 @@ export function createEntityContentExtension< filter: z.string().optional(), }), ), + // config: { + // schema: ({ z }) => ({ + // path: z.string().default(options.defaultPath), + // title: z.string().default(options.defaultTitle), + // filter: z.string().optional(), + // }), + // }, factory({ config, inputs, node }) { const ExtensionComponent = lazy(() => options diff --git a/plugins/catalog/api-report-alpha.md b/plugins/catalog/api-report-alpha.md index 102e2a7aa3..03711b7d3d 100644 --- a/plugins/catalog/api-report-alpha.md +++ b/plugins/catalog/api-report-alpha.md @@ -12,6 +12,39 @@ import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; import { PortableSchema } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; +import { ZodObject } from 'zod'; + +// Warning: (ae-missing-release-tag) "catalogAboutEntityCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const catalogAboutEntityCard: ExtensionDefinition< + { + filter?: string | undefined; + }, + ZodObject +>; + +// Warning: (ae-missing-release-tag) "catalogLinksEntityCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const catalogLinksEntityCard: ExtensionDefinition< + { + filter?: string | undefined; + }, + ZodObject +>; + +// Warning: (ae-missing-release-tag) "catalogOverviewEntityContent" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const catalogOverviewEntityContent: ExtensionDefinition< + { + title: string; + path: string; + filter?: string | undefined; + }, + ZodObject +>; // @alpha (undocumented) export const catalogTranslationRef: TranslationRef< @@ -106,7 +139,7 @@ export function createCatalogFilterExtension< inputs?: TInputs; configSchema?: PortableSchema; loader: (options: { config: TConfig }) => Promise; -}): ExtensionDefinition; +}): ExtensionDefinition>; // @alpha (undocumented) const _default: BackstagePlugin< diff --git a/plugins/catalog/src/alpha/index.ts b/plugins/catalog/src/alpha/index.ts index 06a78ec6ea..acf61865ba 100644 --- a/plugins/catalog/src/alpha/index.ts +++ b/plugins/catalog/src/alpha/index.ts @@ -16,3 +16,5 @@ export { default } from './plugin'; export { createCatalogFilterExtension } from './createCatalogFilterExtension'; +export { catalogAboutEntityCard, catalogLinksEntityCard } from './entityCards'; +export { catalogOverviewEntityContent } from './entityContents'; diff --git a/plugins/search-react/api-report-alpha.md b/plugins/search-react/api-report-alpha.md index aea85d0f81..6160759042 100644 --- a/plugins/search-react/api-report-alpha.md +++ b/plugins/search-react/api-report-alpha.md @@ -11,6 +11,7 @@ import { ListItemProps } from '@material-ui/core/ListItem'; import { PortableSchema } from '@backstage/frontend-plugin-api'; import { SearchDocument } from '@backstage/plugin-search-common'; import { SearchResult } from '@backstage/plugin-search-common'; +import { ZodObject } from 'zod'; // @alpha (undocumented) export type BaseSearchResultListItemProps = T & { @@ -25,7 +26,7 @@ export function createSearchResultListItemExtension< }, >( options: SearchResultItemExtensionOptions, -): ExtensionDefinition; +): ExtensionDefinition>; // @alpha (undocumented) export namespace createSearchResultListItemExtension { diff --git a/plugins/search/api-report-alpha.md b/plugins/search/api-report-alpha.md index db2999ba25..ade5f530ef 100644 --- a/plugins/search/api-report-alpha.md +++ b/plugins/search/api-report-alpha.md @@ -6,6 +6,7 @@ import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; +import { ZodObject } from 'zod'; // @alpha (undocumented) const _default: BackstagePlugin< @@ -17,18 +18,27 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const searchApi: ExtensionDefinition<{}>; +export const searchApi: ExtensionDefinition< + {}, + ZodObject +>; // @alpha (undocumented) -export const searchNavItem: ExtensionDefinition<{ - title: string; -}>; +export const searchNavItem: ExtensionDefinition< + { + title: string; + }, + ZodObject +>; // @alpha (undocumented) -export const searchPage: ExtensionDefinition<{ - path: string; - noTrack: boolean; -}>; +export const searchPage: ExtensionDefinition< + { + path: string; + noTrack: boolean; + }, + any +>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/techdocs/api-report-alpha.md b/plugins/techdocs/api-report-alpha.md index cf9f5fa9a3..fc57370a53 100644 --- a/plugins/techdocs/api-report-alpha.md +++ b/plugins/techdocs/api-report-alpha.md @@ -6,6 +6,7 @@ import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; +import { ZodObject } from 'zod'; // @alpha (undocumented) const _default: BackstagePlugin< @@ -23,13 +24,16 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const techDocsSearchResultListItemExtension: ExtensionDefinition<{ - lineClamp: number; - noTrack: boolean; - asListItem: boolean; - asLink: boolean; - title?: string | undefined; -}>; +export const techDocsSearchResultListItemExtension: ExtensionDefinition< + { + lineClamp: number; + noTrack: boolean; + asListItem: boolean; + asLink: boolean; + title?: string | undefined; + }, + ZodObject +>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/user-settings/api-report-alpha.md b/plugins/user-settings/api-report-alpha.md index b06fd1e583..db4373fd43 100644 --- a/plugins/user-settings/api-report-alpha.md +++ b/plugins/user-settings/api-report-alpha.md @@ -7,6 +7,7 @@ import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; +import { ZodObject } from 'zod'; // @alpha (undocumented) const _default: BackstagePlugin< @@ -18,9 +19,12 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const settingsNavItem: ExtensionDefinition<{ - title: string; -}>; +export const settingsNavItem: ExtensionDefinition< + { + title: string; + }, + ZodObject +>; // @alpha (undocumented) export const userSettingsTranslationRef: TranslationRef<