import { valid as isValidSemver } from 'semver'; import type { INodeExecutionData, INodeProperties } from 'n8n-workflow'; interface PackageJson { name: string; version: string; description: string; } export const packageOperations: INodeProperties[] = [ { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, default: 'getMetadata', displayOptions: { show: { resource: ['package'], }, }, options: [ { name: 'Get Metadata', value: 'getMetadata', action: 'Returns all the metadata for a package at a specific version', description: 'Returns all the metadata for a package at a specific version', routing: { request: { method: 'GET', url: '=/{{ encodeURIComponent($parameter.packageName) }}/{{ $parameter.packageVersion }}', }, }, }, { name: 'Get Versions', value: 'getVersions', action: 'Returns all the versions for a package', description: 'Returns all the versions for a package', routing: { request: { method: 'GET', url: '=/{{ encodeURIComponent($parameter.packageName) }}', }, output: { postReceive: [ async function (items) { const allVersions: INodeExecutionData[] = []; for (const { json } of items) { const itemVersions = json.time as Record; Object.keys(itemVersions).forEach((version) => { if (isValidSemver(version)) { allVersions.push({ json: { version, published_at: itemVersions[version], }, }); } }); } allVersions.sort( (a, b) => new Date(b.json.published_at as string).getTime() - new Date(a.json.published_at as string).getTime(), ); return allVersions; }, ], }, }, }, { name: 'Search', value: 'search', action: 'Search for packages', description: 'Search for packages', routing: { request: { method: 'GET', url: '/-/v1/search', qs: { text: '={{$parameter.query}}', size: '={{$parameter.limit}}', from: '={{$parameter.offset}}', popularity: 0.99, }, }, output: { postReceive: [ async function (items) { return items.flatMap(({ json }) => (json.objects as Array<{ package: PackageJson }>).map( ({ package: { name, version, description } }) => ({ json: { name, version, description } }) as INodeExecutionData, ), ); }, ], }, }, }, ], }, ]; export const packageFields: INodeProperties[] = [ { displayName: 'Package Name', name: 'packageName', type: 'string', required: true, default: '', displayOptions: { show: { resource: ['package'], operation: ['getMetadata', 'getVersions'], }, }, }, { displayName: 'Package Version', name: 'packageVersion', type: 'string', required: true, default: 'latest', displayOptions: { show: { resource: ['package'], operation: ['getMetadata'], }, }, }, { displayName: 'Query', name: 'query', type: 'string', required: true, displayOptions: { show: { resource: ['package'], operation: ['search'], }, }, default: '', description: 'The query text used to search for packages', }, { displayName: 'Limit', name: 'limit', type: 'number', default: 10, typeOptions: { minValue: 1, maxValue: 100, }, displayOptions: { show: { resource: ['package'], operation: ['search'], }, }, description: 'Max number of results to return', }, { displayName: 'Offset', name: 'offset', type: 'number', default: 0, typeOptions: { minValue: 0, }, displayOptions: { show: { resource: ['package'], operation: ['search'], }, }, description: 'Offset to return results from', }, ];