diff --git a/plugins/scaffolder-common/report.api.md b/plugins/scaffolder-common/report.api.md index 8d7a61910d..3aa7e08121 100644 --- a/plugins/scaffolder-common/report.api.md +++ b/plugins/scaffolder-common/report.api.md @@ -77,6 +77,10 @@ export interface TemplateEntityV1beta3 extends Entity { type: string; presentation?: TemplatePresentationV1beta3; EXPERIMENTAL_recovery?: TemplateRecoveryV1beta3; + EXPERIMENTAL_formDecorators?: { + id: string; + input?: JsonObject; + }[]; parameters?: TemplateParametersV1beta3 | TemplateParametersV1beta3[]; steps: Array; output?: { diff --git a/plugins/scaffolder-react/report-alpha.api.md b/plugins/scaffolder-react/report-alpha.api.md index 7084625ad4..092217abe8 100644 --- a/plugins/scaffolder-react/report-alpha.api.md +++ b/plugins/scaffolder-react/report-alpha.api.md @@ -5,6 +5,7 @@ ```ts /// +import { AnyApiRef } from '@backstage/core-plugin-api'; import { ApiHolder } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; @@ -75,6 +76,35 @@ export function createFormField< TUiOptions extends z.ZodType, >(opts: FormFieldExtensionData): FormField; +// @alpha +export function createScaffolderFormDecorator< + TDeps extends { + [key in string]: AnyApiRef; + }, + TInputSchema extends { + [key in string]: (zImpl: typeof z) => z.ZodType; + }, + TInput extends {} = { + [key in keyof TInputSchema]: z.infer>; + }, +>(options: { + id: string; + schema?: { + input?: TInputSchema; + }; + deps?: TDeps; + fn: ( + ctx: ScaffolderFormDecoratorContext, + deps: TDeps extends { + [key in string]: AnyApiRef; + } + ? { + [key in keyof TDeps]: TDeps[key]['T']; + } + : never, + ) => Promise; +}): ScaffolderFormDecorator; + // @alpha export const DefaultTemplateOutputs: (props: { output?: ScaffolderTaskOutput; @@ -190,6 +220,50 @@ export interface ScaffolderFieldProps { required?: boolean; } +// @alpha (undocumented) +export type ScaffolderFormDecorator< + TInputSchema extends { + [key in string]: (zImpl: typeof z) => z.ZodType; + } = {}, + TDeps extends { + [key in string]: AnyApiRef; + } = { + [key in string]: AnyApiRef; + }, + TInput extends {} = { + [key in keyof TInputSchema]: z.infer>; + }, +> = { + version: 'v1'; + id: string; + schema?: { + input?: TInputSchema; + }; + deps?: TDeps; + fn: ( + ctx: ScaffolderFormDecoratorContext, + deps: TDeps extends { + [key in string]: AnyApiRef; + } + ? { + [key in keyof TDeps]: TDeps[key]['T']; + } + : never, + ) => Promise; +}; + +// @alpha (undocumented) +export type ScaffolderFormDecoratorContext = { + input: TInput; + formState: Record; + setFormState: ( + fn: (currentState: Record) => Record, + ) => void; + setSecrets: ( + fn: (currentState: Record) => Record, + ) => void; +}; + // @alpha (undocumented) export function ScaffolderPageContextMenu( props: ScaffolderPageContextMenuProps, @@ -346,9 +420,9 @@ export const useFormDataFromQuery: ( // @alpha (undocumented) export const useTemplateParameterSchema: (templateRef: string) => { - manifest: TemplateParameterSchema | undefined; + manifest?: TemplateParameterSchema | undefined; loading: boolean; - error: Error | undefined; + error?: Error | undefined; }; // @alpha diff --git a/plugins/scaffolder-react/report.api.md b/plugins/scaffolder-react/report.api.md index 5523b52ad9..1ac2fd279b 100644 --- a/plugins/scaffolder-react/report.api.md +++ b/plugins/scaffolder-react/report.api.md @@ -538,6 +538,10 @@ export type TemplateParameterSchema = { description?: string; schema: JsonObject; }>; + EXPERIMENTAL_formDecorators?: { + id: string; + input?: JsonObject; + }[]; }; // @public diff --git a/plugins/scaffolder-react/src/next/extensions/createScaffolderFormDecorator.ts b/plugins/scaffolder-react/src/next/extensions/createScaffolderFormDecorator.ts index 59c144249a..965cfa6107 100644 --- a/plugins/scaffolder-react/src/next/extensions/createScaffolderFormDecorator.ts +++ b/plugins/scaffolder-react/src/next/extensions/createScaffolderFormDecorator.ts @@ -17,6 +17,7 @@ import { AnyApiRef } from '@backstage/core-plugin-api'; import { JsonValue } from '@backstage/types'; import { z } from 'zod'; +/** @alpha */ export type ScaffolderFormDecoratorContext = { input: TInput; formState: Record; @@ -29,6 +30,7 @@ export type ScaffolderFormDecoratorContext = { ) => void; }; +/** @alpha */ export type ScaffolderFormDecorator< TInputSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType } = {}, TDeps extends { [key in string]: AnyApiRef } = { [key in string]: AnyApiRef }, @@ -53,7 +55,7 @@ export type ScaffolderFormDecorator< /** * Method for creating decorators which can be used to collect * secrets from the user before submitting to the backend. - * @public + * @alpha */ export function createScaffolderFormDecorator< TDeps extends { [key in string]: AnyApiRef }, diff --git a/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts b/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts index 4daba383b0..452e3a67a8 100644 --- a/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts +++ b/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts @@ -17,11 +17,14 @@ import useAsync from 'react-use/esm/useAsync'; import { scaffolderApiRef } from '../../api/ref'; import { useApi } from '@backstage/core-plugin-api'; +import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; /** * @alpha */ -export const useTemplateParameterSchema = (templateRef: string) => { +export const useTemplateParameterSchema = ( + templateRef: string, +): { manifest?: TemplateParameterSchema; loading: boolean; error?: Error } => { const scaffolderApi = useApi(scaffolderApiRef); const { value: manifest,