Fix style

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2025-12-02 14:12:58 +01:00
parent b0e475301a
commit d710f5af73
18 changed files with 71 additions and 52 deletions

View File

@@ -11,7 +11,7 @@ export class ProboApi implements ICredentialType {
displayName = 'Probo API';
icon: Icon = { light: 'file:../icons/probo.svg', dark: 'file:../icons/probo.svg' };
icon: Icon = { light: 'file:../icons/probo-light.svg', dark: 'file:../icons/probo.svg' };
documentationUrl = 'https://www.getprobo.com/docs';

View File

@@ -0,0 +1,24 @@
<svg viewBox="0 0 300 300" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1030_164)">
<rect width="300" height="300" rx="70" fill="#FFFFFF"/>
<g clip-path="url(#clip1_1030_164)">
<rect width="320" height="320" transform="translate(-9.69238 -10)" fill="#FFFFFF"/>
<path d="M238.194 83.0279C274.406 137.651 160.574 258.266 -29.4255 142.266" stroke="#101E1C" stroke-width="42.6667"/>
<path d="M238.194 83.0279C274.406 137.651 160.574 258.266 -29.4255 142.266" stroke="url(#paint0_linear_1030_164)" stroke-width="42.6667"/>
<path d="M220.112 94.3364C226.365 104.327 239.53 107.363 249.515 101.118C259.501 94.873 262.527 81.7113 256.274 71.7206L238.193 83.0285L220.112 94.3364ZM97.9074 324.933L118.61 319.8C87.9762 196.62 115.788 133.041 146.656 105.377C162.52 91.1595 180.159 85.27 194.453 84.9721C209.505 84.6583 217.534 90.218 220.112 94.3364L238.193 83.0285L256.274 71.7206C242.999 50.5115 217.649 41.8122 193.53 42.315C168.652 42.8335 141.327 52.8361 118.165 73.5935C70.9833 115.879 44.5053 198.58 77.2047 330.066L97.9074 324.933Z" fill="#101E1C"/>
</g>
</g>
<defs>
<linearGradient id="paint0_linear_1030_164" x1="216.193" y1="173.319" x2="-18.0923" y2="173.319" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFFFFF" stop-opacity="0"/>
<stop offset="1" stop-color="#FFFFFF"/>
</linearGradient>
<clipPath id="clip0_1030_164">
<rect width="300" height="300" rx="70" fill="white"/>
</clipPath>
<clipPath id="clip1_1030_164">
<rect width="320" height="320" fill="white" transform="translate(-9.69238 -10)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -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) {

View File

@@ -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"]}}',

View File

@@ -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',

View File

@@ -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;

View File

@@ -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',

View File

@@ -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;

View File

@@ -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',

View File

@@ -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;

View File

@@ -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)}`);
}
}

View File

@@ -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',

View File

@@ -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',

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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',

View File

@@ -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;

View File

@@ -11,7 +11,9 @@
"release": "n8n-node release",
"prepublishOnly": "n8n-node prerelease"
},
"author": "Probo Inc",
"author": {
"name": "Probo Inc"
},
"files": [
"dist"
],