Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eslint-plugin-formatjs

Package Overview
Dependencies
Maintainers
3
Versions
236
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-formatjs - npm Package Compare versions

Comparing version 4.11.3 to 4.12.0

26

index.d.ts

@@ -1,24 +0,4 @@

declare const plugin: {
rules: {
'blocklist-elements': import("eslint").Rule.RuleModule;
'enforce-default-message': import("eslint").Rule.RuleModule;
'enforce-description': import("eslint").Rule.RuleModule;
'enforce-id': import("eslint").Rule.RuleModule;
'enforce-placeholders': import("eslint").Rule.RuleModule;
'enforce-plural-rules': import("eslint").Rule.RuleModule;
'no-camel-case': import("eslint").Rule.RuleModule;
'no-complex-selectors': import("eslint").Rule.RuleModule;
'no-emoji': import("eslint").Rule.RuleModule;
'no-id': import("eslint").Rule.RuleModule;
'no-invalid-icu': import("eslint").Rule.RuleModule;
'no-literal-string-in-jsx': import("eslint").Rule.RuleModule;
'no-multiple-plurals': import("eslint").Rule.RuleModule;
'no-multiple-whitespaces': import("eslint").Rule.RuleModule;
'no-offset': import("eslint").Rule.RuleModule;
'no-useless-message': import("eslint").Rule.RuleModule;
'prefer-formatted-message': import("eslint").Rule.RuleModule;
'prefer-pound-in-plural': import("eslint").Rule.RuleModule;
};
import { RuleModule } from '@typescript-eslint/utils/ts-eslint';
export type Plugin = {
rules: Record<string, RuleModule<string, readonly unknown[]>>;
};
export type Plugin = typeof plugin;
export {};

73

index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const blocklist_elements_1 = tslib_1.__importDefault(require("./rules/blocklist-elements"));
const enforce_default_message_1 = tslib_1.__importDefault(require("./rules/enforce-default-message"));
const enforce_description_1 = tslib_1.__importDefault(require("./rules/enforce-description"));
const enforce_id_1 = tslib_1.__importDefault(require("./rules/enforce-id"));
const enforce_placeholders_1 = tslib_1.__importDefault(require("./rules/enforce-placeholders"));
const no_invalid_icu_1 = tslib_1.__importDefault(require("./rules/no-invalid-icu"));
const enforce_plural_rules_1 = tslib_1.__importDefault(require("./rules/enforce-plural-rules"));
const no_camel_case_1 = tslib_1.__importDefault(require("./rules/no-camel-case"));
const no_complex_selectors_1 = tslib_1.__importDefault(require("./rules/no-complex-selectors"));
const no_emoji_1 = tslib_1.__importDefault(require("./rules/no-emoji"));
const no_id_1 = tslib_1.__importDefault(require("./rules/no-id"));
const no_multiple_plurals_1 = tslib_1.__importDefault(require("./rules/no-multiple-plurals"));
const no_multiple_whitespaces_1 = tslib_1.__importDefault(require("./rules/no-multiple-whitespaces"));
const no_offset_1 = tslib_1.__importDefault(require("./rules/no-offset"));
const no_literal_string_in_jsx_1 = tslib_1.__importDefault(require("./rules/no-literal-string-in-jsx"));
const no_useless_message_1 = tslib_1.__importDefault(require("./rules/no-useless-message"));
const prefer_formatted_message_1 = tslib_1.__importDefault(require("./rules/prefer-formatted-message"));
const prefer_pound_in_plural_1 = tslib_1.__importDefault(require("./rules/prefer-pound-in-plural"));
const blocklist_elements_1 = require("./rules/blocklist-elements");
const enforce_default_message_1 = require("./rules/enforce-default-message");
const enforce_description_1 = require("./rules/enforce-description");
const enforce_id_1 = require("./rules/enforce-id");
const enforce_placeholders_1 = require("./rules/enforce-placeholders");
const no_invalid_icu_1 = require("./rules/no-invalid-icu");
const enforce_plural_rules_1 = require("./rules/enforce-plural-rules");
const no_camel_case_1 = require("./rules/no-camel-case");
const no_complex_selectors_1 = require("./rules/no-complex-selectors");
const no_emoji_1 = require("./rules/no-emoji");
const no_id_1 = require("./rules/no-id");
const no_multiple_plurals_1 = require("./rules/no-multiple-plurals");
const no_multiple_whitespaces_1 = require("./rules/no-multiple-whitespaces");
const no_offset_1 = require("./rules/no-offset");
const no_literal_string_in_jsx_1 = require("./rules/no-literal-string-in-jsx");
const no_useless_message_1 = require("./rules/no-useless-message");
const prefer_formatted_message_1 = require("./rules/prefer-formatted-message");
const prefer_pound_in_plural_1 = require("./rules/prefer-pound-in-plural");
const plugin = {
rules: {
'blocklist-elements': blocklist_elements_1.default,
'enforce-default-message': enforce_default_message_1.default,
'enforce-description': enforce_description_1.default,
'enforce-id': enforce_id_1.default,
'enforce-placeholders': enforce_placeholders_1.default,
'enforce-plural-rules': enforce_plural_rules_1.default,
'no-camel-case': no_camel_case_1.default,
'no-complex-selectors': no_complex_selectors_1.default,
'no-emoji': no_emoji_1.default,
'no-id': no_id_1.default,
'no-invalid-icu': no_invalid_icu_1.default,
'no-literal-string-in-jsx': no_literal_string_in_jsx_1.default,
'no-multiple-plurals': no_multiple_plurals_1.default,
'no-multiple-whitespaces': no_multiple_whitespaces_1.default,
'no-offset': no_offset_1.default,
'no-useless-message': no_useless_message_1.default,
'prefer-formatted-message': prefer_formatted_message_1.default,
'prefer-pound-in-plural': prefer_pound_in_plural_1.default,
[blocklist_elements_1.name]: blocklist_elements_1.rule,
[enforce_default_message_1.name]: enforce_default_message_1.rule,
[enforce_description_1.name]: enforce_description_1.rule,
[enforce_id_1.name]: enforce_id_1.rule,
[enforce_placeholders_1.name]: enforce_placeholders_1.rule,
[enforce_plural_rules_1.name]: enforce_plural_rules_1.rule,
[no_camel_case_1.name]: no_camel_case_1.rule,
[no_complex_selectors_1.name]: no_complex_selectors_1.rule,
[no_emoji_1.name]: no_emoji_1.rule,
[no_id_1.name]: no_id_1.rule,
[no_invalid_icu_1.name]: no_invalid_icu_1.rule,
[no_literal_string_in_jsx_1.name]: no_literal_string_in_jsx_1.rule,
[no_multiple_plurals_1.name]: no_multiple_plurals_1.rule,
[no_multiple_whitespaces_1.name]: no_multiple_whitespaces_1.rule,
[no_offset_1.name]: no_offset_1.rule,
[no_useless_message_1.name]: no_useless_message_1.rule,
[prefer_formatted_message_1.name]: prefer_formatted_message_1.rule,
[prefer_pound_in_plural_1.name]: prefer_pound_in_plural_1.rule,
},
};
module.exports = plugin;
{
"name": "eslint-plugin-formatjs",
"version": "4.11.3",
"version": "4.12.0",
"description": "ESLint plugin for formatjs",

@@ -25,3 +25,3 @@ "main": "index.js",

"@types/picomatch": "^2.3.0",
"@typescript-eslint/utils": "^6.5.0",
"@typescript-eslint/utils": "^6.18.1",
"emoji-regex": "^10.2.1",

@@ -32,5 +32,5 @@ "magic-string": "^0.30.0",

"typescript": "5",
"unicode-emoji-utils": "^1.1.1",
"@formatjs/icu-messageformat-parser": "2.7.3",
"@formatjs/ts-transformer": "3.13.9"
"unicode-emoji-utils": "^1.2.0",
"@formatjs/ts-transformer": "3.13.10",
"@formatjs/icu-messageformat-parser": "2.7.4"
},

@@ -37,0 +37,0 @@ "peerDependencies": {

@@ -1,3 +0,17 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type MessageIds = 'blocklist';
type Options = [Element[]?];
export declare const name = "blocklist-elements";
export declare enum Element {
literal = "literal",
argument = "argument",
number = "number",
date = "date",
time = "time",
select = "select",
selectordinal = "selectordinal",
plural = "plural",
tag = "tag"
}
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.Element = exports.name = void 0;
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
const util_1 = require("../util");
class BlacklistElement extends Error {
constructor(type) {
super();
this.message = `${type} element is blocklisted`;
}
exports.name = 'blocklist-elements';
function getMessage(type) {
return {
messageId: 'blocklist',
data: { type },
};
}

@@ -22,33 +24,34 @@ var Element;

Element["tag"] = "tag";
})(Element || (Element = {}));
})(Element || (exports.Element = Element = {}));
function verifyAst(blocklist, ast) {
const errors = [];
for (const el of ast) {
if ((0, icu_messageformat_parser_1.isLiteralElement)(el) && blocklist.includes(Element.literal)) {
throw new BlacklistElement(Element.literal);
errors.push(getMessage(Element.literal));
}
if ((0, icu_messageformat_parser_1.isArgumentElement)(el) && blocklist.includes(Element.argument)) {
throw new BlacklistElement(Element.argument);
errors.push(getMessage(Element.argument));
}
if ((0, icu_messageformat_parser_1.isNumberElement)(el) && blocklist.includes(Element.number)) {
throw new BlacklistElement(Element.number);
errors.push(getMessage(Element.number));
}
if ((0, icu_messageformat_parser_1.isDateElement)(el) && blocklist.includes(Element.date)) {
throw new BlacklistElement(Element.date);
errors.push(getMessage(Element.date));
}
if ((0, icu_messageformat_parser_1.isTimeElement)(el) && blocklist.includes(Element.time)) {
throw new BlacklistElement(Element.time);
errors.push(getMessage(Element.time));
}
if ((0, icu_messageformat_parser_1.isSelectElement)(el) && blocklist.includes(Element.select)) {
throw new BlacklistElement(Element.select);
errors.push(getMessage(Element.select));
}
if ((0, icu_messageformat_parser_1.isTagElement)(el) && blocklist.includes(Element.tag)) {
throw new BlacklistElement(Element.tag);
errors.push(getMessage(Element.tag));
}
if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
if (blocklist.includes(Element.plural)) {
throw new BlacklistElement(Element.argument);
errors.push(getMessage(Element.argument));
}
if (el.pluralType === 'ordinal' &&
blocklist.includes(Element.selectordinal)) {
throw new BlacklistElement(Element.selectordinal);
errors.push(getMessage(Element.selectordinal));
}

@@ -63,2 +66,3 @@ }

}
return errors;
}

