Skip to content

Commit

Permalink
feat: Create NPM node (#6177)
Browse files Browse the repository at this point in the history
  • Loading branch information
netroy authored May 10, 2023
1 parent 80831cd commit f3bc6f1
Show file tree
Hide file tree
Showing 12 changed files with 566 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/NodeExecuteFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ function convertN8nRequestToAxios(n8nRequest: IHttpRequestOptions): AxiosRequest
// if there is a body and it's empty (does not have properties),
// make sure not to send anything in it as some services fail when
// sending GET request with empty body.
if (typeof body === 'object' && !isObjectEmpty(body)) {
if (typeof body === 'string' || (typeof body === 'object' && !isObjectEmpty(body))) {
axiosRequest.data = body;
}
}
Expand Down
46 changes: 46 additions & 0 deletions packages/nodes-base/credentials/NpmApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type {
IAuthenticateGeneric,
ICredentialTestRequest,
ICredentialType,
INodeProperties,
} from 'n8n-workflow';

export class NpmApi implements ICredentialType {
name = 'npmApi';

displayName = 'Npm API';

documentationUrl = 'npm';

properties: INodeProperties[] = [
{
displayName: 'Access Token',
name: 'accessToken',
type: 'string',
typeOptions: { password: true },
default: '',
},
{
displayName: 'Registry Url',
name: 'registryUrl',
type: 'string',
default: 'https://registry.npmjs.org',
},
];

authenticate: IAuthenticateGeneric = {
type: 'generic',
properties: {
headers: {
Authorization: '=Bearer {{$credentials.accessToken}}',
},
},
};

test: ICredentialTestRequest = {
request: {
baseURL: '={{$credentials.registryUrl}}',
url: '/-/whoami',
},
};
}
94 changes: 94 additions & 0 deletions packages/nodes-base/nodes/Npm/DistTagDescription.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import type { INodeProperties } from 'n8n-workflow';

export const distTagOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
default: 'getMany',
displayOptions: {
show: {
resource: ['distTag'],
},
},

options: [
{
name: 'Get All',
value: 'getMany',
action: 'Returns all the dist-tags for a package',
description: 'Returns all the dist-tags for a package',
routing: {
request: {
method: 'GET',
url: '=/-/package/{{ encodeURIComponent($parameter.packageName) }}/dist-tags',
},
},
},
{
name: 'Update',
value: 'update',
action: 'Update a the dist-tags for a package',
description: 'Update a the dist-tags for a package',
routing: {
request: {
method: 'PUT',
url: '=/-/package/{{ encodeURIComponent($parameter.packageName) }}/dist-tags/{{ encodeURIComponent($parameter.distTagName) }}',
},
send: {
preSend: [
async function (this, requestOptions) {
requestOptions.headers!['content-type'] = 'application/x-www-form-urlencoded';
requestOptions.body = this.getNodeParameter('packageVersion');
return requestOptions;
},
],
},
},
},
],
},
];

export const distTagFields: INodeProperties[] = [
{
displayName: 'Package Name',
name: 'packageName',
type: 'string',
required: true,
default: '',
displayOptions: {
show: {
resource: ['distTag'],
operation: ['getMany', 'update'],
},
},
},
{
displayName: 'Package Version',
name: 'packageVersion',
type: 'string',
required: true,
default: '',
displayOptions: {
show: {
resource: ['distTag'],
operation: ['update'],
},
},
},
{
displayName: 'Distribution Tag Name',
name: 'distTagName',
type: 'string',
required: true,
default: 'latest',
displayOptions: {
show: {
resource: ['distTag'],
operation: ['update'],
},
},
},
];
19 changes: 19 additions & 0 deletions packages/nodes-base/nodes/Npm/Npm.node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"node": "n8n-nodes-base.npm",
"nodeVersion": "1.0",
"codexVersion": "1.0",
"categories": ["Development"],
"resources": {
"credentialDocumentation": [
{
"url": "https://docs.n8n.io/credentials/npm"
}
],
"primaryDocumentation": [
{
"url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.npm/"
}
],
"generic": []
}
}
54 changes: 54 additions & 0 deletions packages/nodes-base/nodes/Npm/Npm.node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type { INodeType, INodeTypeDescription } from 'n8n-workflow';
import { packageFields, packageOperations } from './PackageDescription';
import { distTagFields, distTagOperations } from './DistTagDescription';

export class Npm implements INodeType {
description: INodeTypeDescription = {
displayName: 'Npm',
name: 'npm',
icon: 'file:npm.svg',
group: ['input'],
version: 1,
subtitle: '={{ $parameter["operation"] + ": " + $parameter["resource"] }}',
description: 'Consume NPM registry API',
defaults: {
name: 'npm',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'npmApi',
required: false,
},
],
requestDefaults: {
baseURL: '={{ $credentials.registryUrl }}',
},
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Package',
value: 'package',
},
{
name: 'Distribution Tag',
value: 'distTag',
},
],
default: 'package',
},

...packageOperations,
...packageFields,

...distTagOperations,
...distTagFields,
],
};
}
Loading

0 comments on commit f3bc6f1

Please sign in to comment.