UNPKG

9.99 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.normalizePackageData = void 0;
4const semver = require("semver");
5const hosted_git_info_1 = require("hosted-git-info");
6const url = require("url");
7function normalizePackageData(data) {
8 for (const it of check) {
9 it(data);
10 }
11}
12exports.normalizePackageData = normalizePackageData;
13const depTypes = ["dependencies", "devDependencies", "optionalDependencies"];
14const check = [
15 function (data) {
16 if (data.repositories) {
17 data.repository = data.repositories[0];
18 }
19 if (typeof data.repository === "string") {
20 data.repository = {
21 type: "git",
22 url: data.repository,
23 };
24 }
25 if (data.repository != null && data.repository.url) {
26 const hosted = hosted_git_info_1.fromUrl(data.repository.url);
27 if (hosted) {
28 data.repository.url = hosted.getDefaultRepresentation() == "shortcut" ? hosted.https() : hosted.toString();
29 }
30 }
31 },
32 function (data) {
33 const files = data.files;
34 if (files && !Array.isArray(files)) {
35 delete data.files;
36 }
37 else if (data.files) {
38 data.files = data.files.filter(function (file) {
39 return !(!file || typeof file !== "string");
40 });
41 }
42 },
43 function (data) {
44 if (!data.bin) {
45 return;
46 }
47 if (typeof data.bin === "string") {
48 const b = {};
49 const match = data.name.match(/^@[^/]+[/](.*)$/);
50 if (match) {
51 b[match[1]] = data.bin;
52 }
53 else {
54 b[data.name] = data.bin;
55 }
56 data.bin = b;
57 }
58 },
59 function (data) {
60 if (data.description && typeof data.description !== "string") {
61 delete data.description;
62 }
63 if (data.description === undefined) {
64 delete data.description;
65 }
66 },
67 fixBundleDependenciesField,
68 function fixDependencies(data) {
69 objectifyDeps(data);
70 fixBundleDependenciesField(data);
71 for (const deps of ["dependencies", "devDependencies", "optionalDependencies"]) {
72 if (!(deps in data)) {
73 continue;
74 }
75 if (!data[deps] || typeof data[deps] !== "object") {
76 delete data[deps];
77 continue;
78 }
79 Object.keys(data[deps]).forEach(function (d) {
80 const r = data[deps][d];
81 if (typeof r !== "string") {
82 delete data[deps][d];
83 }
84 const hosted = hosted_git_info_1.fromUrl(data[deps][d]);
85 if (hosted) {
86 data[deps][d] = hosted.toString();
87 }
88 });
89 }
90 },
91 function fixBugsField(data) {
92 if (!data.bugs && data.repository && data.repository.url) {
93 const hosted = hosted_git_info_1.fromUrl(data.repository.url);
94 if (hosted && hosted.bugs()) {
95 data.bugs = { url: hosted.bugs() };
96 }
97 }
98 else if (data.bugs) {
99 const emailRe = /^.+@.*\..+$/;
100 if (typeof data.bugs == "string") {
101 if (emailRe.test(data.bugs)) {
102 data.bugs = { email: data.bugs };
103 }
104 else if (url.parse(data.bugs).protocol) {
105 data.bugs = { url: data.bugs };
106 }
107 }
108 else {
109 bugsTypos(data.bugs);
110 const oldBugs = data.bugs;
111 data.bugs = {};
112 if (oldBugs.url) {
113 if (typeof oldBugs.url == "string" && url.parse(oldBugs.url).protocol) {
114 data.bugs.url = oldBugs.url;
115 }
116 }
117 if (oldBugs.email) {
118 if (typeof oldBugs.email == "string" && emailRe.test(oldBugs.email)) {
119 data.bugs.email = oldBugs.email;
120 }
121 }
122 }
123 if (!data.bugs.email && !data.bugs.url) {
124 delete data.bugs;
125 }
126 }
127 },
128 function fixModulesField(data) {
129 if (data.modules) {
130 delete data.modules;
131 }
132 },
133 function fixKeywordsField(data) {
134 if (typeof data.keywords === "string") {
135 data.keywords = data.keywords.split(/,\s+/);
136 }
137 if (data.keywords && !Array.isArray(data.keywords)) {
138 delete data.keywords;
139 }
140 else if (data.keywords) {
141 data.keywords = data.keywords.filter(function (kw) {
142 return !(typeof kw !== "string" || !kw);
143 });
144 }
145 },
146 function fixVersionField(data) {
147 const loose = true;
148 if (!data.version) {
149 data.version = "";
150 return true;
151 }
152 if (!semver.valid(data.version, loose)) {
153 throw new Error(`Invalid version: "${data.version}"`);
154 }
155 data.version = semver.clean(data.version, loose);
156 return true;
157 },
158 function fixPeople(data) {
159 modifyPeople(data, unParsePerson);
160 modifyPeople(data, parsePerson);
161 },
162 function fixNameField(data) {
163 if (!data.name) {
164 data.name = "";
165 return;
166 }
167 if (typeof data.name !== "string") {
168 throw new Error("name field must be a string.");
169 }
170 data.name = data.name.trim();
171 ensureValidName(data.name);
172 },
173 function fixHomepageField(data) {
174 if (!data.homepage && data.repository && data.repository.url) {
175 const hosted = hosted_git_info_1.fromUrl(data.repository.url);
176 if (hosted && hosted.docs()) {
177 data.homepage = hosted.docs();
178 }
179 }
180 if (!data.homepage) {
181 return;
182 }
183 if (typeof data.homepage !== "string") {
184 delete data.homepage;
185 }
186 if (!url.parse(data.homepage).protocol) {
187 data.homepage = `https://${data.homepage}`;
188 }
189 return;
190 },
191];
192function fixBundleDependenciesField(data) {
193 const bdd = "bundledDependencies";
194 const bd = "bundleDependencies";
195 if (data[bdd] && !data[bd]) {
196 data[bd] = data[bdd];
197 delete data[bdd];
198 }
199 if (data[bd] && !Array.isArray(data[bd])) {
200 delete data[bd];
201 }
202 else if (data[bd]) {
203 data[bd] = data[bd].filter(function (bd) {
204 if (!bd || typeof bd !== "string") {
205 return false;
206 }
207 else {
208 if (!data.dependencies) {
209 data.dependencies = {};
210 }
211 if (!("bd" in data.dependencies)) {
212 data.dependencies[bd] = "*";
213 }
214 return true;
215 }
216 });
217 }
218}
219function isValidScopedPackageName(spec) {
220 if (spec.charAt(0) !== "@") {
221 return false;
222 }
223 const rest = spec.slice(1).split("/");
224 if (rest.length !== 2) {
225 return false;
226 }
227 return rest[0] !== "" && rest[1] !== "" && rest[0] != null && rest[1] != null && rest[0] === encodeURIComponent(rest[0]) && rest[1] === encodeURIComponent(rest[1]);
228}
229function isCorrectlyEncodedName(spec) {
230 return !/[/@\s+%:]/.test(spec) && spec === encodeURIComponent(spec);
231}
232function ensureValidName(name) {
233 if (name.charAt(0) === "." ||
234 !(isValidScopedPackageName(name) || isCorrectlyEncodedName(name)) ||
235 name.toLowerCase() === "node_modules" ||
236 name.toLowerCase() === "favicon.ico") {
237 throw new Error("Invalid name: " + JSON.stringify(name));
238 }
239}
240function modifyPeople(data, fn) {
241 if (data.author) {
242 data.author = fn(data.author);
243 }
244 for (const set of ["maintainers", "contributors"]) {
245 if (!Array.isArray(data[set])) {
246 continue;
247 }
248 data[set] = data[set].map(fn);
249 }
250 return data;
251}
252function unParsePerson(person) {
253 if (typeof person === "string") {
254 return person;
255 }
256 const name = person.name || "";
257 const u = person.url || person.web;
258 const url = u ? ` (${u})` : "";
259 const e = person.email || person.mail;
260 const email = e ? ` <${e}>` : "";
261 return `${name}${email}${url}`;
262}
263function parsePerson(person) {
264 if (typeof person !== "string") {
265 return person;
266 }
267 const name = /^([^(<]+)/.exec(person);
268 const url = /\(([^)]+)\)/.exec(person);
269 const email = /<([^>]+)>/.exec(person);
270 const obj = {};
271 if (name && name[0].trim()) {
272 obj.name = name[0].trim();
273 }
274 if (email) {
275 obj.email = email[1];
276 }
277 if (url) {
278 obj.url = url[1];
279 }
280 return obj;
281}
282function depObjectify(deps) {
283 if (!deps) {
284 return {};
285 }
286 if (typeof deps === "string") {
287 deps = deps.trim().split(/[\n\r\s\t ,]+/);
288 }
289 if (!Array.isArray(deps)) {
290 return deps;
291 }
292 const o = {};
293 deps
294 .filter(function (d) {
295 return typeof d === "string";
296 })
297 .forEach(function (d) {
298 d = d.trim().split(/(:?[@\s><=])/);
299 const dn = d.shift();
300 let dv = d.join("");
301 dv = dv.trim();
302 dv = dv.replace(/^@/, "");
303 o[dn] = dv;
304 });
305 return o;
306}
307function objectifyDeps(data) {
308 depTypes.forEach(function (type) {
309 if (!data[type]) {
310 return;
311 }
312 data[type] = depObjectify(data[type]);
313 });
314}
315const typoBugs = { web: "url", name: "url" };
316function bugsTypos(bugs) {
317 if (!bugs) {
318 return;
319 }
320 Object.keys(bugs).forEach(function (k) {
321 if (typoBugs[k]) {
322 bugs[typoBugs[k]] = bugs[k];
323 delete bugs[k];
324 }
325 });
326}
327//# sourceMappingURL=normalizePackageData.js.map
\No newline at end of file