@@ -79,11 +83,9 @@ function checkNode(context, node) {

}
try {
verifyAst(context.options[0], (0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
}
catch (e) {
const errors = verifyAst(blocklist, (0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
for (const error of errors) {
context.report({
node: messageNode,
message: e instanceof Error ? e.message : String(e),
node,
...error,
});

@@ -93,3 +95,19 @@ }

}
const rule = {
const create = (context) => {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices?.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({
CallExpression: callExpressionVisitor,
}, {
CallExpression: callExpressionVisitor,
});
}
return {
JSXOpeningElement: (node) => checkNode(context, node),
CallExpression: callExpressionVisitor,
};
};
exports.rule = {
meta: {

@@ -99,4 +117,2 @@ type: 'problem',

description: 'Disallow specific elements in ICU message format',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#blocklist-elements',

@@ -108,26 +124,14 @@ },

type: 'array',
properties: {
items: {
type: 'string',
enum: Object.keys(Element),
},
items: {
type: 'string',
enum: Object.keys(Element),
},
},
],
messages: {
blocklist: `{{type}} element is blocklisted`,
},
},
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
if (context.parserServices.defineTemplateBodyVisitor) {
return context.parserServices.defineTemplateBodyVisitor({
CallExpression: callExpressionVisitor,
}, {
CallExpression: callExpressionVisitor,
});
}
return {
JSXOpeningElement: (node) => checkNode(context, node),
CallExpression: callExpressionVisitor,
};
},
defaultOptions: [],
create,
};
exports.default = rule;

@@ -1,3 +0,10 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
export declare enum Option {
literal = "literal",
anything = "anything"
}
type MessageIds = 'defaultMessage' | 'defaultMessageLiteral';
type Options = [`${Option}`?];
export declare const name = "enforce-default-message";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = exports.Option = void 0;
const util_1 = require("../util");
var Option;
(function (Option) {
Option["literal"] = "literal";
Option["anything"] = "anything";
})(Option || (exports.Option = Option = {}));
exports.name = 'enforce-default-message';
function checkNode(context, node) {

@@ -12,5 +19,3 @@ const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));

