diff --git a/packages/hooks/src/hooks/hook.ts b/packages/hooks/src/hooks/hook.ts index 7e3bc178d..7c019e7e8 100644 --- a/packages/hooks/src/hooks/hook.ts +++ b/packages/hooks/src/hooks/hook.ts @@ -2,9 +2,11 @@ import type { PluginApi } from '../utils/utils.js' import type * as hooks from './index.js' export type DefaultArgs = Record +export type PluginResultStoreValue = string | number | null +export type PluginResultStore = Record export interface PluginResult { status: { result: 'OK', message?: string } | { result: 'KO' | 'WARNING', message: string } - store?: Record + store?: PluginResultStore [key: string]: any } diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts index 67bc2a58a..3bc1689a5 100644 --- a/packages/hooks/src/index.ts +++ b/packages/hooks/src/index.ts @@ -134,4 +134,5 @@ export * from './utils/crypto.js' export * from './hooks/index.js' export * from './hooks/hook.js' export * from './utils/utils.js' +export * from './utils/plugin-result-handler.js' export * from './config.js' diff --git a/packages/hooks/src/utils/plugin-result-handler.ts b/packages/hooks/src/utils/plugin-result-handler.ts new file mode 100644 index 000000000..eb4a7c3d9 --- /dev/null +++ b/packages/hooks/src/utils/plugin-result-handler.ts @@ -0,0 +1,93 @@ +import type { PluginResult, PluginResultStore, PluginResultStoreValue } from '@/hooks/hook.js' +import { parseError } from './logger.js' + +export class PluginResultBuilder { + private okMessages = [] as string[] + private warnMessages = [] as string[] + private koMessages = [] as string[] + private extras: Record = {} + public store: PluginResultStore = {} + + constructor(okMessage: string | undefined) { + if (okMessage) { + this.okMessages.push(okMessage) + } + } + + addExtra(key: string, value: any) { + this.extras[key] = value + return this + } + + addOkMessage(...messages: string[]) { + this.okMessages.push(...messages) + return this + } + + addKoMessage(...messages: string[]) { + this.koMessages.push(...messages) + return this + } + + addWarnMessage(...messages: string[]) { + this.warnMessages.push(...messages) + return this + } + + setOkMessage(...messages: string[]) { + this.okMessages = messages + return this + } + + setKoMessage(...messages: string[]) { + this.koMessages = messages + return this + } + + setWarnMessage(...messages: string[]) { + this.warnMessages = messages + return this + } + + setToStore(key: string, value: PluginResultStoreValue) { + this.store[key] = value + } + + deleteFromStore(key: string) { + delete this.store[key] + } + + returnUnexpectedError(error: unknown): PluginResult { + this.addKoMessage('UnexpectedError') + this.addExtra('error', parseError(error)) + return this.getResultObject() + } + + getResultObject(): PluginResult { + const result: PluginResult = { + status: { + result: 'OK', + message: this.okMessages.join('\n') || undefined, + }, + ...this.extras, + } + + if (this.koMessages.length) { + result.status = { + result: 'KO', + message: this.koMessages.join('\n'), + } + } else if (this.warnMessages.length) { + result.status = { + result: 'WARNING', + message: this.warnMessages.join('\n'), + } + } + + if (Object.keys(this.store).length) { + result.store = this.store + } + + return result + } +} diff --git a/plugins/keycloak/src/functions.ts b/plugins/keycloak/src/functions.ts index e920f7440..6ab77eeae 100644 --- a/plugins/keycloak/src/functions.ts +++ b/plugins/keycloak/src/functions.ts @@ -1,5 +1,5 @@ import type { Project, StepCall, UserEmail, ZoneObject } from '@cpn-console/hooks' -import { generateRandomPassword, parseError } from '@cpn-console/hooks' +import { generateRandomPassword, parseError, PluginResultBuilder } from '@cpn-console/hooks' import type GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation.js' import type ClientRepresentation from '@keycloak/keycloak-admin-client/lib/defs/clientRepresentation.js' import type { CustomGroup } from './group.js' @@ -60,6 +60,7 @@ export const deleteProject: StepCall = async ({ args: project }) => { } export const upsertProject: StepCall = async ({ args: project }) => { + const pluginResult = new PluginResultBuilder('Up-to-date') try { const kcClient = await getkcClient() const projectName = project.slug @@ -74,6 +75,10 @@ export const upsertProject: StepCall = async ({ args: project }) => { id: member.id, groupId: projectGroup.id, }) + .catch((err) => { + pluginResult.addKoMessage(`Can't remove ${member.email} from keycloak project group`) + pluginResult.addExtra(`remove-${member.id}`, err) + }) } return undefined }), @@ -83,6 +88,10 @@ export const upsertProject: StepCall = async ({ args: project }) => { id: user.id, groupId: projectGroup.id, }) + .catch((err) => { + pluginResult.addKoMessage(`Can't add ${user.email} to keycloak project group`) + pluginResult.addExtra(`add-${user.id}`, err) + }) } return undefined }), @@ -130,20 +139,9 @@ export const upsertProject: StepCall = async ({ args: project }) => { return undefined })) - return { - status: { - result: 'OK', - message: 'Up-to-date', - }, - } + return pluginResult.getResultObject() } catch (error) { - return { - error: parseError(error), - status: { - result: 'KO', - message: 'Failed', - }, - } + return pluginResult.returnUnexpectedError(error) } }