-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
75 lines (54 loc) · 2 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
const { _builtinLibs } = require('repl');
const isSANB = require('is-string-and-not-blank');
const slug = require('speakingurl');
const errors = require('./errors');
const isValidPackageName = str => {
// rules from npm last checked on September 7, 2017
// <https://docs.npmjs.com/files/package.json#name>
// ensure it's a string
if (!isSANB(str)) return errors.notString;
// first trim it
if (str !== str.trim()) return errors.trim;
// can't be > 214 characters
if (str.length > 214) return errors.maxLength;
// can't start with a dot or underscore
if (['.', '_'].includes(str.slice(0, 1))) return errors.dotUnderscore;
// no uppercase letters
if (str !== str.toLowerCase()) return errors.uppercase;
//
// name can be prefixed by a scope, e.g. @myorg/package
//
// must have @
if (str.includes('@')) {
// must have @ at beginning of string
if (str.indexOf('@') !== 0) return errors.atFirst;
// must have only one @
if (str.indexOf('@') !== str.lastIndexOf('@')) return errors.extraAt;
// must have /
if (!str.includes('/')) return errors.noSlash;
// must have only one /
if (str.indexOf('/') !== str.lastIndexOf('/')) return errors.extraSlash;
// validate scope
const arr = str.split('/');
const scope = arr[0].slice(1);
const isValidScopeName = isValidPackageName(scope);
if (isValidScopeName !== true) return isValidScopeName;
// validate name again
return isValidPackageName(arr[1]);
}
// don't use the same name as a core Node module
// <https://stackoverflow.com/a/35825896/3586413>
if (_builtinLibs.includes(str)) return errors.builtIn;
// no non-URL-safe characters
// <https://github.com/lovell/limax/issues/24>
const safeStr = slug(str);
if (str !== safeStr)
return `${errors.nonURLSafe}, try using "${safeStr}" instead`;
//
// *EXEMPTION*: due to the sheer number of npm package name squatters
//
// don't put "js" or "node" in the name
//
return true;
};
module.exports = isValidPackageName;