node: messageNode,
message: `"defaultMessage" must be:
- a string literal or
- template literal without variable`,
messageId: 'defaultMessageLiteral',
});

@@ -21,3 +26,3 @@ }

node: node,
message: '`defaultMessage` has to be specified in message descriptor',
messageId: 'defaultMessage',
});

@@ -28,3 +33,3 @@ }

}
const rule = {
exports.rule = {
meta: {

@@ -34,4 +39,2 @@ type: 'problem',

description: 'Enforce defaultMessage in message descriptor',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#enforce-default-message',

@@ -42,9 +45,19 @@ },

{
enum: ['literal', 'anything'],
type: 'string',
enum: Object.keys(Option),
},
],
messages: {
defaultMessageLiteral: `"defaultMessage" must be:
- a string literal or
- template literal without variable`,
defaultMessage: '`defaultMessage` has to be specified in message descriptor',
},
},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -62,2 +75,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;

@@ -1,3 +0,10 @@

import { Rule } from 'eslint';
declare const _default: Rule.RuleModule;
export default _default;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
export declare enum Option {
literal = "literal",
anything = "anything"
}
type MessageIds = 'enforceDescription' | 'enforceDescriptionLiteral';
type Options = [`${Option}`?];
export declare const name = "enforce-description";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = exports.Option = void 0;
const util_1 = require("../util");
var Option;
(function (Option) {
Option["literal"] = "literal";
Option["anything"] = "anything";
})(Option || (exports.Option = Option = {}));
function checkNode(context, node) {

@@ -12,3 +18,3 @@ const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));

node: descriptionNode,
message: '`description` has to be a string literal (not function call or variable)',
messageId: 'enforceDescriptionLiteral',
});

@@ -19,3 +25,3 @@ }

node: node,
message: '`description` has to be specified in message descriptor',
messageId: 'enforceDescription',
});

