chore: change notification send action to use zod

Signed-off-by: Hellgren Heikki <heikki.hellgren@op.fi>
This commit is contained in:
Hellgren Heikki
2025-04-30 14:37:50 +03:00
parent 3551662f98
commit b60253da4d
5 changed files with 46 additions and 76 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend-module-notifications': patch
---
Change notification send scaffolder action to use native zod schemas
@@ -4,9 +4,7 @@
```ts
import { BackendFeature } from '@backstage/backend-plugin-api';
import { JsonObject } from '@backstage/types';
import { NotificationService } from '@backstage/plugin-notifications-node';
import { NotificationSeverity } from '@backstage/plugin-notifications-common';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
// @public (undocumented)
@@ -14,17 +12,19 @@ export function createSendNotificationAction(options: {
notifications: NotificationService;
}): TemplateAction<
{
recipients: string;
entityRefs?: string[];
recipients: 'entity' | 'broadcast';
title: string;
info?: string;
link?: string;
severity?: NotificationSeverity;
scope?: string;
optional?: boolean;
entityRefs?: string[] | undefined;
info?: string | undefined;
link?: string | undefined;
severity?: 'normal' | 'high' | 'low' | 'critical' | undefined;
scope?: string | undefined;
optional?: boolean | undefined;
},
JsonObject,
'v1'
{
[x: string]: any;
},
'v2'
>;
// @public
@@ -25,7 +25,7 @@ describe('notification:send', () => {
send: jest.fn(),
};
let action: TemplateAction<any>;
let action: TemplateAction<any, any, 'v2'>;
beforeEach(() => {
jest.resetAllMocks();
@@ -23,7 +23,7 @@ describe('notification:send', () => {
send: jest.fn(),
};
let action: TemplateAction<any>;
let action: TemplateAction<any, any, 'v2'>;
beforeEach(() => {
jest.resetAllMocks();
@@ -17,10 +17,7 @@ import {
NotificationRecipients,
NotificationService,
} from '@backstage/plugin-notifications-node';
import {
NotificationPayload,
NotificationSeverity,
} from '@backstage/plugin-notifications-common';
import { NotificationPayload } from '@backstage/plugin-notifications-common';
import { createTemplateAction } from '@backstage/plugin-scaffolder-node';
import { examples } from './sendNotification.examples';
@@ -31,73 +28,41 @@ export function createSendNotificationAction(options: {
notifications: NotificationService;
}) {
const { notifications } = options;
return createTemplateAction<{
recipients: string;
entityRefs?: string[];
title: string;
info?: string;
link?: string;
severity?: NotificationSeverity;
scope?: string;
optional?: boolean;
}>({
return createTemplateAction({
id: 'notification:send',
description: 'Sends a notification using NotificationService',
examples,
schema: {
input: {
type: 'object',
required: ['recipients', 'title'],
properties: {
recipients: {
title: 'Recipient',
enum: ['broadcast', 'entity'],
description:
recipients: z =>
z
.enum(['broadcast', 'entity'])
.describe(
'The recipient of the notification, either broadcast or entity. If using entity, also entityRef must be provided',
type: 'string',
},
entityRefs: {
title: 'Entity references',
description:
),
entityRefs: z =>
z
.array(z.string())
.optional()
.describe(
'The entity references to send the notification to, required if using recipient of entity',
type: 'array',
items: {
type: 'string',
},
},
title: {
title: 'Title',
description: 'Notification title',
type: 'string',
},
info: {
title: 'Description',
description: 'Notification description',
type: 'string',
},
link: {
title: 'Link',
description: 'Notification link',
type: 'string',
},
severity: {
title: 'Severity',
type: 'string',
description: `Notification severity`,
enum: ['low', 'normal', 'high', 'critical'],
},
scope: {
title: 'Scope',
description: 'Notification scope',
type: 'string',
},
optional: {
title: 'Optional',
description:
),
title: z => z.string().describe('Notification title'),
info: z => z.string().optional().describe('Notification description'),
link: z => z.string().optional().describe('Notification link'),
severity: z =>
z
.enum(['low', 'normal', 'high', 'critical'])
.optional()
.describe('Notification severity'),
scope: z => z.string().optional().describe('Notification scope'),
optional: z =>
z
.boolean()
.optional()
.describe(
'Do not fail the action if the notification sending fails',
type: 'boolean',
},
},
),
},
},
async handler(ctx) {