Skip to content
Permalink
Newer
Older
100644 100 lines (87 sloc) 5.11 KB
Ignoring revisions in .git-blame-ignore-revs.
January 18, 2023 20:50
1
const path = require('path')
2
const browserslist = require('browserslist')
3
const {findConfig} = require('browserslist/node')
4
const {version,homepage} = require('../package.json')
5
const createRule = (name, browserstring, description, {ts = null} = {}) => {
6
const rule = require(`./rules/${name}`)
7
module.exports.rules[name] = {
8
meta: Object.assign({
9
type: 'problem',
10
docs: {
11
description,
12
recommended: true,
13
url: `${homepage}/blob/v${version}/docs/${name}.md`
14
},
15
fixable: false,
16
schema: [],
17
deprecated: false,
18
replacedBy: null,
19
}, rule.meta || {}),
20
create(context) {
21
let browsers = browserslist(browserstring)
22
const config = findConfig(path.dirname(context.getFilename())) || { defaults: 'defaults' }
23
const desiredBrowsers = browserslist(config.defaults)
24
const badBrowsers = desiredBrowsers.filter(browser => browsers.indexOf(browser) !== -1).join(', ')
25
if (badBrowsers) {
26
const create = typeof rule === 'function' ? rule : rule.create
27
return create(context, badBrowsers)
28
}
29
return {}
30
}
31
}
32
33
const configName = `typescript-${ts || 'base'}`
34
if (!module.exports.configs[configName]) {
35
let config = {rules: {}}
36
if (ts === 2016) {
37
config.extends = [`plugin:escompat/typescript-base`]
38
} else if (ts) {
39
let previous = ts - 1
40
while (!module.exports.configs[`typescript-${previous}`]) previous -= 1
41
42
config.extends = [`plugin:escompat/typescript-${previous}`]
43
}
44
module.exports.configs[configName] = config
45
}
46
module.exports.configs[`typescript-base`].rules[`escompat/${name}`] = 'off'
47
module.exports.configs[configName].rules[`escompat/${name}`] = 'error'
48
}
49
50
module.exports = { rules: {}, configs: {} }
51
// ES2015
52
createRule('no-edge-destructure-bug', 'edge < 18', 'disallow the use of specific destructuring patterns that cause bugs in old Edge')
53
54
// ES2016
55
createRule('no-exponentiation-operator', 'chrome < 52, edge < 14, firefox < 52, safari < 10.1', 'disallow use of exponentiation operator (**)', {ts: 2016})
56
57
// ES2018
58
createRule('no-async-iteration', 'edge < 79, safari < 12, firefox < 57, chrome < 63', 'disallow the use of `for await of` style loops', {ts: 2018})
59
createRule('no-async-generator', 'edge < 79, safari < 12, firefox < 57, chrome < 63', 'disallow the use of async generator functions', {ts: 2018})
60
createRule('no-object-rest-spread', 'edge < 79, safari < 11.1, firefox < 55, chrome < 60', 'disallow object rest/spread patterns', {ts: 2018})
61
createRule('no-regexp-s-flag', 'edge < 79, safari < 11.1, firefox < 78, chrome < 62', 'disallow the use of the RegExp `s` flag')
62
createRule('no-regexp-lookbehind', 'edge < 79, safari > 0, firefox < 78, chrome < 62', 'disallow the use of RegExp lookbehinds')
63
createRule('no-regexp-named-group', 'edge < 79, safari 11.1, firefox < 78, chrome < 64', 'disallow the use of RegExp named groups')
64
65
// ES2019
66
createRule('no-optional-catch', 'edge < 79, safari < 11.1, firefox < 58, chrome < 66', 'always require catch() to have an argument', {ts: 2019})
67
68
// ES2020
69
createRule('no-dynamic-imports', 'edge < 79, safari < 11, firefox < 67, chrome < 63', 'disallow dynamic import statements')
70
createRule('no-optional-chaining', 'edge < 80, safari < 13.1, firefox < 72, chrome < 80', 'disallow the .? optional chaning operator', {ts: 2020})
71
createRule('no-nullish-coalescing', 'edge < 80, safari < 13.1, firefox < 72, chrome < 80', 'disallow the ?? nullish coalescing operator', {ts: 2020})
72
createRule('no-bigint', 'edge < 79, safari < 14, firefox < 68, chrome < 67', 'disallow bigints')
73
74
// ES2021
75
createRule('no-numeric-separators', 'edge < 79, safari < 13, firefox < 68, chrome < 75', 'disallow use of numeric seperators like 1_000_000', {ts:2021})
76
77
// ES2022
78
createRule('no-public-static-class-fields', 'edge < 79, safari < 14.5, firefox < 75, chrome < 72', 'disallow public static class fields like foo = 1', {ts: 2022})
79
createRule('no-public-instance-class-fields', 'edge < 79, safari < 14.5, firefox < 69, chrome < 72', 'disallow public class fields like foo = 1', {ts: 2022})
80
createRule('no-computed-public-class-fields', 'edge < 79, safari < 14.5, firefox < 69, chrome < 74', 'disallow computed public static or instance class fields like [foo] = 1', {ts: 2022})
81
createRule('no-private-class-fields', 'edge < 79, safari < 14.5, firefox < 90, chrome < 74', 'disallow private class fields like #foo = 1', {ts: 2022})
82
83
// Proposals...
84
createRule('no-do-expression', 'edge > 0, safari > 0, firefox > 0, chrome > 0', 'disallow "do" expressions')
85
createRule('no-bind-operator', 'edge > 0, safari > 0, firefox > 0, chrome > 0', 'disallow the :: bind operator')
86
createRule('no-pipeline-operator', 'edge > 0, safari > 0, firefox > 0, chrome > 0', 'disallow the > pipeline operator')
87
88
module.exports.configs.recommended = {
89
plugins: ['escompat'],
90
parserOptions: { ecmaVersion: 2020 },
91
rules: Object.keys(module.exports.rules).reduce((o, r) => (o['escompat/' + r] = ['error'], o), {})
92
}
93
94
module.exports.configs.typescript = {
95
extends: ['plugin:escompat/typescript-2016']
96
}
97
98
if (require.main === module) {
99
console.log(require('util').inspect(module.exports, {depth: Infinity}))
100
}