@@ -26,3 +32,4 @@ }

}
exports.default = {
exports.name = 'enforce-description';
exports.rule = {
meta: {

@@ -32,4 +39,2 @@ type: 'problem',

description: 'Enforce description in message descriptor',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#enforce-description',

@@ -40,9 +45,17 @@ },

{
enum: ['literal', 'anything'],
type: 'string',
enum: Object.keys(Option),
},
],
messages: {
enforceDescription: '`description` has to be specified in message descriptor',
enforceDescriptionLiteral: '`description` has to be a string literal (not function call or variable)',
},
},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -49,0 +62,0 @@ CallExpression: callExpressionVisitor,

@@ -1,3 +0,10 @@

import { Rule } from 'eslint';
declare const _default: Rule.RuleModule;
export default _default;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
export type Option = {
idInterpolationPattern: string;
idWhitelist?: string[];
};
type MessageIds = 'enforceId' | 'enforceIdDefaultMessage' | 'enforceIdDescription' | 'enforceIdMatching' | 'enforceIdMatchingAllowlisted';
type Options = [Option];
export declare const name = "enforce-id";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const ts_transformer_1 = require("@formatjs/ts-transformer");
const util_1 = require("../util");
function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps }) {
function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps, }) {
const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));

@@ -10,4 +11,4 @@ for (const [{ message: { defaultMessage, description, id }, idPropNode, descriptionNode, messagePropNode, },] of msgs) {

context.report({
node: node,
message: `id must be specified`,
node,
messageId: 'enforceId',
});

@@ -18,4 +19,4 @@ }

context.report({
node: node,
message: `defaultMessage must be a string literal to calculate generated IDs`,
node,
messageId: 'enforceIdDefaultMessage',
});

@@ -25,4 +26,4 @@ }

context.report({
node: node,
message: `description must be a string literal to calculate generated IDs`,
node,
messageId: 'enforceIdDescription',
});

@@ -45,13 +46,21 @@ }

if (id !== correctId) {
let message = `"id" does not match with hash pattern ${idInterpolationPattern}`;
let messageId = 'enforceIdMatching';
let messageData = {
idInterpolationPattern,
expected: correctId,
actual: id,
};
if (idWhitelistRegexps) {
message += ` or allowlisted patterns ["${idWhitelistRegexps
.map(r => r.toString())
.join('", "')}"]`;
messageId = 'enforceIdMatchingAllowlisted';
messageData = {
...messageData,
idWhitelist: idWhitelistRegexps
.map(r => `"${r.toString()}"`)
.join(', '),
};
}
context.report({
node: node,
message: `${message}.
Expected: ${correctId}
Actual: ${id}`,
node,
messageId,
data: messageData,
fix(fixer) {

@@ -64,7 +73,10 @@ if (idPropNode) {

}
// Insert after default message node
if (messagePropNode.type === 'JSXAttribute') {
return fixer.insertTextAfter(messagePropNode, ` id="${correctId}"`);
if (messagePropNode) {
// Insert after default message node
if (messagePropNode.type === 'JSXAttribute') {
return fixer.insertTextAfter(messagePropNode, ` id="${correctId}"`);
}
return fixer.insertTextAfter(messagePropNode, `, id: '${correctId}'`);
}
return fixer.insertTextAfter(messagePropNode, `, id: '${correctId}'`);
return null;
},

@@ -77,3 +89,4 @@ });

}
exports.default = {
exports.name = 'enforce-id';
exports.rule = {
meta: {

@@ -83,4 +96,2 @@ type: 'problem',

description: 'Enforce (generated) ID in message descriptor',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#enforce-id',

@@ -109,6 +120,22 @@ },

],
messages: {
enforceId: `id must be specified`,
enforceIdDefaultMessage: `defaultMessage must be a string literal to calculate generated IDs`,
enforceIdDescription: `description must be a string literal to calculate generated IDs`,
enforceIdMatching: `"id" does not match with hash pattern {{idInterpolationPattern}}.
Expected: {{expected}}
Actual: {{actual}}`,
enforceIdMatchingAllowlisted: `"id" does not match with hash pattern {{idInterpolationPattern}} or allowlisted patterns {{idWhitelist}}.
Expected: {{expected}}
Actual: {{actual}}`,
},
},
defaultOptions: [
{
idInterpolationPattern: '[sha512:contenthash:base64:6]',
},
],
create(context) {
const tmp = context?.options?.[0];
const opts = {
const tmp = context.options[0];
let opts = {
idInterpolationPattern: tmp?.idInterpolationPattern,

@@ -121,3 +148,5 @@ };

const callExpressionVisitor = (node) => checkNode(context, node, opts);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -124,0 +153,0 @@ CallExpression: callExpressionVisitor,

@@ -1,3 +0,8 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type MessageIds = 'parserError' | 'missingValue' | 'unusedValue';
type Options = [{
ignoreList: string[];
}?];
export declare const name = "enforce-placeholders";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");

@@ -71,3 +72,4 @@ const util_1 = require("../util");

node: messageNode,
message: e instanceof Error ? e.message : String(e),
messageId: 'parserError',
data: { message: e instanceof Error ? e.message : String(e) },
});

@@ -86,3 +88,6 @@ continue;

node: messageNode,
message: `Missing value(s) for the following placeholder(s): ${missingPlaceholders.join(', ')}.`,
messageId: 'missingValue',
data: {
list: missingPlaceholders.join(', '),
},
});

