5.2.14 • Published 6 months ago

eslint-plugin-formatjs v5.2.14

Weekly downloads
21,801
License
MIT
Repository
github
Last release
6 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

6 months ago

5.2.13

7 months ago

5.2.12

7 months ago

5.2.11

7 months ago

5.2.10

7 months ago

5.2.9

7 months ago

5.2.8

8 months ago

5.2.7

8 months ago

5.2.6

8 months ago

5.2.5

9 months ago

5.2.4

9 months ago

5.2.3

9 months ago

5.2.2

9 months ago

5.2.1

9 months ago

5.2.0

9 months ago

5.1.5

10 months ago

5.1.4

10 months ago

5.1.3

10 months ago

5.1.2

10 months ago

5.1.1

10 months ago

4.14.0

11 months ago

5.0.2

10 months ago

5.0.1

10 months ago

5.0.0

11 months ago

5.1.0

10 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

2 years ago

4.12.1

2 years ago

4.12.0

2 years 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

3 years ago

4.5.0

3 years ago

4.4.0

3 years ago

4.3.4

3 years ago

4.3.3

3 years ago

4.3.9

3 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

4 years ago

2.21.0

4 years ago

3.0.0

4 years ago

2.20.2

4 years ago

2.20.3

4 years ago

2.20.0

4 years ago

2.20.1

4 years ago

2.20.4

4 years ago

2.20.5

4 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

5 years ago

2.11.0

5 years ago

2.10.7

5 years ago

2.10.6

5 years ago

2.10.5

5 years ago

2.10.4

5 years ago

2.10.3

5 years ago

2.10.2

5 years ago

2.10.1

5 years ago

2.10.0

5 years ago

2.9.13

5 years ago

2.9.12

5 years ago

2.9.11

5 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

6 years ago

1.5.10

6 years ago

1.5.9

6 years ago

1.5.8

6 years ago

1.5.7

6 years ago

1.5.6

6 years ago

1.5.5

6 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