5.2.14 • Published 4 months ago

eslint-plugin-formatjs v5.2.14

Weekly downloads
21,801
License
MIT
Repository
github
Last release
4 months ago

eslint-plugin-formatjs

This eslint plugin allows you to enforce certain rules in your ICU message. This is currently under development

Usage

npm install eslint-plugin-formatjs

Then in your eslint config:

{
  "plugins": ["formatjs"],
  "rules": {
    "formatjs/no-offset": "error"
  }
}

Currently this uses intl.formatMessage, defineMessages, <FormattedMessage> from react-intl, or _ from @formatjs/macro as hooks to verify the message. Therefore, in your code use 1 of the following mechanisms:

import {_} from '@formatjs/macro';

const message = _({
  defaultMessage: 'foo',
  description: 'bar',
});
import {defineMessages} from 'react-intl';

const messages = defineMessages({
  foo: {
    defaultMessage: 'foo',
    description: 'bar',
  },
});
import {FormattedMessage} from 'react-intl';

<FormattedMessage defaultMessage="foo" description="bar" />;
function foo() {
  intl.formatMessage({
    defaultMessage: 'foo',
  });
}

Available Rules

enforce-placeholders

Makes sure all values are passed in if message has placeholders (number/date/time/plural/select/selectordinal). This requires values to be passed in as literal object (not a variable).

// WORKS, no error
<FormattedMessage
  defaultMessage="this is a {placeholder}"
  values={{placeholder: 'dog'}}
/>

// WORKS, no error
intl.formatMessage({
  defaultMessage: 'this is a {placeholder}'
}, {placeholder: 'dog'})

// WORKS, error bc no values were provided
<FormattedMessage
  defaultMessage="this is a {placeholder}"
/>

// WORKS, error bc no values were provided
intl.formatMessage({
  defaultMessage: 'this is a {placeholder}'
})

// WORKS, error bc `placeholder` is not passed in
<FormattedMessage
  defaultMessage="this is a {placeholder}"
  values={{foo: 1}}
/>

// WORKS, error bc `placeholder` is not passed in
intl.formatMessage({
  defaultMessage: 'this is a {placeholder}'
}, {foo: 1})

// DOESN'T WORK
<FormattedMessage
  defaultMessage="this is a {placeholder}"
  values={someVar}
/>

// DOESN'T WORK
intl.formatMessage({
  defaultMessage: 'this is a {placeholder}'
}, values)

blacklist-elements

This blacklists usage of specific elements in ICU message.

Why

  • Certain translation vendors cannot handle things like selectordinal

Available elements

enum Element {
  // literal text, like `defaultMessage: 'some text'`
  literal = 'literal',
  // placeholder, like `defaultMessage: '{placeholder} var'`
  argument = 'argument',
  // number, like `defaultMessage: '{placeholder, number} var'`
  number = 'number',
  // date, like `defaultMessage: '{placeholder, date} var'`
  date = 'date',
  // time, like `defaultMessage: '{placeholder, time} var'`
  time = 'time',
  // select, like `defaultMessage: '{var, select, foo{one} bar{two}} var'`
  select = 'select',
  // selectordinal, like `defaultMessage: '{var, selectordinal, one{one} other{two}} var'`
  selectordinal = 'selectordinal',
  // plural, like `defaultMessage: '{var, plural, one{one} other{two}} var'`
  plural = 'plural',
}

Example

{
  "plugins": ["formatjs"],
  "rules": {
    "formatjs/blacklist-elements": [2, ["selectordinal"]]
  }
}

enforce-description

This enforces description in the message descriptor.

Why

  • Description provides helpful context for translators
import {defineMessages} from 'react-intl';

const messages = defineMessages({
  // WORKS
  foo: {
    defaultMessage: 'foo',
    description: 'bar',
  },
  // FAILS
  bar: {
    defaultMessage: 'bar',
  },
});

no-camel-case

This make sure placeholders are not camel-case.

Why

  • This is to prevent case-sensitivity issue in certain translation vendors.
import {defineMessages} from 'react-intl';

const messages = defineMessages({
  // WORKS
  foo: {
    defaultMessage: 'foo {snake_case} {nothing}',
  },
  // FAILS
  bar: {
    defaultMessage: 'foo {camelCase}',
  },
});

enforce-plural-rules

Enforce certain plural rules to always be specified/forbidden in a message.

Why

  • It is recommended to always specify other as fallback in the message.
  • Some translation vendors only accept certain rules.

Available rules

enum LDML {
  zero = 'zero',
  one = 'one',
  two = 'two',
  few = 'few',
  many = 'many',
  other = 'other',
}

Example

