diff --git a/.babelrc b/.babelrc index 522e1d3..9d032c1 100644 --- a/.babelrc +++ b/.babelrc @@ -1,21 +1,24 @@ { - "presets": [ - "es2015", - "stage-3" - ], - "plugins": [ - "transform-class-properties" - ], - "env": { - "test": { - "plugins": [ - ["istanbul", { - "exclude": [ - "tests", - "test-utils" - ] - }] - ] + "presets": [ + "es2015", + "stage-3" + ], + "plugins": [ + "transform-class-properties" + ], + "env": { + "test": { + "plugins": [ + [ + "istanbul", + { + "exclude": [ + "tests", + "test-utils" + ] + } + ] + ] + } } - } } diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..9571781 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +end_of_line = lf +max_line_length = null diff --git a/.eslintrc b/.eslintrc index 0774f00..f432c59 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,40 +1,47 @@ { - "parser": "babel-eslint", - "extends": "airbnb", - "plugins": [ - "react", - "jsx-a11y", - "import" - ], - "rules": { - "indent": [ - "error", - 4 + "parser": "babel-eslint", + "extends": "airbnb", + "plugins": [ + "react", + "jsx-a11y", + "import" ], - "no-plusplus": [ - "error", - { - "allowForLoopAfterthoughts": true - } - ], - "no-console": [ - "error", - { - "allow": ["warn", "error"] - } - ], - "jsx-a11y/href-no-hash": "off", - "jsx-a11y/anchor-is-valid": ["warn", { "aspects": ["invalidHref"] }] - }, - "globals": { - "module": true, - "window": true, - "XMLHttpRequest": true, - "document": true, - "FormData": true, - "FileList": true, - "describe": true, - "it": true, - "assert": true - } + "rules": { + "indent": [ + "error", + 4, + { + "SwitchCase": 1 + } + ], + "no-plusplus": [ + "error", + { + "allowForLoopAfterthoughts": true + } + ], + "no-console": [ + "error", + { + "allow": [ + "warn", + "error" + ] + } + ], + "jsx-a11y/href-no-hash": "off", + "jsx-a11y/anchor-is-valid": [ + "warn", + { + "aspects": [ + "invalidHref" + ] + } + ] + }, + "env": { + "browser": true, + "node": true, + "jasmine": true + } } diff --git a/esdoc.json b/esdoc.json index 24c1361..6297967 100644 --- a/esdoc.json +++ b/esdoc.json @@ -1,15 +1,15 @@ { - "source": "./src", - "destination": "./docs", - "plugins": [ - { - "name": "esdoc-standard-plugin" - }, - { - "name": "esdoc-ecmascript-proposal-plugin", - "option": { - "all": true - } - } - ] -} \ No newline at end of file + "source": "./src", + "destination": "./docs", + "plugins": [ + { + "name": "esdoc-standard-plugin" + }, + { + "name": "esdoc-ecmascript-proposal-plugin", + "option": { + "all": true + } + } + ] +} diff --git a/example/ajax.json b/example/ajax.json index 7fac90f..4eb8fad 100644 --- a/example/ajax.json +++ b/example/ajax.json @@ -1,15 +1,15 @@ { - "validationErrors": { - "base": [ - "Form validation error", - "Error 145" - ], - "name": [ - "Name is required", - "Another error" - ], - "email": [ - "E-mail is not valid" - ] - } -} \ No newline at end of file + "validationErrors": { + "base": [ + "Form validation error", + "Error 145" + ], + "name": [ + "Name is required", + "Another error" + ], + "email": [ + "E-mail is not valid" + ] + } +} diff --git a/example/ajaxSuccess.json b/example/ajaxSuccess.json index 70ce2e4..3cb32a2 100644 --- a/example/ajaxSuccess.json +++ b/example/ajaxSuccess.json @@ -1,3 +1,3 @@ { - "redirect": "/success.php" -} \ No newline at end of file + "redirect": "/success.php" +} diff --git a/example/bootstrap.html b/example/bootstrap.html index 06f4c7e..aa1173d 100644 --- a/example/bootstrap.html +++ b/example/bootstrap.html @@ -3,13 +3,9 @@ - + Jedi Validate - Lightweight form validation component. - @@ -271,9 +267,9 @@

