From 1e4813c9d77c8bb0c00910c1558513b4cd13e52f Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Wed, 3 Dec 2025 11:24:43 +0100 Subject: [PATCH] Add vendor operations Signed-off-by: Bryan Frimin --- packages/n8n-node/nodes/Probo/Probo.node.ts | 5 + .../n8n-node/nodes/Probo/actions/index.ts | 2 + .../Probo/actions/vendor/create.operation.ts | 306 +++++++++++++++++ .../Probo/actions/vendor/delete.operation.ts | 42 +++ .../Probo/actions/vendor/get.operation.ts | 135 ++++++++ .../Probo/actions/vendor/getAll.operation.ts | 184 ++++++++++ .../nodes/Probo/actions/vendor/index.ts | 61 ++++ .../Probo/actions/vendor/update.operation.ts | 324 ++++++++++++++++++ 8 files changed, 1059 insertions(+) create mode 100644 packages/n8n-node/nodes/Probo/actions/vendor/create.operation.ts create mode 100644 packages/n8n-node/nodes/Probo/actions/vendor/delete.operation.ts create mode 100644 packages/n8n-node/nodes/Probo/actions/vendor/get.operation.ts create mode 100644 packages/n8n-node/nodes/Probo/actions/vendor/getAll.operation.ts create mode 100644 packages/n8n-node/nodes/Probo/actions/vendor/index.ts create mode 100644 packages/n8n-node/nodes/Probo/actions/vendor/update.operation.ts diff --git a/packages/n8n-node/nodes/Probo/Probo.node.ts b/packages/n8n-node/nodes/Probo/Probo.node.ts index 5c5b7fac5..439dfc216 100644 --- a/packages/n8n-node/nodes/Probo/Probo.node.ts +++ b/packages/n8n-node/nodes/Probo/Probo.node.ts @@ -102,6 +102,11 @@ export class Probo implements INodeType { value: 'organization', description: 'Manage organizations', }, + { + name: 'Vendor', + value: 'vendor', + description: 'Manage vendors', + }, ], default: 'execute', }, diff --git a/packages/n8n-node/nodes/Probo/actions/index.ts b/packages/n8n-node/nodes/Probo/actions/index.ts index 7bb1527e8..14278a4f2 100644 --- a/packages/n8n-node/nodes/Probo/actions/index.ts +++ b/packages/n8n-node/nodes/Probo/actions/index.ts @@ -7,6 +7,7 @@ import * as framework from './framework'; import * as measure from './measure'; import * as meeting from './meeting'; import * as organization from './organization'; +import * as vendor from './vendor'; export interface ResourceModule { description: INodeProperties[]; @@ -27,6 +28,7 @@ export const resources: Record = { measure: measure as ResourceModule, meeting: meeting as ResourceModule, organization: organization as ResourceModule, + vendor: vendor as ResourceModule, }; export function getAllResourceOperations(): INodeProperties[] { diff --git a/packages/n8n-node/nodes/Probo/actions/vendor/create.operation.ts b/packages/n8n-node/nodes/Probo/actions/vendor/create.operation.ts new file mode 100644 index 000000000..ff09b92d7 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/vendor/create.operation.ts @@ -0,0 +1,306 @@ +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: ['vendor'], + operation: ['create'], + }, + }, + default: '', + description: 'The ID of the organization', + required: true, + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['create'], + }, + }, + default: '', + description: 'The name of the vendor', + required: true, + }, + { + displayName: 'Description', + name: 'description', + type: 'string', + typeOptions: { + rows: 4, + }, + displayOptions: { + show: { + resource: ['vendor'], + operation: ['create'], + }, + }, + default: '', + description: 'The description of the vendor', + }, + { + displayName: 'Category', + name: 'category', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['create'], + }, + }, + default: '', + description: 'The category of the vendor', + }, + { + displayName: 'Website URL', + name: 'websiteUrl', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['create'], + }, + }, + default: '', + description: 'The website URL of the vendor', + }, + { + displayName: 'Legal Name', + name: 'legalName', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['create'], + }, + }, + default: '', + description: 'The legal name of the vendor', + }, + { + displayName: 'Headquarter Address', + name: 'headquarterAddress', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['create'], + }, + }, + default: '', + description: 'The headquarter address of the vendor', + }, + { + displayName: 'Business Owner ID', + name: 'businessOwnerId', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['create'], + }, + }, + default: '', + description: 'The ID of the business owner (People ID)', + }, + { + displayName: 'Security Owner ID', + name: 'securityOwnerId', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['create'], + }, + }, + default: '', + description: 'The ID of the security owner (People ID)', + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: ['vendor'], + operation: ['create'], + }, + }, + options: [ + { + displayName: 'Business Associate Agreement URL', + name: 'businessAssociateAgreementUrl', + type: 'string', + default: '', + }, + { + displayName: 'Certifications', + name: 'certifications', + type: 'string', + default: '', + description: 'Comma-separated list of certifications', + }, + { + displayName: 'Countries', + name: 'countries', + type: 'string', + default: '', + description: 'Comma-separated list of country codes', + }, + { + displayName: 'Data Processing Agreement URL', + name: 'dataProcessingAgreementUrl', + type: 'string', + default: '', + }, + { + displayName: 'Privacy Policy URL', + name: 'privacyPolicyUrl', + type: 'string', + default: '', + }, + { + displayName: 'Security Page URL', + name: 'securityPageUrl', + type: 'string', + default: '', + }, + { + displayName: 'Service Level Agreement URL', + name: 'serviceLevelAgreementUrl', + type: 'string', + default: '', + }, + { + displayName: 'Status Page URL', + name: 'statusPageUrl', + type: 'string', + default: '', + description: 'The status page URL of the vendor', + }, + { + displayName: 'Subprocessors List URL', + name: 'subprocessorsListUrl', + type: 'string', + default: '', + }, + { + displayName: 'Terms of Service URL', + name: 'termsOfServiceUrl', + type: 'string', + default: '', + }, + { + displayName: 'Trust Page URL', + name: 'trustPageUrl', + type: 'string', + default: '', + }, + ], + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + 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 category = this.getNodeParameter('category', itemIndex, '') as string; + const websiteUrl = this.getNodeParameter('websiteUrl', itemIndex, '') as string; + const legalName = this.getNodeParameter('legalName', itemIndex, '') as string; + const headquarterAddress = this.getNodeParameter('headquarterAddress', itemIndex, '') as string; + const businessOwnerId = this.getNodeParameter('businessOwnerId', itemIndex, '') as string; + const securityOwnerId = this.getNodeParameter('securityOwnerId', itemIndex, '') as string; + const additionalFields = this.getNodeParameter('additionalFields', itemIndex, {}) as { + statusPageUrl?: string; + termsOfServiceUrl?: string; + privacyPolicyUrl?: string; + serviceLevelAgreementUrl?: string; + dataProcessingAgreementUrl?: string; + businessAssociateAgreementUrl?: string; + subprocessorsListUrl?: string; + securityPageUrl?: string; + trustPageUrl?: string; + certifications?: string; + countries?: string; + }; + + const query = ` + mutation CreateVendor($input: CreateVendorInput!) { + createVendor(input: $input) { + vendorEdge { + node { + id + name + description + category + websiteUrl + legalName + headquarterAddress + statusPageUrl + termsOfServiceUrl + privacyPolicyUrl + serviceLevelAgreementUrl + dataProcessingAgreementUrl + businessAssociateAgreementUrl + subprocessorsListUrl + securityPageUrl + trustPageUrl + certifications + countries + showOnTrustCenter + createdAt + updatedAt + } + } + } + } + `; + + const input: Record = { + organizationId, + name, + }; + if (description) input.description = description; + if (category) input.category = category; + if (websiteUrl) input.websiteUrl = websiteUrl; + if (legalName) input.legalName = legalName; + if (headquarterAddress) input.headquarterAddress = headquarterAddress; + if (businessOwnerId) input.businessOwnerId = businessOwnerId; + if (securityOwnerId) input.securityOwnerId = securityOwnerId; + if (additionalFields.statusPageUrl) input.statusPageUrl = additionalFields.statusPageUrl; + if (additionalFields.termsOfServiceUrl) input.termsOfServiceUrl = additionalFields.termsOfServiceUrl; + if (additionalFields.privacyPolicyUrl) input.privacyPolicyUrl = additionalFields.privacyPolicyUrl; + if (additionalFields.serviceLevelAgreementUrl) input.serviceLevelAgreementUrl = additionalFields.serviceLevelAgreementUrl; + if (additionalFields.dataProcessingAgreementUrl) input.dataProcessingAgreementUrl = additionalFields.dataProcessingAgreementUrl; + if (additionalFields.businessAssociateAgreementUrl) input.businessAssociateAgreementUrl = additionalFields.businessAssociateAgreementUrl; + if (additionalFields.subprocessorsListUrl) input.subprocessorsListUrl = additionalFields.subprocessorsListUrl; + if (additionalFields.securityPageUrl) input.securityPageUrl = additionalFields.securityPageUrl; + if (additionalFields.trustPageUrl) input.trustPageUrl = additionalFields.trustPageUrl; + if (additionalFields.certifications) { + input.certifications = additionalFields.certifications.split(',').map((c) => c.trim()).filter(Boolean); + } + if (additionalFields.countries) { + input.countries = additionalFields.countries.split(',').map((c) => c.trim()).filter(Boolean); + } + + const responseData = await proboApiRequest.call(this, query, { input }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} + diff --git a/packages/n8n-node/nodes/Probo/actions/vendor/delete.operation.ts b/packages/n8n-node/nodes/Probo/actions/vendor/delete.operation.ts new file mode 100644 index 000000000..c53e75d3c --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/vendor/delete.operation.ts @@ -0,0 +1,42 @@ +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: ['delete'], + }, + }, + default: '', + description: 'The ID of the vendor to delete', + required: true, + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const vendorId = this.getNodeParameter('vendorId', itemIndex) as string; + + const query = ` + mutation DeleteVendor($input: DeleteVendorInput!) { + deleteVendor(input: $input) { + deletedVendorId + } + } + `; + + const responseData = await proboApiRequest.call(this, query, { input: { vendorId } }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} + diff --git a/packages/n8n-node/nodes/Probo/actions/vendor/get.operation.ts b/packages/n8n-node/nodes/Probo/actions/vendor/get.operation.ts new file mode 100644 index 000000000..667436582 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/vendor/get.operation.ts @@ -0,0 +1,135 @@ +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: ['get'], + }, + }, + default: '', + description: 'The ID of the vendor', + required: true, + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + resource: ['vendor'], + operation: ['get'], + }, + }, + options: [ + { + displayName: 'Include Organization', + name: 'includeOrganization', + type: 'boolean', + default: false, + description: 'Whether to include organization in the response', + }, + { + displayName: 'Include Business Owner', + name: 'includeBusinessOwner', + type: 'boolean', + default: false, + description: 'Whether to include business owner in the response', + }, + { + displayName: 'Include Security Owner', + name: 'includeSecurityOwner', + type: 'boolean', + default: false, + description: 'Whether to include security owner in the response', + }, + ], + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const vendorId = this.getNodeParameter('vendorId', itemIndex) as string; + const options = this.getNodeParameter('options', itemIndex, {}) as { + includeOrganization?: boolean; + includeBusinessOwner?: boolean; + includeSecurityOwner?: boolean; + }; + + const organizationFragment = options.includeOrganization + ? `organization { + id + name + }` + : ''; + + const businessOwnerFragment = options.includeBusinessOwner + ? `businessOwner { + id + fullName + primaryEmailAddress + }` + : ''; + + const securityOwnerFragment = options.includeSecurityOwner + ? `securityOwner { + id + fullName + primaryEmailAddress + }` + : ''; + + const query = ` + query GetVendor($vendorId: ID!) { + node(id: $vendorId) { + ... on Vendor { + id + name + description + category + websiteUrl + legalName + headquarterAddress + statusPageUrl + termsOfServiceUrl + privacyPolicyUrl + serviceLevelAgreementUrl + dataProcessingAgreementUrl + businessAssociateAgreementUrl + subprocessorsListUrl + securityPageUrl + trustPageUrl + certifications + countries + showOnTrustCenter + ${organizationFragment} + ${businessOwnerFragment} + ${securityOwnerFragment} + createdAt + updatedAt + } + } + } + `; + + const variables = { + vendorId, + }; + + const responseData = await proboApiRequest.call(this, query, variables); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} + diff --git a/packages/n8n-node/nodes/Probo/actions/vendor/getAll.operation.ts b/packages/n8n-node/nodes/Probo/actions/vendor/getAll.operation.ts new file mode 100644 index 000000000..e367ca460 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/vendor/getAll.operation.ts @@ -0,0 +1,184 @@ +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: ['vendor'], + operation: ['getAll'], + }, + }, + default: '', + description: 'The ID of the organization', + required: true, + }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: ['vendor'], + 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: ['vendor'], + operation: ['getAll'], + returnAll: [false], + }, + }, + typeOptions: { + minValue: 1, + }, + default: 50, + description: 'Max number of results to return', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + resource: ['vendor'], + operation: ['getAll'], + }, + }, + options: [ + { + displayName: 'Include Organization', + name: 'includeOrganization', + type: 'boolean', + default: false, + description: 'Whether to include organization in the response', + }, + { + displayName: 'Include Business Owner', + name: 'includeBusinessOwner', + type: 'boolean', + default: false, + description: 'Whether to include business owner in the response', + }, + { + displayName: 'Include Security Owner', + name: 'includeSecurityOwner', + type: 'boolean', + default: false, + description: 'Whether to include security owner in the response', + }, + ], + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + 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 options = this.getNodeParameter('options', itemIndex, {}) as { + includeOrganization?: boolean; + includeBusinessOwner?: boolean; + includeSecurityOwner?: boolean; + }; + + const organizationFragment = options.includeOrganization + ? `organization { + id + name + }` + : ''; + + const businessOwnerFragment = options.includeBusinessOwner + ? `businessOwner { + id + fullName + primaryEmailAddress + }` + : ''; + + const securityOwnerFragment = options.includeSecurityOwner + ? `securityOwner { + id + fullName + primaryEmailAddress + }` + : ''; + + const query = ` + query GetVendors($organizationId: ID!, $first: Int, $after: CursorKey) { + node(id: $organizationId) { + ... on Organization { + vendors(first: $first, after: $after) { + edges { + node { + id + name + description + category + websiteUrl + legalName + headquarterAddress + statusPageUrl + termsOfServiceUrl + privacyPolicyUrl + serviceLevelAgreementUrl + dataProcessingAgreementUrl + businessAssociateAgreementUrl + subprocessorsListUrl + securityPageUrl + trustPageUrl + certifications + countries + showOnTrustCenter + ${organizationFragment} + ${businessOwnerFragment} + ${securityOwnerFragment} + createdAt + updatedAt + } + } + pageInfo { + hasNextPage + endCursor + } + } + } + } + } + `; + + const vendors = await proboApiRequestAllItems.call( + this, + query, + { organizationId }, + (response) => { + const data = response?.data as IDataObject | undefined; + const node = data?.node as IDataObject | undefined; + return node?.vendors as IDataObject | undefined; + }, + returnAll, + limit, + ); + + return { + json: { vendors }, + pairedItem: { item: itemIndex }, + }; +} + diff --git a/packages/n8n-node/nodes/Probo/actions/vendor/index.ts b/packages/n8n-node/nodes/Probo/actions/vendor/index.ts new file mode 100644 index 000000000..96f356182 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/vendor/index.ts @@ -0,0 +1,61 @@ +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: ['vendor'], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a new vendor', + action: 'Create a vendor', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a vendor', + action: 'Delete a vendor', + }, + { + name: 'Get', + value: 'get', + description: 'Get a vendor', + action: 'Get a vendor', + }, + { + name: 'Get Many', + value: 'getAll', + description: 'Get many vendors', + action: 'Get many vendors', + }, + { + name: 'Update', + value: 'update', + description: 'Update an existing vendor', + action: 'Update a vendor', + }, + ], + 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 }; + diff --git a/packages/n8n-node/nodes/Probo/actions/vendor/update.operation.ts b/packages/n8n-node/nodes/Probo/actions/vendor/update.operation.ts new file mode 100644 index 000000000..0f614d1c6 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/vendor/update.operation.ts @@ -0,0 +1,324 @@ +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: ['update'], + }, + }, + default: '', + description: 'The ID of the vendor to update', + required: true, + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['update'], + }, + }, + default: '', + description: 'The name of the vendor', + }, + { + displayName: 'Description', + name: 'description', + type: 'string', + typeOptions: { + rows: 4, + }, + displayOptions: { + show: { + resource: ['vendor'], + operation: ['update'], + }, + }, + default: '', + description: 'The description of the vendor', + }, + { + displayName: 'Category', + name: 'category', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['update'], + }, + }, + default: '', + description: 'The category of the vendor', + }, + { + displayName: 'Website URL', + name: 'websiteUrl', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['update'], + }, + }, + default: '', + description: 'The website URL of the vendor', + }, + { + displayName: 'Legal Name', + name: 'legalName', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['update'], + }, + }, + default: '', + description: 'The legal name of the vendor', + }, + { + displayName: 'Headquarter Address', + name: 'headquarterAddress', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['update'], + }, + }, + default: '', + description: 'The headquarter address of the vendor', + }, + { + displayName: 'Business Owner ID', + name: 'businessOwnerId', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['update'], + }, + }, + default: '', + description: 'The ID of the business owner (People ID)', + }, + { + displayName: 'Security Owner ID', + name: 'securityOwnerId', + type: 'string', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['update'], + }, + }, + default: '', + description: 'The ID of the security owner (People ID)', + }, + { + displayName: 'Show on Trust Center', + name: 'showOnTrustCenter', + type: 'boolean', + displayOptions: { + show: { + resource: ['vendor'], + operation: ['update'], + }, + }, + default: false, + description: 'Whether to show the vendor on the trust center', + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: ['vendor'], + operation: ['update'], + }, + }, + options: [ + { + displayName: 'Business Associate Agreement URL', + name: 'businessAssociateAgreementUrl', + type: 'string', + default: '', + }, + { + displayName: 'Certifications', + name: 'certifications', + type: 'string', + default: '', + description: 'Comma-separated list of certifications', + }, + { + displayName: 'Countries', + name: 'countries', + type: 'string', + default: '', + description: 'Comma-separated list of country codes', + }, + { + displayName: 'Data Processing Agreement URL', + name: 'dataProcessingAgreementUrl', + type: 'string', + default: '', + }, + { + displayName: 'Privacy Policy URL', + name: 'privacyPolicyUrl', + type: 'string', + default: '', + }, + { + displayName: 'Security Page URL', + name: 'securityPageUrl', + type: 'string', + default: '', + }, + { + displayName: 'Service Level Agreement URL', + name: 'serviceLevelAgreementUrl', + type: 'string', + default: '', + }, + { + displayName: 'Status Page URL', + name: 'statusPageUrl', + type: 'string', + default: '', + description: 'The status page URL of the vendor', + }, + { + displayName: 'Subprocessors List URL', + name: 'subprocessorsListUrl', + type: 'string', + default: '', + }, + { + displayName: 'Terms of Service URL', + name: 'termsOfServiceUrl', + type: 'string', + default: '', + }, + { + displayName: 'Trust Page URL', + name: 'trustPageUrl', + type: 'string', + default: '', + }, + ], + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const vendorId = this.getNodeParameter('vendorId', itemIndex) as string; + const name = this.getNodeParameter('name', itemIndex, '') as string; + const description = this.getNodeParameter('description', itemIndex, '') as string; + const category = this.getNodeParameter('category', itemIndex, '') as string; + const websiteUrl = this.getNodeParameter('websiteUrl', itemIndex, '') as string; + const legalName = this.getNodeParameter('legalName', itemIndex, '') as string; + const headquarterAddress = this.getNodeParameter('headquarterAddress', itemIndex, '') as string; + const businessOwnerId = this.getNodeParameter('businessOwnerId', itemIndex, '') as string; + const securityOwnerId = this.getNodeParameter('securityOwnerId', itemIndex, '') as string; + const showOnTrustCenter = this.getNodeParameter('showOnTrustCenter', itemIndex) as boolean | undefined; + const additionalFields = this.getNodeParameter('additionalFields', itemIndex, {}) as { + statusPageUrl?: string; + termsOfServiceUrl?: string; + privacyPolicyUrl?: string; + serviceLevelAgreementUrl?: string; + dataProcessingAgreementUrl?: string; + businessAssociateAgreementUrl?: string; + subprocessorsListUrl?: string; + securityPageUrl?: string; + trustPageUrl?: string; + certifications?: string; + countries?: string; + }; + + const query = ` + mutation UpdateVendor($input: UpdateVendorInput!) { + updateVendor(input: $input) { + vendor { + id + name + description + category + websiteUrl + legalName + headquarterAddress + statusPageUrl + termsOfServiceUrl + privacyPolicyUrl + serviceLevelAgreementUrl + dataProcessingAgreementUrl + businessAssociateAgreementUrl + subprocessorsListUrl + securityPageUrl + trustPageUrl + certifications + countries + showOnTrustCenter + createdAt + updatedAt + } + } + } + `; + + const input: Record = { id: vendorId }; + if (name) input.name = name; + if (description !== undefined) input.description = description === '' ? null : description; + if (category) input.category = category; + if (websiteUrl !== undefined) input.websiteUrl = websiteUrl === '' ? null : websiteUrl; + if (legalName !== undefined) input.legalName = legalName === '' ? null : legalName; + if (headquarterAddress !== undefined) input.headquarterAddress = headquarterAddress === '' ? null : headquarterAddress; + if (businessOwnerId !== undefined) input.businessOwnerId = businessOwnerId === '' ? null : businessOwnerId; + if (securityOwnerId !== undefined) input.securityOwnerId = securityOwnerId === '' ? null : securityOwnerId; + if (showOnTrustCenter !== undefined) input.showOnTrustCenter = showOnTrustCenter; + if (additionalFields.statusPageUrl !== undefined) input.statusPageUrl = additionalFields.statusPageUrl === '' ? null : additionalFields.statusPageUrl; + if (additionalFields.termsOfServiceUrl !== undefined) input.termsOfServiceUrl = additionalFields.termsOfServiceUrl === '' ? null : additionalFields.termsOfServiceUrl; + if (additionalFields.privacyPolicyUrl !== undefined) input.privacyPolicyUrl = additionalFields.privacyPolicyUrl === '' ? null : additionalFields.privacyPolicyUrl; + if (additionalFields.serviceLevelAgreementUrl !== undefined) input.serviceLevelAgreementUrl = additionalFields.serviceLevelAgreementUrl === '' ? null : additionalFields.serviceLevelAgreementUrl; + if (additionalFields.dataProcessingAgreementUrl !== undefined) input.dataProcessingAgreementUrl = additionalFields.dataProcessingAgreementUrl === '' ? null : additionalFields.dataProcessingAgreementUrl; + if (additionalFields.businessAssociateAgreementUrl !== undefined) input.businessAssociateAgreementUrl = additionalFields.businessAssociateAgreementUrl === '' ? null : additionalFields.businessAssociateAgreementUrl; + if (additionalFields.subprocessorsListUrl !== undefined) input.subprocessorsListUrl = additionalFields.subprocessorsListUrl === '' ? null : additionalFields.subprocessorsListUrl; + if (additionalFields.securityPageUrl !== undefined) input.securityPageUrl = additionalFields.securityPageUrl === '' ? null : additionalFields.securityPageUrl; + if (additionalFields.trustPageUrl !== undefined) input.trustPageUrl = additionalFields.trustPageUrl === '' ? null : additionalFields.trustPageUrl; + if (additionalFields.certifications !== undefined) { + if (additionalFields.certifications === '') { + input.certifications = []; + } else { + input.certifications = additionalFields.certifications.split(',').map((c) => c.trim()).filter(Boolean); + } + } + if (additionalFields.countries !== undefined) { + if (additionalFields.countries === '') { + input.countries = []; + } else { + input.countries = additionalFields.countries.split(',').map((c) => c.trim()).filter(Boolean); + } + } + + const responseData = await proboApiRequest.call(this, query, { input }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} +