{
  "plugins": ["formatjs"],
  "rules": {
    "formatjs/enforce-plural-rules": [
      2,
      {
        "one": true,
        "other": true,
        "zero": false
      }
    ]
  }
}

no-camel-case

This make sure placeholders are not camel-case.

Why

  • This is to prevent case-sensitivity issue in certain translation vendors.
import {defineMessages} from 'react-intl';

const messages = defineMessages({
  // WORKS
  foo: {
    defaultMessage: 'foo {snake_case} {nothing}',
  },
  // FAILS
  bar: {
    defaultMessage: 'foo {camelCase}',
  },
});

no-emoji

This prevents usage of emoji in message.

Why

  • Certain translation vendors cannot handle emojis.
  • Cross-platform encoding for emojis are faulty.
import {defineMessages} from 'react-intl';

const messages = defineMessages({
  // WORKS
  foo: {
    defaultMessage: 'Smileys & People',
  },
  // FAILS
  bar: {
    defaultMessage: '😃 Smileys & People',
  },
});

no-multiple-plurals

This prevents specifying multiple plurals in your message.

Why

  • Nested plurals are hard to translate across languages so some translation vendors don't allow it.
import {defineMessages} from 'react-intl'

const messages = defineMessages({
    // WORKS
    foo: {
        defaultMessage: '{p1, plural, one{one}}',
    },
    // FAILS
    bar: {
        defaultMessage: '{p1, plural, one{one}} {p2, plural, one{two}}',
    }
    // ALSO FAILS
    bar2: {
        defaultMessage: '{p1, plural, one{{p2, plural, one{two}}}}',
    }
})

no-offset

This prevents specifying offset in plural rules in your message.

Why

  • Offset has complicated logic implication so some translation vendors don't allow it.
import {defineMessages} from 'react-intl';

const messages = defineMessages({
  // WORKS
  foo: {
    defaultMessage: '{var, plural, one{one} other{other}}',
  },
  // FAILS
  bar: {
    defaultMessage: '{var, plural, offset:1 one{one} other{other}}',
  },
});
5.2.14

4 months ago

5.2.13

5 months ago

5.2.12

5 months ago

5.2.11

5 months ago

5.2.10

5 months ago

5.2.9

5 months ago

5.2.8

6 months ago

5.2.7

6 months ago

5.2.6

6 months ago

5.2.5

7 months ago

5.2.4

7 months ago

5.2.3

7 months ago

5.2.2

7 months ago

5.2.1

7 months ago

5.2.0

7 months ago

5.1.5

8 months ago

5.1.4

8 months ago

5.1.3

8 months ago

5.1.2

8 months ago

5.1.1

8 months ago

4.14.0

9 months ago

5.0.2

8 months ago

5.0.1

8 months ago

5.0.0

9 months ago

5.1.0

8 months ago

4.13.2

1 year ago

4.13.3

1 year ago

4.13.1

1 year ago

4.13.0

1 year ago

4.12.2

1 year ago

4.12.1

1 year ago

4.12.0

1 year ago

4.11.0

2 years ago

4.11.1

2 years ago

4.11.2

2 years ago

4.11.3

2 years ago

4.10.5

2 years ago

4.10.4

2 years ago

4.10.2

2 years ago

4.10.3

2 years ago

4.10.1

2 years ago

4.10.0

2 years ago

4.9.0

2 years ago

4.9.1

2 years ago

4.8.0

2 years ago

4.7.0

2 years ago

4.7.2

2 years ago

4.7.1

2 years ago

4.6.0

2 years ago

4.5.0

2 years ago

4.4.0

2 years ago

4.3.4

3 years ago

4.3.3

3 years ago

4.3.9

2 years ago

4.3.5

3 years ago

4.3.8

3 years ago

4.3.7

3 years ago

4.3.2

3 years ago

4.3.1

3 years ago

4.3.0

3 years ago

4.2.2

3 years ago

4.2.0

3 years ago

4.0.1

3 years ago

4.0.0

3 years ago

4.0.2

3 years ago

3.1.3

3 years ago

3.1.5

3 years ago

3.1.4

3 years ago

4.1.0

3 years ago

3.1.1

3 years ago

3.1.0

3 years ago

3.0.1

3 years ago

2.19.0

4 years ago

2.19.1

3 years ago

2.21.0

3 years ago

3.0.0

3 years ago

2.20.2

3 years ago

2.20.3

3 years ago

2.20.0

3 years ago

2.20.1

3 years ago

2.20.4

3 years ago

2.20.5

3 years ago

2.18.0

4 years ago

2.17.9

4 years ago

2.17.8

4 years ago

2.17.7

4 years ago

2.17.6

4 years ago

2.17.5

4 years ago