@@ -94,3 +99,3 @@ }

node: element,
message: 'Value not used by the message.',
messageId: 'unusedValue',
});

@@ -101,3 +106,4 @@ }

}
const rule = {
exports.name = 'enforce-placeholders';
exports.rule = {
meta: {

@@ -107,4 +113,2 @@ type: 'problem',

description: 'Enforce that all messages with placeholders have enough passed-in values',
category: 'Errors',
recommended: true,
url: 'https://formatjs.io/docs/tooling/linter#enforce-placeholders',

@@ -126,6 +130,14 @@ },

],
messages: {
parserError: '{{message}}',
missingValue: 'Missing value(s) for the following placeholder(s): {{list}}.',
unusedValue: 'Value not used by the message.',
},
},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -143,2 +155,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;

@@ -1,3 +0,17 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
declare enum LDML {
zero = "zero",
one = "one",
two = "two",
few = "few",
many = "many",
other = "other"
}
type PluralConfig = {
[key in LDML]?: boolean;
};
export type Options = [PluralConfig?];
type MessageIds = 'missingPlural' | 'forbidden';
export declare const name = "enforce-plural-rules";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
const util_1 = require("../util");
class PluralRulesEnforcement extends Error {
constructor(message) {
super();
this.message = message;
}
}
var LDML;

