11cb0ef41Sopenharmony_ci'use strict' 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_civar scopedPackagePattern = new RegExp('^(?:@([^/]+?)[/])?([^/]+?)$') 41cb0ef41Sopenharmony_civar builtins = require('builtins') 51cb0ef41Sopenharmony_civar blacklist = [ 61cb0ef41Sopenharmony_ci 'node_modules', 71cb0ef41Sopenharmony_ci 'favicon.ico', 81cb0ef41Sopenharmony_ci] 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_cifunction validate (name) { 111cb0ef41Sopenharmony_ci var warnings = [] 121cb0ef41Sopenharmony_ci var errors = [] 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci if (name === null) { 151cb0ef41Sopenharmony_ci errors.push('name cannot be null') 161cb0ef41Sopenharmony_ci return done(warnings, errors) 171cb0ef41Sopenharmony_ci } 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci if (name === undefined) { 201cb0ef41Sopenharmony_ci errors.push('name cannot be undefined') 211cb0ef41Sopenharmony_ci return done(warnings, errors) 221cb0ef41Sopenharmony_ci } 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci if (typeof name !== 'string') { 251cb0ef41Sopenharmony_ci errors.push('name must be a string') 261cb0ef41Sopenharmony_ci return done(warnings, errors) 271cb0ef41Sopenharmony_ci } 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci if (!name.length) { 301cb0ef41Sopenharmony_ci errors.push('name length must be greater than zero') 311cb0ef41Sopenharmony_ci } 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci if (name.match(/^\./)) { 341cb0ef41Sopenharmony_ci errors.push('name cannot start with a period') 351cb0ef41Sopenharmony_ci } 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci if (name.match(/^_/)) { 381cb0ef41Sopenharmony_ci errors.push('name cannot start with an underscore') 391cb0ef41Sopenharmony_ci } 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci if (name.trim() !== name) { 421cb0ef41Sopenharmony_ci errors.push('name cannot contain leading or trailing spaces') 431cb0ef41Sopenharmony_ci } 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci // No funny business 461cb0ef41Sopenharmony_ci blacklist.forEach(function (blacklistedName) { 471cb0ef41Sopenharmony_ci if (name.toLowerCase() === blacklistedName) { 481cb0ef41Sopenharmony_ci errors.push(blacklistedName + ' is a blacklisted name') 491cb0ef41Sopenharmony_ci } 501cb0ef41Sopenharmony_ci }) 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci // Generate warnings for stuff that used to be allowed 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci // core module names like http, events, util, etc 551cb0ef41Sopenharmony_ci builtins({ version: '*' }).forEach(function (builtin) { 561cb0ef41Sopenharmony_ci if (name.toLowerCase() === builtin) { 571cb0ef41Sopenharmony_ci warnings.push(builtin + ' is a core module name') 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci }) 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci if (name.length > 214) { 621cb0ef41Sopenharmony_ci warnings.push('name can no longer contain more than 214 characters') 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci // mIxeD CaSe nAMEs 661cb0ef41Sopenharmony_ci if (name.toLowerCase() !== name) { 671cb0ef41Sopenharmony_ci warnings.push('name can no longer contain capital letters') 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci if (/[~'!()*]/.test(name.split('/').slice(-1)[0])) { 711cb0ef41Sopenharmony_ci warnings.push('name can no longer contain special characters ("~\'!()*")') 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci if (encodeURIComponent(name) !== name) { 751cb0ef41Sopenharmony_ci // Maybe it's a scoped package name, like @user/package 761cb0ef41Sopenharmony_ci var nameMatch = name.match(scopedPackagePattern) 771cb0ef41Sopenharmony_ci if (nameMatch) { 781cb0ef41Sopenharmony_ci var user = nameMatch[1] 791cb0ef41Sopenharmony_ci var pkg = nameMatch[2] 801cb0ef41Sopenharmony_ci if (encodeURIComponent(user) === user && encodeURIComponent(pkg) === pkg) { 811cb0ef41Sopenharmony_ci return done(warnings, errors) 821cb0ef41Sopenharmony_ci } 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci errors.push('name can only contain URL-friendly characters') 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci return done(warnings, errors) 891cb0ef41Sopenharmony_ci} 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_civar done = function (warnings, errors) { 921cb0ef41Sopenharmony_ci var result = { 931cb0ef41Sopenharmony_ci validForNewPackages: errors.length === 0 && warnings.length === 0, 941cb0ef41Sopenharmony_ci validForOldPackages: errors.length === 0, 951cb0ef41Sopenharmony_ci warnings: warnings, 961cb0ef41Sopenharmony_ci errors: errors, 971cb0ef41Sopenharmony_ci } 981cb0ef41Sopenharmony_ci if (!result.warnings.length) { 991cb0ef41Sopenharmony_ci delete result.warnings 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci if (!result.errors.length) { 1021cb0ef41Sopenharmony_ci delete result.errors 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci return result 1051cb0ef41Sopenharmony_ci} 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_cimodule.exports = validate 108