-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(PostBin Node): Add PostBin node (#3236)
* π§ Initial progress on PostBin node. * β¨ Implemented Bin and Request operations for PostBin node. * π§ Reworked the node in the declarative way. * π§ PosBin node refactoring after reworking it. * β¨ Implemented Bin id parsing in PostBin node. Done some final refactoring and documentation. * β‘ Improvements * β‘ Add comments * πUpdating the PostBin node based on the product review * πUpdating PostBin node Bin ID validation logic * β‘ Small improvements * β‘ Transform the bin requests and add additional properties Co-authored-by: ricardo <ricardoespinoza105@gmail.com> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
- Loading branch information
1 parent
5f3bed3
commit 06c407d
Showing
8 changed files
with
455 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { | ||
INodeProperties | ||
} from 'n8n-workflow'; | ||
|
||
import { | ||
buildBinAPIURL, | ||
transformBinReponse, | ||
} from './GenericFunctions'; | ||
|
||
|
||
// Operations for the `Bin` resource: | ||
export const binOperations: INodeProperties[] = [ | ||
{ | ||
displayName: 'Operation', | ||
name: 'operation', | ||
type: 'options', | ||
displayOptions: { | ||
show: { | ||
resource: [ | ||
'bin', | ||
], | ||
}, | ||
}, | ||
options: [ | ||
{ | ||
name: 'Create', | ||
value: 'create', | ||
description: 'Create bin', | ||
routing: { | ||
request: { | ||
method: 'POST', | ||
url: '/developers/postbin/api/bin', | ||
}, | ||
output: { | ||
postReceive: [ | ||
transformBinReponse, | ||
], | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: 'Get', | ||
value: 'get', | ||
description: 'Get a bin', | ||
routing: { | ||
request: { | ||
method: 'GET', | ||
}, | ||
output: { | ||
postReceive: [ | ||
transformBinReponse, | ||
], | ||
}, | ||
send: { | ||
preSend: [ | ||
// Parse binId before sending to make sure it's in the right format | ||
buildBinAPIURL, | ||
], | ||
}, | ||
}, | ||
}, | ||
{ | ||
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, | ||
], | ||
}, | ||
}, | ||
}, | ||
], | ||
default: 'create', | ||
}, | ||
]; | ||
|
||
// Properties of the `Bin` resource | ||
export const binFields: INodeProperties[] = [ | ||
{ | ||
name: 'binId', | ||
displayName: 'Bin ID', | ||
type: 'string', | ||
default: '', | ||
required: true, | ||
displayOptions: { | ||
show: { | ||
resource: [ | ||
'bin', | ||
], | ||
operation: [ | ||
'get', | ||
'delete', | ||
], | ||
}, | ||
}, | ||
description: 'Unique identifier for each bin', | ||
}, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import { | ||
IExecuteSingleFunctions, | ||
IHttpRequestOptions, | ||
IN8nHttpFullResponse, | ||
INodeExecutionData, | ||
NodeApiError, | ||
} from 'n8n-workflow'; | ||
|
||
// Regular expressions used to extract binId from parameter value | ||
const BIN_ID_REGEX = /\b\d{13}-\d{13}\b/g; | ||
|
||
/** | ||
* 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 | ||
* @param {IExecuteSingleFunctions} this | ||
* @param {IHttpRequestOptions} requestOptions | ||
* @returns {Promise<IHttpRequestOptions>} requestOptions | ||
*/ | ||
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 = `/developers/postbin/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 | ||
* @param {IExecuteSingleFunctions} this | ||
* @param {IHttpRequestOptions} requestOptions | ||
* @returns {Promise<IHttpRequestOptions>} requestOptions | ||
*/ | ||
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 = `/developers/postbin/${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 | ||
* @param {IExecuteSingleFunctions} this | ||
* @param {IHttpRequestOptions} requestOptions | ||
* @returns {Promise<IHttpRequestOptions>} requestOptions | ||
*/ | ||
export async function buildRequestURL(this: IExecuteSingleFunctions, requestOptions: IHttpRequestOptions): Promise<IHttpRequestOptions> { | ||
const reqId = this.getNodeParameter('requestId', 'shift') as string; | ||
const binId = parseBinId(this); | ||
|
||
requestOptions.url = `/developers/postbin/api/bin/${binId}/req/${reqId}`; | ||
return requestOptions; | ||
} | ||
|
||
/** | ||
* 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>'.` | ||
* | ||
* @param {IExecuteSingleFunctions} this | ||
* @param {IHttpRequestOptions} requestOptions | ||
* @returns {Promise<IHttpRequestOptions>} requestOptions | ||
*/ | ||
function parseBinId(context: IExecuteSingleFunctions) { | ||
const binId = context.getNodeParameter('binId') as string; | ||
// Test if the Bin id is in the expected format | ||
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, | ||
}); | ||
} | ||
|
||
/** | ||
* Converts the bin response data and adds additional properties | ||
* | ||
* @param {IExecuteSingleFunctions} this | ||
* @param {INodeExecutionData} items[] | ||
* @param {IN8nHttpFullResponse} response | ||
* @returns {Promise<INodeExecutionData[]>} | ||
*/ | ||
export async function transformBinReponse(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.toptal.com/developers/postbin/' + item.json.binId, | ||
'viewUrl': 'https://www.toptal.com/developers/postbin/b/' + item.json.binId, | ||
}); | ||
return items; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"node": "n8n-nodes-base.postbin", | ||
"nodeVersion": "1.0", | ||
"codexVersion": "1.0", | ||
"categories": [ | ||
"Development", | ||
"Data & Storage" | ||
], | ||
"resources": { | ||
"primaryDocumentation": [ | ||
{ | ||
"url": "https://docs.n8n.io/nodes/n8n-nodes-base.postbin/" | ||
} | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { | ||
INodeType, | ||
INodeTypeDescription | ||
} 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', | ||
color: '#4dc0b5', | ||
}, | ||
inputs: ['main'], | ||
outputs: ['main'], | ||
credentials: [], | ||
requestDefaults: { | ||
baseURL: 'https://www.toptal.com', | ||
}, | ||
properties: [ | ||
{ | ||
displayName: 'Resource', | ||
name: 'resource', | ||
type: 'options', | ||
options: [ | ||
{ | ||
name: 'Bin', | ||
value: 'bin', | ||
}, | ||
{ | ||
name: 'Request', | ||
value: 'request', | ||
}, | ||
], | ||
default: 'bin', | ||
required: true, | ||
}, | ||
...binOperations, | ||
...binFields, | ||
...requestOperations, | ||
...requestFields, | ||
], | ||
}; | ||
} |
Oops, something went wrong.