@@ -21,2 +16,3 @@ (function (LDML) {

function verifyAst(plConfig, ast) {
const errors = [];
for (const el of ast) {

@@ -27,6 +23,6 @@ if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {

if (plConfig[rule] && !el.options[rule]) {
throw new PluralRulesEnforcement(`Missing plural rule "${rule}"`);
errors.push({ messageId: 'missingPlural', data: { rule } });
}
if (!plConfig[rule] && el.options[rule]) {
throw new PluralRulesEnforcement(`Plural rule "${rule}" is forbidden`);
errors.push({ messageId: 'forbidden', data: { rule } });
}

@@ -36,6 +32,7 @@ }

for (const selector of Object.keys(options)) {
verifyAst(plConfig, options[selector].value);
errors.push(...verifyAst(plConfig, options[selector].value));
}
}
}
return errors;
}

@@ -56,11 +53,9 @@ function checkNode(context, node) {

}
try {
verifyAst(context.options[0], (0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
}
catch (e) {
const errors = verifyAst(plConfig, (0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
for (const error of errors) {
context.report({
node: messageNode,
message: e instanceof Error ? e.message : String(e),
...error,
});

@@ -70,3 +65,4 @@ }

}
const rule = {
exports.name = 'enforce-plural-rules';
exports.rule = {
meta: {

@@ -76,4 +72,2 @@ type: 'problem',

description: 'Enforce plural rules to always specify certain categories like `one`/`other`',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#enforce-plural-rules',

@@ -94,6 +88,13 @@ },

],
messages: {
missingPlural: `Missing plural rule "{{rule}}"`,
forbidden: `Plural rule "{{rule}}" is forbidden`,
},
},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -111,2 +112,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;

@@ -1,3 +0,6 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type MessageIds = 'camelcase';
type Options = [Element[]?];
export declare const name = "no-camel-case";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
const util_1 = require("../util");
exports.name = 'no-camel-case';
const CAMEL_CASE_REGEX = /[A-Z]/;
class CamelCase extends Error {
constructor() {
super(...arguments);
this.message = 'Camel case arguments are not allowed';
}
}
function verifyAst(ast) {
const errors = [];
for (const el of ast) {
if ((0, icu_messageformat_parser_1.isArgumentElement)(el)) {
if (CAMEL_CASE_REGEX.test(el.value)) {
throw new CamelCase();
errors.push({ messageId: 'camelcase', data: {} });
}

@@ -22,10 +19,11 @@ continue;

if (CAMEL_CASE_REGEX.test(el.value)) {
throw new CamelCase();
errors.push({ messageId: 'camelcase', data: {} });
}
const { options } = el;
for (const selector of Object.keys(options)) {
verifyAst(options[selector].value);
errors.push(...verifyAst(options[selector].value));
}
}
}
return errors;
}

@@ -39,11 +37,9 @@ function checkNode(context, node) {

}
try {
verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
}
catch (e) {
const errors = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
for (const error of errors) {
context.report({
node: messageNode,
message: e instanceof Error ? e.message : String(e),
...error,
});

@@ -53,3 +49,3 @@ }

}
const rule = {
exports.rule = {
meta: {

@@ -59,11 +55,16 @@ type: 'problem',

description: 'Disallow camel case placeholders in message',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#no-camel-case',
},
fixable: 'code',
schema: [],
messages: {
camelcase: 'Camel case arguments are not allowed',
},
},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -81,2 +82,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;

@@ -1,3 +0,9 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
interface Config {
limit: number;
}
type MessageIds = 'tooComplex' | 'parserError';
type Options = [Config?];
export declare const name = "no-complex-selectors";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");

@@ -68,20 +69,16 @@ const util_1 = require("../util");

node: messageNode,
message: e instanceof Error ? e.message : String(e),
messageId: 'parserError',
data: { message: e instanceof Error ? e.message : String(e) },
});
return;
}
let complexity = 0;
try {
complexity = calculateComplexity(ast);
}
catch (e) {
context.report({
node: messageNode,
message: e instanceof Error ? e.message : e,
});
}
const complexity = calculateComplexity(ast);
if (complexity > config.limit) {
context.report({
node: messageNode,
message: `Message complexity is too high (${complexity} vs limit at ${config.limit})`,
messageId: 'tooComplex',
data: {
complexity,
limit: config.limit,
},
});

@@ -91,3 +88,4 @@ }

}
const rule = {
exports.name = 'no-complex-selectors';
exports.rule = {
meta: {

@@ -105,4 +103,2 @@ type: 'problem',

`,
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#no-complex-selectors',

@@ -122,6 +118,13 @@ },

fixable: 'code',
messages: {
tooComplex: `Message complexity is too high ({{complexity}} vs limit at {{limit}})`,
parserError: '{{meesage}}',
},
},
defaultOptions: [{ limit: 20 }],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -139,2 +142,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;

@@ -1,3 +0,9 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
export declare const name = "no-emoji";
type MessageIds = 'notAllowed' | 'notAllowedAboveVersion';
type NoEmojiConfig = {
versionAbove: string;
};
export type Options = [NoEmojiConfig?];
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const unicode_emoji_utils_1 = require("unicode-emoji-utils");
const util_1 = require("../util");
exports.name = 'no-emoji';
function checkNode(context, node) {

@@ -61,3 +63,3 @@ const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));

];
const rule = {
exports.rule = {
meta: {

@@ -67,4 +69,2 @@ type: 'problem',

description: 'Disallow emojis in message',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#no-emoji',

@@ -85,5 +85,8 @@ },

},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -101,2 +104,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;

@@ -1,3 +0,6 @@

import { Rule } from 'eslint';
declare const _default: Rule.RuleModule;
export default _default;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type MessageIds = 'noId';
type Options = [];
export declare const name = "no-id";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const util_1 = require("../util");

@@ -7,2 +8,3 @@ function isComment(token) {

}
exports.name = 'no-id';
function checkNode(context, node) {

@@ -14,3 +16,3 @@ const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));

node: idPropNode,
message: 'Manual `id` are not allowed in message descriptor',
messageId: 'noId',
fix(fixer) {

@@ -29,3 +31,3 @@ const src = context.getSourceCode();

}
exports.default = {
exports.rule = {
meta: {

@@ -35,11 +37,16 @@ type: 'problem',

description: 'Ban explicit ID from MessageDescriptor',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#no-id',
},
fixable: 'code',
schema: [],
messages: {
noId: 'Manual `id` are not allowed in message descriptor',
},
},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -46,0 +53,0 @@ CallExpression: callExpressionVisitor,

@@ -1,3 +0,6 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type MessageIds = 'icuError';
type Options = [];
export declare const name = "no-invalid-icu";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
const util_1 = require("../util");
exports.name = 'no-invalid-icu';
function checkNode(context, node) {

@@ -24,3 +26,4 @@ const settings = (0, util_1.getSettings)(context);

node: messageNode,
message: `Error parsing ICU string: ${msg}`,
messageId: 'icuError',
data: { message: `Error parsing ICU string: ${msg}` },
});

@@ -30,3 +33,3 @@ }

}
const rule = {
exports.rule = {
meta: {

@@ -36,10 +39,15 @@ type: 'problem',

description: `Make sure ICU messages are formatted correctly with no bad select statements, plurals, etc.`,
category: 'Errors',
recommended: true,
},
fixable: 'code',
schema: [],
messages: {
icuError: 'Invalid ICU Message format: {{message}}',
},
},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -57,2 +65,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;

@@ -1,3 +0,13 @@

import type { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type PropMatcher = readonly [TagNamePattern: string, PropNamePattern: string][];
type Config = {
props?: {
include?: PropMatcher;
exclude?: PropMatcher;
};
};
type MessageIds = 'noLiteralStringInJsx';
type Options = [Config?];
export declare const name = "no-literal-string-in-jsx";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const tslib_1 = require("tslib");

@@ -37,3 +38,4 @@ const utils_1 = require("@typescript-eslint/utils");

}
const rule = {
exports.name = 'no-literal-string-in-jsx';
exports.rule = {
meta: {

@@ -43,4 +45,2 @@ type: 'problem',

description: 'Disallow untranslated literal strings without translation.',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#no-literal-string-in-jsx',

@@ -66,3 +66,7 @@ },

],
messages: {
noLiteralStringInJsx: 'Cannot have untranslated text in JSX',
},
},
defaultOptions: [],
// TODO: Vue support

@@ -115,3 +119,3 @@ create(context) {

node: node,
message: 'Cannot have untranslated text in JSX',
messageId: 'noLiteralStringInJsx',
});

@@ -157,3 +161,3 @@ }

node: node,
message: 'Cannot have untranslated text in JSX',
messageId: 'noLiteralStringInJsx',
});

@@ -173,3 +177,3 @@ }

node: node,
message: 'Cannot have untranslated text in JSX',
messageId: 'noLiteralStringInJsx',
});

@@ -186,2 +190,1 @@ },

};
exports.default = rule;

@@ -1,3 +0,6 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type MessageIds = 'noMultiplePlurals';
type Options = [];
export declare const name = "no-multiple-plurals";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
const util_1 = require("../util");
class MultiplePlurals extends Error {
constructor() {
super(...arguments);
this.message = 'Cannot specify more than 1 plural rules';
}
}
function verifyAst(ast, pluralCount = { count: 0 }) {
const errors = [];
for (const el of ast) {

@@ -16,10 +12,11 @@ if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {

if (pluralCount.count > 1) {
throw new MultiplePlurals();
errors.push({ messageId: 'noMultiplePlurals', data: {} });
}
const { options } = el;
for (const selector of Object.keys(options)) {
verifyAst(options[selector].value, pluralCount);
errors.push(...verifyAst(options[selector].value, pluralCount));
}
}
}
return errors;
}

@@ -33,11 +30,9 @@ function checkNode(context, node) {

}
try {
verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
}
catch (e) {
const errors = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
for (const error of errors) {
context.report({
node: messageNode,
message: e instanceof Error ? e.message : String(e),
node,
...error,
});

@@ -47,3 +42,4 @@ }

}
const rule = {
exports.name = 'no-multiple-plurals';
exports.rule = {
meta: {

@@ -53,11 +49,16 @@ type: 'problem',

description: 'Disallow multiple plural rules in the same message',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#no-multiple-plurals',
},
fixable: 'code',
schema: [],
messages: {
noMultiplePlurals: 'Multiple plural rules in the same message',
},
},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -75,2 +76,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;

@@ -1,3 +0,6 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type MessageIds = 'noMultipleWhitespaces' | 'parserError';
type Options = [];
export declare const name = "no-multiple-whitespaces";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");

@@ -92,3 +93,4 @@ const util_1 = require("../util");

node: messageNode,
message: e instanceof Error ? e.message : String(e),
messageId: 'parserError',
data: { message: e instanceof Error ? e.message : String(e) },
});

@@ -109,3 +111,4 @@ return;

}
const rule = {
exports.name = 'no-multiple-whitespaces';
exports.rule = {
meta: {

@@ -115,4 +118,2 @@ type: 'problem',

description: 'Prevents usage of multiple consecutive whitespaces in message',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#no-multiple-whitespaces',

@@ -122,8 +123,13 @@ },

noMultipleWhitespaces: 'Multiple consecutive whitespaces are not allowed',
parserError: '{{message}}',
},
fixable: 'code',
schema: [],
},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -141,2 +147,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;

@@ -1,3 +0,6 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type MessageIds = 'noOffset';
type Options = [];
export declare const name = "no-offset";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
const util_1 = require("../util");
class NoOffsetError extends Error {
constructor() {
super(...arguments);
this.message = 'offset are not allowed in plural rules';
}
}
function verifyAst(ast) {
const errors = [];
for (const el of ast) {
if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
if (el.offset) {
throw new NoOffsetError();
errors.push({ messageId: 'noOffset', data: {} });
}
const { options } = el;
for (const selector of Object.keys(options)) {
verifyAst(options[selector].value);
errors.push(...verifyAst(options[selector].value));
}
}
}
return errors;
}

@@ -31,11 +28,9 @@ function checkNode(context, node) {

}
try {
verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
}
catch (e) {
const errors = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
for (const error of errors) {
context.report({
node: messageNode,
message: e.message,
...error,
});

@@ -45,3 +40,4 @@ }

}
const rule = {
exports.name = 'no-offset';
exports.rule = {
meta: {

@@ -51,11 +47,16 @@ type: 'problem',

description: 'Disallow offset in plural rules',
category: 'Errors',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#no-offset',
},
fixable: 'code',
messages: {
noOffset: 'offset is not allowed',
},
schema: [],
},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -73,2 +74,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;

@@ -1,3 +0,6 @@

import { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type MessageIds = 'unnecessaryFormat' | 'unnecessaryFormatNumber' | 'unnecessaryFormatDate' | 'unnecessaryFormatTime';
type Options = [];
export declare const name = "no-useless-message";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
const util_1 = require("../util");
class JustArgument extends Error {
constructor() {
super(...arguments);
this.message = 'Unnecessary formatted message.';
}
}
class JustNumber extends Error {
constructor() {
super(...arguments);
this.message = 'Unnecessary formatted message: just use FormattedNumber or intl.formatNumber.';
}
}
class JustDate extends Error {
constructor() {
super(...arguments);
this.message = 'Unnecessary formatted message: just use FormattedDate or intl.formatDate.';
}
}
class JustTime extends Error {
constructor() {
super(...arguments);
this.message = 'Unnecessary formatted message: just use FormattedTime or intl.formatTime.';
}
}
function verifyAst(ast) {

@@ -35,9 +12,9 @@ if (ast.length !== 1) {

case icu_messageformat_parser_1.TYPE.argument:
throw new JustArgument();
return 'unnecessaryFormat';
case icu_messageformat_parser_1.TYPE.number:
throw new JustNumber();
return 'unnecessaryFormatNumber';
case icu_messageformat_parser_1.TYPE.date:
throw new JustDate();
return 'unnecessaryFormatDate';
case icu_messageformat_parser_1.TYPE.time:
throw new JustTime();
return 'unnecessaryFormatTime';
}

@@ -52,16 +29,14 @@ }

}
try {
verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
}
catch (e) {
const messageId = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
ignoreTag: settings.ignoreTag,
}));
if (messageId)
context.report({
node: messageNode,
message: e instanceof Error ? e.message : String(e),
messageId,
});
}
}
}
const rule = {
exports.name = 'no-useless-message';
exports.rule = {
meta: {

@@ -71,10 +46,20 @@ type: 'problem',

description: 'Disallow unnecessary formatted message',
recommended: true,
recommended: 'recommended',
url: 'https://formatjs.io/docs/tooling/linter#no-useless-message',
},
fixable: 'code',
schema: [],
messages: {
unnecessaryFormat: 'Unnecessary formatted message.',
unnecessaryFormatNumber: 'Unnecessary formatted message: just use FormattedNumber or intl.formatNumber.',
unnecessaryFormatDate: 'Unnecessary formatted message: just use FormattedDate or intl.formatDate.',
unnecessaryFormatTime: 'Unnecessary formatted message: just use FormattedTime or intl.formatTime.',
},
},
defaultOptions: [],
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -92,2 +77,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;

@@ -1,3 +0,6 @@

import type { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type MessageIds = 'jsxChildren';
type Options = [];
export declare const name = "prefer-formatted-message";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const util_1 = require("../util");
const rule = {
exports.name = 'prefer-formatted-message';
exports.rule = {
meta: {

@@ -9,3 +11,2 @@ type: 'suggestion',

description: 'Prefer `FormattedMessage` component over `intl.formatMessage` if applicable.',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#prefer-formatted-message',

@@ -16,3 +17,5 @@ },

},
schema: [],
},
defaultOptions: [],
// TODO: Vue support

@@ -36,2 +39,1 @@ create(context) {

};
exports.default = rule;

@@ -1,3 +0,6 @@

import type { Rule } from 'eslint';
declare const rule: Rule.RuleModule;
export default rule;
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
type MessageIds = 'preferPoundInPlurals' | 'parseError';
type Options = [];
export declare const name = "prefer-pound-in-plural";
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const tslib_1 = require("tslib");

@@ -151,3 +152,4 @@ const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");

node: messageNode,
message: e instanceof Error ? e.message : String(e),
messageId: 'parseError',
data: { message: e instanceof Error ? e.message : String(e) },
});

@@ -159,3 +161,4 @@ return;

}
const rule = {
exports.name = 'prefer-pound-in-plural';
exports.rule = {
meta: {

@@ -165,3 +168,2 @@ type: 'suggestion',

description: 'Prefer using # to reference the count in the plural argument.',
recommended: false,
url: 'https://formatjs.io/docs/tooling/linter#prefer-pound-in-plurals',

@@ -171,9 +173,14 @@ },

preferPoundInPlurals: 'Prefer using # to reference the count in the plural argument instead of repeating the argument.',
parseError: '{{message}}',
},
fixable: 'code',
schema: [],
},
defaultOptions: [],
// TODO: Vue support
create(context) {
const callExpressionVisitor = (node) => checkNode(context, node);
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
if (context.parserServices.defineTemplateBodyVisitor) {
//@ts-expect-error
return context.parserServices.defineTemplateBodyVisitor({

@@ -191,2 +198,1 @@ CallExpression: callExpressionVisitor,

};
exports.default = rule;
import { MessageFormatElement } from '@formatjs/icu-messageformat-parser';
import { TSESTree } from '@typescript-eslint/utils';
import { Rule } from 'eslint';
import { RuleContext } from '@typescript-eslint/utils/ts-eslint';
export interface MessageDescriptor {

@@ -23,3 +23,3 @@ id?: string;

}
export declare function getSettings({ settings }: Rule.RuleContext): Settings;
export declare function getSettings<TMessageIds extends string, TOptions extends readonly unknown[]>({ settings }: RuleContext<TMessageIds, TOptions>): Settings;
export declare function isIntlFormatMessageCall(node: TSESTree.Node): node is TSESTree.CallExpression;

@@ -26,0 +26,0 @@ export declare function extractMessageDescriptor(node?: TSESTree.Expression): MessageDescriptorNodeInfo | undefined;

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc