diff --git a/.eslintrc.cjs b/.eslintrc.cjs index ff538113ce5..eaa733dbe37 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -51,6 +51,7 @@ module.exports = { files: ['specs/**/*.yml'], rules: { 'automation-custom/end-with-dot': 'error', + 'automation-custom/no-big-int': 'error', 'automation-custom/no-final-dot': 'error', 'automation-custom/single-quote-ref': 'error', }, @@ -58,12 +59,12 @@ module.exports = { { files: ['!specs/bundled/*.yml'], rules: { - 'automation-custom/out-of-line-enum': 'error', - 'automation-custom/out-of-line-one-of': 'error', 'automation-custom/out-of-line-all-of': 'error', 'automation-custom/out-of-line-any-of': 'error', - 'automation-custom/valid-acl': 'error', + 'automation-custom/out-of-line-enum': 'error', + 'automation-custom/out-of-line-one-of': 'error', 'automation-custom/ref-common': 'error', + 'automation-custom/valid-acl': 'error', 'automation-custom/valid-inline-title': 'error', }, }, diff --git a/eslint/src/index.ts b/eslint/src/index.ts index 96bf96e7679..ebe64eb5f81 100644 --- a/eslint/src/index.ts +++ b/eslint/src/index.ts @@ -1,4 +1,5 @@ import { endWithDot } from './rules/endWithDot.js'; +import { noBigInt } from './rules/noBigInt.js'; import { noFinalDot } from './rules/noFinalDot.js'; import { noNewLine } from './rules/noNewLine.js'; import { createOutOfLineRule } from './rules/outOfLineRule.js'; @@ -9,15 +10,16 @@ import { validInlineTitle } from './rules/validInlineTitle.js'; const rules = { 'end-with-dot': endWithDot, + 'no-big-int': noBigInt, 'no-final-dot': noFinalDot, - 'out-of-line-enum': createOutOfLineRule({ property: 'enum' }), - 'out-of-line-one-of': createOutOfLineRule({ property: 'oneOf' }), + 'no-new-line': noNewLine, 'out-of-line-all-of': createOutOfLineRule({ property: 'allOf' }), 'out-of-line-any-of': createOutOfLineRule({ property: 'anyOf' }), + 'out-of-line-enum': createOutOfLineRule({ property: 'enum' }), + 'out-of-line-one-of': createOutOfLineRule({ property: 'oneOf' }), + 'ref-common': refCommon, 'single-quote-ref': singleQuoteRef, 'valid-acl': validACL, - 'no-new-line': noNewLine, - 'ref-common': refCommon, 'valid-inline-title': validInlineTitle, }; diff --git a/eslint/src/rules/noBigInt.ts b/eslint/src/rules/noBigInt.ts new file mode 100644 index 00000000000..d33b89641da --- /dev/null +++ b/eslint/src/rules/noBigInt.ts @@ -0,0 +1,47 @@ +import { createRule } from 'eslint-plugin-yml/lib/utils'; + +import { isPairWithKey, isScalar } from '../utils.js'; + +// type: number with format: int64 will generate a BigInteger which is not nice to use, most of the time we only need int, long, float or double. +export const noBigInt = createRule('noBigInt', { + meta: { + docs: { + description: 'type big integer is forbidden, did you mean type: integer ?', + categories: null, + extensionRule: false, + layout: false, + }, + messages: { + noBigInt: 'type big integer is forbidden, did you mean type: integer ?', + }, + type: 'layout', + schema: [], + }, + create(context) { + if (!context.getSourceCode().parserServices.isYAML) { + return {}; + } + + return { + YAMLPair(node): void { + if (!isPairWithKey(node, 'type')) { + return; + } + + if (!isScalar(node.value) || node.value.value !== 'number') { + return; + } + + // check the format next to the type + node.parent.pairs.find((pair) => { + if (isPairWithKey(pair, 'format') && isScalar(pair.value) && (pair.value.value === 'int32' || pair.value.value === 'int64')) { + context.report({ + node: pair.value as any, + messageId: 'noBigInt', + }); + } + }); + }, + }; + }, +}); diff --git a/eslint/tests/noBigInt.test.ts b/eslint/tests/noBigInt.test.ts new file mode 100644 index 00000000000..ed5c00b3654 --- /dev/null +++ b/eslint/tests/noBigInt.test.ts @@ -0,0 +1,51 @@ +import { runClassic } from 'eslint-vitest-rule-tester'; +import yamlParser from 'yaml-eslint-parser'; +import { noBigInt } from '../src/rules/noBigInt.js'; + + +runClassic( + 'no-big-int', + noBigInt, + { + valid: [` +type: object +properties: + id: + type: number + format: float + url: + type: string + format: uri +`, ` +prop: + type: integer + format: int32 +`], + invalid: [ + { + code: ` +type: object +properties: + id: + type: number + format: int64 + url: + type: string + format: uri +`, + errors: [{ messageId: 'noBigInt' }], + }, + { + code: ` +prop: + type: number + format: int32 +`, + errors: [{ messageId: 'noBigInt' }], + }, + ], + }, + { + parser: yamlParser, + }, +);