Expose commitment CRUD on MCP, CLI, n8n

Sync GraphQL commitment group and item operations
to the remaining API surfaces so automation can
manage compliance portal commitments end to end.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-07-20 19:25:29 +02:00
parent e27a830d76
commit 2db37660d3
24 changed files with 3588 additions and 0 deletions

View File

@@ -0,0 +1,161 @@
// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
const commitmentIconOptions = [
{ name: 'Lock Key', value: 'LOCK_KEY' },
{ name: 'Eye Slash', value: 'EYE_SLASH' },
{ name: 'Fingerprint', value: 'FINGERPRINT' },
{ name: 'Shield Warning', value: 'SHIELD_WARNING' },
{ name: 'Shield Check', value: 'SHIELD_CHECK' },
{ name: 'Siren', value: 'SIREN' },
{ name: 'Key', value: 'KEY' },
{ name: 'Lock', value: 'LOCK' },
{ name: 'Cloud', value: 'CLOUD' },
{ name: 'Database', value: 'DATABASE' },
{ name: 'Globe', value: 'GLOBE' },
{ name: 'Eye', value: 'EYE' },
{ name: 'Users', value: 'USERS' },
{ name: 'Certificate', value: 'CERTIFICATE' },
{ name: 'Gavel', value: 'GAVEL' },
{ name: 'Heartbeat', value: 'HEARTBEAT' },
{ name: 'Bell', value: 'BELL' },
{ name: 'Bug', value: 'BUG' },
{ name: 'Code', value: 'CODE' },
{ name: 'Server', value: 'SERVER' },
];
export const description: INodeProperties[] = [
{
displayName: 'Commitment Group ID',
name: 'groupId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createCommitment'],
},
},
default: '',
description: 'The ID of the commitment group',
required: true,
},
{
displayName: 'Icon',
name: 'icon',
type: 'options',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createCommitment'],
},
},
options: commitmentIconOptions,
default: 'LOCK_KEY',
description: 'The icon of the commitment',
required: true,
},
{
displayName: 'Eyebrow',
name: 'eyebrow',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createCommitment'],
},
},
default: '',
description: 'The eyebrow text of the commitment',
required: true,
},
{
displayName: 'Title',
name: 'title',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createCommitment'],
},
},
default: '',
description: 'The title of the commitment',
required: true,
},
{
displayName: 'Description',
name: 'description',
type: 'string',
typeOptions: {
rows: 4,
},
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createCommitment'],
},
},
default: '',
description: 'The description of the commitment',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const groupId = this.getNodeParameter('groupId', itemIndex) as string;
const icon = this.getNodeParameter('icon', itemIndex) as string;
const eyebrow = this.getNodeParameter('eyebrow', itemIndex) as string;
const title = this.getNodeParameter('title', itemIndex) as string;
const description = this.getNodeParameter('description', itemIndex) as string;
const query = `
mutation CreateCompliancePortalCommitment($input: CreateCompliancePortalCommitmentInput!) {
createCompliancePortalCommitment(input: $input) {
compliancePortalCommitmentEdge {
node {
id
icon
eyebrow
title
description
rank
createdAt
updatedAt
}
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, {
input: { groupId, icon, eyebrow, title, description },
});
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,105 @@
// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Trust Center ID',
name: 'trustCenterId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createCommitmentGroup'],
},
},
default: '',
description: 'The ID of the trust center',
required: true,
},
{
displayName: 'Title',
name: 'title',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createCommitmentGroup'],
},
},
default: '',
description: 'The title of the commitment group',
required: true,
},
{
displayName: 'Description',
name: 'description',
type: 'string',
typeOptions: {
rows: 4,
},
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createCommitmentGroup'],
},
},
default: '',
description: 'The description of the commitment group',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const trustCenterId = this.getNodeParameter('trustCenterId', itemIndex) as string;
const title = this.getNodeParameter('title', itemIndex) as string;
const description = this.getNodeParameter('description', itemIndex) as string;
const query = `
mutation CreateCompliancePortalCommitmentGroup($input: CreateCompliancePortalCommitmentGroupInput!) {
createCompliancePortalCommitmentGroup(input: $input) {
compliancePortalCommitmentGroupEdge {
node {
id
title
description
rank
createdAt
updatedAt
}
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, {
input: { trustCenterId, title, description },
});
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,61 @@
// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Commitment ID',
name: 'commitmentId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['deleteCommitment'],
},
},
default: '',
description: 'The ID of the commitment to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const commitmentId = this.getNodeParameter('commitmentId', itemIndex) as string;
const query = `
mutation DeleteCompliancePortalCommitment($input: DeleteCompliancePortalCommitmentInput!) {
deleteCompliancePortalCommitment(input: $input) {
deletedCompliancePortalCommitmentId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { id: commitmentId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,61 @@
// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Commitment Group ID',
name: 'commitmentGroupId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['deleteCommitmentGroup'],
},
},
default: '',
description: 'The ID of the commitment group to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const commitmentGroupId = this.getNodeParameter('commitmentGroupId', itemIndex) as string;
const query = `
mutation DeleteCompliancePortalCommitmentGroup($input: DeleteCompliancePortalCommitmentGroupInput!) {
deleteCompliancePortalCommitmentGroup(input: $input) {
deletedCompliancePortalCommitmentGroupId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { id: commitmentGroupId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,124 @@
// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData, IDataObject } from 'n8n-workflow';
import { proboApiRequestAllItems } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['getAllCommitmentGroups'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['getAllCommitmentGroups'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['getAllCommitmentGroups'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
},
default: 50,
description: 'Max number of results to return',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
const returnAll = this.getNodeParameter('returnAll', itemIndex) as boolean;
const limit = this.getNodeParameter('limit', itemIndex, 50) as number;
const query = `
query GetCompliancePortalCommitmentGroups($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
trustCenter {
commitmentGroups(first: $first, after: $after) {
edges {
node {
id
title
description
rank
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
}
`;
const commitmentGroups = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
const trustCenter = node?.trustCenter as IDataObject | undefined;
return trustCenter?.commitmentGroups as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { commitmentGroups },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,123 @@
// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData, IDataObject } from 'n8n-workflow';
import { proboApiRequestAllItems } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Commitment Group ID',
name: 'groupId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['getAllCommitments'],
},
},
default: '',
description: 'The ID of the commitment group',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['getAllCommitments'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['getAllCommitments'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
},
default: 50,
description: 'Max number of results to return',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const groupId = this.getNodeParameter('groupId', itemIndex) as string;
const returnAll = this.getNodeParameter('returnAll', itemIndex) as boolean;
const limit = this.getNodeParameter('limit', itemIndex, 50) as number;
const query = `
query GetCompliancePortalCommitments($groupId: ID!, $first: Int, $after: CursorKey) {
node(id: $groupId) {
... on CompliancePortalCommitmentGroup {
commitments(first: $first, after: $after) {
edges {
node {
id
icon
eyebrow
title
description
rank
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const commitments = await proboApiRequestAllItems.call(
this,
query,
{ groupId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.commitments as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { commitments },
pairedItem: { item: itemIndex },
};
}

View File

@@ -28,6 +28,14 @@ import * as getAllFilesOp from './getAllFiles.operation';
import * as deleteFileOp from './deleteFile.operation';
import * as createExternalUrlOp from './createExternalUrl.operation';
import * as deleteExternalUrlOp from './deleteExternalUrl.operation';
import * as getAllCommitmentGroupsOp from './getAllCommitmentGroups.operation';
import * as createCommitmentGroupOp from './createCommitmentGroup.operation';
import * as updateCommitmentGroupOp from './updateCommitmentGroup.operation';
import * as deleteCommitmentGroupOp from './deleteCommitmentGroup.operation';
import * as getAllCommitmentsOp from './getAllCommitments.operation';
import * as createCommitmentOp from './createCommitment.operation';
import * as updateCommitmentOp from './updateCommitment.operation';
import * as deleteCommitmentOp from './deleteCommitment.operation';
export const description: INodeProperties[] = [
{
@@ -41,6 +49,18 @@ export const description: INodeProperties[] = [
},
},
options: [
{
name: 'Create Commitment',
value: 'createCommitment',
description: 'Create a new compliance portal commitment',
action: 'Create a compliance portal commitment',
},
{
name: 'Create Commitment Group',
value: 'createCommitmentGroup',
description: 'Create a new compliance portal commitment group',
action: 'Create a compliance portal commitment group',
},
{
name: 'Create External URL',
value: 'createExternalUrl',
@@ -53,6 +73,18 @@ export const description: INodeProperties[] = [
description: 'Create a new trust center reference',
action: 'Create a trust center reference',
},
{
name: 'Delete Commitment',
value: 'deleteCommitment',
description: 'Delete a compliance portal commitment',
action: 'Delete a compliance portal commitment',
},
{
name: 'Delete Commitment Group',
value: 'deleteCommitmentGroup',
description: 'Delete a compliance portal commitment group',
action: 'Delete a compliance portal commitment group',
},
{
name: 'Delete External URL',
value: 'deleteExternalUrl',
@@ -77,6 +109,18 @@ export const description: INodeProperties[] = [
description: 'Get trust center settings',
action: 'Get trust center settings',
},
{
name: 'Get Many Commitment Groups',
value: 'getAllCommitmentGroups',
description: 'Get many compliance portal commitment groups',
action: 'Get many compliance portal commitment groups',
},
{
name: 'Get Many Commitments',
value: 'getAllCommitments',
description: 'Get many compliance portal commitments',
action: 'Get many compliance portal commitments',
},
{
name: 'Get Many Files',
value: 'getAllFiles',
@@ -95,6 +139,18 @@ export const description: INodeProperties[] = [
description: 'Update trust center settings',
action: 'Update trust center settings',
},
{
name: 'Update Commitment',
value: 'updateCommitment',
description: 'Update a compliance portal commitment',
action: 'Update a compliance portal commitment',
},
{
name: 'Update Commitment Group',
value: 'updateCommitmentGroup',
description: 'Update a compliance portal commitment group',
action: 'Update a compliance portal commitment group',
},
],
default: 'get',
},
@@ -107,6 +163,14 @@ export const description: INodeProperties[] = [
...deleteFileOp.description,
...createExternalUrlOp.description,
...deleteExternalUrlOp.description,
...getAllCommitmentGroupsOp.description,
...createCommitmentGroupOp.description,
...updateCommitmentGroupOp.description,
...deleteCommitmentGroupOp.description,
...getAllCommitmentsOp.description,
...createCommitmentOp.description,
...updateCommitmentOp.description,
...deleteCommitmentOp.description,
];
export {
@@ -119,4 +183,12 @@ export {
deleteFileOp as deleteFile,
createExternalUrlOp as createExternalUrl,
deleteExternalUrlOp as deleteExternalUrl,
getAllCommitmentGroupsOp as getAllCommitmentGroups,
createCommitmentGroupOp as createCommitmentGroup,
updateCommitmentGroupOp as updateCommitmentGroup,
deleteCommitmentGroupOp as deleteCommitmentGroup,
getAllCommitmentsOp as getAllCommitments,
createCommitmentOp as createCommitment,
updateCommitmentOp as updateCommitment,
deleteCommitmentOp as deleteCommitment,
};

View File

@@ -0,0 +1,175 @@
// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
const commitmentIconOptions = [
{ name: '(Unchanged)', value: '' },
{ name: 'Lock Key', value: 'LOCK_KEY' },
{ name: 'Eye Slash', value: 'EYE_SLASH' },
{ name: 'Fingerprint', value: 'FINGERPRINT' },
{ name: 'Shield Warning', value: 'SHIELD_WARNING' },
{ name: 'Shield Check', value: 'SHIELD_CHECK' },
{ name: 'Siren', value: 'SIREN' },
{ name: 'Key', value: 'KEY' },
{ name: 'Lock', value: 'LOCK' },
{ name: 'Cloud', value: 'CLOUD' },
{ name: 'Database', value: 'DATABASE' },
{ name: 'Globe', value: 'GLOBE' },
{ name: 'Eye', value: 'EYE' },
{ name: 'Users', value: 'USERS' },
{ name: 'Certificate', value: 'CERTIFICATE' },
{ name: 'Gavel', value: 'GAVEL' },
{ name: 'Heartbeat', value: 'HEARTBEAT' },
{ name: 'Bell', value: 'BELL' },
{ name: 'Bug', value: 'BUG' },
{ name: 'Code', value: 'CODE' },
{ name: 'Server', value: 'SERVER' },
];
export const description: INodeProperties[] = [
{
displayName: 'Commitment ID',
name: 'commitmentId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['updateCommitment'],
},
},
default: '',
description: 'The ID of the commitment to update',
required: true,
},
{
displayName: 'Icon',
name: 'icon',
type: 'options',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['updateCommitment'],
},
},
options: commitmentIconOptions,
default: '',
description: 'The icon of the commitment',
},
{
displayName: 'Eyebrow',
name: 'eyebrow',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['updateCommitment'],
},
},
default: '',
description: 'The eyebrow text of the commitment',
},
{
displayName: 'Title',
name: 'title',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['updateCommitment'],
},
},
default: '',
description: 'The title of the commitment',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
typeOptions: {
rows: 4,
},
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['updateCommitment'],
},
},
default: '',
description: 'The description of the commitment',
},
{
displayName: 'Rank',
name: 'rank',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['updateCommitment'],
},
},
default: '',
description: 'The rank of the commitment for ordering',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const commitmentId = this.getNodeParameter('commitmentId', itemIndex) as string;
const icon = this.getNodeParameter('icon', itemIndex, '') as string;
const eyebrow = this.getNodeParameter('eyebrow', itemIndex, '') as string;
const title = this.getNodeParameter('title', itemIndex, '') as string;
const description = this.getNodeParameter('description', itemIndex, '') as string;
const rank = this.getNodeParameter('rank', itemIndex, '') as string;
const query = `
mutation UpdateCompliancePortalCommitment($input: UpdateCompliancePortalCommitmentInput!) {
updateCompliancePortalCommitment(input: $input) {
compliancePortalCommitment {
id
icon
eyebrow
title
description
rank
createdAt
updatedAt
}
}
}
`;
const input: Record<string, unknown> = { id: commitmentId };
if (icon) input.icon = icon;
if (eyebrow) input.eyebrow = eyebrow;
if (title) input.title = title;
if (description) input.description = description;
if (rank) input.rank = Number(rank);
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,118 @@
// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Commitment Group ID',
name: 'commitmentGroupId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['updateCommitmentGroup'],
},
},
default: '',
description: 'The ID of the commitment group to update',
required: true,
},
{
displayName: 'Title',
name: 'title',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['updateCommitmentGroup'],
},
},
default: '',
description: 'The title of the commitment group',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
typeOptions: {
rows: 4,
},
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['updateCommitmentGroup'],
},
},
default: '',
description: 'The description of the commitment group',
},
{
displayName: 'Rank',
name: 'rank',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['updateCommitmentGroup'],
},
},
default: '',
description: 'The rank of the commitment group for ordering',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const commitmentGroupId = this.getNodeParameter('commitmentGroupId', itemIndex) as string;
const title = this.getNodeParameter('title', itemIndex, '') as string;
const description = this.getNodeParameter('description', itemIndex, '') as string;
const rank = this.getNodeParameter('rank', itemIndex, '') as string;
const query = `
mutation UpdateCompliancePortalCommitmentGroup($input: UpdateCompliancePortalCommitmentGroupInput!) {
updateCompliancePortalCommitmentGroup(input: $input) {
compliancePortalCommitmentGroup {
id
title
description
rank
createdAt
updatedAt
}
}
}
`;
const input: Record<string, unknown> = { id: commitmentGroupId };
if (title) input.title = title;
if (description) input.description = description;
if (rank) input.rank = Number(rank);
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}