diff --git a/packages/n8n-node/nodes/Probo/Probo.node.ts b/packages/n8n-node/nodes/Probo/Probo.node.ts index 67377704c..336efe7ff 100644 --- a/packages/n8n-node/nodes/Probo/Probo.node.ts +++ b/packages/n8n-node/nodes/Probo/Probo.node.ts @@ -62,6 +62,11 @@ export class Probo implements INodeType { type: 'options', noDataExpression: true, options: [ + { + name: 'Asset', + value: 'asset', + description: 'Manage assets', + }, { name: 'Control', value: 'control', diff --git a/packages/n8n-node/nodes/Probo/actions/asset/create.operation.ts b/packages/n8n-node/nodes/Probo/actions/asset/create.operation.ts new file mode 100644 index 000000000..752c5d5dd --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/asset/create.operation.ts @@ -0,0 +1,165 @@ +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: ['asset'], + operation: ['create'], + }, + }, + default: '', + description: 'The ID of the organization', + required: true, + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['create'], + }, + }, + default: '', + description: 'The name of the asset', + required: true, + }, + { + displayName: 'Amount', + name: 'amount', + type: 'number', + displayOptions: { + show: { + resource: ['asset'], + operation: ['create'], + }, + }, + default: 1, + description: 'The amount of the asset', + required: true, + }, + { + displayName: 'Owner ID', + name: 'ownerId', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['create'], + }, + }, + default: '', + description: 'The ID of the owner (People)', + required: true, + }, + { + displayName: 'Asset Type', + name: 'assetType', + type: 'options', + displayOptions: { + show: { + resource: ['asset'], + operation: ['create'], + }, + }, + options: [ + { + name: 'Physical', + value: 'PHYSICAL', + }, + { + name: 'Virtual', + value: 'VIRTUAL', + }, + ], + default: 'PHYSICAL', + description: 'The type of the asset', + required: true, + }, + { + displayName: 'Data Types Stored', + name: 'dataTypesStored', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['create'], + }, + }, + default: '', + description: 'The types of data stored in the asset', + required: true, + }, + { + displayName: 'Vendor IDs', + name: 'vendorIds', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['create'], + }, + }, + default: '', + description: 'Comma-separated list of vendor IDs', + }, +]; + +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 amount = this.getNodeParameter('amount', itemIndex) as number; + const ownerId = this.getNodeParameter('ownerId', itemIndex) as string; + const assetType = this.getNodeParameter('assetType', itemIndex) as string; + const dataTypesStored = this.getNodeParameter('dataTypesStored', itemIndex) as string; + const vendorIdsStr = this.getNodeParameter('vendorIds', itemIndex, '') as string; + + const query = ` + mutation CreateAsset($input: CreateAssetInput!) { + createAsset(input: $input) { + assetEdge { + node { + id + name + amount + assetType + dataTypesStored + createdAt + updatedAt + } + } + } + } + `; + + const vendorIds = vendorIdsStr ? vendorIdsStr.split(',').map((id) => id.trim()).filter(Boolean) : undefined; + + const variables = { + input: { + organizationId, + name, + amount, + ownerId, + assetType, + dataTypesStored, + ...(vendorIds && vendorIds.length > 0 && { vendorIds }), + }, + }; + + const responseData = await proboApiRequest.call(this, query, variables); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} + diff --git a/packages/n8n-node/nodes/Probo/actions/asset/delete.operation.ts b/packages/n8n-node/nodes/Probo/actions/asset/delete.operation.ts new file mode 100644 index 000000000..c64cee895 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/asset/delete.operation.ts @@ -0,0 +1,42 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Asset ID', + name: 'assetId', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['delete'], + }, + }, + default: '', + description: 'The ID of the asset to delete', + required: true, + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const assetId = this.getNodeParameter('assetId', itemIndex) as string; + + const query = ` + mutation DeleteAsset($input: DeleteAssetInput!) { + deleteAsset(input: $input) { + deletedAssetId + } + } + `; + + const responseData = await proboApiRequest.call(this, query, { input: { assetId } }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} + diff --git a/packages/n8n-node/nodes/Probo/actions/asset/get.operation.ts b/packages/n8n-node/nodes/Probo/actions/asset/get.operation.ts new file mode 100644 index 000000000..8758eb021 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/asset/get.operation.ts @@ -0,0 +1,54 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Asset ID', + name: 'assetId', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['get'], + }, + }, + default: '', + description: 'The ID of the asset', + required: true, + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const assetId = this.getNodeParameter('assetId', itemIndex) as string; + + const query = ` + query GetAsset($assetId: ID!) { + node(id: $assetId) { + ... on Asset { + id + name + amount + assetType + dataTypesStored + createdAt + updatedAt + } + } + } + `; + + const variables = { + assetId, + }; + + const responseData = await proboApiRequest.call(this, query, variables); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} + diff --git a/packages/n8n-node/nodes/Probo/actions/asset/getAll.operation.ts b/packages/n8n-node/nodes/Probo/actions/asset/getAll.operation.ts new file mode 100644 index 000000000..d5a693f5c --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/asset/getAll.operation.ts @@ -0,0 +1,99 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequestAllItems } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Organization ID', + name: 'organizationId', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['getAll'], + }, + }, + default: '', + description: 'The ID of the organization', + required: true, + }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: ['asset'], + 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: ['asset'], + 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 { + 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 GetAssets($organizationId: ID!, $first: Int, $after: CursorKey) { + node(id: $organizationId) { + ... on Organization { + assets(first: $first, after: $after) { + edges { + node { + id + name + amount + assetType + dataTypesStored + createdAt + updatedAt + } + } + pageInfo { + hasNextPage + endCursor + } + } + } + } + } + `; + + const assets = await proboApiRequestAllItems.call( + this, + query, + { organizationId }, + (response) => response?.data?.node?.assets, + returnAll, + limit, + ); + + return { + json: { assets }, + pairedItem: { item: itemIndex }, + }; +} + diff --git a/packages/n8n-node/nodes/Probo/actions/asset/index.ts b/packages/n8n-node/nodes/Probo/actions/asset/index.ts new file mode 100644 index 000000000..98d1a3d6b --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/asset/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: ['asset'], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a new asset', + action: 'Create an asset', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete an asset', + action: 'Delete an asset', + }, + { + name: 'Get', + value: 'get', + description: 'Get an asset', + action: 'Get an asset', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all assets', + action: 'Get all assets', + }, + { + name: 'Update', + value: 'update', + description: 'Update an existing asset', + action: 'Update an asset', + }, + ], + 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/asset/update.operation.ts b/packages/n8n-node/nodes/Probo/actions/asset/update.operation.ts new file mode 100644 index 000000000..1f244da31 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/asset/update.operation.ts @@ -0,0 +1,155 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Asset ID', + name: 'id', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['update'], + }, + }, + default: '', + description: 'The ID of the asset to update', + required: true, + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['update'], + }, + }, + default: '', + description: 'The name of the asset', + }, + { + displayName: 'Amount', + name: 'amount', + type: 'number', + displayOptions: { + show: { + resource: ['asset'], + operation: ['update'], + }, + }, + default: 0, + description: 'The amount of the asset', + }, + { + displayName: 'Owner ID', + name: 'ownerId', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['update'], + }, + }, + default: '', + description: 'The ID of the owner (People)', + }, + { + displayName: 'Asset Type', + name: 'assetType', + type: 'options', + displayOptions: { + show: { + resource: ['asset'], + operation: ['update'], + }, + }, + options: [ + { + name: 'Physical', + value: 'PHYSICAL', + }, + { + name: 'Virtual', + value: 'VIRTUAL', + }, + ], + default: '', + description: 'The type of the asset', + }, + { + displayName: 'Data Types Stored', + name: 'dataTypesStored', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['update'], + }, + }, + default: '', + description: 'The types of data stored in the asset', + }, + { + displayName: 'Vendor IDs', + name: 'vendorIds', + type: 'string', + displayOptions: { + show: { + resource: ['asset'], + operation: ['update'], + }, + }, + default: '', + description: 'Comma-separated list of vendor IDs', + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const id = this.getNodeParameter('id', itemIndex) as string; + const name = this.getNodeParameter('name', itemIndex, '') as string; + const amount = this.getNodeParameter('amount', itemIndex, 0) as number; + const ownerId = this.getNodeParameter('ownerId', itemIndex, '') as string; + const assetType = this.getNodeParameter('assetType', itemIndex, '') as string; + const dataTypesStored = this.getNodeParameter('dataTypesStored', itemIndex, '') as string; + const vendorIdsStr = this.getNodeParameter('vendorIds', itemIndex, '') as string; + + const query = ` + mutation UpdateAsset($input: UpdateAssetInput!) { + updateAsset(input: $input) { + asset { + id + name + amount + assetType + dataTypesStored + createdAt + updatedAt + } + } + } + `; + + const input: Record = { id }; + if (name) input.name = name; + if (amount) input.amount = amount; + if (ownerId) input.ownerId = ownerId; + if (assetType) input.assetType = assetType; + if (dataTypesStored) input.dataTypesStored = dataTypesStored; + if (vendorIdsStr) { + const vendorIds = vendorIdsStr.split(',').map((vid) => vid.trim()).filter(Boolean); + if (vendorIds.length > 0) input.vendorIds = vendorIds; + } + + const responseData = await proboApiRequest.call(this, query, { input }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} + diff --git a/packages/n8n-node/nodes/Probo/actions/index.ts b/packages/n8n-node/nodes/Probo/actions/index.ts index 0b4e2df42..dfe9bdd8f 100644 --- a/packages/n8n-node/nodes/Probo/actions/index.ts +++ b/packages/n8n-node/nodes/Probo/actions/index.ts @@ -1,4 +1,5 @@ import type { IExecuteFunctions, INodeExecutionData, INodeProperties } from 'n8n-workflow'; +import * as asset from './asset'; import * as control from './control'; import * as execute from './execute'; import * as framework from './framework'; @@ -15,6 +16,7 @@ export interface OperationModule { } export const resources: Record = { + asset: asset as ResourceModule, control: control as ResourceModule, execute: execute as ResourceModule, framework: framework as ResourceModule,