"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/normalize-package-data/lib/fixer.js" (8 Mar 2017, 11805 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 var semver = require("semver")
    2 var validateLicense = require('validate-npm-package-license');
    3 var hostedGitInfo = require("hosted-git-info")
    4 var isBuiltinModule = require("is-builtin-module")
    5 var depTypes = ["dependencies","devDependencies","optionalDependencies"]
    6 var extractDescription = require("./extract_description")
    7 var url = require("url")
    8 var typos = require("./typos")
    9 
   10 var fixer = module.exports = {
   11   // default warning function
   12   warn: function() {},
   13 
   14   fixRepositoryField: function(data) {
   15     if (data.repositories) {
   16       this.warn("repositories");
   17       data.repository = data.repositories[0]
   18     }
   19     if (!data.repository) return this.warn("missingRepository")
   20     if (typeof data.repository === "string") {
   21       data.repository = {
   22         type: "git",
   23         url: data.repository
   24       }
   25     }
   26     var r = data.repository.url || ""
   27     if (r) {
   28       var hosted = hostedGitInfo.fromUrl(r)
   29       if (hosted) {
   30         r = data.repository.url
   31           = hosted.getDefaultRepresentation() == "shortcut" ? hosted.https() : hosted.toString()
   32       }
   33     }
   34 
   35     if (r.match(/github.com\/[^\/]+\/[^\/]+\.git\.git$/)) {
   36       this.warn("brokenGitUrl", r)
   37     }
   38   }
   39 
   40 , fixTypos: function(data) {
   41     Object.keys(typos.topLevel).forEach(function (d) {
   42       if (data.hasOwnProperty(d)) {
   43         this.warn("typo", d, typos.topLevel[d])
   44       }
   45     }, this)
   46   }
   47 
   48 , fixScriptsField: function(data) {
   49     if (!data.scripts) return
   50     if (typeof data.scripts !== "object") {
   51       this.warn("nonObjectScripts")
   52       delete data.scripts
   53       return
   54     }
   55     Object.keys(data.scripts).forEach(function (k) {
   56       if (typeof data.scripts[k] !== "string") {
   57         this.warn("nonStringScript")
   58         delete data.scripts[k]
   59       } else if (typos.script[k] && !data.scripts[typos.script[k]]) {
   60         this.warn("typo", k, typos.script[k], "scripts")
   61       }
   62     }, this)
   63   }
   64 
   65 , fixFilesField: function(data) {
   66     var files = data.files
   67     if (files && !Array.isArray(files)) {
   68       this.warn("nonArrayFiles")
   69       delete data.files
   70     } else if (data.files) {
   71       data.files = data.files.filter(function(file) {
   72         if (!file || typeof file !== "string") {
   73           this.warn("invalidFilename", file)
   74           return false
   75         } else {
   76           return true
   77         }
   78       }, this)
   79     }
   80   }
   81 
   82 , fixBinField: function(data) {
   83     if (!data.bin) return;
   84     if (typeof data.bin === "string") {
   85       var b = {}
   86       var match
   87       if (match = data.name.match(/^@[^/]+[/](.*)$/)) {
   88         b[match[1]] = data.bin
   89       } else {
   90         b[data.name] = data.bin
   91       }
   92       data.bin = b
   93     }
   94   }
   95 
   96 , fixManField: function(data) {
   97     if (!data.man) return;
   98     if (typeof data.man === "string") {
   99       data.man = [ data.man ]
  100     }
  101   }
  102 , fixBundleDependenciesField: function(data) {
  103     var bdd = "bundledDependencies"
  104     var bd = "bundleDependencies"
  105     if (data[bdd] && !data[bd]) {
  106       data[bd] = data[bdd]
  107       delete data[bdd]
  108     }
  109     if (data[bd] && !Array.isArray(data[bd])) {
  110       this.warn("nonArrayBundleDependencies")
  111       delete data[bd]
  112     } else if (data[bd]) {
  113       data[bd] = data[bd].filter(function(bd) {
  114         if (!bd || typeof bd !== 'string') {
  115           this.warn("nonStringBundleDependency", bd)
  116           return false
  117         } else {
  118           if (!data.dependencies) {
  119             data.dependencies = {}
  120           }
  121           if (!data.dependencies.hasOwnProperty(bd)) {
  122             this.warn("nonDependencyBundleDependency", bd)
  123             data.dependencies[bd] = "*"
  124           }
  125           return true
  126         }
  127       }, this)
  128     }
  129   }
  130 
  131 , fixDependencies: function(data, strict) {
  132     var loose = !strict
  133     objectifyDeps(data, this.warn)
  134     addOptionalDepsToDeps(data, this.warn)
  135     this.fixBundleDependenciesField(data)
  136 
  137     ;['dependencies','devDependencies'].forEach(function(deps) {
  138       if (!(deps in data)) return
  139       if (!data[deps] || typeof data[deps] !== "object") {
  140         this.warn("nonObjectDependencies", deps)
  141         delete data[deps]
  142         return
  143       }
  144       Object.keys(data[deps]).forEach(function (d) {
  145         var r = data[deps][d]
  146         if (typeof r !== 'string') {
  147           this.warn("nonStringDependency", d, JSON.stringify(r))
  148           delete data[deps][d]
  149         }
  150         var hosted = hostedGitInfo.fromUrl(data[deps][d])
  151         if (hosted) data[deps][d] = hosted.toString()
  152       }, this)
  153     }, this)
  154   }
  155 
  156 , fixModulesField: function (data) {
  157     if (data.modules) {
  158       this.warn("deprecatedModules")
  159       delete data.modules
  160     }
  161   }
  162 
  163 , fixKeywordsField: function (data) {
  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       this.warn("nonArrayKeywords")
  170     } else if (data.keywords) {
  171       data.keywords = data.keywords.filter(function(kw) {
  172         if (typeof kw !== "string" || !kw) {
  173           this.warn("nonStringKeyword");
  174           return false
  175         } else {
  176           return true
  177         }
  178       }, this)
  179     }
  180   }
  181 
  182 , fixVersionField: function(data, strict) {
  183     // allow "loose" semver 1.0 versions in non-strict mode
  184     // enforce strict semver 2.0 compliance in strict mode
  185     var loose = !strict
  186     if (!data.version) {
  187       data.version = ""
  188       return true
  189     }
  190     if (!semver.valid(data.version, loose)) {
  191       throw new Error('Invalid version: "'+ data.version + '"')
  192     }
  193     data.version = semver.clean(data.version, loose)
  194     return true
  195   }
  196 
  197 , fixPeople: function(data) {
  198     modifyPeople(data, unParsePerson)
  199     modifyPeople(data, parsePerson)
  200   }
  201 
  202 , fixNameField: function(data, options) {
  203     if (typeof options === "boolean") options = {strict: options}
  204     else if (typeof options === "undefined") options = {}
  205     var strict = options.strict
  206     if (!data.name && !strict) {
  207       data.name = ""
  208       return
  209     }
  210     if (typeof data.name !== "string") {
  211       throw new Error("name field must be a string.")
  212     }
  213     if (!strict)
  214       data.name = data.name.trim()
  215     ensureValidName(data.name, strict, options.allowLegacyCase)
  216     if (isBuiltinModule(data.name))
  217       this.warn("conflictingName", data.name)
  218   }
  219 
  220 
  221 , fixDescriptionField: function (data) {
  222     if (data.description && typeof data.description !== 'string') {
  223       this.warn("nonStringDescription")
  224       delete data.description
  225     }
  226     if (data.readme && !data.description)
  227       data.description = extractDescription(data.readme)
  228       if(data.description === undefined) delete data.description;
  229     if (!data.description) this.warn("missingDescription")
  230   }
  231 
  232 , fixReadmeField: function (data) {
  233     if (!data.readme) {
  234       this.warn("missingReadme")
  235       data.readme = "ERROR: No README data found!"
  236     }
  237   }
  238 
  239 , fixBugsField: function(data) {
  240     if (!data.bugs && data.repository && data.repository.url) {
  241       var hosted = hostedGitInfo.fromUrl(data.repository.url)
  242       if(hosted && hosted.bugs()) {
  243         data.bugs = {url: hosted.bugs()}
  244       }
  245     }
  246     else if(data.bugs) {
  247       var emailRe = /^.+@.*\..+$/
  248       if(typeof data.bugs == "string") {
  249         if(emailRe.test(data.bugs))
  250           data.bugs = {email:data.bugs}
  251         else if(url.parse(data.bugs).protocol)
  252           data.bugs = {url: data.bugs}
  253         else
  254           this.warn("nonEmailUrlBugsString")
  255       }
  256       else {
  257         bugsTypos(data.bugs, this.warn)
  258         var oldBugs = data.bugs
  259         data.bugs = {}
  260         if(oldBugs.url) {
  261           if(typeof(oldBugs.url) == "string" && url.parse(oldBugs.url).protocol)
  262             data.bugs.url = oldBugs.url
  263           else
  264             this.warn("nonUrlBugsUrlField")
  265         }
  266         if(oldBugs.email) {
  267           if(typeof(oldBugs.email) == "string" && emailRe.test(oldBugs.email))
  268             data.bugs.email = oldBugs.email
  269           else
  270             this.warn("nonEmailBugsEmailField")
  271         }
  272       }
  273       if(!data.bugs.email && !data.bugs.url) {
  274         delete data.bugs
  275         this.warn("emptyNormalizedBugs")
  276       }
  277     }
  278   }
  279 
  280 , fixHomepageField: function(data) {
  281     if (!data.homepage && data.repository && data.repository.url) {
  282       var hosted = hostedGitInfo.fromUrl(data.repository.url)
  283       if (hosted && hosted.docs()) data.homepage = hosted.docs()
  284     }
  285     if (!data.homepage) return
  286 
  287     if(typeof data.homepage !== "string") {
  288       this.warn("nonUrlHomepage")
  289       return delete data.homepage
  290     }
  291     if(!url.parse(data.homepage).protocol) {
  292       this.warn("missingProtocolHomepage")
  293       data.homepage = "http://" + data.homepage
  294     }
  295   }
  296 
  297 , fixLicenseField: function(data) {
  298     if (!data.license) {
  299       return this.warn("missingLicense")
  300     } else{
  301       if (
  302         typeof(data.license) !== 'string' ||
  303         data.license.length < 1
  304       ) {
  305         this.warn("invalidLicense")
  306       } else {
  307         if (!validateLicense(data.license).validForNewPackages)
  308           this.warn("invalidLicense")
  309       }
  310     }
  311   }
  312 }
  313 
  314 function isValidScopedPackageName(spec) {
  315   if (spec.charAt(0) !== '@') return false
  316 
  317   var rest = spec.slice(1).split('/')
  318   if (rest.length !== 2) return false
  319 
  320   return rest[0] && rest[1] &&
  321     rest[0] === encodeURIComponent(rest[0]) &&
  322     rest[1] === encodeURIComponent(rest[1])
  323 }
  324 
  325 function isCorrectlyEncodedName(spec) {
  326   return !spec.match(/[\/@\s\+%:]/) &&
  327     spec === encodeURIComponent(spec)
  328 }
  329 
  330 function ensureValidName (name, strict, allowLegacyCase) {
  331   if (name.charAt(0) === "." ||
  332       !(isValidScopedPackageName(name) || isCorrectlyEncodedName(name)) ||
  333       (strict && (!allowLegacyCase) && name !== name.toLowerCase()) ||
  334       name.toLowerCase() === "node_modules" ||
  335       name.toLowerCase() === "favicon.ico") {
  336         throw new Error("Invalid name: " + JSON.stringify(name))
  337   }
  338 }
  339 
  340 function modifyPeople (data, fn) {
  341   if (data.author) data.author = fn(data.author)
  342   ;["maintainers", "contributors"].forEach(function (set) {
  343     if (!Array.isArray(data[set])) return;
  344     data[set] = data[set].map(fn)
  345   })
  346   return data
  347 }
  348 
  349 function unParsePerson (person) {
  350   if (typeof person === "string") return person
  351   var name = person.name || ""
  352   var u = person.url || person.web
  353   var url = u ? (" ("+u+")") : ""
  354   var e = person.email || person.mail
  355   var email = e ? (" <"+e+">") : ""
  356   return name+email+url
  357 }
  358 
  359 function parsePerson (person) {
  360   if (typeof person !== "string") return person
  361   var name = person.match(/^([^\(<]+)/)
  362   var url = person.match(/\(([^\)]+)\)/)
  363   var email = person.match(/<([^>]+)>/)
  364   var obj = {}
  365   if (name && name[0].trim()) obj.name = name[0].trim()
  366   if (email) obj.email = email[1];
  367   if (url) obj.url = url[1];
  368   return obj
  369 }
  370 
  371 function addOptionalDepsToDeps (data, warn) {
  372   var o = data.optionalDependencies
  373   if (!o) return;
  374   var d = data.dependencies || {}
  375   Object.keys(o).forEach(function (k) {
  376     d[k] = o[k]
  377   })
  378   data.dependencies = d
  379 }
  380 
  381 function depObjectify (deps, type, warn) {
  382   if (!deps) return {}
  383   if (typeof deps === "string") {
  384     deps = deps.trim().split(/[\n\r\s\t ,]+/)
  385   }
  386   if (!Array.isArray(deps)) return deps
  387   warn("deprecatedArrayDependencies", type)
  388   var o = {}
  389   deps.filter(function (d) {
  390     return typeof d === "string"
  391   }).forEach(function(d) {
  392     d = d.trim().split(/(:?[@\s><=])/)
  393     var dn = d.shift()
  394     var dv = d.join("")
  395     dv = dv.trim()
  396     dv = dv.replace(/^@/, "")
  397     o[dn] = dv
  398   })
  399   return o
  400 }
  401 
  402 function objectifyDeps (data, warn) {
  403   depTypes.forEach(function (type) {
  404     if (!data[type]) return;
  405     data[type] = depObjectify(data[type], type, warn)
  406   })
  407 }
  408 
  409 function bugsTypos(bugs, warn) {
  410   if (!bugs) return
  411   Object.keys(bugs).forEach(function (k) {
  412     if (typos.bugs[k]) {
  413       warn("typo", k, typos.bugs[k], "bugs")
  414       bugs[typos.bugs[k]] = bugs[k]
  415       delete bugs[k]
  416     }
  417   })
  418 }