A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/npm/cli/commit/7ddfbadd1d51d07e68afbe1b91a36106d98c7bea below:

@npmcli/package-json@6.1.1 · npm/cli@7ddfbad · GitHub

1 +

// Originally normalize-package-data

2 + 3 +

const url = require('node:url')

4 +

const hostedGitInfo = require('hosted-git-info')

5 +

const validateLicense = require('validate-npm-package-license')

6 + 7 +

const typos = {

8 +

dependancies: 'dependencies',

9 +

dependecies: 'dependencies',

10 +

depdenencies: 'dependencies',

11 +

devEependencies: 'devDependencies',

12 +

depends: 'dependencies',

13 +

'dev-dependencies': 'devDependencies',

14 +

devDependences: 'devDependencies',

15 +

devDepenencies: 'devDependencies',

16 +

devdependencies: 'devDependencies',

17 +

repostitory: 'repository',

18 +

repo: 'repository',

19 +

prefereGlobal: 'preferGlobal',

20 +

hompage: 'homepage',

21 +

hampage: 'homepage',

22 +

autohr: 'author',

23 +

autor: 'author',

24 +

contributers: 'contributors',

25 +

publicationConfig: 'publishConfig',

26 +

script: 'scripts',

27 +

}

28 + 29 +

const isEmail = str => str.includes('@') && (str.indexOf('@') < str.lastIndexOf('.'))

30 + 31 +

// Extracts description from contents of a readme file in markdown format

32 +

