From a7eb36c6e3837926a6be28a9c6541752b47b13b2 Mon Sep 17 00:00:00 2001 From: Andreas Berger Date: Thu, 16 Mar 2023 18:25:52 +0100 Subject: [PATCH 1/4] Improve type-check for scaffolder output parameters If an action uses zod to define the actions output schema, it is now ensured that `ctx.output` is using only the defined properties Signed-off-by: Andreas Berger --- .changeset/good-papayas-lay.md | 6 + .../api-report.md | 19 +- .../api-report.md | 65 +- .../api-report.md | 15 +- .../api-report.md | 17 +- .../api-report.md | 13 +- plugins/scaffolder-backend/api-report.md | 734 ++++++++++-------- .../actions/builtin/catalog/fetch.ts | 68 +- plugins/scaffolder-node/api-report.md | 31 +- .../src/actions/createTemplateAction.ts | 18 +- plugins/scaffolder-node/src/actions/types.ts | 19 +- 11 files changed, 567 insertions(+), 438 deletions(-) create mode 100644 .changeset/good-papayas-lay.md diff --git a/.changeset/good-papayas-lay.md b/.changeset/good-papayas-lay.md new file mode 100644 index 0000000000..258397a14f --- /dev/null +++ b/.changeset/good-papayas-lay.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +'@backstage/plugin-scaffolder-node': patch +--- + +Improve type-check for scaffolder output parameters diff --git a/plugins/scaffolder-backend-module-cookiecutter/api-report.md b/plugins/scaffolder-backend-module-cookiecutter/api-report.md index 2944f5240e..997e6b00e9 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/api-report.md +++ b/plugins/scaffolder-backend-module-cookiecutter/api-report.md @@ -16,12 +16,15 @@ export function createFetchCookiecutterAction(options: { reader: UrlReader; integrations: ScmIntegrations; containerRunner?: ContainerRunner; -}): TemplateAction<{ - url: string; - targetPath?: string | undefined; - values: JsonObject; - copyWithoutRender?: string[] | undefined; - extensions?: string[] | undefined; - imageName?: string | undefined; -}>; +}): TemplateAction< + { + url: string; + targetPath?: string | undefined; + values: JsonObject; + copyWithoutRender?: string[] | undefined; + extensions?: string[] | undefined; + imageName?: string | undefined; + }, + undefined +>; ``` diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index 6db732fdcc..fcd5fada08 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -9,40 +9,49 @@ import { TemplateAction } from '@backstage/plugin-scaffolder-node'; // @public export const createGitlabProjectAccessTokenAction: (options: { integrations: ScmIntegrationRegistry; -}) => TemplateAction<{ - repoUrl: string; - projectId: string | number; - name: string; - accessLevel: number; - scopes: string[]; - token?: string | undefined; -}>; +}) => TemplateAction< + { + repoUrl: string; + projectId: string | number; + name: string; + accessLevel: number; + scopes: string[]; + token?: string | undefined; + }, + undefined +>; // @public export const createGitlabProjectDeployTokenAction: (options: { integrations: ScmIntegrationRegistry; -}) => TemplateAction<{ - repoUrl: string; - projectId: string | number; - name: string; - username: string; - scopes: string[]; - token?: string | undefined; -}>; +}) => TemplateAction< + { + repoUrl: string; + projectId: string | number; + name: string; + username: string; + scopes: string[]; + token?: string | undefined; + }, + undefined +>; // @public export const createGitlabProjectVariableAction: (options: { integrations: ScmIntegrationRegistry; -}) => TemplateAction<{ - repoUrl: string; - projectId: string | number; - key: string; - value: string; - variableType: string; - variableProtected: boolean; - masked: boolean; - raw: boolean; - environmentScope: string; - token?: string | undefined; -}>; +}) => TemplateAction< + { + repoUrl: string; + projectId: string | number; + key: string; + value: string; + variableType: string; + variableProtected: boolean; + masked: boolean; + raw: boolean; + environmentScope: string; + token?: string | undefined; + }, + undefined +>; ``` diff --git a/plugins/scaffolder-backend-module-rails/api-report.md b/plugins/scaffolder-backend-module-rails/api-report.md index c91daa1344..5c27c8b957 100644 --- a/plugins/scaffolder-backend-module-rails/api-report.md +++ b/plugins/scaffolder-backend-module-rails/api-report.md @@ -15,10 +15,13 @@ export function createFetchRailsAction(options: { integrations: ScmIntegrations; containerRunner: ContainerRunner; allowedImageNames?: string[]; -}): TemplateAction<{ - url: string; - targetPath?: string | undefined; - values: JsonObject; - imageName?: string | undefined; -}>; +}): TemplateAction< + { + url: string; + targetPath?: string | undefined; + values: JsonObject; + imageName?: string | undefined; + }, + undefined +>; ``` diff --git a/plugins/scaffolder-backend-module-sentry/api-report.md b/plugins/scaffolder-backend-module-sentry/api-report.md index ef09bdebc0..3583981b2d 100644 --- a/plugins/scaffolder-backend-module-sentry/api-report.md +++ b/plugins/scaffolder-backend-module-sentry/api-report.md @@ -9,13 +9,16 @@ import { TemplateAction } from '@backstage/plugin-scaffolder-node'; // @public export function createSentryCreateProjectAction(options: { config: Config; -}): TemplateAction<{ - organizationSlug: string; - teamSlug: string; - name: string; - slug?: string | undefined; - authToken?: string | undefined; -}>; +}): TemplateAction< + { + organizationSlug: string; + teamSlug: string; + name: string; + slug?: string | undefined; + authToken?: string | undefined; + }, + undefined +>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/scaffolder-backend-module-yeoman/api-report.md b/plugins/scaffolder-backend-module-yeoman/api-report.md index 562fe52ac2..62a6d62156 100644 --- a/plugins/scaffolder-backend-module-yeoman/api-report.md +++ b/plugins/scaffolder-backend-module-yeoman/api-report.md @@ -7,9 +7,12 @@ import { JsonObject } from '@backstage/types'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; // @public -export function createRunYeomanAction(): TemplateAction<{ - namespace: string; - args?: string[] | undefined; - options?: JsonObject | undefined; -}>; +export function createRunYeomanAction(): TemplateAction< + { + namespace: string; + args?: string[] | undefined; + options?: JsonObject | undefined; + }, + undefined +>; ``` diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index a50bb7a515..62626c551e 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -78,49 +78,66 @@ export function createCatalogRegisterAction(options: { repoContentsUrl: string; catalogInfoPath?: string | undefined; optional?: boolean | undefined; - } + }, + undefined >; // @public -export function createCatalogWriteAction(): TemplateAction_2<{ - entity: {} & { - [k: string]: unknown; - }; - filePath?: string | undefined; -}>; +export function createCatalogWriteAction(): TemplateAction_2< + { + filePath?: string | undefined; + entity: {}; + }, + undefined +>; // @public -export function createDebugLogAction(): TemplateAction_2<{ - message?: string | undefined; - listWorkspace?: boolean | undefined; -}>; +export function createDebugLogAction(): TemplateAction_2< + { + message?: string | undefined; + listWorkspace?: boolean | undefined; + }, + undefined +>; // @public export function createFetchCatalogEntityAction(options: { catalogClient: CatalogApi; -}): TemplateAction_2<{ - entityRef?: string | undefined; - entityRefs?: string[] | undefined; - optional?: boolean | undefined; -}>; +}): TemplateAction_2< + { + optional?: boolean | undefined; + entityRef?: string | undefined; + entityRefs?: string[] | undefined; + }, + { + entities?: any[] | undefined; + entity?: any; + } +>; // @public export function createFetchPlainAction(options: { reader: UrlReader; integrations: ScmIntegrations; -}): TemplateAction_2<{ - url: string; - targetPath?: string | undefined; -}>; +}): TemplateAction_2< + { + url: string; + targetPath?: string | undefined; + }, + undefined +>; // @public export function createFetchPlainFileAction(options: { reader: UrlReader; integrations: ScmIntegrations; -}): TemplateAction_2<{ - url: string; - targetPath: string; -}>; +}): TemplateAction_2< + { + url: string; + targetPath: string; + }, + undefined +>; // @public export function createFetchTemplateAction(options: { @@ -128,57 +145,72 @@ export function createFetchTemplateAction(options: { integrations: ScmIntegrations; additionalTemplateFilters?: Record; additionalTemplateGlobals?: Record; -}): TemplateAction_2<{ - url: string; - targetPath?: string | undefined; - values: any; - templateFileExtension?: string | boolean | undefined; - copyWithoutRender?: string[] | undefined; - copyWithoutTemplating?: string[] | undefined; - cookiecutterCompat?: boolean | undefined; - replace?: boolean | undefined; -}>; +}): TemplateAction_2< + { + url: string; + targetPath?: string | undefined; + values: any; + templateFileExtension?: string | boolean | undefined; + copyWithoutRender?: string[] | undefined; + copyWithoutTemplating?: string[] | undefined; + cookiecutterCompat?: boolean | undefined; + replace?: boolean | undefined; + }, + undefined +>; // @public -export const createFilesystemDeleteAction: () => TemplateAction_2<{ - files: string[]; -}>; +export const createFilesystemDeleteAction: () => TemplateAction_2< + { + files: string[]; + }, + undefined +>; // @public -export const createFilesystemRenameAction: () => TemplateAction_2<{ - files: Array<{ - from: string; - to: string; - overwrite?: boolean; - }>; -}>; +export const createFilesystemRenameAction: () => TemplateAction_2< + { + files: Array<{ + from: string; + to: string; + overwrite?: boolean; + }>; + }, + undefined +>; // @public export function createGithubActionsDispatchAction(options: { integrations: ScmIntegrations; githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2<{ - repoUrl: string; - workflowId: string; - branchOrTagName: string; - workflowInputs?: - | { - [key: string]: string; - } - | undefined; - token?: string | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + workflowId: string; + branchOrTagName: string; + workflowInputs?: + | { + [key: string]: string; + } + | undefined; + token?: string | undefined; + }, + undefined +>; // @public export function createGithubIssuesLabelAction(options: { integrations: ScmIntegrationRegistry; githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2<{ - repoUrl: string; - number: number; - labels: string[]; - token?: string | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + number: number; + labels: string[]; + token?: string | undefined; + }, + undefined +>; // @public export interface CreateGithubPullRequestActionOptions { @@ -203,334 +235,373 @@ export type CreateGithubPullRequestClientFactoryInput = { export function createGithubRepoCreateAction(options: { integrations: ScmIntegrationRegistry; githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2<{ - repoUrl: string; - description?: string | undefined; - homepage?: string | undefined; - access?: string | undefined; - deleteBranchOnMerge?: boolean | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - allowRebaseMerge?: boolean | undefined; - allowSquashMerge?: boolean | undefined; - squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined; - squashMergeCommitMessage?: - | 'PR_BODY' - | 'COMMIT_MESSAGES' - | 'BLANK' - | undefined; - allowMergeCommit?: boolean | undefined; - allowAutoMerge?: boolean | undefined; - requireCodeOwnerReviews?: boolean | undefined; - bypassPullRequestAllowances?: - | { - users?: string[] | undefined; - teams?: string[] | undefined; - apps?: string[] | undefined; - } - | undefined; - requiredApprovingReviewCount?: number | undefined; - restrictions?: - | { - users: string[]; - teams: string[]; - apps?: string[] | undefined; - } - | undefined; - requiredStatusCheckContexts?: string[] | undefined; - requireBranchesToBeUpToDate?: boolean | undefined; - requiredConversationResolution?: boolean | undefined; - repoVisibility?: 'internal' | 'private' | 'public' | undefined; - collaborators?: - | ( - | { - user: string; - access: string; - } - | { - team: string; - access: string; - } - | { - username: string; - access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage'; - } - )[] - | undefined; - hasProjects?: boolean | undefined; - hasWiki?: boolean | undefined; - hasIssues?: boolean | undefined; - token?: string | undefined; - topics?: string[] | undefined; - requireCommitSigning?: boolean | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + description?: string | undefined; + homepage?: string | undefined; + access?: string | undefined; + deleteBranchOnMerge?: boolean | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + allowRebaseMerge?: boolean | undefined; + allowSquashMerge?: boolean | undefined; + squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined; + squashMergeCommitMessage?: + | 'PR_BODY' + | 'COMMIT_MESSAGES' + | 'BLANK' + | undefined; + allowMergeCommit?: boolean | undefined; + allowAutoMerge?: boolean | undefined; + requireCodeOwnerReviews?: boolean | undefined; + bypassPullRequestAllowances?: + | { + users?: string[] | undefined; + teams?: string[] | undefined; + apps?: string[] | undefined; + } + | undefined; + requiredApprovingReviewCount?: number | undefined; + restrictions?: + | { + users: string[]; + teams: string[]; + apps?: string[] | undefined; + } + | undefined; + requiredStatusCheckContexts?: string[] | undefined; + requireBranchesToBeUpToDate?: boolean | undefined; + requiredConversationResolution?: boolean | undefined; + repoVisibility?: 'internal' | 'private' | 'public' | undefined; + collaborators?: + | ( + | { + user: string; + access: string; + } + | { + team: string; + access: string; + } + | { + username: string; + access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage'; + } + )[] + | undefined; + hasProjects?: boolean | undefined; + hasWiki?: boolean | undefined; + hasIssues?: boolean | undefined; + token?: string | undefined; + topics?: string[] | undefined; + requireCommitSigning?: boolean | undefined; + }, + undefined +>; // @public export function createGithubRepoPushAction(options: { integrations: ScmIntegrationRegistry; config: Config; githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2<{ - repoUrl: string; - description?: string | undefined; - defaultBranch?: string | undefined; - protectDefaultBranch?: boolean | undefined; - protectEnforceAdmins?: boolean | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - requireCodeOwnerReviews?: boolean | undefined; - dismissStaleReviews?: boolean | undefined; - bypassPullRequestAllowances?: - | { - users?: string[]; - teams?: string[]; - apps?: string[]; - } - | undefined; - requiredApprovingReviewCount?: number | undefined; - restrictions?: - | { - users: string[]; - teams: string[]; - apps?: string[]; - } - | undefined; - requiredStatusCheckContexts?: string[] | undefined; - requireBranchesToBeUpToDate?: boolean | undefined; - requiredConversationResolution?: boolean | undefined; - sourcePath?: string | undefined; - token?: string | undefined; - requiredCommitSigning?: boolean | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + description?: string | undefined; + defaultBranch?: string | undefined; + protectDefaultBranch?: boolean | undefined; + protectEnforceAdmins?: boolean | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + requireCodeOwnerReviews?: boolean | undefined; + dismissStaleReviews?: boolean | undefined; + bypassPullRequestAllowances?: + | { + users?: string[]; + teams?: string[]; + apps?: string[]; + } + | undefined; + requiredApprovingReviewCount?: number | undefined; + restrictions?: + | { + users: string[]; + teams: string[]; + apps?: string[]; + } + | undefined; + requiredStatusCheckContexts?: string[] | undefined; + requireBranchesToBeUpToDate?: boolean | undefined; + requiredConversationResolution?: boolean | undefined; + sourcePath?: string | undefined; + token?: string | undefined; + requiredCommitSigning?: boolean | undefined; + }, + undefined +>; // @public export function createGithubWebhookAction(options: { integrations: ScmIntegrationRegistry; defaultWebhookSecret?: string; githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2<{ - repoUrl: string; - webhookUrl: string; - webhookSecret?: string | undefined; - events?: string[] | undefined; - active?: boolean | undefined; - contentType?: 'form' | 'json' | undefined; - insecureSsl?: boolean | undefined; - token?: string | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + webhookUrl: string; + webhookSecret?: string | undefined; + events?: string[] | undefined; + active?: boolean | undefined; + contentType?: 'form' | 'json' | undefined; + insecureSsl?: boolean | undefined; + token?: string | undefined; + }, + undefined +>; // @public export function createPublishAzureAction(options: { integrations: ScmIntegrationRegistry; config: Config; -}): TemplateAction_2<{ - repoUrl: string; - description?: string | undefined; - defaultBranch?: string | undefined; - sourcePath?: string | undefined; - token?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + description?: string | undefined; + defaultBranch?: string | undefined; + sourcePath?: string | undefined; + token?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + }, + undefined +>; // @public @deprecated export function createPublishBitbucketAction(options: { integrations: ScmIntegrationRegistry; config: Config; -}): TemplateAction_2<{ - repoUrl: string; - description?: string | undefined; - defaultBranch?: string | undefined; - repoVisibility?: 'private' | 'public' | undefined; - sourcePath?: string | undefined; - enableLFS?: boolean | undefined; - token?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + description?: string | undefined; + defaultBranch?: string | undefined; + repoVisibility?: 'private' | 'public' | undefined; + sourcePath?: string | undefined; + enableLFS?: boolean | undefined; + token?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + }, + undefined +>; // @public export function createPublishBitbucketCloudAction(options: { integrations: ScmIntegrationRegistry; config: Config; -}): TemplateAction_2<{ - repoUrl: string; - description?: string | undefined; - defaultBranch?: string | undefined; - repoVisibility?: 'private' | 'public' | undefined; - sourcePath?: string | undefined; - token?: string | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + description?: string | undefined; + defaultBranch?: string | undefined; + repoVisibility?: 'private' | 'public' | undefined; + sourcePath?: string | undefined; + token?: string | undefined; + }, + undefined +>; // @public export function createPublishBitbucketServerAction(options: { integrations: ScmIntegrationRegistry; config: Config; -}): TemplateAction_2<{ - repoUrl: string; - description?: string | undefined; - defaultBranch?: string | undefined; - repoVisibility?: 'private' | 'public' | undefined; - sourcePath?: string | undefined; - enableLFS?: boolean | undefined; - token?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + description?: string | undefined; + defaultBranch?: string | undefined; + repoVisibility?: 'private' | 'public' | undefined; + sourcePath?: string | undefined; + enableLFS?: boolean | undefined; + token?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + }, + undefined +>; // @public export function createPublishGerritAction(options: { integrations: ScmIntegrationRegistry; config: Config; -}): TemplateAction_2<{ - repoUrl: string; - description: string; - defaultBranch?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - sourcePath?: string | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + description: string; + defaultBranch?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + sourcePath?: string | undefined; + }, + undefined +>; // @public export function createPublishGerritReviewAction(options: { integrations: ScmIntegrationRegistry; config: Config; -}): TemplateAction_2<{ - repoUrl: string; - branch?: string | undefined; - sourcePath?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + branch?: string | undefined; + sourcePath?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + }, + undefined +>; // @public export function createPublishGithubAction(options: { integrations: ScmIntegrationRegistry; config: Config; githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2<{ - repoUrl: string; - description?: string | undefined; - homepage?: string | undefined; - access?: string | undefined; - defaultBranch?: string | undefined; - protectDefaultBranch?: boolean | undefined; - protectEnforceAdmins?: boolean | undefined; - deleteBranchOnMerge?: boolean | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - allowRebaseMerge?: boolean | undefined; - allowSquashMerge?: boolean | undefined; - squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined; - squashMergeCommitMessage?: - | 'PR_BODY' - | 'COMMIT_MESSAGES' - | 'BLANK' - | undefined; - allowMergeCommit?: boolean | undefined; - allowAutoMerge?: boolean | undefined; - sourcePath?: string | undefined; - bypassPullRequestAllowances?: - | { - users?: string[]; - teams?: string[]; - apps?: string[]; - } - | undefined; - requiredApprovingReviewCount?: number | undefined; - restrictions?: - | { - users: string[]; - teams: string[]; - apps?: string[]; - } - | undefined; - requireCodeOwnerReviews?: boolean | undefined; - dismissStaleReviews?: boolean | undefined; - requiredStatusCheckContexts?: string[] | undefined; - requireBranchesToBeUpToDate?: boolean | undefined; - requiredConversationResolution?: boolean | undefined; - repoVisibility?: 'internal' | 'private' | 'public' | undefined; - collaborators?: - | ( - | { - user: string; - access: string; - } - | { - team: string; - access: string; - } - | { - username: string; - access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage'; - } - )[] - | undefined; - hasProjects?: boolean | undefined; - hasWiki?: boolean | undefined; - hasIssues?: boolean | undefined; - token?: string | undefined; - topics?: string[] | undefined; - requiredCommitSigning?: boolean | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + description?: string | undefined; + homepage?: string | undefined; + access?: string | undefined; + defaultBranch?: string | undefined; + protectDefaultBranch?: boolean | undefined; + protectEnforceAdmins?: boolean | undefined; + deleteBranchOnMerge?: boolean | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + allowRebaseMerge?: boolean | undefined; + allowSquashMerge?: boolean | undefined; + squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined; + squashMergeCommitMessage?: + | 'PR_BODY' + | 'COMMIT_MESSAGES' + | 'BLANK' + | undefined; + allowMergeCommit?: boolean | undefined; + allowAutoMerge?: boolean | undefined; + sourcePath?: string | undefined; + bypassPullRequestAllowances?: + | { + users?: string[]; + teams?: string[]; + apps?: string[]; + } + | undefined; + requiredApprovingReviewCount?: number | undefined; + restrictions?: + | { + users: string[]; + teams: string[]; + apps?: string[]; + } + | undefined; + requireCodeOwnerReviews?: boolean | undefined; + dismissStaleReviews?: boolean | undefined; + requiredStatusCheckContexts?: string[] | undefined; + requireBranchesToBeUpToDate?: boolean | undefined; + requiredConversationResolution?: boolean | undefined; + repoVisibility?: 'internal' | 'private' | 'public' | undefined; + collaborators?: + | ( + | { + user: string; + access: string; + } + | { + team: string; + access: string; + } + | { + username: string; + access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage'; + } + )[] + | undefined; + hasProjects?: boolean | undefined; + hasWiki?: boolean | undefined; + hasIssues?: boolean | undefined; + token?: string | undefined; + topics?: string[] | undefined; + requiredCommitSigning?: boolean | undefined; + }, + undefined +>; // @public export const createPublishGithubPullRequestAction: ( options: CreateGithubPullRequestActionOptions, -) => TemplateAction_2<{ - title: string; - branchName: string; - description: string; - repoUrl: string; - draft?: boolean | undefined; - targetPath?: string | undefined; - sourcePath?: string | undefined; - token?: string | undefined; - reviewers?: string[] | undefined; - teamReviewers?: string[] | undefined; -}>; +) => TemplateAction_2< + { + title: string; + branchName: string; + description: string; + repoUrl: string; + draft?: boolean | undefined; + targetPath?: string | undefined; + sourcePath?: string | undefined; + token?: string | undefined; + reviewers?: string[] | undefined; + teamReviewers?: string[] | undefined; + }, + undefined +>; // @public export function createPublishGitlabAction(options: { integrations: ScmIntegrationRegistry; config: Config; -}): TemplateAction_2<{ - repoUrl: string; - defaultBranch?: string | undefined; - repoVisibility?: 'internal' | 'private' | 'public' | undefined; - sourcePath?: string | undefined; - token?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - setUserAsOwner?: boolean | undefined; - topics?: string[] | undefined; -}>; +}): TemplateAction_2< + { + repoUrl: string; + defaultBranch?: string | undefined; + repoVisibility?: 'internal' | 'private' | 'public' | undefined; + sourcePath?: string | undefined; + token?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + setUserAsOwner?: boolean | undefined; + topics?: string[] | undefined; + }, + undefined +>; // @public export const createPublishGitlabMergeRequestAction: (options: { integrations: ScmIntegrationRegistry; -}) => TemplateAction_2<{ - repoUrl: string; - title: string; - description: string; - branchName: string; - sourcePath?: string | undefined; - targetPath?: string | undefined; - token?: string | undefined; - commitAction?: 'update' | 'delete' | 'create' | undefined; - projectid?: string | undefined; - removeSourceBranch?: boolean | undefined; - assignee?: string | undefined; -}>; +}) => TemplateAction_2< + { + repoUrl: string; + title: string; + description: string; + branchName: string; + sourcePath?: string | undefined; + targetPath?: string | undefined; + token?: string | undefined; + commitAction?: 'update' | 'delete' | 'create' | undefined; + projectid?: string | undefined; + removeSourceBranch?: boolean | undefined; + assignee?: string | undefined; + }, + undefined +>; // @public export function createRouter(options: RouterOptions): Promise; @@ -543,14 +614,17 @@ export const createTemplateAction: < TActionInput = TInputSchema extends ZodType ? IReturn : TParams, + TActionOutput = TOutputSchema extends ZodType + ? IReturn_1 + : undefined, >( action: TemplateActionOptions, -) => TemplateAction_2; +) => TemplateAction_2; // @public export function createWaitAction(options?: { maxWaitTime?: Duration | HumanDuration; -}): TemplateAction_2; +}): TemplateAction_2; // @public export type CreateWorkerOptions = { diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts index 1bcbfa0006..d6abeee792 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts @@ -17,6 +17,7 @@ import { CatalogApi } from '@backstage/catalog-client'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import yaml from 'yaml'; +import { z } from 'zod'; const id = 'catalog:fetch'; @@ -63,55 +64,46 @@ export function createFetchCatalogEntityAction(options: { }) { const { catalogClient } = options; - return createTemplateAction<{ - entityRef?: string; - entityRefs?: string[]; - optional?: boolean; - }>({ + return createTemplateAction({ id, description: 'Returns entity or entities from the catalog by entity reference(s)', examples, schema: { - input: { - type: 'object', - properties: { - entityRef: { - type: 'string', - title: 'Entity reference', + input: z.object({ + entityRef: z + .string({ description: 'Entity reference of the entity to get', - }, - entityRefs: { - type: 'array', - title: 'Entity references', + }) + .optional(), + entityRefs: z + .array(z.string(), { description: 'Entity references of the entities to get', - }, - optional: { - title: 'Optional', + }) + .optional(), + optional: z + .boolean({ description: 'Allow the entity or entities to optionally exist. Default: false', - type: 'boolean', - }, - }, - }, - output: { - type: 'object', - properties: { - entity: { - title: 'Entity found by the entity reference', - type: 'object', + }) + .optional(), + }), + output: z.object({ + entity: z + .any({ description: 'Object containing same values used in the Entity schema. Only when used with `entityRef` parameter.', - }, - entities: { - title: 'Entities found by the entity references', - type: 'array', - items: { type: 'object' }, - description: - 'Array containing objects with same values used in the Entity schema. Only when used with `entityRefs` parameter.', - }, - }, - }, + }) + .optional(), + entities: z + .array( + z.any({ + description: + 'Array containing objects with same values used in the Entity schema. Only when used with `entityRefs` parameter.', + }), + ) + .optional(), + }), }, async handler(ctx) { const { entityRef, entityRefs, optional } = ctx.input; diff --git a/plugins/scaffolder-node/api-report.md b/plugins/scaffolder-node/api-report.md index d5b9b73767..6e865e0cd6 100644 --- a/plugins/scaffolder-node/api-report.md +++ b/plugins/scaffolder-node/api-report.md @@ -16,13 +16,19 @@ import { Writable } from 'stream'; import { z } from 'zod'; // @public -export type ActionContext = { +export type ActionContext< + TActionInput extends JsonObject, + TActionOutput extends JsonObject | undefined = undefined, +> = { logger: Logger; logStream: Writable; secrets?: TaskSecrets; workspacePath: string; input: TActionInput; - output(name: string, value: JsonValue): void; + output( + name: TActionOutput extends undefined ? string : KEY, + value: TActionOutput extends undefined ? JsonValue : TActionOutput[KEY], + ): void; createTemporaryDirectory(): Promise; templateInfo?: TemplateInfo; isDryRun?: boolean; @@ -41,9 +47,12 @@ export const createTemplateAction: < TActionInput = TInputSchema extends z.ZodType ? IReturn : TParams, + TActionOutput = TOutputSchema extends z.ZodType + ? IReturn_1 + : undefined, >( action: TemplateActionOptions, -) => TemplateAction; +) => TemplateAction; // @alpha export interface ScaffolderActionsExtensionPoint { @@ -60,7 +69,10 @@ export type TaskSecrets = Record & { }; // @public (undocumented) -export type TemplateAction = { +export type TemplateAction< + TActionInput = unknown, + TActionOutput = undefined, +> = { id: string; description?: string; examples?: { @@ -72,7 +84,7 @@ export type TemplateAction = { input?: Schema; output?: Schema; }; - handler: (ctx: ActionContext) => Promise; + handler: (ctx: ActionContext) => Promise; }; // @public (undocumented) @@ -92,6 +104,13 @@ export type TemplateActionOptions< input?: TInputSchema; output?: TOutputSchema; }; - handler: (ctx: ActionContext) => Promise; + handler: ( + ctx: ActionContext< + TActionInput, + TOutputSchema extends z.ZodType + ? IReturn + : undefined + >, + ) => Promise; }; ``` diff --git a/plugins/scaffolder-node/src/actions/createTemplateAction.ts b/plugins/scaffolder-node/src/actions/createTemplateAction.ts index 8c98042d8c..3540e9220d 100644 --- a/plugins/scaffolder-node/src/actions/createTemplateAction.ts +++ b/plugins/scaffolder-node/src/actions/createTemplateAction.ts @@ -33,7 +33,14 @@ export type TemplateActionOptions< input?: TInputSchema; output?: TOutputSchema; }; - handler: (ctx: ActionContext) => Promise; + handler: ( + ctx: ActionContext< + TActionInput, + TOutputSchema extends z.ZodType + ? IReturn + : undefined + >, + ) => Promise; }; /** @@ -48,9 +55,12 @@ export const createTemplateAction = < TActionInput = TInputSchema extends z.ZodType ? IReturn : TParams, + TActionOutput = TOutputSchema extends z.ZodType + ? IReturn + : undefined, >( action: TemplateActionOptions, -): TemplateAction => { +): TemplateAction => { const inputSchema = action.schema?.input && 'safeParseAsync' in action.schema.input ? zodToJsonSchema(action.schema.input) @@ -61,7 +71,7 @@ export const createTemplateAction = < ? zodToJsonSchema(action.schema.output) : action.schema?.output; - const templateAction = { + return { ...action, schema: { ...action.schema, @@ -69,6 +79,4 @@ export const createTemplateAction = < output: outputSchema, }, }; - - return templateAction; }; diff --git a/plugins/scaffolder-node/src/actions/types.ts b/plugins/scaffolder-node/src/actions/types.ts index 8827aaf98c..c81fafd9ad 100644 --- a/plugins/scaffolder-node/src/actions/types.ts +++ b/plugins/scaffolder-node/src/actions/types.ts @@ -17,7 +17,7 @@ import { Logger } from 'winston'; import { Writable } from 'stream'; import { JsonObject, JsonValue } from '@backstage/types'; -import { TaskSecrets } from '../tasks/types'; +import { TaskSecrets } from '../tasks'; import { TemplateInfo } from '@backstage/plugin-scaffolder-common'; import { UserEntity } from '@backstage/catalog-model'; import { Schema } from 'jsonschema'; @@ -26,13 +26,19 @@ import { Schema } from 'jsonschema'; * ActionContext is passed into scaffolder actions. * @public */ -export type ActionContext = { +export type ActionContext< + TActionInput extends JsonObject, + TActionOutput extends JsonObject | undefined = undefined, +> = { logger: Logger; logStream: Writable; secrets?: TaskSecrets; workspacePath: string; input: TActionInput; - output(name: string, value: JsonValue): void; + output( + name: TActionOutput extends undefined ? string : KEY, + value: TActionOutput extends undefined ? JsonValue : TActionOutput[KEY], + ): void; /** * Creates a temporary directory for use by the action, which is then cleaned up automatically. @@ -68,7 +74,10 @@ export type ActionContext = { }; /** @public */ -export type TemplateAction = { +export type TemplateAction< + TActionInput = unknown, + TActionOutput = undefined, +> = { id: string; description?: string; examples?: { description: string; example: string }[]; @@ -77,5 +86,5 @@ export type TemplateAction = { input?: Schema; output?: Schema; }; - handler: (ctx: ActionContext) => Promise; + handler: (ctx: ActionContext) => Promise; }; From 0da07e505b2c0ecbabdc74ac8728ee01ad7b083f Mon Sep 17 00:00:00 2001 From: Andreas Berger Date: Thu, 23 Mar 2023 21:03:59 +0100 Subject: [PATCH 2/4] Distinguish between undefined and unknown action outputs Signed-off-by: Andreas Berger --- .../api-report.md | 2 +- .../api-report.md | 6 +- .../api-report.md | 2 +- .../api-report.md | 2 +- .../api-report.md | 2 +- plugins/scaffolder-backend/api-report.md | 60 ++++++++++--------- plugins/scaffolder-node/api-report.md | 51 ++++++++++------ .../src/actions/createTemplateAction.ts | 32 ++++++---- plugins/scaffolder-node/src/actions/index.ts | 1 + plugins/scaffolder-node/src/actions/types.ts | 19 +++--- 10 files changed, 104 insertions(+), 73 deletions(-) diff --git a/plugins/scaffolder-backend-module-cookiecutter/api-report.md b/plugins/scaffolder-backend-module-cookiecutter/api-report.md index 997e6b00e9..f14abde0c8 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/api-report.md +++ b/plugins/scaffolder-backend-module-cookiecutter/api-report.md @@ -25,6 +25,6 @@ export function createFetchCookiecutterAction(options: { extensions?: string[] | undefined; imageName?: string | undefined; }, - undefined + unknown >; ``` diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index fcd5fada08..551b80be51 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -18,7 +18,7 @@ export const createGitlabProjectAccessTokenAction: (options: { scopes: string[]; token?: string | undefined; }, - undefined + unknown >; // @public @@ -33,7 +33,7 @@ export const createGitlabProjectDeployTokenAction: (options: { scopes: string[]; token?: string | undefined; }, - undefined + unknown >; // @public @@ -52,6 +52,6 @@ export const createGitlabProjectVariableAction: (options: { environmentScope: string; token?: string | undefined; }, - undefined + unknown >; ``` diff --git a/plugins/scaffolder-backend-module-rails/api-report.md b/plugins/scaffolder-backend-module-rails/api-report.md index 5c27c8b957..ef78a3c34f 100644 --- a/plugins/scaffolder-backend-module-rails/api-report.md +++ b/plugins/scaffolder-backend-module-rails/api-report.md @@ -22,6 +22,6 @@ export function createFetchRailsAction(options: { values: JsonObject; imageName?: string | undefined; }, - undefined + unknown >; ``` diff --git a/plugins/scaffolder-backend-module-sentry/api-report.md b/plugins/scaffolder-backend-module-sentry/api-report.md index 3583981b2d..b7c012cc70 100644 --- a/plugins/scaffolder-backend-module-sentry/api-report.md +++ b/plugins/scaffolder-backend-module-sentry/api-report.md @@ -17,7 +17,7 @@ export function createSentryCreateProjectAction(options: { slug?: string | undefined; authToken?: string | undefined; }, - undefined + unknown >; // (No @packageDocumentation comment for this package) diff --git a/plugins/scaffolder-backend-module-yeoman/api-report.md b/plugins/scaffolder-backend-module-yeoman/api-report.md index 62a6d62156..f4111b1006 100644 --- a/plugins/scaffolder-backend-module-yeoman/api-report.md +++ b/plugins/scaffolder-backend-module-yeoman/api-report.md @@ -13,6 +13,6 @@ export function createRunYeomanAction(): TemplateAction< args?: string[] | undefined; options?: JsonObject | undefined; }, - undefined + unknown >; ``` diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 62626c551e..6bb1491f5f 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -6,6 +6,7 @@ /// import { ActionContext as ActionContext_2 } from '@backstage/plugin-scaffolder-node'; +import { ActionOutputType } from '@backstage/plugin-scaffolder-node'; import { CatalogApi } from '@backstage/catalog-client'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node'; @@ -79,7 +80,7 @@ export function createCatalogRegisterAction(options: { catalogInfoPath?: string | undefined; optional?: boolean | undefined; }, - undefined + unknown >; // @public @@ -88,7 +89,7 @@ export function createCatalogWriteAction(): TemplateAction_2< filePath?: string | undefined; entity: {}; }, - undefined + unknown >; // @public @@ -97,7 +98,7 @@ export function createDebugLogAction(): TemplateAction_2< message?: string | undefined; listWorkspace?: boolean | undefined; }, - undefined + unknown >; // @public @@ -124,7 +125,7 @@ export function createFetchPlainAction(options: { url: string; targetPath?: string | undefined; }, - undefined + unknown >; // @public @@ -136,7 +137,7 @@ export function createFetchPlainFileAction(options: { url: string; targetPath: string; }, - undefined + unknown >; // @public @@ -156,7 +157,7 @@ export function createFetchTemplateAction(options: { cookiecutterCompat?: boolean | undefined; replace?: boolean | undefined; }, - undefined + unknown >; // @public @@ -164,7 +165,7 @@ export const createFilesystemDeleteAction: () => TemplateAction_2< { files: string[]; }, - undefined + unknown >; // @public @@ -176,7 +177,7 @@ export const createFilesystemRenameAction: () => TemplateAction_2< overwrite?: boolean; }>; }, - undefined + unknown >; // @public @@ -195,7 +196,7 @@ export function createGithubActionsDispatchAction(options: { | undefined; token?: string | undefined; }, - undefined + unknown >; // @public @@ -209,7 +210,7 @@ export function createGithubIssuesLabelAction(options: { labels: string[]; token?: string | undefined; }, - undefined + unknown >; // @public @@ -297,7 +298,7 @@ export function createGithubRepoCreateAction(options: { topics?: string[] | undefined; requireCommitSigning?: boolean | undefined; }, - undefined + unknown >; // @public @@ -339,7 +340,7 @@ export function createGithubRepoPushAction(options: { token?: string | undefined; requiredCommitSigning?: boolean | undefined; }, - undefined + unknown >; // @public @@ -358,7 +359,7 @@ export function createGithubWebhookAction(options: { insecureSsl?: boolean | undefined; token?: string | undefined; }, - undefined + unknown >; // @public @@ -376,7 +377,7 @@ export function createPublishAzureAction(options: { gitAuthorName?: string | undefined; gitAuthorEmail?: string | undefined; }, - undefined + unknown >; // @public @deprecated @@ -396,7 +397,7 @@ export function createPublishBitbucketAction(options: { gitAuthorName?: string | undefined; gitAuthorEmail?: string | undefined; }, - undefined + unknown >; // @public @@ -412,7 +413,7 @@ export function createPublishBitbucketCloudAction(options: { sourcePath?: string | undefined; token?: string | undefined; }, - undefined + unknown >; // @public @@ -432,7 +433,7 @@ export function createPublishBitbucketServerAction(options: { gitAuthorName?: string | undefined; gitAuthorEmail?: string | undefined; }, - undefined + unknown >; // @public @@ -449,7 +450,7 @@ export function createPublishGerritAction(options: { gitAuthorEmail?: string | undefined; sourcePath?: string | undefined; }, - undefined + unknown >; // @public @@ -465,7 +466,7 @@ export function createPublishGerritReviewAction(options: { gitAuthorName?: string | undefined; gitAuthorEmail?: string | undefined; }, - undefined + unknown >; // @public @@ -541,7 +542,7 @@ export function createPublishGithubAction(options: { topics?: string[] | undefined; requiredCommitSigning?: boolean | undefined; }, - undefined + unknown >; // @public @@ -560,7 +561,7 @@ export const createPublishGithubPullRequestAction: ( reviewers?: string[] | undefined; teamReviewers?: string[] | undefined; }, - undefined + unknown >; // @public @@ -580,7 +581,7 @@ export function createPublishGitlabAction(options: { setUserAsOwner?: boolean | undefined; topics?: string[] | undefined; }, - undefined + unknown >; // @public @@ -600,7 +601,7 @@ export const createPublishGitlabMergeRequestAction: (options: { removeSourceBranch?: boolean | undefined; assignee?: string | undefined; }, - undefined + unknown >; // @public @@ -614,17 +615,20 @@ export const createTemplateAction: < TActionInput = TInputSchema extends ZodType ? IReturn : TParams, - TActionOutput = TOutputSchema extends ZodType - ? IReturn_1 - : undefined, + TActionOutput extends ActionOutputType = ActionOutputType, >( - action: TemplateActionOptions, + action: TemplateActionOptions< + TActionInput, + TInputSchema, + TOutputSchema, + TActionOutput + >, ) => TemplateAction_2; // @public export function createWaitAction(options?: { maxWaitTime?: Duration | HumanDuration; -}): TemplateAction_2; +}): TemplateAction_2; // @public export type CreateWorkerOptions = { diff --git a/plugins/scaffolder-node/api-report.md b/plugins/scaffolder-node/api-report.md index 6e865e0cd6..dfd2d38acd 100644 --- a/plugins/scaffolder-node/api-report.md +++ b/plugins/scaffolder-node/api-report.md @@ -18,7 +18,7 @@ import { z } from 'zod'; // @public export type ActionContext< TActionInput extends JsonObject, - TActionOutput extends JsonObject | undefined = undefined, + TActionOutput extends JsonObject | unknown | undefined = unknown, > = { logger: Logger; logStream: Writable; @@ -26,8 +26,16 @@ export type ActionContext< workspacePath: string; input: TActionInput; output( - name: TActionOutput extends undefined ? string : KEY, - value: TActionOutput extends undefined ? JsonValue : TActionOutput[KEY], + name: TActionOutput extends JsonObject + ? KEY + : TActionOutput extends undefined + ? never + : string, + value: TActionOutput extends JsonObject + ? TActionOutput[KEY] + : TActionOutput extends undefined + ? never + : JsonValue, ): void; createTemporaryDirectory(): Promise; templateInfo?: TemplateInfo; @@ -39,6 +47,17 @@ export type ActionContext< signal?: AbortSignal; }; +// @public (undocumented) +export type ActionOutputType = TOutputSchema extends z.ZodType< + any, + any, + infer IReturn +> + ? IReturn + : TOutputSchema extends undefined + ? undefined + : unknown; + // @public export const createTemplateAction: < TParams, @@ -47,11 +66,14 @@ export const createTemplateAction: < TActionInput = TInputSchema extends z.ZodType ? IReturn : TParams, - TActionOutput = TOutputSchema extends z.ZodType - ? IReturn_1 - : undefined, + TActionOutput extends ActionOutputType = ActionOutputType, >( - action: TemplateActionOptions, + action: TemplateActionOptions< + TActionInput, + TInputSchema, + TOutputSchema, + TActionOutput + >, ) => TemplateAction; // @alpha @@ -69,10 +91,7 @@ export type TaskSecrets = Record & { }; // @public (undocumented) -export type TemplateAction< - TActionInput = unknown, - TActionOutput = undefined, -> = { +export type TemplateAction = { id: string; description?: string; examples?: { @@ -92,6 +111,7 @@ export type TemplateActionOptions< TActionInput = {}, TInputSchema extends Schema | z.ZodType = {}, TOutputSchema extends Schema | z.ZodType = {}, + TActionOutput extends ActionOutputType = ActionOutputType, > = { id: string; description?: string; @@ -104,13 +124,6 @@ export type TemplateActionOptions< input?: TInputSchema; output?: TOutputSchema; }; - handler: ( - ctx: ActionContext< - TActionInput, - TOutputSchema extends z.ZodType - ? IReturn - : undefined - >, - ) => Promise; + handler: (ctx: ActionContext) => Promise; }; ``` diff --git a/plugins/scaffolder-node/src/actions/createTemplateAction.ts b/plugins/scaffolder-node/src/actions/createTemplateAction.ts index 3540e9220d..56818ccd57 100644 --- a/plugins/scaffolder-node/src/actions/createTemplateAction.ts +++ b/plugins/scaffolder-node/src/actions/createTemplateAction.ts @@ -19,11 +19,23 @@ import { z } from 'zod'; import { Schema } from 'jsonschema'; import zodToJsonSchema from 'zod-to-json-schema'; +/** @public */ +export type ActionOutputType = TOutputSchema extends z.ZodType< + any, + any, + infer IReturn +> + ? IReturn + : TOutputSchema extends undefined + ? undefined + : unknown; + /** @public */ export type TemplateActionOptions< TActionInput = {}, TInputSchema extends Schema | z.ZodType = {}, TOutputSchema extends Schema | z.ZodType = {}, + TActionOutput extends ActionOutputType = ActionOutputType, > = { id: string; description?: string; @@ -33,14 +45,7 @@ export type TemplateActionOptions< input?: TInputSchema; output?: TOutputSchema; }; - handler: ( - ctx: ActionContext< - TActionInput, - TOutputSchema extends z.ZodType - ? IReturn - : undefined - >, - ) => Promise; + handler: (ctx: ActionContext) => Promise; }; /** @@ -55,11 +60,14 @@ export const createTemplateAction = < TActionInput = TInputSchema extends z.ZodType ? IReturn : TParams, - TActionOutput = TOutputSchema extends z.ZodType - ? IReturn - : undefined, + TActionOutput extends ActionOutputType = ActionOutputType, >( - action: TemplateActionOptions, + action: TemplateActionOptions< + TActionInput, + TInputSchema, + TOutputSchema, + TActionOutput + >, ): TemplateAction => { const inputSchema = action.schema?.input && 'safeParseAsync' in action.schema.input diff --git a/plugins/scaffolder-node/src/actions/index.ts b/plugins/scaffolder-node/src/actions/index.ts index e4af098356..e7b4b1899d 100644 --- a/plugins/scaffolder-node/src/actions/index.ts +++ b/plugins/scaffolder-node/src/actions/index.ts @@ -17,5 +17,6 @@ export { createTemplateAction, type TemplateActionOptions, + type ActionOutputType, } from './createTemplateAction'; export { type ActionContext, type TemplateAction } from './types'; diff --git a/plugins/scaffolder-node/src/actions/types.ts b/plugins/scaffolder-node/src/actions/types.ts index c81fafd9ad..454e0a68b4 100644 --- a/plugins/scaffolder-node/src/actions/types.ts +++ b/plugins/scaffolder-node/src/actions/types.ts @@ -28,7 +28,7 @@ import { Schema } from 'jsonschema'; */ export type ActionContext< TActionInput extends JsonObject, - TActionOutput extends JsonObject | undefined = undefined, + TActionOutput extends JsonObject | unknown | undefined = unknown, > = { logger: Logger; logStream: Writable; @@ -36,8 +36,16 @@ export type ActionContext< workspacePath: string; input: TActionInput; output( - name: TActionOutput extends undefined ? string : KEY, - value: TActionOutput extends undefined ? JsonValue : TActionOutput[KEY], + name: TActionOutput extends JsonObject + ? KEY + : TActionOutput extends undefined + ? never + : string, + value: TActionOutput extends JsonObject + ? TActionOutput[KEY] + : TActionOutput extends undefined + ? never + : JsonValue, ): void; /** @@ -74,10 +82,7 @@ export type ActionContext< }; /** @public */ -export type TemplateAction< - TActionInput = unknown, - TActionOutput = undefined, -> = { +export type TemplateAction = { id: string; description?: string; examples?: { description: string; example: string }[]; From ce0cf80ef297c9287a8795609c8857f900b65223 Mon Sep 17 00:00:00 2001 From: Andreas Berger Date: Fri, 24 Mar 2023 12:07:44 +0100 Subject: [PATCH 3/4] Allow defining output type in createTemplateAction This change allow to define the output type of the createTemplateAction. This is necessary for zod definitions, which results in "Type instantiation is excessively deep and possibly infinite." Signed-off-by: Andreas Berger --- .../api-report.md | 11 ++++++---- plugins/scaffolder-backend/api-report.md | 10 ++++++--- plugins/scaffolder-node/api-report.md | 21 +++++++++++-------- .../src/actions/createTemplateAction.ts | 21 +++++++++++-------- 4 files changed, 38 insertions(+), 25 deletions(-) diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/api-report.md b/plugins/scaffolder-backend-module-confluence-to-markdown/api-report.md index 398beb5059..53b830c60b 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/api-report.md +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/api-report.md @@ -13,8 +13,11 @@ export const createConfluenceToMarkdownAction: (options: { reader: UrlReader; integrations: ScmIntegrations; config: Config; -}) => TemplateAction<{ - confluenceUrls: string[]; - repoUrl: string; -}>; +}) => TemplateAction< + { + confluenceUrls: string[]; + repoUrl: string; + }, + unknown +>; ``` diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 6bb1491f5f..c845eb57a1 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -609,13 +609,17 @@ export function createRouter(options: RouterOptions): Promise; // @public @deprecated (undocumented) export const createTemplateAction: < - TParams, + TInputParams, + TOutputParams = unknown, TInputSchema extends ZodType | Schema = {}, TOutputSchema extends ZodType | Schema = {}, TActionInput = TInputSchema extends ZodType ? IReturn - : TParams, - TActionOutput extends ActionOutputType = ActionOutputType, + : TInputParams, + TActionOutput extends ActionOutputType< + TOutputSchema, + TOutputParams + > = ActionOutputType, >( action: TemplateActionOptions< TActionInput, diff --git a/plugins/scaffolder-node/api-report.md b/plugins/scaffolder-node/api-report.md index dfd2d38acd..42f2df7c8b 100644 --- a/plugins/scaffolder-node/api-report.md +++ b/plugins/scaffolder-node/api-report.md @@ -48,25 +48,28 @@ export type ActionContext< }; // @public (undocumented) -export type ActionOutputType = TOutputSchema extends z.ZodType< - any, - any, - infer IReturn -> +export type ActionOutputType< + TOutputSchema, + FallbackOutput = unknown, +> = TOutputSchema extends z.ZodType ? IReturn : TOutputSchema extends undefined ? undefined - : unknown; + : FallbackOutput; // @public export const createTemplateAction: < - TParams, + TInputParams, + TOutputParams = unknown, TInputSchema extends z.ZodType | Schema = {}, TOutputSchema extends z.ZodType | Schema = {}, TActionInput = TInputSchema extends z.ZodType ? IReturn - : TParams, - TActionOutput extends ActionOutputType = ActionOutputType, + : TInputParams, + TActionOutput extends ActionOutputType< + TOutputSchema, + TOutputParams + > = ActionOutputType, >( action: TemplateActionOptions< TActionInput, diff --git a/plugins/scaffolder-node/src/actions/createTemplateAction.ts b/plugins/scaffolder-node/src/actions/createTemplateAction.ts index 56818ccd57..bba568e3e5 100644 --- a/plugins/scaffolder-node/src/actions/createTemplateAction.ts +++ b/plugins/scaffolder-node/src/actions/createTemplateAction.ts @@ -20,15 +20,14 @@ import { Schema } from 'jsonschema'; import zodToJsonSchema from 'zod-to-json-schema'; /** @public */ -export type ActionOutputType = TOutputSchema extends z.ZodType< - any, - any, - infer IReturn -> +export type ActionOutputType< + TOutputSchema, + FallbackOutput = unknown, +> = TOutputSchema extends z.ZodType ? IReturn : TOutputSchema extends undefined ? undefined - : unknown; + : FallbackOutput; /** @public */ export type TemplateActionOptions< @@ -54,13 +53,17 @@ export type TemplateActionOptions< * @public */ export const createTemplateAction = < - TParams, + TInputParams, + TOutputParams = unknown, TInputSchema extends Schema | z.ZodType = {}, TOutputSchema extends Schema | z.ZodType = {}, TActionInput = TInputSchema extends z.ZodType ? IReturn - : TParams, - TActionOutput extends ActionOutputType = ActionOutputType, + : TInputParams, + TActionOutput extends ActionOutputType< + TOutputSchema, + TOutputParams + > = ActionOutputType, >( action: TemplateActionOptions< TActionInput, From f7e8b8ba83ddd873cd2cc31b6f86a3701e90268a Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 28 Mar 2023 14:22:33 +0200 Subject: [PATCH 4/4] chore: simplify the types a little bit Signed-off-by: blam --- .../api-report.md | 3 +- .../api-report.md | 2 +- .../api-report.md | 7 +- .../api-report.md | 2 +- .../api-report.md | 3 +- .../api-report.md | 2 +- plugins/scaffolder-backend/api-report.md | 72 +++++++++---------- plugins/scaffolder-node/api-report.md | 49 +++++-------- .../src/actions/createTemplateAction.ts | 28 +++----- plugins/scaffolder-node/src/actions/index.ts | 1 - plugins/scaffolder-node/src/actions/types.ts | 23 +++--- 11 files changed, 81 insertions(+), 111 deletions(-) diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/api-report.md b/plugins/scaffolder-backend-module-confluence-to-markdown/api-report.md index 53b830c60b..70428f118c 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/api-report.md +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/api-report.md @@ -4,6 +4,7 @@ ```ts import { Config } from '@backstage/config'; +import { JsonObject } from '@backstage/types'; import { ScmIntegrations } from '@backstage/integration'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; import { UrlReader } from '@backstage/backend-common'; @@ -18,6 +19,6 @@ export const createConfluenceToMarkdownAction: (options: { confluenceUrls: string[]; repoUrl: string; }, - unknown + JsonObject >; ``` diff --git a/plugins/scaffolder-backend-module-cookiecutter/api-report.md b/plugins/scaffolder-backend-module-cookiecutter/api-report.md index f14abde0c8..927d4b4c55 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/api-report.md +++ b/plugins/scaffolder-backend-module-cookiecutter/api-report.md @@ -25,6 +25,6 @@ export function createFetchCookiecutterAction(options: { extensions?: string[] | undefined; imageName?: string | undefined; }, - unknown + JsonObject >; ``` diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index 551b80be51..2ec05e74de 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { JsonObject } from '@backstage/types'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; @@ -18,7 +19,7 @@ export const createGitlabProjectAccessTokenAction: (options: { scopes: string[]; token?: string | undefined; }, - unknown + JsonObject >; // @public @@ -33,7 +34,7 @@ export const createGitlabProjectDeployTokenAction: (options: { scopes: string[]; token?: string | undefined; }, - unknown + JsonObject >; // @public @@ -52,6 +53,6 @@ export const createGitlabProjectVariableAction: (options: { environmentScope: string; token?: string | undefined; }, - unknown + JsonObject >; ``` diff --git a/plugins/scaffolder-backend-module-rails/api-report.md b/plugins/scaffolder-backend-module-rails/api-report.md index ef78a3c34f..06b7dc457f 100644 --- a/plugins/scaffolder-backend-module-rails/api-report.md +++ b/plugins/scaffolder-backend-module-rails/api-report.md @@ -22,6 +22,6 @@ export function createFetchRailsAction(options: { values: JsonObject; imageName?: string | undefined; }, - unknown + JsonObject >; ``` diff --git a/plugins/scaffolder-backend-module-sentry/api-report.md b/plugins/scaffolder-backend-module-sentry/api-report.md index b7c012cc70..746cce1348 100644 --- a/plugins/scaffolder-backend-module-sentry/api-report.md +++ b/plugins/scaffolder-backend-module-sentry/api-report.md @@ -4,6 +4,7 @@ ```ts import { Config } from '@backstage/config'; +import { JsonObject } from '@backstage/types'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; // @public @@ -17,7 +18,7 @@ export function createSentryCreateProjectAction(options: { slug?: string | undefined; authToken?: string | undefined; }, - unknown + JsonObject >; // (No @packageDocumentation comment for this package) diff --git a/plugins/scaffolder-backend-module-yeoman/api-report.md b/plugins/scaffolder-backend-module-yeoman/api-report.md index f4111b1006..d8bdcb7b3b 100644 --- a/plugins/scaffolder-backend-module-yeoman/api-report.md +++ b/plugins/scaffolder-backend-module-yeoman/api-report.md @@ -13,6 +13,6 @@ export function createRunYeomanAction(): TemplateAction< args?: string[] | undefined; options?: JsonObject | undefined; }, - unknown + JsonObject >; ``` diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index c845eb57a1..f083db5102 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -6,7 +6,6 @@ /// import { ActionContext as ActionContext_2 } from '@backstage/plugin-scaffolder-node'; -import { ActionOutputType } from '@backstage/plugin-scaffolder-node'; import { CatalogApi } from '@backstage/catalog-client'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node'; @@ -80,16 +79,18 @@ export function createCatalogRegisterAction(options: { catalogInfoPath?: string | undefined; optional?: boolean | undefined; }, - unknown + JsonObject >; // @public export function createCatalogWriteAction(): TemplateAction_2< { + entity: {} & { + [k: string]: unknown; + }; filePath?: string | undefined; - entity: {}; }, - unknown + JsonObject >; // @public @@ -98,7 +99,7 @@ export function createDebugLogAction(): TemplateAction_2< message?: string | undefined; listWorkspace?: boolean | undefined; }, - unknown + JsonObject >; // @public @@ -106,13 +107,13 @@ export function createFetchCatalogEntityAction(options: { catalogClient: CatalogApi; }): TemplateAction_2< { - optional?: boolean | undefined; entityRef?: string | undefined; entityRefs?: string[] | undefined; + optional?: boolean | undefined; }, { - entities?: any[] | undefined; entity?: any; + entities?: any[] | undefined; } >; @@ -125,7 +126,7 @@ export function createFetchPlainAction(options: { url: string; targetPath?: string | undefined; }, - unknown + JsonObject >; // @public @@ -137,7 +138,7 @@ export function createFetchPlainFileAction(options: { url: string; targetPath: string; }, - unknown + JsonObject >; // @public @@ -157,7 +158,7 @@ export function createFetchTemplateAction(options: { cookiecutterCompat?: boolean | undefined; replace?: boolean | undefined; }, - unknown + JsonObject >; // @public @@ -165,7 +166,7 @@ export const createFilesystemDeleteAction: () => TemplateAction_2< { files: string[]; }, - unknown + JsonObject >; // @public @@ -177,7 +178,7 @@ export const createFilesystemRenameAction: () => TemplateAction_2< overwrite?: boolean; }>; }, - unknown + JsonObject >; // @public @@ -196,7 +197,7 @@ export function createGithubActionsDispatchAction(options: { | undefined; token?: string | undefined; }, - unknown + JsonObject >; // @public @@ -210,7 +211,7 @@ export function createGithubIssuesLabelAction(options: { labels: string[]; token?: string | undefined; }, - unknown + JsonObject >; // @public @@ -298,7 +299,7 @@ export function createGithubRepoCreateAction(options: { topics?: string[] | undefined; requireCommitSigning?: boolean | undefined; }, - unknown + JsonObject >; // @public @@ -340,7 +341,7 @@ export function createGithubRepoPushAction(options: { token?: string | undefined; requiredCommitSigning?: boolean | undefined; }, - unknown + JsonObject >; // @public @@ -359,7 +360,7 @@ export function createGithubWebhookAction(options: { insecureSsl?: boolean | undefined; token?: string | undefined; }, - unknown + JsonObject >; // @public @@ -377,7 +378,7 @@ export function createPublishAzureAction(options: { gitAuthorName?: string | undefined; gitAuthorEmail?: string | undefined; }, - unknown + JsonObject >; // @public @deprecated @@ -397,7 +398,7 @@ export function createPublishBitbucketAction(options: { gitAuthorName?: string | undefined; gitAuthorEmail?: string | undefined; }, - unknown + JsonObject >; // @public @@ -413,7 +414,7 @@ export function createPublishBitbucketCloudAction(options: { sourcePath?: string | undefined; token?: string | undefined; }, - unknown + JsonObject >; // @public @@ -433,7 +434,7 @@ export function createPublishBitbucketServerAction(options: { gitAuthorName?: string | undefined; gitAuthorEmail?: string | undefined; }, - unknown + JsonObject >; // @public @@ -450,7 +451,7 @@ export function createPublishGerritAction(options: { gitAuthorEmail?: string | undefined; sourcePath?: string | undefined; }, - unknown + JsonObject >; // @public @@ -466,7 +467,7 @@ export function createPublishGerritReviewAction(options: { gitAuthorName?: string | undefined; gitAuthorEmail?: string | undefined; }, - unknown + JsonObject >; // @public @@ -542,7 +543,7 @@ export function createPublishGithubAction(options: { topics?: string[] | undefined; requiredCommitSigning?: boolean | undefined; }, - unknown + JsonObject >; // @public @@ -561,7 +562,7 @@ export const createPublishGithubPullRequestAction: ( reviewers?: string[] | undefined; teamReviewers?: string[] | undefined; }, - unknown + JsonObject >; // @public @@ -581,7 +582,7 @@ export function createPublishGitlabAction(options: { setUserAsOwner?: boolean | undefined; topics?: string[] | undefined; }, - unknown + JsonObject >; // @public @@ -601,7 +602,7 @@ export const createPublishGitlabMergeRequestAction: (options: { removeSourceBranch?: boolean | undefined; assignee?: string | undefined; }, - unknown + JsonObject >; // @public @@ -609,30 +610,29 @@ export function createRouter(options: RouterOptions): Promise; // @public @deprecated (undocumented) export const createTemplateAction: < - TInputParams, - TOutputParams = unknown, + TInputParams extends JsonObject = JsonObject, + TOutputParams extends JsonObject = JsonObject, TInputSchema extends ZodType | Schema = {}, TOutputSchema extends ZodType | Schema = {}, TActionInput = TInputSchema extends ZodType ? IReturn : TInputParams, - TActionOutput extends ActionOutputType< - TOutputSchema, - TOutputParams - > = ActionOutputType, + TActionOutput = TOutputSchema extends ZodType + ? IReturn_1 + : TOutputParams, >( action: TemplateActionOptions< TActionInput, + TActionOutput, TInputSchema, - TOutputSchema, - TActionOutput + TOutputSchema >, ) => TemplateAction_2; // @public export function createWaitAction(options?: { maxWaitTime?: Duration | HumanDuration; -}): TemplateAction_2; +}): TemplateAction_2; // @public export type CreateWorkerOptions = { diff --git a/plugins/scaffolder-node/api-report.md b/plugins/scaffolder-node/api-report.md index 42f2df7c8b..51f2aab501 100644 --- a/plugins/scaffolder-node/api-report.md +++ b/plugins/scaffolder-node/api-report.md @@ -7,7 +7,6 @@ import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { JsonObject } from '@backstage/types'; -import { JsonValue } from '@backstage/types'; import { Logger } from 'winston'; import { Schema } from 'jsonschema'; import { TemplateInfo } from '@backstage/plugin-scaffolder-common'; @@ -18,24 +17,16 @@ import { z } from 'zod'; // @public export type ActionContext< TActionInput extends JsonObject, - TActionOutput extends JsonObject | unknown | undefined = unknown, + TActionOutput extends JsonObject = JsonObject, > = { logger: Logger; logStream: Writable; secrets?: TaskSecrets; workspacePath: string; input: TActionInput; - output( - name: TActionOutput extends JsonObject - ? KEY - : TActionOutput extends undefined - ? never - : string, - value: TActionOutput extends JsonObject - ? TActionOutput[KEY] - : TActionOutput extends undefined - ? never - : JsonValue, + output( + name: keyof TActionOutput, + value: TActionOutput[keyof TActionOutput], ): void; createTemporaryDirectory(): Promise; templateInfo?: TemplateInfo; @@ -47,35 +38,24 @@ export type ActionContext< signal?: AbortSignal; }; -// @public (undocumented) -export type ActionOutputType< - TOutputSchema, - FallbackOutput = unknown, -> = TOutputSchema extends z.ZodType - ? IReturn - : TOutputSchema extends undefined - ? undefined - : FallbackOutput; - // @public export const createTemplateAction: < - TInputParams, - TOutputParams = unknown, + TInputParams extends JsonObject = JsonObject, + TOutputParams extends JsonObject = JsonObject, TInputSchema extends z.ZodType | Schema = {}, TOutputSchema extends z.ZodType | Schema = {}, TActionInput = TInputSchema extends z.ZodType ? IReturn : TInputParams, - TActionOutput extends ActionOutputType< - TOutputSchema, - TOutputParams - > = ActionOutputType, + TActionOutput = TOutputSchema extends z.ZodType + ? IReturn_1 + : TOutputParams, >( action: TemplateActionOptions< TActionInput, + TActionOutput, TInputSchema, - TOutputSchema, - TActionOutput + TOutputSchema >, ) => TemplateAction; @@ -94,7 +74,10 @@ export type TaskSecrets = Record & { }; // @public (undocumented) -export type TemplateAction = { +export type TemplateAction< + TActionInput = unknown, + TActionOutput = JsonObject, +> = { id: string; description?: string; examples?: { @@ -112,9 +95,9 @@ export type TemplateAction = { // @public (undocumented) export type TemplateActionOptions< TActionInput = {}, + TActionOutput = {}, TInputSchema extends Schema | z.ZodType = {}, TOutputSchema extends Schema | z.ZodType = {}, - TActionOutput extends ActionOutputType = ActionOutputType, > = { id: string; description?: string; diff --git a/plugins/scaffolder-node/src/actions/createTemplateAction.ts b/plugins/scaffolder-node/src/actions/createTemplateAction.ts index bba568e3e5..25c0dead55 100644 --- a/plugins/scaffolder-node/src/actions/createTemplateAction.ts +++ b/plugins/scaffolder-node/src/actions/createTemplateAction.ts @@ -18,23 +18,14 @@ import { ActionContext, TemplateAction } from './types'; import { z } from 'zod'; import { Schema } from 'jsonschema'; import zodToJsonSchema from 'zod-to-json-schema'; - -/** @public */ -export type ActionOutputType< - TOutputSchema, - FallbackOutput = unknown, -> = TOutputSchema extends z.ZodType - ? IReturn - : TOutputSchema extends undefined - ? undefined - : FallbackOutput; +import { JsonObject } from '@backstage/types'; /** @public */ export type TemplateActionOptions< TActionInput = {}, + TActionOutput = {}, TInputSchema extends Schema | z.ZodType = {}, TOutputSchema extends Schema | z.ZodType = {}, - TActionOutput extends ActionOutputType = ActionOutputType, > = { id: string; description?: string; @@ -53,23 +44,22 @@ export type TemplateActionOptions< * @public */ export const createTemplateAction = < - TInputParams, - TOutputParams = unknown, + TInputParams extends JsonObject = JsonObject, + TOutputParams extends JsonObject = JsonObject, TInputSchema extends Schema | z.ZodType = {}, TOutputSchema extends Schema | z.ZodType = {}, TActionInput = TInputSchema extends z.ZodType ? IReturn : TInputParams, - TActionOutput extends ActionOutputType< - TOutputSchema, - TOutputParams - > = ActionOutputType, + TActionOutput = TOutputSchema extends z.ZodType + ? IReturn + : TOutputParams, >( action: TemplateActionOptions< TActionInput, + TActionOutput, TInputSchema, - TOutputSchema, - TActionOutput + TOutputSchema >, ): TemplateAction => { const inputSchema = diff --git a/plugins/scaffolder-node/src/actions/index.ts b/plugins/scaffolder-node/src/actions/index.ts index e7b4b1899d..e4af098356 100644 --- a/plugins/scaffolder-node/src/actions/index.ts +++ b/plugins/scaffolder-node/src/actions/index.ts @@ -17,6 +17,5 @@ export { createTemplateAction, type TemplateActionOptions, - type ActionOutputType, } from './createTemplateAction'; export { type ActionContext, type TemplateAction } from './types'; diff --git a/plugins/scaffolder-node/src/actions/types.ts b/plugins/scaffolder-node/src/actions/types.ts index 454e0a68b4..259773f1c0 100644 --- a/plugins/scaffolder-node/src/actions/types.ts +++ b/plugins/scaffolder-node/src/actions/types.ts @@ -16,7 +16,7 @@ import { Logger } from 'winston'; import { Writable } from 'stream'; -import { JsonObject, JsonValue } from '@backstage/types'; +import { JsonObject } from '@backstage/types'; import { TaskSecrets } from '../tasks'; import { TemplateInfo } from '@backstage/plugin-scaffolder-common'; import { UserEntity } from '@backstage/catalog-model'; @@ -28,24 +28,16 @@ import { Schema } from 'jsonschema'; */ export type ActionContext< TActionInput extends JsonObject, - TActionOutput extends JsonObject | unknown | undefined = unknown, + TActionOutput extends JsonObject = JsonObject, > = { logger: Logger; logStream: Writable; secrets?: TaskSecrets; workspacePath: string; input: TActionInput; - output( - name: TActionOutput extends JsonObject - ? KEY - : TActionOutput extends undefined - ? never - : string, - value: TActionOutput extends JsonObject - ? TActionOutput[KEY] - : TActionOutput extends undefined - ? never - : JsonValue, + output( + name: keyof TActionOutput, + value: TActionOutput[keyof TActionOutput], ): void; /** @@ -82,7 +74,10 @@ export type ActionContext< }; /** @public */ -export type TemplateAction = { +export type TemplateAction< + TActionInput = unknown, + TActionOutput = JsonObject, +> = { id: string; description?: string; examples?: { description: string; example: string }[];