Add missing resources to CLI, MCP, and n8n surfaces

Audit all three API surfaces against the console GraphQL schema and add
missing resources: asset, audit, datum, dpia, evidence upload, measure,
obligation, processing activity, rights request, snapshot, task, tia,
trust center (with references/files), and vendor management CLI
commands; MCP tools for deletes, rights requests, trust center, vendor
contacts/services, and compliance external URLs; n8n nodes for
obligation, finding, task, evidence, processing activity, dpia, tia,
rights request, snapshot, audit log, access review, organization
context, trust center, and additional control/measure/vendor operations.

Include MCP e2e test infrastructure (testutil MCP client with API key
auth and JSON-RPC session management) and tests covering all new MCP
tools.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-04-21 16:08:37 +02:00
parent f505e23cb0
commit 7be92defcc
220 changed files with 26395 additions and 7 deletions

View File

@@ -0,0 +1,64 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Access Review Campaign ID',
name: 'accessReviewCampaignId',
type: 'string',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['cancel'],
},
},
default: '',
description: 'The ID of the access review campaign to cancel',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const accessReviewCampaignId = this.getNodeParameter('accessReviewCampaignId', itemIndex) as string;
const query = `
mutation CancelAccessReviewCampaign($input: CancelAccessReviewCampaignInput!) {
cancelAccessReviewCampaign(input: $input) {
accessReviewCampaign {
id
name
description
status
startedAt
completedAt
createdAt
updatedAt
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { accessReviewCampaignId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,64 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Access Review Campaign ID',
name: 'accessReviewCampaignId',
type: 'string',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['close'],
},
},
default: '',
description: 'The ID of the access review campaign to close',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const accessReviewCampaignId = this.getNodeParameter('accessReviewCampaignId', itemIndex) as string;
const query = `
mutation CloseAccessReviewCampaign($input: CloseAccessReviewCampaignInput!) {
closeAccessReviewCampaign(input: $input) {
accessReviewCampaign {
id
name
description
status
startedAt
completedAt
createdAt
updatedAt
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { accessReviewCampaignId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,103 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'string',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['create'],
},
},
default: '',
description: 'The name of the access review campaign',
required: true,
},
{
displayName: 'Description',
name: 'description',
type: 'string',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['create'],
},
},
default: '',
description: 'The description of the access review campaign',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
const name = this.getNodeParameter('name', itemIndex) as string;
const description = this.getNodeParameter('description', itemIndex, '') as string;
const query = `
mutation CreateAccessReviewCampaign($input: CreateAccessReviewCampaignInput!) {
createAccessReviewCampaign(input: $input) {
accessReviewCampaignEdge {
node {
id
name
description
status
startedAt
completedAt
createdAt
updatedAt
}
}
}
}
`;
const variables = {
input: {
organizationId,
name,
...(description && { description }),
},
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Access Review Campaign ID',
name: 'accessReviewCampaignId',
type: 'string',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['delete'],
},
},
default: '',
description: 'The ID of the access review campaign to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const accessReviewCampaignId = this.getNodeParameter('accessReviewCampaignId', itemIndex) as string;
const query = `
mutation DeleteAccessReviewCampaign($input: DeleteAccessReviewCampaignInput!) {
deleteAccessReviewCampaign(input: $input) {
deletedAccessReviewCampaignId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { accessReviewCampaignId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,68 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Access Review Campaign ID',
name: 'accessReviewCampaignId',
type: 'string',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the access review campaign',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const accessReviewCampaignId = this.getNodeParameter('accessReviewCampaignId', itemIndex) as string;
const query = `
query GetAccessReviewCampaign($accessReviewCampaignId: ID!) {
node(id: $accessReviewCampaignId) {
... on AccessReviewCampaign {
id
name
description
status
startedAt
completedAt
createdAt
updatedAt
}
}
}
`;
const variables = {
accessReviewCampaignId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,117 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['accessReview'],
operation: ['getAll'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['getAll'],
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 GetAccessReviewCampaigns($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
accessReviewCampaigns(first: $first, after: $after) {
edges {
node {
id
name
description
status
startedAt
completedAt
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const accessReviewCampaigns = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.accessReviewCampaigns as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { accessReviewCampaigns },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,107 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as createOp from './create.operation';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
import * as updateOp from './update.operation';
import * as startOp from './start.operation';
import * as closeOp from './close.operation';
import * as cancelOp from './cancel.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['accessReview'],
},
},
options: [
{
name: 'Cancel',
value: 'cancel',
description: 'Cancel an access review campaign',
action: 'Cancel an access review campaign',
},
{
name: 'Close',
value: 'close',
description: 'Close an access review campaign',
action: 'Close an access review campaign',
},
{
name: 'Create',
value: 'create',
description: 'Create a new access review campaign',
action: 'Create an access review campaign',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete an access review campaign',
action: 'Delete an access review campaign',
},
{
name: 'Get',
value: 'get',
description: 'Get an access review campaign',
action: 'Get an access review campaign',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many access review campaigns',
action: 'Get many access review campaigns',
},
{
name: 'Start',
value: 'start',
description: 'Start an access review campaign',
action: 'Start an access review campaign',
},
{
name: 'Update',
value: 'update',
description: 'Update an existing access review campaign',
action: 'Update an access review campaign',
},
],
default: 'create',
},
...createOp.description,
...deleteOp.description,
...getOp.description,
...getAllOp.description,
...updateOp.description,
...startOp.description,
...closeOp.description,
...cancelOp.description,
];
export {
createOp as create,
deleteOp as delete,
getOp as get,
getAllOp as getAll,
updateOp as update,
startOp as start,
closeOp as close,
cancelOp as cancel,
};

View File

@@ -0,0 +1,64 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Access Review Campaign ID',
name: 'accessReviewCampaignId',
type: 'string',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['start'],
},
},
default: '',
description: 'The ID of the access review campaign to start',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const accessReviewCampaignId = this.getNodeParameter('accessReviewCampaignId', itemIndex) as string;
const query = `
mutation StartAccessReviewCampaign($input: StartAccessReviewCampaignInput!) {
startAccessReviewCampaign(input: $input) {
accessReviewCampaign {
id
name
description
status
startedAt
completedAt
createdAt
updatedAt
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { accessReviewCampaignId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,96 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Access Review Campaign ID',
name: 'accessReviewCampaignId',
type: 'string',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the access review campaign to update',
required: true,
},
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['update'],
},
},
default: '',
description: 'The name of the access review campaign',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
displayOptions: {
show: {
resource: ['accessReview'],
operation: ['update'],
},
},
default: '',
description: 'The description of the access review campaign',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const accessReviewCampaignId = this.getNodeParameter('accessReviewCampaignId', itemIndex) as string;
const name = this.getNodeParameter('name', itemIndex, '') as string;
const description = this.getNodeParameter('description', itemIndex, '') as string;
const query = `
mutation UpdateAccessReviewCampaign($input: UpdateAccessReviewCampaignInput!) {
updateAccessReviewCampaign(input: $input) {
accessReviewCampaign {
id
name
description
status
startedAt
completedAt
createdAt
updatedAt
}
}
}
`;
const input: Record<string, string> = { accessReviewCampaignId };
if (name) input.name = name;
if (description) input.description = description;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,68 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Audit Log Entry ID',
name: 'auditLogEntryId',
type: 'string',
displayOptions: {
show: {
resource: ['auditLog'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the audit log entry',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const auditLogEntryId = this.getNodeParameter('auditLogEntryId', itemIndex) as string;
const query = `
query GetAuditLogEntry($auditLogEntryId: ID!) {
node(id: $auditLogEntryId) {
... on AuditLogEntry {
id
actorId
actorType
action
resourceType
resourceId
metadata
createdAt
}
}
}
`;
const variables = {
auditLogEntryId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,117 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['auditLog'],
operation: ['getAll'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['auditLog'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['auditLog'],
operation: ['getAll'],
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 GetAuditLogEntries($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
auditLogEntries(first: $first, after: $after) {
edges {
node {
id
actorId
actorType
action
resourceType
resourceId
metadata
createdAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const auditLogEntries = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.auditLogEntries as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { auditLogEntries },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,50 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['auditLog'],
},
},
options: [
{
name: 'Get',
value: 'get',
description: 'Get an audit log entry',
action: 'Get an audit log entry',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many audit log entries',
action: 'Get many audit log entries',
},
],
default: 'get',
},
...getOp.description,
...getAllOp.description,
];
export { getOp as get, getAllOp as getAll };

View File

@@ -18,6 +18,16 @@ import * as updateOp from './update.operation';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
import * as linkMeasureOp from './linkMeasure.operation';
import * as unlinkMeasureOp from './unlinkMeasure.operation';
import * as linkDocumentOp from './linkDocument.operation';
import * as unlinkDocumentOp from './unlinkDocument.operation';
import * as linkAuditOp from './linkAudit.operation';
import * as unlinkAuditOp from './unlinkAudit.operation';
import * as linkObligationOp from './linkObligation.operation';
import * as unlinkObligationOp from './unlinkObligation.operation';
import * as linkSnapshotOp from './linkSnapshot.operation';
import * as unlinkSnapshotOp from './unlinkSnapshot.operation';
export const description: INodeProperties[] = [
{
@@ -55,6 +65,66 @@ export const description: INodeProperties[] = [
description: 'Get many controls',
action: 'Get many controls',
},
{
name: 'Link Audit',
value: 'linkAudit',
description: 'Link an audit to a control',
action: 'Link an audit to a control',
},
{
name: 'Link Document',
value: 'linkDocument',
description: 'Link a document to a control',
action: 'Link a document to a control',
},
{
name: 'Link Measure',
value: 'linkMeasure',
description: 'Link a measure to a control',
action: 'Link a measure to a control',
},
{
name: 'Link Obligation',
value: 'linkObligation',
description: 'Link an obligation to a control',
action: 'Link an obligation to a control',
},
{
name: 'Link Snapshot',
value: 'linkSnapshot',
description: 'Link a snapshot to a control',
action: 'Link a snapshot to a control',
},
{
name: 'Unlink Audit',
value: 'unlinkAudit',
description: 'Unlink an audit from a control',
action: 'Unlink an audit from a control',
},
{
name: 'Unlink Document',
value: 'unlinkDocument',
description: 'Unlink a document from a control',
action: 'Unlink a document from a control',
},
{
name: 'Unlink Measure',
value: 'unlinkMeasure',
description: 'Unlink a measure from a control',
action: 'Unlink a measure from a control',
},
{
name: 'Unlink Obligation',
value: 'unlinkObligation',
description: 'Unlink an obligation from a control',
action: 'Unlink an obligation from a control',
},
{
name: 'Unlink Snapshot',
value: 'unlinkSnapshot',
description: 'Unlink a snapshot from a control',
action: 'Unlink a snapshot from a control',
},
{
name: 'Update',
value: 'update',
@@ -69,6 +139,32 @@ export const description: INodeProperties[] = [
...deleteOp.description,
...getOp.description,
...getAllOp.description,
...linkMeasureOp.description,
...unlinkMeasureOp.description,
...linkDocumentOp.description,
...unlinkDocumentOp.description,
...linkAuditOp.description,
...unlinkAuditOp.description,
...linkObligationOp.description,
...unlinkObligationOp.description,
...linkSnapshotOp.description,
...unlinkSnapshotOp.description,
];
export { createOp as create, updateOp as update, deleteOp as delete, getOp as get, getAllOp as getAll };
export {
createOp as create,
updateOp as update,
deleteOp as delete,
getOp as get,
getAllOp as getAll,
linkMeasureOp as linkMeasure,
unlinkMeasureOp as unlinkMeasure,
linkDocumentOp as linkDocument,
unlinkDocumentOp as unlinkDocument,
linkAuditOp as linkAudit,
unlinkAuditOp as unlinkAudit,
linkObligationOp as linkObligation,
unlinkObligationOp as unlinkObligation,
linkSnapshotOp as linkSnapshot,
unlinkSnapshotOp as unlinkSnapshot,
};

View File

@@ -0,0 +1,81 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Control ID',
name: 'controlId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['linkAudit'],
},
},
default: '',
description: 'The ID of the control',
required: true,
},
{
displayName: 'Audit ID',
name: 'auditId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['linkAudit'],
},
},
default: '',
description: 'The ID of the audit to link',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const controlId = this.getNodeParameter('controlId', itemIndex) as string;
const auditId = this.getNodeParameter('auditId', itemIndex) as string;
const query = `
mutation CreateControlAuditMapping($input: CreateControlAuditMappingInput!) {
createControlAuditMapping(input: $input) {
controlEdge {
node {
id
name
}
}
auditEdge {
node {
id
name
}
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { controlId, auditId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,81 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Control ID',
name: 'controlId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['linkDocument'],
},
},
default: '',
description: 'The ID of the control',
required: true,
},
{
displayName: 'Document ID',
name: 'documentId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['linkDocument'],
},
},
default: '',
description: 'The ID of the document to link',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const controlId = this.getNodeParameter('controlId', itemIndex) as string;
const documentId = this.getNodeParameter('documentId', itemIndex) as string;
const query = `
mutation CreateControlDocumentMapping($input: CreateControlDocumentMappingInput!) {
createControlDocumentMapping(input: $input) {
controlEdge {
node {
id
name
}
}
documentEdge {
node {
id
title
}
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { controlId, documentId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,81 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Control ID',
name: 'controlId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['linkMeasure'],
},
},
default: '',
description: 'The ID of the control',
required: true,
},
{
displayName: 'Measure ID',
name: 'measureId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['linkMeasure'],
},
},
default: '',
description: 'The ID of the measure to link',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const controlId = this.getNodeParameter('controlId', itemIndex) as string;
const measureId = this.getNodeParameter('measureId', itemIndex) as string;
const query = `
mutation CreateControlMeasureMapping($input: CreateControlMeasureMappingInput!) {
createControlMeasureMapping(input: $input) {
controlEdge {
node {
id
name
}
}
measureEdge {
node {
id
name
}
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { controlId, measureId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,81 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Control ID',
name: 'controlId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['linkObligation'],
},
},
default: '',
description: 'The ID of the control',
required: true,
},
{
displayName: 'Obligation ID',
name: 'obligationId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['linkObligation'],
},
},
default: '',
description: 'The ID of the obligation to link',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const controlId = this.getNodeParameter('controlId', itemIndex) as string;
const obligationId = this.getNodeParameter('obligationId', itemIndex) as string;
const query = `
mutation CreateControlObligationMapping($input: CreateControlObligationMappingInput!) {
createControlObligationMapping(input: $input) {
controlEdge {
node {
id
name
}
}
obligationEdge {
node {
id
name
}
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { controlId, obligationId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,81 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Control ID',
name: 'controlId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['linkSnapshot'],
},
},
default: '',
description: 'The ID of the control',
required: true,
},
{
displayName: 'Snapshot ID',
name: 'snapshotId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['linkSnapshot'],
},
},
default: '',
description: 'The ID of the snapshot to link',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const controlId = this.getNodeParameter('controlId', itemIndex) as string;
const snapshotId = this.getNodeParameter('snapshotId', itemIndex) as string;
const query = `
mutation CreateControlSnapshotMapping($input: CreateControlSnapshotMappingInput!) {
createControlSnapshotMapping(input: $input) {
controlEdge {
node {
id
name
}
}
snapshotEdge {
node {
id
name
}
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { controlId, snapshotId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,71 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Control ID',
name: 'controlId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['unlinkAudit'],
},
},
default: '',
description: 'The ID of the control',
required: true,
},
{
displayName: 'Audit ID',
name: 'auditId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['unlinkAudit'],
},
},
default: '',
description: 'The ID of the audit to unlink',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const controlId = this.getNodeParameter('controlId', itemIndex) as string;
const auditId = this.getNodeParameter('auditId', itemIndex) as string;
const query = `
mutation DeleteControlAuditMapping($input: DeleteControlAuditMappingInput!) {
deleteControlAuditMapping(input: $input) {
deletedControlId
deletedAuditId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { controlId, auditId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,71 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Control ID',
name: 'controlId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['unlinkDocument'],
},
},
default: '',
description: 'The ID of the control',
required: true,
},
{
displayName: 'Document ID',
name: 'documentId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['unlinkDocument'],
},
},
default: '',
description: 'The ID of the document to unlink',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const controlId = this.getNodeParameter('controlId', itemIndex) as string;
const documentId = this.getNodeParameter('documentId', itemIndex) as string;
const query = `
mutation DeleteControlDocumentMapping($input: DeleteControlDocumentMappingInput!) {
deleteControlDocumentMapping(input: $input) {
deletedControlId
deletedDocumentId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { controlId, documentId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,71 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Control ID',
name: 'controlId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['unlinkMeasure'],
},
},
default: '',
description: 'The ID of the control',
required: true,
},
{
displayName: 'Measure ID',
name: 'measureId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['unlinkMeasure'],
},
},
default: '',
description: 'The ID of the measure to unlink',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const controlId = this.getNodeParameter('controlId', itemIndex) as string;
const measureId = this.getNodeParameter('measureId', itemIndex) as string;
const query = `
mutation DeleteControlMeasureMapping($input: DeleteControlMeasureMappingInput!) {
deleteControlMeasureMapping(input: $input) {
deletedControlId
deletedMeasureId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { controlId, measureId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,71 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Control ID',
name: 'controlId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['unlinkObligation'],
},
},
default: '',
description: 'The ID of the control',
required: true,
},
{
displayName: 'Obligation ID',
name: 'obligationId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['unlinkObligation'],
},
},
default: '',
description: 'The ID of the obligation to unlink',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const controlId = this.getNodeParameter('controlId', itemIndex) as string;
const obligationId = this.getNodeParameter('obligationId', itemIndex) as string;
const query = `
mutation DeleteControlObligationMapping($input: DeleteControlObligationMappingInput!) {
deleteControlObligationMapping(input: $input) {
deletedControlId
deletedObligationId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { controlId, obligationId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,71 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Control ID',
name: 'controlId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['unlinkSnapshot'],
},
},
default: '',
description: 'The ID of the control',
required: true,
},
{
displayName: 'Snapshot ID',
name: 'snapshotId',
type: 'string',
displayOptions: {
show: {
resource: ['control'],
operation: ['unlinkSnapshot'],
},
},
default: '',
description: 'The ID of the snapshot to unlink',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const controlId = this.getNodeParameter('controlId', itemIndex) as string;
const snapshotId = this.getNodeParameter('snapshotId', itemIndex) as string;
const query = `
mutation DeleteControlSnapshotMapping($input: DeleteControlSnapshotMappingInput!) {
deleteControlSnapshotMapping(input: $input) {
deletedControlId
deletedSnapshotId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { controlId, snapshotId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,166 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Processing Activity ID',
name: 'processingActivityId',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the processing activity',
required: true,
},
{
displayName: 'Description',
name: 'description',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['create'],
},
},
default: '',
description: 'The description of the DPIA',
required: true,
},
{
displayName: 'Necessity and Proportionality',
name: 'necessityAndProportionality',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['create'],
},
},
default: '',
description: 'The necessity and proportionality assessment',
required: true,
},
{
displayName: 'Potential Risk',
name: 'potentialRisk',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['create'],
},
},
default: '',
description: 'The potential risk assessment',
required: true,
},
{
displayName: 'Mitigations',
name: 'mitigations',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['create'],
},
},
default: '',
description: 'The mitigations for the identified risks',
required: true,
},
{
displayName: 'Residual Risk',
name: 'residualRisk',
type: 'options',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['create'],
},
},
options: [
{
name: 'Low',
value: 'LOW',
},
{
name: 'Medium',
value: 'MEDIUM',
},
{
name: 'High',
value: 'HIGH',
},
],
default: 'LOW',
description: 'The residual risk level',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const processingActivityId = this.getNodeParameter('processingActivityId', itemIndex) as string;
const description = this.getNodeParameter('description', itemIndex) as string;
const necessityAndProportionality = this.getNodeParameter('necessityAndProportionality', itemIndex) as string;
const potentialRisk = this.getNodeParameter('potentialRisk', itemIndex) as string;
const mitigations = this.getNodeParameter('mitigations', itemIndex) as string;
const residualRisk = this.getNodeParameter('residualRisk', itemIndex) as string;
const query = `
mutation CreateDataProtectionImpactAssessment($input: CreateDataProtectionImpactAssessmentInput!) {
createDataProtectionImpactAssessment(input: $input) {
dataProtectionImpactAssessmentEdge {
node {
id
description
necessityAndProportionality
potentialRisk
mitigations
residualRisk
createdAt
updatedAt
}
}
}
}
`;
const variables = {
input: {
processingActivityId,
description,
necessityAndProportionality,
potentialRisk,
mitigations,
residualRisk,
},
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'DPIA ID',
name: 'dataProtectionImpactAssessmentId',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['delete'],
},
},
default: '',
description: 'The ID of the DPIA to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const dataProtectionImpactAssessmentId = this.getNodeParameter('dataProtectionImpactAssessmentId', itemIndex) as string;
const query = `
mutation DeleteDataProtectionImpactAssessment($input: DeleteDataProtectionImpactAssessmentInput!) {
deleteDataProtectionImpactAssessment(input: $input) {
deletedDataProtectionImpactAssessmentId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { dataProtectionImpactAssessmentId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,68 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'DPIA ID',
name: 'dataProtectionImpactAssessmentId',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the DPIA',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const dataProtectionImpactAssessmentId = this.getNodeParameter('dataProtectionImpactAssessmentId', itemIndex) as string;
const query = `
query GetDataProtectionImpactAssessment($dataProtectionImpactAssessmentId: ID!) {
node(id: $dataProtectionImpactAssessmentId) {
... on DataProtectionImpactAssessment {
id
description
necessityAndProportionality
potentialRisk
mitigations
residualRisk
createdAt
updatedAt
}
}
}
`;
const variables = {
dataProtectionImpactAssessmentId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,117 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['dpia'],
operation: ['getAll'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['getAll'],
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 GetDataProtectionImpactAssessments($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
dataProtectionImpactAssessments(first: $first, after: $after) {
edges {
node {
id
description
necessityAndProportionality
potentialRisk
mitigations
residualRisk
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const dataProtectionImpactAssessments = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.dataProtectionImpactAssessments as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { dataProtectionImpactAssessments },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,74 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as createOp from './create.operation';
import * as updateOp from './update.operation';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['dpia'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new DPIA',
action: 'Create a DPIA',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a DPIA',
action: 'Delete a DPIA',
},
{
name: 'Get',
value: 'get',
description: 'Get a DPIA',
action: 'Get a DPIA',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many DPIAs',
action: 'Get many dpias',
},
{
name: 'Update',
value: 'update',
description: 'Update an existing DPIA',
action: 'Update a DPIA',
},
],
default: 'create',
},
...createOp.description,
...updateOp.description,
...deleteOp.description,
...getOp.description,
...getAllOp.description,
];
export { createOp as create, updateOp as update, deleteOp as delete, getOp as get, getAllOp as getAll };

View File

@@ -0,0 +1,159 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'DPIA ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the DPIA to update',
required: true,
},
{
displayName: 'Description',
name: 'description',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['update'],
},
},
default: '',
description: 'The description of the DPIA',
},
{
displayName: 'Necessity and Proportionality',
name: 'necessityAndProportionality',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['update'],
},
},
default: '',
description: 'The necessity and proportionality assessment',
},
{
displayName: 'Potential Risk',
name: 'potentialRisk',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['update'],
},
},
default: '',
description: 'The potential risk assessment',
},
{
displayName: 'Mitigations',
name: 'mitigations',
type: 'string',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['update'],
},
},
default: '',
description: 'The mitigations for the identified risks',
},
{
displayName: 'Residual Risk',
name: 'residualRisk',
type: 'options',
displayOptions: {
show: {
resource: ['dpia'],
operation: ['update'],
},
},
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'Low',
value: 'LOW',
},
{
name: 'Medium',
value: 'MEDIUM',
},
{
name: 'High',
value: 'HIGH',
},
],
default: '',
description: 'The residual risk level',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const id = this.getNodeParameter('id', itemIndex) as string;
const description = this.getNodeParameter('description', itemIndex, '') as string;
const necessityAndProportionality = this.getNodeParameter('necessityAndProportionality', itemIndex, '') as string;
const potentialRisk = this.getNodeParameter('potentialRisk', itemIndex, '') as string;
const mitigations = this.getNodeParameter('mitigations', itemIndex, '') as string;
const residualRisk = this.getNodeParameter('residualRisk', itemIndex, '') as string;
const query = `
mutation UpdateDataProtectionImpactAssessment($input: UpdateDataProtectionImpactAssessmentInput!) {
updateDataProtectionImpactAssessment(input: $input) {
dataProtectionImpactAssessment {
id
description
necessityAndProportionality
potentialRisk
mitigations
residualRisk
createdAt
updatedAt
}
}
}
`;
const input: Record<string, string> = { id };
if (description) input.description = description;
if (necessityAndProportionality) input.necessityAndProportionality = necessityAndProportionality;
if (potentialRisk) input.potentialRisk = potentialRisk;
if (mitigations) input.mitigations = mitigations;
if (residualRisk) input.residualRisk = residualRisk;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Evidence ID',
name: 'evidenceId',
type: 'string',
displayOptions: {
show: {
resource: ['evidence'],
operation: ['delete'],
},
},
default: '',
description: 'The ID of the evidence to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const evidenceId = this.getNodeParameter('evidenceId', itemIndex) as string;
const query = `
mutation DeleteEvidence($input: DeleteEvidenceInput!) {
deleteEvidence(input: $input) {
deletedEvidenceId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { evidenceId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,66 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Evidence ID',
name: 'evidenceId',
type: 'string',
displayOptions: {
show: {
resource: ['evidence'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the evidence',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const evidenceId = this.getNodeParameter('evidenceId', itemIndex) as string;
const query = `
query GetEvidence($evidenceId: ID!) {
node(id: $evidenceId) {
... on Evidence {
id
state
type
description
createdAt
updatedAt
}
}
}
`;
const variables = {
evidenceId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,115 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData, IDataObject } from 'n8n-workflow';
import { proboApiRequestAllItems } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Measure ID',
name: 'measureId',
type: 'string',
displayOptions: {
show: {
resource: ['evidence'],
operation: ['getAll'],
},
},
default: '',
description: 'The ID of the measure to list evidences for',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['evidence'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['evidence'],
operation: ['getAll'],
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 measureId = this.getNodeParameter('measureId', itemIndex) as string;
const returnAll = this.getNodeParameter('returnAll', itemIndex) as boolean;
const limit = this.getNodeParameter('limit', itemIndex, 50) as number;
const query = `
query GetEvidences($measureId: ID!, $first: Int, $after: CursorKey) {
node(id: $measureId) {
... on Measure {
evidences(first: $first, after: $after) {
edges {
node {
id
state
type
description
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const evidences = await proboApiRequestAllItems.call(
this,
query,
{ measureId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.evidences as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { evidences },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,66 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
import * as uploadOp from './upload.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['evidence'],
},
},
options: [
{
name: 'Delete',
value: 'delete',
description: 'Delete an evidence',
action: 'Delete an evidence',
},
{
name: 'Get',
value: 'get',
description: 'Get an evidence',
action: 'Get an evidence',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many evidences for a measure',
action: 'Get many evidences',
},
{
name: 'Upload',
value: 'upload',
description: 'Upload evidence for a measure',
action: 'Upload evidence',
},
],
default: 'getAll',
},
...deleteOp.description,
...getOp.description,
...getAllOp.description,
...uploadOp.description,
];
export { deleteOp as delete, getOp as get, getAllOp as getAll, uploadOp as upload };

View File

@@ -0,0 +1,100 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiMultipartRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Measure ID',
name: 'measureId',
type: 'string',
displayOptions: {
show: {
resource: ['evidence'],
operation: ['upload'],
},
},
default: '',
description: 'The ID of the measure to upload evidence for',
required: true,
},
{
displayName: 'Input Data Field Name',
name: 'binaryPropertyName',
type: 'string',
displayOptions: {
show: {
resource: ['evidence'],
operation: ['upload'],
},
},
default: 'data',
description: 'The name of the input field containing the binary file data to upload',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const measureId = this.getNodeParameter('measureId', itemIndex) as string;
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex) as string;
const binaryData = this.helpers.assertBinaryData(itemIndex, binaryPropertyName);
const fileBuffer = await this.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName);
const fileName = binaryData.fileName || 'evidence';
const mimeType = binaryData.mimeType || 'application/octet-stream';
const query = `
mutation UploadMeasureEvidence($input: UploadMeasureEvidenceInput!) {
uploadMeasureEvidence(input: $input) {
evidenceEdge {
node {
id
state
type
description
createdAt
updatedAt
}
}
}
}
`;
const variables = {
input: {
measureId,
file: null,
},
};
const responseData = await proboApiMultipartRequest.call(
this,
query,
variables,
'variables.input.file',
fileBuffer,
fileName,
mimeType,
);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,272 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'string',
displayOptions: {
show: {
resource: ['finding'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Kind',
name: 'kind',
type: 'options',
displayOptions: {
show: {
resource: ['finding'],
operation: ['create'],
},
},
options: [
{
name: 'Minor Nonconformity',
value: 'MINOR_NONCONFORMITY',
},
{
name: 'Major Nonconformity',
value: 'MAJOR_NONCONFORMITY',
},
{
name: 'Observation',
value: 'OBSERVATION',
},
{
name: 'Exception',
value: 'EXCEPTION',
},
],
default: 'MINOR_NONCONFORMITY',
description: 'The kind of finding',
required: true,
},
{
displayName: 'Description',
name: 'description',
type: 'string',
displayOptions: {
show: {
resource: ['finding'],
operation: ['create'],
},
},
default: '',
description: 'The description of the finding',
required: true,
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['finding'],
operation: ['create'],
},
},
options: [
{
displayName: 'Corrective Action',
name: 'correctiveAction',
type: 'string',
default: '',
description: 'The corrective action for the finding',
},
{
displayName: 'Due Date',
name: 'dueDate',
type: 'string',
default: '',
description: 'The due date for the finding (ISO 8601 format)',
},
{
displayName: 'Effectiveness Check',
name: 'effectivenessCheck',
type: 'string',
default: '',
description: 'The effectiveness check for the finding',
},
{
displayName: 'Identified On',
name: 'identifiedOn',
type: 'string',
default: '',
description: 'The date the finding was identified (ISO 8601 format)',
},
{
displayName: 'Owner ID',
name: 'ownerId',
type: 'string',
default: '',
description: 'The ID of the person who owns this finding',
},
{
displayName: 'Priority',
name: 'priority',
type: 'options',
options: [
{
name: 'Low',
value: 'LOW',
},
{
name: 'Medium',
value: 'MEDIUM',
},
{
name: 'High',
value: 'HIGH',
},
],
default: 'MEDIUM',
description: 'The priority of the finding',
},
{
displayName: 'Risk ID',
name: 'riskId',
type: 'string',
default: '',
description: 'The ID of the associated risk',
},
{
displayName: 'Root Cause',
name: 'rootCause',
type: 'string',
default: '',
description: 'The root cause of the finding',
},
{
displayName: 'Source',
name: 'source',
type: 'string',
default: '',
description: 'The source of the finding',
},
{
displayName: 'Status',
name: 'status',
type: 'options',
options: [
{
name: 'Closed',
value: 'CLOSED',
},
{
name: 'False Positive',
value: 'FALSE_POSITIVE',
},
{
name: 'In Progress',
value: 'IN_PROGRESS',
},
{
name: 'Mitigated',
value: 'MITIGATED',
},
{
name: 'Open',
value: 'OPEN',
},
{
name: 'Risk Accepted',
value: 'RISK_ACCEPTED',
},
],
default: 'OPEN',
description: 'The status of the finding',
},
],
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
const kind = this.getNodeParameter('kind', itemIndex) as string;
const description = this.getNodeParameter('description', itemIndex) as string;
const additionalFields = this.getNodeParameter('additionalFields', itemIndex, {}) as {
source?: string;
identifiedOn?: string;
rootCause?: string;
correctiveAction?: string;
ownerId?: string;
dueDate?: string;
status?: string;
priority?: string;
riskId?: string;
effectivenessCheck?: string;
};
const query = `
mutation CreateFinding($input: CreateFindingInput!) {
createFinding(input: $input) {
findingEdge {
node {
id
kind
description
source
identifiedOn
rootCause
correctiveAction
dueDate
status
priority
effectivenessCheck
createdAt
updatedAt
}
}
}
}
`;
const input: Record<string, unknown> = {
organizationId,
kind,
description,
};
if (additionalFields.source) input.source = additionalFields.source;
if (additionalFields.identifiedOn) input.identifiedOn = additionalFields.identifiedOn;
if (additionalFields.rootCause) input.rootCause = additionalFields.rootCause;
if (additionalFields.correctiveAction) input.correctiveAction = additionalFields.correctiveAction;
if (additionalFields.ownerId) input.ownerId = additionalFields.ownerId;
if (additionalFields.dueDate) input.dueDate = additionalFields.dueDate;
if (additionalFields.status) input.status = additionalFields.status;
if (additionalFields.priority) input.priority = additionalFields.priority;
if (additionalFields.riskId) input.riskId = additionalFields.riskId;
if (additionalFields.effectivenessCheck) input.effectivenessCheck = additionalFields.effectivenessCheck;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Finding ID',
name: 'findingId',
type: 'string',
displayOptions: {
show: {
resource: ['finding'],
operation: ['delete'],
},
},
default: '',
description: 'The ID of the finding to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const findingId = this.getNodeParameter('findingId', itemIndex) as string;
const query = `
mutation DeleteFinding($input: DeleteFindingInput!) {
deleteFinding(input: $input) {
deletedFindingId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { findingId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,73 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Finding ID',
name: 'findingId',
type: 'string',
displayOptions: {
show: {
resource: ['finding'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the finding',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const findingId = this.getNodeParameter('findingId', itemIndex) as string;
const query = `
query GetFinding($findingId: ID!) {
node(id: $findingId) {
... on Finding {
id
kind
description
source
identifiedOn
rootCause
correctiveAction
dueDate
status
priority
effectivenessCheck
createdAt
updatedAt
}
}
}
`;
const variables = {
findingId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,122 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['finding'],
operation: ['getAll'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['finding'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['finding'],
operation: ['getAll'],
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 GetFindings($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
findings(first: $first, after: $after) {
edges {
node {
id
kind
description
source
identifiedOn
rootCause
correctiveAction
dueDate
status
priority
effectivenessCheck
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const findings = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.findings as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { findings },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,98 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as createOp from './create.operation';
import * as updateOp from './update.operation';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
import * as linkAuditOp from './linkAudit.operation';
import * as unlinkAuditOp from './unlinkAudit.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['finding'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new finding',
action: 'Create a finding',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a finding',
action: 'Delete a finding',
},
{
name: 'Get',
value: 'get',
description: 'Get a finding',
action: 'Get a finding',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many findings',
action: 'Get many findings',
},
{
name: 'Link Audit',
value: 'linkAudit',
description: 'Link an audit to a finding',
action: 'Link an audit to a finding',
},
{
name: 'Unlink Audit',
value: 'unlinkAudit',
description: 'Unlink an audit from a finding',
action: 'Unlink an audit from a finding',
},
{
name: 'Update',
value: 'update',
description: 'Update an existing finding',
action: 'Update a finding',
},
],
default: 'create',
},
...createOp.description,
...updateOp.description,
...deleteOp.description,
...getOp.description,
...getAllOp.description,
...linkAuditOp.description,
...unlinkAuditOp.description,
];
export {
createOp as create,
updateOp as update,
deleteOp as delete,
getOp as get,
getAllOp as getAll,
linkAuditOp as linkAudit,
unlinkAuditOp as unlinkAudit,
};

View File

@@ -0,0 +1,87 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Finding ID',
name: 'findingId',
type: 'string',
displayOptions: {
show: {
resource: ['finding'],
operation: ['linkAudit'],
},
},
default: '',
description: 'The ID of the finding',
required: true,
},
{
displayName: 'Audit ID',
name: 'auditId',
type: 'string',
displayOptions: {
show: {
resource: ['finding'],
operation: ['linkAudit'],
},
},
default: '',
description: 'The ID of the audit to link',
required: true,
},
{
displayName: 'Reference ID',
name: 'referenceId',
type: 'string',
displayOptions: {
show: {
resource: ['finding'],
operation: ['linkAudit'],
},
},
default: '',
description: 'The reference ID for the mapping',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const findingId = this.getNodeParameter('findingId', itemIndex) as string;
const auditId = this.getNodeParameter('auditId', itemIndex) as string;
const referenceId = this.getNodeParameter('referenceId', itemIndex) as string;
const query = `
mutation CreateFindingAuditMapping($input: CreateFindingAuditMappingInput!) {
createFindingAuditMapping(input: $input) {
finding {
id
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { findingId, auditId, referenceId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,72 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Finding ID',
name: 'findingId',
type: 'string',
displayOptions: {
show: {
resource: ['finding'],
operation: ['unlinkAudit'],
},
},
default: '',
description: 'The ID of the finding',
required: true,
},
{
displayName: 'Audit ID',
name: 'auditId',
type: 'string',
displayOptions: {
show: {
resource: ['finding'],
operation: ['unlinkAudit'],
},
},
default: '',
description: 'The ID of the audit to unlink',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const findingId = this.getNodeParameter('findingId', itemIndex) as string;
const auditId = this.getNodeParameter('auditId', itemIndex) as string;
const query = `
mutation DeleteFindingAuditMapping($input: DeleteFindingAuditMappingInput!) {
deleteFindingAuditMapping(input: $input) {
finding {
id
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { findingId, auditId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,235 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Finding ID',
name: 'findingId',
type: 'string',
displayOptions: {
show: {
resource: ['finding'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the finding to update',
required: true,
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['finding'],
operation: ['update'],
},
},
options: [
{
displayName: 'Corrective Action',
name: 'correctiveAction',
type: 'string',
default: '',
description: 'The corrective action for the finding',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
default: '',
description: 'The description of the finding',
},
{
displayName: 'Due Date',
name: 'dueDate',
type: 'string',
default: '',
description: 'The due date for the finding (ISO 8601 format)',
},
{
displayName: 'Effectiveness Check',
name: 'effectivenessCheck',
type: 'string',
default: '',
description: 'The effectiveness check for the finding',
},
{
displayName: 'Identified On',
name: 'identifiedOn',
type: 'string',
default: '',
description: 'The date the finding was identified (ISO 8601 format)',
},
{
displayName: 'Owner ID',
name: 'ownerId',
type: 'string',
default: '',
description: 'The ID of the person who owns this finding',
},
{
displayName: 'Priority',
name: 'priority',
type: 'options',
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'Low',
value: 'LOW',
},
{
name: 'Medium',
value: 'MEDIUM',
},
{
name: 'High',
value: 'HIGH',
},
],
default: '',
description: 'The priority of the finding',
},
{
displayName: 'Risk ID',
name: 'riskId',
type: 'string',
default: '',
description: 'The ID of the associated risk',
},
{
displayName: 'Root Cause',
name: 'rootCause',
type: 'string',
default: '',
description: 'The root cause of the finding',
},
{
displayName: 'Source',
name: 'source',
type: 'string',
default: '',
description: 'The source of the finding',
},
{
displayName: 'Status',
name: 'status',
type: 'options',
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'Closed',
value: 'CLOSED',
},
{
name: 'False Positive',
value: 'FALSE_POSITIVE',
},
{
name: 'In Progress',
value: 'IN_PROGRESS',
},
{
name: 'Mitigated',
value: 'MITIGATED',
},
{
name: 'Open',
value: 'OPEN',
},
{
name: 'Risk Accepted',
value: 'RISK_ACCEPTED',
},
],
default: '',
description: 'The status of the finding',
},
],
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const findingId = this.getNodeParameter('findingId', itemIndex) as string;
const additionalFields = this.getNodeParameter('additionalFields', itemIndex, {}) as {
description?: string;
source?: string;
identifiedOn?: string;
rootCause?: string;
correctiveAction?: string;
ownerId?: string;
dueDate?: string;
status?: string;
priority?: string;
riskId?: string;
effectivenessCheck?: string;
};
const query = `
mutation UpdateFinding($input: UpdateFindingInput!) {
updateFinding(input: $input) {
finding {
id
kind
description
source
identifiedOn
rootCause
correctiveAction
dueDate
status
priority
effectivenessCheck
createdAt
updatedAt
}
}
}
`;
const input: Record<string, unknown> = { id: findingId };
if (additionalFields.description !== undefined) input.description = additionalFields.description === '' ? null : additionalFields.description;
if (additionalFields.source !== undefined) input.source = additionalFields.source === '' ? null : additionalFields.source;
if (additionalFields.identifiedOn !== undefined) input.identifiedOn = additionalFields.identifiedOn === '' ? null : additionalFields.identifiedOn;
if (additionalFields.rootCause !== undefined) input.rootCause = additionalFields.rootCause === '' ? null : additionalFields.rootCause;
if (additionalFields.correctiveAction !== undefined) input.correctiveAction = additionalFields.correctiveAction === '' ? null : additionalFields.correctiveAction;
if (additionalFields.ownerId !== undefined) input.ownerId = additionalFields.ownerId === '' ? null : additionalFields.ownerId;
if (additionalFields.dueDate !== undefined) input.dueDate = additionalFields.dueDate === '' ? null : additionalFields.dueDate;
if (additionalFields.status !== undefined) input.status = additionalFields.status;
if (additionalFields.priority !== undefined) input.priority = additionalFields.priority;
if (additionalFields.riskId !== undefined) input.riskId = additionalFields.riskId === '' ? null : additionalFields.riskId;
if (additionalFields.effectivenessCheck !== undefined) input.effectivenessCheck = additionalFields.effectivenessCheck === '' ? null : additionalFields.effectivenessCheck;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -13,18 +13,31 @@
// PERFORMANCE OF THIS SOFTWARE.
import type { IExecuteFunctions, INodeExecutionData, INodeProperties } from 'n8n-workflow';
import * as accessReview from './accessReview';
import * as asset from './asset';
import * as audit from './audit';
import * as auditLog from './auditLog';
import * as control from './control';
import * as datum from './datum';
import * as document from './document';
import * as dpia from './dpia';
import * as evidence from './evidence';
import * as execute from './execute';
import * as finding from './finding';
import * as framework from './framework';
import * as measure from './measure';
import * as obligation from './obligation';
import * as organization from './organization';
import * as organizationContext from './organizationContext';
import * as processingActivity from './processingActivity';
import * as rightsRequest from './rightsRequest';
import * as user from './user';
import * as risk from './risk';
import * as snapshot from './snapshot';
import * as statementOfApplicability from './statementOfApplicability';
import * as task from './task';
import * as tia from './tia';
import * as trustCenter from './trustCenter';
import * as vendor from './vendor';
import * as webhook from './webhook';
@@ -39,18 +52,31 @@ export interface OperationModule {
}
export const resources: Record<string, ResourceModule> = {
accessReview: accessReview as ResourceModule,
asset: asset as ResourceModule,
audit: audit as ResourceModule,
auditLog: auditLog as ResourceModule,
control: control as ResourceModule,
datum: datum as ResourceModule,
document: document as ResourceModule,
dpia: dpia as ResourceModule,
evidence: evidence as ResourceModule,
execute: execute as ResourceModule,
finding: finding as ResourceModule,
framework: framework as ResourceModule,
measure: measure as ResourceModule,
obligation: obligation as ResourceModule,
organization: organization as ResourceModule,
organizationContext: organizationContext as ResourceModule,
processingActivity: processingActivity as ResourceModule,
rightsRequest: rightsRequest as ResourceModule,
user: user as ResourceModule,
risk: risk as ResourceModule,
snapshot: snapshot as ResourceModule,
statementOfApplicability: statementOfApplicability as ResourceModule,
task: task as ResourceModule,
tia: tia as ResourceModule,
trustCenter: trustCenter as ResourceModule,
vendor: vendor as ResourceModule,
webhook: webhook as ResourceModule,
};

View File

@@ -18,6 +18,8 @@ import * as updateOp from './update.operation';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
import * as linkDocumentOp from './linkDocument.operation';
import * as unlinkDocumentOp from './unlinkDocument.operation';
export const description: INodeProperties[] = [
{
@@ -55,6 +57,18 @@ export const description: INodeProperties[] = [
description: 'Get many measures',
action: 'Get many measures',
},
{
name: 'Link Document',
value: 'linkDocument',
description: 'Link a document to a measure',
action: 'Link a document to a measure',
},
{
name: 'Unlink Document',
value: 'unlinkDocument',
description: 'Unlink a document from a measure',
action: 'Unlink a document from a measure',
},
{
name: 'Update',
value: 'update',
@@ -69,6 +83,16 @@ export const description: INodeProperties[] = [
...deleteOp.description,
...getOp.description,
...getAllOp.description,
...linkDocumentOp.description,
...unlinkDocumentOp.description,
];
export { createOp as create, updateOp as update, deleteOp as delete, getOp as get, getAllOp as getAll };
export {
createOp as create,
updateOp as update,
deleteOp as delete,
getOp as get,
getAllOp as getAll,
linkDocumentOp as linkDocument,
unlinkDocumentOp as unlinkDocument,
};

View File

@@ -0,0 +1,81 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Measure ID',
name: 'measureId',
type: 'string',
displayOptions: {
show: {
resource: ['measure'],
operation: ['linkDocument'],
},
},
default: '',
description: 'The ID of the measure',
required: true,
},
{
displayName: 'Document ID',
name: 'documentId',
type: 'string',
displayOptions: {
show: {
resource: ['measure'],
operation: ['linkDocument'],
},
},
default: '',
description: 'The ID of the document to link',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const measureId = this.getNodeParameter('measureId', itemIndex) as string;
const documentId = this.getNodeParameter('documentId', itemIndex) as string;
const query = `
mutation CreateMeasureDocumentMapping($input: CreateMeasureDocumentMappingInput!) {
createMeasureDocumentMapping(input: $input) {
measureEdge {
node {
id
name
}
}
documentEdge {
node {
id
title
}
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { measureId, documentId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,71 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Measure ID',
name: 'measureId',
type: 'string',
displayOptions: {
show: {
resource: ['measure'],
operation: ['unlinkDocument'],
},
},
default: '',
description: 'The ID of the measure',
required: true,
},
{
displayName: 'Document ID',
name: 'documentId',
type: 'string',
displayOptions: {
show: {
resource: ['measure'],
operation: ['unlinkDocument'],
},
},
default: '',
description: 'The ID of the document to unlink',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const measureId = this.getNodeParameter('measureId', itemIndex) as string;
const documentId = this.getNodeParameter('documentId', itemIndex) as string;
const query = `
mutation DeleteMeasureDocumentMapping($input: DeleteMeasureDocumentMappingInput!) {
deleteMeasureDocumentMapping(input: $input) {
deletedMeasureId
deletedDocumentId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { measureId, documentId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,253 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Area',
name: 'area',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['create'],
},
},
default: '',
description: 'The area of the obligation',
required: true,
},
{
displayName: 'Source',
name: 'source',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['create'],
},
},
default: '',
description: 'The source of the obligation',
required: true,
},
{
displayName: 'Requirement',
name: 'requirement',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['create'],
},
},
default: '',
description: 'The requirement of the obligation',
required: true,
},
{
displayName: 'Actions to Be Implemented',
name: 'actionsToBeImplemented',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['create'],
},
},
default: '',
description: 'The actions to be implemented for the obligation',
},
{
displayName: 'Regulator',
name: 'regulator',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['create'],
},
},
default: '',
description: 'The regulator of the obligation',
},
{
displayName: 'Owner ID',
name: 'ownerId',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the owner',
},
{
displayName: 'Last Review Date',
name: 'lastReviewDate',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['create'],
},
},
default: '',
description: 'The last review date of the obligation',
},
{
displayName: 'Due Date',
name: 'dueDate',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['create'],
},
},
default: '',
description: 'The due date of the obligation',
},
{
displayName: 'Status',
name: 'status',
type: 'options',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['create'],
},
},
options: [
{
name: 'Non Compliant',
value: 'NON_COMPLIANT',
},
{
name: 'Partially Compliant',
value: 'PARTIALLY_COMPLIANT',
},
{
name: 'Compliant',
value: 'COMPLIANT',
},
],
default: 'NON_COMPLIANT',
description: 'The status of the obligation',
},
{
displayName: 'Type',
name: 'type',
type: 'options',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['create'],
},
},
options: [
{
name: 'Legal',
value: 'LEGAL',
},
{
name: 'Contractual',
value: 'CONTRACTUAL',
},
],
default: 'LEGAL',
description: 'The type of the obligation',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
const area = this.getNodeParameter('area', itemIndex) as string;
const source = this.getNodeParameter('source', itemIndex) as string;
const requirement = this.getNodeParameter('requirement', itemIndex) as string;
const actionsToBeImplemented = this.getNodeParameter('actionsToBeImplemented', itemIndex, '') as string;
const regulator = this.getNodeParameter('regulator', itemIndex, '') as string;
const ownerId = this.getNodeParameter('ownerId', itemIndex, '') as string;
const lastReviewDate = this.getNodeParameter('lastReviewDate', itemIndex, '') as string;
const dueDate = this.getNodeParameter('dueDate', itemIndex, '') as string;
const status = this.getNodeParameter('status', itemIndex, '') as string;
const type = this.getNodeParameter('type', itemIndex, '') as string;
const query = `
mutation CreateObligation($input: CreateObligationInput!) {
createObligation(input: $input) {
obligationEdge {
node {
id
area
source
requirement
actionsToBeImplemented
regulator
lastReviewDate
dueDate
status
type
createdAt
updatedAt
}
}
}
}
`;
const variables = {
input: {
organizationId,
area,
source,
requirement,
...(actionsToBeImplemented && { actionsToBeImplemented }),
...(regulator && { regulator }),
...(ownerId && { ownerId }),
...(lastReviewDate && { lastReviewDate }),
...(dueDate && { dueDate }),
...(status && { status }),
...(type && { type }),
},
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Obligation ID',
name: 'obligationId',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['delete'],
},
},
default: '',
description: 'The ID of the obligation to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const obligationId = this.getNodeParameter('obligationId', itemIndex) as string;
const query = `
mutation DeleteObligation($input: DeleteObligationInput!) {
deleteObligation(input: $input) {
deletedObligationId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { obligationId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,72 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Obligation ID',
name: 'obligationId',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the obligation',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const obligationId = this.getNodeParameter('obligationId', itemIndex) as string;
const query = `
query GetObligation($obligationId: ID!) {
node(id: $obligationId) {
... on Obligation {
id
area
source
requirement
actionsToBeImplemented
regulator
lastReviewDate
dueDate
status
type
createdAt
updatedAt
}
}
}
`;
const variables = {
obligationId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,121 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['obligation'],
operation: ['getAll'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['getAll'],
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 GetObligations($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
obligations(first: $first, after: $after) {
edges {
node {
id
area
source
requirement
actionsToBeImplemented
regulator
lastReviewDate
dueDate
status
type
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const obligations = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.obligations as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { obligations },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,74 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as createOp from './create.operation';
import * as updateOp from './update.operation';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['obligation'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new obligation',
action: 'Create an obligation',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete an obligation',
action: 'Delete an obligation',
},
{
name: 'Get',
value: 'get',
description: 'Get an obligation',
action: 'Get an obligation',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many obligations',
action: 'Get many obligations',
},
{
name: 'Update',
value: 'update',
description: 'Update an existing obligation',
action: 'Update an obligation',
},
],
default: 'create',
},
...createOp.description,
...updateOp.description,
...deleteOp.description,
...getOp.description,
...getAllOp.description,
];
export { createOp as create, updateOp as update, deleteOp as delete, getOp as get, getAllOp as getAll };

View File

@@ -0,0 +1,252 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Obligation ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the obligation to update',
required: true,
},
{
displayName: 'Area',
name: 'area',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['update'],
},
},
default: '',
description: 'The area of the obligation',
},
{
displayName: 'Source',
name: 'source',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['update'],
},
},
default: '',
description: 'The source of the obligation',
},
{
displayName: 'Requirement',
name: 'requirement',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['update'],
},
},
default: '',
description: 'The requirement of the obligation',
},
{
displayName: 'Actions to Be Implemented',
name: 'actionsToBeImplemented',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['update'],
},
},
default: '',
description: 'The actions to be implemented for the obligation',
},
{
displayName: 'Regulator',
name: 'regulator',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['update'],
},
},
default: '',
description: 'The regulator of the obligation',
},
{
displayName: 'Owner ID',
name: 'ownerId',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the owner',
},
{
displayName: 'Last Review Date',
name: 'lastReviewDate',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['update'],
},
},
default: '',
description: 'The last review date of the obligation',
},
{
displayName: 'Due Date',
name: 'dueDate',
type: 'string',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['update'],
},
},
default: '',
description: 'The due date of the obligation',
},
{
displayName: 'Status',
name: 'status',
type: 'options',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['update'],
},
},
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'Non Compliant',
value: 'NON_COMPLIANT',
},
{
name: 'Partially Compliant',
value: 'PARTIALLY_COMPLIANT',
},
{
name: 'Compliant',
value: 'COMPLIANT',
},
],
default: '',
description: 'The status of the obligation',
},
{
displayName: 'Type',
name: 'type',
type: 'options',
displayOptions: {
show: {
resource: ['obligation'],
operation: ['update'],
},
},
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'Legal',
value: 'LEGAL',
},
{
name: 'Contractual',
value: 'CONTRACTUAL',
},
],
default: '',
description: 'The type of the obligation',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const id = this.getNodeParameter('id', itemIndex) as string;
const area = this.getNodeParameter('area', itemIndex, '') as string;
const source = this.getNodeParameter('source', itemIndex, '') as string;
const requirement = this.getNodeParameter('requirement', itemIndex, '') as string;
const actionsToBeImplemented = this.getNodeParameter('actionsToBeImplemented', itemIndex, '') as string;
const regulator = this.getNodeParameter('regulator', itemIndex, '') as string;
const ownerId = this.getNodeParameter('ownerId', itemIndex, '') as string;
const lastReviewDate = this.getNodeParameter('lastReviewDate', itemIndex, '') as string;
const dueDate = this.getNodeParameter('dueDate', itemIndex, '') as string;
const status = this.getNodeParameter('status', itemIndex, '') as string;
const type = this.getNodeParameter('type', itemIndex, '') as string;
const query = `
mutation UpdateObligation($input: UpdateObligationInput!) {
updateObligation(input: $input) {
obligation {
id
area
source
requirement
actionsToBeImplemented
regulator
lastReviewDate
dueDate
status
type
createdAt
updatedAt
}
}
}
`;
const input: Record<string, string> = { id };
if (area) input.area = area;
if (source) input.source = source;
if (requirement) input.requirement = requirement;
if (actionsToBeImplemented) input.actionsToBeImplemented = actionsToBeImplemented;
if (regulator) input.regulator = regulator;
if (ownerId) input.ownerId = ownerId;
if (lastReviewDate) input.lastReviewDate = lastReviewDate;
if (dueDate) input.dueDate = dueDate;
if (status) input.status = status;
if (type) input.type = type;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,68 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'string',
displayOptions: {
show: {
resource: ['organizationContext'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
const query = `
query GetOrganizationContext($organizationId: ID!) {
node(id: $organizationId) {
... on Organization {
context {
organizationId
product
architecture
team
processes
customers
}
}
}
}
`;
const variables = {
organizationId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,50 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as getOp from './get.operation';
import * as updateOp from './update.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['organizationContext'],
},
},
options: [
{
name: 'Get',
value: 'get',
description: 'Get the organization context',
action: 'Get the organization context',
},
{
name: 'Update',
value: 'update',
description: 'Update the organization context',
action: 'Update the organization context',
},
],
default: 'get',
},
...getOp.description,
...updateOp.description,
];
export { getOp as get, updateOp as update };

View File

@@ -0,0 +1,139 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'string',
displayOptions: {
show: {
resource: ['organizationContext'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Product',
name: 'product',
type: 'string',
displayOptions: {
show: {
resource: ['organizationContext'],
operation: ['update'],
},
},
default: '',
description: 'The product description of the organization',
},
{
displayName: 'Architecture',
name: 'architecture',
type: 'string',
displayOptions: {
show: {
resource: ['organizationContext'],
operation: ['update'],
},
},
default: '',
description: 'The architecture description of the organization',
},
{
displayName: 'Team',
name: 'team',
type: 'string',
displayOptions: {
show: {
resource: ['organizationContext'],
operation: ['update'],
},
},
default: '',
description: 'The team description of the organization',
},
{
displayName: 'Processes',
name: 'processes',
type: 'string',
displayOptions: {
show: {
resource: ['organizationContext'],
operation: ['update'],
},
},
default: '',
description: 'The processes description of the organization',
},
{
displayName: 'Customers',
name: 'customers',
type: 'string',
displayOptions: {
show: {
resource: ['organizationContext'],
operation: ['update'],
},
},
default: '',
description: 'The customers description of the organization',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
const product = this.getNodeParameter('product', itemIndex, '') as string;
const architecture = this.getNodeParameter('architecture', itemIndex, '') as string;
const team = this.getNodeParameter('team', itemIndex, '') as string;
const processes = this.getNodeParameter('processes', itemIndex, '') as string;
const customers = this.getNodeParameter('customers', itemIndex, '') as string;
const query = `
mutation UpdateOrganizationContext($input: UpdateOrganizationContextInput!) {
updateOrganizationContext(input: $input) {
context {
organizationId
product
architecture
team
processes
customers
}
}
}
`;
const input: Record<string, string> = { organizationId };
if (product) input.product = product;
if (architecture) input.architecture = architecture;
if (team) input.team = team;
if (processes) input.processes = processes;
if (customers) input.customers = customers;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,171 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'string',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['create'],
},
},
default: '',
description: 'The name of the processing activity',
required: true,
},
{
displayName: 'Purpose',
name: 'purpose',
type: 'string',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['create'],
},
},
default: '',
description: 'The purpose of the processing activity',
required: true,
},
{
displayName: 'Role',
name: 'role',
type: 'options',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['create'],
},
},
options: [
{
name: 'Controller',
value: 'CONTROLLER',
},
{
name: 'Processor',
value: 'PROCESSOR',
},
],
default: 'CONTROLLER',
description: 'The role for the processing activity',
required: true,
},
{
displayName: 'Lawful Basis',
name: 'lawfulBasis',
type: 'options',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['create'],
},
},
options: [
{
name: 'Consent',
value: 'CONSENT',
},
{
name: 'Contractual Necessity',
value: 'CONTRACTUAL_NECESSITY',
},
{
name: 'Legal Obligation',
value: 'LEGAL_OBLIGATION',
},
{
name: 'Legitimate Interest',
value: 'LEGITIMATE_INTEREST',
},
{
name: 'Public Task',
value: 'PUBLIC_TASK',
},
{
name: 'Vital Interests',
value: 'VITAL_INTERESTS',
},
],
default: 'LEGITIMATE_INTEREST',
description: 'The lawful basis for the processing activity',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
const name = this.getNodeParameter('name', itemIndex) as string;
const purpose = this.getNodeParameter('purpose', itemIndex) as string;
const role = this.getNodeParameter('role', itemIndex) as string;
const lawfulBasis = this.getNodeParameter('lawfulBasis', itemIndex) as string;
const query = `
mutation CreateProcessingActivity($input: CreateProcessingActivityInput!) {
createProcessingActivity(input: $input) {
processingActivityEdge {
node {
id
name
purpose
role
lawfulBasis
createdAt
updatedAt
}
}
}
}
`;
const variables = {
input: {
organizationId,
name,
purpose,
role,
lawfulBasis,
},
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Processing Activity ID',
name: 'processingActivityId',
type: 'string',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['delete'],
},
},
default: '',
description: 'The ID of the processing activity to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const processingActivityId = this.getNodeParameter('processingActivityId', itemIndex) as string;
const query = `
mutation DeleteProcessingActivity($input: DeleteProcessingActivityInput!) {
deleteProcessingActivity(input: $input) {
deletedProcessingActivityId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { processingActivityId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,67 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Processing Activity ID',
name: 'processingActivityId',
type: 'string',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the processing activity',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const processingActivityId = this.getNodeParameter('processingActivityId', itemIndex) as string;
const query = `
query GetProcessingActivity($processingActivityId: ID!) {
node(id: $processingActivityId) {
... on ProcessingActivity {
id
name
purpose
role
lawfulBasis
createdAt
updatedAt
}
}
}
`;
const variables = {
processingActivityId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,116 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['processingActivity'],
operation: ['getAll'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['getAll'],
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 GetProcessingActivities($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
processingActivities(first: $first, after: $after) {
edges {
node {
id
name
purpose
role
lawfulBasis
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const processingActivities = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.processingActivities as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { processingActivities },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,74 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as createOp from './create.operation';
import * as updateOp from './update.operation';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['processingActivity'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new processing activity',
action: 'Create a processing activity',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a processing activity',
action: 'Delete a processing activity',
},
{
name: 'Get',
value: 'get',
description: 'Get a processing activity',
action: 'Get a processing activity',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many processing activities',
action: 'Get many processing activities',
},
{
name: 'Update',
value: 'update',
description: 'Update an existing processing activity',
action: 'Update a processing activity',
},
],
default: 'create',
},
...createOp.description,
...updateOp.description,
...deleteOp.description,
...getOp.description,
...getAllOp.description,
];
export { createOp as create, updateOp as update, deleteOp as delete, getOp as get, getAllOp as getAll };

View File

@@ -0,0 +1,169 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Processing Activity ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the processing activity to update',
required: true,
},
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['update'],
},
},
default: '',
description: 'The name of the processing activity',
},
{
displayName: 'Purpose',
name: 'purpose',
type: 'string',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['update'],
},
},
default: '',
description: 'The purpose of the processing activity',
},
{
displayName: 'Role',
name: 'role',
type: 'options',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['update'],
},
},
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'Controller',
value: 'CONTROLLER',
},
{
name: 'Processor',
value: 'PROCESSOR',
},
],
default: '',
description: 'The role for the processing activity',
},
{
displayName: 'Lawful Basis',
name: 'lawfulBasis',
type: 'options',
displayOptions: {
show: {
resource: ['processingActivity'],
operation: ['update'],
},
},
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'Consent',
value: 'CONSENT',
},
{
name: 'Contractual Necessity',
value: 'CONTRACTUAL_NECESSITY',
},
{
name: 'Legal Obligation',
value: 'LEGAL_OBLIGATION',
},
{
name: 'Legitimate Interest',
value: 'LEGITIMATE_INTEREST',
},
{
name: 'Public Task',
value: 'PUBLIC_TASK',
},
{
name: 'Vital Interests',
value: 'VITAL_INTERESTS',
},
],
default: '',
description: 'The lawful basis for the processing activity',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const id = this.getNodeParameter('id', itemIndex) as string;
const name = this.getNodeParameter('name', itemIndex, '') as string;
const purpose = this.getNodeParameter('purpose', itemIndex, '') as string;
const role = this.getNodeParameter('role', itemIndex, '') as string;
const lawfulBasis = this.getNodeParameter('lawfulBasis', itemIndex, '') as string;
const query = `
mutation UpdateProcessingActivity($input: UpdateProcessingActivityInput!) {
updateProcessingActivity(input: $input) {
processingActivity {
id
name
purpose
role
lawfulBasis
createdAt
updatedAt
}
}
}
`;
const input: Record<string, string> = { id };
if (name) input.name = name;
if (purpose) input.purpose = purpose;
if (role) input.role = role;
if (lawfulBasis) input.lawfulBasis = lawfulBasis;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,210 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Request Type',
name: 'requestType',
type: 'options',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['create'],
},
},
options: [
{
name: 'Access',
value: 'ACCESS',
},
{
name: 'Deletion',
value: 'DELETION',
},
{
name: 'Portability',
value: 'PORTABILITY',
},
],
default: 'ACCESS',
description: 'The type of rights request',
required: true,
},
{
displayName: 'Request State',
name: 'requestState',
type: 'options',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['create'],
},
},
options: [
{
name: 'To Do',
value: 'TODO',
},
{
name: 'In Progress',
value: 'IN_PROGRESS',
},
{
name: 'Done',
value: 'DONE',
},
],
default: 'TODO',
description: 'The state of the rights request',
required: true,
},
{
displayName: 'Data Subject',
name: 'dataSubject',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['create'],
},
},
default: '',
description: 'The data subject of the rights request',
required: true,
},
{
displayName: 'Contact',
name: 'contact',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['create'],
},
},
default: '',
description: 'The contact for the rights request',
},
{
displayName: 'Details',
name: 'details',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['create'],
},
},
default: '',
description: 'The details of the rights request',
},
{
displayName: 'Deadline',
name: 'deadline',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['create'],
},
},
default: '',
description: 'The deadline for the rights request',
},
{
displayName: 'Action Taken',
name: 'actionTaken',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['create'],
},
},
default: '',
description: 'The action taken for the rights request',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
const requestType = this.getNodeParameter('requestType', itemIndex) as string;
const requestState = this.getNodeParameter('requestState', itemIndex) as string;
const dataSubject = this.getNodeParameter('dataSubject', itemIndex) as string;
const contact = this.getNodeParameter('contact', itemIndex, '') as string;
const details = this.getNodeParameter('details', itemIndex, '') as string;
const deadline = this.getNodeParameter('deadline', itemIndex, '') as string;
const actionTaken = this.getNodeParameter('actionTaken', itemIndex, '') as string;
const query = `
mutation CreateRightsRequest($input: CreateRightsRequestInput!) {
createRightsRequest(input: $input) {
rightsRequestEdge {
node {
id
requestType
requestState
dataSubject
contact
details
deadline
actionTaken
createdAt
updatedAt
}
}
}
}
`;
const variables = {
input: {
organizationId,
requestType,
requestState,
dataSubject,
...(contact && { contact }),
...(details && { details }),
...(deadline && { deadline }),
...(actionTaken && { actionTaken }),
},
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Rights Request ID',
name: 'rightsRequestId',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['delete'],
},
},
default: '',
description: 'The ID of the rights request to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const rightsRequestId = this.getNodeParameter('rightsRequestId', itemIndex) as string;
const query = `
mutation DeleteRightsRequest($input: DeleteRightsRequestInput!) {
deleteRightsRequest(input: $input) {
deletedRightsRequestId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { rightsRequestId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,70 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Rights Request ID',
name: 'rightsRequestId',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the rights request',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const rightsRequestId = this.getNodeParameter('rightsRequestId', itemIndex) as string;
const query = `
query GetRightsRequest($rightsRequestId: ID!) {
node(id: $rightsRequestId) {
... on RightsRequest {
id
requestType
requestState
dataSubject
contact
details
deadline
actionTaken
createdAt
updatedAt
}
}
}
`;
const variables = {
rightsRequestId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,119 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['rightsRequest'],
operation: ['getAll'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['getAll'],
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 GetRightsRequests($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
rightsRequests(first: $first, after: $after) {
edges {
node {
id
requestType
requestState
dataSubject
contact
details
deadline
actionTaken
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const rightsRequests = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.rightsRequests as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { rightsRequests },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,74 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as createOp from './create.operation';
import * as updateOp from './update.operation';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['rightsRequest'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new rights request',
action: 'Create a rights request',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a rights request',
action: 'Delete a rights request',
},
{
name: 'Get',
value: 'get',
description: 'Get a rights request',
action: 'Get a rights request',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many rights requests',
action: 'Get many rights requests',
},
{
name: 'Update',
value: 'update',
description: 'Update an existing rights request',
action: 'Update a rights request',
},
],
default: 'create',
},
...createOp.description,
...updateOp.description,
...deleteOp.description,
...getOp.description,
...getAllOp.description,
];
export { createOp as create, updateOp as update, deleteOp as delete, getOp as get, getAllOp as getAll };

View File

@@ -0,0 +1,209 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Rights Request ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the rights request to update',
required: true,
},
{
displayName: 'Request Type',
name: 'requestType',
type: 'options',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['update'],
},
},
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'Access',
value: 'ACCESS',
},
{
name: 'Deletion',
value: 'DELETION',
},
{
name: 'Portability',
value: 'PORTABILITY',
},
],
default: '',
description: 'The type of rights request',
},
{
displayName: 'Request State',
name: 'requestState',
type: 'options',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['update'],
},
},
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'To Do',
value: 'TODO',
},
{
name: 'In Progress',
value: 'IN_PROGRESS',
},
{
name: 'Done',
value: 'DONE',
},
],
default: '',
description: 'The state of the rights request',
},
{
displayName: 'Data Subject',
name: 'dataSubject',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['update'],
},
},
default: '',
description: 'The data subject of the rights request',
},
{
displayName: 'Contact',
name: 'contact',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['update'],
},
},
default: '',
description: 'The contact for the rights request',
},
{
displayName: 'Details',
name: 'details',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['update'],
},
},
default: '',
description: 'The details of the rights request',
},
{
displayName: 'Deadline',
name: 'deadline',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['update'],
},
},
default: '',
description: 'The deadline for the rights request',
},
{
displayName: 'Action Taken',
name: 'actionTaken',
type: 'string',
displayOptions: {
show: {
resource: ['rightsRequest'],
operation: ['update'],
},
},
default: '',
description: 'The action taken for the rights request',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const id = this.getNodeParameter('id', itemIndex) as string;
const requestType = this.getNodeParameter('requestType', itemIndex, '') as string;
const requestState = this.getNodeParameter('requestState', itemIndex, '') as string;
const dataSubject = this.getNodeParameter('dataSubject', itemIndex, '') as string;
const contact = this.getNodeParameter('contact', itemIndex, '') as string;
const details = this.getNodeParameter('details', itemIndex, '') as string;
const deadline = this.getNodeParameter('deadline', itemIndex, '') as string;
const actionTaken = this.getNodeParameter('actionTaken', itemIndex, '') as string;
const query = `
mutation UpdateRightsRequest($input: UpdateRightsRequestInput!) {
updateRightsRequest(input: $input) {
rightsRequest {
id
requestType
requestState
dataSubject
contact
details
deadline
actionTaken
createdAt
updatedAt
}
}
}
`;
const input: Record<string, string> = { id };
if (requestType) input.requestType = requestType;
if (requestState) input.requestState = requestState;
if (dataSubject) input.dataSubject = dataSubject;
if (contact) input.contact = contact;
if (details) input.details = details;
if (deadline) input.deadline = deadline;
if (actionTaken) input.actionTaken = actionTaken;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -67,10 +67,7 @@ export const description: INodeProperties[] = [
},
},
options: [
{
name: 'Mitigated',
value: 'MITIGATED',
},
{ name: '(Unchanged)', value: '' },
{
name: 'Accepted',
value: 'ACCEPTED',
@@ -79,12 +76,16 @@ export const description: INodeProperties[] = [
name: 'Avoided',
value: 'AVOIDED',
},
{
name: 'Mitigated',
value: 'MITIGATED',
},
{
name: 'Transferred',
value: 'TRANSFERRED',
},
],
default: 'MITIGATED',
default: '',
description: 'The treatment strategy for the risk',
},
{

View File

@@ -0,0 +1,146 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'string',
displayOptions: {
show: {
resource: ['snapshot'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
resource: ['snapshot'],
operation: ['create'],
},
},
default: '',
description: 'The name of the snapshot',
required: true,
},
{
displayName: 'Description',
name: 'description',
type: 'string',
displayOptions: {
show: {
resource: ['snapshot'],
operation: ['create'],
},
},
default: '',
description: 'The description of the snapshot',
},
{
displayName: 'Type',
name: 'type',
type: 'options',
displayOptions: {
show: {
resource: ['snapshot'],
operation: ['create'],
},
},
options: [
{
name: 'Assets',
value: 'ASSETS',
},
{
name: 'Findings',
value: 'FINDINGS',
},
{
name: 'Obligations',
value: 'OBLIGATIONS',
},
{
name: 'Processing Activities',
value: 'PROCESSING_ACTIVITIES',
},
{
name: 'Risks',
value: 'RISKS',
},
{
name: 'Statements of Applicability',
value: 'STATEMENTS_OF_APPLICABILITY',
},
{
name: 'Vendors',
value: 'VENDORS',
},
],
default: 'RISKS',
description: 'The type of snapshot',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
const name = this.getNodeParameter('name', itemIndex) as string;
const description = this.getNodeParameter('description', itemIndex, '') as string;
const type = this.getNodeParameter('type', itemIndex) as string;
const query = `
mutation CreateSnapshot($input: CreateSnapshotInput!) {
createSnapshot(input: $input) {
snapshotEdge {
node {
id
name
description
type
createdAt
}
}
}
}
`;
const variables = {
input: {
organizationId,
name,
...(description && { description }),
type,
},
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Snapshot ID',
name: 'snapshotId',
type: 'string',
displayOptions: {
show: {
resource: ['snapshot'],
operation: ['delete'],
},
},
default: '',
description: 'The ID of the snapshot to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const snapshotId = this.getNodeParameter('snapshotId', itemIndex) as string;
const query = `
mutation DeleteSnapshot($input: DeleteSnapshotInput!) {
deleteSnapshot(input: $input) {
deletedSnapshotId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { snapshotId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,65 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Snapshot ID',
name: 'snapshotId',
type: 'string',
displayOptions: {
show: {
resource: ['snapshot'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the snapshot',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const snapshotId = this.getNodeParameter('snapshotId', itemIndex) as string;
const query = `
query GetSnapshot($snapshotId: ID!) {
node(id: $snapshotId) {
... on Snapshot {
id
name
description
type
createdAt
}
}
}
`;
const variables = {
snapshotId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,114 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['snapshot'],
operation: ['getAll'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['snapshot'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['snapshot'],
operation: ['getAll'],
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 GetSnapshots($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
snapshots(first: $first, after: $after) {
edges {
node {
id
name
description
type
createdAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const snapshots = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.snapshots as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { snapshots },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,66 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as createOp from './create.operation';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['snapshot'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new snapshot',
action: 'Create a snapshot',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a snapshot',
action: 'Delete a snapshot',
},
{
name: 'Get',
value: 'get',
description: 'Get a snapshot',
action: 'Get a snapshot',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many snapshots',
action: 'Get many snapshots',
},
],
default: 'create',
},
...createOp.description,
...deleteOp.description,
...getOp.description,
...getAllOp.description,
];
export { createOp as create, deleteOp as delete, getOp as get, getAllOp as getAll };

View File

@@ -0,0 +1,198 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Measure ID',
name: 'measureId',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the measure this task belongs to',
required: true,
},
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['create'],
},
},
default: '',
description: 'The name of the task',
required: true,
},
{
displayName: 'Description',
name: 'description',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['create'],
},
},
default: '',
description: 'The description of the task',
},
{
displayName: 'Priority',
name: 'priority',
type: 'options',
displayOptions: {
show: {
resource: ['task'],
operation: ['create'],
},
},
options: [
{
name: 'Urgent',
value: 'URGENT',
},
{
name: 'High',
value: 'HIGH',
},
{
name: 'Medium',
value: 'MEDIUM',
},
{
name: 'Low',
value: 'LOW',
},
],
default: 'MEDIUM',
description: 'The priority of the task',
},
{
displayName: 'Time Estimate',
name: 'timeEstimate',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['create'],
},
},
default: '',
description: 'The time estimate for the task',
},
{
displayName: 'Assigned To ID',
name: 'assignedToId',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the user assigned to this task',
},
{
displayName: 'Deadline',
name: 'deadline',
type: 'dateTime',
displayOptions: {
show: {
resource: ['task'],
operation: ['create'],
},
},
default: '',
description: 'The deadline for the task',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
const measureId = this.getNodeParameter('measureId', itemIndex) as string;
const name = this.getNodeParameter('name', itemIndex) as string;
const description = this.getNodeParameter('description', itemIndex, '') as string;
const priority = this.getNodeParameter('priority', itemIndex, '') as string;
const timeEstimate = this.getNodeParameter('timeEstimate', itemIndex, '') as string;
const assignedToId = this.getNodeParameter('assignedToId', itemIndex, '') as string;
const deadline = this.getNodeParameter('deadline', itemIndex, '') as string;
const query = `
mutation CreateTask($input: CreateTaskInput!) {
createTask(input: $input) {
taskEdge {
node {
id
name
description
state
priority
timeEstimate
deadline
createdAt
updatedAt
}
}
}
}
`;
const variables = {
input: {
organizationId,
measureId,
name,
...(description && { description }),
...(priority && { priority }),
...(timeEstimate && { timeEstimate }),
...(assignedToId && { assignedToId }),
...(deadline && { deadline }),
},
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Task ID',
name: 'taskId',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['delete'],
},
},
default: '',
description: 'The ID of the task to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const taskId = this.getNodeParameter('taskId', itemIndex) as string;
const query = `
mutation DeleteTask($input: DeleteTaskInput!) {
deleteTask(input: $input) {
deletedTaskId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { taskId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,69 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Task ID',
name: 'taskId',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the task',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const taskId = this.getNodeParameter('taskId', itemIndex) as string;
const query = `
query GetTask($taskId: ID!) {
node(id: $taskId) {
... on Task {
id
name
description
state
priority
timeEstimate
deadline
createdAt
updatedAt
}
}
}
`;
const variables = {
taskId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,118 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['task'],
operation: ['getAll'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['task'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['task'],
operation: ['getAll'],
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 GetTasks($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
tasks(first: $first, after: $after) {
edges {
node {
id
name
description
state
priority
timeEstimate
deadline
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const tasks = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.tasks as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { tasks },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,74 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as createOp from './create.operation';
import * as updateOp from './update.operation';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['task'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new task',
action: 'Create a task',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a task',
action: 'Delete a task',
},
{
name: 'Get',
value: 'get',
description: 'Get a task',
action: 'Get a task',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many tasks',
action: 'Get many tasks',
},
{
name: 'Update',
value: 'update',
description: 'Update an existing task',
action: 'Update a task',
},
],
default: 'create',
},
...createOp.description,
...updateOp.description,
...deleteOp.description,
...getOp.description,
...getAllOp.description,
];
export { createOp as create, updateOp as update, deleteOp as delete, getOp as get, getAllOp as getAll };

View File

@@ -0,0 +1,242 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Task ID',
name: 'taskId',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the task to update',
required: true,
},
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['update'],
},
},
default: '',
description: 'The name of the task',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['update'],
},
},
default: '',
description: 'The description of the task',
},
{
displayName: 'State',
name: 'state',
type: 'options',
displayOptions: {
show: {
resource: ['task'],
operation: ['update'],
},
},
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'Todo',
value: 'TODO',
},
{
name: 'In Progress',
value: 'IN_PROGRESS',
},
{
name: 'Done',
value: 'DONE',
},
],
default: '',
description: 'The state of the task',
},
{
displayName: 'Priority',
name: 'priority',
type: 'options',
displayOptions: {
show: {
resource: ['task'],
operation: ['update'],
},
},
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'High',
value: 'HIGH',
},
{
name: 'Low',
value: 'LOW',
},
{
name: 'Medium',
value: 'MEDIUM',
},
{
name: 'Urgent',
value: 'URGENT',
},
],
default: '',
description: 'The priority of the task',
},
{
displayName: 'Rank',
name: 'rank',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['update'],
},
},
default: '',
description: 'The rank of the task for ordering',
},
{
displayName: 'Time Estimate',
name: 'timeEstimate',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['update'],
},
},
default: '',
description: 'The time estimate for the task',
},
{
displayName: 'Deadline',
name: 'deadline',
type: 'dateTime',
displayOptions: {
show: {
resource: ['task'],
operation: ['update'],
},
},
default: '',
description: 'The deadline for the task',
},
{
displayName: 'Assigned To ID',
name: 'assignedToId',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the user assigned to this task',
},
{
displayName: 'Measure ID',
name: 'measureId',
type: 'string',
displayOptions: {
show: {
resource: ['task'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the measure this task belongs to',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const taskId = this.getNodeParameter('taskId', itemIndex) as string;
const name = this.getNodeParameter('name', itemIndex, '') as string;
const description = this.getNodeParameter('description', itemIndex, '') as string;
const state = this.getNodeParameter('state', itemIndex, '') as string;
const priority = this.getNodeParameter('priority', itemIndex, '') as string;
const rank = this.getNodeParameter('rank', itemIndex, '') as string;
const timeEstimate = this.getNodeParameter('timeEstimate', itemIndex, '') as string;
const deadline = this.getNodeParameter('deadline', itemIndex, '') as string;
const assignedToId = this.getNodeParameter('assignedToId', itemIndex, '') as string;
const measureId = this.getNodeParameter('measureId', itemIndex, '') as string;
const query = `
mutation UpdateTask($input: UpdateTaskInput!) {
updateTask(input: $input) {
task {
id
name
description
state
priority
timeEstimate
deadline
createdAt
updatedAt
}
}
}
`;
const input: Record<string, string> = { taskId };
if (name) input.name = name;
if (description) input.description = description;
if (state) input.state = state;
if (priority) input.priority = priority;
if (rank) input.rank = rank;
if (timeEstimate) input.timeEstimate = timeEstimate;
if (deadline) input.deadline = deadline;
if (assignedToId) input.assignedToId = assignedToId;
if (measureId) input.measureId = measureId;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,152 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Processing Activity ID',
name: 'processingActivityId',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['create'],
},
},
default: '',
description: 'The ID of the processing activity',
required: true,
},
{
displayName: 'Data Subjects',
name: 'dataSubjects',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['create'],
},
},
default: '',
description: 'The data subjects involved in the transfer',
required: true,
},
{
displayName: 'Legal Mechanism',
name: 'legalMechanism',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['create'],
},
},
default: '',
description: 'The legal mechanism for the transfer',
required: true,
},
{
displayName: 'Transfer',
name: 'transfer',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['create'],
},
},
default: '',
description: 'The transfer details',
required: true,
},
{
displayName: 'Local Law Risk',
name: 'localLawRisk',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['create'],
},
},
default: '',
description: 'The local law risk assessment',
required: true,
},
{
displayName: 'Supplementary Measures',
name: 'supplementaryMeasures',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['create'],
},
},
default: '',
description: 'The supplementary measures for the transfer',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const processingActivityId = this.getNodeParameter('processingActivityId', itemIndex) as string;
const dataSubjects = this.getNodeParameter('dataSubjects', itemIndex) as string;
const legalMechanism = this.getNodeParameter('legalMechanism', itemIndex) as string;
const transfer = this.getNodeParameter('transfer', itemIndex) as string;
const localLawRisk = this.getNodeParameter('localLawRisk', itemIndex) as string;
const supplementaryMeasures = this.getNodeParameter('supplementaryMeasures', itemIndex) as string;
const query = `
mutation CreateTransferImpactAssessment($input: CreateTransferImpactAssessmentInput!) {
createTransferImpactAssessment(input: $input) {
transferImpactAssessmentEdge {
node {
id
dataSubjects
legalMechanism
transfer
localLawRisk
supplementaryMeasures
createdAt
updatedAt
}
}
}
}
`;
const variables = {
input: {
processingActivityId,
dataSubjects,
legalMechanism,
transfer,
localLawRisk,
supplementaryMeasures,
},
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'TIA ID',
name: 'transferImpactAssessmentId',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['delete'],
},
},
default: '',
description: 'The ID of the TIA to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const transferImpactAssessmentId = this.getNodeParameter('transferImpactAssessmentId', itemIndex) as string;
const query = `
mutation DeleteTransferImpactAssessment($input: DeleteTransferImpactAssessmentInput!) {
deleteTransferImpactAssessment(input: $input) {
deletedTransferImpactAssessmentId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { transferImpactAssessmentId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,68 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'TIA ID',
name: 'transferImpactAssessmentId',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the TIA',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const transferImpactAssessmentId = this.getNodeParameter('transferImpactAssessmentId', itemIndex) as string;
const query = `
query GetTransferImpactAssessment($transferImpactAssessmentId: ID!) {
node(id: $transferImpactAssessmentId) {
... on TransferImpactAssessment {
id
dataSubjects
legalMechanism
transfer
localLawRisk
supplementaryMeasures
createdAt
updatedAt
}
}
}
`;
const variables = {
transferImpactAssessmentId,
};
const responseData = await proboApiRequest.call(this, query, variables);
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,117 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['tia'],
operation: ['getAll'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['tia'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['tia'],
operation: ['getAll'],
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 GetTransferImpactAssessments($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
transferImpactAssessments(first: $first, after: $after) {
edges {
node {
id
dataSubjects
legalMechanism
transfer
localLawRisk
supplementaryMeasures
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const transferImpactAssessments = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.transferImpactAssessments as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { transferImpactAssessments },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,74 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as createOp from './create.operation';
import * as updateOp from './update.operation';
import * as deleteOp from './delete.operation';
import * as getOp from './get.operation';
import * as getAllOp from './getAll.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['tia'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new TIA',
action: 'Create a TIA',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a TIA',
action: 'Delete a TIA',
},
{
name: 'Get',
value: 'get',
description: 'Get a TIA',
action: 'Get a TIA',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many TIAs',
action: 'Get many tias',
},
{
name: 'Update',
value: 'update',
description: 'Update an existing TIA',
action: 'Update a TIA',
},
],
default: 'create',
},
...createOp.description,
...updateOp.description,
...deleteOp.description,
...getOp.description,
...getAllOp.description,
];
export { createOp as create, updateOp as update, deleteOp as delete, getOp as get, getAllOp as getAll };

View File

@@ -0,0 +1,141 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'TIA ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['update'],
},
},
default: '',
description: 'The ID of the TIA to update',
required: true,
},
{
displayName: 'Data Subjects',
name: 'dataSubjects',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['update'],
},
},
default: '',
description: 'The data subjects involved in the transfer',
},
{
displayName: 'Legal Mechanism',
name: 'legalMechanism',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['update'],
},
},
default: '',
description: 'The legal mechanism for the transfer',
},
{
displayName: 'Transfer',
name: 'transfer',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['update'],
},
},
default: '',
description: 'The transfer details',
},
{
displayName: 'Local Law Risk',
name: 'localLawRisk',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['update'],
},
},
default: '',
description: 'The local law risk assessment',
},
{
displayName: 'Supplementary Measures',
name: 'supplementaryMeasures',
type: 'string',
displayOptions: {
show: {
resource: ['tia'],
operation: ['update'],
},
},
default: '',
description: 'The supplementary measures for the transfer',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const id = this.getNodeParameter('id', itemIndex) as string;
const dataSubjects = this.getNodeParameter('dataSubjects', itemIndex, '') as string;
const legalMechanism = this.getNodeParameter('legalMechanism', itemIndex, '') as string;
const transfer = this.getNodeParameter('transfer', itemIndex, '') as string;
const localLawRisk = this.getNodeParameter('localLawRisk', itemIndex, '') as string;
const supplementaryMeasures = this.getNodeParameter('supplementaryMeasures', itemIndex, '') as string;
const query = `
mutation UpdateTransferImpactAssessment($input: UpdateTransferImpactAssessmentInput!) {
updateTransferImpactAssessment(input: $input) {
transferImpactAssessment {
id
dataSubjects
legalMechanism
transfer
localLawRisk
supplementaryMeasures
createdAt
updatedAt
}
}
}
`;
const input: Record<string, string> = { id };
if (dataSubjects) input.dataSubjects = dataSubjects;
if (legalMechanism) input.legalMechanism = legalMechanism;
if (transfer) input.transfer = transfer;
if (localLawRisk) input.localLawRisk = localLawRisk;
if (supplementaryMeasures) input.supplementaryMeasures = supplementaryMeasures;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,96 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['createExternalUrl'],
},
},
default: '',
description: 'The ID of the trust center',
required: true,
},
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createExternalUrl'],
},
},
default: '',
description: 'The name of the external URL',
required: true,
},
{
displayName: 'URL',
name: 'url',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createExternalUrl'],
},
},
default: '',
description: 'The external URL',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const trustCenterId = this.getNodeParameter('trustCenterId', itemIndex) as string;
const name = this.getNodeParameter('name', itemIndex) as string;
const url = this.getNodeParameter('url', itemIndex) as string;
const query = `
mutation CreateComplianceExternalURL($input: CreateComplianceExternalURLInput!) {
createComplianceExternalURL(input: $input) {
complianceExternalURLEdge {
node {
id
name
url
rank
createdAt
updatedAt
}
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, {
input: { trustCenterId, name, url },
});
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,115 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['createReference'],
},
},
default: '',
description: 'The ID of the trust center',
required: true,
},
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createReference'],
},
},
default: '',
description: 'The name of the reference',
required: true,
},
{
displayName: 'Description',
name: 'description',
type: 'string',
typeOptions: {
rows: 4,
},
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createReference'],
},
},
default: '',
description: 'The description of the reference',
},
{
displayName: 'Website URL',
name: 'websiteUrl',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['createReference'],
},
},
default: '',
description: 'The website URL of the reference',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const trustCenterId = this.getNodeParameter('trustCenterId', itemIndex) as string;
const name = this.getNodeParameter('name', itemIndex) as string;
const description = this.getNodeParameter('description', itemIndex, '') as string;
const websiteUrl = this.getNodeParameter('websiteUrl', itemIndex, '') as string;
const query = `
mutation CreateTrustCenterReference($input: CreateTrustCenterReferenceInput!) {
createTrustCenterReference(input: $input) {
trustCenterReferenceEdge {
node {
id
name
description
websiteUrl
rank
createdAt
updatedAt
}
}
}
}
`;
const input: Record<string, unknown> = { trustCenterId, name };
if (description) input.description = description;
if (websiteUrl) input.websiteUrl = websiteUrl;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Compliance External URL ID',
name: 'complianceExternalUrlId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['deleteExternalUrl'],
},
},
default: '',
description: 'The ID of the compliance external URL to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const complianceExternalUrlId = this.getNodeParameter('complianceExternalUrlId', itemIndex) as string;
const query = `
mutation DeleteComplianceExternalURL($input: DeleteComplianceExternalURLInput!) {
deleteComplianceExternalURL(input: $input) {
deletedComplianceExternalURLId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { id: complianceExternalUrlId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Trust Center File ID',
name: 'trustCenterFileId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['deleteFile'],
},
},
default: '',
description: 'The ID of the trust center file to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const trustCenterFileId = this.getNodeParameter('trustCenterFileId', itemIndex) as string;
const query = `
mutation DeleteTrustCenterFile($input: DeleteTrustCenterFileInput!) {
deleteTrustCenterFile(input: $input) {
deletedTrustCenterFileId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { id: trustCenterFileId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Trust Center Reference ID',
name: 'trustCenterReferenceId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['deleteReference'],
},
},
default: '',
description: 'The ID of the trust center reference to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const trustCenterReferenceId = this.getNodeParameter('trustCenterReferenceId', itemIndex) as string;
const query = `
mutation DeleteTrustCenterReference($input: DeleteTrustCenterReferenceInput!) {
deleteTrustCenterReference(input: $input) {
deletedTrustCenterReferenceId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { id: trustCenterReferenceId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,67 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'string',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['get'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
const query = `
query GetTrustCenter($organizationId: ID!) {
node(id: $organizationId) {
... on Organization {
trustCenter {
id
active
searchEngineIndexing
logoFileUrl
darkLogoFileUrl
ndaFileName
ndaFileUrl
createdAt
updatedAt
}
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { organizationId });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,115 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['getAllFiles'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['getAllFiles'],
},
},
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: ['getAllFiles'],
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 GetTrustCenterFiles($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
trustCenterFiles(first: $first, after: $after) {
edges {
node {
id
name
category
trustCenterVisibility
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const trustCenterFiles = await proboApiRequestAllItems.call(
this,
query,
{ organizationId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.trustCenterFiles as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { trustCenterFiles },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,119 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['getAllReferences'],
},
},
default: '',
description: 'The ID of the organization',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['getAllReferences'],
},
},
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: ['getAllReferences'],
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 GetTrustCenterReferences($organizationId: ID!, $first: Int, $after: CursorKey) {
node(id: $organizationId) {
... on Organization {
trustCenter {
references(first: $first, after: $after) {
edges {
node {
id
name
description
websiteUrl
rank
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
}
`;
const references = 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?.references as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { references },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,116 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties } from 'n8n-workflow';
import * as getOp from './get.operation';
import * as updateOp from './update.operation';
import * as getAllReferencesOp from './getAllReferences.operation';
import * as createReferenceOp from './createReference.operation';
import * as deleteReferenceOp from './deleteReference.operation';
import * as getAllFilesOp from './getAllFiles.operation';
import * as deleteFileOp from './deleteFile.operation';
import * as createExternalUrlOp from './createExternalUrl.operation';
import * as deleteExternalUrlOp from './deleteExternalUrl.operation';
export const description: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['trustCenter'],
},
},
options: [
{
name: 'Create External URL',
value: 'createExternalUrl',
description: 'Create a new compliance external URL',
action: 'Create a compliance external URL',
},
{
name: 'Create Reference',
value: 'createReference',
description: 'Create a new trust center reference',
action: 'Create a trust center reference',
},
{
name: 'Delete External URL',
value: 'deleteExternalUrl',
description: 'Delete a compliance external URL',
action: 'Delete a compliance external URL',
},
{
name: 'Delete File',
value: 'deleteFile',
description: 'Delete a trust center file',
action: 'Delete a trust center file',
},
{
name: 'Delete Reference',
value: 'deleteReference',
description: 'Delete a trust center reference',
action: 'Delete a trust center reference',
},
{
name: 'Get',
value: 'get',
description: 'Get trust center settings',
action: 'Get trust center settings',
},
{
name: 'Get Many Files',
value: 'getAllFiles',
description: 'Get many trust center files',
action: 'Get many trust center files',
},
{
name: 'Get Many References',
value: 'getAllReferences',
description: 'Get many trust center references',
action: 'Get many trust center references',
},
{
name: 'Update',
value: 'update',
description: 'Update trust center settings',
action: 'Update trust center settings',
},
],
default: 'get',
},
...getOp.description,
...updateOp.description,
...getAllReferencesOp.description,
...createReferenceOp.description,
...deleteReferenceOp.description,
...getAllFilesOp.description,
...deleteFileOp.description,
...createExternalUrlOp.description,
...deleteExternalUrlOp.description,
];
export {
getOp as get,
updateOp as update,
getAllReferencesOp as getAllReferences,
createReferenceOp as createReference,
deleteReferenceOp as deleteReference,
getAllFilesOp as getAllFiles,
deleteFileOp as deleteFile,
createExternalUrlOp as createExternalUrl,
deleteExternalUrlOp as deleteExternalUrl,
};

