├── .editorconfig ├── .eslintrc ├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── index.js ├── package.json └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true 4 | }, 5 | "rules": { 6 | // warnings 7 | "no-unused-expressions": 1, 8 | "no-warning-comments": 1, 9 | "no-native-reassign": 1, 10 | "no-invalid-regexp": 1, 11 | "no-debugger": 1, 12 | "no-console": 1, 13 | "no-empty": 1, 14 | "radix": 1, 15 | 16 | // errors 17 | "no-shadow-restricted-names": 2, 18 | "handle-callback-err": 2, 19 | "no-self-compare": 2, 20 | "no-empty-class": 2, 21 | "no-unused-vars": 2, 22 | "no-dupe-keys": 2, 23 | "valid-typeof": 2, 24 | "no-undef": 2, 25 | 26 | // stylistic errors 27 | "quotes": [2, "single", "avoid-escape"], 28 | "no-space-before-semi": 2, 29 | "space-unary-word-ops": 2, 30 | "no-spaced-func": 2, 31 | "yoda": "always", 32 | "new-cap": 2, 33 | 34 | // mute 35 | "no-use-before-define": 0, 36 | "eol-last": 0, 37 | "strict": 0, 38 | "eqeqeq": 0, 39 | "curly": 0 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # tmp files 2 | lib-cov 3 | *.seed 4 | *.log 5 | *.csv 6 | *.dat 7 | *.out 8 | *.pid 9 | *.gz 10 | 11 | # tmp folders 12 | pids/ 13 | logs/ 14 | results/ 15 | coverage/ 16 | 17 | # node.js 18 | node_modules/ 19 | npm-debug.log 20 | 21 | # osx 22 | .DS_Store 23 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '10' 5 | - '8' 6 | - '6' 7 | script: 'make test-travis' 8 | after_script: 'npm install coveralls@2 && cat ./coverage/lcov.info | coveralls' 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SRC = index.js 2 | 3 | include node_modules/make-lint/index.mk 4 | 5 | LINT_CONFIG = .eslintrc 6 | TESTS = test.js 7 | 8 | test: lint 9 | @NODE_ENV=test ./node_modules/.bin/mocha \ 10 | $(TESTS) \ 11 | --bail 12 | 13 | test-cov: 14 | @NODE_ENV=test node \ 15 | node_modules/.bin/istanbul cover \ 16 | ./node_modules/.bin/_mocha \ 17 | -- -u exports \ 18 | $(TESTS) \ 19 | --bail 20 | 21 | test-travis: 22 | @NODE_ENV=test node \ 23 | node_modules/.bin/istanbul cover \ 24 | ./node_modules/.bin/_mocha \ 25 | --report lcovonly \ 26 | -- -u exports \ 27 | $(TESTS) \ 28 | --bail 29 | 30 | .PHONY: test 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # regex-username 2 | [![NPM version][npm-image]][npm-url] 3 | [![build status][travis-image]][travis-url] 4 | [![Test coverage][coveralls-image]][coveralls-url] 5 | [![Downloads][downloads-image]][downloads-url] 6 | 7 | Regular expression for usernames - it follows the same rules that GitHub uses. 8 | 9 | ## Installation 10 | 11 | ```sh 12 | npm install regex-username 13 | ``` 14 | 15 | ## Usage 16 | 17 | ```js 18 | var regex = require('regex-username'); 19 | 20 | regex().test('foo-bar'); // => true 21 | regex().test('foobar'); // => true 22 | regex().test('3foobar'); // => true 23 | regex().test('3foo-bar'); // => true 24 | regex().test('foo-bar-baz'); // => true 25 | regex().test('f'); // => true 26 | regex().test('foo-bar-'); // => false 27 | regex().test('-foo-bar'); // => false 28 | regex().test('foo--bar'); // => false 29 | regex().test('~derp@darp---++asdf'); // => false 30 | regex().test('derp@mail.com'); // => false 31 | regex().test('foo_bar'); // => false 32 | ``` 33 | 34 | ## Why? 35 | Which usernames to allow typically varies between applications. For prototypes 36 | however it's nice to have an off the shelf solution. This module is that 37 | solution. It follows the same rules GitHub uses: 38 | 39 | > Username may only contain alphanumeric characters or single hyphens, and cannot begin or end with a hyphen. 40 | 41 | ## See Also 42 | - [regex-email](https://github.com/regexhq/regex-email) 43 | - [youtube-regex](https://github.com/regexhq/youtube-regex) 44 | 45 | ## License 46 | [MIT](https://tldrlegal.com/license/mit-license) 47 | 48 | [npm-image]: https://img.shields.io/npm/v/regex-username.svg?style=flat-square 49 | [npm-url]: https://www.npmjs.com/package/regex-username 50 | [travis-image]: https://img.shields.io/travis/regexhq/regex-username.svg?style=flat-square 51 | [travis-url]: https://travis-ci.org/regexhq/regex-username 52 | [coveralls-image]: https://img.shields.io/coveralls/regexhq/regex-username.svg?style=flat-square 53 | [coveralls-url]: https://coveralls.io/r/regexhq/regex-username?branch=master 54 | [downloads-image]: http://img.shields.io/npm/dm/regex-username.svg?style=flat-square 55 | [downloads-url]: https://npmjs.org/package/regex-username 56 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Expose username regex, following github conventions 3 | * like: 4 | * _Username may only contain alphanumeric characters 5 | * and only single hyphens, and cannot begin or end with a hyphen._ 6 | * 7 | * 8 | * Example input: 9 | * foo 10 | * foo-bar 11 | */ 12 | module.exports = function regexUsername () { 13 | return /^([a-z\d]+-)*[a-z\d]+$/i; 14 | }; 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "regex-username", 3 | "version": "2.0.0", 4 | "description": "Regular expression for usernames - it follows the same rules that GitHub uses.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "make test" 8 | }, 9 | "repository": "regexhq/regex-username", 10 | "keywords": [ 11 | "regular expression", 12 | "regex", 13 | "regexp", 14 | "user", 15 | "username" 16 | ], 17 | "license": "MIT", 18 | "dependencies": {}, 19 | "devDependencies": { 20 | "istanbul": "^0.3.5", 21 | "make-lint": "^1.0.1", 22 | "mocha": "^2.0.1" 23 | }, 24 | "files": [ 25 | "LICENSE", 26 | "index.js", 27 | "README.md" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies 3 | */ 4 | var assert = require('assert'); 5 | var regex = require('./'); 6 | 7 | /** 8 | * Test 9 | */ 10 | describe('username regex', function() { 11 | it('should match username input', function() { 12 | assert.equal(regex().test('foobar'), true); 13 | assert.equal(regex().test('foo-bar'), true); 14 | assert.equal(regex().test('FooBar'), true); 15 | assert.equal(regex().test('FOOBAR'), true); 16 | assert.equal(regex().test('foo-bar-baz'), true); 17 | assert.equal(regex().test('f'), true); 18 | }); 19 | 20 | it('should catch incorrect input', function() { 21 | assert.equal(regex().test('-foo'), false); 22 | assert.equal(regex().test('foo-'), false); 23 | assert.equal(regex().test('-'), false); 24 | assert.equal(regex().test('foo--bar'), false); 25 | assert.equal(regex().test('foo-bar-'), false); 26 | assert.equal(regex().test('3tobi--ferret'), false); 27 | assert.equal(regex().test('~~derp@darp-----++asdfasdf'), false); 28 | assert.equal(regex().test('foo_bar'), false); 29 | assert.equal(regex().test('_foobar'), false); 30 | assert.equal(regex().test('foobar_'), false); 31 | }); 32 | }); 33 | --------------------------------------------------------------------------------