@@ -11,7 +11,7 @@ export async function proboApiRequest(
|
||||
this: IExecuteFunctions | IHookFunctions,
|
||||
query: string,
|
||||
variables: IDataObject = {},
|
||||
): Promise<any> {
|
||||
): Promise<IDataObject> {
|
||||
const credentials = await this.getCredentials('proboApi');
|
||||
|
||||
if (!credentials?.apiKey) {
|
||||
@@ -44,11 +44,11 @@ export async function proboApiRequestAllItems(
|
||||
this: IExecuteFunctions,
|
||||
query: string,
|
||||
variables: IDataObject,
|
||||
getConnection: (response: any) => any,
|
||||
getConnection: (response: IDataObject) => IDataObject | undefined,
|
||||
returnAll: boolean = true,
|
||||
limit: number = 0,
|
||||
): Promise<any[]> {
|
||||
const items: any[] = [];
|
||||
): Promise<IDataObject[]> {
|
||||
const items: IDataObject[] = [];
|
||||
let hasNextPage = true;
|
||||
let cursor: string | null = null;
|
||||
const pageSize = 100;
|
||||
@@ -72,7 +72,8 @@ export async function proboApiRequestAllItems(
|
||||
const connection = getConnection(responseData);
|
||||
|
||||
if (connection?.edges) {
|
||||
items.push(...connection.edges.map((edge: any) => edge.node));
|
||||
const edges = connection.edges as Array<{ node: IDataObject }>;
|
||||
items.push(...edges.map((edge) => edge.node));
|
||||
}
|
||||
|
||||
if (connection?.pageInfo) {
|
||||
|
||||
@@ -15,7 +15,7 @@ export class Probo implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'Probo',
|
||||
name: 'probo',
|
||||
icon: { light: 'file:../../icons/probo.svg', dark: 'file:../../icons/probo.svg' },
|
||||
icon: { light: 'file:../../icons/probo-light.svg', dark: 'file:../../icons/probo.svg' },
|
||||
group: ['input'],
|
||||
version: 1,
|
||||
subtitle: '={{$parameter["resource"]}} / {{$parameter["operation"]}}',
|
||||
|
||||
@@ -36,10 +36,10 @@ export const description: INodeProperties[] = [
|
||||
action: 'Get an asset',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
description: 'Get all assets',
|
||||
action: 'Get all assets',
|
||||
description: 'Get many assets',
|
||||
action: 'Get many assets',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
|
||||
@@ -75,7 +75,7 @@ export const description: INodeProperties[] = [
|
||||
value: 'VIRTUAL',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
default: 'PHYSICAL',
|
||||
description: 'The type of the asset',
|
||||
},
|
||||
{
|
||||
@@ -188,7 +188,7 @@ export async function execute(
|
||||
}
|
||||
`;
|
||||
|
||||
const input: Record<string, any> = { id };
|
||||
const input: Record<string, string | number | string[]> = { id };
|
||||
if (name) input.name = name;
|
||||
if (amount) input.amount = amount;
|
||||
if (ownerId) input.ownerId = ownerId;
|
||||
|
||||
@@ -36,10 +36,10 @@ export const description: INodeProperties[] = [
|
||||
action: 'Get a control',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
description: 'Get all controls',
|
||||
action: 'Get all controls',
|
||||
description: 'Get many controls',
|
||||
action: 'Get many controls',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
|
||||
@@ -75,7 +75,7 @@ export const description: INodeProperties[] = [
|
||||
value: 'EXCLUDED',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
default: 'INCLUDED',
|
||||
description: 'The status of the control',
|
||||
},
|
||||
{
|
||||
@@ -121,7 +121,7 @@ export async function execute(
|
||||
}
|
||||
`;
|
||||
|
||||
const input: Record<string, any> = { id };
|
||||
const input: Record<string, string> = { id };
|
||||
if (sectionTitle) input.sectionTitle = sectionTitle;
|
||||
if (name) input.name = name;
|
||||
if (description) input.description = description;
|
||||
|
||||
@@ -36,10 +36,10 @@ export const description: INodeProperties[] = [
|
||||
action: 'Get a datum',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
description: 'Get all data',
|
||||
action: 'Get all data',
|
||||
description: 'Get many data',
|
||||
action: 'Get many data',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
|
||||
@@ -57,7 +57,7 @@ export const description: INodeProperties[] = [
|
||||
value: 'SECRET',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
default: 'PUBLIC',
|
||||
description: 'The classification of the data',
|
||||
},
|
||||
{
|
||||
@@ -166,7 +166,7 @@ export async function execute(
|
||||
}
|
||||
`;
|
||||
|
||||
const input: Record<string, any> = { id };
|
||||
const input: Record<string, string | string[]> = { id };
|
||||
if (name) input.name = name;
|
||||
if (dataClassification) input.dataClassification = dataClassification;
|
||||
if (ownerId) input.ownerId = ownerId;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { parse, getOperationAST, type DocumentNode } from 'graphql';
|
||||
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
||||
import { proboApiRequest } from '../../GenericFunctions';
|
||||
|
||||
@@ -16,8 +15,7 @@ export const description: INodeProperties[] = [
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
description:
|
||||
'The complete GraphQL operation including operation name and variable declarations (e.g., "query GetUser($userId: ID!) { node(id: $userId) { id } }" or "mutation UpdateUser($input: UpdateUserInput!) { updateUser(input: $input) { id } }")',
|
||||
description: 'The complete GraphQL operation including operation name and variable declarations (e.g., "query GetUser($userId: ID!) { node(ID: $userId) { ID } }" or "mutation UpdateUser($input: UpdateUserInput!) { updateUser(input: $input) { ID } }")',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
@@ -41,23 +39,17 @@ export async function execute(
|
||||
const query = this.getNodeParameter('query', itemIndex) as string;
|
||||
const variablesParam = this.getNodeParameter('variables', itemIndex) as string;
|
||||
|
||||
let document: DocumentNode;
|
||||
try {
|
||||
document = parse(query);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Invalid GraphQL operation: ${error instanceof Error ? error.message : String(error)}`,
|
||||
);
|
||||
// Basic validation: check if query contains a GraphQL operation
|
||||
const trimmedQuery = query.trim();
|
||||
if (!trimmedQuery) {
|
||||
throw new Error('GraphQL query cannot be empty');
|
||||
}
|
||||
|
||||
const operationAST = getOperationAST(document);
|
||||
if (!operationAST) {
|
||||
throw new Error('GraphQL operation must contain a query, mutation, or subscription');
|
||||
}
|
||||
|
||||
if (!operationAST.name) {
|
||||
// Check for operation type (query, mutation, or subscription)
|
||||
const operationMatch = trimmedQuery.match(/^\s*(query|mutation|subscription)\s+(\w+)/i);
|
||||
if (!operationMatch) {
|
||||
throw new Error(
|
||||
'GraphQL operation must have a name (e.g., "query GetUser { ... }" or "mutation UpdateUser { ... }")',
|
||||
'GraphQL operation must start with "query", "mutation", or "subscription" followed by an operation name (e.g., "query GetUser { ... }" or "mutation UpdateUser { ... }")',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -67,7 +59,7 @@ export async function execute(
|
||||
variables =
|
||||
typeof variablesParam === 'string' ? JSON.parse(variablesParam) : variablesParam;
|
||||
} catch (error) {
|
||||
throw new Error(`Invalid JSON in Variables: ${error}`);
|
||||
throw new Error(`Invalid JSON in Variables: ${error instanceof Error ? error.message : String(error)}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ export const description: INodeProperties[] = [
|
||||
name: 'Execute',
|
||||
value: 'execute',
|
||||
description: 'Execute a GraphQL query or mutation',
|
||||
action: 'Execute GraphQL',
|
||||
action: 'Execute graphql',
|
||||
},
|
||||
],
|
||||
default: 'execute',
|
||||
|
||||
@@ -36,10 +36,10 @@ export const description: INodeProperties[] = [
|
||||
action: 'Get a framework',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
description: 'Get all frameworks',
|
||||
action: 'Get all frameworks',
|
||||
description: 'Get many frameworks',
|
||||
action: 'Get many frameworks',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
|
||||
@@ -66,7 +66,7 @@ export async function execute(
|
||||
}
|
||||
`;
|
||||
|
||||
const input: Record<string, any> = { id };
|
||||
const input: Record<string, string> = { id };
|
||||
if (name) input.name = name;
|
||||
if (description) input.description = description;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as measure from './measure';
|
||||
|
||||
export interface ResourceModule {
|
||||
description: INodeProperties[];
|
||||
[key: string]: OperationModule | INodeProperties[] | any;
|
||||
[key: string]: OperationModule | INodeProperties[];
|
||||
}
|
||||
|
||||
export interface OperationModule {
|
||||
|
||||
@@ -36,10 +36,10 @@ export const description: INodeProperties[] = [
|
||||
action: 'Get a measure',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
description: 'Get all measures',
|
||||
action: 'Get all measures',
|
||||
description: 'Get many measures',
|
||||
action: 'Get many measures',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
|
||||
@@ -83,7 +83,7 @@ export const description: INodeProperties[] = [
|
||||
value: 'IMPLEMENTED',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
default: 'NOT_STARTED',
|
||||
description: 'The state of the measure',
|
||||
},
|
||||
];
|
||||
@@ -114,7 +114,7 @@ export async function execute(
|
||||
}
|
||||
`;
|
||||
|
||||
const input: Record<string, any> = { id };
|
||||
const input: Record<string, string> = { id };
|
||||
if (name) input.name = name;
|
||||
if (description) input.description = description;
|
||||
if (category) input.category = category;
|
||||
|
||||
Reference in New Issue
Block a user