View File

@@ -0,0 +1,107 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS 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: ['update'],
},
},
default: '',
description: 'The ID of the trust center to update',
required: true,
},
{
displayName: 'Active',
name: 'active',
type: 'boolean',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['update'],
},
},
default: false,
description: 'Whether the trust center is active',
},
{
displayName: 'Search Engine Indexing',
name: 'searchEngineIndexing',
type: 'options',
displayOptions: {
show: {
resource: ['trustCenter'],
operation: ['update'],
},
},
options: [
{
name: '(Unchanged)',
value: '',
},
{
name: 'Indexable',
value: 'INDEXABLE',
},
{
name: 'Not Indexable',
value: 'NOT_INDEXABLE',
},
],
default: '',
description: 'Whether search engines should index the trust center',
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const trustCenterId = this.getNodeParameter('trustCenterId', itemIndex) as string;
const active = this.getNodeParameter('active', itemIndex) as boolean | undefined;
const searchEngineIndexing = this.getNodeParameter('searchEngineIndexing', itemIndex, '') as string;
const query = `
mutation UpdateTrustCenter($input: UpdateTrustCenterInput!) {
updateTrustCenter(input: $input) {
trustCenter {
id
active
searchEngineIndexing
createdAt
updatedAt
}
}
}
`;
const input: Record<string, unknown> = { trustCenterId };
if (active !== undefined) input.active = active;
if (searchEngineIndexing) input.searchEngineIndexing = searchEngineIndexing;
const responseData = await proboApiRequest.call(this, query, { input });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Vendor ID',
name: 'vendorId',
type: 'string',
displayOptions: {
show: {
resource: ['vendor'],
operation: ['deleteBusinessAssociateAgreement'],
},
},
default: '',
description: 'The ID of the vendor',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const vendorId = this.getNodeParameter('vendorId', itemIndex) as string;
const query = `
mutation DeleteVendorBusinessAssociateAgreement($input: DeleteVendorBusinessAssociateAgreementInput!) {
deleteVendorBusinessAssociateAgreement(input: $input) {
deletedVendorBusinessAssociateAgreementId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { vendorId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Vendor Compliance Report ID',
name: 'vendorComplianceReportId',
type: 'string',
displayOptions: {
show: {
resource: ['vendor'],
operation: ['deleteComplianceReport'],
},
},
default: '',
description: 'The ID of the vendor compliance report to delete',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const vendorComplianceReportId = this.getNodeParameter('vendorComplianceReportId', itemIndex) as string;
const query = `
mutation DeleteVendorComplianceReport($input: DeleteVendorComplianceReportInput!) {
deleteVendorComplianceReport(input: $input) {
deletedVendorComplianceReportId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { vendorComplianceReportId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Vendor ID',
name: 'vendorId',
type: 'string',
displayOptions: {
show: {
resource: ['vendor'],
operation: ['deleteDataPrivacyAgreement'],
},
},
default: '',
description: 'The ID of the vendor',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const vendorId = this.getNodeParameter('vendorId', itemIndex) as string;
const query = `
mutation DeleteVendorDataPrivacyAgreement($input: DeleteVendorDataPrivacyAgreementInput!) {
deleteVendorDataPrivacyAgreement(input: $input) {
deletedVendorDataPrivacyAgreementId
}
}
`;
const responseData = await proboApiRequest.call(this, query, { input: { vendorId } });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,115 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData, IDataObject } from 'n8n-workflow';
import { proboApiRequestAllItems } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Vendor ID',
name: 'vendorId',
type: 'string',
displayOptions: {
show: {
resource: ['vendor'],
operation: ['getAllComplianceReports'],
},
},
default: '',
description: 'The ID of the vendor',
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['vendor'],
operation: ['getAllComplianceReports'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['vendor'],
operation: ['getAllComplianceReports'],
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 vendorId = this.getNodeParameter('vendorId', itemIndex) as string;
const returnAll = this.getNodeParameter('returnAll', itemIndex) as boolean;
const limit = this.getNodeParameter('limit', itemIndex, 50) as number;
const query = `
query GetVendorComplianceReports($vendorId: ID!, $first: Int, $after: CursorKey) {
node(id: $vendorId) {
... on Vendor {
complianceReports(first: $first, after: $after) {
edges {
node {
id
reportDate
validUntil
reportName
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
`;
const vendorComplianceReports = await proboApiRequestAllItems.call(
this,
query,
{ vendorId },
(response) => {
const data = response?.data as IDataObject | undefined;
const node = data?.node as IDataObject | undefined;
return node?.complianceReports as IDataObject | undefined;
},
returnAll,
limit,
);
return {
json: { vendorComplianceReports },
pairedItem: { item: itemIndex },
};
}

View File

@@ -0,0 +1,66 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { proboApiRequest } from '../../GenericFunctions';
export const description: INodeProperties[] = [
{
displayName: 'Vendor ID',
name: 'vendorId',
type: 'string',
displayOptions: {
show: {
resource: ['vendor'],
operation: ['getBusinessAssociateAgreement'],
},
},
default: '',
description: 'The ID of the vendor',
required: true,
},
];
export async function execute(
this: IExecuteFunctions,
itemIndex: number,
): Promise<INodeExecutionData> {
const vendorId = this.getNodeParameter('vendorId', itemIndex) as string;
const query = `
query GetVendorBusinessAssociateAgreement($vendorId: ID!) {
node(id: $vendorId) {
... on Vendor {
businessAssociateAgreement {
id
validFrom
validUntil
fileName
fileUrl
fileSize
createdAt
updatedAt
}
}
}
}
`;
const responseData = await proboApiRequest.call(this, query, { vendorId });
return {
json: responseData,
pairedItem: { item: itemIndex },
};
}

Some files were not shown because too many files have changed in this diff Show More