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,91 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
import { buildBinAPIURL, transformBinResponse } from './GenericFunctions';
|
||||
|
||||
// Operations for the `Bin` resource:
|
||||
export const binOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['bin'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
description: 'Create bin',
|
||||
routing: {
|
||||
request: {
|
||||
method: 'POST',
|
||||
url: '/api/bin',
|
||||
},
|
||||
output: {
|
||||
postReceive: [transformBinResponse],
|
||||
},
|
||||
},
|
||||
action: 'Create a bin',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
description: 'Get a bin',
|
||||
routing: {
|
||||
request: {
|
||||
method: 'GET',
|
||||
},
|
||||
output: {
|
||||
postReceive: [transformBinResponse],
|
||||
},
|
||||
send: {
|
||||
preSend: [
|
||||
// Parse binId before sending to make sure it's in the right format
|
||||
buildBinAPIURL,
|
||||
],
|
||||
},
|
||||
},
|
||||
action: 'Get a bin',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
description: 'Delete a bin',
|
||||
routing: {
|
||||
request: {
|
||||
method: 'DELETE',
|
||||
},
|
||||
send: {
|
||||
preSend: [
|
||||
// Parse binId before sending to make sure it's in the right format
|
||||
buildBinAPIURL,
|
||||
],
|
||||
},
|
||||
},
|
||||
action: 'Delete a bin',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
// Properties of the `Bin` resource
|
||||
export const binFields: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Bin ID',
|
||||
name: 'binId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['bin'],
|
||||
operation: ['get', 'delete'],
|
||||
},
|
||||
},
|
||||
description: 'Unique identifier for each bin',
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,115 @@
|
||||
import type {
|
||||
IExecuteSingleFunctions,
|
||||
IHttpRequestOptions,
|
||||
IN8nHttpFullResponse,
|
||||
INodeExecutionData,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
|
||||
// Regular expressions used to extract binId from parameter value
|
||||
const BIN_ID_REGEX = /\b\d{13}-\d{13}\b/g;
|
||||
|
||||
/**
|
||||
* Extracts the PostBin Bin Id from the specified string.
|
||||
* This method should be able to extract bin Id from the
|
||||
* PostBin URL or from the string in the following format:
|
||||
* `Bin '<binId>'.`
|
||||
*
|
||||
*/
|
||||
function parseBinId(context: IExecuteSingleFunctions) {
|
||||
const binId = context.getNodeParameter('binId') as string;
|
||||
// Test if the Bin id is in the expected format
|
||||
BIN_ID_REGEX.lastIndex = 0;
|
||||
const idMatch = BIN_ID_REGEX.exec(binId);
|
||||
|
||||
// Return what is matched
|
||||
if (idMatch) {
|
||||
return idMatch[0];
|
||||
}
|
||||
|
||||
// If it's not recognized, error out
|
||||
throw new NodeApiError(
|
||||
context.getNode(),
|
||||
{},
|
||||
{
|
||||
message: 'Bin ID format is not valid',
|
||||
description: 'Please check the provided Bin ID and try again.',
|
||||
parseXml: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates correctly-formatted PostBin API URL based on the entered binId.
|
||||
* This function makes sure binId is in the expected format by parsing it
|
||||
* from current node parameter value.
|
||||
*
|
||||
*/
|
||||
export async function buildBinAPIURL(
|
||||
this: IExecuteSingleFunctions,
|
||||
requestOptions: IHttpRequestOptions,
|
||||
): Promise<IHttpRequestOptions> {
|
||||
const binId = parseBinId(this);
|
||||
// Assemble the PostBin API URL and put it back to requestOptions
|
||||
requestOptions.url = `/api/bin/${binId}`;
|
||||
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates correctly-formatted PostBin Bin test URL based on the entered binId.
|
||||
* This function makes sure binId is in the expected format by parsing it
|
||||
* from current node parameter value.
|
||||
*
|
||||
*/
|
||||
export async function buildBinTestURL(
|
||||
this: IExecuteSingleFunctions,
|
||||
requestOptions: IHttpRequestOptions,
|
||||
): Promise<IHttpRequestOptions> {
|
||||
const binId = parseBinId(this);
|
||||
|
||||
// Assemble the PostBin API URL and put it back to requestOptions
|
||||
requestOptions.url = `/${binId}`;
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates correctly-formatted PostBin API URL based on the entered binId and reqId.
|
||||
* This function makes sure binId is in the expected format by parsing it
|
||||
* from current node parameter value.
|
||||
*
|
||||
*/
|
||||
export async function buildRequestURL(
|
||||
this: IExecuteSingleFunctions,
|
||||
requestOptions: IHttpRequestOptions,
|
||||
): Promise<IHttpRequestOptions> {
|
||||
const reqId = this.getNodeParameter('requestId', 'shift') as string;
|
||||
const binId = parseBinId(this);
|
||||
|
||||
requestOptions.url = `/api/bin/${binId}/req/${reqId}`;
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the bin response data and adds additional properties
|
||||
*
|
||||
*/
|
||||
export async function transformBinResponse(
|
||||
this: IExecuteSingleFunctions,
|
||||
items: INodeExecutionData[],
|
||||
_response: IN8nHttpFullResponse,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
items.forEach(
|
||||
(item) =>
|
||||
(item.json = {
|
||||
binId: item.json.binId,
|
||||
nowTimestamp: item.json.now,
|
||||
nowIso: new Date(item.json.now as string).toISOString(),
|
||||
expiresTimestamp: item.json.expires,
|
||||
expiresIso: new Date(item.json.expires as string).toISOString(),
|
||||
requestUrl: 'https://www.postb.in/' + (item.json.binId as string),
|
||||
viewUrl: 'https://www.postb.in/b/' + (item.json.binId as string),
|
||||
}),
|
||||
);
|
||||
return items;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"node": "n8n-nodes-base.postbin",
|
||||
"nodeVersion": "1.0",
|
||||
"codexVersion": "1.0",
|
||||
"categories": ["Development", "Data & Storage"],
|
||||
"resources": {
|
||||
"primaryDocumentation": [
|
||||
{
|
||||
"url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.postbin/"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import type { INodeType, INodeTypeDescription } from 'n8n-workflow';
|
||||
import { NodeConnectionTypes } from 'n8n-workflow';
|
||||
|
||||
import { binFields, binOperations } from './BinDescription';
|
||||
import { requestFields, requestOperations } from './RequestDescription';
|
||||
|
||||
export class PostBin implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'PostBin',
|
||||
name: 'postBin',
|
||||
icon: 'file:postbin.svg',
|
||||
group: ['transform'],
|
||||
version: 1,
|
||||
subtitle: '={{ $parameter["operation"] + ": " + $parameter["resource"] }}',
|
||||
description: 'Consume PostBin API',
|
||||
defaults: {
|
||||
name: 'PostBin',
|
||||
},
|
||||
usableAsTool: true,
|
||||
inputs: [NodeConnectionTypes.Main],
|
||||
outputs: [NodeConnectionTypes.Main],
|
||||
credentials: [],
|
||||
requestDefaults: {
|
||||
baseURL: 'https://www.postb.in',
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Resource',
|
||||
name: 'resource',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
options: [
|
||||
{
|
||||
name: 'Bin',
|
||||
value: 'bin',
|
||||
},
|
||||
{
|
||||
name: 'Request',
|
||||
value: 'request',
|
||||
},
|
||||
],
|
||||
default: 'bin',
|
||||
required: true,
|
||||
},
|
||||
...binOperations,
|
||||
...binFields,
|
||||
...requestOperations,
|
||||
...requestFields,
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
import { buildBinTestURL, buildRequestURL } from './GenericFunctions';
|
||||
|
||||
// Operations for the `Request` resource
|
||||
export const requestOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['request'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
description: 'Get a request',
|
||||
routing: {
|
||||
request: {
|
||||
method: 'GET',
|
||||
url: '=/api/bin/{{$parameter["binId"]}}/req/{{$parameter["requestId"]}}',
|
||||
},
|
||||
send: {
|
||||
preSend: [
|
||||
// Parse binId before sending to make sure it's in the right format
|
||||
buildRequestURL,
|
||||
],
|
||||
},
|
||||
},
|
||||
action: 'Get a request',
|
||||
},
|
||||
{
|
||||
name: 'Remove First',
|
||||
value: 'removeFirst',
|
||||
description: 'Remove the first request from bin',
|
||||
routing: {
|
||||
request: {
|
||||
method: 'GET',
|
||||
url: '=/api/bin/{{$parameter["binId"]}}/req/shift',
|
||||
},
|
||||
send: {
|
||||
preSend: [
|
||||
// Parse binId before sending to make sure it's in the right format
|
||||
buildRequestURL,
|
||||
],
|
||||
},
|
||||
},
|
||||
action: 'Remove First a request',
|
||||
},
|
||||
{
|
||||
name: 'Send',
|
||||
value: 'send',
|
||||
description: 'Send a test request to the bin',
|
||||
routing: {
|
||||
request: {
|
||||
method: 'POST',
|
||||
},
|
||||
send: {
|
||||
preSend: [
|
||||
// Parse binId before sending to make sure it's in the right format
|
||||
buildBinTestURL,
|
||||
],
|
||||
},
|
||||
output: {
|
||||
postReceive: [
|
||||
{
|
||||
type: 'set',
|
||||
properties: {
|
||||
value: '={{ { "requestId": $response.body } }}',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
action: 'Send a request',
|
||||
},
|
||||
],
|
||||
default: 'get',
|
||||
},
|
||||
];
|
||||
|
||||
// Properties of the `Request` resource
|
||||
export const requestFields: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Bin ID',
|
||||
name: 'binId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['request'],
|
||||
operation: ['get', 'removeFirst', 'send'],
|
||||
},
|
||||
},
|
||||
description: 'Unique identifier for each bin',
|
||||
},
|
||||
{
|
||||
displayName: 'Bin Content',
|
||||
name: 'binContent',
|
||||
type: 'string',
|
||||
default: '',
|
||||
typeOptions: {
|
||||
rows: 5,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['request'],
|
||||
operation: ['send'],
|
||||
},
|
||||
},
|
||||
// Content is sent in the body of POST requests
|
||||
routing: {
|
||||
send: {
|
||||
property: 'content',
|
||||
type: 'body',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Request ID',
|
||||
name: 'requestId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['request'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
description: 'Unique identifier for each request',
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"binId": {
|
||||
"type": "string"
|
||||
},
|
||||
"expiresIso": {
|
||||
"type": "string"
|
||||
},
|
||||
"expiresTimestamp": {
|
||||
"type": "integer"
|
||||
},
|
||||
"nowIso": {
|
||||
"type": "string"
|
||||
},
|
||||
"nowTimestamp": {
|
||||
"type": "integer"
|
||||
},
|
||||
"requestUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"viewUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"version": 1
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"binId": {
|
||||
"type": "string"
|
||||
},
|
||||
"expiresIso": {
|
||||
"type": "string"
|
||||
},
|
||||
"expiresTimestamp": {
|
||||
"type": "integer"
|
||||
},
|
||||
"nowIso": {
|
||||
"type": "string"
|
||||
},
|
||||
"nowTimestamp": {
|
||||
"type": "integer"
|
||||
},
|
||||
"requestUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"viewUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"version": 1
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"requestId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"version": 1
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc.--><path fill="#4dc0b5" d="M352 256c0 22.2-1.2 43.6-3.3 64H163.3c-2.1-20.4-4.2-41.8-4.2-64s2.1-43.6 4.2-64h185.4c2.1 20.4 3.3 41.8 3.3 64m151.9-64c5.3 20.5 8.1 41.9 8.1 64s-2.8 43.5-8.1 64H380.8c2.1-20.6 3.2-42.9 3.2-64 0-22-1.1-43.4-3.2-64zm-10.5-32H376.7c-10-63.86-29.8-117.38-55.3-151.558C399.8 29.09 463.4 85.94 493.4 160m-149.1 0H167.7c6.1-36.4 15.5-68.62 27-94.65 10.5-23.61 22.2-40.74 33.5-51.54C239.4 3.178 248.7 0 256 0s16.6 3.178 27.8 13.81c11.3 10.8 23 27.93 33.5 51.54 11.5 26.03 20.9 58.25 27 94.65m-325.69 0C48.59 85.94 112.2 29.09 190.6 8.442 165.1 42.62 145.3 96.14 135.3 160zm112.59 32c-2.1 20.6-4.1 42-4.1 64 0 21.1 2 43.4 4.1 64H8.065C2.8 299.5 0 278.1 0 256s2.8-43.5 8.065-64zm63.5 254.6c-11.5-26-20.9-58.2-27-94.6h176.6c-6.1 36.4-15.5 68.6-27 94.6-10.5 23.7-22.2 40.8-33.5 51.6-11.2 10.6-20.5 13.8-28.7 13.8-6.4 0-15.7-3.2-26.9-13.8-11.3-10.8-23-27.9-33.5-51.6m-4.1 57C112.2 482.9 48.59 426.1 18.61 352H135.3c10 63.9 29.8 117.4 55.3 151.6m130.8 0c25.5-34.2 45.3-87.7 55.3-151.6h116.7c-30 74.1-93.6 130.9-172 151.6"/></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
Reference in New Issue
Block a user