2.17.4

4 years ago

2.17.3

4 years ago

2.17.2

4 years ago

2.17.1

4 years ago

2.17.0

4 years ago

2.16.1

4 years ago

2.15.6

4 years ago

2.15.7

4 years ago

2.15.4

4 years ago

2.15.5

4 years ago

2.16.0

4 years ago

2.15.2

4 years ago

2.15.3

4 years ago

2.15.0

4 years ago

2.15.1

4 years ago

2.14.9

4 years ago

2.14.7

4 years ago

2.14.8

4 years ago

2.14.10

4 years ago

2.14.6

4 years ago

2.14.5

4 years ago

2.14.4

4 years ago

2.14.3

4 years ago

2.14.2

4 years ago

2.14.1

4 years ago

2.14.0

4 years ago

2.13.1

4 years ago

2.13.0

4 years ago

2.12.9

4 years ago

2.12.8

4 years ago

2.12.7

4 years ago

2.12.5

4 years ago

2.12.6

4 years ago

2.12.4

4 years ago

2.12.3

4 years ago

2.12.2

4 years ago

2.12.1

4 years ago

2.12.0

4 years ago

2.11.0

4 years ago

2.10.7

4 years ago

2.10.6

4 years ago

2.10.5

4 years ago

2.10.4

4 years ago

2.10.3

4 years ago

2.10.2

4 years ago

2.10.1

4 years ago

2.10.0

4 years ago

2.9.13

4 years ago

2.9.12

4 years ago

2.9.11

4 years ago

2.9.10

5 years ago

2.9.9

5 years ago

2.9.8

5 years ago

2.9.7

5 years ago

2.9.6

5 years ago

2.9.5

5 years ago

2.9.4

5 years ago

2.9.3

5 years ago

2.9.2

5 years ago

2.9.1

5 years ago

2.9.0

5 years ago

2.8.0

5 years ago

2.7.17

5 years ago

2.7.16

5 years ago

2.7.15

5 years ago

2.7.14

5 years ago

2.7.13

5 years ago

2.7.12

5 years ago

2.7.11

5 years ago

2.7.10

5 years ago

2.7.9

5 years ago

2.7.8

5 years ago

2.7.7

5 years ago

2.7.6

5 years ago

2.7.5

5 years ago

2.7.4

5 years ago

2.7.3

5 years ago

2.7.0

5 years ago

2.7.2

5 years ago

2.7.1

5 years ago

2.6.5

5 years ago

2.6.4

5 years ago

2.6.3

5 years ago

2.6.2

5 years ago

2.6.1

5 years ago

2.6.0

5 years ago

2.5.7

5 years ago

2.5.6

5 years ago

2.5.5

5 years ago

2.5.4

5 years ago

2.5.3

5 years ago

2.4.1-alpha.0

5 years ago

2.5.0

5 years ago

2.5.2

5 years ago

2.5.1

5 years ago

2.3.21

5 years ago

2.3.20

5 years ago

2.3.19

5 years ago

2.3.18

5 years ago

2.3.17

5 years ago

2.3.16

5 years ago

2.3.15

5 years ago

2.3.14

5 years ago

2.3.13

5 years ago

2.3.11

5 years ago

2.3.10

5 years ago

2.3.9

5 years ago

2.3.8

5 years ago

2.3.7

5 years ago

2.3.6

5 years ago

2.3.5

5 years ago

2.3.4

5 years ago

2.3.3

5 years ago

2.3.2

5 years ago

2.3.1

5 years ago

2.3.0

5 years ago

2.2.5

5 years ago

2.2.4

5 years ago

2.2.3

5 years ago

2.2.2

5 years ago

2.2.1

5 years ago

2.2.0

5 years ago

2.1.5

5 years ago

2.1.4

5 years ago

2.1.3

5 years ago

2.1.2

5 years ago

2.1.0

5 years ago

2.0.2

5 years ago

2.0.1

5 years ago

2.0.0

5 years ago

1.6.0

5 years ago

1.5.11

5 years ago

1.5.10

5 years ago

1.5.9

5 years ago

1.5.8

5 years ago

1.5.7

5 years ago

1.5.6

5 years ago

1.5.5

5 years ago

1.5.4

6 years ago

1.5.3

6 years ago

1.5.2

6 years ago

1.5.1

6 years ago

1.5.0

6 years ago

1.4.3

6 years ago

1.4.2

6 years ago

1.4.1-alpha.6

6 years ago

1.4.1

6 years ago

1.4.0

6 years ago

1.3.1

6 years ago

1.3.0

6 years ago

1.2.0

6 years ago

1.1.1

6 years ago

1.1.0

6 years ago

1.0.2

6 years ago