mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
@@ -83,6 +83,7 @@ For a more thorough introduction, read [setting up a Meteor project](docs/SETUP_
|
||||
* [check](docs/rules/check.md): Core API for check and Match
|
||||
* [connections](docs/rules/connections.md): Core API for connections
|
||||
* [collections](docs/rules/collections.md): Core API for collections
|
||||
* [session](docs/rules/session.md): Core API for Session
|
||||
|
||||
## Best Practices
|
||||
* [audit-argument-checks](docs/rules/audit-argument-checks.md): Enforce check on all arguments passed to methods and publish functions
|
||||
|
||||
114
docs/rules/session.md
Normal file
114
docs/rules/session.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Core API for Session (session)
|
||||
|
||||
Prevent misusage of [Session](http://docs.meteor.com/#/full/session).
|
||||
|
||||
|
||||
## Rule Details
|
||||
|
||||
This rule aims to prevent errors when using Publications and Subscriptions. It verifies `Session` is used in the correct environments.
|
||||
|
||||
The following patterns are considered warnings:
|
||||
|
||||
```js
|
||||
|
||||
Session.set('foo')
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
Session.setDefault('foo')
|
||||
|
||||
```
|
||||
|
||||
|
||||
```js
|
||||
|
||||
Session.set('foo', true, 'bar')
|
||||
|
||||
```
|
||||
|
||||
|
||||
```js
|
||||
|
||||
if (Meteor.isServer) {
|
||||
Session.set('foo')
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
```js
|
||||
|
||||
Session.get('foo', true)
|
||||
|
||||
```
|
||||
|
||||
|
||||
```js
|
||||
|
||||
Session.get()
|
||||
|
||||
```
|
||||
|
||||
|
||||
```js
|
||||
|
||||
Session.equals('foo')
|
||||
|
||||
```
|
||||
|
||||
The following patterns are not warnings:
|
||||
|
||||
```js
|
||||
|
||||
Session.set('foo', true)
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
Session.setDefault('foo', true)
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
Session.get('foo')
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
Session.equals('foo', true)
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
#### no-equal
|
||||
|
||||
By default this rule does not warn when trying to call `Session.equal`. Usually a call to `Session.equals` is meant instead.
|
||||
To warn when using `Session.equal`, configure the rule as
|
||||
|
||||
```
|
||||
|
||||
session: [2, "no-equal"]
|
||||
|
||||
```
|
||||
|
||||
With this configuration, the rule will warn on this pattern:
|
||||
|
||||
```js
|
||||
|
||||
Session.equal('foo', 'bar')
|
||||
|
||||
```
|
||||
|
||||
## When Not To Use It
|
||||
|
||||
Disable this rule if you are using [no-session](./no-session.md).
|
||||
|
||||
## Further Reading
|
||||
|
||||
- http://docs.meteor.com/#/full/session
|
||||
@@ -22,6 +22,7 @@ module.exports = {
|
||||
check: unpack('./rules/check'),
|
||||
connections: unpack('./rules/connections'),
|
||||
collections: unpack('./rules/collections'),
|
||||
session: unpack('./rules/session'),
|
||||
|
||||
// Best Practices
|
||||
'audit-argument-checks': unpack('./rules/audit-argument-checks'),
|
||||
@@ -39,6 +40,7 @@ module.exports = {
|
||||
check: 0,
|
||||
connections: 0,
|
||||
collections: 0,
|
||||
session: 0,
|
||||
|
||||
// Best Practices
|
||||
'audit-argument-checks': 0,
|
||||
|
||||
73
lib/rules/session.js
Normal file
73
lib/rules/session.js
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @fileoverview Core API for Session
|
||||
* @author Dominik Ferber
|
||||
* @copyright 2015 Dominik Ferber. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
import {NON_METEOR, SERVER} from '../util/environment'
|
||||
import {getExecutors} from '../util'
|
||||
import {getPropertyName} from '../util/ast'
|
||||
|
||||
module.exports = getMeta => context => {
|
||||
const {env} = getMeta(context)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Public
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
if (env === NON_METEOR || env === SERVER) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
CallExpression: function (node) {
|
||||
if (
|
||||
node.callee.type === 'MemberExpression' &&
|
||||
node.callee.object.type === 'Identifier' &&
|
||||
node.callee.object.name === 'Session'
|
||||
) {
|
||||
const executors = getExecutors(env, context.getAncestors())
|
||||
if (executors.size === 0) {
|
||||
return
|
||||
}
|
||||
if (executors.has('server')) {
|
||||
context.report(node, 'Allowed on client only')
|
||||
return
|
||||
}
|
||||
|
||||
switch (getPropertyName(node.callee.property)) {
|
||||
case 'set':
|
||||
case 'setDefault':
|
||||
case 'equals':
|
||||
if (node.arguments.length !== 2) {
|
||||
context.report(node, 'Expected two arguments')
|
||||
}
|
||||
break
|
||||
case 'get':
|
||||
if (node.arguments.length !== 1) {
|
||||
context.report(node, 'Expected one argument')
|
||||
}
|
||||
break
|
||||
case 'equal':
|
||||
if (context.options.length > 0 && context.options[0] === 'no-equal') {
|
||||
context.report(node.callee.property, 'Did you mean "Session.equals" instead?')
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.schema = [
|
||||
{
|
||||
enum: ['equal', 'no-equal']
|
||||
}
|
||||
]
|
||||
121
tests/lib/rules/session.js
Normal file
121
tests/lib/rules/session.js
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* @fileoverview Core API for Session
|
||||
* @author Dominik Ferber
|
||||
* @copyright 2015 Dominik Ferber. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
import {NON_METEOR, UNIVERSAL, CLIENT, SERVER} from '../../../dist/util/environment'
|
||||
const rule = require('../../../dist/rules/session')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const commonValidCode = [
|
||||
'x()',
|
||||
'Session.set("foo", true)',
|
||||
'Session.setDefault("foo", true)',
|
||||
'Session.get("foo")',
|
||||
'Session.equals("foo", true)',
|
||||
{
|
||||
code: `Session.equal('foo', 'bar')`,
|
||||
options: ['equal']
|
||||
},
|
||||
`
|
||||
if (Meteor.isServer) {
|
||||
Session.set('foo')
|
||||
}
|
||||
`
|
||||
]
|
||||
|
||||
const commonInvalidCode = [
|
||||
{
|
||||
code: `Session.set('foo')`,
|
||||
errors: [{message: 'Expected two arguments', type: 'CallExpression'}]
|
||||
},
|
||||
{
|
||||
code: `Session.setDefault('foo')`,
|
||||
errors: [{message: 'Expected two arguments', type: 'CallExpression'}]
|
||||
},
|
||||
{
|
||||
code: `Session.set('foo', true, 'bar')`,
|
||||
errors: [{message: 'Expected two arguments', type: 'CallExpression'}]
|
||||
},
|
||||
{
|
||||
code: `
|
||||
Session.get('foo', true)
|
||||
`,
|
||||
errors: [{message: 'Expected one argument', type: 'CallExpression'}]
|
||||
},
|
||||
{
|
||||
code: `Session.get()`,
|
||||
errors: [{message: 'Expected one argument', type: 'CallExpression'}]
|
||||
},
|
||||
{
|
||||
code: `Session.equals('foo')`,
|
||||
errors: [{message: 'Expected two arguments', type: 'CallExpression'}]
|
||||
},
|
||||
{
|
||||
code: `Session.equal('foo', 'bar')`,
|
||||
options: ['no-equal'],
|
||||
errors: [{message: 'Did you mean "Session.equals" instead?', type: 'Identifier'}]
|
||||
}
|
||||
]
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Tests
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
ruleTester.run('session', rule(() => ({env: CLIENT})), {
|
||||
valid: [
|
||||
...commonValidCode
|
||||
],
|
||||
|
||||
invalid: [
|
||||
...commonInvalidCode
|
||||
]
|
||||
})
|
||||
|
||||
ruleTester.run('session', rule(() => ({env: UNIVERSAL})), {
|
||||
valid: [
|
||||
`
|
||||
if (Meteor.isClient) {
|
||||
Session.set('foo', true)
|
||||
}
|
||||
`,
|
||||
`
|
||||
if (Meteor.isCordova) {
|
||||
Session.set('foo', true)
|
||||
}
|
||||
`
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{
|
||||
code: `Session.set('foo', true)`,
|
||||
errors: [{message: 'Allowed on client only', type: 'CallExpression'}]
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
ruleTester.run('session', rule(() => ({env: SERVER})), {
|
||||
valid: [
|
||||
...commonValidCode,
|
||||
...commonInvalidCode
|
||||
],
|
||||
|
||||
invalid: []
|
||||
})
|
||||
|
||||
ruleTester.run('session', rule(() => ({env: NON_METEOR})), {
|
||||
valid: [
|
||||
...commonValidCode,
|
||||
...commonInvalidCode
|
||||
],
|
||||
|
||||
invalid: []
|
||||
})
|
||||
Reference in New Issue
Block a user