UNPKG

verdaccio-plugin-community-nodes

Version:
147 lines 6.99 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const semver_1 = __importDefault(require("semver")); const PLUGIN_NAME = 'verdaccio-plugin-community-nodes'; const PLUGIN_VERSION = '0.2.6'; class VerdaccioMiddlewarePlugin { config; parsedConfig; logger; fetchOptions = { headers: { 'User-Agent': `${PLUGIN_NAME}/${PLUGIN_VERSION}` } }; constructor(config, options) { this.config = config; this.logger = options.logger; // Parse and validate configuration with defaults const enabled = typeof config.enabled === 'string' ? config.enabled.toLowerCase() === 'true' : !!config.enabled; const environment = (config.environment || 'staging').toLowerCase(); // Determine API URL based on environment, but only if not provided in config const apiUrl = this.config.apiUrl || (environment === 'production' ? 'https://api.n8n.io/api/community-nodes' : 'https://api-staging.n8n.io/api/community-nodes'); this.parsedConfig = { ...config, enabled, environment, apiUrl }; this.logger.info(`${PLUGIN_NAME}@${PLUGIN_VERSION} initialized with config: ${JSON.stringify({ enabled: this.parsedConfig.enabled, environment: this.parsedConfig.environment })}`); } async filter_metadata(passedPackage) { if (!this.parsedConfig.enabled) { this.logger.debug(`${PLUGIN_NAME} is disabled, skipping filter_metadata for ${passedPackage.name}`); return passedPackage; } try { return await this.checkPackageVersions(passedPackage); } catch (error) { if (error instanceof Error) { this.logger.error(`${PLUGIN_NAME} error checking package ${passedPackage.name}: ${error.message}`); } else { this.logger.error(`${PLUGIN_NAME} error checking package ${passedPackage.name}: ${String(error)}`); } return passedPackage; } } async checkPackageVersions(passedPackage) { const { name } = passedPackage; try { // Construct URL with proper encoding const encodedPackageName = encodeURIComponent(name); let url = `${this.parsedConfig.apiUrl}?filters[packageName][$eq]=${encodedPackageName}&filters[isPublished][$in][0]=true`; // Add unpublished filter for staging environment if (this.parsedConfig.environment === 'staging') { url += '&filters[isPublished][$in][1]=false'; } this.logger.debug(`${PLUGIN_NAME}: Fetching data for ${name} from ${url}`); const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 5000); try { const response = await fetch(url, { ...this.fetchOptions, signal: controller.signal }); if (!response.ok) { const errorText = await response.text().catch(() => 'Unable to read error response'); throw new Error(`HTTP ${response.status}: ${errorText}`); } const data = await response.json(); // Validate response data if (!data?.data?.length) { this.logger.debug(`${PLUGIN_NAME}: No community node found for ${name}`); return passedPackage; } const nodeData = data.data[0]; const nodeVersions = nodeData.attributes.nodeVersions; if (!nodeVersions?.length) { this.logger.debug(`${PLUGIN_NAME}: No versions found for ${name}`); return passedPackage; } // Filter and sort approved versions using semver const approvedVersions = [...nodeVersions] .filter(v => semver_1.default.valid(v.npmVersion)) // Filter out invalid semver .sort((a, b) => semver_1.default.compare(b.npmVersion, a.npmVersion)); if (!approvedVersions.length) { this.logger.warn(`${PLUGIN_NAME}: No valid approved versions found for ${name}`); return passedPackage; } // Filter to only versions that exist in the package const availableApprovedVersions = approvedVersions.filter(v => passedPackage.versions && passedPackage.versions[v.npmVersion]); if (!availableApprovedVersions.length) { this.logger.warn(`${PLUGIN_NAME}: No approved versions are available in registry for ${name}`); return passedPackage; } // Return package with only approved versions const approvedVersionList = availableApprovedVersions.map(v => v.npmVersion).join(', '); this.logger.debug(`${PLUGIN_NAME}: Filtering ${name} to only approved versions: ${approvedVersionList}`); return this.createFilteredPackage(passedPackage, availableApprovedVersions); } finally { clearTimeout(timeoutId); } } catch (error) { if (error instanceof Error) { if (error.name === 'AbortError') { this.logger.error(`${PLUGIN_NAME}: Request timeout for ${name}`); } else { this.logger.error(`${PLUGIN_NAME}: API request failed for ${name}: ${error.message}`); } } else { this.logger.error(`${PLUGIN_NAME}: Unknown error for ${name}: ${String(error)}`); } throw error; } } createFilteredPackage(pkg, approvedVersions) { const modifiedPackage = { ...pkg }; // Only keep the approved versions if (modifiedPackage.versions) { const filteredVersions = {}; for (const approvedVersion of approvedVersions) { const version = approvedVersion.npmVersion; if (modifiedPackage.versions[version]) { filteredVersions[version] = modifiedPackage.versions[version]; } } modifiedPackage.versions = filteredVersions; // Update dist-tags to point to the newest approved version if (modifiedPackage['dist-tags'] && approvedVersions.length > 0) { modifiedPackage['dist-tags'].latest = approvedVersions[0].npmVersion; } } return modifiedPackage; } } exports.default = VerdaccioMiddlewarePlugin; //# sourceMappingURL=index.js.map