// 这个正则用于检验包名 是否是 scoped package name var scopedPackagePattern = newRegExp('^(?:@([^/]+?)[/])?([^/]+?)$') // 一个第三方库 包含了一些特殊的关键字 字符串数组 例如http fs https等 var builtins = require('builtins') // 跟上面这个库类似的功能 var blacklist = [ 'node_modules', 'favicon.ico' ]
// 导出一个函数名 // name 传入检测的包名 var validate = module.exports = function (name) { // 存放警告情况的数组 var warnings = [] // 存放错误情况的数组 var errors = []
// 以下是一系列用于判断包名是否合规的判断 // 前几个判断没通过直接就return出去了 // 不能是null if (name === null) { errors.push('name cannot be null') returndone(warnings, errors) }
// 不能是undefined if (name === undefined) { errors.push('name cannot be undefined') returndone(warnings, errors) }
// 必须是字符串 if (typeof name !== 'string') { errors.push('name must be a string') returndone(warnings, errors) }
// 长度不能为0 if (!name.length) { errors.push('name length must be greater than zero') }
// 不能以.开头 if (name.match(/^\./)) { errors.push('name cannot start with a period') }
// 不能以_开头 if (name.match(/^_/)) { errors.push('name cannot start with an underscore') }
// 必须是a-z 0-9 @以内的字符开头 后来新加的判断 这么说的话 大写字母也不能开头 特殊字符也不能开头了 if (name.length && !name.match(/^[a-z0-9@]/)) { warnings.push('name can only start with lowercase character and digit') }
// 不能有首尾空格 if (name.trim() !== name) { errors.push('name cannot contain leading or trailing spaces') }
// 不能是黑名单里面的字符串 // No funny business blacklist.forEach(function (blacklistedName) { if (name.toLowerCase() === blacklistedName) { errors.push(blacklistedName + ' is a blacklisted name') } })
// Generate warnings for stuff that used to be allowed
// 不能是关键字字符串 多数是nodejs的关键字 // core module names like http, events, util, etc builtins.forEach(function (builtin) { if (name.toLowerCase() === builtin) { warnings.push(builtin + ' is a core module name') } })
// 长度不能大于214个字符 // really-long-package-names-------------------------------such--length-----many---wow // the thisisareallyreallylongpackagenameitshouldpublishdowenowhavealimittothelengthofpackagenames-poch. if (name.length > 214) { warnings.push('name can no longer contain more than 214 characters') }
// 不能包含大写 // mIxeD CaSe nAMEs if (name.toLowerCase() !== name) { warnings.push('name can no longer contain capital letters') }
// @user/package package不能以~'!()* 字符开头 if (/[~'!()*]/.test(name.split('/').slice(-1)[0])) { warnings.push('name can no longer contain special characters ("~\'!()*")') }
// 不能包含中文或其他语言文字 if (encodeURIComponent(name) !== name) { // Maybe it's a scoped package name, like @user/package var nameMatch = name.match(scopedPackagePattern) // 如果是 @user/package形式 分别判断是否转码后相等 if (nameMatch) { var user = nameMatch[1] var pkg = nameMatch[2] if (encodeURIComponent(user) === user && encodeURIComponent(pkg) === pkg) { returndone(warnings, errors) } }
errors.push('name can only contain URL-friendly characters') } // 最后返回结果 returndone(warnings, errors) }