Jedi Validate } }, callbacks: { - success: function(response) { + success: function (response) { }, - error: function(errors) { + error: function (errors) { } } }; @@ -304,7 +300,7 @@

Jedi Validate }, rules: { phone: { - required: [true, function(oldData) { + required: [true, function (oldData) { const newData = validator.collect('checkbox'); // manual data recollect for concrete field return !!newData['checkbox']; }], diff --git a/jsconfig.json b/jsconfig.json index 0136d6f..a54b93b 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,16 +1,18 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=759670 - // for the documentation about the jsconfig.json format - "compilerOptions": { - "target": "es6", - "module": "commonjs", - "allowSyntheticDefaultImports": true - }, - "exclude": [ - "node_modules", - "bower_components", - "jspm_packages", - "tmp", - "temp" - ] + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "allowSyntheticDefaultImports": true + }, + "exclude": [ + "node_modules", + "bower_components", + "jspm_packages", + "tmp", + "temp", + "cache", + "coverage", + "dist", + "docs" + ] } diff --git a/package.json b/package.json index cdc23bc..baabcf7 100644 --- a/package.json +++ b/package.json @@ -1,75 +1,80 @@ { - "name": "jedi-validate", - "version": "1.3.9", - "description": "A lightweight form validation component", - "main": "./dist/jedi-validate.js", - "scripts": { - "test": "cross-env NODE_ENV=test karma start --single-run", - "tests": "cross-env NODE_ENV=test karma start", - "start": "rimraf ./dist && webpack-dev-server --hot --inline --progress --colors --watch --port 4000", - "build": "rimraf ./docs && npm run esdoc && rimraf ./dist && webpack --progress --colors", - "lint": "eslint src/**/*.js", - "fix": "eslint src/**/*.js --fix", - "fix-tests": "eslint tests/**/*.js --fix", - "esdoc": "esdoc -c esdoc.json" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/dmitriytat/jedi-validate.git" - }, - "keywords": [ - "form", - "validation", - "formdata" - ], - "author": "Dmitriy Tatarintsev ", - "license": "MIT", - "bugs": { - "url": "https://github.com/dmitriytat/jedi-validate/issues" - }, - "homepage": "https://github.com/dmitriytat/jedi-validate#readme", - "devDependencies": { - "@types/chai": "^4.0.4", - "@types/mocha": "^2.2.43", - "@types/should": "^11.2.0", - "@types/sinon": "^2.3.5", - "babel-core": "^6.26.0", - "babel-eslint": "^8.0.1", - "babel-loader": "^7.1.2", - "babel-plugin-istanbul": "^4.1.5", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-preset-es2015": "^6.24.1", - "babel-preset-stage-3": "^6.24.1", - "bootstrap": "^3.3.7", - "chai": "^4.1.2", - "cross-env": "^5.0.5", - "esdoc": "^1.0.3", - "esdoc-ecmascript-proposal-plugin": "^1.0.0", - "esdoc-standard-plugin": "^1.0.0", - "eslint": "^4.8.0", - "eslint-config-airbnb": "^15.1.0", - "eslint-loader": "^1.9.0", - "eslint-plugin-import": "^2.7.0", - "eslint-plugin-jsx-a11y": "^6.0.2", - "eslint-plugin-react": "^7.4.0", - "extract-text-webpack-plugin": "^3.0.0", - "json-loader": "^0.5.7", - "karma": "^1.7.1", - "karma-chai": "^0.1.0", - "karma-chrome-launcher": "^2.2.0", - "karma-coverage": "^1.1.1", - "karma-coveralls": "^1.1.2", - "karma-mocha": "^1.3.0", - "karma-mocha-reporter": "^2.2.4", - "karma-webpack": "2.0.4", - "mocha": "^3.5.3", - "rimraf": "^2.6.2", - "should": "^13.1.0", - "sinon": "^4.0.0", - "webpack": "^3.6.0", - "webpack-dev-server": "^2.9.1" - }, - "dependencies": { - "deepmerge": "^1.5.2" - } + "name": "jedi-validate", + "version": "1.3.9", + "description": "A lightweight form validation component", + "main": "./dist/jedi-validate.js", + "scripts": { + "prestart": "rimraf ./dist", + "start": "webpack-dev-server --hot --inline --progress --colors --watch --port 4000", + "prebuild": "npm run esdoc && rimraf ./dist", + "build": "cross-env NODE_ENV=production webpack --progress --colors", + "lint": "eslint src/**/*.js", + "fix": "eslint src/**/*.js --fix", + "fix-tests": "eslint tests/**/*.js --fix", + "preesdoc": "rimraf ./docs", + "esdoc": "esdoc -c esdoc.json", + "test": "cross-env NODE_ENV=test karma start --single-run", + "tests": "cross-env NODE_ENV=test karma start" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/dmitriytat/jedi-validate.git" + }, + "keywords": [ + "form", + "validation", + "formdata" + ], + "author": "Dmitriy Tatarintsev ", + "license": "MIT", + "bugs": { + "url": "https://github.com/dmitriytat/jedi-validate/issues" + }, + "homepage": "https://github.com/dmitriytat/jedi-validate#readme", + "devDependencies": { + "@types/chai": "^4.0.4", + "@types/mocha": "^2.2.43", + "@types/should": "^11.2.0", + "@types/sinon": "^2.3.5", + "babel-core": "^6.26.0", + "babel-eslint": "^8.0.1", + "babel-loader": "^7.1.2", + "babel-minify-webpack-plugin": "^0.2.0", + "babel-plugin-istanbul": "^4.1.5", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-preset-es2015": "^6.24.1", + "babel-preset-stage-3": "^6.24.1", + "bootstrap": "^3.3.7", + "chai": "^4.1.2", + "compression-webpack-plugin": "^1.0.1", + "cross-env": "^5.0.5", + "esdoc": "^1.0.3", + "esdoc-ecmascript-proposal-plugin": "^1.0.0", + "esdoc-standard-plugin": "^1.0.0", + "eslint": "^4.8.0", + "eslint-config-airbnb": "^15.1.0", + "eslint-loader": "^1.9.0", + "eslint-plugin-import": "^2.7.0", + "eslint-plugin-jsx-a11y": "^6.0.2", + "eslint-plugin-react": "^7.4.0", + "extract-text-webpack-plugin": "^3.0.0", + "json-loader": "^0.5.7", + "karma": "^1.7.1", + "karma-chai": "^0.1.0", + "karma-chrome-launcher": "^2.2.0", + "karma-coverage": "^1.1.1", + "karma-coveralls": "^1.1.2", + "karma-mocha": "^1.3.0", + "karma-mocha-reporter": "^2.2.4", + "karma-webpack": "2.0.4", + "mocha": "^3.5.3", + "rimraf": "^2.6.2", + "should": "^13.1.0", + "sinon": "^4.0.0", + "webpack": "^3.6.0", + "webpack-dev-server": "^2.9.1" + }, + "dependencies": { + "deepmerge": "^1.5.2" + } } diff --git a/src/i18n/jedi-validate-i18n-data.json b/src/i18n/jedi-validate-i18n-data.json index cff463c..2db66b0 100644 --- a/src/i18n/jedi-validate-i18n-data.json +++ b/src/i18n/jedi-validate-i18n-data.json @@ -1,13 +1,13 @@ { - "ru": { - "This field is required": "Это поле необходимо заполнить", - "Please, provide correct value": "Пожалуйста, введите корректное значение", - "This email is incorrect": "Пожалуйста, введите корректный адрес электронной почты", - "This file is too large": "Попробуйте загрузить файл поменьше", - "This extension is not supported": "Пожалуйста, выберите файл с правильным расширением", - "This phone number is incorrect": "Не корректный номер телефона", - "Wrong url": "Не корректный url", - "Can not send form!": "Форма не отправлена!", - "JSON parsing error": "Ошибка разбора JSON" - } + "ru": { + "This field is required": "Это поле необходимо заполнить", + "Please, provide correct value": "Пожалуйста, введите корректное значение", + "This email is incorrect": "Пожалуйста, введите корректный адрес электронной почты", + "This file is too large": "Попробуйте загрузить файл поменьше", + "This extension is not supported": "Пожалуйста, выберите файл с правильным расширением", + "This phone number is incorrect": "Не корректный номер телефона", + "Wrong url": "Не корректный url", + "Can not send form!": "Форма не отправлена!", + "JSON parsing error": "Ошибка разбора JSON" + } } diff --git a/src/jedi-validate.d.ts b/src/jedi-validate.d.ts index 9e88961..12f29d8 100644 --- a/src/jedi-validate.d.ts +++ b/src/jedi-validate.d.ts @@ -3,7 +3,9 @@ import {JediValidate} from "jedi-validate"; declare module "jedi-validate" { class JediValidate { public collect(params?: string | Array): object; + public addMethod(rule: string, func: Function, message: string): void; + public addToDictionary(sourceText: string, translatedText: string, language: string): void; } } diff --git a/src/lib/convert-data.js b/src/lib/convert-data.js index 8215671..7b453a0 100644 --- a/src/lib/convert-data.js +++ b/src/lib/convert-data.js @@ -52,30 +52,30 @@ export function convertData(data, type) { let convertedData; switch (type) { - case 'serialize': - convertedData = Object.keys(data) - .reduce((query, name) => `${query}${getQueryPart(name, data[name])}`, ''); - return convertedData.length ? convertedData.slice(0, -1) : ''; - case 'formData': - return Object.keys(data).reduce((formData, name) => { - if (data[name] instanceof FileList) { - if (data[name].length > 1) { - for (let i = 0; i < data[name].length; i += 1) { - formData.append(`${name}[${i}]`, data[name][i]); + case 'serialize': + convertedData = Object.keys(data) + .reduce((query, name) => `${query}${getQueryPart(name, data[name])}`, ''); + return convertedData.length ? convertedData.slice(0, -1) : ''; + case 'formData': + return Object.keys(data).reduce((formData, name) => { + if (data[name] instanceof FileList) { + if (data[name].length > 1) { + for (let i = 0; i < data[name].length; i += 1) { + formData.append(`${name}[${i}]`, data[name][i]); + } + } else if (data[name].length === 1) { + formData.append(name, data[name][0]); } - } else if (data[name].length === 1) { - formData.append(name, data[name][0]); + } else if (typeof data[name] === 'object') { + Object.keys(data[name]).forEach(key => formData.append(`${name}[${key}]`, data[name][key])); + } else { + formData.append(name, data[name]); } - } else if (typeof data[name] === 'object') { - Object.keys(data[name]).forEach(key => formData.append(`${name}[${key}]`, data[name][key])); - } else { - formData.append(name, data[name]); - } - return formData; - }, new FormData()); - case 'json': - default: - return JSON.stringify(data); + return formData; + }, new FormData()); + case 'json': + default: + return JSON.stringify(data); } } diff --git a/src/lib/get-data.js b/src/lib/get-data.js index 210c211..61bf23b 100644 --- a/src/lib/get-data.js +++ b/src/lib/get-data.js @@ -66,17 +66,17 @@ export function getInputValue(input) { } switch (type) { - case 'select-one': - return input.options && input.options[input.selectedIndex] ? input.options[input.selectedIndex].value : ''; - case 'select-multiple': - return [...input.options].filter(option => option.selected).map(option => option.value); - case 'checkbox': - case 'radio': - return input.checked ? input.value : ''; - case 'file': - return input.files; - default: - return input.value; + case 'select-one': + return input.options && input.options[input.selectedIndex] ? input.options[input.selectedIndex].value : ''; + case 'select-multiple': + return [...input.options].filter(option => option.selected).map(option => option.value); + case 'checkbox': + case 'radio': + return input.checked ? input.value : ''; + case 'file': + return input.files; + default: + return input.value; } } diff --git a/tests/jedi-validate.js b/tests/jedi-validate.js index f73ac46..d8fec32 100644 --- a/tests/jedi-validate.js +++ b/tests/jedi-validate.js @@ -101,7 +101,8 @@ describe('Jedi Validate', () => { }); it('addMethod', () => { - const check = () => {}; + const check = () => { + }; validator.addMethod('check', check, 'check error'); should(validator.methods.check.func).be.equal(check); @@ -141,7 +142,9 @@ describe('Jedi Validate', () => { it('Error on callback', () => { validator.send = sinon.spy(); validator.addMethod('check', () => true, 'check error'); - validator.options.callbacks.error = () => { throw new Error('error'); }; + validator.options.callbacks.error = () => { + throw new Error('error'); + }; should(validator.handleSubmit(new Event('submit'))).not.throw(); }); @@ -160,7 +163,9 @@ describe('Jedi Validate', () => { it('Success throw callback', () => { validator.send = sinon.spy(); validator.addMethod('check', () => true, 'check error'); - validator.options.callbacks.success = () => { throw new Error('error'); }; + validator.options.callbacks.success = () => { + throw new Error('error'); + }; validator.options.ajax = false; validator.root.querySelector('#phoned2').value = 231232322; diff --git a/tests/validate-data.js b/tests/validate-data.js index f2b8363..7333b09 100644 --- a/tests/validate-data.js +++ b/tests/validate-data.js @@ -58,8 +58,14 @@ describe('Validate data', () => { it('Pass incorrect value', () => { assert.deepEqual(validateField(rules.phone2, methods, data.phone2, 'phone2', errorMessages, data, translate), [errorMessages.phone2.regexp]); - assert.deepEqual(validateField({ ...rules.phone, url: null }, methods, 'dfsdf', 'phone', errorMessages, data, translate), ['Only digits available']); - assert.deepEqual(validateField({ ...rules.phone, lol: true }, methods, data.phone, 'phone', errorMessages, data, translate), ['Method "lol" not found']); + assert.deepEqual(validateField({ + ...rules.phone, + url: null + }, methods, 'dfsdf', 'phone', errorMessages, data, translate), ['Only digits available']); + assert.deepEqual(validateField({ + ...rules.phone, + lol: true + }, methods, data.phone, 'phone', errorMessages, data, translate), ['Method "lol" not found']); }); }); @@ -128,7 +134,9 @@ describe('Validate data', () => { it('Should not throw error if function incorrect', () => { should(() => { - isCheckable([true, () => { throw new Error('error'); }], {}); + isCheckable([true, () => { + throw new Error('error'); + }], {}); }).not.throw(); }); diff --git a/webpack.config.js b/webpack.config.js index ae47154..46d5117 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,13 +1,17 @@ -var webpack = require('webpack'); +const webpack = require('webpack'); +const MinifyPlugin = require('babel-minify-webpack-plugin'); +const CompressionPlugin = require('compression-webpack-plugin'); -module.exports = { +const NODE_ENV = process.env.NODE_ENV || 'development'; + +const config = { entry: { 'jedi-validate': './src/index.js', 'jedi-validate.min': './src/index.js', }, devtool: 'source-map', output: { - path: __dirname + '/dist', + path: `${__dirname}/dist`, filename: '[name].js', libraryTarget: 'umd', library: 'JediValidate', @@ -34,9 +38,32 @@ module.exports = { ], }, plugins: [ - new webpack.optimize.UglifyJsPlugin({ - include: /\.min\.js$/, - minimize: true, + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify(NODE_ENV), + }, }), ], }; + +if (NODE_ENV === 'production') { + config.plugins.push( + new MinifyPlugin( + { + removeDebugger: true, + }, + { + test: /\.min\.js$/, + comments: false, + }, + ), + ); + + config.plugins.push( + new CompressionPlugin({ + test: /\.min\.js$/, + }), + ); +} + +module.exports = config;