first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"node": "n8n-nodes-base.peekalink",
|
||||
"nodeVersion": "1.0",
|
||||
"codexVersion": "1.0",
|
||||
"categories": ["Development"],
|
||||
"resources": {
|
||||
"credentialDocumentation": [
|
||||
{
|
||||
"url": "https://docs.n8n.io/integrations/builtin/credentials/peekalink/"
|
||||
}
|
||||
],
|
||||
"primaryDocumentation": [
|
||||
{
|
||||
"url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.peekalink/"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
import {
|
||||
Node,
|
||||
NodeApiError,
|
||||
type IExecuteFunctions,
|
||||
type INodeExecutionData,
|
||||
type INodeTypeDescription,
|
||||
type JsonObject,
|
||||
NodeConnectionTypes,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
export const apiUrl = 'https://api.peekalink.io';
|
||||
|
||||
type Operation = 'preview' | 'isAvailable';
|
||||
|
||||
export class Peekalink extends Node {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'Peekalink',
|
||||
name: 'peekalink',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-class-description-icon-not-svg
|
||||
icon: 'file:peekalink.png',
|
||||
group: ['output'],
|
||||
version: 1,
|
||||
subtitle: '={{$parameter["operation"]',
|
||||
description: 'Consume the Peekalink API',
|
||||
defaults: {
|
||||
name: 'Peekalink',
|
||||
},
|
||||
usableAsTool: true,
|
||||
inputs: [NodeConnectionTypes.Main],
|
||||
outputs: [NodeConnectionTypes.Main],
|
||||
credentials: [
|
||||
{
|
||||
name: 'peekalinkApi',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
options: [
|
||||
{
|
||||
name: 'Is Available',
|
||||
value: 'isAvailable',
|
||||
description: 'Check whether preview for a given link is available',
|
||||
action: 'Check whether the preview for a given link is available',
|
||||
},
|
||||
{
|
||||
name: 'Preview',
|
||||
value: 'preview',
|
||||
description: 'Return the preview for a link',
|
||||
action: 'Return the preview for a link',
|
||||
},
|
||||
],
|
||||
default: 'preview',
|
||||
},
|
||||
{
|
||||
displayName: 'URL',
|
||||
name: 'url',
|
||||
type: 'string',
|
||||
default: '',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
async execute(context: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||
const items = context.getInputData();
|
||||
const operation = context.getNodeParameter('operation', 0) as Operation;
|
||||
const credentials = await context.getCredentials('peekalinkApi');
|
||||
|
||||
const returnData = await Promise.all(
|
||||
items.map(async (_, i) => {
|
||||
try {
|
||||
const link = context.getNodeParameter('url', i) as string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return await context.helpers.request({
|
||||
method: 'POST',
|
||||
uri: operation === 'preview' ? apiUrl : `${apiUrl}/is-available/`,
|
||||
body: { link },
|
||||
headers: { 'X-API-Key': credentials.apiKey },
|
||||
json: true,
|
||||
});
|
||||
} catch (error) {
|
||||
if (context.continueOnFail()) {
|
||||
return { error: error.message };
|
||||
}
|
||||
throw new NodeApiError(context.getNode(), error as JsonObject);
|
||||
}
|
||||
}),
|
||||
);
|
||||
return [context.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,169 @@
|
||||
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
||||
import { NodeConnectionTypes, type WorkflowTestData } from 'n8n-workflow';
|
||||
|
||||
import { apiUrl } from '../Peekalink.node';
|
||||
|
||||
describe('Peekalink Node', () => {
|
||||
const testHarness = new NodeTestHarness();
|
||||
const exampleComPreview = {
|
||||
url: 'https://example.com/',
|
||||
domain: 'example.com',
|
||||
lastUpdated: '2022-11-13T22:43:20.986744Z',
|
||||
nextUpdate: '2022-11-20T22:43:20.982384Z',
|
||||
contentType: 'html',
|
||||
mimeType: 'text/html',
|
||||
size: 648,
|
||||
redirected: false,
|
||||
title: 'Example Domain',
|
||||
description: 'This domain is for use in illustrative examples in documents',
|
||||
name: 'EXAMPLE.COM',
|
||||
trackersDetected: false,
|
||||
};
|
||||
|
||||
const tests: WorkflowTestData[] = [
|
||||
{
|
||||
description: 'should run isAvailable operation',
|
||||
input: {
|
||||
workflowData: {
|
||||
nodes: [
|
||||
{
|
||||
parameters: {},
|
||||
id: '8b7bb389-e4ef-424a-bca1-e7ead60e43eb',
|
||||
name: 'When clicking "Execute Workflow"',
|
||||
type: 'n8n-nodes-base.manualTrigger',
|
||||
typeVersion: 1,
|
||||
position: [740, 380],
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
operation: 'isAvailable',
|
||||
url: 'https://example.com/',
|
||||
},
|
||||
id: '7354367e-39a7-4fc1-8cdd-442f0b0c7b62',
|
||||
name: 'Peekalink',
|
||||
type: 'n8n-nodes-base.peekalink',
|
||||
typeVersion: 1,
|
||||
position: [960, 380],
|
||||
credentials: {
|
||||
peekalinkApi: {
|
||||
id: '1',
|
||||
name: 'peekalink',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
connections: {
|
||||
'When clicking "Execute Workflow"': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'Peekalink',
|
||||
type: NodeConnectionTypes.Main,
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
nodeData: {
|
||||
Peekalink: [
|
||||
[
|
||||
{
|
||||
json: {
|
||||
isAvailable: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
nock: {
|
||||
baseUrl: apiUrl,
|
||||
mocks: [
|
||||
{
|
||||
method: 'post',
|
||||
path: '/is-available/',
|
||||
statusCode: 200,
|
||||
responseBody: { isAvailable: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
description: 'should run preview operation',
|
||||
input: {
|
||||
workflowData: {
|
||||
nodes: [
|
||||
{
|
||||
parameters: {},
|
||||
id: '8b7bb389-e4ef-424a-bca1-e7ead60e43eb',
|
||||
name: 'When clicking "Execute Workflow"',
|
||||
type: 'n8n-nodes-base.manualTrigger',
|
||||
typeVersion: 1,
|
||||
position: [740, 380],
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
operation: 'preview',
|
||||
url: 'https://example.com/',
|
||||
},
|
||||
id: '7354367e-39a7-4fc1-8cdd-442f0b0c7b62',
|
||||
name: 'Peekalink',
|
||||
type: 'n8n-nodes-base.peekalink',
|
||||
typeVersion: 1,
|
||||
position: [960, 380],
|
||||
credentials: {
|
||||
peekalinkApi: {
|
||||
id: '1',
|
||||
name: 'peekalink',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
connections: {
|
||||
'When clicking "Execute Workflow"': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'Peekalink',
|
||||
type: NodeConnectionTypes.Main,
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
nodeData: {
|
||||
Peekalink: [
|
||||
[
|
||||
{
|
||||
json: exampleComPreview,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
nock: {
|
||||
baseUrl: apiUrl,
|
||||
mocks: [
|
||||
{
|
||||
method: 'post',
|
||||
path: '/',
|
||||
statusCode: 200,
|
||||
responseBody: exampleComPreview,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
for (const testData of tests) {
|
||||
testHarness.setupTest(testData);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user