MCPcopy Create free account
hub / github.com/github/awesome-copilot / validateExternalPlugins

Function validateExternalPlugins

eng/external-plugin-validation.mjs:356–396  ·  view source on GitHub ↗
(plugins, options = {})

Source from the content-addressed store, hash-verified

354}
355
356export function validateExternalPlugins(plugins, options = {}) {
357 const policy = resolvePolicy(options.policy ?? options);
358 const errors = [];
359 const warnings = [];
360 const localNames = new Map(
361 (options.localPluginNames ?? []).map((name) => [String(name).toLowerCase(), String(name)])
362 );
363 const seenExternalNames = new Map();
364
365 if (!Array.isArray(plugins)) {
366 return {
367 errors: ["external.json must contain an array"],
368 warnings,
369 };
370 }
371
372 plugins.forEach((plugin, index) => {
373 const result = validateExternalPlugin(plugin, index, { policy });
374 errors.push(...result.errors);
375 warnings.push(...result.warnings);
376
377 if (!isNonEmptyString(plugin?.name)) {
378 return;
379 }
380
381 const normalizedName = plugin.name.toLowerCase();
382 const duplicateIndex = seenExternalNames.get(normalizedName);
383 if (duplicateIndex !== undefined) {
384 errors.push(`external.json[${index}]: duplicate plugin name "${plugin.name}" already used by external.json[${duplicateIndex}]`);
385 } else {
386 seenExternalNames.set(normalizedName, index);
387 }
388
389 const localDuplicate = localNames.get(normalizedName);
390 if (localDuplicate) {
391 errors.push(`external.json[${index}]: plugin name "${plugin.name}" conflicts with local plugin "${localDuplicate}"`);
392 }
393 });
394
395 return { errors, warnings };
396}
397
398export function readExternalPlugins(options = {}) {
399 const filePath = options.filePath ?? EXTERNAL_PLUGINS_FILE;

Callers 2

upsertExternalPluginFunction · 0.90
readExternalPluginsFunction · 0.85

Calls 3

resolvePolicyFunction · 0.85
validateExternalPluginFunction · 0.85
isNonEmptyStringFunction · 0.85

Tested by

no test coverage detected