verdaccio-plugin-community-nodes
Version:
plugin for n8n community nodes
137 lines (128 loc) • 7.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _semver = _interopRequireDefault(require("semver"));
var _axios = _interopRequireDefault(require("axios"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const PLUGIN_NAME = 'verdaccio-plugin-community-nodes';
class VerdaccioMiddlewarePlugin {
constructor(config, options) {
_defineProperty(this, "config", void 0);
_defineProperty(this, "parsedConfig", void 0);
_defineProperty(this, "logger", void 0);
_defineProperty(this, "httpClient", _axios.default.create({
timeout: 5000,
headers: {
'User-Agent': `${PLUGIN_NAME}/0.1.0`
}
}));
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 = _objectSpread(_objectSpread({}, config), {}, {
enabled,
environment,
apiUrl
});
this.logger.info(`${PLUGIN_NAME} 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;
const requestedVersion = this.getRequestedVersion(passedPackage);
try {
var _response$data, _response$data$data;
// Construct URL with proper encoding
const encodedPackageName = encodeURIComponent(name);
const url = `${this.parsedConfig.apiUrl}?filters[packageName][$eq]=${encodedPackageName}`;
this.logger.debug(`${PLUGIN_NAME}: Fetching data for ${name} from ${url}`);
const response = await this.httpClient.get(url);
// Validate response data
if (!((_response$data = response.data) === null || _response$data === void 0 ? void 0 : (_response$data$data = _response$data.data) === null || _response$data$data === void 0 ? void 0 : _response$data$data.length)) {
this.logger.debug(`${PLUGIN_NAME}: No community node found for ${name}`);
return passedPackage;
}
const nodeData = response.data.data[0];
const nodeVersions = nodeData.attributes.nodeVersions;
if (!(nodeVersions === null || nodeVersions === void 0 ? void 0 : nodeVersions.length)) {
this.logger.debug(`${PLUGIN_NAME}: No versions found for ${name}`);
return passedPackage;
}
// Check if requested version exists
if (nodeVersions.some(v => v.npmVersion === requestedVersion)) {
this.logger.debug(`${PLUGIN_NAME}: Requested version ${requestedVersion} exists for ${name}`);
return passedPackage;
}
// Find newest version using semver for proper version comparison
const sortedVersions = [...nodeVersions].filter(v => _semver.default.valid(v.npmVersion)) // Filter out invalid semver
.sort((a, b) => _semver.default.compare(b.npmVersion, a.npmVersion));
if (!sortedVersions.length) {
this.logger.warn(`${PLUGIN_NAME}: No valid versions found for ${name}`);
return passedPackage;
}
const newestVersion = sortedVersions[0].npmVersion;
this.logger.debug(`${PLUGIN_NAME}: Requested version ${requestedVersion} not found for ${name}, ` + `returning newest version ${newestVersion} instead`);
// Create modified package with only the newest version
return this.createFilteredPackage(passedPackage, newestVersion);
} catch (error) {
if (_axios.default.isAxiosError(error)) {
var _error$response, _error$response2;
this.logger.error(`${PLUGIN_NAME}: API request failed for ${name}: ${error.message}, ` + `status: ${(_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.status}, data: ${JSON.stringify((_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data)}`);
} else if (error instanceof Error) {
this.logger.error(`${PLUGIN_NAME}: Error processing data for ${name}: ${error.message}`);
}
throw error;
}
}
createFilteredPackage(pkg, version) {
const modifiedPackage = _objectSpread({}, pkg);
// Only keep the specified version
if (modifiedPackage.versions) {
const versionData = modifiedPackage.versions[version] || {};
modifiedPackage.versions = {
[version]: versionData
};
// Update dist-tags
if (modifiedPackage['dist-tags']) {
modifiedPackage['dist-tags'].latest = version;
}
}
return modifiedPackage;
}
getRequestedVersion(pkg) {
var _pkg$distTags;
return ((_pkg$distTags = pkg['dist-tags']) === null || _pkg$distTags === void 0 ? void 0 : _pkg$distTags.latest) || 'latest';
}
}
exports.default = VerdaccioMiddlewarePlugin;