11cb0ef41Sopenharmony_ci'use strict'
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_civar scopedPackagePattern = new RegExp('^(?:@([^/]+?)[/])?([^/]+?)$')
41cb0ef41Sopenharmony_civar builtins = require('builtins')
51cb0ef41Sopenharmony_civar blacklist = [
61cb0ef41Sopenharmony_ci  'node_modules',
71cb0ef41Sopenharmony_ci  'favicon.ico',
81cb0ef41Sopenharmony_ci]
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_cifunction validate (name) {
111cb0ef41Sopenharmony_ci  var warnings = []
121cb0ef41Sopenharmony_ci  var errors = []
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci  if (name === null) {
151cb0ef41Sopenharmony_ci    errors.push('name cannot be null')
161cb0ef41Sopenharmony_ci    return done(warnings, errors)
171cb0ef41Sopenharmony_ci  }
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci  if (name === undefined) {
201cb0ef41Sopenharmony_ci    errors.push('name cannot be undefined')
211cb0ef41Sopenharmony_ci    return done(warnings, errors)
221cb0ef41Sopenharmony_ci  }
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci  if (typeof name !== 'string') {
251cb0ef41Sopenharmony_ci    errors.push('name must be a string')
261cb0ef41Sopenharmony_ci    return done(warnings, errors)
271cb0ef41Sopenharmony_ci  }
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci  if (!name.length) {
301cb0ef41Sopenharmony_ci    errors.push('name length must be greater than zero')
311cb0ef41Sopenharmony_ci  }
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci  if (name.match(/^\./)) {
341cb0ef41Sopenharmony_ci    errors.push('name cannot start with a period')
351cb0ef41Sopenharmony_ci  }
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  if (name.match(/^_/)) {
381cb0ef41Sopenharmony_ci    errors.push('name cannot start with an underscore')
391cb0ef41Sopenharmony_ci  }
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci  if (name.trim() !== name) {
421cb0ef41Sopenharmony_ci    errors.push('name cannot contain leading or trailing spaces')
431cb0ef41Sopenharmony_ci  }
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  // No funny business
461cb0ef41Sopenharmony_ci  blacklist.forEach(function (blacklistedName) {
471cb0ef41Sopenharmony_ci    if (name.toLowerCase() === blacklistedName) {
481cb0ef41Sopenharmony_ci      errors.push(blacklistedName + ' is a blacklisted name')
491cb0ef41Sopenharmony_ci    }
501cb0ef41Sopenharmony_ci  })
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  // Generate warnings for stuff that used to be allowed
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  // core module names like http, events, util, etc
551cb0ef41Sopenharmony_ci  builtins({ version: '*' }).forEach(function (builtin) {
561cb0ef41Sopenharmony_ci    if (name.toLowerCase() === builtin) {
571cb0ef41Sopenharmony_ci      warnings.push(builtin + ' is a core module name')
581cb0ef41Sopenharmony_ci    }
591cb0ef41Sopenharmony_ci  })
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  if (name.length > 214) {
621cb0ef41Sopenharmony_ci    warnings.push('name can no longer contain more than 214 characters')
631cb0ef41Sopenharmony_ci  }
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  // mIxeD CaSe nAMEs
661cb0ef41Sopenharmony_ci  if (name.toLowerCase() !== name) {
671cb0ef41Sopenharmony_ci    warnings.push('name can no longer contain capital letters')
681cb0ef41Sopenharmony_ci  }
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  if (/[~'!()*]/.test(name.split('/').slice(-1)[0])) {
711cb0ef41Sopenharmony_ci    warnings.push('name can no longer contain special characters ("~\'!()*")')
721cb0ef41Sopenharmony_ci  }
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  if (encodeURIComponent(name) !== name) {
751cb0ef41Sopenharmony_ci    // Maybe it's a scoped package name, like @user/package
761cb0ef41Sopenharmony_ci    var nameMatch = name.match(scopedPackagePattern)
771cb0ef41Sopenharmony_ci    if (nameMatch) {
781cb0ef41Sopenharmony_ci      var user = nameMatch[1]
791cb0ef41Sopenharmony_ci      var pkg = nameMatch[2]
801cb0ef41Sopenharmony_ci      if (encodeURIComponent(user) === user && encodeURIComponent(pkg) === pkg) {
811cb0ef41Sopenharmony_ci        return done(warnings, errors)
821cb0ef41Sopenharmony_ci      }
831cb0ef41Sopenharmony_ci    }
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci    errors.push('name can only contain URL-friendly characters')
861cb0ef41Sopenharmony_ci  }
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  return done(warnings, errors)
891cb0ef41Sopenharmony_ci}
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_civar done = function (warnings, errors) {
921cb0ef41Sopenharmony_ci  var result = {
931cb0ef41Sopenharmony_ci    validForNewPackages: errors.length === 0 && warnings.length === 0,
941cb0ef41Sopenharmony_ci    validForOldPackages: errors.length === 0,
951cb0ef41Sopenharmony_ci    warnings: warnings,
961cb0ef41Sopenharmony_ci    errors: errors,
971cb0ef41Sopenharmony_ci  }
981cb0ef41Sopenharmony_ci  if (!result.warnings.length) {
991cb0ef41Sopenharmony_ci    delete result.warnings
1001cb0ef41Sopenharmony_ci  }
1011cb0ef41Sopenharmony_ci  if (!result.errors.length) {
1021cb0ef41Sopenharmony_ci    delete result.errors
1031cb0ef41Sopenharmony_ci  }
1041cb0ef41Sopenharmony_ci  return result
1051cb0ef41Sopenharmony_ci}
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_cimodule.exports = validate
108