chore: added ability to define attributes

Signed-off-by: benjdlambert <ben@blam.sh>
This commit is contained in:
benjdlambert
2025-06-13 10:25:38 +02:00
parent 2bb5a5a32e
commit 2092bd5bb2
7 changed files with 135 additions and 2 deletions
@@ -70,6 +70,11 @@ describe('actionsServiceFactory', () => {
input: {},
output: {},
},
attributes: {
destructive: false,
idempotent: false,
readOnly: false,
},
};
beforeEach(() => {
@@ -306,6 +311,11 @@ describe('actionsServiceFactory', () => {
type: 'object',
},
},
attributes: {
destructive: false,
idempotent: false,
readOnly: false,
},
title: 'Test',
},
],
@@ -67,13 +67,19 @@ export class DefaultActionsRegistryService implements ActionsRegistryService {
actions: Array.from(this.actions.entries()).map(([id, action]) => ({
id,
...action,
attributes: {
// todo(blam): what's safe defaults?
destructive: action.attributes?.destructive ?? false,
idempotent: action.attributes?.idempotent ?? false,
readOnly: action.attributes?.readOnly ?? false,
},
schema: {
input: action.schema?.input
? zodToJsonSchema(action.schema.input(z))
: zodToJsonSchema(z.any()),
: zodToJsonSchema(z.object({})),
output: action.schema?.output
? zodToJsonSchema(action.schema.output(z))
: zodToJsonSchema(z.any()),
: zodToJsonSchema(z.object({})),
},
})),
});
@@ -181,6 +181,109 @@ describe('actionsRegistryServiceFactory', () => {
});
});
it('should set default attributes', async () => {
const pluginSubject = createBackendPlugin({
pluginId: 'my-plugin',
register(reg) {
reg.registerInit({
deps: {
actionsRegistry: coreServices.actionsRegistry,
},
async init({ actionsRegistry }) {
actionsRegistry.register({
name: 'test',
title: 'Test',
description: 'Test',
schema: {
input: z => z.object({}),
output: z => z.object({}),
},
action: async () => ({ output: { ok: true } }),
});
},
});
},
});
const { server } = await startTestBackend({
features: [pluginSubject, ...defaultServices],
});
const { body, status } = await request(server).get(
'/api/my-plugin/.backstage/actions/v1/actions',
);
expect(status).toBe(200);
expect(body).toMatchObject({
actions: [
{
name: 'test',
attributes: {
destructive: false,
idempotent: false,
readOnly: false,
},
},
],
});
});
it('should allow setting attributes', async () => {
const pluginSubject = createBackendPlugin({
pluginId: 'my-plugin',
register(reg) {
reg.registerInit({
deps: {
actionsRegistry: coreServices.actionsRegistry,
},
async init({ actionsRegistry }) {
actionsRegistry.register({
name: 'test',
title: 'Test',
description: 'Test',
attributes: {
destructive: true,
idempotent: true,
readOnly: true,
},
schema: {
input: z => z.object({}),
output: z => z.object({}),
},
action: async () => ({ output: { ok: true } }),
});
},
});
},
});
const { server } = await startTestBackend({
features: [pluginSubject, ...defaultServices],
});
const { body, status } = await request(server).get(
'/api/my-plugin/.backstage/actions/v1/actions',
);
expect(status).toBe(200);
expect(body).toMatchObject({
actions: [
{
name: 'test',
title: 'Test',
description: 'Test',
attributes: {
destructive: true,
idempotent: true,
readOnly: true,
},
},
],
});
});
it('should forces registration of input and output schema as objects', async () => {
const pluginSubject = createBackendPlugin({
pluginId: 'my-plugin',
@@ -40,6 +40,11 @@ export type ActionsRegistryActionOptions<
input: (zod: typeof z) => TInputSchema;
output: (zod: typeof z) => TOutputSchema;
};
attributes?: {
destructive?: boolean;
idempotent?: boolean;
readOnly?: boolean;
};
action: (
context: ActionsRegistryActionContext<TInputSchema>,
) => Promise<
@@ -29,6 +29,11 @@ export type ActionsServiceAction = {
input: JSONSchema7;
output: JSONSchema7;
};
attributes: {
readOnly: boolean;
destructive: boolean;
idempotent: boolean;
};
};
/**
+2
View File
@@ -59,12 +59,14 @@
"@keyv/valkey": "^1.0.1",
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5",
"@types/json-schema": "^7.0.6",
"@types/keyv": "^4.2.0",
"@types/qs": "^6.9.6",
"better-sqlite3": "^11.0.0",
"cookie": "^0.7.0",
"express": "^4.17.1",
"fs-extra": "^11.0.0",
"json-schema": "^0.4.0",
"keyv": "^5.2.1",
"knex": "^3.0.0",
"mysql2": "^3.0.0",
+2
View File
@@ -3784,6 +3784,7 @@ __metadata:
"@types/express": "npm:^4.17.6"
"@types/express-serve-static-core": "npm:^4.17.5"
"@types/jest": "npm:*"
"@types/json-schema": "npm:^7.0.6"
"@types/keyv": "npm:^4.2.0"
"@types/qs": "npm:^6.9.6"
"@types/supertest": "npm:^2.0.8"
@@ -3791,6 +3792,7 @@ __metadata:
cookie: "npm:^0.7.0"
express: "npm:^4.17.1"
fs-extra: "npm:^11.0.0"
json-schema: "npm:^0.4.0"
keyv: "npm:^5.2.1"
knex: "npm:^3.0.0"
mysql2: "npm:^3.0.0"