(plugin, index, options = {})
| 315 | } |
| 316 | |
| 317 | export function validateExternalPlugin(plugin, index, options = {}) { |
| 318 | const policy = resolvePolicy(options.policy ?? options); |
| 319 | const errors = []; |
| 320 | const warnings = []; |
| 321 | const prefix = `external.json[${index}]`; |
| 322 | |
| 323 | if (!plugin || typeof plugin !== "object" || Array.isArray(plugin)) { |
| 324 | return { |
| 325 | errors: [`${prefix}: entry must be an object`], |
| 326 | warnings, |
| 327 | }; |
| 328 | } |
| 329 | |
| 330 | validatePluginName(plugin.name, prefix, errors); |
| 331 | validateDescription(plugin.description, prefix, errors); |
| 332 | validateVersion(plugin.version, prefix, errors); |
| 333 | validateAuthor(plugin.author, prefix, errors, policy.requireAuthor); |
| 334 | validateRepository(plugin.repository, prefix, errors, policy.requireRepository); |
| 335 | validateHomepage(plugin.homepage, prefix, errors); |
| 336 | validateLicense(plugin.license, prefix, errors, policy.requireLicense); |
| 337 | validateKeywords(plugin.keywords ?? plugin.tags, prefix, errors, warnings, policy.requireKeywords); |
| 338 | |
| 339 | if (plugin.tags !== undefined && plugin.keywords === undefined) { |
| 340 | warnings.push(`${prefix}: prefer "keywords" over legacy "tags"`); |
| 341 | } |
| 342 | |
| 343 | if (!plugin.source) { |
| 344 | errors.push(`${prefix}: "source" is required`); |
| 345 | } else if (typeof plugin.source === "string") { |
| 346 | errors.push(`${prefix}: "source" must be an object (local file paths are not allowed for external plugins)`); |
| 347 | } else if (!policy.allowedSourceTypes.includes(plugin.source.source)) { |
| 348 | errors.push(`${prefix}: "source.source" must be one of: ${policy.allowedSourceTypes.join(", ")}`); |
| 349 | } else if (plugin.source.source === "github") { |
| 350 | validateGitHubSource(plugin.source, prefix, errors, policy.requireImmutableLocator); |
| 351 | } |
| 352 | |
| 353 | return { errors, warnings }; |
| 354 | } |
| 355 | |
| 356 | export function validateExternalPlugins(plugins, options = {}) { |
| 357 | const policy = resolvePolicy(options.policy ?? options); |
no test coverage detected