Commit c399944102546e6d55f30085fbdf864ca4814e6b

Authored by Ryan Glover
1 parent 5dd12447fa
Exists in master

wip converting to 1.3

- Adding imports where they make sense.
- Converting from jshint to eslint and writing styleguide.
- General file and convention cleanup.
- Tweaks to misc. annoyances.
Showing 4859 changed files with 315818 additions and 381 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 4859 files displayed.

File was created 1 module.exports = {
2 'env': {
3 'es6': true,
4 'browser': true,
5 'meteor': true,
6 'node': true
7 },
8 'extends': 'eslint:recommended',
9 'ecmaFeatures': {
10 'jsx': true,
11 'experimentalObjectRestSpread': true
12 },
13 'plugins': [
14 'react'
15 ],
16 'globals': {
17 'BlazeLayout': true,
18 'Documents': true,
19 'FlowRouter': true
20 },
21 'rules': {
22 'comma-dangle': [2, 'never'],
23 'eqeqeq': [2, 'smart'],
24 'indent': [2, 2],
25 'linebreak-style': [2, 'unix'],
26 'no-unneeded-ternary': [2],
27 'quotes': [2, 'single'],
28 'semi': [2, 'always'],
29 'space-infix-ops': [2],
30 'space-in-parens': [2, 'always', { 'exceptions': ['{}'] }]
31 }
32 };
33
1 .DS_Store 1 .DS_Store
2 settings-development.json
2 settings-production.json 3 settings-production.json
3 npm-debug.log 4 npm-debug.log
4 5
1 # Meteor packages used by this project, one per line. 1 # Meteor packages used by this project, one per line.
2 # 2 #
3 # 'meteor add' and 'meteor remove' will edit this file for you, 3 # 'meteor add' and 'meteor remove' will edit this file for you,
4 # but you can also edit it by hand. 4 # but you can also edit it by hand.
5 5
6 accounts-password 6 accounts-password
7 accounts-base 7 accounts-base
8 jquery 8 jquery
9 check 9 check
10 audit-argument-checks 10 audit-argument-checks
11 themeteorchef:jquery-validation 11 themeteorchef:jquery-validation
12 twbs:bootstrap
13 browser-policy 12 browser-policy
14 meteorhacks:npm
15 13
16 14
17 themeteorchef:bert 15 themeteorchef:bert
18 meteorhacks:ssr 16 meteorhacks:ssr
19 standard-minifiers 17 standard-minifiers
20 18
21 19
22 npm-container
23 ecmascript 20 ecmascript
24 digilord:faker
25 kadira:flow-router 21 kadira:flow-router
26 kadira:blaze-layout 22 kadira:blaze-layout
27 meteorhacks:fast-render 23 meteorhacks:fast-render
28 meteor-base 24 meteor-base
29 session 25 session
30 templating 26 templating
31 fourseven:scss 27 fourseven:scss
32 stevezhu:lodash 28 stevezhu:lodash
33 reactive-var 29 reactive-var
34 reactive-dict 30 reactive-dict
35 aldeed:collection2 31 aldeed:collection2
36 tracker 32 tracker
33 twbs:bootstrap
1 METEOR@1.2.1 1 METEOR@1.3-modules-beta.6
2 2
1 accounts-base@1.2.2 1 accounts-base@1.2.3-modules.6
2 accounts-password@1.1.4 2 accounts-password@1.1.5-modules.6
3 alanning:roles@1.2.14
3 aldeed:collection2@2.6.1 4 aldeed:collection2@2.6.1
4 aldeed:simple-schema@1.3.3 5 aldeed:simple-schema@1.3.3
6 allow-deny@1.0.1-modules.6
5 audit-argument-checks@1.0.4 7 audit-argument-checks@1.0.4
6 autoupdate@1.2.4 8 autoupdate@1.2.5-modules.6
7 babel-compiler@5.8.24_1 9 babel-compiler@6.4.0-modules.6
8 babel-runtime@0.1.4 10 babel-runtime@0.1.5-modules.6
9 base64@1.0.4 11 base64@1.0.5-modules.6
10 binary-heap@1.0.4 12 binary-heap@1.0.5-modules.6
11 blaze@2.1.3 13 blaze@2.1.4-modules.6
12 blaze-tools@1.0.4 14 blaze-tools@1.0.5-modules.6
13 boilerplate-generator@1.0.4 15 boilerplate-generator@1.0.5-modules.6
14 browser-policy@1.0.5 16 browser-policy@1.0.6-modules.6
15 browser-policy-common@1.0.4 17 browser-policy-common@1.0.5-modules.6
16 browser-policy-content@1.0.6 18 browser-policy-content@1.0.7-modules.6
17 browser-policy-framing@1.0.6 19 browser-policy-framing@1.0.7-modules.6
18 caching-compiler@1.0.0 20 caching-compiler@1.0.1-modules.6
19 caching-html-compiler@1.0.2 21 caching-html-compiler@1.0.3-modules.6
20 callback-hook@1.0.4 22 callback-hook@1.0.5-modules.6
21 check@1.1.0 23 check@1.1.1-modules.6
22 chuangbo:cookie@1.1.0 24 chuangbo:cookie@1.1.0
23 coffeescript@1.0.11 25 coffeescript@1.0.12-modules.6
24 cosmos:browserify@0.9.2 26 cosmos:browserify@0.9.2
25 ddp@1.2.2 27 ddp@1.2.2
26 ddp-client@1.2.1 28 ddp-client@1.2.2-modules.6
27 ddp-common@1.2.2 29 ddp-common@1.2.2
28 ddp-rate-limiter@1.0.0 30 ddp-rate-limiter@1.0.1-modules.6
29 ddp-server@1.2.2 31 ddp-server@1.2.3-modules.6
30 deps@1.0.9 32 deps@1.0.9
31 diff-sequence@1.0.1 33 diff-sequence@1.0.2-modules.6
32 digilord:faker@1.0.7 34 ecmascript@0.4.0-modules.6
33 ecmascript@0.1.6 35 ecmascript-runtime@0.2.7-modules.6
34 ecmascript-runtime@0.2.6 36 ejson@1.0.8-modules.6
35 ejson@1.0.7 37 email@1.0.9-modules.6
36 email@1.0.8
37 fortawesome:fontawesome@4.4.0_1 38 fortawesome:fontawesome@4.4.0_1
38 fourseven:scss@3.4.1 39 fourseven:scss@3.4.1
39 geojson-utils@1.0.4 40 geojson-utils@1.0.5-modules.6
40 hot-code-push@1.0.0 41 hot-code-push@1.0.1-modules.6
41 html-tools@1.0.5 42 html-tools@1.0.6-modules.6
42 htmljs@1.0.5 43 htmljs@1.0.6-modules.6
43 http@1.1.1 44 http@1.1.2-modules.6
44 id-map@1.0.4 45 id-map@1.0.4
45 jquery@1.11.4 46 jquery@1.11.5-modules.6
46 kadira:blaze-layout@2.3.0 47 kadira:blaze-layout@2.3.0
47 kadira:flow-router@2.10.0 48 kadira:flow-router@2.10.0
48 livedata@1.0.15 49 livedata@1.0.15
49 localstorage@1.0.5 50 localstorage@1.0.6-modules.6
50 logging@1.0.8 51 logging@1.0.9-modules.6
51 meteor@1.1.10 52 meteor@1.1.11-modules.6
52 meteor-base@1.0.1 53 meteor-base@1.0.1
53 meteorhacks:async@1.0.0 54 meteor-env-dev@0.0.1-modules.6
55 meteor-env-prod@0.0.1-modules.6
54 meteorhacks:fast-render@2.11.0 56 meteorhacks:fast-render@2.11.0
55 meteorhacks:inject-data@1.4.1 57 meteorhacks:inject-data@1.4.1
56 meteorhacks:npm@1.5.0
57 meteorhacks:picker@1.0.3 58 meteorhacks:picker@1.0.3
58 meteorhacks:ssr@2.2.0 59 meteorhacks:ssr@2.2.0
59 minifiers@1.1.7 60 minifiers-css@1.1.8-modules.6
60 minimongo@1.0.10 61 minifiers-js@1.1.8-modules.6
61 mongo@1.1.3 62 minimongo@1.0.11-modules.6
63 modules@0.5.0-modules.6
64 modules-runtime@0.5.0-modules.6
65 momentjs:moment@2.11.2
66 mongo@1.1.4-modules.6
62 mongo-id@1.0.1 67 mongo-id@1.0.1
63 npm-bcrypt@0.7.8_2 68 npm-bcrypt@0.7.8_2
64 npm-container@1.2.0 69 npm-mongo@1.4.40-modules.6
65 npm-mongo@1.4.39_1 70 observe-sequence@1.0.8-modules.6
66 observe-sequence@1.0.7
67 ordered-dict@1.0.4 71 ordered-dict@1.0.4
68 promise@0.5.1 72 promise@0.5.2-modules.6
69 random@1.0.5 73 random@1.0.6-modules.6
70 rate-limit@1.0.0 74 rate-limit@1.0.1-modules.6
71 reactive-dict@1.1.3 75 reactive-dict@1.1.4-modules.6
72 reactive-var@1.0.6 76 reactive-var@1.0.6
73 reload@1.1.4 77 reload@1.1.5-modules.6
74 retry@1.0.4 78 retry@1.0.4
75 routepolicy@1.0.6 79 routepolicy@1.0.7-modules.6
76 service-configuration@1.0.5 80 service-configuration@1.0.6-modules.6
77 session@1.1.1 81 session@1.1.2-modules.6
78 sha@1.0.4 82 sha@1.0.4
79 spacebars@1.0.7 83 spacebars@1.0.8-modules.6
80 spacebars-compiler@1.0.7 84 spacebars-compiler@1.0.8-modules.6
81 srp@1.0.4 85 srp@1.0.5-modules.6
82 standard-minifiers@1.0.2 86 standard-minifiers@1.0.3-modules.6
87 standard-minifiers-css@1.0.3-modules.6
88 standard-minifiers-js@1.0.3-modules.6
83 stevezhu:lodash@3.10.1 89 stevezhu:lodash@3.10.1
84 templating@1.1.5 90 templating@1.1.6-modules.6
85 templating-tools@1.0.0 91 templating-tools@1.0.1-modules.6
86 themeteorchef:bert@2.1.0 92 themeteorchef:bert@2.2.0
87 themeteorchef:jquery-validation@1.14.0 93 themeteorchef:jquery-validation@1.14.0
88 tracker@1.0.9 94 tracker@1.0.10-modules.6
89 twbs:bootstrap@3.3.6 95 twbs:bootstrap@3.3.6
90 ui@1.0.8 96 ui@1.0.8
91 underscore@1.0.4 97 underscore@1.0.5-modules.6
92 url@1.0.5 98 url@1.0.6-modules.6
both/methods/insert/collection-name.js
File was created 1 Meteor.methods({
2 insert( object ) {
3 check( object, Object );
4
5 try {
6 return Documents.insert( object );
7 } catch ( exception ) {
8 throw new Meteor.Error( '500', `${ exception }` );
9 }
10 }
11 });
12
both/methods/insert/collection.js
1 Meteor.methods({ File was deleted
2 insertMethod( argument ) {
3 check( argument, Object );
4
5 try {
6 var documentId = Collection.insert( argument );
7 return documentId;
8 } catch( exception ) {
9 return exception;
10 }
11 }
12 });
13 1 Meteor.methods({
both/methods/read/collection.js
1 Meteor.methods({ File was deleted
2 readMethod( argument ) {
3 check( argument, String );
4
5 var document = Collection.findOne( argument );
6
7 if ( !document ) {
8 throw new Meteor.Error( 'document-not-found', 'No documents found matching this query.' );
9 }
10
11 return document;
12 }
13 });
14 1 Meteor.methods({
both/methods/remove/collection-name.js
File was created 1 Meteor.methods({
2 remove( argument ) {
3 check( documentId, String );
4
5 try {
6 return Documents.remove( documentId );
7 } catch ( exception ) {
8 throw new Meteor.Error( '500', `${ exception }` );
9 }
10 }
11 });
12
both/methods/remove/collection.js
1 Meteor.methods({ File was deleted
2 removeMethod( argument ) {
3 check( argument, String );
4
5 try {
6 Collection.remove( argument );
7 } catch( exception ) {
8 return exception;
9 }
10 }
11 });
12 1 Meteor.methods({
both/methods/update/collection-name.js
File was created 1 Meteor.methods({
2 update( update ) {
3 check( update, String );
4
5 try {
6 return Documents.update( update._id, {
7 $set: update
8 });
9 } catch ( exception ) {
10 throw new Meteor.Error( '500', `${ exception }` );
11 }
12 }
13 });
14
both/methods/update/collection.js
1 Meteor.methods({ File was deleted
2 updateMethod( argument ) {
3 check( argument, Object );
4
5 try {
6 var documentId = Collection.update( argument._id, {
7 $set: { 'key': argument.key }
8 });
9 return documentId;
10 } catch( exception ) {
11 return exception;
12 }
13 }
14 });
15 1 Meteor.methods({
both/modules/_modules.js
1 Modules = {}; File was deleted
2 Modules.both = {};
3 1 Modules = {};
both/modules/startup.js
1 let startup = () => {}; 1 let startup = () => {};
2 2
3 Modules.both.startup = startup; 3 export { startup };
4 4
both/routes/authenticated.js
1 const authenticatedRoutes = FlowRouter.group({ 1 const authenticatedRoutes = FlowRouter.group({
2 name: 'authenticated' 2 name: 'authenticated'
3 }); 3 });
4 4
5 authenticatedRoutes.route( '/', { 5 authenticatedRoutes.route( '/', {
6 name: 'index', 6 name: 'index',
7 action() { 7 action() {
8 BlazeLayout.render( 'default', { yield: 'index' } ); 8 BlazeLayout.render( 'default', { yield: 'index' } );
9 } 9 }
10 }); 10 });
11 11
12 authenticatedRoutes.route( '/dashboard', { 12 authenticatedRoutes.route( '/dashboard', {
13 name: 'dashboard', 13 name: 'dashboard',
14 action() { 14 action() {
15 BlazeLayout.render( 'default', { yield: 'dashboard' } ); 15 BlazeLayout.render( 'default', { yield: 'dashboard' }, hello );
16 } 16 }
17 }); 17 });
18 18
1 Meteor.startup( () => Modules.both.startup() ); 1 import { startup } from './modules/startup';
2
3 Meteor.startup( () => startup() );
2 4
client/modules/_modules.js
1 Modules.client = {}; File was deleted
2 1 Modules.client = {};
client/modules/login.js
1 let login = ( options ) => { 1 let _handleLogin = ( template ) => {
2 _validate( options.form, options.template ); 2 let email = template.find( '[name="emailAddress"]' ).value,
3 }; 3 password = template.find( '[name="password"]' ).value;
4 4
5 let _validate = ( form, template ) => { 5 Meteor.loginWithPassword( email, password, ( error ) => {
6 $( form ).validate( validation( template ) ); 6 if ( error ) {
7 Bert.alert( error.reason, 'warning' );
8 } else {
9 Bert.alert( 'Logged in!', 'success' );
10 }
11 });
7 }; 12 };
8 13
9 let validation = ( template ) => { 14 let validation = ( template ) => {
10 return { 15 return {
11 rules: { 16 rules: {
12 emailAddress: { 17 emailAddress: {
13 required: true, 18 required: true,
14 email: true 19 email: true
15 }, 20 },
16 password: { 21 password: {
17 required: true 22 required: true
18 } 23 }
19 }, 24 },
20 messages: { 25 messages: {
21 emailAddress: { 26 emailAddress: {
22 required: 'Need an email address here.', 27 required: 'Need an email address here.',
23 email: 'Is this email address legit?' 28 email: 'Is this email address legit?'
24 }, 29 },
25 password: { 30 password: {
26 required: 'Need a password here.' 31 required: 'Need a password here.'
27 } 32 }
28 }, 33 },
29 submitHandler() { _handleLogin( template ); } 34 submitHandler() { _handleLogin( template ); }
30 }; 35 };
31 }; 36 };
32 37
33 let _handleLogin = ( template ) => { 38 let _validate = ( form, template ) => {
34 let email = template.find( '[name="emailAddress"]' ).value, 39 $( form ).validate( validation( template ) );
35 password = template.find( '[name="password"]' ).value;
36
37 Meteor.loginWithPassword( email, password, ( error ) => {
38 if ( error ) {
39 Bert.alert( error.reason, 'warning' );
40 } else {
41 Bert.alert( 'Logged in!', 'success' );
42 }
client/modules/recover-password.js
1 let recoverPassword = ( options ) => { 1 let _handleRecovery = ( template ) => {
2 _validate( options.form, options.template ); 2 let email = template.find( '[name="emailAddress"]' ).value;
3 };
4 3
5 let _validate = ( form, template ) => { 4 Accounts.forgotPassword( { email: email }, ( error ) => {
6 $( form ).validate( validation( template ) ); 5 if ( error ) {
6 Bert.alert( error.reason, 'warning' );
7 } else {
8 Bert.alert( 'Check your inbox for a reset link!', 'success' );
9 }
10 });
7 }; 11 };
8 12
9 let validation = ( template ) => { 13 let validation = ( template ) => {
10 return { 14 return {
11 rules: { 15 rules: {
12 emailAddress: { 16 emailAddress: {
13 required: true, 17 required: true,
14 email: true 18 email: true
15 } 19 }
16 }, 20 },
17 messages: { 21 messages: {
18 emailAddress: { 22 emailAddress: {
19 required: 'Need an email address here.', 23 required: 'Need an email address here.',
20 email: 'Is this email address legit?' 24 email: 'Is this email address legit?'
21 } 25 }
22 }, 26 },
23 submitHandler() { _handleRecovery( template ); } 27 submitHandler() { _handleRecovery( template ); }
24 }; 28 };
25 }; 29 };
26 30
27 let _handleRecovery = ( template ) => { 31 let _validate = ( form, template ) => {
28 let email = template.find( '[name="emailAddress"]' ).value; 32 $( form ).validate( validation( template ) );
29
30 Accounts.forgotPassword( { email: email }, ( error ) => {
31 if ( error ) {
32 Bert.alert( error.reason, 'warning' );
33 } else {
34 Bert.alert( 'Check your inbox for a reset link!', 'success' );
35 }
client/modules/reset-password.js
1 let resetPassword = ( options ) => { 1 let _handleReset = ( template ) => {
2 _validate( options.form, options.template ); 2 var token = FlowRouter.current().params.token,
3 }; 3 password = template.find( '[name="newPassword"]' ).value;
4 4
5 let _validate = ( form, template ) => { 5 Accounts.resetPassword( token, password, ( error ) => {
6 $( form ).validate( validation( template ) ); 6 if ( error ) {
7 Bert.alert( error.reason, 'danger' );
8 } else {
9 Bert.alert( 'Password reset!', 'success' );
10 }
11 });
7 }; 12 };
8 13
9 let validation = ( template ) => { 14 let validation = ( template ) => {
10 return { 15 return {
11 rules: { 16 rules: {
12 newPassword: { 17 newPassword: {
13 required: true, 18 required: true,
14 minlength: 6 19 minlength: 6
15 }, 20 },
16 repeatNewPassword: { 21 repeatNewPassword: {
17 required: true, 22 required: true,
18 minlength: 6, 23 minlength: 6,
19 equalTo: '[name="newPassword"]' 24 equalTo: '[name="newPassword"]'
20 } 25 }
21 }, 26 },
22 messages: { 27 messages: {
23 newPassword: { 28 newPassword: {
24 required: "Enter a new password, please.", 29 required: "Enter a new password, please.",
25 minlength: "Use at least six characters, please." 30 minlength: "Use at least six characters, please."
26 }, 31 },
27 repeatNewPassword: { 32 repeatNewPassword: {
28 required: "Repeat your new password, please.", 33 required: "Repeat your new password, please.",
29 equalTo: "Hmm, your passwords don't match. Try again?" 34 equalTo: "Hmm, your passwords don't match. Try again?"
30 } 35 }
31 }, 36 },
32 submitHandler() { _handleReset( template ); } 37 submitHandler() { _handleReset( template ); }
33 }; 38 };
34 }; 39 };
35 40
36 let _handleReset = ( template ) => { 41 let _validate = ( form, template ) => {
37 var token = FlowRouter.current().params.token, 42 $( form ).validate( validation( template ) );
38 password = template.find( '[name="newPassword"]' ).value;
39
40 Accounts.resetPassword( token, password, ( error ) => {
41 if ( error ) {
42 Bert.alert( error.reason, 'danger' );
43 } else {
44 Bert.alert( 'Password reset!', 'success' );
45 }
client/modules/signup.js
1 let signup = ( options ) => { 1 let _handleSignup = ( template ) => {
2 _validate( options.form, options.template ); 2 let user = {
3 }; 3 email: template.find( '[name="emailAddress"]' ).value,
4 password: template.find( '[name="password"]' ).value
5 };
4 6
5 let _validate = ( form, template ) => { 7 Accounts.createUser( user, ( error ) => {
6 $( form ).validate( validation( template ) ); 8 if ( error ) {
9 Bert.alert( error.reason, 'danger' );
10 } else {
11 Bert.alert( 'Welcome!', 'success' );
12 }
13 });
7 }; 14 };
8 15
9 let validation = ( template ) => { 16 let validation = ( template ) => {
10 return { 17 return {
11 rules: { 18 rules: {
12 emailAddress: { 19 emailAddress: {
13 required: true, 20 required: true,
14 email: true 21 email: true
15 }, 22 },
16 password: { 23 password: {
17 required: true, 24 required: true,
18 minlength: 6 25 minlength: 6
19 } 26 }
20 }, 27 },
21 messages: { 28 messages: {
22 emailAddress: { 29 emailAddress: {
23 required: 'Need an email address here.', 30 required: 'Need an email address here.',
24 email: 'Is this email address legit?' 31 email: 'Is this email address legit?'
25 }, 32 },
26 password: { 33 password: {
27 required: 'Need a password here.', 34 required: 'Need a password here.',
28 minlength: 'Use at least six characters, please.' 35 minlength: 'Use at least six characters, please.'
29 } 36 }
30 }, 37 },
31 submitHandler() { _handleSignup( template ); } 38 submitHandler() { _handleSignup( template ); }
32 }; 39 };
33 }; 40 };
34 41
35 let _handleSignup = ( template ) => { 42 let _validate = ( form, template ) => {
36 let user = { 43 $( form ).validate( validation( template ) );
37 email: template.find( '[name="emailAddress"]' ).value,
38 password: template.find( '[name="password"]' ).value
39 };
40
41 Accounts.createUser( user, ( error ) => {
42 if ( error ) {
43 Bert.alert( error.reason, 'danger' );
44 } else {
client/modules/startup.js
1 let startup = () => {}; 1 export function startup() {
2 2 Bert.defaults.style = 'growl-top-right';
3 Modules.client.startup = startup; 3 }
4 4
client/startup.js
1 Meteor.startup( () => Modules.client.startup() ); 1 import { startup } from './modules/startup';
2
3 Meteor.startup( () => startup() );
2 4
client/stylesheets/application.scss
1 @import "tools/extends"; 1 @import "tools/extends";
2 2
3 @import "objects/forms"; 3 @import "objects/forms";
4 4
5 @import "components/loading";
5 @import "components/login"; 6 @import "components/login";
6 7
client/stylesheets/components/_loading.scss
File was created 1 @keyframes rotate {
2 from { transform: rotate( 0deg ); }
3 to { transform: rotate( 360deg ); }
4 }
5
6 @-webkit-keyframes rotate {
7 from { -webkit-transform: rotate( 0deg ); }
8 to { -webkit-transform: rotate( 360deg ); }
9 }
10
11 .loading {
12 -webkit-animation-name: rotate;
13 -webkit-animation-duration: 0.5s;
14 -webkit-animation-iteration-count: infinite;
15 -webkit-animation-timing-function: linear;
16 animation-name: rotate;
17 animation-duration: 0.5s;
18 animation-iteration-count: infinite;
19 animation-timing-function: linear;
20 }
21
client/templates/authenticated/index.html
1 <template name="index"> 1 <template name="index">
2 <div class="jumbotron text-center" style="padding: 20px;"> 2 <div class="jumbotron text-center" style="padding: 20px;">
3 <h2>Base</h2> 3 <h2>Base</h2>
4 <p>A starting point for Meteor applications.</p> 4 <p>A starting point for Meteor applications.</p>
5 <p><a class="btn btn-success" href="http://themeteorchef.com/base" role="button">Read the Documentation</a></p> 5 <p><a class="btn btn-success" href="https://themeteorchef.com/base" role="button">Read the Documentation</a></p>
6 <p style="font-size: 16px; color: #aaa;">Currently at v3.4.0</p> 6 <p style="font-size: 16px; color: #aaa;">Currently at v4.0.0</p>
7 </div> 7 </div>
8 </template> 8 </template>
9 9
client/templates/globals/loading.html
1 <template name="loading"> 1 <template name="loading">
2 <svg version="1.1" id="loader-1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 2 <svg version="1.1" class="loading" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
3 width="40px" height="40px" viewBox="0 0 40 40" enable-background="new 0 0 40 40" xml:space="preserve"> 3 width="40px" height="40px" viewBox="0 0 40 40" enable-background="new 0 0 40 40" xml:space="preserve">
4 <path opacity="1.0" fill="#eee" d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946 4 <path opacity="1.0" fill="#eee" d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946
5 s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634 5 s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634
6 c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z"/> 6 c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z"/>
7 <path fill="#da5347" d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0 7 <path fill="#da5347" d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0
8 C22.32,8.481,24.301,9.057,26.013,10.047z"> 8 C22.32,8.481,24.301,9.057,26.013,10.047z">
9 <animateTransform attributeType="xml"
10 attributeName="transform"
11 type="rotate"
12 from="0 20 20"
13 to="360 20 20"
14 dur="0.5s"
15 repeatCount="indefinite"/>
16 </path> 9 </path>
17 </svg> 10 </svg>
18 </template> 11 </template>
19 12
client/templates/public/login.js
1 import { login } from '../../modules/login';
2
1 Template.login.onRendered( () => { 3 Template.login.onRendered( () => {
2 Modules.client.login( { form: "#login", template: Template.instance() } ); 4 login( { form: "#login", template: Template.instance() } );
3 }); 5 });
4 6
5 Template.login.events({ 7 Template.login.events({
6 'submit form': ( event ) => event.preventDefault() 8 'submit form': ( event ) => event.preventDefault()
7 }); 9 });
8 10
client/templates/public/recover-password.js
1 import { recoverPassword } from '../../modules/recover-password';
2
1 Template.recoverPassword.onRendered( () => { 3 Template.recoverPassword.onRendered( () => {
2 Modules.client.recoverPassword({ 4 recoverPassword({
3 form: "#recover-password", 5 form: "#recover-password",
4 template: Template.instance() 6 template: Template.instance()
5 }); 7 });
6 }); 8 });
7 9
8 Template.recoverPassword.events({ 10 Template.recoverPassword.events({
9 'submit form': ( event ) => event.preventDefault() 11 'submit form': ( event ) => event.preventDefault()
10 }); 12 });
11 13
client/templates/public/reset-password.js
1 import { resetPassword } from '../../modules/login';
2
1 Template.resetPassword.onRendered( () => { 3 Template.resetPassword.onRendered( () => {
2 Modules.client.resetPassword({ 4 resetPassword({
3 form: "#reset-password", 5 form: "#reset-password",
4 template: Template.instance() 6 template: Template.instance()
5 }); 7 });
6 }); 8 });
7 9
8 Template.resetPassword.events({ 10 Template.resetPassword.events({
9 'submit form': ( event ) => event.preventDefault() 11 'submit form': ( event ) => event.preventDefault()
10 }); 12 });
11 13
client/templates/public/signup.js
1 import { signup } from '../../modules/signup';
2
1 Template.signup.onRendered( () => { 3 Template.signup.onRendered( () => {
2 Modules.client.signup({ 4 signup( { form: "#signup", template: Template.instance() } );
3 form: "#signup",
4 template: Template.instance()
5 });
6 }); 5 });
7 6
8 Template.signup.events({ 7 Template.signup.events({
9 'submit form': ( event ) => event.preventDefault() 8 'submit form': ( event ) => event.preventDefault()
collections/collection.js
1 Collection = new Meteor.Collection( 'collection' ); File was deleted
2
3 Collection.allow({
4 insert: () => false,
5 update: () => false,
6 remove: () => false
7 });
8
9 Collection.deny({
10 insert: () => true,
11 update: () => true,
12 remove: () => true
13 });
14
15 let CollectionSchema = new SimpleSchema({
16 "owner": {
17 type: String,
18 label: "The ID of the owner of this document."
19 }
20 });
21
22 Collection.attachSchema( CollectionSchema );
23 1 Collection = new Meteor.Collection( 'collection' );
collections/documents.js
File was created 1 Documents = new Mongo.Collection( 'documents' );
2
3 Documents.allow({
4 insert: () => false,
5 update: () => false,
6 remove: () => false
7 });
8
9 Documents.deny({
10 insert: () => true,
11 update: () => true,
12 remove: () => true
13 });
14
15 let DocumentsSchema = new SimpleSchema({
16 "title": {
17 type: String,
18 label: "The title of this document."
19 }
20 });
21
22 Documents.attachSchema( DocumentsSchema );
23
node_modules/.bin/eslint
File was created 1 ../eslint/bin/eslint.js
node_modules/eslint-config-airbnb/.eslintrc
File was created 1 {
2 "extends": "airbnb",
3 "rules": {
4 // disable requiring trailing commas because it might be nice to revert to
5 // being JSON at some point, and I don't want to make big changes now.
6 "comma-dangle": 0
7 }
8 }
9
node_modules/eslint-config-airbnb/CHANGELOG.md
File was created 1 5.0.0 / 2016-02-03
2 ==================
3 - [breaking] disallow unneeded ternary expressions
4 - [breaking] Avoid lexical declarations in case/default clauses
5 - [dev deps] update `babel-tape-runner`, `eslint-plugin-react`, `react`, `tape`
6
7 4.0.0 / 2016-01-22
8 ==================
9 - [breaking] require outer IIFE wrapping; flesh out guide section
10 - [minor] Add missing `arrow-body-style`, `prefer-template` rules (#678)
11 - [minor] Add `prefer-arrow-callback` to ES6 rules (to match the guide) (#677)
12 - [Tests] run `npm run lint` as part of tests; fix errors
13 - [Tests] use `parallelshell` to parallelize npm run-scripts
14
15 3.1.0 / 2016-01-07
16 ==================
17 - [minor] Allow multiple stateless components in a single file
18
19 3.0.2 / 2016-01-06
20 ==================
21 - [fix] Ignore URLs in `max-len` (#664)
22
23 3.0.1 / 2016-01-06
24 ==================
25 - [fix] because we use babel, keywords should not be quoted
26
27 3.0.0 / 2016-01-04
28 ==================
29 - [breaking] enable `quote-props` rule (#632)
30 - [breaking] Define a max line length of 100 characters (#639)
31 - [breaking] [react] Minor cleanup for the React styleguide, add `react/jsx-no-bind` (#619)
32 - [breaking] update best-practices config to prevent parameter object manipulation (#627)
33 - [minor] Enable react/no-is-mounted rule (#635, #633)
34 - [minor] Sort react/prefer-es6-class alphabetically (#634)
35 - [minor] enable react/prefer-es6-class rule
36 - Permit strict mode in "legacy" config
37 - [react] add missing rules from eslint-plugin-react (enforcing where necessary) (#581)
38 - [dev deps] update `eslint-plugin-react`
39
40 2.1.1 / 2015-12-15
41 ==================
42 - [fix] Remove deprecated react/jsx-quotes (#622)
43
44 2.1.0 / 2015-12-15
45 ==================
46 - [fix] use `require.resolve` to allow nested `extend`s (#582)
47 - [new] enable `object-shorthand` rule (#621)
48 - [new] enable `arrow-spacing` rule (#517)
49 - [docs] flesh out react rule defaults (#618)
50
51 2.0.0 / 2015-12-03
52 ==================
53 - [breaking] `space-before-function-paren`: require function spacing: `function <optional name>(` (#605)
54 - [breaking] `indent`: Fix switch statement indentation rule (#606)
55 - [breaking] `array-bracket-spacing`, `computed-property-spacing`: disallow spacing inside brackets (#594)
56 - [breaking] `object-curly-spacing`: require padding inside curly braces (#594)
57 - [breaking] `space-in-parens`: disallow spaces in parens (#594)
58
59 1.0.2 / 2015-11-25
60 ==================
61 - [breaking] `no-multiple-empty-lines`: only allow 1 blank line at EOF (#578)
62 - [new] `restParams`: enable rest params (#592)
63
64 1.0.1 / 2015-11-25
65 ==================
66 - *erroneous publish*
67
68 1.0.0 / 2015-11-08
69 ==================
70 - require `eslint` `v1.0.0` or higher
71 - remove `babel-eslint` dependency
72
73 0.1.1 / 2015-11-05
74 ==================
75 - remove id-length rule (#569)
76 - enable `no-mixed-spaces-and-tabs` (#539)
77 - enable `no-const-assign` (#560)
78 - enable `space-before-keywords` (#554)
79
80 0.1.0 / 2015-11-05
81 ==================
82 - switch to modular rules files courtesy the [eslint-config-default][ecd] project and [@taion][taion]. [PR][pr-modular]
83 - export `eslint-config-airbnb/legacy` for ES5-only users. `eslint-config-airbnb/legacy` does not require the `babel-eslint` parser. [PR][pr-legacy]
84
85 0.0.9 / 2015-09-24
86 ==================
87 - add rule `no-undef`
88 - add rule `id-length`
89
90 0.0.8 / 2015-08-21
91 ==================
92 - now has a changelog
93 - now is modular (see instructions above for with react and without react versions)
94
95 0.0.7 / 2015-07-30
96 ==================
97 - TODO: fill in
98
99 [ecd]: https://github.com/walmartlabs/eslint-config-defaults
100 [taion]: https://github.com/taion
101 [pr-modular]: https://github.com/airbnb/javascript/pull/526
102 [pr-legacy]: https://github.com/airbnb/javascript/pull/527
103
node_modules/eslint-config-airbnb/README.md
File was created 1 # eslint-config-airbnb
2
3 [![npm version](https://badge.fury.io/js/eslint-config-airbnb.svg)](http://badge.fury.io/js/eslint-config-airbnb)
4
5 This package provides Airbnb's .eslintrc as an extensible shared config.
6
7 ## Usage
8
9 We export three ESLint configurations for your usage.
10
11 ### eslint-config-airbnb
12
13 Our default export contains all of our ESLint rules, including EcmaScript 6+
14 and React. It requires `eslint` and `eslint-plugin-react`.
15
16 1. `npm install --save-dev eslint-config-airbnb eslint-plugin-react eslint`
17 2. add `"extends": "airbnb"` to your .eslintrc
18
19 ### eslint-config-airbnb/base
20
21 Lints ES6+ but does not lint React. Requires `eslint`.
22
23 1. `npm install --save-dev eslint-config-airbnb eslint`
24 2. add `"extends": "airbnb/base"` to your .eslintrc
25
26 ### eslint-config-airbnb/legacy
27
28 Lints ES5 and below. Only requires `eslint`.
29
30 1. `npm install --save-dev eslint-config-airbnb eslint`
31 2. add `"extends": "airbnb/legacy"` to your .eslintrc
32
33 See [Airbnb's Javascript styleguide](https://github.com/airbnb/javascript) and
34 the [ESlint config docs](http://eslint.org/docs/user-guide/configuring#extending-configuration-files)
35 for more information.
36
37 ## Improving this config
38
39 Consider adding test cases if you're making complicated rules changes, like
40 anything involving regexes. Perhaps in a distant future, we could use literate
41 programming to structure our README as test cases for our .eslintrc?
42
43 You can run tests with `npm test`.
44
45 You can make sure this module lints with itself using `npm run lint`.
46
node_modules/eslint-config-airbnb/base.js
File was created 1 module.exports = {
2 extends: [
3 'eslint-config-airbnb/legacy',
4 'eslint-config-airbnb/rules/es6',
5 ].map(require.resolve),
6 rules: {}
7 };
8
node_modules/eslint-config-airbnb/index.js
File was created 1 module.exports = {
2 extends: [
3 'eslint-config-airbnb/base',
4 'eslint-config-airbnb/rules/strict',
5 'eslint-config-airbnb/rules/react',
6 ].map(require.resolve),
7 rules: {}
8 };
9
node_modules/eslint-config-airbnb/legacy.js
File was created 1 module.exports = {
2 extends: [
3 'eslint-config-airbnb/rules/best-practices',
4 'eslint-config-airbnb/rules/errors',
5 'eslint-config-airbnb/rules/legacy',
6 'eslint-config-airbnb/rules/node',
7 'eslint-config-airbnb/rules/style',
8 'eslint-config-airbnb/rules/variables'
9 ].map(require.resolve),
10 env: {
11 browser: true,
12 node: true,
13 amd: false,
14 mocha: false,
15 jasmine: false
16 },
17 ecmaFeatures: {},
18 globals: {},
19 rules: {}
20 };
21
node_modules/eslint-config-airbnb/package.json
File was created 1 {
2 "name": "eslint-config-airbnb",
3 "version": "5.0.0",
4 "description": "Airbnb's ESLint config, following our styleguide",
5 "main": "index.js",
6 "scripts": {
7 "lint": "eslint .",
8 "tests-only": "babel-tape-runner ./test/test-*.js",
9 "test": "parallelshell 'npm run lint' 'npm run tests-only'"
10 },
11 "repository": {
12 "type": "git",
13 "url": "git+https://github.com/airbnb/javascript.git"
14 },
15 "keywords": [
16 "eslint",
17 "eslintconfig",
18 "config",
19 "airbnb",
20 "javascript",
21 "styleguide"
22 ],
23 "author": {
24 "name": "Jake Teton-Landis",
25 "url": "https://twitter.com/@jitl"
26 },
27 "contributors": [
28 {
29 "name": "Jake Teton-Landis",
30 "url": "https://twitter.com/jitl"
31 },
32 {
33 "name": "Jordan Harband",
34 "email": "ljharb@gmail.com",
35 "url": "http://ljharb.codes"
36 }
37 ],
38 "license": "MIT",
39 "bugs": {
40 "url": "https://github.com/airbnb/javascript/issues"
41 },
42 "homepage": "https://github.com/airbnb/javascript",
43 "devDependencies": {
44 "babel-tape-runner": "1.2.0",
45 "eslint": "^1.10.3",
46 "eslint-plugin-react": "^3.16.1",
47 "react": "^0.14.7",
48 "tape": "^4.4.0",
49 "parallelshell": "^2.0.0"
50 },
51 "peerDependencies": {
52 "eslint": ">=1.0.0"
53 },
54 "_id": "eslint-config-airbnb@5.0.0",
55 "_shasum": "16886a3a613028f62213c6330e9b42554364ec3f",
56 "_from": "eslint-config-airbnb@*",
57 "_npmVersion": "3.3.12",
58 "_nodeVersion": "5.5.0",
59 "_npmUser": {
60 "name": "ljharb",
61 "email": "ljharb@gmail.com"
62 },
63 "dist": {
64 "shasum": "16886a3a613028f62213c6330e9b42554364ec3f",
65 "tarball": "http://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-5.0.0.tgz"
66 },
67 "maintainers": [
68 {
69 "name": "airbnb",
70 "email": "jordan.harband+npm@airbnb.com"
71 },
72 {
73 "name": "jitl",
74 "email": "just.1.jake@gmail.com"
75 },
76 {
77 "name": "ljharb",
78 "email": "ljharb@gmail.com"
79 }
80 ],
81 "_npmOperationalInternal": {
82 "host": "packages-5-east.internal.npmjs.com",
83 "tmp": "tmp/eslint-config-airbnb-5.0.0.tgz_1454552979702_0.033046064199879766"
84 },
85 "directories": {},
86 "_resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-5.0.0.tgz"
87 }
88
node_modules/eslint-config-airbnb/rules/.eslintrc.json
File was created 1 {
2 "rules": {
3 "quote-props": 0
4 }
5 }
6
node_modules/eslint-config-airbnb/rules/best-practices.js
File was created 1 module.exports = {
2 'rules': {
3 // enforces getter/setter pairs in objects
4 'accessor-pairs': 0,
5 // treat var statements as if they were block scoped
6 'block-scoped-var': 2,
7 // specify the maximum cyclomatic complexity allowed in a program
8 'complexity': [0, 11],
9 // require return statements to either always or never specify values
10 'consistent-return': 2,
11 // specify curly brace conventions for all control statements
12 'curly': [2, 'multi-line'],
13 // require default case in switch statements
14 'default-case': 2,
15 // encourages use of dot notation whenever possible
16 'dot-notation': [2, { 'allowKeywords': true }],
17 // enforces consistent newlines before or after dots
18 'dot-location': 0,
19 // require the use of === and !==
20 'eqeqeq': 2,
21 // make sure for-in loops have an if statement
22 'guard-for-in': 2,
23 // disallow the use of alert, confirm, and prompt
24 'no-alert': 1,
25 // disallow use of arguments.caller or arguments.callee
26 'no-caller': 2,
27 // disallow lexical declarations in case/default clauses
28 // http://eslint.org/docs/rules/no-case-declarations.html
29 'no-case-declarations': 2,
30 // disallow division operators explicitly at beginning of regular expression
31 'no-div-regex': 0,
32 // disallow else after a return in an if
33 'no-else-return': 2,
34 // disallow use of labels for anything other then loops and switches
35 'no-empty-label': 2,
36 // disallow comparisons to null without a type-checking operator
37 'no-eq-null': 0,
38 // disallow use of eval()
39 'no-eval': 2,
40 // disallow adding to native types
41 'no-extend-native': 2,
42 // disallow unnecessary function binding
43 'no-extra-bind': 2,
44 // disallow fallthrough of case statements
45 'no-fallthrough': 2,
46 // disallow the use of leading or trailing decimal points in numeric literals
47 'no-floating-decimal': 2,
48 // disallow the type conversions with shorter notations
49 'no-implicit-coercion': 0,
50 // disallow use of eval()-like methods
51 'no-implied-eval': 2,
52 // disallow this keywords outside of classes or class-like objects
53 'no-invalid-this': 0,
54 // disallow usage of __iterator__ property
55 'no-iterator': 2,
56 // disallow use of labeled statements
57 'no-labels': 2,
58 // disallow unnecessary nested blocks
59 'no-lone-blocks': 2,
60 // disallow creation of functions within loops
61 'no-loop-func': 2,
62 // disallow use of multiple spaces
63 'no-multi-spaces': 2,
64 // disallow use of multiline strings
65 'no-multi-str': 2,
66 // disallow reassignments of native objects
67 'no-native-reassign': 2,
68 // disallow use of new operator when not part of the assignment or comparison
69 'no-new': 2,
70 // disallow use of new operator for Function object
71 'no-new-func': 2,
72 // disallows creating new instances of String,Number, and Boolean
73 'no-new-wrappers': 2,
74 // disallow use of (old style) octal literals
75 'no-octal': 2,
76 // disallow use of octal escape sequences in string literals, such as
77 // var foo = 'Copyright \251';
78 'no-octal-escape': 2,
79 // disallow reassignment of function parameters
80 // disallow parameter object manipulation
81 // rule: http://eslint.org/docs/rules/no-param-reassign.html
82 'no-param-reassign': [2, { 'props': true }],
83 // disallow use of process.env
84 'no-process-env': 0,
85 // disallow usage of __proto__ property
86 'no-proto': 2,
87 // disallow declaring the same variable more then once
88 'no-redeclare': 2,
89 // disallow use of assignment in return statement
90 'no-return-assign': 2,
91 // disallow use of `javascript:` urls.
92 'no-script-url': 2,
93 // disallow comparisons where both sides are exactly the same
94 'no-self-compare': 2,
95 // disallow use of comma operator
96 'no-sequences': 2,
97 // restrict what can be thrown as an exception
98 'no-throw-literal': 2,
99 // disallow usage of expressions in statement position
100 'no-unused-expressions': 2,
101 // disallow unnecessary .call() and .apply()
102 'no-useless-call': 0,
103 // disallow use of void operator
104 'no-void': 0,
105 // disallow usage of configurable warning terms in comments: e.g. todo
106 'no-warning-comments': [0, { 'terms': ['todo', 'fixme', 'xxx'], 'location': 'start' }],
107 // disallow use of the with statement
108 'no-with': 2,
109 // require use of the second argument for parseInt()
110 'radix': 2,
111 // requires to declare all vars on top of their containing scope
112 'vars-on-top': 2,
113 // require immediate function invocation to be wrapped in parentheses
114 // http://eslint.org/docs/rules/wrap-iife.html
115 'wrap-iife': [2, 'outside'],
116 // require or disallow Yoda conditions
117 'yoda': 2
118 }
119 };
120
node_modules/eslint-config-airbnb/rules/errors.js
File was created 1 module.exports = {
2 'rules': {
3 // disallow trailing commas in object literals
4 'comma-dangle': [2, 'always-multiline'],
5 // disallow assignment in conditional expressions
6 'no-cond-assign': [2, 'always'],
7 // disallow use of console
8 'no-console': 1,
9 // disallow use of constant expressions in conditions
10 'no-constant-condition': 1,
11 // disallow control characters in regular expressions
12 'no-control-regex': 2,
13 // disallow use of debugger
14 'no-debugger': 1,
15 // disallow duplicate arguments in functions
16 'no-dupe-args': 2,
17 // disallow duplicate keys when creating object literals
18 'no-dupe-keys': 2,
19 // disallow a duplicate case label.
20 'no-duplicate-case': 2,
21 // disallow the use of empty character classes in regular expressions
22 'no-empty-character-class': 2,
23 // disallow empty statements
24 'no-empty': 2,
25 // disallow assigning to the exception in a catch block
26 'no-ex-assign': 2,
27 // disallow double-negation boolean casts in a boolean context
28 'no-extra-boolean-cast': 0,
29 // disallow unnecessary parentheses
30 'no-extra-parens': [2, 'functions'],
31 // disallow unnecessary semicolons
32 'no-extra-semi': 2,
33 // disallow overwriting functions written as function declarations
34 'no-func-assign': 2,
35 // disallow function or variable declarations in nested blocks
36 'no-inner-declarations': 2,
37 // disallow invalid regular expression strings in the RegExp constructor
38 'no-invalid-regexp': 2,
39 // disallow irregular whitespace outside of strings and comments
40 'no-irregular-whitespace': 2,
41 // disallow negation of the left operand of an in expression
42 'no-negated-in-lhs': 2,
43 // disallow the use of object properties of the global object (Math and JSON) as functions
44 'no-obj-calls': 2,
45 // disallow multiple spaces in a regular expression literal
46 'no-regex-spaces': 2,
47 // disallow sparse arrays
48 'no-sparse-arrays': 2,
49 // disallow unreachable statements after a return, throw, continue, or break statement
50 'no-unreachable': 2,
51 // disallow comparisons with the value NaN
52 'use-isnan': 2,
53 // ensure JSDoc comments are valid
54 'valid-jsdoc': 0,
55 // ensure that the results of typeof are compared against a valid string
56 'valid-typeof': 2,
57 // Avoid code that looks like two expressions but is actually one
58 'no-unexpected-multiline': 0
59 }
60 };
61
node_modules/eslint-config-airbnb/rules/es6.js
File was created 1 module.exports = {
2 'env': {
3 'es6': false
4 },
5 'ecmaFeatures': {
6 'arrowFunctions': true,
7 'blockBindings': true,
8 'classes': true,
9 'defaultParams': true,
10 'destructuring': true,
11 'forOf': true,
12 'generators': false,
13 'modules': true,
14 'objectLiteralComputedProperties': true,
15 'objectLiteralDuplicateProperties': false,
16 'objectLiteralShorthandMethods': true,
17 'objectLiteralShorthandProperties': true,
18 'restParams': true,
19 'spread': true,
20 'superInFunctions': true,
21 'templateStrings': true,
22 'jsx': true
23 },
24 'rules': {
25 // enforces no braces where they can be omitted
26 // http://eslint.org/docs/rules/arrow-body-style
27 'arrow-body-style': [2, 'as-needed'],
28 // require parens in arrow function arguments
29 'arrow-parens': 0,
30 // require space before/after arrow function's arrow
31 // https://github.com/eslint/eslint/blob/master/docs/rules/arrow-spacing.md
32 'arrow-spacing': [2, { 'before': true, 'after': true }],
33 // verify super() callings in constructors
34 'constructor-super': 0,
35 // enforce the spacing around the * in generator functions
36 'generator-star-spacing': 0,
37 // disallow modifying variables of class declarations
38 'no-class-assign': 0,
39 // disallow modifying variables that are declared using const
40 'no-const-assign': 2,
41 // disallow to use this/super before super() calling in constructors.
42 'no-this-before-super': 0,
43 // require let or const instead of var
44 'no-var': 2,
45 // require method and property shorthand syntax for object literals
46 // https://github.com/eslint/eslint/blob/master/docs/rules/object-shorthand.md
47 'object-shorthand': [2, 'always'],
48 // suggest using arrow functions as callbacks
49 'prefer-arrow-callback': 2,
50 // suggest using of const declaration for variables that are never modified after declared
51 'prefer-const': 2,
52 // suggest using the spread operator instead of .apply()
53 'prefer-spread': 0,
54 // suggest using Reflect methods where applicable
55 'prefer-reflect': 0,
56 // suggest using template literals instead of string concatenation
57 // http://eslint.org/docs/rules/prefer-template
58 'prefer-template': 2,
59 // disallow generator functions that do not have yield
60 'require-yield': 0
61 }
62 };
63
node_modules/eslint-config-airbnb/rules/legacy.js
File was created 1 module.exports = {
2 'rules': {
3 // specify the maximum depth that blocks can be nested
4 'max-depth': [0, 4],
5 // limits the number of parameters that can be used in the function declaration.
6 'max-params': [0, 3],
7 // specify the maximum number of statement allowed in a function
8 'max-statements': [0, 10],
9 // disallow use of bitwise operators
10 'no-bitwise': 0,
11 // disallow use of unary operators, ++ and --
12 'no-plusplus': 0
13 }
14 };
15
node_modules/eslint-config-airbnb/rules/node.js
File was created 1 module.exports = {
2 'env': {
3 'node': true
4 },
5 'rules': {
6 // enforce return after a callback
7 'callback-return': 0,
8 // enforces error handling in callbacks (node environment)
9 'handle-callback-err': 0,
10 // disallow mixing regular variable and require declarations
11 'no-mixed-requires': [0, false],
12 // disallow use of new operator with the require function
13 'no-new-require': 0,
14 // disallow string concatenation with __dirname and __filename
15 'no-path-concat': 0,
16 // disallow process.exit()
17 'no-process-exit': 0,
18 // restrict usage of specified node modules
19 'no-restricted-modules': 0,
20 // disallow use of synchronous methods (off by default)
21 'no-sync': 0
22 }
23 };
24
node_modules/eslint-config-airbnb/rules/react.js
File was created 1 module.exports = {
2 'plugins': [
3 'react'
4 ],
5 'ecmaFeatures': {
6 'jsx': true
7 },
8 // View link below for react rules documentation
9 // https://github.com/yannickcr/eslint-plugin-react#list-of-supported-rules
10 'rules': {
11 // Prevent missing displayName in a React component definition
12 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md
13 'react/display-name': [0, { 'acceptTranspilerName': false }],
14 // Forbid certain propTypes (any, array, object)
15 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md
16 'react/forbid-prop-types': [0, { 'forbid': ['any', 'array', 'object'] }],
17 // Enforce boolean attributes notation in JSX
18 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md
19 'react/jsx-boolean-value': [2, 'never'],
20 // Validate closing bracket location in JSX
21 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md
22 'react/jsx-closing-bracket-location': [2, 'line-aligned'],
23 // Enforce or disallow spaces inside of curly braces in JSX attributes
24 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md
25 'react/jsx-curly-spacing': [0, 'never', { 'allowMultiline': true }],
26 // Enforce event handler naming conventions in JSX
27 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-handler-names.md
28 'react/jsx-handler-names': [0, {
29 'eventHandlerPrefix': 'handle',
30 'eventHandlerPropPrefix': 'on',
31 }],
32 // Validate props indentation in JSX
33 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-indent-props.md
34 'react/jsx-indent-props': [2, 2],
35 // Validate JSX has key prop when in array or iterator
36 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-key.md
37 'react/jsx-key': 0,
38 // Limit maximum of props on a single line in JSX
39 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-max-props-per-line.md
40 'react/jsx-max-props-per-line': [0, { 'maximum': 1 }],
41 // Prevent usage of .bind() and arrow functions in JSX props
42 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md
43 'react/jsx-no-bind': 2,
44 // Prevent duplicate props in JSX
45 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-duplicate-props.md
46 'react/jsx-no-duplicate-props': [0, { 'ignoreCase': false }],
47 // Prevent usage of unwrapped JSX strings
48 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-literals.md
49 'react/jsx-no-literals': 0,
50 // Disallow undeclared variables in JSX
51 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-undef.md
52 'react/jsx-no-undef': 2,
53 // Enforce PascalCase for user-defined JSX components
54 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md
55 'react/jsx-pascal-case': 0,
56 // Enforce propTypes declarations alphabetical sorting
57 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-sort-prop-types.md
58 'react/jsx-sort-prop-types': [0, {
59 'ignoreCase': false,
60 'callbacksLast': false,
61 }],
62 // Enforce props alphabetical sorting
63 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-sort-props.md
64 'react/jsx-sort-props': [0, {
65 'ignoreCase': false,
66 'callbacksLast': false,
67 }],
68 // Prevent React to be incorrectly marked as unused
69 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md
70 'react/jsx-uses-react': [2, { 'pragma': 'React' }],
71 // Prevent variables used in JSX to be incorrectly marked as unused
72 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-vars.md
73 'react/jsx-uses-vars': 2,
74 // Prevent usage of dangerous JSX properties
75 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-danger.md
76 'react/no-danger': 0,
77 // Prevent usage of deprecated methods
78 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-deprecated.md
79 'react/no-deprecated': [1, { 'react': '0.14.0' }],
80 // Prevent usage of setState in componentDidMount
81 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md
82 'react/no-did-mount-set-state': [2, 'allow-in-func'],
83 // Prevent usage of setState in componentDidUpdate
84 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md
85 'react/no-did-update-set-state': [2, 'allow-in-func'],
86 // Prevent direct mutation of this.state
87 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-direct-mutation-state.md
88 'react/no-direct-mutation-state': 0,
89 // Prevent usage of isMounted
90 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md
91 'react/no-is-mounted': 2,
92 // Prevent multiple component definition per file
93 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md
94 'react/no-multi-comp': [2, { 'ignoreStateless': true }],
95 // Prevent usage of setState
96 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-set-state.md
97 'react/no-set-state': 0,
98 // Prevent using string references
99 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md
100 'react/no-string-refs': 0,
101 // Prevent usage of unknown DOM property
102 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-unknown-property.md
103 'react/no-unknown-property': 2,
104 // Require ES6 class declarations over React.createClass
105 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md
106 'react/prefer-es6-class': [2, 'always'],
107 // Prevent missing props validation in a React component definition
108 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prop-types.md
109 'react/prop-types': [2, { 'ignore': [], customValidators: [] }],
110 // Prevent missing React when using JSX
111 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md
112 'react/react-in-jsx-scope': 2,
113 // Restrict file extensions that may be required
114 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/require-extension.md
115 'react/require-extension': [0, { 'extensions': ['.jsx'] }],
116 // Prevent extra closing tags for components without children
117 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md
118 'react/self-closing-comp': 2,
119 // Enforce component methods order
120 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md
121 'react/sort-comp': [2, {
122 'order': [
123 'lifecycle',
124 '/^on.+$/',
125 '/^(get|set)(?!(InitialState$|DefaultProps$|ChildContext$)).+$/',
126 'everything-else',
127 '/^render.+$/',
128 'render'
129 ]
130 }],
131 // Prevent missing parentheses around multilines JSX
132 // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/wrap-multilines.md
133 'react/wrap-multilines': [2, {
134 declaration: true,
135 assignment: true,
136 return: true
137 }],
138 }
139 };
140
node_modules/eslint-config-airbnb/rules/strict.js
File was created 1 module.exports = {
2 'rules': {
3 // babel inserts `'use strict';` for us
4 'strict': [2, 'never']
5 }
6 };
7
node_modules/eslint-config-airbnb/rules/style.js
File was created 1 module.exports = {
2 'rules': {
3 // enforce spacing inside array brackets
4 'array-bracket-spacing': [2, 'never'],
5 // enforce one true brace style
6 'brace-style': [2, '1tbs', { 'allowSingleLine': true }],
7 // require camel case names
8 'camelcase': [2, { 'properties': 'never' }],
9 // enforce spacing before and after comma
10 'comma-spacing': [2, { 'before': false, 'after': true }],
11 // enforce one true comma style
12 'comma-style': [2, 'last'],
13 // disallow padding inside computed properties
14 'computed-property-spacing': [2, 'never'],
15 // enforces consistent naming when capturing the current execution context
16 'consistent-this': 0,
17 // enforce newline at the end of file, with no multiple empty lines
18 'eol-last': 2,
19 // require function expressions to have a name
20 'func-names': 1,
21 // enforces use of function declarations or expressions
22 'func-style': 0,
23 // this option enforces minimum and maximum identifier lengths
24 // (variable names, property names etc.)
25 'id-length': 0,
26 // this option sets a specific tab width for your code
27 // https://github.com/eslint/eslint/blob/master/docs/rules/indent.md
28 'indent': [2, 2, { 'SwitchCase': 1, 'VariableDeclarator': 1 }],
29 // specify whether double or single quotes should be used in JSX attributes
30 // http://eslint.org/docs/rules/jsx-quotes
31 'jsx-quotes': [2, 'prefer-double'],
32 // enforces spacing between keys and values in object literal properties
33 'key-spacing': [2, { 'beforeColon': false, 'afterColon': true }],
34 // enforces empty lines around comments
35 'lines-around-comment': 0,
36 // disallow mixed 'LF' and 'CRLF' as linebreaks
37 'linebreak-style': 0,
38 // specify the maximum length of a line in your program
39 // https://github.com/eslint/eslint/blob/master/docs/rules/max-len.md
40 'max-len': [2, 100, 2, {
41 'ignoreUrls': true,
42 'ignoreComments': false
43 }],
44 // specify the maximum depth callbacks can be nested
45 'max-nested-callbacks': 0,
46 // require a capital letter for constructors
47 'new-cap': [2, { 'newIsCap': true }],
48 // disallow the omission of parentheses when invoking a constructor with no arguments
49 'new-parens': 0,
50 // allow/disallow an empty newline after var statement
51 'newline-after-var': 0,
52 // disallow use of the Array constructor
53 'no-array-constructor': 0,
54 // disallow use of the continue statement
55 'no-continue': 0,
56 // disallow comments inline after code
57 'no-inline-comments': 0,
58 // disallow if as the only statement in an else block
59 'no-lonely-if': 0,
60 // disallow mixed spaces and tabs for indentation
61 'no-mixed-spaces-and-tabs': 2,
62 // disallow multiple empty lines and only one newline at the end
63 'no-multiple-empty-lines': [2, { 'max': 2, 'maxEOF': 1 }],
64 // disallow nested ternary expressions
65 'no-nested-ternary': 2,
66 // disallow use of the Object constructor
67 'no-new-object': 2,
68 // disallow space between function identifier and application
69 'no-spaced-func': 2,
70 // disallow the use of ternary operators
71 'no-ternary': 0,
72 // disallow trailing whitespace at the end of lines
73 'no-trailing-spaces': 2,
74 // disallow dangling underscores in identifiers
75 'no-underscore-dangle': 0,
76 // disallow the use of Boolean literals in conditional expressions
77 // also, prefer `a || b` over `a ? a : b`
78 // http://eslint.org/docs/rules/no-unneeded-ternary
79 'no-unneeded-ternary': [2, { 'defaultAssignment': false }],
80 // require padding inside curly braces
81 'object-curly-spacing': [2, 'always'],
82 // allow just one var statement per function
83 'one-var': [2, 'never'],
84 // require assignment operator shorthand where possible or prohibit it entirely
85 'operator-assignment': 0,
86 // enforce operators to be placed before or after line breaks
87 'operator-linebreak': 0,
88 // enforce padding within blocks
89 'padded-blocks': [2, 'never'],
90 // require quotes around object literal property names
91 // http://eslint.org/docs/rules/quote-props.html
92 'quote-props': [2, 'as-needed', { 'keywords': false, 'unnecessary': true, 'numbers': false }],
93 // specify whether double or single quotes should be used
94 'quotes': [2, 'single', 'avoid-escape'],
95 // require identifiers to match the provided regular expression
96 'id-match': 0,
97 // enforce spacing before and after semicolons
98 'semi-spacing': [2, { 'before': false, 'after': true }],
99 // require or disallow use of semicolons instead of ASI
100 'semi': [2, 'always'],
101 // sort variables within the same declaration block
102 'sort-vars': 0,
103 // require a space before certain keywords
104 'space-before-keywords': [2, 'always'],
105 // require a space after certain keywords
106 'space-after-keywords': [2, 'always'],
107 // require or disallow space before blocks
108 'space-before-blocks': 2,
109 // require or disallow space before function opening parenthesis
110 // https://github.com/eslint/eslint/blob/master/docs/rules/space-before-function-paren.md
111 'space-before-function-paren': [2, { 'anonymous': 'always', 'named': 'never' }],
112 // require or disallow spaces inside parentheses
113 'space-in-parens': [2, 'never'],
114 // require spaces around operators
115 'space-infix-ops': 2,
116 // require a space after return, throw, and case
117 'space-return-throw-case': 2,
118 // Require or disallow spaces before/after unary operators
119 'space-unary-ops': 0,
120 // require or disallow a space immediately following the // or /* in a comment
121 'spaced-comment': [2, 'always', {
122 'exceptions': ['-', '+'],
123 'markers': ['=', '!'] // space here to support sprockets directives
124 }],
125 // require regex literals to be wrapped in parentheses
126 'wrap-regex': 0
127 }
128 };
129
node_modules/eslint-config-airbnb/rules/variables.js
File was created 1 module.exports = {
2 'rules': {
3 // enforce or disallow variable initializations at definition
4 'init-declarations': 0,
5 // disallow the catch clause parameter name being the same as a variable in the outer scope
6 'no-catch-shadow': 0,
7 // disallow deletion of variables
8 'no-delete-var': 2,
9 // disallow labels that share a name with a variable
10 'no-label-var': 0,
11 // disallow shadowing of names such as arguments
12 'no-shadow-restricted-names': 2,
13 // disallow declaration of variables already declared in the outer scope
14 'no-shadow': 2,
15 // disallow use of undefined when initializing variables
16 'no-undef-init': 0,
17 // disallow use of undeclared variables unless mentioned in a /*global */ block
18 'no-undef': 2,
19 // disallow use of undefined variable
20 'no-undefined': 0,
21 // disallow declaration of variables that are not used in the code
22 'no-unused-vars': [2, { 'vars': 'local', 'args': 'after-used' }],
23 // disallow use of variables before they are defined
24 'no-use-before-define': 2
25 }
26 };
27
node_modules/eslint-config-airbnb/test/.eslintrc
File was created 1 {
2 "rules": {
3 // disabled because I find it tedious to write tests while following this
4 // rule
5 "no-shadow": 0,
6 // tests uses `t` for tape
7 "id-length": [2, {"min": 2, "properties": "never", "exceptions": ["t"]}]
8 }
9 }
10
node_modules/eslint-config-airbnb/test/test-base.js
File was created 1 import fs from 'fs';
2 import path from 'path';
3 import test from 'tape';
4
5 const files = {
6 base: require('../base')
7 };
8
9 fs.readdirSync(path.join(__dirname, '../rules')).forEach(name => {
10 if (name === 'react.js') {
11 return;
12 }
13
14 files[name] = require(`../rules/${name}`);
15 });
16
17 Object.keys(files).forEach(name => {
18 const config = files[name];
19
20 test(`${name}: does not reference react`, t => {
21 t.plan(2);
22
23 t.notOk(config.plugins, 'plugins is unspecified');
24
25 // scan rules for react/ and fail if any exist
26 const reactRuleIds = Object.keys(config.rules)
27 .filter(ruleId => ruleId.indexOf('react/') === 0);
28 t.deepEquals(reactRuleIds, [], 'there are no react/ rules');
29 });
30 });
31
node_modules/eslint-config-airbnb/test/test-react-order.js
File was created 1 import test from 'tape';
2 import { CLIEngine } from 'eslint';
3 import eslintrc from '../';
4 import reactRules from '../rules/react';
5
6 const cli = new CLIEngine({
7 useEslintrc: false,
8 baseConfig: eslintrc,
9
10 // This rule fails when executing on text.
11 rules: { indent: 0 },
12 });
13
14 function lint(text) {
15 // @see http://eslint.org/docs/developer-guide/nodejs-api.html#executeonfiles
16 // @see http://eslint.org/docs/developer-guide/nodejs-api.html#executeontext
17 return cli.executeOnText(text).results[0];
18 }
19
20 function wrapComponent(body) {
21 return `
22 import React from 'react';
23 export default class MyComponent extends React.Component {
24 ${body}
25 }
26 `;
27 }
28
29 test('validate react prop order', t => {
30 t.test('make sure our eslintrc has React linting dependencies', t => {
31 t.plan(1);
32 t.equal(reactRules.plugins[0], 'react', 'uses eslint-plugin-react');
33 });
34
35 t.test('passes a good component', t => {
36 t.plan(3);
37 const result = lint(wrapComponent(`
38 componentWillMount() {}
39 componentDidMount() {}
40 setFoo() {}
41 getFoo() {}
42 setBar() {}
43 someMethod() {}
44 renderDogs() {}
45 render() { return <div />; }
46 `));
47
48 t.notOk(result.warningCount, 'no warnings');
49 t.notOk(result.errorCount, 'no errors');
50 t.deepEquals(result.messages, [], 'no messages in results');
51 });
52
53 t.test('order: when random method is first', t => {
54 t.plan(2);
55 const result = lint(wrapComponent(`
56 someMethod() {}
57 componentWillMount() {}
58 componentDidMount() {}
59 setFoo() {}
60 getFoo() {}
61 setBar() {}
62 renderDogs() {}
63 render() { return <div />; }
64 `));
65
66 t.ok(result.errorCount, 'fails');
67 t.equal(result.messages[0].ruleId, 'react/sort-comp', 'fails due to sort');
68 });
69
70 t.test('order: when random method after lifecycle methods', t => {
71 t.plan(2);
72 const result = lint(wrapComponent(`
73 componentWillMount() {}
74 componentDidMount() {}
75 someMethod() {}
76 setFoo() {}
77 getFoo() {}
78 setBar() {}
79 renderDogs() {}
80 render() { return <div />; }
81 `));
82
83 t.ok(result.errorCount, 'fails');
84 t.equal(result.messages[0].ruleId, 'react/sort-comp', 'fails due to sort');
85 });
86 });
87
node_modules/eslint-plugin-react/CHANGELOG.md
File was created 1 # Change Log
2 All notable changes to this project will be documented in this file.
3 This project adheres to [Semantic Versioning](http://semver.org/).
4 This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com).
5
6 ## [3.16.1] - 2016-01-24
7 ### Fixed
8 * Fix `jsx-sort-prop-types` issue with custom propTypes ([#408][] @alitaheri)
9
10 [3.16.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.16.0...v3.16.1
11 [#408]: https://github.com/yannickcr/eslint-plugin-react/issues/408
12
13 ## [3.16.0] - 2016-01-24
14 ### Added
15 * Add `jsx-equals-spacing` rule ([#394][] @ryym)
16 * Add auto fix for `wrap-multiline`
17 * Add auto fix for `jsx-boolean-value`
18 * Add auto fix for `no-unknown-property`
19 * Add auto fix for `jsx-curly-spacing` ([#407][] @ewendel)
20 * Add `requiredFirst` option to `jsx-sort-prop-types` ([#392][] @chrislaskey)
21 * Add `ignoreRefs` option to `jsx-no-bind` ([#330][] @silvenon)
22
23 ### Fixed
24 * Ignore `ref` in `jsx-handler-names` (again) ([#396][])
25
26 ### Changed
27 * Update dependencies
28
29 [3.16.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.15.0...v3.16.0
30 [#394]: https://github.com/yannickcr/eslint-plugin-react/issues/394
31 [#407]: https://github.com/yannickcr/eslint-plugin-react/pull/407
32 [#392]: https://github.com/yannickcr/eslint-plugin-react/pull/392
33 [#330]: https://github.com/yannickcr/eslint-plugin-react/issues/330
34 [#396]: https://github.com/yannickcr/eslint-plugin-react/issues/396
35
36 ## [3.15.0] - 2016-01-12
37 ### Added
38 * Add support for flow annotations to `prop-types` ([#382][] @phpnode)
39
40 ### Fixed
41 * Fix `prop-types` crash when initializing class variable with an empty object ([#383][])
42 * Fix `prop-types` crash when propTypes are using the spread operator ([#389][])
43
44 ### Changed
45 * Improve `sort-comp` error messages ([#372][] @SystemParadox)
46 * Update dependencies
47
48 [3.15.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.14.0...v3.15.0
49 [#382]: https://github.com/yannickcr/eslint-plugin-react/pull/382
50 [#383]: https://github.com/yannickcr/eslint-plugin-react/issues/383
51 [#389]: https://github.com/yannickcr/eslint-plugin-react/issues/389
52 [#372]: https://github.com/yannickcr/eslint-plugin-react/pull/372
53
54 ## [3.14.0] - 2016-01-05
55 ### Added
56 * Add `jsx-indent` rule ([#342][])
57 * Add shared setting for pragma configuration ([#228][] @NickStefan)
58
59 ### Fixed
60 * Fix crash in `jsx-key` ([#380][] @nfcampos)
61 * Fix crash in `forbid-prop-types` ([#377][] @nfcampos)
62 * Ignore `ref` in `jsx-handler-names` ([#375][])
63
64 ### Changed
65 * Add AppVeyor CI to run tests on a Windows platform
66 * Add `sort-comp` codemod to `sort-comp` documentation ([#381][] @turadg)
67
68 [3.14.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.13.1...v3.14.0
69 [#342]: https://github.com/yannickcr/eslint-plugin-react/issues/342
70 [#228]: https://github.com/yannickcr/eslint-plugin-react/issues/228
71 [#380]: https://github.com/yannickcr/eslint-plugin-react/pull/380
72 [#377]: https://github.com/yannickcr/eslint-plugin-react/pull/377
73 [#375]: https://github.com/yannickcr/eslint-plugin-react/issues/375
74 [#381]: https://github.com/yannickcr/eslint-plugin-react/pull/381
75
76 ## [3.13.1] - 2015-12-26
77 ### Fixed
78 * Fix crash in `jsx-key` ([#373][] @lukekarrys)
79
80 [3.13.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.13.0...v3.13.1
81 [#373]: https://github.com/yannickcr/eslint-plugin-react/issues/373
82
83 ## [3.13.0] - 2015-12-24
84 ### Added
85 * Add `no-string-refs` rule ([#341][] @Intellicode)
86 * Add support for propTypes assigned via a variable in `prop-types` ([#355][])
87
88 ### Fixed
89 * Fix `never` option in `prefer-es6-class`
90 * Fix `jsx-key` false-positives ([#320][] @silvenon)
91
92 ### Changed
93 * Documentation improvements ([#368][] @lencioni, [#370][] @tmcw, [#371][])
94 * Update dependencies
95
96 [3.13.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.12.0...v3.13.0
97 [#341]: https://github.com/yannickcr/eslint-plugin-react/issues/341
98 [#355]: https://github.com/yannickcr/eslint-plugin-react/issues/355
99 [#320]: https://github.com/yannickcr/eslint-plugin-react/issues/320
100
101 [#368]: https://github.com/yannickcr/eslint-plugin-react/pull/368
102 [#370]: https://github.com/yannickcr/eslint-plugin-react/pull/370
103 [#371]: https://github.com/yannickcr/eslint-plugin-react/issues/371
104
105 ## [3.12.0] - 2015-12-20
106 ### Added
107 * Add `no-deprecated` rule ([#356][] @graue)
108 * Add `no-is-mounted` rule ([#37][] @lencioni)
109 * Add `never` option to `prefer-es6-class` rule ([#359][] @pwmckenna)
110
111 ### Fixed
112 * Fix `jsx-pascal-case` to stop checking lower cased components ([#329][])
113 * Fix crash in component detection class ([#364][])
114
115 ### Changed
116 * Add link to [eslint-plugin-react-native](https://github.com/Intellicode/eslint-plugin-react-native) in Readme
117 * Update dependencies
118
119 [3.12.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.11.3...v3.12.0
120 [#356]: https://github.com/yannickcr/eslint-plugin-react/pull/356
121 [#37]: https://github.com/yannickcr/eslint-plugin-react/issues/37
122 [#359]: https://github.com/yannickcr/eslint-plugin-react/pull/359
123 [#329]: https://github.com/yannickcr/eslint-plugin-react/issues/329
124 [#364]: https://github.com/yannickcr/eslint-plugin-react/issues/364
125
126 ## [3.11.3] - 2015-12-05
127 ### Fixed
128 * Fix crash in `prop-types` when reassigning props ([#345][])
129 * Fix `jsx-handler-names` for stateless components ([#346][])
130
131 ### Changed
132 * Update `jsx-handler-names` error messages to be less specific ([#348][] @jakemmarsh)
133
134 [3.11.3]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.11.2...v3.11.3
135 [#345]: https://github.com/yannickcr/eslint-plugin-react/issues/345
136 [#346]: https://github.com/yannickcr/eslint-plugin-react/issues/346
137 [#348]: https://github.com/yannickcr/eslint-plugin-react/pull/348
138
139 ## [3.11.2] - 2015-12-01
140 ### Fixed
141 * Allow numbers in `jsx-pascal-case` ([#339][])
142 * Fix `jsx-handler-names` crash with arrays ([#340][])
143
144 ### Changed
145 * Add allow-in-func option to `no-did-update-set-state` documentation
146
147 [3.11.2]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.11.1...v3.11.2
148 [#339]: https://github.com/yannickcr/eslint-plugin-react/issues/339
149 [#340]: https://github.com/yannickcr/eslint-plugin-react/issues/340
150
151 ## [3.11.1] - 2015-11-29
152 ### Fixed
153 * Fix SVG attributes support for `no-unknown-property` ([#338][])
154
155 [3.11.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.11.0...v3.11.1
156 [#338]: https://github.com/yannickcr/eslint-plugin-react/issues/338
157
158 ## [3.11.0] - 2015-11-29
159 ### Added
160 * Add `jsx-handler-names` rule ([#315][] @jakemmarsh)
161 * Add SVG attributes support to `no-unknown-property` ([#318][])
162 * Add shorthandFirst option to `jsx-sort-props` ([#336][] @lucasmotta)
163
164 ### Fixed
165 * Fix destructured props detection in stateless components ([#326][])
166 * Fix props validation for nested stateless components ([#331][])
167 * Fix `require-extension` to ignore extension if it's part of the package name ([#319][])
168
169 ### Changed
170 * Allow consecutive uppercase letters in `jsx-pascal-case` ([#328][] @lencioni)
171 * Update dependencies
172
173 [3.11.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.10.0...v3.11.0
174 [#315]: https://github.com/yannickcr/eslint-plugin-react/pull/315
175 [#318]: https://github.com/yannickcr/eslint-plugin-react/issues/318
176 [#336]: https://github.com/yannickcr/eslint-plugin-react/pull/336
177 [#326]: https://github.com/yannickcr/eslint-plugin-react/issues/326
178 [#331]: https://github.com/yannickcr/eslint-plugin-react/issues/331
179 [#319]: https://github.com/yannickcr/eslint-plugin-react/issues/319
180 [#328]: https://github.com/yannickcr/eslint-plugin-react/issues/328
181
182 ## [3.10.0] - 2015-11-21
183 ### Added
184 * Add `jsx-pascal-case` rule ([#306][] @jakemmarsh)
185
186 ### Fixed
187 * Fix crash on incomplete class property declaration ([#317][] @dapetcu21)
188 * Fix crash with ESLint 1.10.0 ([#323][] @lukekarrys)
189
190 [3.10.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.9.0...v3.10.0
191 [#306]: https://github.com/yannickcr/eslint-plugin-react/pull/306
192 [#317]: https://github.com/yannickcr/eslint-plugin-react/issues/317
193 [#323]: https://github.com/yannickcr/eslint-plugin-react/issues/323
194
195 ## [3.9.0] - 2015-11-17
196 ### Added
197 * Add `jsx-key` rule ([#293][] @benmosher)
198 * Add `allow-in-func` option to `no-did-update-set-state` ([#300][])
199 * Add option to only enforce `jsx-closing-bracket-location` rule to one type of tag (nonEmpty or selfClosing) ([#307][])
200
201 ### Fixed
202 * Fix crash when destructuring with only the rest spread ([#269][])
203 * Fix variables detection when searching for related components ([#303][])
204 * Fix `no-unknown-property` to not check custom elements ([#308][] @zertosh)
205
206 ### Changed
207 * Improve `jsx-closing-bracket-location` error message ([#301][] @alopatin)
208 * Update dependencies
209
210 [3.9.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.8.0...v3.9.0
211 [#293]: https://github.com/yannickcr/eslint-plugin-react/pull/293
212 [#300]: https://github.com/yannickcr/eslint-plugin-react/issues/300
213 [#307]: https://github.com/yannickcr/eslint-plugin-react/issues/307
214 [#269]: https://github.com/yannickcr/eslint-plugin-react/issues/269
215 [#303]: https://github.com/yannickcr/eslint-plugin-react/issues/303
216 [#308]: https://github.com/yannickcr/eslint-plugin-react/pull/308
217 [#301]: https://github.com/yannickcr/eslint-plugin-react/pull/301
218
219 ## [3.8.0] - 2015-11-07
220 ### Added
221 * Add ignoreStateless option to `no-multi-comp` ([#290][])
222
223 ### Fixed
224 * Fix classes with properties to always be marked as components ([#291][])
225 * Fix ES5 class detection when using `createClass` by itself ([#297][])
226 * Fix direct props detection ([#298][])
227 * Ignore functions containing the keyword `this` during component detection
228
229 [3.8.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.7.1...v3.8.0
230 [#290]: https://github.com/yannickcr/eslint-plugin-react/issues/290
231 [#291]: https://github.com/yannickcr/eslint-plugin-react/issues/291
232 [#297]: https://github.com/yannickcr/eslint-plugin-react/issues/297
233 [#298]: https://github.com/yannickcr/eslint-plugin-react/issues/298
234
235 ## [3.7.1] - 2015-11-05
236 ### Fixed
237 * Fix `sort-comp` crash on stateless components ([#285][])
238 * Fix crash in ES5 components detection ([#286][])
239 * Fix ES5 components detection from nested functions ([#287][])
240
241 [3.7.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.7.0...v3.7.1
242 [#285]: https://github.com/yannickcr/eslint-plugin-react/issues/285
243 [#286]: https://github.com/yannickcr/eslint-plugin-react/issues/286
244 [#287]: https://github.com/yannickcr/eslint-plugin-react/issues/287
245
246 ## [3.7.0] - 2015-11-05
247 ### Added
248 * Add `jsx-no-bind` rule ([#184][] @Daniel15)
249 * Add line-aligned option to `jsx-closing-bracket-location` ([#243][] @alopatin)
250
251 ### Fixed
252 * Fix a lot of issues about components detection, mostly related to stateless components ([#264][], [#267][], [#268][], [#276][], [#277][], [#280][])
253
254 ### Changed
255 * Update dependencies
256
257 [3.7.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.6.3...v3.7.0
258 [#184]: https://github.com/yannickcr/eslint-plugin-react/issues/184
259 [#243]: https://github.com/yannickcr/eslint-plugin-react/issues/243
260 [#264]: https://github.com/yannickcr/eslint-plugin-react/issues/264
261 [#267]: https://github.com/yannickcr/eslint-plugin-react/issues/267
262 [#268]: https://github.com/yannickcr/eslint-plugin-react/issues/268
263 [#276]: https://github.com/yannickcr/eslint-plugin-react/issues/276
264 [#277]: https://github.com/yannickcr/eslint-plugin-react/issues/277
265 [#280]: https://github.com/yannickcr/eslint-plugin-react/issues/280
266
267 ## [3.6.3] - 2015-10-20
268 ### Fixed
269 * Fix `display-name` for stateless components ([#256][])
270 * Fix `prop-types` props validation in constructor ([#259][])
271 * Fix typo in README ([#261][] @chiedojohn)
272
273 [3.6.3]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.6.2...v3.6.3
274 [#256]: https://github.com/yannickcr/eslint-plugin-react/issues/256
275 [#259]: https://github.com/yannickcr/eslint-plugin-react/issues/259
276 [#261]: https://github.com/yannickcr/eslint-plugin-react/pull/261
277
278 ## [3.6.2] - 2015-10-18
279 ### Fixed
280 * Fix wrong prop-types detection ([#255][])
281
282 [3.6.2]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.6.1...v3.6.2
283 [#255]: https://github.com/yannickcr/eslint-plugin-react/issues/255
284
285 ## [3.6.1] - 2015-10-18
286 ### Fixed
287 * Fix props validation in constructor ([#254][])
288
289 [3.6.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.6.0...v3.6.1
290 [#254]: https://github.com/yannickcr/eslint-plugin-react/issues/254
291
292 ## [3.6.0] - 2015-10-18
293 ### Added
294 * Add support for stateless function components to `display-name` and `prop-types` ([#237][])
295 * Add callbacksLast option to `jsx-sort-props` and `jsx-sort-prop-types` ([#242][] @Daniel15)
296 * Add `prefer-es6-class` rule ([#247][] @hamiltondanielb)
297
298 ### Fixed
299 * Fix `forbid-prop-types` crash with destructured PropTypes ([#230][] @epmatsw)
300 * Fix `forbid-prop-types` to do not modify AST directly ([#249][] @rhysd)
301 * Fix `prop-types` crash with empty destructuring ([#251][])
302 * Fix `prop-types` to not validate computed keys in destructuring ([#236][])
303
304 ### Changed
305 * Update dependencies
306 * Improve components detection ([#233][])
307 * Documentation improvements ([#248][] @dguo)
308
309 [3.6.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.5.1...v3.6.0
310 [#237]: https://github.com/yannickcr/eslint-plugin-react/issues/237
311 [#242]: https://github.com/yannickcr/eslint-plugin-react/pull/242
312 [#247]: https://github.com/yannickcr/eslint-plugin-react/issues/247
313 [#230]: https://github.com/yannickcr/eslint-plugin-react/issues/230
314 [#249]: https://github.com/yannickcr/eslint-plugin-react/issues/249
315 [#251]: https://github.com/yannickcr/eslint-plugin-react/issues/251
316 [#236]: https://github.com/yannickcr/eslint-plugin-react/issues/236
317 [#233]: https://github.com/yannickcr/eslint-plugin-react/issues/233
318 [#248]: https://github.com/yannickcr/eslint-plugin-react/pull/248
319
320 ## [3.5.1] - 2015-10-01
321 ### Fixed
322 * Fix `no-direct-mutation-state` to report only in React components ([#229][])
323 * Fix `forbid-prop-types` for arrayOf and instanceOf ([#230][])
324
325 ### Changed
326 * Documentation improvements ([#232][] @edge)
327
328 [3.5.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.5.0...v3.5.1
329 [#229]: https://github.com/yannickcr/eslint-plugin-react/issues/229
330 [#230]: https://github.com/yannickcr/eslint-plugin-react/issues/230
331 [#232]: https://github.com/yannickcr/eslint-plugin-react/pull/232
332
333 ## [3.5.0] - 2015-09-28
334 ### Added
335 * Add `no-direct-mutation-state` rule ([#133][], [#201][] @petersendidit)
336 * Add `forbid-prop-types` rule ([#215][] @pwmckenna)
337
338 ### Fixed
339 * Fix no-did-mount/update-set-state rules, these rules were not working on ES6 classes
340
341 ### Changed
342 * Update dependencies
343 * Documentation improvements ([#222][] @Andersos)
344
345 [3.5.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.4.2...v3.5.0
346 [#133]: https://github.com/yannickcr/eslint-plugin-react/issues/133
347 [#201]: https://github.com/yannickcr/eslint-plugin-react/issues/201
348 [#215]: https://github.com/yannickcr/eslint-plugin-react/issues/215
349 [#222]: https://github.com/yannickcr/eslint-plugin-react/pull/222
350
351 ## [3.4.2] - 2015-09-18
352 ### Fixed
353 * Only display the `jsx-quotes` deprecation warning with the default formatter ([#221][])
354
355 [3.4.2]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.4.1...v3.4.2
356 [#221]: https://github.com/yannickcr/eslint-plugin-react/issues/221
357
358 ## [3.4.1] - 2015-09-17
359 ### Fixed
360 * Fix `jsx-quotes` rule deprecation message ([#220][])
361
362 [3.4.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.4.0...v3.4.1
363 [#220]: https://github.com/yannickcr/eslint-plugin-react/issues/220
364
365 ## [3.4.0] - 2015-09-16
366 ### Added
367 * Add namespaced JSX support to `jsx-no-undef` ([#219][] @zertosh)
368 * Add option to `jsx-closing-bracket-location` to configure different styles for self-closing and non-empty tags ([#208][] @evocateur)
369
370 ### Deprecated
371 * Deprecate `jsx-quotes` rule, will now trigger a warning if used ([#217][])
372
373 [3.4.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.3.2...v3.4.0
374 [#219]: https://github.com/yannickcr/eslint-plugin-react/pull/219
375 [#208]: https://github.com/yannickcr/eslint-plugin-react/pull/208
376 [#217]: https://github.com/yannickcr/eslint-plugin-react/issues/217
377
378 ## [3.3.2] - 2015-09-10
379 ### Changed
380 * Add `state` in lifecycle methods for `sort-comp` rule ([#197][] @mathieudutour)
381 * Treat component with render which returns `createElement` as valid ([#206][] @epmatsw)
382
383 ### Fixed
384 * Fix allowed methods on arrayOf in `prop-types` ([#146][])
385 * Fix default configuration for `jsx-boolean-value` ([#210][])
386
387 [3.3.2]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.3.1...v3.3.2
388 [#146]: https://github.com/yannickcr/eslint-plugin-react/issues/146
389 [#197]: https://github.com/yannickcr/eslint-plugin-react/pull/197
390 [#206]: https://github.com/yannickcr/eslint-plugin-react/pull/206
391 [#210]: https://github.com/yannickcr/eslint-plugin-react/issues/210
392
393 ## [3.3.1] - 2015-09-01
394 ### Changed
395 * Update dependencies
396 * Update changelog to follow the Keep a CHANGELOG standards
397 * Documentation improvements ([#198][] @lencioni)
398
399 ### Fixed
400 * Fix `jsx-closing-bracket-location` for multiline props ([#199][])
401
402 [3.3.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.3.0...v3.3.1
403 [#198]: https://github.com/yannickcr/eslint-plugin-react/pull/198
404 [#199]: https://github.com/yannickcr/eslint-plugin-react/issues/199
405
406 ## [3.3.0] - 2015-08-26
407 ### Added
408 * Add `jsx-indent-props` rule ([#15][], [#181][])
409 * Add `no-set-state rule` ([#197][] @markdalgleish)
410 * Add `jsx-closing-bracket-location` rule ([#14][], [#64][])
411
412 ### Changed
413 * Update dependencies
414
415 ### Fixed
416 * Fix crash on propTypes declarations with an empty body ([#193][] @mattyod)
417
418 [3.3.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.2.3...v3.3.0
419 [#15]: https://github.com/yannickcr/eslint-plugin-react/issues/15
420 [#181]: https://github.com/yannickcr/eslint-plugin-react/issues/181
421 [#197]: https://github.com/yannickcr/eslint-plugin-react/pull/197
422 [#14]: https://github.com/yannickcr/eslint-plugin-react/issues/14
423 [#64]: https://github.com/yannickcr/eslint-plugin-react/issues/64
424 [#193]: https://github.com/yannickcr/eslint-plugin-react/pull/193
425
426 ## [3.2.3] - 2015-08-16
427 ### Changed
428 * Update dependencies
429
430 ### Fixed
431 * Fix object rest/spread handling ([#187][] @xjamundx, [#189][] @Morantron)
432
433 [3.2.3]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.2.2...v3.2.3
434 [#187]: https://github.com/yannickcr/eslint-plugin-react/pull/187
435 [#189]: https://github.com/yannickcr/eslint-plugin-react/pull/189
436
437 ## [3.2.2] - 2015-08-11
438 ### Changed
439 * Remove peerDependencies ([#178][])
440
441 [3.2.2]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.2.1...v3.2.2
442 [#178]: https://github.com/yannickcr/eslint-plugin-react/issues/178
443
444 ## [3.2.1] - 2015-08-08
445 ### Fixed
446 * Fix crash when propTypes don't have any parent ([#182][])
447 * Fix jsx-no-literals reporting errors outside JSX ([#183][] @CalebMorris)
448
449 [3.2.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.2.0...v3.2.1
450 [#182]: https://github.com/yannickcr/eslint-plugin-react/issues/182
451 [#183]: https://github.com/yannickcr/eslint-plugin-react/pull/183
452
453 ## [3.2.0] - 2015-08-04
454 ### Added
455 * Add `jsx-max-props-per-line` rule ([#13][])
456 * Add `jsx-no-literals` rule ([#176][] @CalebMorris)
457
458 ### Changed
459 * Update dependencies
460
461 ### Fixed
462 * Fix object access in `jsx-no-undef` ([#172][])
463
464 [3.2.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.1.0...v3.2.0
465 [#13]: https://github.com/yannickcr/eslint-plugin-react/issues/13
466 [#176]: https://github.com/yannickcr/eslint-plugin-react/pull/176
467 [#172]: https://github.com/yannickcr/eslint-plugin-react/issues/172
468
469 ## [3.1.0] - 2015-07-28
470 ### Added
471 * Add event handlers to `no-unknown-property` ([#164][] @mkenyon)
472 * Add customValidators option to `prop-types` ([#145][] @CalebMorris)
473
474 ### Changed
475 * Update dependencies
476 * Documentation improvements ([#167][] @ngbrown)
477
478 ### Fixed
479 * Fix comment handling in `jsx-curly-spacing` ([#165][])
480
481 [3.1.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v3.0.0...v3.1.0
482 [#164]: https://github.com/yannickcr/eslint-plugin-react/pull/164
483 [#145]: https://github.com/yannickcr/eslint-plugin-react/issues/145
484 [#165]: https://github.com/yannickcr/eslint-plugin-react/issues/165
485 [#167]: https://github.com/yannickcr/eslint-plugin-react/pull/167
486
487 ## [3.0.0] - 2015-07-21
488 ### Added
489 * Add jsx-no-duplicate-props rule ([#161][] @hummlas)
490 * Add allowMultiline option to the `jsx-curly-spacing` rule ([#156][] @mathieumg)
491
492 ## Breaking
493 * In `jsx-curly-spacing` braces spanning multiple lines are now allowed with `never` option ([#156][] @mathieumg)
494
495 ### Fixed
496 * Fix multiple var and destructuring handling in `props-types` ([#159][])
497 * Fix crash when retrieving propType name ([#163][])
498
499 [3.0.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.7.1...v3.0.0
500 [#161]: https://github.com/yannickcr/eslint-plugin-react/pull/161
501 [#156]: https://github.com/yannickcr/eslint-plugin-react/pull/156
502 [#159]: https://github.com/yannickcr/eslint-plugin-react/issues/159
503 [#163]: https://github.com/yannickcr/eslint-plugin-react/issues/163
504
505 ## [2.7.1] - 2015-07-16
506 ### Changed
507 * Update peerDependencies requirements ([#154][])
508 * Update codebase for ESLint v1.0.0
509 * Change oneOfType to actually keep the child types ([#148][] @CalebMorris)
510 * Documentation improvements ([#147][] @lencioni)
511
512 [2.7.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.7.0...v2.7.1
513 [#154]: https://github.com/yannickcr/eslint-plugin-react/issues/154
514 [#148]: https://github.com/yannickcr/eslint-plugin-react/issues/148
515 [#147]: https://github.com/yannickcr/eslint-plugin-react/pull/147
516
517 ## [2.7.0] - 2015-07-11
518 ### Added
519 * Add `no-danger` rule ([#138][] @scothis)
520 * Add `jsx-curly-spacing` rule ([#142][])
521
522 ### Fixed
523 * Fix properties limitations on propTypes ([#139][])
524 * Fix component detection ([#144][])
525
526 [2.7.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.6.4...v2.7.0
527 [#138]: https://github.com/yannickcr/eslint-plugin-react/pull/138
528 [#142]: https://github.com/yannickcr/eslint-plugin-react/issues/142
529 [#139]: https://github.com/yannickcr/eslint-plugin-react/issues/139
530 [#144]: https://github.com/yannickcr/eslint-plugin-react/issues/144
531
532 ## [2.6.4] - 2015-07-02
533 ### Fixed
534 * Fix simple destructuring handling ([#137][])
535
536 [2.6.4]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.6.3...v2.6.4
537 [#137]: https://github.com/yannickcr/eslint-plugin-react/issues/137
538
539 ## [2.6.3] - 2015-06-30
540 ### Fixed
541 * Fix ignore option for `prop-types` rule ([#135][])
542 * Fix nested props destructuring ([#136][])
543
544 [2.6.3]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.6.2...v2.6.3
545 [#135]: https://github.com/yannickcr/eslint-plugin-react/issues/135
546 [#136]: https://github.com/yannickcr/eslint-plugin-react/issues/136
547
548 ## [2.6.2] - 2015-06-28
549 ### Fixed
550 * Fix props validation when using a prop as an object key ([#132][])
551
552 [2.6.2]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.6.1...v2.6.2
553 [#132]: https://github.com/yannickcr/eslint-plugin-react/issues/132
554
555 ## [2.6.1] - 2015-06-28
556 ### Fixed
557 * Fix crash in `prop-types` when encountering an empty variable declaration ([#130][])
558
559 [2.6.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.6.0...v2.6.1
560 [#130]: https://github.com/yannickcr/eslint-plugin-react/issues/130
561
562 ## [2.6.0] - 2015-06-28
563 ### Added
564 * Add support for nested propTypes ([#62][] [#105][] @Cellule)
565 * Add `require-extension` rule ([#117][] @scothis)
566 * Add support for computed string format in `prop-types` ([#127][] @Cellule)
567 * Add ES6 methods to `sort-comp` default configuration ([#97][] [#122][])
568 * Add support for props destructuring directly on the this keyword
569 * Add `acceptTranspilerName` option to `display-name` rule ([#75][])
570 * Add schema to validate rules options
571
572 ### Changed
573 * Update dependencies
574
575 ### Fixed
576 * Fix test command for Windows ([#114][] @Cellule)
577 * Fix detection of missing displayName and propTypes when `ecmaFeatures.jsx` is false ([#119][] @rpl)
578 * Fix propTypes destructuring with properties as string ([#118][] @Cellule)
579 * Fix `jsx-sort-prop-types` support for keys as string ([#123][] @Cellule)
580 * Fix crash if a ClassProperty has only one token ([#125][])
581 * Fix invalid class property handling in `jsx-sort-prop-types` ([#129][])
582
583 [2.6.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.5.2...v2.6.0
584 [#62]: https://github.com/yannickcr/eslint-plugin-react/issues/62
585 [#105]: https://github.com/yannickcr/eslint-plugin-react/issues/105
586 [#114]: https://github.com/yannickcr/eslint-plugin-react/pull/114
587 [#117]: https://github.com/yannickcr/eslint-plugin-react/pull/117
588 [#119]: https://github.com/yannickcr/eslint-plugin-react/pull/119
589 [#118]: https://github.com/yannickcr/eslint-plugin-react/issues/118
590 [#123]: https://github.com/yannickcr/eslint-plugin-react/pull/123
591 [#125]: https://github.com/yannickcr/eslint-plugin-react/issues/125
592 [#127]: https://github.com/yannickcr/eslint-plugin-react/pull/127
593 [#97]: https://github.com/yannickcr/eslint-plugin-react/issues/97
594 [#122]: https://github.com/yannickcr/eslint-plugin-react/issues/122
595 [#129]: https://github.com/yannickcr/eslint-plugin-react/issues/129
596 [#75]: https://github.com/yannickcr/eslint-plugin-react/issues/75
597
598 ## [2.5.2] - 2015-06-14
599 ### Fixed
600 * Fix regression in `jsx-uses-vars` with `babel-eslint` ([#110][])
601
602 [2.5.2]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.5.1...v2.5.2
603 [#110]: https://github.com/yannickcr/eslint-plugin-react/issues/110
604
605 ## [2.5.1] - 2015-06-14
606 ### Changed
607 * Update dependencies
608 * Documentation improvements ([#99][] @morenoh149)
609
610 ### Fixed
611 * Fix `prop-types` crash when propTypes definition is invalid ([#95][])
612 * Fix `jsx-uses-vars` for ES6 classes ([#96][])
613 * Fix hasOwnProperty that is taken for a prop ([#102][])
614
615 [2.5.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.5.0...v2.5.1
616 [#95]: https://github.com/yannickcr/eslint-plugin-react/issues/95
617 [#96]: https://github.com/yannickcr/eslint-plugin-react/issues/96
618 [#102]: https://github.com/yannickcr/eslint-plugin-react/issues/102
619 [#99]: https://github.com/yannickcr/eslint-plugin-react/pull/99
620
621 ## [2.5.0] - 2015-06-04
622 ### Added
623 * Add option to make `wrap-multilines` more granular ([#94][] @PiPeep)
624
625 ### Changed
626 * Update dependencies
627 * Documentation improvements ([#92][] [#93][] @lencioni)
628
629 [2.5.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.4.0...v2.5.0
630 [#94]: https://github.com/yannickcr/eslint-plugin-react/pull/94
631 [#92]: https://github.com/yannickcr/eslint-plugin-react/pull/92
632 [#93]: https://github.com/yannickcr/eslint-plugin-react/pull/93
633
634 ## [2.4.0] - 2015-05-30
635 ### Added
636 * Add pragma option to `jsx-uses-react` ([#82][] @dominicbarnes)
637 * Add context props to `sort-comp` ([#89][] @zertosh)
638
639 ### Changed
640 * Update dependencies
641 * Documentation improvement ([#91][] @matthewwithanm)
642
643 ### Fixed
644 * Fix itemID in `no-unknown-property` rule ([#85][] @cody)
645 * Fix license field in package.json ([#90][] @zertosh)
646 * Fix usage of contructor in `sort-comp` options ([#88][])
647
648 [2.4.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.3.0...v2.4.0
649 [#82]: https://github.com/yannickcr/eslint-plugin-react/pull/82
650 [#89]: https://github.com/yannickcr/eslint-plugin-react/pull/89
651 [#85]: https://github.com/yannickcr/eslint-plugin-react/pull/85
652 [#90]: https://github.com/yannickcr/eslint-plugin-react/pull/90
653 [#88]: https://github.com/yannickcr/eslint-plugin-react/issues/88
654 [#91]: https://github.com/yannickcr/eslint-plugin-react/pull/91
655
656 ## [2.3.0] - 2015-05-14
657 ### Added
658 * Add `sort-comp` rule ([#39][])
659 * Add `allow-in-func` option to `no-did-mount-set-state` ([#56][])
660
661 ### Changed
662 * Update dependencies
663 * Improve errors locations for `prop-types`
664
665 ### Fixed
666 * Fix quoted propTypes in ES6 ([#77][])
667
668 [2.3.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.2.0...v2.3.0
669 [#39]: https://github.com/yannickcr/eslint-plugin-react/issues/39
670 [#77]: https://github.com/yannickcr/eslint-plugin-react/issues/77
671 [#56]: https://github.com/yannickcr/eslint-plugin-react/issues/56
672
673 ## [2.2.0] - 2015-04-22
674 ### Added
675 * Add `jsx-sort-prop-types` rule ([#38][] @AlexKVal)
676
677 ### Changed
678 * Documentation improvements ([#71][] @AlexKVal)
679
680 ### Fixed
681 * Fix variables marked as used when a prop has the same name ([#69][] @burnnat)
682
683 [2.2.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.1.1...v2.2.0
684 [#38]: https://github.com/yannickcr/eslint-plugin-react/issues/38
685 [#69]: https://github.com/yannickcr/eslint-plugin-react/pull/69
686 [#71]: https://github.com/yannickcr/eslint-plugin-react/pull/71
687
688 ## [2.1.1] - 2015-04-17
689 ### Added
690 * Add support for classes static properties ([#43][])
691 * Add tests for the `babel-eslint` parser
692 * Add ESLint as peerDependency ([#63][] @AlexKVal)
693
694 ### Changed
695 * Documentation improvements ([#55][] @AlexKVal, [#60][] @chriscalo)
696
697 [2.1.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.1.0...v2.1.1
698 [#43]: https://github.com/yannickcr/eslint-plugin-react/issues/43
699 [#63]: https://github.com/yannickcr/eslint-plugin-react/pull/63
700 [#55]: https://github.com/yannickcr/eslint-plugin-react/pull/55
701 [#60]: https://github.com/yannickcr/eslint-plugin-react/pull/60
702
703 ## [2.1.0] - 2015-04-06
704 ### Added
705 * Add `jsx-boolean-value` rule ([#11][])
706 * Add support for static methods in `display-name` and `prop-types` ([#48][])
707
708 ### Changed
709 * Update `jsx-sort-props` to reset the alphabetical verification on spread ([#47][] @zertosh)
710 * Update `jsx-uses-vars` to be enabled by default ([#49][] @banderson)
711
712 ### Fixed
713 * Fix describing comment for hasSpreadOperator() method ([#53][] @AlexKVal)
714
715 [2.1.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.0.2...v2.1.0
716 [#47]: https://github.com/yannickcr/eslint-plugin-react/pull/47
717 [#49]: https://github.com/yannickcr/eslint-plugin-react/pull/49
718 [#11]: https://github.com/yannickcr/eslint-plugin-react/issues/11
719 [#48]: https://github.com/yannickcr/eslint-plugin-react/issues/48
720 [#53]: https://github.com/yannickcr/eslint-plugin-react/pull/53
721
722 ## [2.0.2] - 2015-03-31
723 ### Fixed
724 * Fix ignore rest spread when destructuring props ([#46][])
725 * Fix component detection in `prop-types` and `display-name` ([#45][])
726 * Fix spread handling in `jsx-sort-props` ([#42][] @zertosh)
727
728 [2.0.2]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.0.1...v2.0.2
729 [#46]: https://github.com/yannickcr/eslint-plugin-react/issues/46
730 [#45]: https://github.com/yannickcr/eslint-plugin-react/issues/45
731 [#42]: https://github.com/yannickcr/eslint-plugin-react/pull/42
732
733 ## [2.0.1] - 2015-03-30
734 ### Fixed
735 * Fix props detection when used in an object ([#41][])
736
737 [2.0.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v2.0.0...v2.0.1
738 [#41]: https://github.com/yannickcr/eslint-plugin-react/issues/41
739
740 ## [2.0.0] - 2015-03-29
741 ### Added
742 * Add `jsx-sort-props` rule ([#16][])
743 * Add `no-unknown-property` rule ([#28][])
744 * Add ignore option to `prop-types` rule
745
746 ### Changed
747 * Update dependencies
748
749 ## Breaking
750 * In `prop-types` the children prop is no longer ignored
751
752 ### Fixed
753 * Fix components are now detected when using ES6 classes ([#24][])
754 * Fix `prop-types` now return the right line/column ([#33][])
755 * Fix props are now detected when destructuring ([#27][])
756 * Fix only check for computed property names in `prop-types` ([#36][] @burnnat)
757
758 [2.0.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v1.6.1...v2.0.0
759 [#16]: https://github.com/yannickcr/eslint-plugin-react/issues/16
760 [#28]: https://github.com/yannickcr/eslint-plugin-react/issues/28
761 [#24]: https://github.com/yannickcr/eslint-plugin-react/issues/24
762 [#33]: https://github.com/yannickcr/eslint-plugin-react/issues/33
763 [#27]: https://github.com/yannickcr/eslint-plugin-react/issues/27
764 [#36]: https://github.com/yannickcr/eslint-plugin-react/pull/36
765
766 ## [1.6.1] - 2015-03-25
767 ### Changed
768 * Update `jsx-quotes` documentation
769
770 ### Fixed
771 * Fix `jsx-no-undef` with `babel-eslint` ([#30][])
772 * Fix `jsx-quotes` on Literal childs ([#29][])
773
774 [1.6.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v1.6.0...v1.6.1
775 [#30]: https://github.com/yannickcr/eslint-plugin-react/issues/30
776 [#29]: https://github.com/yannickcr/eslint-plugin-react/issues/29
777
778 ## [1.6.0] - 2015-03-22
779 ### Added
780 * Add `jsx-no-undef` rule
781 * Add `jsx-quotes` rule ([#12][])
782 * Add `@jsx` pragma support ([#23][])
783
784 ### Changed
785 * Allow `this.getState` references (not calls) in lifecycle methods ([#22][] @benmosher)
786 * Update dependencies
787
788 ### Fixed
789 * Fix `react-in-jsx-scope` in Node.js env
790 * Fix usage of propTypes with an external object ([#9][])
791
792 [1.6.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v1.5.0...v1.6.0
793 [#12]: https://github.com/yannickcr/eslint-plugin-react/issues/12
794 [#23]: https://github.com/yannickcr/eslint-plugin-react/issues/23
795 [#9]: https://github.com/yannickcr/eslint-plugin-react/issues/9
796 [#22]: https://github.com/yannickcr/eslint-plugin-react/pull/22
797
798 ## [1.5.0] - 2015-03-14
799 ### Added
800 * Add `jsx-uses-vars` rule
801
802 ### Fixed
803 * Fix `jsx-uses-react` for ESLint 0.17.0
804
805 [1.5.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v1.4.1...v1.5.0
806
807 ## [1.4.1] - 2015-03-03
808 ### Fixed
809 * Fix `this.props.children` marked as missing in props validation ([#7][])
810 * Fix usage of `this.props` without property ([#8][])
811
812 [1.4.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v1.4.0...v1.4.1
813 [#7]: https://github.com/yannickcr/eslint-plugin-react/issues/7
814 [#8]: https://github.com/yannickcr/eslint-plugin-react/issues/8
815
816 ## [1.4.0] - 2015-02-24
817 ### Added
818 * Add `react-in-jsx-scope` rule ([#5][] @glenjamin)
819 * Add `jsx-uses-react` rule ([#6][] @glenjamin)
820
821 ### Changed
822 * Update `prop-types` to check props usage insead of propTypes presence ([#4][])
823
824 [1.4.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v1.3.0...v1.4.0
825 [#4]: https://github.com/yannickcr/eslint-plugin-react/issues/4
826 [#5]: https://github.com/yannickcr/eslint-plugin-react/pull/5
827 [#6]: https://github.com/yannickcr/eslint-plugin-react/pull/6
828
829 ## [1.3.0] - 2015-02-24
830 ### Added
831 * Add `no-did-mount-set-state` rule
832 * Add `no-did-update-set-state` rule
833
834 ### Changed
835 * Update dependencies
836
837 [1.3.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v1.2.2...v1.3.0
838
839 ## [1.2.2] - 2015-02-09
840 ### Changed
841 * Update dependencies
842
843 ### Fixed
844 * Fix childs detection in `self-closing-comp` ([#3][])
845
846 [1.2.2]: https://github.com/yannickcr/eslint-plugin-react/compare/v1.2.1...v1.2.2
847 [#3]: https://github.com/yannickcr/eslint-plugin-react/issues/3
848
849 ## [1.2.1] - 2015-01-29
850 ### Changed
851 * Update Readme
852 * Update dependencies
853 * Update `wrap-multilines` and `self-closing-comp` rules for ESLint 0.13.0
854
855 [1.2.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v1.2.0...v1.2.1
856
857 ## [1.2.0] - 2014-12-29
858 ### Added
859 * Add `self-closing-comp` rule
860
861 ### Fixed
862 * Fix `display-name` and `prop-types` rules
863
864 [1.2.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v1.1.0...v1.2.0
865
866 ## [1.1.0] - 2014-12-28
867 ### Added
868 * Add `display-name` rule
869 * Add `wrap-multilines` rule
870 * Add rules documentation
871 * Add rules tests
872
873 [1.1.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v1.0.0...v1.1.0
874
875 ## 1.0.0 - 2014-12-16
876 ### Added
877 * First revision
878
node_modules/eslint-plugin-react/LICENSE
File was created 1 The MIT License (MIT)
2
3 Copyright (c) 2014 Yannick Croissant
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
23
node_modules/eslint-plugin-react/README.md
File was created 1 ESLint-plugin-React
2 ===================
3
4 [![Maintenance Status][status-image]][status-url] [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Build Status][appveyor-image]][appveyor-url] [![Dependency Status][deps-image]][deps-url] [![Coverage Status][coverage-image]][coverage-url] [![Code Climate][climate-image]][climate-url]
5
6 React specific linting rules for ESLint
7
8 # Installation
9
10 Install [ESLint](https://www.github.com/eslint/eslint) either locally or globally.
11
12 ```sh
13 $ npm install eslint
14 ```
15
16 If you installed `ESLint` globally, you have to install React plugin globally too. Otherwise, install it locally.
17
18 ```sh
19 $ npm install eslint-plugin-react
20 ```
21
22 # Configuration
23
24 Add `plugins` section and specify ESLint-plugin-React as a plugin.
25
26 ```json
27 {
28 "plugins": [
29 "react"
30 ]
31 }
32 ```
33
34 You can also specify some settings that will be shared across all the plugin rules.
35
36 ```js
37 {
38 "settings": {
39 "react": {
40 "pragma": "React" // Pragma to use, default to "React"
41 }
42 }
43 }
44 ```
45
46 If it is not already the case you must also configure `ESLint` to support JSX.
47
48 With ESLint 1.x.x:
49
50 ```json
51 {
52 "ecmaFeatures": {
53 "jsx": true
54 }
55 }
56 ```
57
58 With ESLint 2.x.x:
59
60 ```json
61 {
62 "parserOptions": {
63 "ecmaFeatures": {
64 "jsx": true
65 }
66 }
67 }
68 ```
69
70 Finally, enable all of the rules that you would like to use.
71
72 ```json
73 {
74 "rules": {
75 "react/display-name": 1,
76 "react/forbid-prop-types": 1,
77 "react/jsx-boolean-value": 1,
78 "react/jsx-closing-bracket-location": 1,
79 "react/jsx-curly-spacing": 1,
80 "react/jsx-equals-spacing": 1,
81 "react/jsx-handler-names": 1,
82 "react/jsx-indent-props": 1,
83 "react/jsx-indent": 1,
84 "react/jsx-key": 1,
85 "react/jsx-max-props-per-line": 1,
86 "react/jsx-no-bind": 1,
87 "react/jsx-no-duplicate-props": 1,
88 "react/jsx-no-literals": 1,
89 "react/jsx-no-undef": 1,
90 "react/jsx-pascal-case": 1,
91 "react/jsx-quotes": 1,
92 "react/jsx-sort-prop-types": 1,
93 "react/jsx-sort-props": 1,
94 "react/jsx-uses-react": 1,
95 "react/jsx-uses-vars": 1,
96 "react/no-danger": 1,
97 "react/no-deprecated": 1,
98 "react/no-did-mount-set-state": 1,
99 "react/no-did-update-set-state": 1,
100 "react/no-direct-mutation-state": 1,
101 "react/no-is-mounted": 1,
102 "react/no-multi-comp": 1,
103 "react/no-set-state": 1,
104 "react/no-string-refs": 1,
105 "react/no-unknown-property": 1,
106 "react/prefer-es6-class": 1,
107 "react/prop-types": 1,
108 "react/react-in-jsx-scope": 1,
109 "react/require-extension": 1,
110 "react/self-closing-comp": 1,
111 "react/sort-comp": 1,
112 "react/wrap-multilines": 1
113 }
114 }
115 ```
116
117 # List of supported rules
118
119 * [display-name](docs/rules/display-name.md): Prevent missing `displayName` in a React component definition
120 * [forbid-prop-types](docs/rules/forbid-prop-types.md): Forbid certain propTypes
121 * [jsx-boolean-value](docs/rules/jsx-boolean-value.md): Enforce boolean attributes notation in JSX (fixable)
122 * [jsx-closing-bracket-location](docs/rules/jsx-closing-bracket-location.md): Validate closing bracket location in JSX
123 * [jsx-curly-spacing](docs/rules/jsx-curly-spacing.md): Enforce or disallow spaces inside of curly braces in JSX attributes (fixable)
124 * [jsx-equals-spacing](docs/rules/jsx-equals-spacing.md): Enforce or disallow spaces around equal signs in JSX attributes
125 * [jsx-handler-names](docs/rules/jsx-handler-names.md): Enforce event handler naming conventions in JSX
126 * [jsx-indent-props](docs/rules/jsx-indent-props.md): Validate props indentation in JSX
127 * [jsx-indent](docs/rules/jsx-indent.md): Validate JSX indentation
128 * [jsx-key](docs/rules/jsx-key.md): Validate JSX has key prop when in array or iterator
129 * [jsx-max-props-per-line](docs/rules/jsx-max-props-per-line.md): Limit maximum of props on a single line in JSX
130 * [jsx-no-bind](docs/rules/jsx-no-bind.md): Prevent usage of `.bind()` and arrow functions in JSX props
131 * [jsx-no-duplicate-props](docs/rules/jsx-no-duplicate-props.md): Prevent duplicate props in JSX
132 * [jsx-no-literals](docs/rules/jsx-no-literals.md): Prevent usage of unwrapped JSX strings
133 * [jsx-no-undef](docs/rules/jsx-no-undef.md): Disallow undeclared variables in JSX
134 * [jsx-pascal-case](docs/rules/jsx-pascal-case.md): Enforce PascalCase for user-defined JSX components
135 * [jsx-quotes](docs/rules/jsx-quotes.md): Enforce quote style for JSX attributes
136 * [jsx-sort-prop-types](docs/rules/jsx-sort-prop-types.md): Enforce propTypes declarations alphabetical sorting
137 * [jsx-sort-props](docs/rules/jsx-sort-props.md): Enforce props alphabetical sorting
138 * [jsx-uses-react](docs/rules/jsx-uses-react.md): Prevent React to be incorrectly marked as unused
139 * [jsx-uses-vars](docs/rules/jsx-uses-vars.md): Prevent variables used in JSX to be incorrectly marked as unused
140 * [no-danger](docs/rules/no-danger.md): Prevent usage of dangerous JSX properties
141 * [no-deprecated](docs/rules/no-deprecated.md): Prevent usage of deprecated methods
142 * [no-did-mount-set-state](docs/rules/no-did-mount-set-state.md): Prevent usage of `setState` in `componentDidMount`
143 * [no-did-update-set-state](docs/rules/no-did-update-set-state.md): Prevent usage of `setState` in `componentDidUpdate`
144 * [no-direct-mutation-state](docs/rules/no-direct-mutation-state.md): Prevent direct mutation of `this.state`
145 * [no-is-mounted](docs/rules/no-is-mounted.md): Prevent usage of `isMounted`
146 * [no-multi-comp](docs/rules/no-multi-comp.md): Prevent multiple component definition per file
147 * [no-set-state](docs/rules/no-set-state.md): Prevent usage of `setState`
148 * [no-string-refs](docs/rules/no-string-refs.md): Prevent using string references in `ref` attribute.
149 * [no-unknown-property](docs/rules/no-unknown-property.md): Prevent usage of unknown DOM property (fixable)
150 * [prefer-es6-class](docs/rules/prefer-es6-class.md): Enforce ES5 or ES6 class for React Components
151 * [prop-types](docs/rules/prop-types.md): Prevent missing props validation in a React component definition
152 * [react-in-jsx-scope](docs/rules/react-in-jsx-scope.md): Prevent missing `React` when using JSX
153 * [require-extension](docs/rules/require-extension.md): Restrict file extensions that may be required
154 * [self-closing-comp](docs/rules/self-closing-comp.md): Prevent extra closing tags for components without children
155 * [sort-comp](docs/rules/sort-comp.md): Enforce component methods order
156 * [wrap-multilines](docs/rules/wrap-multilines.md): Prevent missing parentheses around multilines JSX (fixable)
157
158 ## React Native
159
160 If you're searching for React Native specific linting rules, check out [eslint-plugin-react-native](https://github.com/Intellicode/eslint-plugin-react-native).
161
162 # License
163
164 ESLint-plugin-React is licensed under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
165
166
167 [npm-url]: https://npmjs.org/package/eslint-plugin-react
168 [npm-image]: https://img.shields.io/npm/v/eslint-plugin-react.svg
169
170 [travis-url]: https://travis-ci.org/yannickcr/eslint-plugin-react
171 [travis-image]: https://img.shields.io/travis/yannickcr/eslint-plugin-react/master.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSItMTQyLjUgLTE0Mi41IDI4NSAyODUiPjxjaXJjbGUgcj0iMTQxLjciIGZpbGw9IiNERDQ4MTQiLz48ZyBpZD0iYSIgZmlsbD0iI0ZGRiI%2BPGNpcmNsZSBjeD0iLTk2LjQiIHI9IjE4LjkiLz48cGF0aCBkPSJNLTQ1LjYgNjguNGMtMTYuNi0xMS0yOS0yOC0zNC00Ny44IDYtNSA5LjgtMTIuMyA5LjgtMjAuNnMtMy44LTE1LjctOS44LTIwLjZjNS0xOS44IDE3LjQtMzYuNyAzNC00Ny44bDEzLjggMjMuMkMtNDYtMzUuMi01NS4zLTE4LjctNTUuMyAwYzAgMTguNyA5LjMgMzUuMiAyMy41IDQ1LjJ6Ii8%2BPC9nPjx1c2UgeGxpbms6aHJlZj0iI2EiIHRyYW5zZm9ybT0icm90YXRlKDEyMCkiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSgyNDApIi8%2BPC9zdmc%2B
172
173 [appveyor-url]: https://ci.appveyor.com/project/yannickcr/eslint-plugin-react
174 [appveyor-image]: https://img.shields.io/appveyor/ci/yannickcr/eslint-plugin-react/master.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjEyOCIgaGVpZ2h0PSIxMjgiIHZpZXdCb3g9IjAgMCAxMjggMTI4Ij48ZyBmaWxsPSIjMUJBMUUyIiB0cmFuc2Zvcm09InNjYWxlKDgpIj48cGF0aCBkPSJNMCAyLjI2NWw2LjUzOS0uODg4LjAwMyA2LjI4OC02LjUzNi4wMzd6Ii8%2BPHBhdGggZD0iTTYuNTM2IDguMzlsLjAwNSA2LjI5My02LjUzNi0uODk2di01LjQ0eiIvPjxwYXRoIGQ9Ik03LjMyOCAxLjI2MWw4LjY3LTEuMjYxdjcuNTg1bC04LjY3LjA2OXoiLz48cGF0aCBkPSJNMTYgOC40NDlsLS4wMDIgNy41NTEtOC42Ny0xLjIyLS4wMTItNi4zNDV6Ii8%2BPC9nPjwvc3ZnPg==
175
176 [deps-url]: https://david-dm.org/yannickcr/eslint-plugin-react
177 [deps-image]: https://img.shields.io/david/dev/yannickcr/eslint-plugin-react.svg
178
179 [coverage-url]: https://coveralls.io/r/yannickcr/eslint-plugin-react?branch=master
180 [coverage-image]: https://img.shields.io/coveralls/yannickcr/eslint-plugin-react/master.svg
181
182 [climate-url]: https://codeclimate.com/github/yannickcr/eslint-plugin-react
183 [climate-image]: https://img.shields.io/codeclimate/github/yannickcr/eslint-plugin-react.svg
184
185 [status-url]: https://github.com/yannickcr/eslint-plugin-react/pulse
186 [status-image]: https://img.shields.io/badge/status-maintained-brightgreen.svg
187
node_modules/eslint-plugin-react/index.js
File was created 1 'use strict';
2
3 module.exports = {
4 rules: {
5 'jsx-uses-react': require('./lib/rules/jsx-uses-react'),
6 'no-multi-comp': require('./lib/rules/no-multi-comp'),
7 'prop-types': require('./lib/rules/prop-types'),
8 'display-name': require('./lib/rules/display-name'),
9 'wrap-multilines': require('./lib/rules/wrap-multilines'),
10 'self-closing-comp': require('./lib/rules/self-closing-comp'),
11 'no-danger': require('./lib/rules/no-danger'),
12 'no-set-state': require('./lib/rules/no-set-state'),
13 'no-is-mounted': require('./lib/rules/no-is-mounted'),
14 'no-deprecated': require('./lib/rules/no-deprecated'),
15 'no-did-mount-set-state': require('./lib/rules/no-did-mount-set-state'),
16 'no-did-update-set-state': require('./lib/rules/no-did-update-set-state'),
17 'react-in-jsx-scope': require('./lib/rules/react-in-jsx-scope'),
18 'jsx-uses-vars': require('./lib/rules/jsx-uses-vars'),
19 'jsx-handler-names': require('./lib/rules/jsx-handler-names'),
20 'jsx-pascal-case': require('./lib/rules/jsx-pascal-case'),
21 'jsx-no-bind': require('./lib/rules/jsx-no-bind'),
22 'jsx-no-undef': require('./lib/rules/jsx-no-undef'),
23 'jsx-quotes': require('./lib/rules/jsx-quotes'),
24 'no-unknown-property': require('./lib/rules/no-unknown-property'),
25 'jsx-curly-spacing': require('./lib/rules/jsx-curly-spacing'),
26 'jsx-equals-spacing': require('./lib/rules/jsx-equals-spacing'),
27 'jsx-sort-props': require('./lib/rules/jsx-sort-props'),
28 'jsx-sort-prop-types': require('./lib/rules/jsx-sort-prop-types'),
29 'jsx-boolean-value': require('./lib/rules/jsx-boolean-value'),
30 'sort-comp': require('./lib/rules/sort-comp'),
31 'require-extension': require('./lib/rules/require-extension'),
32 'jsx-no-duplicate-props': require('./lib/rules/jsx-no-duplicate-props'),
33 'jsx-max-props-per-line': require('./lib/rules/jsx-max-props-per-line'),
34 'jsx-no-literals': require('./lib/rules/jsx-no-literals'),
35 'jsx-indent-props': require('./lib/rules/jsx-indent-props'),
36 'jsx-indent': require('./lib/rules/jsx-indent'),
37 'jsx-closing-bracket-location': require('./lib/rules/jsx-closing-bracket-location'),
38 'no-direct-mutation-state': require('./lib/rules/no-direct-mutation-state'),
39 'forbid-prop-types': require('./lib/rules/forbid-prop-types'),
40 'prefer-es6-class': require('./lib/rules/prefer-es6-class'),
41 'jsx-key': require('./lib/rules/jsx-key'),
42 'no-string-refs': require('./lib/rules/no-string-refs')
43 },
44 rulesConfig: {
45 'jsx-uses-react': 0,
46 'no-multi-comp': 0,
47 'prop-types': 0,
48 'display-name': 0,
49 'wrap-multilines': 0,
50 'self-closing-comp': 0,
51 'no-deprecated': 0,
52 'no-danger': 0,
53 'no-set-state': 0,
54 'no-is-mounted': 0,
55 'no-did-mount-set-state': 0,
56 'no-did-update-set-state': 0,
57 'react-in-jsx-scope': 0,
58 'jsx-uses-vars': 1,
59 'jsx-handler-names': 0,
60 'jsx-pascal-case': 0,
61 'jsx-no-bind': 0,
62 'jsx-no-undef': 0,
63 'jsx-quotes': 0,
64 'no-unknown-property': 0,
65 'jsx-curly-spacing': 0,
66 'jsx-equals-spacing': 0,
67 'jsx-sort-props': 0,
68 'jsx-sort-prop-types': 0,
69 'jsx-boolean-value': 0,
70 'sort-comp': 0,
71 'require-extension': 0,
72 'jsx-no-duplicate-props': 0,
73 'jsx-max-props-per-line': 0,
74 'jsx-no-literals': 0,
75 'jsx-indent-props': 0,
76 'jsx-indent': 0,
77 'jsx-closing-bracket-location': 0,
78 'no-direct-mutation-state': 0,
79 'forbid-prop-types': 0,
80 'prefer-es6-class': 0,
81 'jsx-key': 0,
82 'no-string-refs': 0
83 }
84 };
85
node_modules/eslint-plugin-react/lib/rules/display-name.js
File was created 1 /**
2 * @fileoverview Prevent missing displayName in a React component definition
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 var Components = require('../util/Components');
8
9 // ------------------------------------------------------------------------------
10 // Rule Definition
11 // ------------------------------------------------------------------------------
12
13 module.exports = Components.detect(function(context, components, utils) {
14
15 var config = context.options[0] || {};
16 var acceptTranspilerName = config.acceptTranspilerName || false;
17
18 var MISSING_MESSAGE = 'Component definition is missing display name';
19
20 /**
21 * Checks if we are declaring a display name
22 * @param {ASTNode} node The AST node being checked.
23 * @returns {Boolean} True if we are declaring a display name, false if not.
24 */
25 function isDisplayNameDeclaration(node) {
26 // Special case for class properties
27 // (babel-eslint does not expose property name so we have to rely on tokens)
28 if (node.type === 'ClassProperty') {
29 var tokens = context.getFirstTokens(node, 2);
30 if (
31 tokens[0].value === 'displayName' ||
32 (tokens[1] && tokens[1].value === 'displayName')
33 ) {
34 return true;
35 }
36 return false;
37 }
38
39 return Boolean(
40 node &&
41 node.name === 'displayName'
42 );
43 }
44
45 /**
46 * Mark a prop type as declared
47 * @param {ASTNode} node The AST node being checked.
48 */
49 function markDisplayNameAsDeclared(node) {
50 components.set(node, {
51 hasDisplayName: true
52 });
53 }
54
55 /**
56 * Reports missing display name for a given component
57 * @param {Object} component The component to process
58 */
59 function reportMissingDisplayName(component) {
60 context.report(
61 component.node,
62 MISSING_MESSAGE, {
63 component: component.name
64 }
65 );
66 }
67
68 /**
69 * Checks if the component have a name set by the transpiler
70 * @param {ASTNode} node The AST node being checked.
71 * @returns {Boolean} True ifcomponent have a name, false if not.
72 */
73 function hasTranspilerName(node) {
74 var namedObjectAssignment = (
75 node.type === 'ObjectExpression' &&
76 node.parent &&
77 node.parent.parent &&
78 node.parent.parent.type === 'AssignmentExpression' && (
79 !node.parent.parent.left.object ||
80 node.parent.parent.left.object.name !== 'module' ||
81 node.parent.parent.left.property.name !== 'exports'
82 )
83 );
84 var namedObjectDeclaration = (
85 node.type === 'ObjectExpression' &&
86 node.parent &&
87 node.parent.parent &&
88 node.parent.parent.type === 'VariableDeclarator'
89 );
90 var namedClass = (
91 node.type === 'ClassDeclaration' &&
92 node.id && node.id.name
93 );
94
95 var namedFunctionDeclaration = (
96 (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') &&
97 node.id &&
98 node.id.name
99 );
100
101 var namedFunctionExpression = (
102 (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') &&
103 node.parent &&
104 (node.parent.type === 'VariableDeclarator' || node.parent.method === true)
105 );
106
107 if (
108 namedObjectAssignment || namedObjectDeclaration ||
109 namedClass ||
110 namedFunctionDeclaration || namedFunctionExpression
111 ) {
112 return true;
113 }
114 return false;
115 }
116
117 // --------------------------------------------------------------------------
118 // Public
119 // --------------------------------------------------------------------------
120
121 return {
122
123 ClassProperty: function(node) {
124 if (!isDisplayNameDeclaration(node)) {
125 return;
126 }
127 markDisplayNameAsDeclared(node);
128 },
129
130 MemberExpression: function(node) {
131 if (!isDisplayNameDeclaration(node.property)) {
132 return;
133 }
134 var component = utils.getRelatedComponent(node);
135 if (!component) {
136 return;
137 }
138 markDisplayNameAsDeclared(component.node);
139 },
140
141 FunctionExpression: function(node) {
142 if (!acceptTranspilerName || !hasTranspilerName(node)) {
143 return;
144 }
145 markDisplayNameAsDeclared(node);
146 },
147
148 FunctionDeclaration: function(node) {
149 if (!acceptTranspilerName || !hasTranspilerName(node)) {
150 return;
151 }
152 markDisplayNameAsDeclared(node);
153 },
154
155 ArrowFunctionExpression: function(node) {
156 if (!acceptTranspilerName || !hasTranspilerName(node)) {
157 return;
158 }
159 markDisplayNameAsDeclared(node);
160 },
161
162 MethodDefinition: function(node) {
163 if (!isDisplayNameDeclaration(node.key)) {
164 return;
165 }
166 markDisplayNameAsDeclared(node);
167 },
168
169 ClassDeclaration: function(node) {
170 if (!acceptTranspilerName || !hasTranspilerName(node)) {
171 return;
172 }
173 markDisplayNameAsDeclared(node);
174 },
175
176 ObjectExpression: function(node) {
177 if (!acceptTranspilerName || !hasTranspilerName(node)) {
178 // Search for the displayName declaration
179 node.properties.forEach(function(property) {
180 if (!property.key || !isDisplayNameDeclaration(property.key)) {
181 return;
182 }
183 markDisplayNameAsDeclared(node);
184 });
185 return;
186 }
187 markDisplayNameAsDeclared(node);
188 },
189
190 'Program:exit': function() {
191 var list = components.list();
192 // Report missing display name for all components
193 for (var component in list) {
194 if (!list.hasOwnProperty(component) || list[component].hasDisplayName) {
195 continue;
196 }
197 reportMissingDisplayName(list[component]);
198 }
199 }
200 };
201 });
202
203 module.exports.schema = [{
204 type: 'object',
205 properties: {
206 acceptTranspilerName: {
207 type: 'boolean'
208 }
209 },
210 additionalProperties: false
211 }];
212
node_modules/eslint-plugin-react/lib/rules/forbid-prop-types.js
File was created 1 /**
2 * @fileoverview Forbid certain propTypes
3 */
4 'use strict';
5
6 // ------------------------------------------------------------------------------
7 // Constants
8 // ------------------------------------------------------------------------------
9
10 var DEFAULTS = ['any', 'array', 'object'];
11
12 // ------------------------------------------------------------------------------
13 // Rule Definition
14 // ------------------------------------------------------------------------------
15
16 module.exports = function(context) {
17
18 function isForbidden(type) {
19 var configuration = context.options[0] || {};
20
21 var forbid = configuration.forbid || DEFAULTS;
22 return forbid.indexOf(type) >= 0;
23 }
24
25 /**
26 * Checks if node is `propTypes` declaration
27 * @param {ASTNode} node The AST node being checked.
28 * @returns {Boolean} True if node is `propTypes` declaration, false if not.
29 */
30 function isPropTypesDeclaration(node) {
31
32 // Special case for class properties
33 // (babel-eslint does not expose property name so we have to rely on tokens)
34 if (node.type === 'ClassProperty') {
35 var tokens = context.getFirstTokens(node, 2);
36 if (tokens[0].value === 'propTypes' || (tokens[1] && tokens[1].value === 'propTypes')) {
37 return true;
38 }
39 return false;
40 }
41
42 return Boolean(
43 node &&
44 node.name === 'propTypes'
45 );
46 }
47
48
49 /**
50 * Checks if propTypes declarations are forbidden
51 * @param {Array} declarations The array of AST nodes being checked.
52 * @returns {void}
53 */
54 function checkForbidden(declarations) {
55 declarations.forEach(function(declaration) {
56 var target;
57 var value = declaration.value;
58 if (
59 value.type === 'MemberExpression' &&
60 value.property &&
61 value.property.name &&
62 value.property.name === 'isRequired'
63 ) {
64 value = value.object;
65 }
66 if (
67 value.type === 'CallExpression' &&
68 value.callee.type === 'MemberExpression'
69 ) {
70 value = value.callee;
71 }
72 if (value.property) {
73 target = value.property.name;
74 } else if (value.type === 'Identifier') {
75 target = value.name;
76 }
77 if (isForbidden(target)) {
78 context.report(declaration, 'Prop type `' + target + '` is forbidden');
79 }
80 });
81 }
82
83 return {
84 ClassProperty: function(node) {
85 if (isPropTypesDeclaration(node) && node.value && node.value.type === 'ObjectExpression') {
86 checkForbidden(node.value.properties);
87 }
88 },
89
90 MemberExpression: function(node) {
91 if (isPropTypesDeclaration(node.property)) {
92 var right = node.parent.right;
93 if (right && right.type === 'ObjectExpression') {
94 checkForbidden(right.properties);
95 }
96 }
97 },
98
99 ObjectExpression: function(node) {
100 node.properties.forEach(function(property) {
101 if (!property.key) {
102 return;
103 }
104
105 if (!isPropTypesDeclaration(property.key)) {
106 return;
107 }
108 if (property.value.type === 'ObjectExpression') {
109 checkForbidden(property.value.properties);
110 }
111 });
112 }
113
114 };
115 };
116
117 module.exports.schema = [{
118 type: 'object',
119 properties: {
120 forbid: {
121 type: 'array',
122 items: {
123 type: 'string'
124 }
125 }
126 },
127 additionalProperties: true
128 }];
129
node_modules/eslint-plugin-react/lib/rules/jsx-boolean-value.js
File was created 1 /**
2 * @fileoverview Enforce boolean attributes notation in JSX
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Rule Definition
9 // ------------------------------------------------------------------------------
10
11 module.exports = function(context) {
12
13 var configuration = context.options[0] || 'never';
14
15 var NEVER_MESSAGE = 'Value must be omitted for boolean attributes';
16 var ALWAYS_MESSAGE = 'Value must be set for boolean attributes';
17
18 return {
19 JSXAttribute: function(node) {
20 switch (configuration) {
21 case 'always':
22 if (node.value === null) {
23 context.report({
24 node: node,
25 message: ALWAYS_MESSAGE,
26 fix: function(fixer) {
27 return fixer.insertTextAfter(node, '={true}');
28 }
29 });
30 }
31 break;
32 case 'never':
33 if (node.value && node.value.type === 'JSXExpressionContainer' && node.value.expression.value === true) {
34 context.report({
35 node: node,
36 message: NEVER_MESSAGE,
37 fix: function(fixer) {
38 return fixer.removeRange([node.name.range[1], node.value.range[1]]);
39 }
40 });
41 }
42 break;
43 default:
44 break;
45 }
46 }
47 };
48 };
49
50 module.exports.schema = [{
51 enum: ['always', 'never']
52 }];
53
node_modules/eslint-plugin-react/lib/rules/jsx-closing-bracket-location.js
File was created 1 /**
2 * @fileoverview Validate closing bracket location in JSX
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Rule Definition
9 // ------------------------------------------------------------------------------
10 module.exports = function(context) {
11
12 var MESSAGE = 'The closing bracket must be {{location}}{{details}}';
13 var MESSAGE_LOCATION = {
14 'after-props': 'placed after the last prop',
15 'after-tag': 'placed after the opening tag',
16 'props-aligned': 'aligned with the last prop',
17 'tag-aligned': 'aligned with the opening tag',
18 'line-aligned': 'aligned with the line containing the opening tag'
19 };
20 var DEFAULT_LOCATION = 'tag-aligned';
21
22 var config = context.options[0];
23 var options = {
24 nonEmpty: DEFAULT_LOCATION,
25 selfClosing: DEFAULT_LOCATION
26 };
27
28 if (typeof config === 'string') {
29 // simple shorthand [1, 'something']
30 options.nonEmpty = config;
31 options.selfClosing = config;
32 } else if (typeof config === 'object') {
33 // [1, {location: 'something'}] (back-compat)
34 if (config.hasOwnProperty('location')) {
35 options.nonEmpty = config.location;
36 options.selfClosing = config.location;
37 }
38 // [1, {nonEmpty: 'something'}]
39 if (config.hasOwnProperty('nonEmpty')) {
40 options.nonEmpty = config.nonEmpty;
41 }
42 // [1, {selfClosing: 'something'}]
43 if (config.hasOwnProperty('selfClosing')) {
44 options.selfClosing = config.selfClosing;
45 }
46 }
47
48 /**
49 * Get expected location for the closing bracket
50 * @param {Object} tokens Locations of the opening bracket, closing bracket and last prop
51 * @return {String} Expected location for the closing bracket
52 */
53 function getExpectedLocation(tokens) {
54 var location;
55 // Is always after the opening tag if there is no props
56 if (typeof tokens.lastProp === 'undefined') {
57 location = 'after-tag';
58 // Is always after the last prop if this one is on the same line as the opening bracket
59 } else if (tokens.opening.line === tokens.lastProp.line) {
60 location = 'after-props';
61 // Else use configuration dependent on selfClosing property
62 } else {
63 location = tokens.selfClosing ? options.selfClosing : options.nonEmpty;
64 }
65 return location;
66 }
67
68 /**
69 * Get the correct 0-indexed column for the closing bracket, given the
70 * expected location.
71 * @param {Object} tokens Locations of the opening bracket, closing bracket and last prop
72 * @param {String} expectedLocation Expected location for the closing bracket
73 * @return {?Number} The correct column for the closing bracket, or null
74 */
75 function getCorrectColumn(tokens, expectedLocation) {
76 switch (expectedLocation) {
77 case 'props-aligned':
78 return tokens.lastProp.column;
79 case 'tag-aligned':
80 return tokens.opening.column;
81 case 'line-aligned':
82 return tokens.openingStartOfLine.column;
83 default:
84 return null;
85 }
86 }
87
88 /**
89 * Check if the closing bracket is correctly located
90 * @param {Object} tokens Locations of the opening bracket, closing bracket and last prop
91 * @param {String} expectedLocation Expected location for the closing bracket
92 * @return {Boolean} True if the closing bracket is correctly located, false if not
93 */
94 function hasCorrectLocation(tokens, expectedLocation) {
95 switch (expectedLocation) {
96 case 'after-tag':
97 return tokens.tag.line === tokens.closing.line;
98 case 'after-props':
99 return tokens.lastProp.line === tokens.closing.line;
100 case 'props-aligned':
101 case 'tag-aligned':
102 case 'line-aligned':
103 var correctColumn = getCorrectColumn(tokens, expectedLocation);
104 return correctColumn === tokens.closing.column;
105 default:
106 return true;
107 }
108 }
109
110 /**
111 * Get the locations of the opening bracket, closing bracket, last prop, and
112 * start of opening line.
113 * @param {ASTNode} node The node to check
114 * @return {Object} Locations of the opening bracket, closing bracket, last
115 * prop and start of opening line.
116 */
117 function getTokensLocations(node) {
118 var opening = context.getFirstToken(node).loc.start;
119 var closing = context.getLastTokens(node, node.selfClosing ? 2 : 1)[0].loc.start;
120 var tag = context.getFirstToken(node.name).loc.start;
121 var lastProp;
122 if (node.attributes.length) {
123 lastProp = node.attributes[node.attributes.length - 1];
124 lastProp = {
125 column: context.getFirstToken(lastProp).loc.start.column,
126 line: context.getLastToken(lastProp).loc.end.line
127 };
128 }
129 var openingLine = context.getSourceCode().lines[opening.line - 1];
130 var openingStartOfLine = {
131 column: /^\s*/.exec(openingLine)[0].length,
132 line: opening.line
133 };
134 return {
135 tag: tag,
136 opening: opening,
137 closing: closing,
138 lastProp: lastProp,
139 selfClosing: node.selfClosing,
140 openingStartOfLine: openingStartOfLine
141 };
142 }
143
144 return {
145 JSXOpeningElement: function(node) {
146 var tokens = getTokensLocations(node);
147 var expectedLocation = getExpectedLocation(tokens);
148 if (hasCorrectLocation(tokens, expectedLocation)) {
149 return;
150 }
151
152 var data = {location: MESSAGE_LOCATION[expectedLocation], details: ''};
153 var correctColumn = getCorrectColumn(tokens, expectedLocation);
154
155 if (correctColumn !== null) {
156 var expectedNextLine = tokens.lastProp &&
157 (tokens.lastProp.line === tokens.closing.line);
158 data.details = ' (expected column ' + (correctColumn + 1) +
159 (expectedNextLine ? ' on the next line)' : ')');
160 }
161
162 context.report({
163 node: node,
164 loc: tokens.closing,
165 message: MESSAGE,
166 data: data
167 });
168 }
169 };
170
171 };
172
173 module.exports.schema = [{
174 oneOf: [
175 {
176 enum: ['after-props', 'props-aligned', 'tag-aligned', 'line-aligned']
177 },
178 {
179 type: 'object',
180 properties: {
181 location: {
182 enum: ['after-props', 'props-aligned', 'tag-aligned', 'line-aligned']
183 }
184 },
185 additionalProperties: false
186 }, {
187 type: 'object',
188 properties: {
189 nonEmpty: {
190 enum: ['after-props', 'props-aligned', 'tag-aligned', 'line-aligned', false]
191 },
192 selfClosing: {
193 enum: ['after-props', 'props-aligned', 'tag-aligned', 'line-aligned', false]
194 }
195 },
196 additionalProperties: false
197 }
198 ]
199 }];
200
node_modules/eslint-plugin-react/lib/rules/jsx-curly-spacing.js
File was created 1 /**
2 * @fileoverview Enforce or disallow spaces inside of curly braces in JSX attributes.
3 * @author Jamund Ferguson
4 * @author Brandyn Bennett
5 * @author Michael Ficarra
6 * @author Vignesh Anand
7 * @author Jamund Ferguson
8 * @author Yannick Croissant
9 * @author Erik Wendel
10 */
11 'use strict';
12
13 // ------------------------------------------------------------------------------
14 // Rule Definition
15 // ------------------------------------------------------------------------------
16
17 module.exports = function(context) {
18 var spaced = context.options[0] === 'always';
19 var multiline = context.options[1] ? context.options[1].allowMultiline : true;
20
21 // --------------------------------------------------------------------------
22 // Helpers
23 // --------------------------------------------------------------------------
24
25 /**
26 * Determines whether two adjacent tokens have a newline between them.
27 * @param {Object} left - The left token object.
28 * @param {Object} right - The right token object.
29 * @returns {boolean} Whether or not there is a newline between the tokens.
30 */
31 function isMultiline(left, right) {
32 return left.loc.start.line !== right.loc.start.line;
33 }
34
35 /**
36 * Determines whether two adjacent tokens have whitespace between them.
37 * @param {Object} left - The left token object.
38 * @param {Object} right - The right token object.
39 * @returns {boolean} Whether or not there is space between the tokens.
40 */
41 function isSpaced(left, right) {
42 return left.range[1] < right.range[0];
43 }
44
45 /**
46 * Reports that there shouldn't be a newline after the first token
47 * @param {ASTNode} node - The node to report in the event of an error.
48 * @param {Token} token - The token to use for the report.
49 * @returns {void}
50 */
51 function reportNoBeginningNewline(node, token) {
52 context.report({
53 node: node,
54 loc: token.loc.start,
55 message: 'There should be no newline after \'' + token.value + '\'',
56 fix: function(fixer) {
57 var nextToken = context.getSourceCode().getTokenAfter(token);
58 return fixer.replaceTextRange([token.range[1], nextToken.range[0]], spaced ? ' ' : '');
59 }
60 });
61 }
62
63 /**
64 * Reports that there shouldn't be a newline before the last token
65 * @param {ASTNode} node - The node to report in the event of an error.
66 * @param {Token} token - The token to use for the report.
67 * @returns {void}
68 */
69 function reportNoEndingNewline(node, token) {
70 context.report({
71 node: node,
72 loc: token.loc.start,
73 message: 'There should be no newline before \'' + token.value + '\'',
74 fix: function(fixer) {
75 var previousToken = context.getSourceCode().getTokenBefore(token);
76 return fixer.replaceTextRange([previousToken.range[1], token.range[0]], spaced ? ' ' : '');
77 }
78 });
79 }
80
81 /**
82 * Reports that there shouldn't be a space after the first token
83 * @param {ASTNode} node - The node to report in the event of an error.
84 * @param {Token} token - The token to use for the report.
85 * @returns {void}
86 */
87 function reportNoBeginningSpace(node, token) {
88 context.report({
89 node: node,
90 loc: token.loc.start,
91 message: 'There should be no space after \'' + token.value + '\'',
92 fix: function(fixer) {
93 var nextToken = context.getSourceCode().getTokenAfter(token);
94 return fixer.removeRange([token.range[1], nextToken.range[0]]);
95 }
96 });
97 }
98
99 /**
100 * Reports that there shouldn't be a space before the last token
101 * @param {ASTNode} node - The node to report in the event of an error.
102 * @param {Token} token - The token to use for the report.
103 * @returns {void}
104 */
105 function reportNoEndingSpace(node, token) {
106 context.report({
107 node: node,
108 loc: token.loc.start,
109 message: 'There should be no space before \'' + token.value + '\'',
110 fix: function(fixer) {
111 var previousToken = context.getSourceCode().getTokenBefore(token);
112 return fixer.removeRange([previousToken.range[1], token.range[0]]);
113 }
114 });
115 }
116
117 /**
118 * Reports that there should be a space after the first token
119 * @param {ASTNode} node - The node to report in the event of an error.
120 * @param {Token} token - The token to use for the report.
121 * @returns {void}
122 */
123 function reportRequiredBeginningSpace(node, token) {
124 context.report({
125 node: node,
126 loc: token.loc.start,
127 message: 'A space is required after \'' + token.value + '\'',
128 fix: function(fixer) {
129 return fixer.insertTextAfter(token, ' ');
130 }
131 });
132 }
133
134 /**
135 * Reports that there should be a space before the last token
136 * @param {ASTNode} node - The node to report in the event of an error.
137 * @param {Token} token - The token to use for the report.
138 * @returns {void}
139 */
140 function reportRequiredEndingSpace(node, token) {
141 context.report({
142 node: node,
143 loc: token.loc.start,
144 message: 'A space is required before \'' + token.value + '\'',
145 fix: function(fixer) {
146 return fixer.insertTextBefore(token, ' ');
147 }
148 });
149 }
150
151 /**
152 * Determines if spacing in curly braces is valid.
153 * @param {ASTNode} node The AST node to check.
154 * @param {Token} first The first token to check (should be the opening brace)
155 * @param {Token} second The second token to check (should be first after the opening brace)
156 * @param {Token} penultimate The penultimate token to check (should be last before closing brace)
157 * @param {Token} last The last token to check (should be closing brace)
158 * @returns {void}
159 */
160 function validateBraceSpacing(node, first, second, penultimate, last) {
161 if (spaced) {
162 if (!isSpaced(first, second)) {
163 reportRequiredBeginningSpace(node, first);
164 } else if (!multiline && isMultiline(first, second)) {
165 reportNoBeginningNewline(node, first);
166 }
167
168 if (!isSpaced(penultimate, last)) {
169 reportRequiredEndingSpace(node, last);
170 } else if (!multiline && isMultiline(penultimate, last)) {
171 reportNoEndingNewline(node, last);
172 }
173
174 return;
175 }
176
177 // "never" setting if we get here.
178 if (isSpaced(first, second) && !(multiline && isMultiline(first, second))) {
179 reportNoBeginningSpace(node, first);
180 }
181
182 if (isSpaced(penultimate, last) && !(multiline && isMultiline(penultimate, last))) {
183 reportNoEndingSpace(node, last);
184 }
185 }
186
187 // --------------------------------------------------------------------------
188 // Public
189 // --------------------------------------------------------------------------
190
191 return {
192 JSXExpressionContainer: function(node) {
193 var first = context.getFirstToken(node);
194 var second = context.getFirstToken(node, 1);
195 var penultimate = context.getLastToken(node, 1);
196 var last = context.getLastToken(node);
197
198 if (first === penultimate && second === last) {
199 return;
200 }
201
202 validateBraceSpacing(node, first, second, penultimate, last);
203 }
204 };
205 };
206
207 module.exports.schema = [{
208 enum: ['always', 'never']
209 }, {
210 type: 'object',
211 properties: {
212 allowMultiline: {
213 type: 'boolean'
214 }
215 },
216 additionalProperties: false
217 }];
218
node_modules/eslint-plugin-react/lib/rules/jsx-equals-spacing.js
File was created 1 /**
2 * @fileoverview Disallow or enforce spaces around equal signs in JSX attributes.
3 * @author ryym
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Rule Definition
9 // ------------------------------------------------------------------------------
10
11 module.exports = function(context) {
12 var config = context.options[0];
13 var sourceCode = context.getSourceCode();
14
15 /**
16 * Determines a given attribute node has an equal sign.
17 * @param {ASTNode} attrNode - The attribute node.
18 * @returns {boolean} Whether or not the attriute node has an equal sign.
19 */
20 function hasEqual(attrNode) {
21 return attrNode.type !== 'JSXSpreadAttribute' && attrNode.value !== null;
22 }
23
24 // --------------------------------------------------------------------------
25 // Public
26 // --------------------------------------------------------------------------
27
28 return {
29 JSXOpeningElement: function(node) {
30 node.attributes.forEach(function(attrNode) {
31 if (!hasEqual(attrNode)) {
32 return;
33 }
34
35 var equalToken = sourceCode.getTokenAfter(attrNode.name);
36 var spacedBefore = sourceCode.isSpaceBetweenTokens(attrNode.name, equalToken);
37 var spacedAfter = sourceCode.isSpaceBetweenTokens(equalToken, attrNode.value);
38
39 switch (config) {
40 default:
41 case 'never':
42 if (spacedBefore) {
43 context.report(attrNode, equalToken.loc.start,
44 'There should be no space before \'=\'');
45 }
46 if (spacedAfter) {
47 context.report(attrNode, equalToken.loc.start,
48 'There should be no space after \'=\'');
49 }
50 break;
51 case 'always':
52 if (!spacedBefore) {
53 context.report(attrNode, equalToken.loc.start,
54 'A space is required before \'=\'');
55 }
56 if (!spacedAfter) {
57 context.report(attrNode, equalToken.loc.start,
58 'A space is required after \'=\'');
59 }
60 break;
61 }
62 });
63 }
64 };
65 };
66
67 module.exports.schema = [{
68 enum: ['always', 'never']
69 }];
70
node_modules/eslint-plugin-react/lib/rules/jsx-handler-names.js
File was created 1 /**
2 * @fileoverview Enforce event handler naming conventions in JSX
3 * @author Jake Marsh
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Rule Definition
9 // ------------------------------------------------------------------------------
10
11 module.exports = function(context) {
12
13 var configuration = context.options[0] || {};
14 var eventHandlerPrefix = configuration.eventHandlerPrefix || 'handle';
15 var eventHandlerPropPrefix = configuration.eventHandlerPropPrefix || 'on';
16
17 var EVENT_HANDLER_REGEX = new RegExp('^((props\.' + eventHandlerPropPrefix + ')'
18 + '|((.*\.)?' + eventHandlerPrefix + ')).+$');
19 var PROP_EVENT_HANDLER_REGEX = new RegExp('^(' + eventHandlerPropPrefix + '.+|ref)$');
20
21 return {
22 JSXAttribute: function(node) {
23 if (!node.value || !node.value.expression || !node.value.expression.object) {
24 return;
25 }
26
27 var propKey = typeof node.name === 'object' ? node.name.name : node.name;
28 var propValue = context.getSource(node.value.expression).replace(/^this\./, '');
29
30 if (propKey === 'ref') {
31 return;
32 }
33
34 var propIsEventHandler = PROP_EVENT_HANDLER_REGEX.test(propKey);
35 var propFnIsNamedCorrectly = EVENT_HANDLER_REGEX.test(propValue);
36
37 if (propIsEventHandler && !propFnIsNamedCorrectly) {
38 context.report(
39 node,
40 'Handler function for ' + propKey + ' prop key must begin with \'' + eventHandlerPrefix + '\''
41 );
42 } else if (propFnIsNamedCorrectly && !propIsEventHandler) {
43 context.report(
44 node,
45 'Prop key for ' + propValue + ' must begin with \'' + eventHandlerPropPrefix + '\''
46 );
47 }
48 }
49 };
50
51 };
52
53 module.exports.schema = [{
54 type: 'object',
55 properties: {
56 eventHandlerPrefix: {
57 type: 'string'
58 },
59 eventHandlerPropPrefix: {
60 type: 'string'
61 }
62 },
63 additionalProperties: false
64 }];
65
node_modules/eslint-plugin-react/lib/rules/jsx-indent-props.js
File was created 1 /**
2 * @fileoverview Validate props indentation in JSX
3 * @author Yannick Croissant
4
5 * This rule has been ported and modified from eslint and nodeca.
6 * @author Vitaly Puzrin
7 * @author Gyandeep Singh
8 * @copyright 2015 Vitaly Puzrin. All rights reserved.
9 * @copyright 2015 Gyandeep Singh. All rights reserved.
10 Copyright (C) 2014 by Vitaly Puzrin
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the 'Software'), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in
20 all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 THE SOFTWARE.
29 */
30 'use strict';
31
32 // ------------------------------------------------------------------------------
33 // Rule Definition
34 // ------------------------------------------------------------------------------
35 module.exports = function(context) {
36
37 var MESSAGE = 'Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}.';
38
39 var extraColumnStart = 0;
40 var indentType = 'space';
41 var indentSize = 4;
42
43 if (context.options.length) {
44 if (context.options[0] === 'tab') {
45 indentSize = 1;
46 indentType = 'tab';
47 } else if (typeof context.options[0] === 'number') {
48 indentSize = context.options[0];
49 indentType = 'space';
50 }
51 }
52
53 /**
54 * Reports a given indent violation and properly pluralizes the message
55 * @param {ASTNode} node Node violating the indent rule
56 * @param {Number} needed Expected indentation character count
57 * @param {Number} gotten Indentation character count in the actual node/code
58 * @param {Object=} loc Error line and column location
59 */
60 function report(node, needed, gotten, loc) {
61 var msgContext = {
62 needed: needed,
63 type: indentType,
64 characters: needed === 1 ? 'character' : 'characters',
65 gotten: gotten
66 };
67
68 if (loc) {
69 context.report(node, loc, MESSAGE, msgContext);
70 } else {
71 context.report(node, MESSAGE, msgContext);
72 }
73 }
74
75 /**
76 * Get node indent
77 * @param {ASTNode} node Node to examine
78 * @param {Boolean} byLastLine get indent of node's last line
79 * @param {Boolean} excludeCommas skip comma on start of line
80 * @return {Number} Indent
81 */
82 function getNodeIndent(node, byLastLine, excludeCommas) {
83 byLastLine = byLastLine || false;
84 excludeCommas = excludeCommas || false;
85
86 var src = context.getSource(node, node.loc.start.column + extraColumnStart);
87 var lines = src.split('\n');
88 if (byLastLine) {
89 src = lines[lines.length - 1];
90 } else {
91 src = lines[0];
92 }
93
94 var skip = excludeCommas ? ',' : '';
95
96 var regExp;
97 if (indentType === 'space') {
98 regExp = new RegExp('^[ ' + skip + ']+');
99 } else {
100 regExp = new RegExp('^[\t' + skip + ']+');
101 }
102
103 var indent = regExp.exec(src);
104 return indent ? indent[0].length : 0;
105 }
106
107 /**
108 * Checks node is the first in its own start line. By default it looks by start line.
109 * @param {ASTNode} node The node to check
110 * @param {Boolean} [byEndLocation] Lookup based on start position or end
111 * @return {Boolean} true if its the first in the its start line
112 */
113 function isNodeFirstInLine(node, byEndLocation) {
114 var firstToken = byEndLocation === true ? context.getLastToken(node, 1) : context.getTokenBefore(node);
115 var startLine = byEndLocation === true ? node.loc.end.line : node.loc.start.line;
116 var endLine = firstToken ? firstToken.loc.end.line : -1;
117
118 return startLine !== endLine;
119 }
120
121 /**
122 * Check indent for nodes list
123 * @param {ASTNode[]} nodes list of node objects
124 * @param {Number} indent needed indent
125 * @param {Boolean} excludeCommas skip comma on start of line
126 */
127 function checkNodesIndent(nodes, indent, excludeCommas) {
128 nodes.forEach(function(node) {
129 var nodeIndent = getNodeIndent(node, false, excludeCommas);
130 if (
131 node.type !== 'ArrayExpression' && node.type !== 'ObjectExpression' &&
132 nodeIndent !== indent && isNodeFirstInLine(node)
133 ) {
134 report(node, indent, nodeIndent);
135 }
136 });
137 }
138
139 return {
140 JSXOpeningElement: function(node) {
141 var elementIndent = getNodeIndent(node);
142 checkNodesIndent(node.attributes, elementIndent + indentSize);
143 }
144 };
145
146 };
147
148 module.exports.schema = [{
149 oneOf: [{
150 enum: ['tab']
151 }, {
152 type: 'integer'
153 }]
154 }];
155
node_modules/eslint-plugin-react/lib/rules/jsx-indent.js
File was created 1 /**
2 * @fileoverview Validate props indentation in JSX
3 * @author Yannick Croissant
4
5 * This rule has been ported and modified from eslint and nodeca.
6 * @author Vitaly Puzrin
7 * @author Gyandeep Singh
8 * @copyright 2015 Vitaly Puzrin. All rights reserved.
9 * @copyright 2015 Gyandeep Singh. All rights reserved.
10 Copyright (C) 2014 by Vitaly Puzrin
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the 'Software'), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in
20 all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 THE SOFTWARE.
29 */
30 'use strict';
31
32 // ------------------------------------------------------------------------------
33 // Rule Definition
34 // ------------------------------------------------------------------------------
35 module.exports = function(context) {
36
37 var MESSAGE = 'Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}.';
38
39 var extraColumnStart = 0;
40 var indentType = 'space';
41 var indentSize = 4;
42
43 if (context.options.length) {
44 if (context.options[0] === 'tab') {
45 indentSize = 1;
46 indentType = 'tab';
47 } else if (typeof context.options[0] === 'number') {
48 indentSize = context.options[0];
49 indentType = 'space';
50 }
51 }
52
53 /**
54 * Reports a given indent violation and properly pluralizes the message
55 * @param {ASTNode} node Node violating the indent rule
56 * @param {Number} needed Expected indentation character count
57 * @param {Number} gotten Indentation character count in the actual node/code
58 * @param {Object=} loc Error line and column location
59 */
60 function report(node, needed, gotten, loc) {
61 var msgContext = {
62 needed: needed,
63 type: indentType,
64 characters: needed === 1 ? 'character' : 'characters',
65 gotten: gotten
66 };
67
68 if (loc) {
69 context.report(node, loc, MESSAGE, msgContext);
70 } else {
71 context.report(node, MESSAGE, msgContext);
72 }
73 }
74
75 /**
76 * Get node indent
77 * @param {ASTNode} node Node to examine
78 * @param {Boolean} byLastLine get indent of node's last line
79 * @param {Boolean} excludeCommas skip comma on start of line
80 * @return {Number} Indent
81 */
82 function getNodeIndent(node, byLastLine, excludeCommas) {
83 byLastLine = byLastLine || false;
84 excludeCommas = excludeCommas || false;
85
86 var src = context.getSource(node, node.loc.start.column + extraColumnStart);
87 var lines = src.split('\n');
88 if (byLastLine) {
89 src = lines[lines.length - 1];
90 } else {
91 src = lines[0];
92 }
93
94 var skip = excludeCommas ? ',' : '';
95
96 var regExp;
97 if (indentType === 'space') {
98 regExp = new RegExp('^[ ' + skip + ']+');
99 } else {
100 regExp = new RegExp('^[\t' + skip + ']+');
101 }
102
103 var indent = regExp.exec(src);
104 return indent ? indent[0].length : 0;
105 }
106
107 /**
108 * Checks node is the first in its own start line. By default it looks by start line.
109 * @param {ASTNode} node The node to check
110 * @return {Boolean} true if its the first in the its start line
111 */
112 function isNodeFirstInLine(node) {
113 var token = node;
114 do {
115 token = context.getTokenBefore(token);
116 } while (token.type === 'JSXText');
117 var startLine = node.loc.start.line;
118 var endLine = token ? token.loc.end.line : -1;
119
120 return startLine !== endLine;
121 }
122
123 /**
124 * Check indent for nodes list
125 * @param {ASTNode[]} nodes list of node objects
126 * @param {Number} indent needed indent
127 * @param {Boolean} excludeCommas skip comma on start of line
128 */
129 function checkNodesIndent(node, indent, excludeCommas) {
130 var nodeIndent = getNodeIndent(node, false, excludeCommas);
131 if (nodeIndent !== indent && isNodeFirstInLine(node)) {
132 report(node, indent, nodeIndent);
133 }
134 }
135
136 return {
137 JSXOpeningElement: function(node) {
138 if (!node.parent || !node.parent.parent) {
139 return;
140 }
141 var parentElementIndent = getNodeIndent(node.parent.parent);
142 var indent = node.parent.parent.loc.start.line === node.loc.start.line ? 0 : indentSize;
143 checkNodesIndent(node, parentElementIndent + indent);
144 },
145 JSXClosingElement: function(node) {
146 if (!node.parent) {
147 return;
148 }
149 var peerElementIndent = getNodeIndent(node.parent.openingElement);
150 checkNodesIndent(node, peerElementIndent);
151 }
152 };
153
154 };
155
156 module.exports.schema = [{
157 oneOf: [{
158 enum: ['tab']
159 }, {
160 type: 'integer'
161 }]
162 }];
163
node_modules/eslint-plugin-react/lib/rules/jsx-key.js
File was created 1 /**
2 * @fileoverview Report missing `key` props in iterators/collection literals.
3 * @author Ben Mosher
4 */
5 'use strict';
6
7 // var Components = require('../util/Components');
8
9 // ------------------------------------------------------------------------------
10 // Rule Definition
11 // ------------------------------------------------------------------------------
12
13 module.exports = function(context) {
14
15 function hasKeyProp(node) {
16 return node.openingElement.attributes.some(function(decl) {
17 if (decl.type === 'JSXSpreadAttribute') {
18 return false;
19 }
20 return (decl.name.name === 'key');
21 });
22 }
23
24 function checkIteratorElement(node) {
25 if (node.type === 'JSXElement' && !hasKeyProp(node)) {
26 context.report(node, 'Missing "key" prop for element in iterator');
27 }
28 }
29
30 function getReturnStatement(body) {
31 return body.filter(function(item) {
32 return item.type === 'ReturnStatement';
33 })[0];
34 }
35
36 return {
37 JSXElement: function(node) {
38 if (hasKeyProp(node)) {
39 return;
40 }
41
42 if (node.parent.type === 'ArrayExpression') {
43 context.report(node, 'Missing "key" prop for element in array');
44 }
45 },
46
47 // Array.prototype.map
48 CallExpression: function (node) {
49 if (node.callee && node.callee.property && node.callee.property.name !== 'map') {
50 return;
51 }
52
53 var fn = node.arguments[0];
54 var isFn = fn && fn.type === 'FunctionExpression';
55 var isArrFn = fn && fn.type === 'ArrowFunctionExpression';
56
57 if (isArrFn && fn.body.type === 'JSXElement') {
58 checkIteratorElement(fn.body);
59 }
60
61 if (isFn || isArrFn) {
62 if (fn.body.type === 'BlockStatement') {
63 var returnStatement = getReturnStatement(fn.body.body);
64 if (returnStatement && returnStatement.argument) {
65 checkIteratorElement(returnStatement.argument);
66 }
67 }
68 }
69 }
70 };
71 };
72
73 module.exports.schema = [];
74
node_modules/eslint-plugin-react/lib/rules/jsx-max-props-per-line.js
File was created 1 /**
2 * @fileoverview Limit maximum of props on a single line in JSX
3 * @author Yannick Croissant
4 */
5
6 'use strict';
7
8 // ------------------------------------------------------------------------------
9 // Rule Definition
10 // ------------------------------------------------------------------------------
11
12 module.exports = function (context) {
13
14 var configuration = context.options[0] || {};
15 var maximum = configuration.maximum || 1;
16
17 function getPropName(propNode) {
18 if (propNode.type === 'JSXSpreadAttribute') {
19 return context.getSource(propNode.argument);
20 }
21 return propNode.name.name;
22 }
23
24 return {
25 JSXOpeningElement: function (node) {
26 var props = {};
27
28 node.attributes.forEach(function(decl) {
29 var line = decl.loc.start.line;
30 if (props[line]) {
31 props[line].push(decl);
32 } else {
33 props[line] = [decl];
34 }
35 });
36
37 for (var line in props) {
38 if (!props.hasOwnProperty(line)) {
39 continue;
40 }
41 if (props[line].length > maximum) {
42 var name = getPropName(props[line][maximum]);
43 context.report(props[line][maximum], 'Prop `' + name + '` must be placed on a new line');
44 break;
45 }
46 }
47 }
48 };
49 };
50
51 module.exports.schema = [{
52 type: 'object',
53 properties: {
54 maximum: {
55 type: 'integer',
56 minimum: 1
57 }
58 }
59 }];
60
node_modules/eslint-plugin-react/lib/rules/jsx-no-bind.js
File was created 1 /**
2 * @fileoverview Prevents usage of Function.prototype.bind and arrow functions
3 * in React component definition.
4 * @author Daniel Lo Nigro <dan.cx>
5 */
6 'use strict';
7
8 // -----------------------------------------------------------------------------
9 // Rule Definition
10 // -----------------------------------------------------------------------------
11
12 module.exports = function(context) {
13 var configuration = context.options[0] || {};
14
15 return {
16 JSXAttribute: function(node) {
17 var isRef = configuration.ignoreRefs && node.name.name === 'ref';
18 if (isRef || !node.value || !node.value.expression) {
19 return;
20 }
21 var valueNode = node.value.expression;
22 if (
23 !configuration.allowBind &&
24 valueNode.type === 'CallExpression' &&
25 valueNode.callee.type === 'MemberExpression' &&
26 valueNode.callee.property.name === 'bind'
27 ) {
28 context.report(node, 'JSX props should not use .bind()');
29 } else if (
30 !configuration.allowArrowFunctions &&
31 valueNode.type === 'ArrowFunctionExpression'
32 ) {
33 context.report(node, 'JSX props should not use arrow functions');
34 }
35 }
36 };
37 };
38
39 module.exports.schema = [{
40 type: 'object',
41 properties: {
42 allowArrowFunctions: {
43 default: false,
44 type: 'boolean'
45 },
46 allowBind: {
47 default: false,
48 type: 'boolean'
49 },
50 ignoreRefs: {
51 default: false,
52 type: 'boolean'
53 }
54 },
55 additionalProperties: false
56 }];
57
node_modules/eslint-plugin-react/lib/rules/jsx-no-duplicate-props.js
File was created 1 /**
2 * @fileoverview Enforce no duplicate props
3 * @author Markus ร…nรถstam
4 */
5
6 'use strict';
7
8 // ------------------------------------------------------------------------------
9 // Rule Definition
10 // ------------------------------------------------------------------------------
11
12 module.exports = function (context) {
13
14 var configuration = context.options[0] || {};
15 var ignoreCase = configuration.ignoreCase || false;
16
17 return {
18 JSXOpeningElement: function (node) {
19 var props = {};
20
21 node.attributes.forEach(function(decl) {
22 if (decl.type === 'JSXSpreadAttribute') {
23 return;
24 }
25
26 var name = decl.name.name;
27
28 if (ignoreCase) {
29 name = name.toLowerCase();
30 }
31
32 if (props.hasOwnProperty(name)) {
33 context.report(decl, 'No duplicate props allowed');
34 } else {
35 props[name] = 1;
36 }
37 });
38 }
39 };
40 };
41
42 module.exports.schema = [{
43 type: 'object',
44 properties: {
45 ignoreCase: {
46 type: 'boolean'
47 }
48 },
49 additionalProperties: false
50 }];
51
node_modules/eslint-plugin-react/lib/rules/jsx-no-literals.js
File was created 1 /*
2 * @fileoverview Prevent using string literals in React component definition
3 * @author Caleb Morris
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Rule Definition
9 // ------------------------------------------------------------------------------
10
11 module.exports = function(context) {
12
13 function reportLiteralNode(node) {
14 context.report(node, 'Missing JSX expression container around literal string');
15 }
16
17 // --------------------------------------------------------------------------
18 // Public
19 // --------------------------------------------------------------------------
20
21 return {
22
23 Literal: function(node) {
24 if (
25 !/^[\s]+$/.test(node.value) &&
26 node.parent &&
27 node.parent.type !== 'JSXExpressionContainer' &&
28 node.parent.type !== 'JSXAttribute' &&
29 node.parent.type.indexOf('JSX') !== -1
30 ) {
31 reportLiteralNode(node);
32 }
33 }
34
35 };
36
37 };
38
39 module.exports.schema = [{
40 type: 'object',
41 properties: {},
42 additionalProperties: false
43 }];
44
node_modules/eslint-plugin-react/lib/rules/jsx-no-undef.js
File was created 1 /**
2 * @fileoverview Disallow undeclared variables in JSX
3 * @author Yannick Croissant
4 */
5
6 'use strict';
7
8 /**
9 * Checks if a node name match the JSX tag convention.
10 * @param {String} name - Name of the node to check.
11 * @returns {boolean} Whether or not the node name match the JSX tag convention.
12 */
13 var tagConvention = /^[a-z]|\-/;
14 function isTagName(name) {
15 return tagConvention.test(name);
16 }
17
18 // ------------------------------------------------------------------------------
19 // Rule Definition
20 // ------------------------------------------------------------------------------
21
22 module.exports = function(context) {
23
24 /**
25 * Compare an identifier with the variables declared in the scope
26 * @param {ASTNode} node - Identifier or JSXIdentifier node
27 * @returns {void}
28 */
29 function checkIdentifierInJSX(node) {
30 var scope = context.getScope();
31 var variables = scope.variables;
32 var i;
33 var len;
34
35 while (scope.type !== 'global') {
36 scope = scope.upper;
37 variables = scope.variables.concat(variables);
38 }
39 if (scope.childScopes.length) {
40 variables = scope.childScopes[0].variables.concat(variables);
41 // Temporary fix for babel-eslint
42 if (scope.childScopes[0].childScopes.length) {
43 variables = scope.childScopes[0].childScopes[0].variables.concat(variables);
44 }
45 }
46
47 for (i = 0, len = variables.length; i < len; i++) {
48 if (variables[i].name === node.name) {
49 return;
50 }
51 }
52
53 context.report(node, '\'' + node.name + '\' is not defined.');
54 }
55
56 return {
57 JSXOpeningElement: function(node) {
58 switch (node.name.type) {
59 case 'JSXIdentifier':
60 node = node.name;
61 break;
62 case 'JSXMemberExpression':
63 node = node.name.object;
64 break;
65 case 'JSXNamespacedName':
66 node = node.name.namespace;
67 break;
68 default:
69 break;
70 }
71 if (isTagName(node.name)) {
72 return;
73 }
74 checkIdentifierInJSX(node);
75 }
76 };
77
78 };
79
80 module.exports.schema = [];
81
node_modules/eslint-plugin-react/lib/rules/jsx-pascal-case.js
File was created 1 /**
2 * @fileoverview Enforce PasalCase for user-defined JSX components
3 * @author Jake Marsh
4 */
5
6 'use strict';
7
8 // ------------------------------------------------------------------------------
9 // Constants
10 // ------------------------------------------------------------------------------
11
12 var PASCAL_CASE_REGEX = /^[A-Z0-9]+[a-z0-9]+(?:[A-Z0-9]+[a-z0-9]*)*$/;
13 var COMPAT_TAG_REGEX = /^[a-z]|\-/;
14
15 // ------------------------------------------------------------------------------
16 // Rule Definition
17 // ------------------------------------------------------------------------------
18
19 module.exports = function(context) {
20
21 return {
22 JSXOpeningElement: function(node) {
23 switch (node.name.type) {
24 case 'JSXIdentifier':
25 node = node.name;
26 break;
27 case 'JSXMemberExpression':
28 node = node.name.object;
29 break;
30 case 'JSXNamespacedName':
31 node = node.name.namespace;
32 break;
33 default:
34 break;
35 }
36
37 var isPascalCase = PASCAL_CASE_REGEX.test(node.name);
38 var isCompatTag = COMPAT_TAG_REGEX.test(node.name);
39
40 if (!isPascalCase && !isCompatTag) {
41 context.report(node, 'Imported JSX component ' + node.name + ' must be in PascalCase');
42 }
43 }
44 };
45
46 };
47
node_modules/eslint-plugin-react/lib/rules/jsx-quotes.js
File was created 1 /**
2 * @fileoverview Enforce props quotes style
3 * @author Matt DuVall <http://www.mattduvall.com/>, Brandon Payton, Yannick Croissant
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Constants
9 // ------------------------------------------------------------------------------
10
11 var QUOTE_SETTINGS = {
12 double: {
13 quote: '"',
14 alternateQuote: '\'',
15 description: 'doublequote'
16 },
17 single: {
18 quote: '\'',
19 alternateQuote: '"',
20 description: 'singlequote'
21 }
22 };
23
24 var AVOID_ESCAPE = 'avoid-escape';
25
26 var isWarnedForDeprecation = false;
27
28 // ------------------------------------------------------------------------------
29 // Rule Definition
30 // ------------------------------------------------------------------------------
31
32 module.exports = function(context) {
33
34 /**
35 * Validate that a string passed in is surrounded by the specified character
36 * @param {string} val The text to check.
37 * @param {string} character The character to see if it's surrounded by.
38 * @returns {boolean} True if the text is surrounded by the character, false if not.
39 * @private
40 */
41 function isSurroundedBy(val, character) {
42 return val[0] === character && val[val.length - 1] === character;
43 }
44
45 return {
46
47 Program: function() {
48 if (isWarnedForDeprecation || /\=-(f|-format)=/.test(process.argv.join('='))) {
49 return;
50 }
51 /* eslint-disable no-console */
52 console.log('The react/jsx-quotes rule is deprecated. Please use the jsx-quotes rule instead.');
53 /* eslint-enable no-console */
54 isWarnedForDeprecation = true;
55 },
56
57 Literal: function(node) {
58
59 if (node.parent.type !== 'JSXAttribute') {
60 return;
61 }
62 var val = node.value;
63 var rawVal = node.raw;
64 var quoteOption = context.options[0];
65 var settings = QUOTE_SETTINGS[quoteOption];
66 var avoidEscape = context.options[1] === AVOID_ESCAPE;
67 var isValid;
68
69 if (settings && typeof val === 'string') {
70 isValid = isSurroundedBy(rawVal, settings.quote);
71
72 if (!isValid && avoidEscape) {
73 isValid = isSurroundedBy(rawVal, settings.alternateQuote) && rawVal.indexOf(settings.quote) >= 0;
74 }
75
76 if (!isValid) {
77 context.report(node, 'JSX attributes must use ' + settings.description + '.');
78 }
79 }
80 }
81 };
82
83 };
84
85 module.exports.schema = [{
86 enum: ['single', 'double']
87 }, {
88 enum: ['avoid-escape']
89 }];
90
node_modules/eslint-plugin-react/lib/rules/jsx-sort-prop-types.js
File was created 1 /**
2 * @fileoverview Enforce propTypes declarations alphabetical sorting
3 */
4 'use strict';
5
6 // ------------------------------------------------------------------------------
7 // Rule Definition
8 // ------------------------------------------------------------------------------
9
10 module.exports = function(context) {
11
12 var configuration = context.options[0] || {};
13 var requiredFirst = configuration.requiredFirst || false;
14 var callbacksLast = configuration.callbacksLast || false;
15 var ignoreCase = configuration.ignoreCase || false;
16
17 /**
18 * Checks if node is `propTypes` declaration
19 * @param {ASTNode} node The AST node being checked.
20 * @returns {Boolean} True if node is `propTypes` declaration, false if not.
21 */
22 function isPropTypesDeclaration(node) {
23
24 // Special case for class properties
25 // (babel-eslint does not expose property name so we have to rely on tokens)
26 if (node.type === 'ClassProperty') {
27 var tokens = context.getFirstTokens(node, 2);
28 return (tokens[0] && tokens[0].value === 'propTypes') ||
29 (tokens[1] && tokens[1].value === 'propTypes');
30 }
31
32 return Boolean(
33 node &&
34 node.name === 'propTypes'
35 );
36 }
37
38 function getKey(node) {
39 return node.key.type === 'Identifier' ? node.key.name : node.key.value;
40 }
41
42 function getValueName(node) {
43 return node.value.property && node.value.property.name;
44 }
45
46 function isCallbackPropName(propName) {
47 return /^on[A-Z]/.test(propName);
48 }
49
50 function isRequiredProp(node) {
51 return getValueName(node) === 'isRequired';
52 }
53
54 /**
55 * Checks if propTypes declarations are sorted
56 * @param {Array} declarations The array of AST nodes being checked.
57 * @returns {void}
58 */
59 function checkSorted(declarations) {
60 declarations.reduce(function(prev, curr) {
61 var prevPropName = getKey(prev);
62 var currentPropName = getKey(curr);
63 var previousIsRequired = isRequiredProp(prev);
64 var currentIsRequired = isRequiredProp(curr);
65 var previousIsCallback = isCallbackPropName(prevPropName);
66 var currentIsCallback = isCallbackPropName(currentPropName);
67
68 if (ignoreCase) {
69 prevPropName = prevPropName.toLowerCase();
70 currentPropName = currentPropName.toLowerCase();
71 }
72
73 if (requiredFirst) {
74 if (previousIsRequired && !currentIsRequired) {
75 // Transition between required and non-required. Don't compare for alphabetical.
76 return curr;
77 }
78 if (!previousIsRequired && currentIsRequired) {
79 // Encountered a non-required prop after a required prop
80 context.report(curr, 'Required prop types must be listed before all other prop types');
81 return curr;
82 }
83 }
84
85 if (callbacksLast) {
86 if (!previousIsCallback && currentIsCallback) {
87 // Entering the callback prop section
88 return curr;
89 }
90 if (previousIsCallback && !currentIsCallback) {
91 // Encountered a non-callback prop after a callback prop
92 context.report(prev, 'Callback prop types must be listed after all other prop types');
93 return prev;
94 }
95 }
96
97 if (currentPropName < prevPropName) {
98 context.report(curr, 'Prop types declarations should be sorted alphabetically');
99 return prev;
100 }
101
102 return curr;
103 }, declarations[0]);
104 }
105
106 return {
107 ClassProperty: function(node) {
108 if (isPropTypesDeclaration(node) && node.value && node.value.type === 'ObjectExpression') {
109 checkSorted(node.value.properties);
110 }
111 },
112
113 MemberExpression: function(node) {
114 if (isPropTypesDeclaration(node.property)) {
115 var right = node.parent.right;
116 if (right && right.type === 'ObjectExpression') {
117 checkSorted(right.properties);
118 }
119 }
120 },
121
122 ObjectExpression: function(node) {
123 node.properties.forEach(function(property) {
124 if (!property.key) {
125 return;
126 }
127
128 if (!isPropTypesDeclaration(property.key)) {
129 return;
130 }
131 if (property.value.type === 'ObjectExpression') {
132 checkSorted(property.value.properties);
133 }
134 });
135 }
136
137 };
138 };
139
140 module.exports.schema = [{
141 type: 'object',
142 properties: {
143 requiredFirst: {
144 type: 'boolean'
145 },
146 callbacksLast: {
147 type: 'boolean'
148 },
149 ignoreCase: {
150 type: 'boolean'
151 }
152 },
153 additionalProperties: false
154 }];
155
node_modules/eslint-plugin-react/lib/rules/jsx-sort-props.js
File was created 1 /**
2 * @fileoverview Enforce props alphabetical sorting
3 * @author Ilya Volodin, Yannick Croissant
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Rule Definition
9 // ------------------------------------------------------------------------------
10
11 function isCallbackPropName(propName) {
12 return /^on[A-Z]/.test(propName);
13 }
14
15 module.exports = function(context) {
16
17 var configuration = context.options[0] || {};
18 var ignoreCase = configuration.ignoreCase || false;
19 var callbacksLast = configuration.callbacksLast || false;
20 var shorthandFirst = configuration.shorthandFirst || false;
21
22 return {
23 JSXOpeningElement: function(node) {
24 node.attributes.reduce(function(memo, decl, idx, attrs) {
25 if (decl.type === 'JSXSpreadAttribute') {
26 return attrs[idx + 1];
27 }
28
29 var previousPropName = memo.name.name;
30 var currentPropName = decl.name.name;
31 var previousValue = memo.value;
32 var currentValue = decl.value;
33 var previousIsCallback = isCallbackPropName(previousPropName);
34 var currentIsCallback = isCallbackPropName(currentPropName);
35
36 if (ignoreCase) {
37 previousPropName = previousPropName.toLowerCase();
38 currentPropName = currentPropName.toLowerCase();
39 }
40
41 if (callbacksLast) {
42 if (!previousIsCallback && currentIsCallback) {
43 // Entering the callback prop section
44 return decl;
45 }
46 if (previousIsCallback && !currentIsCallback) {
47 // Encountered a non-callback prop after a callback prop
48 context.report(memo, 'Callbacks must be listed after all other props');
49 return memo;
50 }
51 }
52
53 if (shorthandFirst) {
54 if (currentValue && !previousValue) {
55 return decl;
56 }
57 if (!currentValue && previousValue) {
58 context.report(memo, 'Shorthand props must be listed before all other props');
59 return memo;
60 }
61 }
62
63 if (currentPropName < previousPropName) {
64 context.report(decl, 'Props should be sorted alphabetically');
65 return memo;
66 }
67
68 return decl;
69 }, node.attributes[0]);
70 }
71 };
72 };
73
74 module.exports.schema = [{
75 type: 'object',
76 properties: {
77 // Whether callbacks (prefixed with "on") should be listed at the very end,
78 // after all other props.
79 callbacksLast: {
80 type: 'boolean'
81 },
82 // Whether shorthand properties (without a value) should be listed first
83 shorthandFirst: {
84 type: 'boolean'
85 },
86 ignoreCase: {
87 type: 'boolean'
88 }
89 },
90 additionalProperties: false
91 }];
92
node_modules/eslint-plugin-react/lib/rules/jsx-uses-react.js
File was created 1 /**
2 * @fileoverview Prevent React to be marked as unused
3 * @author Glen Mailer
4 */
5 'use strict';
6
7 var variableUtil = require('../util/variable');
8 var pragmaUtil = require('../util/pragma');
9
10 // ------------------------------------------------------------------------------
11 // Rule Definition
12 // ------------------------------------------------------------------------------
13
14 module.exports = function(context) {
15
16 var pragma = pragmaUtil.getFromContext(context);
17
18 // --------------------------------------------------------------------------
19 // Public
20 // --------------------------------------------------------------------------
21
22 return {
23
24 JSXOpeningElement: function() {
25 variableUtil.markVariableAsUsed(context, pragma);
26 },
27
28 BlockComment: function(node) {
29 pragma = pragmaUtil.getFromNode(node) || pragma;
30 }
31
32 };
33
34 };
35
36 module.exports.schema = [{
37 type: 'object',
38 properties: {
39 pragma: {
40 type: 'string'
41 }
42 },
43 additionalProperties: false
44 }];
45
node_modules/eslint-plugin-react/lib/rules/jsx-uses-vars.js
File was created 1 /**
2 * @fileoverview Prevent variables used in JSX to be marked as unused
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 var variableUtil = require('../util/variable');
8
9 // ------------------------------------------------------------------------------
10 // Rule Definition
11 // ------------------------------------------------------------------------------
12
13 module.exports = function(context) {
14
15 return {
16 JSXExpressionContainer: function(node) {
17 if (node.expression.type !== 'Identifier') {
18 return;
19 }
20 variableUtil.markVariableAsUsed(context, node.expression.name);
21 },
22
23 JSXIdentifier: function(node) {
24 if (node.parent.type === 'JSXAttribute') {
25 return;
26 }
27 variableUtil.markVariableAsUsed(context, node.name);
28 }
29
30 };
31
32 };
33
34 module.exports.schema = [];
35
node_modules/eslint-plugin-react/lib/rules/no-danger.js
File was created 1 /**
2 * @fileoverview Prevent usage of dangerous JSX props
3 * @author Scott Andrews
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Constants
9 // ------------------------------------------------------------------------------
10
11 var DANGEROUS_MESSAGE = 'Dangerous property \'{{name}}\' found';
12
13 var DANGEROUS_PROPERTY_NAMES = [
14 'dangerouslySetInnerHTML'
15 ];
16
17 var DANGEROUS_PROPERTIES = DANGEROUS_PROPERTY_NAMES.reduce(function (props, prop) {
18 props[prop] = prop;
19 return props;
20 }, Object.create(null));
21
22 // ------------------------------------------------------------------------------
23 // Helpers
24 // ------------------------------------------------------------------------------
25
26 /**
27 * Checks if a node name match the JSX tag convention.
28 * @param {String} name - Name of the node to check.
29 * @returns {boolean} Whether or not the node name match the JSX tag convention.
30 */
31 var tagConvention = /^[a-z]|\-/;
32 function isTagName(name) {
33 return tagConvention.test(name);
34 }
35
36 /**
37 * Checks if a JSX attribute is dangerous.
38 * @param {String} name - Name of the attribute to check.
39 * @returns {boolean} Whether or not the attribute is dnagerous.
40 */
41 function isDangerous(name) {
42 return name in DANGEROUS_PROPERTIES;
43 }
44
45 // ------------------------------------------------------------------------------
46 // Rule Definition
47 // ------------------------------------------------------------------------------
48
49 module.exports = function(context) {
50
51 return {
52
53 JSXAttribute: function(node) {
54 if (isTagName(node.parent.name.name) && isDangerous(node.name.name)) {
55 context.report(node, DANGEROUS_MESSAGE, {
56 name: node.name.name
57 });
58 }
59 }
60
61 };
62
63 };
64
65 module.exports.schema = [];
66
node_modules/eslint-plugin-react/lib/rules/no-deprecated.js
File was created 1 /**
2 * @fileoverview Prevent usage of deprecated methods
3 * @author Yannick Croissant
4 * @author Scott Feeney
5 */
6 'use strict';
7
8 var pragmaUtil = require('../util/pragma');
9
10 // ------------------------------------------------------------------------------
11 // Constants
12 // ------------------------------------------------------------------------------
13
14 var DEPRECATED_MESSAGE = '{{oldMethod}} is deprecated since React {{version}}{{newMethod}}';
15
16 // ------------------------------------------------------------------------------
17 // Rule Definition
18 // ------------------------------------------------------------------------------
19
20 module.exports = function(context) {
21
22 // Validate React version passed in options
23 // (append the patch version if missing, allowing shorthands like 0.12 for React 0.12.0)
24 var optVer = context.options[0] ? context.options[0].react : '999.999.999';
25 optVer = /^[0-9]+\.[0-9]+$/.test(optVer) ? optVer + '.0' : optVer;
26 optVer = optVer.split('.').map(function(part) {
27 return Number(part);
28 });
29
30 var pragma = pragmaUtil.getFromContext(context);
31
32 function getDeprecated() {
33 var deprecated = {
34 MemberExpression: {}
35 };
36 // 0.12.0
37 deprecated.MemberExpression[pragma + '.renderComponent'] = ['0.12.0', pragma + '.render'];
38 deprecated.MemberExpression[pragma + '.renderComponentToString'] = ['0.12.0', pragma + '.renderToString'];
39 deprecated.MemberExpression[pragma + '.renderComponentToStaticMarkup'] = [
40 '0.12.0',
41 pragma + '.renderToStaticMarkup'
42 ];
43 deprecated.MemberExpression[pragma + '.isValidComponent'] = ['0.12.0', pragma + '.isValidElement'];
44 deprecated.MemberExpression[pragma + '.PropTypes.component'] = ['0.12.0', pragma + '.PropTypes.element'];
45 deprecated.MemberExpression[pragma + '.PropTypes.renderable'] = ['0.12.0', pragma + '.PropTypes.node'];
46 deprecated.MemberExpression[pragma + '.isValidClass'] = ['0.12.0'];
47 deprecated.MemberExpression['this.transferPropsTo'] = ['0.12.0', 'spread operator ({...})'];
48 // 0.13.0
49 deprecated.MemberExpression[pragma + '.addons.classSet'] = ['0.13.0', 'the npm module classnames'];
50 deprecated.MemberExpression[pragma + '.addons.cloneWithProps'] = ['0.13.0', pragma + '.cloneElement'];
51 // 0.14.0
52 deprecated.MemberExpression[pragma + '.render'] = ['0.14.0', 'ReactDOM.render'];
53 deprecated.MemberExpression[pragma + '.unmountComponentAtNode'] = ['0.14.0', 'ReactDOM.unmountComponentAtNode'];
54 deprecated.MemberExpression[pragma + '.findDOMNode'] = ['0.14.0', 'ReactDOM.findDOMNode'];
55 deprecated.MemberExpression[pragma + '.renderToString'] = ['0.14.0', 'ReactDOMServer.renderToString'];
56 deprecated.MemberExpression[pragma + '.renderToStaticMarkup'] = ['0.14.0', 'ReactDOMServer.renderToStaticMarkup'];
57
58 return deprecated;
59 }
60
61 function checkVersion(methodVer) {
62 methodVer = methodVer.split('.').map(function(part) {
63 return Number(part);
64 });
65 var higherMajor = methodVer[0] < optVer[0];
66 var higherMinor = methodVer[0] === optVer[0] && methodVer[1] < optVer[1];
67 var higherOrEqualPatch = methodVer[0] === optVer[0] && methodVer[1] === optVer[1] && methodVer[2] <= optVer[2];
68
69 return higherMajor || higherMinor || higherOrEqualPatch;
70 }
71
72 function isDeprecated(type, method) {
73 var deprecated = getDeprecated();
74
75 return (
76 deprecated[type] &&
77 deprecated[type][method] &&
78 checkVersion(deprecated[type][method][0])
79 );
80 }
81
82 // --------------------------------------------------------------------------
83 // Public
84 // --------------------------------------------------------------------------
85
86 return {
87
88 MemberExpression: function(node) {
89 var method = context.getSource(node);
90 if (!isDeprecated(node.type, method)) {
91 return;
92 }
93 var deprecated = getDeprecated();
94 context.report(node, DEPRECATED_MESSAGE, {
95 oldMethod: method,
96 version: deprecated[node.type][method][0],
97 newMethod: deprecated[node.type][method][1] ? ', use ' + deprecated[node.type][method][1] + ' instead' : ''
98 });
99 },
100
101 BlockComment: function(node) {
102 pragma = pragmaUtil.getFromNode(node) || pragma;
103 }
104
105 };
106
107 };
108
109 module.exports.schema = [{
110 type: 'object',
111 properties: {
112 react: {
113 type: 'string',
114 pattern: '^[0-9]+\.[0-9]+(\.[0-9]+)?$'
115 }
116 },
117 additionalProperties: false
118 }];
119
node_modules/eslint-plugin-react/lib/rules/no-did-mount-set-state.js
File was created 1 /**
2 * @fileoverview Prevent usage of setState in componentDidMount
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Rule Definition
9 // ------------------------------------------------------------------------------
10
11 module.exports = function(context) {
12
13 var mode = context.options[0] || 'never';
14
15 // --------------------------------------------------------------------------
16 // Public
17 // --------------------------------------------------------------------------
18
19 return {
20
21 CallExpression: function(node) {
22 var callee = node.callee;
23 if (
24 callee.type !== 'MemberExpression' ||
25 callee.object.type !== 'ThisExpression' ||
26 callee.property.name !== 'setState'
27 ) {
28 return;
29 }
30 var ancestors = context.getAncestors(callee).reverse();
31 var depth = 0;
32 for (var i = 0, j = ancestors.length; i < j; i++) {
33 if (/Function(Expression|Declaration)$/.test(ancestors[i].type)) {
34 depth++;
35 }
36 if (
37 (ancestors[i].type !== 'Property' && ancestors[i].type !== 'MethodDefinition') ||
38 ancestors[i].key.name !== 'componentDidMount' ||
39 (mode === 'allow-in-func' && depth > 1)
40 ) {
41 continue;
42 }
43 context.report(callee, 'Do not use setState in componentDidMount');
44 break;
45 }
46 }
47 };
48
49 };
50
51 module.exports.schema = [{
52 enum: ['allow-in-func']
53 }];
54
node_modules/eslint-plugin-react/lib/rules/no-did-update-set-state.js
File was created 1 /**
2 * @fileoverview Prevent usage of setState in componentDidUpdate
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Rule Definition
9 // ------------------------------------------------------------------------------
10
11 module.exports = function(context) {
12
13 var mode = context.options[0] || 'never';
14
15 // --------------------------------------------------------------------------
16 // Public
17 // --------------------------------------------------------------------------
18
19 return {
20
21 CallExpression: function(node) {
22 var callee = node.callee;
23 if (
24 callee.type !== 'MemberExpression' ||
25 callee.object.type !== 'ThisExpression' ||
26 callee.property.name !== 'setState'
27 ) {
28 return;
29 }
30 var ancestors = context.getAncestors(callee).reverse();
31 var depth = 0;
32 for (var i = 0, j = ancestors.length; i < j; i++) {
33 if (/Function(Expression|Declaration)$/.test(ancestors[i].type)) {
34 depth++;
35 }
36 if (
37 (ancestors[i].type !== 'Property' && ancestors[i].type !== 'MethodDefinition') ||
38 ancestors[i].key.name !== 'componentDidUpdate' ||
39 (mode === 'allow-in-func' && depth > 1)
40 ) {
41 continue;
42 }
43 context.report(callee, 'Do not use setState in componentDidUpdate');
44 break;
45 }
46 }
47 };
48
49 };
50
51 module.exports.schema = [{
52 enum: ['allow-in-func']
53 }];
54
node_modules/eslint-plugin-react/lib/rules/no-direct-mutation-state.js
File was created 1 /**
2 * @fileoverview Prevent usage of setState in componentDidMount
3 * @author David Petersen
4 */
5 'use strict';
6
7 var Components = require('../util/Components');
8
9 // ------------------------------------------------------------------------------
10 // Rule Definition
11 // ------------------------------------------------------------------------------
12
13 module.exports = Components.detect(function(context, components, utils) {
14
15 /**
16 * Checks if the component is valid
17 * @param {Object} component The component to process
18 * @returns {Boolean} True if the component is valid, false if not.
19 */
20 function isValid(component) {
21 return Boolean(component && !component.mutateSetState);
22 }
23
24 /**
25 * Reports undeclared proptypes for a given component
26 * @param {Object} component The component to process
27 */
28 function reportMutations(component) {
29 var mutation;
30 for (var i = 0, j = component.mutations.length; i < j; i++) {
31 mutation = component.mutations[i];
32 context.report(mutation, 'Do not mutate state directly. Use setState().');
33 }
34 }
35
36 // --------------------------------------------------------------------------
37 // Public
38 // --------------------------------------------------------------------------
39
40 return {
41 AssignmentExpression: function(node) {
42 var item;
43 if (!node.left || !node.left.object || !node.left.object.object) {
44 return;
45 }
46 item = node.left.object;
47 while (item.object.property) {
48 item = item.object;
49 }
50 if (
51 item.object.type === 'ThisExpression' &&
52 item.property.name === 'state'
53 ) {
54 var component = components.get(utils.getParentComponent());
55 var mutations = component && component.mutations || [];
56 mutations.push(node.left.object);
57 components.set(node, {
58 mutateSetState: true,
59 mutations: mutations
60 });
61 }
62 },
63
64 'Program:exit': function() {
65 var list = components.list();
66 for (var component in list) {
67 if (!list.hasOwnProperty(component) || isValid(list[component])) {
68 continue;
69 }
70 reportMutations(list[component]);
71 }
72 }
73 };
74
75 });
76
node_modules/eslint-plugin-react/lib/rules/no-is-mounted.js
File was created 1 /**
2 * @fileoverview Prevent usage of isMounted
3 * @author Joe Lencioni
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Rule Definition
9 // ------------------------------------------------------------------------------
10
11 module.exports = function(context) {
12
13 // --------------------------------------------------------------------------
14 // Public
15 // --------------------------------------------------------------------------
16
17 return {
18
19 CallExpression: function(node) {
20 var callee = node.callee;
21 if (callee.type !== 'MemberExpression') {
22 return;
23 }
24 if (callee.object.type !== 'ThisExpression' || callee.property.name !== 'isMounted') {
25 return;
26 }
27 var ancestors = context.getAncestors(callee);
28 for (var i = 0, j = ancestors.length; i < j; i++) {
29 if (ancestors[i].type === 'Property' || ancestors[i].type === 'MethodDefinition') {
30 context.report(callee, 'Do not use isMounted');
31 break;
32 }
33 }
34 }
35 };
36
37 };
38
39 module.exports.schema = [];
40
node_modules/eslint-plugin-react/lib/rules/no-multi-comp.js
File was created 1 /**
2 * @fileoverview Prevent multiple component definition per file
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 var Components = require('../util/Components');
8
9 // ------------------------------------------------------------------------------
10 // Rule Definition
11 // ------------------------------------------------------------------------------
12
13 module.exports = Components.detect(function(context, components) {
14
15 var configuration = context.options[0] || {};
16 var ignoreStateless = configuration.ignoreStateless || false;
17
18 var MULTI_COMP_MESSAGE = 'Declare only one React component per file';
19
20 /**
21 * Checks if the component is ignored
22 * @param {Object} component The component being checked.
23 * @returns {Boolean} True if the component is ignored, false if not.
24 */
25 function isIgnored(component) {
26 return ignoreStateless === true && /Function/.test(component.node.type);
27 }
28
29 // --------------------------------------------------------------------------
30 // Public
31 // --------------------------------------------------------------------------
32
33 return {
34 'Program:exit': function() {
35 if (components.length() <= 1) {
36 return;
37 }
38
39 var list = components.list();
40 var i = 0;
41
42 for (var component in list) {
43 if (!list.hasOwnProperty(component) || isIgnored(list[component]) || ++i === 1) {
44 continue;
45 }
46 context.report(list[component].node, MULTI_COMP_MESSAGE);
47 }
48 }
49 };
50 });
51
52 module.exports.schema = [{
53 type: 'object',
54 properties: {
55 ignoreStateless: {
56 default: false,
57 type: 'boolean'
58 }
59 },
60 additionalProperties: false
61 }];
62
node_modules/eslint-plugin-react/lib/rules/no-set-state.js
File was created 1 /**
2 * @fileoverview Prevent usage of setState
3 * @author Mark Dalgleish
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Rule Definition
9 // ------------------------------------------------------------------------------
10
11 module.exports = function(context) {
12
13 // --------------------------------------------------------------------------
14 // Public
15 // --------------------------------------------------------------------------
16
17 return {
18
19 CallExpression: function(node) {
20 var callee = node.callee;
21 if (callee.type !== 'MemberExpression') {
22 return;
23 }
24 if (callee.object.type !== 'ThisExpression' || callee.property.name !== 'setState') {
25 return;
26 }
27 var ancestors = context.getAncestors(callee);
28 for (var i = 0, j = ancestors.length; i < j; i++) {
29 if (ancestors[i].type === 'Property' || ancestors[i].type === 'MethodDefinition') {
30 context.report(callee, 'Do not use setState');
31 break;
32 }
33 }
34 }
35 };
36
37 };
38
39 module.exports.schema = [];
40
node_modules/eslint-plugin-react/lib/rules/no-string-refs.js
File was created 1 /**
2 * @fileoverview Prevent string definitions for references and prevent referencing this.refs
3 * @author Tom Hastjarjanto
4 */
5 'use strict';
6
7 var Components = require('../util/Components');
8
9 // ------------------------------------------------------------------------------
10 // Rule Definition
11 // ------------------------------------------------------------------------------
12
13 module.exports = Components.detect(function(context, components, utils) {
14 /**
15 * Checks if we are using refs
16 * @param {ASTNode} node The AST node being checked.
17 * @returns {Boolean} True if we are using refs, false if not.
18 */
19 function isRefsUsage(node) {
20 return Boolean(
21 (
22 utils.getParentES6Component() ||
23 utils.getParentES5Component()
24 ) &&
25 node.object.type === 'ThisExpression' &&
26 node.property.name === 'refs'
27 );
28 }
29
30 /**
31 * Checks if we are using a ref attribute
32 * @param {ASTNode} node The AST node being checked.
33 * @returns {Boolean} True if we are using a ref attribute, false if not.
34 */
35 function isRefAttribute(node) {
36 return Boolean(
37 node.type === 'JSXAttribute' &&
38 node.name &&
39 node.name.name === 'ref'
40 );
41 }
42
43 /**
44 * Checks if a node contains a string value
45 * @param {ASTNode} node The AST node being checked.
46 * @returns {Boolean} True if the node contains a string value, false if not.
47 */
48 function containsStringLiteral(node) {
49 return Boolean(
50 node.value &&
51 node.value.type === 'Literal' &&
52 typeof node.value.value === 'string'
53 );
54 }
55
56 /**
57 * Checks if a node contains a string value within a jsx expression
58 * @param {ASTNode} node The AST node being checked.
59 * @returns {Boolean} True if the node contains a string value within a jsx expression, false if not.
60 */
61 function containsStringExpressionContainer(node) {
62 return Boolean(
63 node.value &&
64 node.value.type === 'JSXExpressionContainer' &&
65 node.value.expression &&
66 node.value.expression.type === 'Literal' &&
67 typeof node.value.expression.value === 'string'
68 );
69 }
70
71 return {
72 MemberExpression: function(node) {
73 if (isRefsUsage(node)) {
74 context.report(node, 'Using this.refs is deprecated.');
75 }
76 },
77 JSXAttribute: function(node) {
78 if (
79 isRefAttribute(node) &&
80 (containsStringLiteral(node) || containsStringExpressionContainer(node))
81 ) {
82 context.report(node, 'Using string literals in ref attributes is deprecated.');
83 }
84 }
85 };
86 });
87
88 module.exports.schema = [];
89
node_modules/eslint-plugin-react/lib/rules/no-unknown-property.js
File was created 1 /**
2 * @fileoverview Prevent usage of unknown DOM property
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Constants
9 // ------------------------------------------------------------------------------
10
11 var UNKNOWN_MESSAGE = 'Unknown property \'{{name}}\' found, use \'{{standardName}}\' instead';
12
13 var DOM_ATTRIBUTE_NAMES = {
14 // Standard
15 'accept-charset': 'acceptCharset',
16 class: 'className',
17 for: 'htmlFor',
18 'http-equiv': 'httpEquiv',
19 // SVG
20 'clip-path': 'clipPath',
21 'fill-opacity': 'fillOpacity',
22 'font-family': 'fontFamily',
23 'font-size': 'fontSize',
24 'marker-end': 'markerEnd',
25 'marker-mid': 'markerMid',
26 'marker-start': 'markerStart',
27 'stop-color': 'stopColor',
28 'stop-opacity': 'stopOpacity',
29 'stroke-dasharray': 'strokeDasharray',
30 'stroke-linecap': 'strokeLinecap',
31 'stroke-opacity': 'strokeOpacity',
32 'stroke-width': 'strokeWidth',
33 'text-anchor': 'textAnchor',
34 'xlink:actuate': 'xlinkActuate',
35 'xlink:arcrole': 'xlinkArcrole',
36 'xlink:href': 'xlinkHref',
37 'xlink:role': 'xlinkRole',
38 'xlink:show': 'xlinkShow',
39 'xlink:title': 'xlinkTitle',
40 'xlink:type': 'xlinkType',
41 'xml:base': 'xmlBase',
42 'xml:lang': 'xmlLang',
43 'xml:space': 'xmlSpace'
44 };
45
46 var DOM_PROPERTY_NAMES = [
47 // Standard
48 'acceptCharset', 'accessKey', 'allowFullScreen', 'allowTransparency', 'autoComplete', 'autoFocus', 'autoPlay',
49 'cellPadding', 'cellSpacing', 'charSet', 'classID', 'className', 'colSpan', 'contentEditable', 'contextMenu',
50 'crossOrigin', 'dateTime', 'encType', 'formAction', 'formEncType', 'formMethod', 'formNoValidate', 'formTarget',
51 'frameBorder', 'hrefLang', 'htmlFor', 'httpEquiv', 'marginHeight', 'marginWidth', 'maxLength', 'mediaGroup',
52 'noValidate', 'onBlur', 'onChange', 'onClick', 'onContextMenu', 'onCopy', 'onCut', 'onDoubleClick',
53 'onDrag', 'onDragEnd', 'onDragEnter', 'onDragExit', 'onDragLeave', 'onDragOver', 'onDragStart', 'onDrop',
54 'onFocus', 'onInput', 'onKeyDown', 'onKeyPress', 'onKeyUp', 'onMouseDown', 'onMouseEnter', 'onMouseLeave',
55 'onMouseMove', 'onMouseOut', 'onMouseOver', 'onMouseUp', 'onPaste', 'onScroll', 'onSubmit', 'onTouchCancel',
56 'onTouchEnd', 'onTouchMove', 'onTouchStart', 'onWheel',
57 'radioGroup', 'readOnly', 'rowSpan', 'spellCheck', 'srcDoc', 'srcSet', 'tabIndex', 'useMap',
58 // Non standard
59 'autoCapitalize', 'autoCorrect',
60 'autoSave',
61 'itemProp', 'itemScope', 'itemType', 'itemRef', 'itemID'
62 ];
63
64 // ------------------------------------------------------------------------------
65 // Helpers
66 // ------------------------------------------------------------------------------
67
68 /**
69 * Checks if a node matches the JSX tag convention.
70 * @param {Object} node - JSX element being tested.
71 * @returns {boolean} Whether or not the node name match the JSX tag convention.
72 */
73 var tagConvention = /^[a-z][^-]*$/;
74 function isTagName(node) {
75 if (tagConvention.test(node.parent.name.name)) {
76 // http://www.w3.org/TR/custom-elements/#type-extension-semantics
77 return !node.parent.attributes.some(function(attrNode) {
78 return (
79 attrNode.type === 'JSXAttribute' &&
80 attrNode.name.type === 'JSXIdentifier' &&
81 attrNode.name.name === 'is'
82 );
83 });
84 }
85 return false;
86 }
87
88 /**
89 * Get the standard name of the attribute.
90 * @param {String} name - Name of the attribute.
91 * @returns {String} The standard name of the attribute.
92 */
93 function getStandardName(name) {
94 if (DOM_ATTRIBUTE_NAMES[name]) {
95 return DOM_ATTRIBUTE_NAMES[name];
96 }
97 var i;
98 var found = DOM_PROPERTY_NAMES.some(function(element, index) {
99 i = index;
100 return element.toLowerCase() === name;
101 });
102 return found ? DOM_PROPERTY_NAMES[i] : null;
103 }
104
105 // ------------------------------------------------------------------------------
106 // Rule Definition
107 // ------------------------------------------------------------------------------
108
109 module.exports = function(context) {
110
111 return {
112
113 JSXAttribute: function(node) {
114 var name = context.getSource(node.name);
115 var standardName = getStandardName(name);
116 if (!isTagName(node) || !standardName) {
117 return;
118 }
119 context.report({
120 node: node,
121 message: UNKNOWN_MESSAGE,
122 data: {
123 name: name,
124 standardName: standardName
125 },
126 fix: function(fixer) {
127 return fixer.replaceText(node.name, standardName);
128 }
129 });
130 }
131 };
132
133 };
134
135 module.exports.schema = [];
136
node_modules/eslint-plugin-react/lib/rules/prefer-es6-class.js
File was created 1 /**
2 * @fileoverview Enforce ES5 or ES6 class for React Components
3 * @author Dan Hamilton
4 */
5 'use strict';
6
7 var Components = require('../util/Components');
8
9 // ------------------------------------------------------------------------------
10 // Rule Definition
11 // ------------------------------------------------------------------------------
12
13 module.exports = Components.detect(function(context, components, utils) {
14 var configuration = context.options[0] || 'always';
15
16 return {
17 ObjectExpression: function(node) {
18 if (utils.isES5Component(node) && configuration === 'always') {
19 context.report(node, 'Component should use es6 class instead of createClass');
20 }
21 },
22 ClassDeclaration: function(node) {
23 if (utils.isES6Component(node) && configuration === 'never') {
24 context.report(node, 'Component should use createClass instead of es6 class');
25 }
26 }
27 };
28 });
29
30 module.exports.schema = [{
31 enum: ['always', 'never']
32 }];
33
node_modules/eslint-plugin-react/lib/rules/prop-types.js
File was created 1 /**
2 * @fileoverview Prevent missing props validation in a React component definition
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 // As for exceptions for props.children or props.className (and alike) look at
8 // https://github.com/yannickcr/eslint-plugin-react/issues/7
9
10 var Components = require('../util/Components');
11 var variable = require('../util/variable');
12
13 // ------------------------------------------------------------------------------
14 // Rule Definition
15 // ------------------------------------------------------------------------------
16
17 module.exports = Components.detect(function(context, components, utils) {
18
19 var configuration = context.options[0] || {};
20 var ignored = configuration.ignore || [];
21 var customValidators = configuration.customValidators || [];
22 // Used to track the type annotations in scope.
23 // Necessary because babel's scopes do not track type annotations.
24 var stack = null;
25
26 var MISSING_MESSAGE = '\'{{name}}\' is missing in props validation';
27
28 /**
29 * Helper for accessing the current scope in the stack.
30 * @param {string} key The name of the identifier to access. If omitted, returns the full scope.
31 * @param {ASTNode} value If provided sets the new value for the identifier.
32 * @returns {Object|ASTNode} Either the whole scope or the ASTNode associated with the given identifier.
33 */
34 function typeScope(key, value) {
35 if (arguments.length === 0) {
36 return stack[stack.length - 1];
37 } else if (arguments.length === 1) {
38 return stack[stack.length - 1][key];
39 }
40 stack[stack.length - 1][key] = value;
41 return value;
42 }
43
44 /**
45 * Checks if we are using a prop
46 * @param {ASTNode} node The AST node being checked.
47 * @returns {Boolean} True if we are using a prop, false if not.
48 */
49 function isPropTypesUsage(node) {
50 var isClassUsage = (
51 (utils.getParentES6Component() || utils.getParentES5Component()) &&
52 node.object.type === 'ThisExpression' && node.property.name === 'props'
53 );
54 var isStatelessFunctionUsage = node.object.name === 'props';
55 return isClassUsage || isStatelessFunctionUsage;
56 }
57
58 /**
59 * Checks if we are declaring a `props` class property with a flow type annotation.
60 * @param {ASTNode} node The AST node being checked.
61 * @returns {Boolean} True if the node is a type annotated props declaration, false if not.
62 */
63 function isAnnotatedPropsDeclaration(node) {
64 if (node && node.type === 'ClassProperty') {
65 var tokens = context.getFirstTokens(node, 2);
66 if (
67 node.typeAnnotation && (
68 tokens[0].value === 'props' ||
69 (tokens[1] && tokens[1].value === 'props')
70 )
71 ) {
72 return true;
73 }
74 }
75 return false;
76 }
77
78 /**
79 * Checks if we are declaring a prop
80 * @param {ASTNode} node The AST node being checked.
81 * @returns {Boolean} True if we are declaring a prop, false if not.
82 */
83 function isPropTypesDeclaration(node) {
84
85 // Special case for class properties
86 // (babel-eslint does not expose property name so we have to rely on tokens)
87 if (node && node.type === 'ClassProperty') {
88 var tokens = context.getFirstTokens(node, 2);
89 if (
90 tokens[0].value === 'propTypes' ||
91 (tokens[1] && tokens[1].value === 'propTypes')
92 ) {
93 return true;
94 }
95 return false;
96 }
97
98 return Boolean(
99 node &&
100 node.name === 'propTypes'
101 );
102
103 }
104
105 /**
106 * Checks if the prop is ignored
107 * @param {String} name Name of the prop to check.
108 * @returns {Boolean} True if the prop is ignored, false if not.
109 */
110 function isIgnored(name) {
111 return ignored.indexOf(name) !== -1;
112 }
113
114 /**
115 * Checks if prop should be validated by plugin-react-proptypes
116 * @param {String} validator Name of validator to check.
117 * @returns {Boolean} True if validator should be checked by custom validator.
118 */
119 function hasCustomValidator(validator) {
120 return customValidators.indexOf(validator) !== -1;
121 }
122
123 /**
124 * Checks if the component must be validated
125 * @param {Object} component The component to process
126 * @returns {Boolean} True if the component must be validated, false if not.
127 */
128 function mustBeValidated(component) {
129 return Boolean(
130 component &&
131 component.usedPropTypes &&
132 !component.ignorePropsValidation
133 );
134 }
135
136 /**
137 * Internal: Checks if the prop is declared
138 * @param {Object} declaredPropTypes Description of propTypes declared in the current component
139 * @param {String[]} keyList Dot separated name of the prop to check.
140 * @returns {Boolean} True if the prop is declared, false if not.
141 */
142 function _isDeclaredInComponent(declaredPropTypes, keyList) {
143 for (var i = 0, j = keyList.length; i < j; i++) {
144 var key = keyList[i];
145 var propType = (
146 // Check if this key is declared
147 declaredPropTypes[key] ||
148 // If not, check if this type accepts any key
149 declaredPropTypes.__ANY_KEY__
150 );
151
152 if (!propType) {
153 // If it's a computed property, we can't make any further analysis, but is valid
154 return key === '__COMPUTED_PROP__';
155 }
156 if (propType === true) {
157 return true;
158 }
159 // Consider every children as declared
160 if (propType.children === true) {
161 return true;
162 }
163 if (propType.acceptedProperties) {
164 return key in propType.acceptedProperties;
165 }
166 if (propType.type === 'union') {
167 // If we fall in this case, we know there is at least one complex type in the union
168 if (i + 1 >= j) {
169 // this is the last key, accept everything
170 return true;
171 }
172 // non trivial, check all of them
173 var unionTypes = propType.children;
174 var unionPropType = {};
175 for (var k = 0, z = unionTypes.length; k < z; k++) {
176 unionPropType[key] = unionTypes[k];
177 var isValid = _isDeclaredInComponent(
178 unionPropType,
179 keyList.slice(i)
180 );
181 if (isValid) {
182 return true;
183 }
184 }
185
186 // every possible union were invalid
187 return false;
188 }
189 declaredPropTypes = propType.children;
190 }
191 return true;
192 }
193
194 /**
195 * Checks if the prop is declared
196 * @param {ASTNode} node The AST node being checked.
197 * @param {String[]} names List of names of the prop to check.
198 * @returns {Boolean} True if the prop is declared, false if not.
199 */
200 function isDeclaredInComponent(node, names) {
201 while (node) {
202 var component = components.get(node);
203 var isDeclared =
204 component && component.confidence === 2 &&
205 _isDeclaredInComponent(component.declaredPropTypes || {}, names)
206 ;
207 if (isDeclared) {
208 return true;
209 }
210 node = node.parent;
211 }
212 return false;
213 }
214
215 /**
216 * Checks if the prop has spread operator.
217 * @param {ASTNode} node The AST node being marked.
218 * @returns {Boolean} True if the prop has spread operator, false if not.
219 */
220 function hasSpreadOperator(node) {
221 var tokens = context.getTokens(node);
222 return tokens.length && tokens[0].value === '...';
223 }
224
225 /**
226 * Retrieve the name of a key node
227 * @param {ASTNode} node The AST node with the key.
228 * @return {string} the name of the key
229 */
230 function getKeyValue(node) {
231 if (node.type === 'ObjectTypeProperty') {
232 var tokens = context.getFirstTokens(node, 1);
233 return tokens[0].value;
234 }
235 var key = node.key || node.argument;
236 return key.type === 'Identifier' ? key.name : key.value;
237 }
238
239 /**
240 * Iterates through a properties node, like a customized forEach.
241 * @param {Object[]} properties Array of properties to iterate.
242 * @param {Function} fn Function to call on each property, receives property key
243 and property value. (key, value) => void
244 */
245 function iterateProperties(properties, fn) {
246 if (properties.length && typeof fn === 'function') {
247 for (var i = 0, j = properties.length; i < j; i++) {
248 var node = properties[i];
249 var key = getKeyValue(node);
250
251 var value = node.value;
252 fn(key, value);
253 }
254 }
255 }
256
257 /**
258 * Creates the representation of the React propTypes for the component.
259 * The representation is used to verify nested used properties.
260 * @param {ASTNode} value Node of the React.PropTypes for the desired property
261 * @return {Object|Boolean} The representation of the declaration, true means
262 * the property is declared without the need for further analysis.
263 */
264 function buildReactDeclarationTypes(value) {
265 if (
266 value &&
267 value.callee &&
268 value.callee.object &&
269 hasCustomValidator(value.callee.object.name)
270 ) {
271 return true;
272 }
273
274 if (
275 value &&
276 value.type === 'MemberExpression' &&
277 value.property &&
278 value.property.name &&
279 value.property.name === 'isRequired'
280 ) {
281 value = value.object;
282 }
283
284 // Verify React.PropTypes that are functions
285 if (
286 value &&
287 value.type === 'CallExpression' &&
288 value.callee &&
289 value.callee.property &&
290 value.callee.property.name &&
291 value.arguments &&
292 value.arguments.length > 0
293 ) {
294 var callName = value.callee.property.name;
295 var argument = value.arguments[0];
296 switch (callName) {
297 case 'shape':
298 if (argument.type !== 'ObjectExpression') {
299 // Invalid proptype or cannot analyse statically
300 return true;
301 }
302 var shapeTypeDefinition = {
303 type: 'shape',
304 children: {}
305 };
306 iterateProperties(argument.properties, function(childKey, childValue) {
307 shapeTypeDefinition.children[childKey] = buildReactDeclarationTypes(childValue);
308 });
309 return shapeTypeDefinition;
310 case 'arrayOf':
311 case 'objectOf':
312 return {
313 type: 'object',
314 children: {
315 __ANY_KEY__: buildReactDeclarationTypes(argument)
316 }
317 };
318 case 'oneOfType':
319 if (
320 !argument.elements ||
321 !argument.elements.length
322 ) {
323 // Invalid proptype or cannot analyse statically
324 return true;
325 }
326 var unionTypeDefinition = {
327 type: 'union',
328 children: []
329 };
330 for (var i = 0, j = argument.elements.length; i < j; i++) {
331 var type = buildReactDeclarationTypes(argument.elements[i]);
332 // keep only complex type
333 if (type !== true) {
334 if (type.children === true) {
335 // every child is accepted for one type, abort type analysis
336 unionTypeDefinition.children = true;
337 return unionTypeDefinition;
338 }
339 }
340
341 unionTypeDefinition.children.push(type);
342 }
343 if (unionTypeDefinition.length === 0) {
344 // no complex type found, simply accept everything
345 return true;
346 }
347 return unionTypeDefinition;
348 case 'instanceOf':
349 return {
350 type: 'instance',
351 // Accept all children because we can't know what type they are
352 children: true
353 };
354 case 'oneOf':
355 default:
356 return true;
357 }
358 }
359 // Unknown property or accepts everything (any, object, ...)
360 return true;
361 }
362
363 /**
364 * Creates the representation of the React props type annotation for the component.
365 * The representation is used to verify nested used properties.
366 * @param {ASTNode} annotation Type annotation for the props class property.
367 * @return {Object|Boolean} The representation of the declaration, true means
368 * the property is declared without the need for further analysis.
369 */
370 function buildTypeAnnotationDeclarationTypes(annotation) {
371 switch (annotation.type) {
372 case 'GenericTypeAnnotation':
373 if (typeScope(annotation.id.name)) {
374 return buildTypeAnnotationDeclarationTypes(typeScope(annotation.id.name));
375 }
376 return true;
377 case 'ObjectTypeAnnotation':
378 var shapeTypeDefinition = {
379 type: 'shape',
380 children: {}
381 };
382 iterateProperties(annotation.properties, function(childKey, childValue) {
383 shapeTypeDefinition.children[childKey] = buildTypeAnnotationDeclarationTypes(childValue);
384 });
385 return shapeTypeDefinition;
386 case 'UnionTypeAnnotation':
387 var unionTypeDefinition = {
388 type: 'union',
389 children: []
390 };
391 for (var i = 0, j = annotation.types.length; i < j; i++) {
392 var type = buildTypeAnnotationDeclarationTypes(annotation.types[i]);
393 // keep only complex type
394 if (type !== true) {
395 if (type.children === true) {
396 // every child is accepted for one type, abort type analysis
397 unionTypeDefinition.children = true;
398 return unionTypeDefinition;
399 }
400 }
401
402 unionTypeDefinition.children.push(type);
403 }
404 if (unionTypeDefinition.children.length === 0) {
405 // no complex type found, simply accept everything
406 return true;
407 }
408 return unionTypeDefinition;
409 case 'ArrayTypeAnnotation':
410 return {
411 type: 'object',
412 children: {
413 __ANY_KEY__: buildTypeAnnotationDeclarationTypes(annotation.elementType)
414 }
415 };
416 default:
417 // Unknown or accepts everything.
418 return true;
419 }
420 }
421
422 /**
423 * Check if we are in a class constructor
424 * @return {boolean} true if we are in a class constructor, false if not
425 */
426 function inConstructor() {
427 var scope = context.getScope();
428 while (scope) {
429 if (scope.block && scope.block.parent && scope.block.parent.kind === 'constructor') {
430 return true;
431 }
432 scope = scope.upper;
433 }
434 return false;
435 }
436
437 /**
438 * Retrieve the name of a property node
439 * @param {ASTNode} node The AST node with the property.
440 * @return {string} the name of the property or undefined if not found
441 */
442 function getPropertyName(node) {
443 var isDirectProp = /^props(\.|\[)/.test(context.getSource(node));
444 var isInClassComponent = utils.getParentES6Component() || utils.getParentES5Component();
445 var isNotInConstructor = !inConstructor(node);
446 if (isDirectProp && isInClassComponent && isNotInConstructor) {
447 return void 0;
448 }
449 if (!isDirectProp) {
450 node = node.parent;
451 }
452 var property = node.property;
453 if (property) {
454 switch (property.type) {
455 case 'Identifier':
456 if (node.computed) {
457 return '__COMPUTED_PROP__';
458 }
459 return property.name;
460 case 'MemberExpression':
461 return void 0;
462 case 'Literal':
463 // Accept computed properties that are literal strings
464 if (typeof property.value === 'string') {
465 return property.value;
466 }
467 // falls through
468 default:
469 if (node.computed) {
470 return '__COMPUTED_PROP__';
471 }
472 break;
473 }
474 }
475 return void 0;
476 }
477
478 /**
479 * Mark a prop type as used
480 * @param {ASTNode} node The AST node being marked.
481 */
482 function markPropTypesAsUsed(node, parentNames) {
483 parentNames = parentNames || [];
484 var type;
485 var name;
486 var allNames;
487 var properties;
488 switch (node.type) {
489 case 'MemberExpression':
490 name = getPropertyName(node);
491 if (name) {
492 allNames = parentNames.concat(name);
493 if (node.parent.type === 'MemberExpression') {
494 markPropTypesAsUsed(node.parent, allNames);
495 }
496 // Do not mark computed props as used.
497 type = name !== '__COMPUTED_PROP__' ? 'direct' : null;
498 } else if (
499 node.parent.id &&
500 node.parent.id.properties &&
501 node.parent.id.properties.length &&
502 getKeyValue(node.parent.id.properties[0])
503 ) {
504 type = 'destructuring';
505 properties = node.parent.id.properties;
506 }
507 break;
508 case 'VariableDeclarator':
509 for (var i = 0, j = node.id.properties.length; i < j; i++) {
510 // let {props: {firstname}} = this
511 var thisDestructuring = (
512 (node.id.properties[i].key.name === 'props' || node.id.properties[i].key.value === 'props') &&
513 node.id.properties[i].value.type === 'ObjectPattern'
514 );
515 // let {firstname} = props
516 var statelessDestructuring = node.init.name === 'props' && utils.getParentStatelessComponent();
517
518 if (thisDestructuring) {
519 properties = node.id.properties[i].value.properties;
520 } else if (statelessDestructuring) {
521 properties = node.id.properties;
522 } else {
523 continue;
524 }
525 type = 'destructuring';
526 break;
527 }
528 break;
529 default:
530 throw new Error(node.type + ' ASTNodes are not handled by markPropTypesAsUsed');
531 }
532
533 var component = components.get(utils.getParentComponent());
534 var usedPropTypes = component && component.usedPropTypes || [];
535
536 switch (type) {
537 case 'direct':
538 // Ignore Object methods
539 if (Object.prototype[name]) {
540 break;
541 }
542
543 var isDirectProp = /^props(\.|\[)/.test(context.getSource(node));
544
545 usedPropTypes.push({
546 name: name,
547 allNames: allNames,
548 node: !isDirectProp && !inConstructor(node) ? node.parent.property : node.property
549 });
550 break;
551 case 'destructuring':
552 for (var k = 0, l = properties.length; k < l; k++) {
553 if (hasSpreadOperator(properties[k]) || properties[k].computed) {
554 continue;
555 }
556 var propName = getKeyValue(properties[k]);
557
558 var currentNode = node;
559 allNames = [];
560 while (currentNode.property && currentNode.property.name !== 'props') {
561 allNames.unshift(currentNode.property.name);
562 currentNode = currentNode.object;
563 }
564 allNames.push(propName);
565
566 if (propName) {
567 usedPropTypes.push({
568 name: propName,
569 allNames: allNames,
570 node: properties[k]
571 });
572 }
573 }
574 break;
575 default:
576 break;
577 }
578
579 components.set(node, {
580 usedPropTypes: usedPropTypes
581 });
582 }
583
584 /**
585 * Mark a prop type as declared
586 * @param {ASTNode} node The AST node being checked.
587 * @param {propTypes} node The AST node containing the proptypes
588 */
589 function markPropTypesAsDeclared(node, propTypes) {
590 var component = components.get(node);
591 var declaredPropTypes = component && component.declaredPropTypes || {};
592 var ignorePropsValidation = false;
593
594 switch (propTypes && propTypes.type) {
595 case 'ObjectTypeAnnotation':
596 iterateProperties(propTypes.properties, function(key, value) {
597 declaredPropTypes[key] = buildTypeAnnotationDeclarationTypes(value);
598 });
599 break;
600 case 'ObjectExpression':
601 iterateProperties(propTypes.properties, function(key, value) {
602 if (!value) {
603 ignorePropsValidation = true;
604 return;
605 }
606 declaredPropTypes[key] = buildReactDeclarationTypes(value);
607 });
608 break;
609 case 'MemberExpression':
610 var curDeclaredPropTypes = declaredPropTypes;
611 // Walk the list of properties, until we reach the assignment
612 // ie: ClassX.propTypes.a.b.c = ...
613 while (
614 propTypes &&
615 propTypes.parent &&
616 propTypes.parent.type !== 'AssignmentExpression' &&
617 propTypes.property &&
618 curDeclaredPropTypes
619 ) {
620 var propName = propTypes.property.name;
621 if (propName in curDeclaredPropTypes) {
622 curDeclaredPropTypes = curDeclaredPropTypes[propName].children;
623 propTypes = propTypes.parent;
624 } else {
625 // This will crash at runtime because we haven't seen this key before
626 // stop this and do not declare it
627 propTypes = null;
628 }
629 }
630 if (propTypes && propTypes.parent && propTypes.property) {
631 curDeclaredPropTypes[propTypes.property.name] =
632 buildReactDeclarationTypes(propTypes.parent.right);
633 }
634 break;
635 case 'Identifier':
636 var variablesInScope = variable.variablesInScope(context);
637 for (var i = 0, j = variablesInScope.length; i < j; i++) {
638 if (variablesInScope[i].name !== propTypes.name) {
639 continue;
640 }
641 var defInScope = variablesInScope[i].defs[variablesInScope[i].defs.length - 1];
642 markPropTypesAsDeclared(node, defInScope.node && defInScope.node.init);
643 return;
644 }
645 ignorePropsValidation = true;
646 break;
647 case null:
648 break;
649 default:
650 ignorePropsValidation = true;
651 break;
652 }
653
654 components.set(node, {
655 declaredPropTypes: declaredPropTypes,
656 ignorePropsValidation: ignorePropsValidation
657 });
658 }
659
660 /**
661 * Reports undeclared proptypes for a given component
662 * @param {Object} component The component to process
663 */
664 function reportUndeclaredPropTypes(component) {
665 var allNames;
666 for (var i = 0, j = component.usedPropTypes.length; i < j; i++) {
667 allNames = component.usedPropTypes[i].allNames;
668 if (
669 isIgnored(allNames[0]) ||
670 isDeclaredInComponent(component.node, allNames)
671 ) {
672 continue;
673 }
674 context.report(
675 component.usedPropTypes[i].node,
676 MISSING_MESSAGE, {
677 name: allNames.join('.').replace(/\.__COMPUTED_PROP__/g, '[]')
678 }
679 );
680 }
681 }
682
683 /**
684 * Resolve the type annotation for a given node.
685 * Flow annotations are sometimes wrapped in outer `TypeAnnotation`
686 * and `NullableTypeAnnotation` nodes which obscure the annotation we're
687 * interested in.
688 * This method also resolves type aliases where possible.
689 *
690 * @param {ASTNode} node The annotation or a node containing the type annotation.
691 * @returns {ASTNode} The resolved type annotation for the node.
692 */
693 function resolveTypeAnnotation(node) {
694 var annotation = node.typeAnnotation || node;
695 while (annotation && (annotation.type === 'TypeAnnotation' || annotation.type === 'NullableTypeAnnotation')) {
696 annotation = annotation.typeAnnotation;
697 }
698 if (annotation.type === 'GenericTypeAnnotation' && typeScope(annotation.id.name)) {
699 return typeScope(annotation.id.name);
700 }
701 return annotation;
702 }
703
704 // --------------------------------------------------------------------------
705 // Public
706 // --------------------------------------------------------------------------
707
708 return {
709 ClassProperty: function(node) {
710 if (isAnnotatedPropsDeclaration(node)) {
711 markPropTypesAsDeclared(node, resolveTypeAnnotation(node));
712 } else if (isPropTypesDeclaration(node)) {
713 markPropTypesAsDeclared(node, node.value);
714 }
715 },
716
717 VariableDeclarator: function(node) {
718 var destructuring = node.init && node.id && node.id.type === 'ObjectPattern';
719 // let {props: {firstname}} = this
720 var thisDestructuring = destructuring && node.init.type === 'ThisExpression';
721 // let {firstname} = props
722 var statelessDestructuring = destructuring && node.init.name === 'props' && utils.getParentStatelessComponent();
723
724 if (!thisDestructuring && !statelessDestructuring) {
725 return;
726 }
727 markPropTypesAsUsed(node);
728 },
729
730 MemberExpression: function(node) {
731 var type;
732 if (isPropTypesUsage(node)) {
733 type = 'usage';
734 } else if (isPropTypesDeclaration(node.property)) {
735 type = 'declaration';
736 }
737
738 switch (type) {
739 case 'usage':
740 markPropTypesAsUsed(node);
741 break;
742 case 'declaration':
743 var component = utils.getRelatedComponent(node);
744 if (!component) {
745 return;
746 }
747 markPropTypesAsDeclared(component.node, node.parent.right || node.parent);
748 break;
749 default:
750 break;
751 }
752 },
753
754 MethodDefinition: function(node) {
755 if (!isPropTypesDeclaration(node.key)) {
756 return;
757 }
758
759 var i = node.value.body.body.length - 1;
760 for (; i >= 0; i--) {
761 if (node.value.body.body[i].type === 'ReturnStatement') {
762 break;
763 }
764 }
765
766 if (i >= 0) {
767 markPropTypesAsDeclared(node, node.value.body.body[i].argument);
768 }
769 },
770
771 ObjectExpression: function(node) {
772 // Search for the proptypes declaration
773 node.properties.forEach(function(property) {
774 if (!isPropTypesDeclaration(property.key)) {
775 return;
776 }
777 markPropTypesAsDeclared(node, property.value);
778 });
779 },
780
781 TypeAlias: function(node) {
782 typeScope(node.id.name, node.right);
783 },
784
785 Program: function() {
786 stack = [{}];
787 },
788
789 BlockStatement: function () {
790 stack.push(Object.create(typeScope()));
791 },
792
793 'BlockStatement:exit': function () {
794 stack.pop();
795 },
796
797 'Program:exit': function() {
798 stack = null;
799 var list = components.list();
800 // Report undeclared proptypes for all classes
801 for (var component in list) {
802 if (!list.hasOwnProperty(component) || !mustBeValidated(list[component])) {
803 continue;
804 }
805 reportUndeclaredPropTypes(list[component]);
806 }
807 }
808 };
809
810 });
811
812 module.exports.schema = [{
813 type: 'object',
814 properties: {
815 ignore: {
816 type: 'array',
817 items: {
818 type: 'string'
819 }
820 },
821 customValidators: {
822 type: 'array',
823 items: {
824 type: 'string'
825 }
826 }
827 },
828 additionalProperties: false
829 }];
830
node_modules/eslint-plugin-react/lib/rules/react-in-jsx-scope.js
File was created 1 /**
2 * @fileoverview Prevent missing React when using JSX
3 * @author Glen Mailer
4 */
5 'use strict';
6
7 var variableUtil = require('../util/variable');
8 var pragmaUtil = require('../util/pragma');
9
10 // -----------------------------------------------------------------------------
11 // Rule Definition
12 // -----------------------------------------------------------------------------
13
14 module.exports = function(context) {
15
16 var pragma = pragmaUtil.getFromContext(context);
17 var NOT_DEFINED_MESSAGE = '\'{{name}}\' must be in scope when using JSX';
18
19 return {
20
21 JSXOpeningElement: function(node) {
22 var variables = variableUtil.variablesInScope(context);
23 if (variableUtil.findVariable(variables, pragma)) {
24 return;
25 }
26 context.report(node, NOT_DEFINED_MESSAGE, {
27 name: pragma
28 });
29 },
30
31 BlockComment: function(node) {
32 pragma = pragmaUtil.getFromNode(node) || pragma;
33 }
34
35 };
36
37 };
38
39 module.exports.schema = [];
40
node_modules/eslint-plugin-react/lib/rules/require-extension.js
File was created 1 /**
2 * @fileoverview Restrict file extensions that may be required
3 * @author Scott Andrews
4 */
5 'use strict';
6
7 var path = require('path');
8
9 // ------------------------------------------------------------------------------
10 // Constants
11 // ------------------------------------------------------------------------------
12
13 var DEFAULTS = {
14 extentions: ['.jsx']
15 };
16
17 var PKG_REGEX = /^[^\.]((?!\/).)*$/;
18
19 // ------------------------------------------------------------------------------
20 // Rule Definition
21 // ------------------------------------------------------------------------------
22
23 module.exports = function(context) {
24
25 function isPackage(id) {
26 return PKG_REGEX.test(id);
27 }
28
29 function isRequire(expression) {
30 return expression.callee.name === 'require';
31 }
32
33 function getId(expression) {
34 return expression.arguments[0] && expression.arguments[0].value;
35 }
36
37 function getExtension(id) {
38 return path.extname(id || '');
39 }
40
41 function getExtentionsConfig() {
42 return context.options[0] && context.options[0].extensions || DEFAULTS.extentions;
43 }
44
45 var forbiddenExtensions = getExtentionsConfig().reduce(function (extensions, extension) {
46 extensions[extension] = true;
47 return extensions;
48 }, Object.create(null));
49
50 function isForbiddenExtension(ext) {
51 return ext in forbiddenExtensions;
52 }
53
54 // --------------------------------------------------------------------------
55 // Public
56 // --------------------------------------------------------------------------
57
58 return {
59
60 CallExpression: function(node) {
61 if (isRequire(node)) {
62 var id = getId(node);
63 var ext = getExtension(id);
64 if (!isPackage(id) && isForbiddenExtension(ext)) {
65 context.report(node, 'Unable to require module with extension \'' + ext + '\'');
66 }
67 }
68 }
69
70 };
71
72 };
73
74 module.exports.schema = [{
75 type: 'object',
76 properties: {
77 extensions: {
78 type: 'array',
79 items: {
80 type: 'string'
81 }
82 }
83 },
84 additionalProperties: false
85 }];
86
node_modules/eslint-plugin-react/lib/rules/self-closing-comp.js
File was created 1 /**
2 * @fileoverview Prevent extra closing tags for components without children
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Rule Definition
9 // ------------------------------------------------------------------------------
10
11 module.exports = function(context) {
12
13 var tagConvention = /^[a-z]|\-/;
14 function isTagName(name) {
15 return tagConvention.test(name);
16 }
17
18 function isComponent(node) {
19 return node.name && node.name.type === 'JSXIdentifier' && !isTagName(node.name.name);
20 }
21
22 function hasChildren(node) {
23 var childrens = node.parent.children;
24 if (
25 !childrens.length ||
26 (childrens.length === 1 && childrens[0].type === 'Literal' && !childrens[0].value.trim())
27 ) {
28 return false;
29 }
30 return true;
31 }
32
33 // --------------------------------------------------------------------------
34 // Public
35 // --------------------------------------------------------------------------
36
37 return {
38
39 JSXOpeningElement: function(node) {
40 if (!isComponent(node) || node.selfClosing || hasChildren(node)) {
41 return;
42 }
43 context.report(node, 'Empty components are self-closing');
44 }
45 };
46
47 };
48
49 module.exports.schema = [];
50
node_modules/eslint-plugin-react/lib/rules/sort-comp.js
File was created 1 /**
2 * @fileoverview Enforce component methods order
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 var util = require('util');
8
9 var Components = require('../util/Components');
10
11 /**
12 * Get the methods order from the default config and the user config
13 * @param {Object} defaultConfig The default configuration.
14 * @param {Object} userConfig The user configuration.
15 * @returns {Array} Methods order
16 */
17 function getMethodsOrder(defaultConfig, userConfig) {
18 userConfig = userConfig || {};
19
20 var groups = util._extend(defaultConfig.groups, userConfig.groups);
21 var order = userConfig.order || defaultConfig.order;
22
23 var config = [];
24 var entry;
25 for (var i = 0, j = order.length; i < j; i++) {
26 entry = order[i];
27 if (groups.hasOwnProperty(entry)) {
28 config = config.concat(groups[entry]);
29 } else {
30 config.push(entry);
31 }
32 }
33
34 return config;
35 }
36
37 // ------------------------------------------------------------------------------
38 // Rule Definition
39 // ------------------------------------------------------------------------------
40
41 module.exports = Components.detect(function(context, components) {
42
43 var errors = {};
44
45 var MISPOSITION_MESSAGE = '{{propA}} should be placed {{position}} {{propB}}';
46
47 var methodsOrder = getMethodsOrder({
48 order: [
49 'lifecycle',
50 'everything-else',
51 'render'
52 ],
53 groups: {
54 lifecycle: [
55 'displayName',
56 'propTypes',
57 'contextTypes',
58 'childContextTypes',
59 'mixins',
60 'statics',
61 'defaultProps',
62 'constructor',
63 'getDefaultProps',
64 'state',
65 'getInitialState',
66 'getChildContext',
67 'componentWillMount',
68 'componentDidMount',
69 'componentWillReceiveProps',
70 'shouldComponentUpdate',
71 'componentWillUpdate',
72 'componentDidUpdate',
73 'componentWillUnmount'
74 ]
75 }
76 }, context.options[0]);
77
78 // --------------------------------------------------------------------------
79 // Public
80 // --------------------------------------------------------------------------
81
82 var regExpRegExp = /\/(.*)\/([g|y|i|m]*)/;
83
84 /**
85 * Get indexes of the matching patterns in methods order configuration
86 * @param {String} method - Method name.
87 * @returns {Array} The matching patterns indexes. Return [Infinity] if there is no match.
88 */
89 function getRefPropIndexes(method) {
90 var isRegExp;
91 var matching;
92 var i;
93 var j;
94 var indexes = [];
95 for (i = 0, j = methodsOrder.length; i < j; i++) {
96 isRegExp = methodsOrder[i].match(regExpRegExp);
97 if (isRegExp) {
98 matching = new RegExp(isRegExp[1], isRegExp[2]).test(method);
99 } else {
100 matching = methodsOrder[i] === method;
101 }
102 if (matching) {
103 indexes.push(i);
104 }
105 }
106
107 // No matching pattern, return 'everything-else' index
108 if (indexes.length === 0) {
109 for (i = 0, j = methodsOrder.length; i < j; i++) {
110 if (methodsOrder[i] === 'everything-else') {
111 indexes.push(i);
112 }
113 }
114 }
115
116 // No matching pattern and no 'everything-else' group
117 if (indexes.length === 0) {
118 indexes.push(Infinity);
119 }
120
121 return indexes;
122 }
123
124 /**
125 * Get properties name
126 * @param {Object} node - Property.
127 * @returns {String} Property name.
128 */
129 function getPropertyName(node) {
130
131 // Special case for class properties
132 // (babel-eslint does not expose property name so we have to rely on tokens)
133 if (node.type === 'ClassProperty') {
134 var tokens = context.getFirstTokens(node, 2);
135 return tokens[1] && tokens[1].type === 'Identifier' ? tokens[1].value : tokens[0].value;
136 }
137
138 return node.key.name;
139 }
140
141 /**
142 * Store a new error in the error list
143 * @param {Object} propA - Mispositioned property.
144 * @param {Object} propB - Reference property.
145 */
146 function storeError(propA, propB) {
147 // Initialize the error object if needed
148 if (!errors[propA.index]) {
149 errors[propA.index] = {
150 node: propA.node,
151 score: 0,
152 closest: {
153 distance: Infinity,
154 ref: {
155 node: null,
156 index: 0
157 }
158 }
159 };
160 }
161 // Increment the prop score
162 errors[propA.index].score++;
163 // Stop here if we already have a closer reference
164 if (Math.abs(propA.index - propB.index) > errors[propA.index].closest.distance) {
165 return;
166 }
167 // Update the closest reference
168 errors[propA.index].closest.distance = Math.abs(propA.index - propB.index);
169 errors[propA.index].closest.ref.node = propB.node;
170 errors[propA.index].closest.ref.index = propB.index;
171 }
172
173 /**
174 * Dedupe errors, only keep the ones with the highest score and delete the others
175 */
176 function dedupeErrors() {
177 for (var i in errors) {
178 if (!errors.hasOwnProperty(i)) {
179 continue;
180 }
181 var index = errors[i].closest.ref.index;
182 if (!errors[index]) {
183 continue;
184 }
185 if (errors[i].score > errors[index].score) {
186 delete errors[index];
187 } else {
188 delete errors[i];
189 }
190 }
191 }
192
193 /**
194 * Report errors
195 */
196 function reportErrors() {
197 dedupeErrors();
198
199 var nodeA;
200 var nodeB;
201 var indexA;
202 var indexB;
203 for (var i in errors) {
204 if (!errors.hasOwnProperty(i)) {
205 continue;
206 }
207
208 nodeA = errors[i].node;
209 nodeB = errors[i].closest.ref.node;
210 indexA = i;
211 indexB = errors[i].closest.ref.index;
212
213 context.report(nodeA, MISPOSITION_MESSAGE, {
214 propA: getPropertyName(nodeA),
215 propB: getPropertyName(nodeB),
216 position: indexA < indexB ? 'before' : 'after'
217 });
218 }
219 }
220
221 /**
222 * Get properties for a given AST node
223 * @param {ASTNode} node The AST node being checked.
224 * @returns {Array} Properties array.
225 */
226 function getComponentProperties(node) {
227 switch (node.type) {
228 case 'ClassDeclaration':
229 return node.body.body;
230 case 'ObjectExpression':
231 return node.properties;
232 default:
233 return [];
234 }
235 }
236
237 /**
238 * Compare two properties and find out if they are in the right order
239 * @param {Array} propertiesNames Array containing all the properties names.
240 * @param {String} propA First property name.
241 * @param {String} propB Second property name.
242 * @returns {Object} Object containing a correct true/false flag and the correct indexes for the two properties.
243 */
244 function comparePropsOrder(propertiesNames, propA, propB) {
245 var i;
246 var j;
247 var k;
248 var l;
249 var refIndexA;
250 var refIndexB;
251
252 // Get references indexes (the correct position) for given properties
253 var refIndexesA = getRefPropIndexes(propA);
254 var refIndexesB = getRefPropIndexes(propB);
255
256 // Get current indexes for given properties
257 var classIndexA = propertiesNames.indexOf(propA);
258 var classIndexB = propertiesNames.indexOf(propB);
259
260 // Loop around the references indexes for the 1st property
261 for (i = 0, j = refIndexesA.length; i < j; i++) {
262 refIndexA = refIndexesA[i];
263
264 // Loop around the properties for the 2nd property (for comparison)
265 for (k = 0, l = refIndexesB.length; k < l; k++) {
266 refIndexB = refIndexesB[k];
267
268 if (
269 // Comparing the same properties
270 refIndexA === refIndexB ||
271 // 1st property is placed before the 2nd one in reference and in current component
272 refIndexA < refIndexB && classIndexA < classIndexB ||
273 // 1st property is placed after the 2nd one in reference and in current component
274 refIndexA > refIndexB && classIndexA > classIndexB
275 ) {
276 return {
277 correct: true,
278 indexA: classIndexA,
279 indexB: classIndexB
280 };
281 }
282
283 }
284 }
285
286 // We did not find any correct match between reference and current component
287 return {
288 correct: false,
289 indexA: refIndexA,
290 indexB: refIndexB
291 };
292 }
293
294 /**
295 * Check properties order from a properties list and store the eventual errors
296 * @param {Array} properties Array containing all the properties.
297 */
298 function checkPropsOrder(properties) {
299 var propertiesNames = properties.map(getPropertyName);
300 var i;
301 var j;
302 var k;
303 var l;
304 var propA;
305 var propB;
306 var order;
307
308 // Loop around the properties
309 for (i = 0, j = propertiesNames.length; i < j; i++) {
310 propA = propertiesNames[i];
311
312 // Loop around the properties a second time (for comparison)
313 for (k = 0, l = propertiesNames.length; k < l; k++) {
314 propB = propertiesNames[k];
315
316 // Compare the properties order
317 order = comparePropsOrder(propertiesNames, propA, propB);
318
319 // Continue to next comparison is order is correct
320 if (order.correct === true) {
321 continue;
322 }
323
324 // Store an error if the order is incorrect
325 storeError({
326 node: properties[i],
327 index: order.indexA
328 }, {
329 node: properties[k],
330 index: order.indexB
331 });
332 }
333 }
334
335 }
336
337 return {
338 'Program:exit': function() {
339 var list = components.list();
340 for (var component in list) {
341 if (!list.hasOwnProperty(component)) {
342 continue;
343 }
344 var properties = getComponentProperties(list[component].node);
345 checkPropsOrder(properties);
346 }
347
348 reportErrors();
349 }
350 };
351
352 });
353
354 module.exports.schema = [{
355 type: 'object',
356 properties: {
357 order: {
358 type: 'array',
359 items: {
360 type: 'string'
361 }
362 },
363 groups: {
364 type: 'object',
365 patternProperties: {
366 '^.*$': {
367 type: 'array',
368 items: {
369 type: 'string'
370 }
371 }
372 }
373 }
374 },
375 additionalProperties: false
376 }];
377
node_modules/eslint-plugin-react/lib/rules/wrap-multilines.js
File was created 1 /**
2 * @fileoverview Prevent missing parentheses around multilines JSX
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 // ------------------------------------------------------------------------------
8 // Constants
9 // ------------------------------------------------------------------------------
10
11 var DEFAULTS = {
12 declaration: true,
13 assignment: true,
14 return: true
15 };
16
17 // ------------------------------------------------------------------------------
18 // Rule Definition
19 // ------------------------------------------------------------------------------
20
21 module.exports = function(context) {
22
23 var sourceCode = context.getSourceCode();
24
25 function isParenthesised(node) {
26 var previousToken = context.getTokenBefore(node);
27 var nextToken = context.getTokenAfter(node);
28
29 return previousToken && nextToken &&
30 previousToken.value === '(' && previousToken.range[1] <= node.range[0] &&
31 nextToken.value === ')' && nextToken.range[0] >= node.range[1];
32 }
33
34 function isMultilines(node) {
35 return node.loc.start.line !== node.loc.end.line;
36 }
37
38 function check(node) {
39 if (!node || node.type !== 'JSXElement') {
40 return;
41 }
42
43 if (!isParenthesised(node) && isMultilines(node)) {
44 context.report({
45 node: node,
46 message: 'Missing parentheses around multilines JSX',
47 fix: function(fixer) {
48 return fixer.replaceText(node, '(' + sourceCode.getText(node) + ')');
49 }
50 });
51 }
52 }
53
54 function isEnabled(type) {
55 var userOptions = context.options[0] || {};
56 if (({}).hasOwnProperty.call(userOptions, type)) {
57 return userOptions[type];
58 }
59 return DEFAULTS[type];
60 }
61
62 // --------------------------------------------------------------------------
63 // Public
64 // --------------------------------------------------------------------------
65
66 return {
67
68 VariableDeclarator: function(node) {
69 if (isEnabled('declaration')) {
70 check(node.init);
71 }
72 },
73
74 AssignmentExpression: function(node) {
75 if (isEnabled('assignment')) {
76 check(node.right);
77 }
78 },
79
80 ReturnStatement: function(node) {
81 if (isEnabled('return')) {
82 check(node.argument);
83 }
84 }
85 };
86
87 };
88
89 module.exports.schema = [{
90 type: 'object',
91 properties: {
92 declaration: {
93 type: 'boolean'
94 },
95 assignment: {
96 type: 'boolean'
97 },
98 return: {
99 type: 'boolean'
100 }
101 },
102 additionalProperties: false
103 }];
104
node_modules/eslint-plugin-react/lib/util/Components.js
File was created 1 /**
2 * @fileoverview Utility class and functions for React components detection
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 var util = require('util');
8 var variableUtil = require('./variable');
9 var pragmaUtil = require('./pragma');
10
11 /**
12 * Components
13 * @class
14 */
15 function Components() {
16 this._list = {};
17 this._getId = function(node) {
18 return node && node.range.join(':');
19 };
20 }
21
22 /**
23 * Add a node to the components list, or update it if it's already in the list
24 *
25 * @param {ASTNode} node The AST node being added.
26 * @param {Number} confidence Confidence in the component detection (0=banned, 1=maybe, 2=yes)
27 */
28 Components.prototype.add = function(node, confidence) {
29 var id = this._getId(node);
30 if (this._list[id]) {
31 if (confidence === 0 || this._list[id].confidence === 0) {
32 this._list[id].confidence = 0;
33 } else {
34 this._list[id].confidence = Math.max(this._list[id].confidence, confidence);
35 }
36 return;
37 }
38 this._list[id] = {
39 node: node,
40 confidence: confidence
41 };
42 };
43
44 /**
45 * Find a component in the list using its node
46 *
47 * @param {ASTNode} node The AST node being searched.
48 * @returns {Object} Component object, undefined if the component is not found
49 */
50 Components.prototype.get = function(node) {
51 var id = this._getId(node);
52 return this._list[id];
53 };
54
55 /**
56 * Update a component in the list
57 *
58 * @param {ASTNode} node The AST node being updated.
59 * @param {Object} props Additional properties to add to the component.
60 */
61 Components.prototype.set = function(node, props) {
62 while (node && !this._list[this._getId(node)]) {
63 node = node.parent;
64 }
65 if (!node) {
66 return;
67 }
68 var id = this._getId(node);
69 this._list[id] = util._extend(this._list[id], props);
70 };
71
72 /**
73 * Return the components list
74 * Components for which we are not confident are not returned
75 *
76 * @returns {Object} Components list
77 */
78 Components.prototype.list = function() {
79 var list = {};
80 for (var i in this._list) {
81 if (!this._list.hasOwnProperty(i) || this._list[i].confidence < 2) {
82 continue;
83 }
84 list[i] = this._list[i];
85 }
86 return list;
87 };
88
89 /**
90 * Return the length of the components list
91 * Components for which we are not confident are not counted
92 *
93 * @returns {Number} Components list length
94 */
95 Components.prototype.length = function() {
96 var length = 0;
97 for (var i in this._list) {
98 if (!this._list.hasOwnProperty(i) || this._list[i].confidence < 2) {
99 continue;
100 }
101 length++;
102 }
103 return length;
104 };
105
106 function componentRule(rule, context) {
107
108 var pragma = pragmaUtil.getFromContext(context);
109 var sourceCode = context.getSourceCode();
110 var components = new Components();
111
112 // Utilities for component detection
113 var utils = {
114
115 /**
116 * Check if the node is a React ES5 component
117 *
118 * @param {ASTNode} node The AST node being checked.
119 * @returns {Boolean} True if the node is a React ES5 component, false if not
120 */
121 isES5Component: function(node) {
122 if (!node.parent) {
123 return false;
124 }
125 return new RegExp('^(' + pragma + '\\.)?createClass$').test(sourceCode.getText(node.parent.callee));
126 },
127
128 /**
129 * Check if the node is a React ES6 component
130 *
131 * @param {ASTNode} node The AST node being checked.
132 * @returns {Boolean} True if the node is a React ES6 component, false if not
133 */
134 isES6Component: function(node) {
135 if (!node.superClass) {
136 return false;
137 }
138 return new RegExp('^(' + pragma + '\\.)?Component$').test(sourceCode.getText(node.superClass));
139 },
140
141 /**
142 * Check if the node is returning JSX
143 *
144 * @param {ASTNode} node The AST node being checked (must be a ReturnStatement).
145 * @returns {Boolean} True if the node is returning JSX, false if not
146 */
147 isReturningJSX: function(node) {
148 var property;
149 switch (node.type) {
150 case 'ReturnStatement':
151 property = 'argument';
152 break;
153 case 'ArrowFunctionExpression':
154 property = 'body';
155 break;
156 default:
157 return false;
158 }
159
160 var returnsJSX =
161 node[property] &&
162 node[property].type === 'JSXElement'
163 ;
164 var returnsReactCreateElement =
165 node[property] &&
166 node[property].callee &&
167 node[property].callee.property &&
168 node[property].callee.property.name === 'createElement'
169 ;
170
171 return Boolean(returnsJSX || returnsReactCreateElement);
172 },
173
174 /**
175 * Get the parent component node from the current scope
176 *
177 * @returns {ASTNode} component node, null if we are not in a component
178 */
179 getParentComponent: function() {
180 return (
181 utils.getParentES6Component() ||
182 utils.getParentES5Component() ||
183 utils.getParentStatelessComponent()
184 );
185 },
186
187 /**
188 * Get the parent ES5 component node from the current scope
189 *
190 * @returns {ASTNode} component node, null if we are not in a component
191 */
192 getParentES5Component: function() {
193 var scope = context.getScope();
194 while (scope) {
195 var node = scope.block && scope.block.parent && scope.block.parent.parent;
196 if (node && utils.isES5Component(node)) {
197 return node;
198 }
199 scope = scope.upper;
200 }
201 return null;
202 },
203
204 /**
205 * Get the parent ES6 component node from the current scope
206 *
207 * @returns {ASTNode} component node, null if we are not in a component
208 */
209 getParentES6Component: function() {
210 var scope = context.getScope();
211 while (scope && scope.type !== 'class') {
212 scope = scope.upper;
213 }
214 var node = scope && scope.block;
215 if (!node || !utils.isES6Component(node)) {
216 return null;
217 }
218 return node;
219 },
220
221 /**
222 * Get the parent stateless component node from the current scope
223 *
224 * @returns {ASTNode} component node, null if we are not in a component
225 */
226 getParentStatelessComponent: function() {
227 var scope = context.getScope();
228 while (scope) {
229 var node = scope.block;
230 var isFunction = /Function/.test(node.type); // Ignore non functions
231 var isNotMethod = !node.parent || node.parent.type !== 'MethodDefinition'; // Ignore classes methods
232 var isNotArgument = !node.parent || node.parent.type !== 'CallExpression'; // Ignore arguments (callback, etc.)
233 if (isFunction && isNotMethod && isNotArgument) {
234 return node;
235 }
236 scope = scope.upper;
237 }
238 return null;
239 },
240
241 /**
242 * Get the related component from a node
243 *
244 * @param {ASTNode} node The AST node being checked (must be a MemberExpression).
245 * @returns {ASTNode} component node, null if we cannot find the component
246 */
247 getRelatedComponent: function(node) {
248 var i;
249 var j;
250 var k;
251 var l;
252 // Get the component path
253 var componentPath = [];
254 while (node) {
255 if (node.property && node.property.type === 'Identifier') {
256 componentPath.push(node.property.name);
257 }
258 if (node.object && node.object.type === 'Identifier') {
259 componentPath.push(node.object.name);
260 }
261 node = node.object;
262 }
263 componentPath.reverse();
264
265 // Find the variable in the current scope
266 var variableName = componentPath.shift();
267 if (!variableName) {
268 return null;
269 }
270 var variableInScope;
271 var variables = variableUtil.variablesInScope(context);
272 for (i = 0, j = variables.length; i < j; i++) {
273 if (variables[i].name === variableName) {
274 variableInScope = variables[i];
275 break;
276 }
277 }
278 if (!variableInScope) {
279 return null;
280 }
281
282 // Find the variable declaration
283 var defInScope;
284 var defs = variableInScope.defs;
285 for (i = 0, j = defs.length; i < j; i++) {
286 if (defs[i].type === 'ClassName' || defs[i].type === 'FunctionName' || defs[i].type === 'Variable') {
287 defInScope = defs[i];
288 break;
289 }
290 }
291 if (!defInScope || !defInScope.node) {
292 return null;
293 }
294 node = defInScope.node.init || defInScope.node;
295
296 // Traverse the node properties to the component declaration
297 for (i = 0, j = componentPath.length; i < j; i++) {
298 if (!node.properties) {
299 continue;
300 }
301 for (k = 0, l = node.properties.length; k < l; k++) {
302 if (node.properties[k].key.name === componentPath[i]) {
303 node = node.properties[k];
304 break;
305 }
306 }
307 if (!node || !node.value) {
308 return null;
309 }
310 node = node.value;
311 }
312
313 // Return the component
314 return components.get(node);
315 }
316 };
317
318 // Component detection instructions
319 var detectionInstructions = {
320 ClassDeclaration: function(node) {
321 if (!utils.isES6Component(node)) {
322 return;
323 }
324 components.add(node, 2);
325 },
326
327 ClassProperty: function(node) {
328 node = utils.getParentComponent();
329 if (!node) {
330 return;
331 }
332 components.add(node, 2);
333 },
334
335 ObjectExpression: function(node) {
336 if (!utils.isES5Component(node)) {
337 return;
338 }
339 components.add(node, 2);
340 },
341
342 FunctionExpression: function(node) {
343 node = utils.getParentComponent();
344 if (!node) {
345 return;
346 }
347 components.add(node, 1);
348 },
349
350 FunctionDeclaration: function(node) {
351 node = utils.getParentComponent();
352 if (!node) {
353 return;
354 }
355 components.add(node, 1);
356 },
357
358 ArrowFunctionExpression: function(node) {
359 node = utils.getParentComponent();
360 if (!node) {
361 return;
362 }
363 if (node.expression && utils.isReturningJSX(node)) {
364 components.add(node, 2);
365 } else {
366 components.add(node, 1);
367 }
368 },
369
370 ThisExpression: function(node) {
371 node = utils.getParentComponent();
372 if (!node || !/Function/.test(node.type)) {
373 return;
374 }
375 // Ban functions with a ThisExpression
376 components.add(node, 0);
377 },
378
379 BlockComment: function(node) {
380 pragma = pragmaUtil.getFromNode(node) || pragma;
381 },
382
383 ReturnStatement: function(node) {
384 if (!utils.isReturningJSX(node)) {
385 return;
386 }
387 node = utils.getParentComponent();
388 if (!node) {
389 return;
390 }
391 components.add(node, 2);
392 }
393 };
394
395 // Update the provided rule instructions to add the component detection
396 var ruleInstructions = rule(context, components, utils);
397 var updatedRuleInstructions = util._extend({}, ruleInstructions);
398 Object.keys(detectionInstructions).forEach(function(instruction) {
399 updatedRuleInstructions[instruction] = function(node) {
400 detectionInstructions[instruction](node);
401 return ruleInstructions[instruction] ? ruleInstructions[instruction](node) : void 0;
402 };
403 });
404 // Return the updated rule instructions
405 return updatedRuleInstructions;
406 }
407
408 Components.detect = function(rule) {
409 return componentRule.bind(this, rule);
410 };
411
412 module.exports = Components;
413
node_modules/eslint-plugin-react/lib/util/pragma.js
File was created 1 /**
2 * @fileoverview Utility functions for React pragma configuration
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 var JSX_ANNOTATION_REGEX = /^\*\s*@jsx\s+([^\s]+)/;
8
9 function getFromContext(context) {
10 var pragma = 'React';
11 // .eslintrc shared settings (http://eslint.org/docs/user-guide/configuring#adding-shared-settings)
12 if (context.settings.react && context.settings.react.pragma) {
13 pragma = context.settings.react.pragma;
14 // Deprecated pragma option, here for backward compatibility
15 } else if (context.options[0] && context.options[0].pragma) {
16 pragma = context.options[0].pragma;
17 }
18 return pragma.split('.')[0];
19 }
20
21 function getFromNode(node) {
22 var matches = JSX_ANNOTATION_REGEX.exec(node.value);
23 if (!matches) {
24 return false;
25 }
26 return matches[1].split('.')[0];
27 }
28
29 module.exports = {
30 getFromContext: getFromContext,
31 getFromNode: getFromNode
32 };
33
node_modules/eslint-plugin-react/lib/util/variable.js
File was created 1 /**
2 * @fileoverview Utility functions for React components detection
3 * @author Yannick Croissant
4 */
5 'use strict';
6
7 /**
8 * Record that a particular variable has been used in code
9 *
10 * @param {Object} context The current rule context.
11 * @param {String} name The name of the variable to mark as used.
12 * @returns {Boolean} True if the variable was found and marked as used, false if not.
13 */
14 function markVariableAsUsed(context, name) {
15 var scope = context.getScope();
16 var variables;
17 var i;
18 var len;
19 var found = false;
20
21 // Special Node.js scope means we need to start one level deeper
22 if (scope.type === 'global') {
23 while (scope.childScopes.length) {
24 scope = scope.childScopes[0];
25 }
26 }
27
28 do {
29 variables = scope.variables;
30 for (i = 0, len = variables.length; i < len; i++) {
31 if (variables[i].name === name) {
32 variables[i].eslintUsed = true;
33 found = true;
34 }
35 }
36 scope = scope.upper;
37 } while (scope);
38
39 return found;
40 }
41
42 /**
43 * Search a particular variable in a list
44 * @param {Array} variables The variables list.
45 * @param {Array} name The name of the variable to search.
46 * @returns {Boolean} True if the variable was found, false if not.
47 */
48 function findVariable(variables, name) {
49 var i;
50 var len;
51
52 for (i = 0, len = variables.length; i < len; i++) {
53 if (variables[i].name === name) {
54 return true;
55 }
56 }
57
58 return false;
59 }
60
61 /**
62 * List all variable in a given scope
63 *
64 * Contain a patch for babel-eslint to avoid https://github.com/babel/babel-eslint/issues/21
65 *
66 * @param {Object} context The current rule context.
67 * @param {Array} name The name of the variable to search.
68 * @returns {Boolean} True if the variable was found, false if not.
69 */
70 function variablesInScope(context) {
71 var scope = context.getScope();
72 var variables = scope.variables;
73
74 while (scope.type !== 'global') {
75 scope = scope.upper;
76 variables = scope.variables.concat(variables);
77 }
78 if (scope.childScopes.length) {
79 variables = scope.childScopes[0].variables.concat(variables);
80 if (scope.childScopes[0].childScopes.length) {
81 variables = scope.childScopes[0].childScopes[0].variables.concat(variables);
82 }
83 }
84
85 return variables;
86 }
87
88 module.exports = {
89 findVariable: findVariable,
90 variablesInScope: variablesInScope,
91 markVariableAsUsed: markVariableAsUsed
92 };
93
node_modules/eslint-plugin-react/package.json
File was created 1 {
2 "name": "eslint-plugin-react",
3 "version": "3.16.1",
4 "author": {
5 "name": "Yannick Croissant",
6 "email": "yannick.croissant+npm@gmail.com"
7 },
8 "description": "React specific linting rules for ESLint",
9 "main": "index.js",
10 "scripts": {
11 "coveralls": "cat ./reports/coverage/lcov.info | coveralls",
12 "lint": "eslint ./",
13 "test": "npm run lint && npm run unit-test",
14 "unit-test": "istanbul cover --dir reports/coverage node_modules/mocha/bin/_mocha tests/**/*.js -- --reporter dot"
15 },
16 "files": [
17 "LICENSE",
18 "README.md",
19 "index.js",
20 "lib"
21 ],
22 "repository": {
23 "type": "git",
24 "url": "git+https://github.com/yannickcr/eslint-plugin-react.git"
25 },
26 "homepage": "https://github.com/yannickcr/eslint-plugin-react",
27 "bugs": {
28 "url": "https://github.com/yannickcr/eslint-plugin-react/issues"
29 },
30 "devDependencies": {
31 "babel-eslint": "5.0.0-beta6",
32 "coveralls": "2.11.6",
33 "eslint": "2.0.0-beta.2",
34 "istanbul": "0.4.2",
35 "mocha": "2.3.4"
36 },
37 "keywords": [
38 "eslint",
39 "eslint-plugin",
40 "eslintplugin",
41 "react"
42 ],
43 "license": "MIT",
44 "gitHead": "c06ebd84bd5e5655a687d0fd7a150b3c10bf8c93",
45 "_id": "eslint-plugin-react@3.16.1",
46 "_shasum": "262d96b77d7c4a42af809a73c0e527a58612293c",
47 "_from": "eslint-plugin-react@*",
48 "_npmVersion": "3.2.2",
49 "_nodeVersion": "4.0.0",
50 "_npmUser": {
51 "name": "yannickcr",
52 "email": "yannick.croissant+npm@gmail.com"
53 },
54 "dist": {
55 "shasum": "262d96b77d7c4a42af809a73c0e527a58612293c",
56 "tarball": "http://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-3.16.1.tgz"
57 },
58 "maintainers": [
59 {
60 "name": "yannickcr",
61 "email": "yannick.croissant+npm@gmail.com"
62 }
63 ],
64 "directories": {},
65 "_resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-3.16.1.tgz",
66 "readme": "ERROR: No README data found!"
67 }
68