From 5890016e8ae56d959a3a7c8ce4b1d63c692ef22a Mon Sep 17 00:00:00 2001 From: Matt Benson Date: Fri, 7 Feb 2025 19:25:05 -0600 Subject: [PATCH] add api to retrieve template extensions info from scaffolder-backend Signed-off-by: Matt Benson --- .changeset/strange-planes-kneel.md | 6 ++ plugins/scaffolder-react/report.api.md | 51 ++++++++++++++-- plugins/scaffolder-react/src/api/types.ts | 72 ++++++++++++++++++++++- plugins/scaffolder/report.api.md | 3 + plugins/scaffolder/src/api.ts | 12 ++++ 5 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 .changeset/strange-planes-kneel.md diff --git a/.changeset/strange-planes-kneel.md b/.changeset/strange-planes-kneel.md new file mode 100644 index 0000000000..8e57057aee --- /dev/null +++ b/.changeset/strange-planes-kneel.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-react': minor +'@backstage/plugin-scaffolder': minor +--- + +add api to retrieve template extensions info from scaffolder-backend diff --git a/plugins/scaffolder-react/report.api.md b/plugins/scaffolder-react/report.api.md index d62a2b43d4..23a8a5975d 100644 --- a/plugins/scaffolder-react/report.api.md +++ b/plugins/scaffolder-react/report.api.md @@ -55,11 +55,8 @@ export type Action = { examples?: ActionExample[]; }; -// @public -export type ActionExample = { - description: string; - example: string; -}; +// @public @deprecated +export type ActionExample = ScaffolderUsageExample; // @public export function createScaffolderFieldExtension< @@ -168,6 +165,15 @@ export type LayoutTemplate = NonNullable< // @public export type ListActionsResponse = Array; +// @public +export type ListTemplateExtensionsResponse = { + filters: Record; + globals: { + functions: Record; + values: Record; + }; +}; + // @public export type LogEvent = { type: 'log' | 'completion' | 'cancelled' | 'recovered'; @@ -241,6 +247,7 @@ export interface ScaffolderApi { tasks: ScaffolderTask[]; totalTasks?: number; }>; + listTemplateExtensions?(): Promise; retry?(taskId: string): Promise; scaffold( options: ScaffolderScaffoldOptions, @@ -492,6 +499,13 @@ export type ScaffolderTaskStatus = | 'processing' | 'skipped'; +// @public +export type ScaffolderUsageExample = { + description?: string; + example: string; + notes?: string; +}; + // @public export interface ScaffolderUseTemplateSecrets { // (undocumented) @@ -523,6 +537,33 @@ export type TaskStream = { output?: ScaffolderTaskOutput; }; +// @public +export type TemplateFilter = { + description?: string; + schema?: { + input?: JSONSchema7; + arguments?: JSONSchema7[]; + output?: JSONSchema7; + }; + examples?: ScaffolderUsageExample[]; +}; + +// @public +export type TemplateGlobalFunction = { + description?: string; + schema?: { + arguments?: JSONSchema7[]; + output?: JSONSchema7; + }; + examples?: ScaffolderUsageExample[]; +}; + +// @public +export type TemplateGlobalValue = { + description?: string; + value: JsonValue; +}; + // @public (undocumented) export type TemplateGroupFilter = { title?: React.ReactNode; diff --git a/plugins/scaffolder-react/src/api/types.ts b/plugins/scaffolder-react/src/api/types.ts index 8e4d989a55..cb73704010 100644 --- a/plugins/scaffolder-react/src/api/types.ts +++ b/plugins/scaffolder-react/src/api/types.ts @@ -45,15 +45,24 @@ export type ScaffolderTask = { }; /** - * A single action example + * A single scaffolder usage example * * @public */ -export type ActionExample = { - description: string; +export type ScaffolderUsageExample = { + description?: string; example: string; + notes?: string; }; +/** + * A single action example + * + * @public + * @deprecated in favor of ScaffolderUsageExample + */ +export type ActionExample = ScaffolderUsageExample; + /** * The response shape for a single action in the `listActions` call to the `scaffolder-backend` * @@ -76,6 +85,58 @@ export type Action = { */ export type ListActionsResponse = Array; +/** + * The response shape for a single filter in the `listTemplateExtensions` call to the `scaffolder-backend` + * + * @public + */ +export type TemplateFilter = { + description?: string; + schema?: { + input?: JSONSchema7; + arguments?: JSONSchema7[]; + output?: JSONSchema7; + }; + examples?: ScaffolderUsageExample[]; +}; + +/** + * The response shape for a single global function in the `listTemplateExtensions` call to the `scaffolder-backend` + * + * @public + */ +export type TemplateGlobalFunction = { + description?: string; + schema?: { + arguments?: JSONSchema7[]; + output?: JSONSchema7; + }; + examples?: ScaffolderUsageExample[]; +}; + +/** + * The response shape for a single global value in the `listTemplateExtensions` call to the `scaffolder-backend` + * + * @public + */ +export type TemplateGlobalValue = { + description?: string; + value: JsonValue; +}; + +/** + * The response shape for the `listTemplateExtensions` call to the `scaffolder-backend` + * + * @public + */ +export type ListTemplateExtensionsResponse = { + filters: Record; + globals: { + functions: Record; + values: Record; + }; +}; + /** @public */ export type ScaffolderOutputLink = { title?: string; @@ -236,6 +297,11 @@ export interface ScaffolderApi { */ listActions(): Promise; + /** + * Returns a structure describing the available templating extensions. + */ + listTemplateExtensions?(): Promise; + streamLogs(options: ScaffolderStreamLogsOptions): Observable; dryRun?(options: ScaffolderDryRunOptions): Promise; diff --git a/plugins/scaffolder/report.api.md b/plugins/scaffolder/report.api.md index c51423ed83..379e6a98b9 100644 --- a/plugins/scaffolder/report.api.md +++ b/plugins/scaffolder/report.api.md @@ -25,6 +25,7 @@ import { JSX as JSX_2 } from 'react'; import { LayoutOptions as LayoutOptions_2 } from '@backstage/plugin-scaffolder-react'; import { LayoutTemplate as LayoutTemplate_2 } from '@backstage/plugin-scaffolder-react'; import { ListActionsResponse as ListActionsResponse_2 } from '@backstage/plugin-scaffolder-react'; +import { ListTemplateExtensionsResponse } from '@backstage/plugin-scaffolder-react'; import { LogEvent as LogEvent_2 } from '@backstage/plugin-scaffolder-react'; import { Observable } from '@backstage/types'; import { PathParams } from '@backstage/core-plugin-api'; @@ -561,6 +562,8 @@ export class ScaffolderClient implements ScaffolderApi_2 { totalTasks?: number; }>; // (undocumented) + listTemplateExtensions(): Promise; + // (undocumented) retry?(taskId: string): Promise; // (undocumented) scaffold( diff --git a/plugins/scaffolder/src/api.ts b/plugins/scaffolder/src/api.ts index 01e163bb30..85450b012a 100644 --- a/plugins/scaffolder/src/api.ts +++ b/plugins/scaffolder/src/api.ts @@ -24,6 +24,7 @@ import { ResponseError } from '@backstage/errors'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { ListActionsResponse, + ListTemplateExtensionsResponse, LogEvent, ScaffolderApi, ScaffolderDryRunOptions, @@ -324,6 +325,17 @@ export class ScaffolderClient implements ScaffolderApi { return await response.json(); } + async listTemplateExtensions(): Promise { + const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder'); + const response = await this.fetchApi.fetch( + `${baseUrl}/v2/template-extensions`, + ); + if (!response.ok) { + throw ResponseError.fromResponse(response); + } + return response.json(); + } + async cancelTask(taskId: string): Promise { const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder'); const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}/cancel`;