├── .babelrc ├── .eslintignore ├── src ├── index.ts ├── validator.ts ├── validator.business.ts ├── validator.business.spec.ts └── validator.spec.ts ├── .prettierrc ├── config └── test │ └── jest.json ├── .editorconfig ├── .gitignore ├── typings └── index.d.ts ├── examples ├── ts │ ├── tsconfig.json │ ├── index.html │ ├── package.json │ ├── readme.md │ └── src │ │ └── index.ts └── js │ ├── index.html │ ├── package.json │ ├── readme.md │ └── src │ └── index.js ├── .circleci └── config.yml ├── .eslintrc.js ├── tsconfig.json ├── .vscode └── launch.json ├── LICENSE ├── rollup.config.js ├── README.md └── package.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .rpt2_cache 3 | .vscode 4 | config 5 | dist 6 | *.spec.ts 7 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as isCreditCard from './validator'; 2 | 3 | export { isCreditCard }; 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5", 4 | "endOfLine": "auto" 5 | } 6 | -------------------------------------------------------------------------------- /config/test/jest.json: -------------------------------------------------------------------------------- 1 | { 2 | "rootDir": "../../", 3 | "preset": "ts-jest", 4 | "restoreMocks": true 5 | } 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist/ 4 | *.orig 5 | .idea/ 6 | */src/**/*.js.map 7 | *.log 8 | package-lock.json 9 | coverage/ 10 | .awcache/ 11 | .rpt2_cache 12 | react-app-env.d.ts 13 | .cache 14 | -------------------------------------------------------------------------------- /typings/index.d.ts: -------------------------------------------------------------------------------- 1 | import { FieldValidationFunctionSync } from '@lemoncode/fonk'; 2 | 3 | export namespace isCreditCard { 4 | export const validator: FieldValidationFunctionSync; 5 | export function setErrorMessage(message: string | string[]): void; 6 | } 7 | -------------------------------------------------------------------------------- /examples/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "jsx": "preserve", 5 | "esModuleInterop": true, 6 | "sourceMap": true, 7 | "allowJs": true, 8 | "lib": ["es6", "dom"], 9 | "rootDir": "src", 10 | "moduleResolution": "node" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | fonk-is-credit-card-validator, javascript example 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/ts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | fonk-is-credit-card-validator, typescript example 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | working_directory: ~/test-ci-code 5 | docker: 6 | - image: circleci/node:10 7 | steps: 8 | - checkout 9 | - run: 10 | name: install 11 | command: 'npm install' 12 | - run: 13 | name: validate 14 | command: 'npm run validate' 15 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', 5 | 'prettier/@typescript-eslint', 6 | 'plugin:prettier/recommended', 7 | ], 8 | plugins: ['@typescript-eslint', 'prettier'], 9 | rules: { 10 | '@typescript-eslint/no-explicit-any': 'off', 11 | '@typescript-eslint/explicit-function-return-type': 'off', 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "es6", 5 | "moduleResolution": "node", 6 | "declaration": false, 7 | "noImplicitAny": false, 8 | "sourceMap": true, 9 | "jsx": "react", 10 | "noLib": false, 11 | "allowJs": true, 12 | "suppressImplicitAnyIndexErrors": true, 13 | "skipLibCheck": true, 14 | "esModuleInterop": true 15 | }, 16 | "include": ["./src/**/*"] 17 | } 18 | -------------------------------------------------------------------------------- /examples/js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fonk-is-credit-card-validator-js-example", 3 | "version": "1.0.0", 4 | "description": "fonk-is-credit-card-validator, javascript example", 5 | "main": "index.html", 6 | "scripts": { 7 | "start": "parcel index.html --open" 8 | }, 9 | "dependencies": { 10 | "@lemoncode/fonk": "latest", 11 | "@lemoncode/fonk-is-credit-card-validator": "latest" 12 | }, 13 | "devDependencies": { 14 | "@babel/core": "^7.6.0", 15 | "parcel-bundler": "^1.6.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fonk-is-credit-card-validator-ts-example", 3 | "version": "1.0.0", 4 | "description": "fonk-is-credit-card-validator, typescript example", 5 | "main": "index.html", 6 | "scripts": { 7 | "start": "parcel index.html --open" 8 | }, 9 | "dependencies": { 10 | "@lemoncode/fonk": "latest", 11 | "@lemoncode/fonk-is-credit-card-validator": "latest" 12 | }, 13 | "devDependencies": { 14 | "@babel/core": "^7.6.0", 15 | "parcel-bundler": "^1.6.1" 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node", 6 | "request": "launch", 7 | "name": "Jest selected file", 8 | "program": "${workspaceRoot}/node_modules/jest/bin/jest.js", 9 | "args": [ 10 | "${fileBasenameNoExtension}", 11 | "-c", 12 | "./config/test/jest.json", 13 | "--verbose", 14 | "-i", 15 | "--no-cache", 16 | "--watchAll" 17 | ], 18 | "console": "integratedTerminal", 19 | "internalConsoleOptions": "neverOpen" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /examples/js/readme.md: -------------------------------------------------------------------------------- 1 | # fonk-is-credit-card-validator example 2 | 3 | Example using `fonk-is-credit-card-validator`. 4 | 5 | [![See fonk-is-credit-card-validator example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/lemoncode/fonk-is-credit-card-validator/tree/master/examples/js) 6 | 7 | # About Basefactor + Lemoncode 8 | 9 | We are an innovating team of Javascript experts, passionate about turning your ideas into robust products. 10 | 11 | [Basefactor, consultancy by Lemoncode](http://www.basefactor.com) provides consultancy and coaching services. 12 | 13 | [Lemoncode](http://lemoncode.net/services/en/#en-home) provides training services. 14 | 15 | For the LATAM/Spanish audience we are running an Online Front End Master degree, more info: http://lemoncode.net/master-frontend 16 | -------------------------------------------------------------------------------- /examples/ts/readme.md: -------------------------------------------------------------------------------- 1 | # fonk-is-credit-card-validator example 2 | 3 | Example using `fonk-is-credit-card-validator`. 4 | 5 | [![See fonk-is-credit-card-validator example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/lemoncode/fonk-is-credit-card-validator/tree/master/examples/ts) 6 | 7 | # About Basefactor + Lemoncode 8 | 9 | We are an innovating team of Javascript experts, passionate about turning your ideas into robust products. 10 | 11 | [Basefactor, consultancy by Lemoncode](http://www.basefactor.com) provides consultancy and coaching services. 12 | 13 | [Lemoncode](http://lemoncode.net/services/en/#en-home) provides training services. 14 | 15 | For the LATAM/Spanish audience we are running an Online Front End Master degree, more info: http://lemoncode.net/master-frontend 16 | -------------------------------------------------------------------------------- /src/validator.ts: -------------------------------------------------------------------------------- 1 | import { FieldValidationFunctionSync } from '@lemoncode/fonk'; 2 | import { isCreditCard } from './validator.business'; 3 | 4 | const VALIDATOR_TYPE = 'IS_CREDIT_CARD'; 5 | 6 | let defaultMessage = 'The value must be a valid credit card'; 7 | export const setErrorMessage = message => (defaultMessage = message); 8 | 9 | const validateType = (value: string) => typeof value === 'string'; 10 | 11 | const isDefined = value => value !== void 0 && value !== null && value !== ''; 12 | 13 | export const validator: FieldValidationFunctionSync = fieldValidatorArgs => { 14 | const { value, message = defaultMessage } = fieldValidatorArgs; 15 | 16 | const succeeded = 17 | !isDefined(value) || (validateType(value) && isCreditCard(value)); 18 | 19 | return { 20 | succeeded, 21 | message: succeeded ? '' : (message as string), 22 | type: VALIDATOR_TYPE, 23 | }; 24 | }; 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Lemoncode 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. 22 | -------------------------------------------------------------------------------- /examples/js/src/index.js: -------------------------------------------------------------------------------- 1 | import { createFormValidation } from '@lemoncode/fonk'; 2 | import { isCreditCard } from '@lemoncode/fonk-is-credit-card-validator'; 3 | 4 | const validationSchema = { 5 | field: { 6 | myField: [isCreditCard.validator], 7 | }, 8 | }; 9 | 10 | const formValidation = createFormValidation(validationSchema); 11 | 12 | Promise.all([ 13 | formValidation.validateField('myField', '6234917882863855suffix'), 14 | formValidation.validateField('myField', '375556917985515'), 15 | ]).then(([failedResult, succeededResult]) => { 16 | document.getElementById('app').innerHTML = ` 17 |
18 |

Example with failed result:

19 | 20 |
21 |   formValidation.validateField('myField', '6234917882863855suffix')
22 | 
23 | 24 |

Result:

25 |
26 | ${JSON.stringify(failedResult, null, 2)}
27 | 
28 |
29 | 30 |
31 |

Example with succeeded result:

32 | 33 |
34 | formValidation.validateField('myField', '375556917985515')
35 | 
36 | 37 |

Result:

38 |
39 | ${JSON.stringify(succeededResult, null, 2)}
40 | 
41 |
42 | `; 43 | }); 44 | -------------------------------------------------------------------------------- /examples/ts/src/index.ts: -------------------------------------------------------------------------------- 1 | import { ValidationSchema, createFormValidation } from '@lemoncode/fonk'; 2 | import { isCreditCard } from '@lemoncode/fonk-is-credit-card-validator'; 3 | 4 | const validationSchema: ValidationSchema = { 5 | field: { 6 | myField: [isCreditCard.validator], 7 | }, 8 | }; 9 | 10 | const formValidation = createFormValidation(validationSchema); 11 | 12 | Promise.all([ 13 | formValidation.validateField('myField', '6234917882863855suffix'), 14 | formValidation.validateField('myField', '375556917985515'), 15 | ]).then(([failedResult, succeededResult]) => { 16 | document.getElementById('app').innerHTML = ` 17 |
18 |

Example with failed result:

19 | 20 |
21 |   formValidation.validateField('myField', '6234917882863855suffix')
22 | 
23 | 24 |

Result:

25 |
26 | ${JSON.stringify(failedResult, null, 2)}
27 | 
28 |
29 | 30 |
31 |

Example with succeeded result:

32 | 33 |
34 | formValidation.validateField('myField', '375556917985515')
35 | 
36 | 37 |

Result:

38 |
39 | ${JSON.stringify(succeededResult, null, 2)}
40 | 
41 |
42 | `; 43 | }); 44 | -------------------------------------------------------------------------------- /src/validator.business.ts: -------------------------------------------------------------------------------- 1 | /* 2 | This code is based on the implementation of the credit card validator of the 'validatorjs' library: 3 | https://github.com/validatorjs/validator.js/blob/master/src/lib/isCreditCard.js 4 | 5 | You can find more information about the library in its github repository: 6 | https://github.com/validatorjs/validator.js 7 | */ 8 | 9 | /* eslint-disable max-len */ 10 | const creditCard = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11}|6[27][0-9]{14})$/; 11 | /* eslint-enable max-len */ 12 | 13 | export const isCreditCard = (str: string) => { 14 | const sanitized: string = str.replace(/[- ]+/g, ''); 15 | if (!creditCard.test(sanitized)) { 16 | return false; 17 | } 18 | 19 | let sum = 0; 20 | let digit: string; 21 | let tmpNum: number; 22 | let shouldDouble = false; 23 | for (let i = sanitized.length - 1; i >= 0; i--) { 24 | digit = sanitized.substring(i, i + 1); 25 | tmpNum = parseInt(digit, 10); 26 | if (shouldDouble) { 27 | tmpNum *= 2; 28 | tmpNum >= 10 ? (sum += (tmpNum % 10) + 1) : (sum += tmpNum); 29 | } else { 30 | sum += tmpNum; 31 | } 32 | shouldDouble = !shouldDouble; 33 | } 34 | return !!(sum % 10 === 0 ? sanitized : false); 35 | }; 36 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from 'rollup-plugin-node-resolve'; 2 | import babel from 'rollup-plugin-babel'; 3 | import commonjs from 'rollup-plugin-commonjs'; 4 | import typescript from 'rollup-plugin-typescript2'; 5 | import { terser } from 'rollup-plugin-terser'; 6 | import { DEFAULT_EXTENSIONS } from '@babel/core'; 7 | import pkg from './package.json'; 8 | 9 | const builds = [ 10 | { format: 'esm', minify: false }, 11 | { format: 'cjs', minify: false }, 12 | { format: 'umd', minify: false }, 13 | { format: 'umd', minify: true }, 14 | ]; 15 | const extensions = [...DEFAULT_EXTENSIONS, '.ts']; 16 | 17 | export default builds.map(({ format, minify }) => { 18 | const minExtension = minify ? '.min' : ''; 19 | return { 20 | input: 'src/index.ts', 21 | output: { 22 | name: pkg.name, 23 | exports: 'named', 24 | file: `dist/${pkg.name}.${format}${minExtension}.js`, 25 | format, 26 | globals: { 27 | '@lemoncode/fonk': 'Fonk', 28 | }, // Necessary for externals libraries and umd format 29 | }, 30 | external: Object.keys(pkg.peerDependencies || {}), 31 | plugins: [ 32 | resolve(), 33 | commonjs(), 34 | typescript({ 35 | tsconfig: 'tsconfig.json', 36 | rollupCommonJSResolveHack: true, // To be compatible with commonjs plugin 37 | }), 38 | babel({ 39 | extensions, 40 | exclude: 'node_modules/**', 41 | }), 42 | minify ? terser() : null, 43 | ], 44 | }; 45 | }); 46 | -------------------------------------------------------------------------------- /src/validator.business.spec.ts: -------------------------------------------------------------------------------- 1 | import { isCreditCard } from './validator.business'; 2 | 3 | describe('is-credit-card business specs', () => { 4 | it('should return succeeded validation when it feeds value is a valid credit card', () => { 5 | // Arrange 6 | const values = [ 7 | '375556917985515', 8 | '36050234196908', 9 | '4716461583322103', 10 | '4716-2210-5188-5662', 11 | '4929 7226 5379 7141', 12 | '5398228707871527', 13 | '6283875070985593', 14 | '6263892624162870', 15 | '6234917882863855', 16 | '6234698580215388', 17 | '6226050967750613', 18 | '6246281879460688', 19 | '2222155765072228', 20 | '2225855203075256', 21 | '2720428011723762', 22 | '2718760626256570', 23 | '6765780016990268', 24 | ]; 25 | 26 | // Act 27 | const results = values.map(isCreditCard); 28 | 29 | // Assert 30 | results.map(result => expect(result).toBeTruthy()); 31 | }); 32 | 33 | it('should return failed validation when it feeds value is not a valid credit card', () => { 34 | // Arrange 35 | const values = [ 36 | 'foo', 37 | 'test', 38 | '5398228707871528', 39 | '2718760626256571', 40 | '2721465526338453', 41 | '2220175103860763', 42 | '375556917985515999999993', 43 | '899999996234917882863855', 44 | 'prefix6234917882863855', 45 | '623491788middle2863855', 46 | '6234917882863855suffix', 47 | ]; 48 | 49 | // Act 50 | const results = values.map(isCreditCard); 51 | 52 | // Assert 53 | results.map(result => expect(result).toBeFalsy()); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fonk-is-credit-card-validator 2 | 3 | [![CircleCI](https://badgen.net/github/status/Lemoncode/fonk-is-credit-card-validator/master?icon=circleci&label=circleci)](https://circleci.com/gh/Lemoncode/fonk-is-credit-card-validator/tree/master) 4 | [![NPM Version](https://badgen.net/npm/v/@lemoncode/fonk-is-credit-card-validator?icon=npm&label=npm)](https://www.npmjs.com/package/@lemoncode/fonk-is-credit-card-validator) 5 | [![bundle-size](https://badgen.net/bundlephobia/min/@lemoncode/fonk-is-credit-card-validator)](https://bundlephobia.com/result?p=@lemoncode/fonk-is-credit-card-validator) 6 | 7 | This is a [fonk](https://github.com/Lemoncode/fonk) microlibrary that brings validation capabilities to: 8 | 9 | - Validate if a field of a form is a valid credit card 10 | 11 | How to install it: 12 | 13 | ```bash 14 | npm install @lemoncode/fonk-is-credit-card-validator --save 15 | ``` 16 | 17 | How to add it to an existing form validation schema: 18 | 19 | We have the following form model: 20 | 21 | ``` 22 | const myFormValues = { 23 | clientId: 1, 24 | creditCard: '375556917985515' 25 | } 26 | ``` 27 | 28 | We can add a isCreditCard validation to the myFormValues 29 | 30 | ```javascript 31 | import { isCreditCard } from '@lemoncode/fonk-is-credit-card-validator'; 32 | 33 | const validationSchema = { 34 | field: { 35 | creditCard: [isCreditCard.validator], 36 | }, 37 | }; 38 | ``` 39 | 40 | You can customize the error message displayed in two ways: 41 | 42 | - Globally, replace the default error message in all validationSchemas (e.g. porting to spanish): 43 | 44 | ```javascript 45 | import { isCreditCard } from '@lemoncode/fonk-is-credit-card-validator'; 46 | 47 | isCreditCard.setErrorMessage( 48 | 'El valor debe de ser un número de tarjeta de crédito válido' 49 | ); 50 | ``` 51 | 52 | - Locally just override the error message for this validationSchema: 53 | 54 | ```javascript 55 | import { isCreditCard } from '@lemoncode/fonk-is-credit-card-validator'; 56 | 57 | const validationSchema = { 58 | field: { 59 | creditCard: [ 60 | { 61 | validator: isCreditCard.validator, 62 | message: 'Error message only updated for the validation schema', 63 | }, 64 | ], 65 | }, 66 | }; 67 | ``` 68 | 69 | Please, refer to [fonk](https://github.com/Lemoncode/fonk) to know more. 70 | 71 | ## License 72 | 73 | [MIT](./LICENSE) 74 | 75 | # About Basefactor + Lemoncode 76 | 77 | We are an innovating team of Javascript experts, passionate about turning your ideas into robust products. 78 | 79 | [Basefactor, consultancy by Lemoncode](http://www.basefactor.com) provides consultancy and coaching services. 80 | 81 | [Lemoncode](http://lemoncode.net/services/en/#en-home) provides training services. 82 | 83 | For the LATAM/Spanish audience we are running an Online Front End Master degree, more info: http://lemoncode.net/master-frontend 84 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@lemoncode/fonk-is-credit-card-validator", 3 | "version": "1.0.1", 4 | "description": "This is a [fonk](https://github.com/Lemoncode/fonk) microlibrary that brings validation capabilities to validate if a field of a form is a valid credit card", 5 | "main": "dist/@lemoncode/fonk-is-credit-card-validator.cjs.js", 6 | "module": "dist/@lemoncode/fonk-is-credit-card-validator.esm.js", 7 | "typings": "typings/index.d.ts", 8 | "files": [ 9 | "dist", 10 | "typings" 11 | ], 12 | "scripts": { 13 | "build": "npm run clean && rollup --config", 14 | "clean": "rimraf dist .rpt2_cache package-lock.json", 15 | "validate": "npm run lint && npm run build && npm run test && npm run test:size", 16 | "lint": "eslint src --ext .ts ", 17 | "lint:fix": "npm run lint -- --fix", 18 | "test": "jest -c ./config/test/jest.json --verbose", 19 | "test:watch": "jest -c ./config/test/jest.json --verbose --watchAll -i", 20 | "test:size": "bundlesize", 21 | "deploy": "npm run validate && np", 22 | "deploy:beta": "npm run validate && np --tag=beta --any-branch" 23 | }, 24 | "bundlesize": [ 25 | { 26 | "path": "./dist/**/*.js", 27 | "maxSize": "1.2kB" 28 | } 29 | ], 30 | "repository": { 31 | "type": "git", 32 | "url": "git+https://github.com/Lemoncode/fonk-is-credit-card-validator.git" 33 | }, 34 | "keywords": [ 35 | "isCreditCard", 36 | "validator", 37 | "fonk", 38 | "form validation", 39 | "validate", 40 | "sync validation" 41 | ], 42 | "author": "Lemoncode", 43 | "license": "MIT", 44 | "bugs": { 45 | "url": "https://github.com/Lemoncode/fonk-is-credit-card-validator/issues" 46 | }, 47 | "homepage": "https://github.com/Lemoncode/fonk-is-credit-card-validator#readme", 48 | "peerDependencies": { 49 | "@lemoncode/fonk": "latest" 50 | }, 51 | "devDependencies": { 52 | "@babel/cli": "^7.5.5", 53 | "@babel/core": "^7.5.5", 54 | "@babel/preset-env": "^7.5.5", 55 | "@lemoncode/fonk": "latest", 56 | "@types/jest": "^24.0.18", 57 | "@typescript-eslint/eslint-plugin": "^2.0.0", 58 | "@typescript-eslint/parser": "^2.0.0", 59 | "bundlesize": "0.18.0", 60 | "eslint": "^6.2.1", 61 | "eslint-config-prettier": "^6.1.0", 62 | "eslint-plugin-prettier": "^3.1.0", 63 | "husky": "^3.0.4", 64 | "jest": "^24.9.0", 65 | "lint-staged": "^9.2.3", 66 | "np": "^5.0.3", 67 | "prettier": "^1.18.2", 68 | "pretty-quick": "^1.11.1", 69 | "rimraf": "^3.0.0", 70 | "rollup": "^1.20.0", 71 | "rollup-plugin-babel": "^4.3.3", 72 | "rollup-plugin-commonjs": "^10.0.2", 73 | "rollup-plugin-node-resolve": "^5.2.0", 74 | "rollup-plugin-terser": "^5.1.1", 75 | "rollup-plugin-typescript2": "^0.22.1", 76 | "ts-jest": "^24.0.2", 77 | "typescript": "^3.5.3" 78 | }, 79 | "husky": { 80 | "hooks": { 81 | "pre-commit": "lint-staged" 82 | } 83 | }, 84 | "lint-staged": { 85 | "src/**/*.{ts,tsx}": [ 86 | "npm run lint:fix", 87 | "pretty-quick — staged", 88 | "git add" 89 | ] 90 | }, 91 | "publishConfig": { 92 | "registry": "https://registry.npmjs.org/", 93 | "access": "public" 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/validator.spec.ts: -------------------------------------------------------------------------------- 1 | import { validator, setErrorMessage } from './validator'; 2 | 3 | const VALIDATOR_TYPE = 'IS_CREDIT_CARD'; 4 | const DEFAULT_MESSAGE = 'The value must be a valid credit card'; 5 | 6 | describe('fonk-is-credit-card-validator specs', () => { 7 | it('should return succeeded validation when it feeds value equals undefined', () => { 8 | // Arrange 9 | const value = void 0; 10 | 11 | // Act 12 | const result = validator({ value }); 13 | 14 | // Assert 15 | expect(result).toEqual({ 16 | succeeded: true, 17 | message: '', 18 | type: VALIDATOR_TYPE, 19 | }); 20 | }); 21 | 22 | it('should return succeeded validation when it feeds value equals null', () => { 23 | // Arrange 24 | const value = null; 25 | 26 | // Act 27 | const result = validator({ value }); 28 | 29 | // Assert 30 | expect(result).toEqual({ 31 | succeeded: true, 32 | message: '', 33 | type: VALIDATOR_TYPE, 34 | }); 35 | }); 36 | 37 | it('should return succeeded validation when it feeds value equals empty string', () => { 38 | // Arrange 39 | const value = ''; 40 | 41 | // Act 42 | const result = validator({ value }); 43 | 44 | // Assert 45 | expect(result).toEqual({ 46 | succeeded: true, 47 | message: '', 48 | type: VALIDATOR_TYPE, 49 | }); 50 | }); 51 | 52 | it('should overwrite default message when it feeds value and message', () => { 53 | // Arrange 54 | const value = 'test'; 55 | const message = 'other message'; 56 | 57 | // Act 58 | const result = validator({ value, message }); 59 | 60 | // Assert 61 | expect(result).toEqual({ 62 | succeeded: false, 63 | message: 'other message', 64 | type: VALIDATOR_TYPE, 65 | }); 66 | }); 67 | 68 | it('should return failed validation when it feeds value is true', () => { 69 | // Arrange 70 | const value = true; 71 | 72 | // Act 73 | const result = validator({ 74 | value, 75 | }); 76 | 77 | // Assert 78 | expect(result).toEqual({ 79 | succeeded: false, 80 | message: DEFAULT_MESSAGE, 81 | type: VALIDATOR_TYPE, 82 | }); 83 | }); 84 | 85 | it('should return failed validation when it feeds value is false', () => { 86 | // Arrange 87 | const value = false; 88 | 89 | // Act 90 | const result = validator({ 91 | value, 92 | }); 93 | 94 | // Assert 95 | expect(result).toEqual({ 96 | succeeded: false, 97 | message: DEFAULT_MESSAGE, 98 | type: VALIDATOR_TYPE, 99 | }); 100 | }); 101 | 102 | it('should return failed validation when it feeds value is an object', () => { 103 | // Arrange 104 | const value = {}; 105 | 106 | // Act 107 | const result = validator({ 108 | value, 109 | }); 110 | 111 | // Assert 112 | expect(result).toEqual({ 113 | succeeded: false, 114 | message: DEFAULT_MESSAGE, 115 | type: VALIDATOR_TYPE, 116 | }); 117 | }); 118 | 119 | it('should return failed validation when it feeds value is a function', () => { 120 | // Arrange 121 | const value = () => null; 122 | 123 | // Act 124 | const result = validator({ 125 | value, 126 | }); 127 | 128 | // Assert 129 | expect(result).toEqual({ 130 | succeeded: false, 131 | message: DEFAULT_MESSAGE, 132 | type: VALIDATOR_TYPE, 133 | }); 134 | }); 135 | 136 | it('should return failed validation when it feeds value is an array', () => { 137 | // Arrange 138 | const value = []; 139 | 140 | // Act 141 | const result = validator({ 142 | value, 143 | }); 144 | 145 | // Assert 146 | expect(result).toEqual({ 147 | succeeded: false, 148 | message: DEFAULT_MESSAGE, 149 | type: VALIDATOR_TYPE, 150 | }); 151 | }); 152 | 153 | it('should return succeeded validation when it feeds value is a valid credit card', () => { 154 | // Arrange 155 | const value = '4716-2210-5188-5662'; 156 | 157 | // Act 158 | const result = validator({ 159 | value, 160 | }); 161 | 162 | // Assert 163 | expect(result).toEqual({ 164 | succeeded: true, 165 | message: '', 166 | type: VALIDATOR_TYPE, 167 | }); 168 | }); 169 | 170 | it('should return failed validation when it feeds value is not a valid credit card', () => { 171 | // Arrange 172 | const value = '4716-2210-5188-5662X'; 173 | 174 | // Act 175 | const result = validator({ 176 | value, 177 | }); 178 | 179 | // Assert 180 | expect(result).toEqual({ 181 | succeeded: false, 182 | message: DEFAULT_MESSAGE, 183 | type: VALIDATOR_TYPE, 184 | }); 185 | }); 186 | 187 | it('should overwrite default message when it feeds value and calls to setErrorMessage', () => { 188 | // Arrange 189 | const value = 'test'; 190 | 191 | setErrorMessage('other message'); 192 | 193 | // Act 194 | const result = validator({ value }); 195 | 196 | // Assert 197 | expect(result).toEqual({ 198 | succeeded: false, 199 | message: 'other message', 200 | type: VALIDATOR_TYPE, 201 | }); 202 | }); 203 | }); 204 | --------------------------------------------------------------------------------