function extractDescription (description) {

33 +

// the first block of text before the first heading that isn't the first line heading

34 +

const lines = description.trim().split('\n')

35 +

let start = 0

36 +

// skip initial empty lines and lines that start with #

37 +

while (lines[start]?.trim().match(/^(#|$)/)) {

38 +

start++

39 +

}

40 +

let end = start + 1

41 +

// keep going till we get to the end or an empty line

42 +

while (end < lines.length && lines[end].trim()) {

43 +

end++

44 +

}

45 +

return lines.slice(start, end).join(' ').trim()

46 +

}

47 + 48 +

function stringifyPerson (person) {

49 +

if (typeof person !== 'string') {

50 +

const name = person.name || ''

51 +

const u = person.url || person.web

52 +

const wrappedUrl = u ? (' (' + u + ')') : ''

53 +

const e = person.email || person.mail

54 +

const wrappedEmail = e ? (' <' + e + '>') : ''

55 +

person = name + wrappedEmail + wrappedUrl

56 +

}

57 +

const matchedName = person.match(/^([^(<]+)/)

58 +

const matchedUrl = person.match(/\(([^()]+)\)/)

59 +

const matchedEmail = person.match(/<([^<>]+)>/)

60 +

const parsed = {}

61 +

if (matchedName?.[0].trim()) {

62 +

parsed.name = matchedName[0].trim()

63 +

}

64 +

if (matchedEmail) {

65 +

parsed.email = matchedEmail[1]

66 +

}

67 +

if (matchedUrl) {

68 +

parsed.url = matchedUrl[1]

69 +

}

70 +

return parsed

71 +

}

72 + 73 +

function normalizeData (data, changes) {

74 +

// fixDescriptionField

75 +

if (data.description && typeof data.description !== 'string') {

76 +

changes?.push(`'description' field should be a string`)

77 +

delete data.description

78 +

}

79 +

if (data.readme && !data.description && data.readme !== 'ERROR: No README data found!') {

80 +

data.description = extractDescription(data.readme)

81 +

}

82 +

if (data.description === undefined) {

83 +

delete data.description

84 +

}

85 +

if (!data.description) {

86 +

changes?.push('No description')

87 +

}

88 + 89 +

// fixModulesField

90 +

if (data.modules) {

91 +

changes?.push(`modules field is deprecated`)

92 +

delete data.modules

93 +

}

94 + 95 +

// fixFilesField

96 +

const files = data.files

97 +

if (files && !Array.isArray(files)) {

98 +

changes?.push(`Invalid 'files' member`)

99 +

delete data.files

100 +

} else if (data.files) {

101 +

data.files = data.files.filter(function (file) {

102 +

if (!file || typeof file !== 'string') {

103 +

changes?.push(`Invalid filename in 'files' list: ${file}`)

104 +

return false

105 +

} else {

106 +

return true

107 +

}

108 +

})

109 +

}

110 + 111 +

// fixManField

112 +

if (data.man && typeof data.man === 'string') {

113 +

data.man = [data.man]

114 +

}

115 + 116 +

// fixBugsField

117 +

if (!data.bugs && data.repository?.url) {

118 +

const hosted = hostedGitInfo.fromUrl(data.repository.url)

119 +

if (hosted && hosted.bugs()) {

120 +

data.bugs = { url: hosted.bugs() }

121 +

}

122 +

} else if (data.bugs) {

123 +

if (typeof data.bugs === 'string') {

124 +

if (isEmail(data.bugs)) {

125 +

data.bugs = { email: data.bugs }

126 +

/* eslint-disable-next-line node/no-deprecated-api */

127 +

} else if (url.parse(data.bugs).protocol) {

128 +

data.bugs = { url: data.bugs }

129 +

} else {

130 +

changes?.push(`Bug string field must be url, email, or {email,url}`)

131 +

}

132 +

} else {

133 +

for (const k in data.bugs) {

134 +

if (['web', 'name'].includes(k)) {

135 +

changes?.push(`bugs['${k}'] should probably be bugs['url'].`)

136 +

data.bugs.url = data.bugs[k]

137 +

delete data.bugs[k]

138 +

}

139 +

}

140 +

const oldBugs = data.bugs

141 +

data.bugs = {}

142 +

if (oldBugs.url) {

143 +

/* eslint-disable-next-line node/no-deprecated-api */

144 +

if (typeof (oldBugs.url) === 'string' && url.parse(oldBugs.url).protocol) {

145 +

data.bugs.url = oldBugs.url

146 +

} else {

147 +

changes?.push('bugs.url field must be a string url. Deleted.')

148 +

}

149 +

}

150 +

if (oldBugs.email) {

151 +

if (typeof (oldBugs.email) === 'string' && isEmail(oldBugs.email)) {

152 +

data.bugs.email = oldBugs.email

153 +

} else {

154 +

changes?.push('bugs.email field must be a string email. Deleted.')

155 +

}

156 +

}

157 +

}

158 +

if (!data.bugs.email && !data.bugs.url) {

159 +

delete data.bugs

160 +

changes?.push('Normalized value of bugs field is an empty object. Deleted.')

161 +

}

162 +

}

163 +

// fixKeywordsField

164 +

if (typeof data.keywords === 'string') {

165 +

data.keywords = data.keywords.split(/,\s+/)

166 +

}

167 +

if (data.keywords && !Array.isArray(data.keywords)) {

168 +

delete data.keywords

169 +

changes?.push(`keywords should be an array of strings`)

170 +

} else if (data.keywords) {

171 +

data.keywords = data.keywords.filter(function (kw) {

172 +

if (typeof kw !== 'string' || !kw) {

173 +

changes?.push(`keywords should be an array of strings`)

174 +

return false

175 +

} else {

176 +

return true

177 +

}

178 +

})

179 +

}

180 +

// fixBundleDependenciesField

181 +

const bdd = 'bundledDependencies'

182 +

const bd = 'bundleDependencies'

183 +

if (data[bdd] && !data[bd]) {

184 +

data[bd] = data[bdd]

185 +

delete data[bdd]

186 +

}

187 +

if (data[bd] && !Array.isArray(data[bd])) {

188 +

changes?.push(`Invalid 'bundleDependencies' list. Must be array of package names`)

189 +

delete data[bd]

190 +

} else if (data[bd]) {

191 +

data[bd] = data[bd].filter(function (filtered) {

192 +

if (!filtered || typeof filtered !== 'string') {

193 +

changes?.push(`Invalid bundleDependencies member: ${filtered}`)

194 +

return false

195 +

} else {

196 +

if (!data.dependencies) {

197 +

data.dependencies = {}

198 +

}

199 +

if (!Object.prototype.hasOwnProperty.call(data.dependencies, filtered)) {

200 +

changes?.push(`Non-dependency in bundleDependencies: ${filtered}`)

201 +

data.dependencies[filtered] = '*'

202 +

}

203 +

return true

204 +

}

205 +

})

206 +

}

207 +

// fixHomepageField

208 +

if (!data.homepage && data.repository && data.repository.url) {

209 +

const hosted = hostedGitInfo.fromUrl(data.repository.url)

210 +

if (hosted) {

211 +

data.homepage = hosted.docs()

212 +

}

213 +

}

214 +

if (data.homepage) {

215 +

if (typeof data.homepage !== 'string') {

216 +

changes?.push('homepage field must be a string url. Deleted.')

217 +

delete data.homepage

218 +

} else {

219 +

/* eslint-disable-next-line node/no-deprecated-api */

220 +

if (!url.parse(data.homepage).protocol) {

221 +

data.homepage = 'http://' + data.homepage

222 +

}

223 +

}

224 +

}

225 +

// fixReadmeField

226 +

if (!data.readme) {

227 +

changes?.push('No README data')

228 +

data.readme = 'ERROR: No README data found!'

229 +

}

230 +

// fixLicenseField

231 +

const license = data.license || data.licence

232 +

if (!license) {

233 +

changes?.push('No license field.')

234 +

} else if (typeof (license) !== 'string' || license.length < 1 || license.trim() === '') {

235 +

changes?.push('license should be a valid SPDX license expression')

236 +

} else if (!validateLicense(license).validForNewPackages) {

237 +

changes?.push('license should be a valid SPDX license expression')

238 +

}

239 +

// fixPeople

240 +

if (data.author) {

241 +

data.author = stringifyPerson(data.author)

242 +

}

243 +

['maintainers', 'contributors'].forEach(function (set) {

244 +

if (!Array.isArray(data[set])) {

245 +

return

246 +

}

247 +

data[set] = data[set].map(stringifyPerson)

248 +

})

249 +

// fixTypos

250 +

for (const d in typos) {

251 +

if (Object.prototype.hasOwnProperty.call(data, d)) {

252 +

changes?.push(`${d} should probably be ${typos[d]}.`)

253 +

}

254 +

}

255 +

}

256 + 257 +

module.exports = { normalizeData }


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4