Skip to content

Commit df3c2bf

Browse files
authored
refactor: migrate from TypeScript to JavaScript (#28651)
* refactor: migrate from TypeScript to JavaScript * fix(diff-features): enumerate features with tsx if necessary * fixup! Merge branch 'main' into un-typescript * chore(eslint): forbid `@typedef` * refactor: migrate `@typedef` imports to `@import` * chore(eslint): enable jsdoc/prefer-import-tag * refactor: replace `import()` in JSDoc with `@import` * chore(eslint): refine build ignore It was also ignoring `scripts/build`. * chore: run `eslint --fix` * fixup! refactor: migrate `@typedef` imports to `@import` * fix(scripts/build): add missing async option Helps TypeScript to infer the right return type. * chore(tsconfig): remove unnecessary `include` * chore(tsconfig): remove `skipLibCheck` * fix(types): import from `build/types.d.ts` * fix: resolve newly surfaced type errors * chore(eslint): remove typescript config/plugins * chore(deps-dev): remove unused dependencies * fix(eslint): use latest ecmaVersion As recommended, see: https://eslint.org/docs/latest/use/configure/language-options#specifying-javascript-options * chore(tsconfig): include tests in type checking * chore(lint): remove duplicate type imports * chore(lint): avoid invalid test value * chore(lint): fix some types * fixup! chore(lint): avoid invalid test value * fixup! chore(lint): fix some types * chore(utils): add missing test for __compat * chore(eslint): ignore `import/no-unresolved` errors for `yargs/helpers` * chore(lint): remove unnessary type annotation * chore(lint): refine type * fix(yargs): avoid callback + use parseSync() for proper typing * chore(scripts/diff-features): specify tsx version Same as in `package.json` in main. * fixup! fix(yargs): avoid callback + use parseSync() for proper typing * fixup! fix(yargs): avoid callback + use parseSync() for proper typing * chore: use arrow function type syntax * refactor(lint): extract types to d.ts file * fix(lint/types): unmark path.{full,category} as optional * test(lint): fix incomplete paths in test cases * chore(lint): handle undefined rawdata * test(lint): add missing version_added field * chore(types): introduce InternalDataType * chore(eslint): bring back `@typescript/eslint` * chore(tsconfig): re-enable skipLibCheck Otherwise we stumble over web-features type import without file extension. * chore(lint): avoid cast to unknown * chore(eslint): forbid unknown type in JSDoc * chore(mocha): remove unused mjs extension * chore(eslint): use jsdoc/recommended-typescript-flavor * chore(eslint): fix type import * chore(eslint): ignore no-empty-function once * chore(eslint): disable duplicate no-unused-vars rule * chore(eslint): use single no-unused-var + refine * style(eslint): remove unused vars * style(eslint): resolve no-unused-vars issue
1 parent e4501ee commit df3c2bf

145 files changed

Lines changed: 3381 additions & 4281 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/add-push-artifacts.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ jobs:
2121
cache: npm
2222
package-manager-cache: true
2323
- run: npm ci
24-
- run: npx tsx ./scripts/enumerate-features.ts features.json
25-
- run: npx tsx ./scripts/diff-features.ts --no-github --format=json > features.diff.json
24+
- run: node ./scripts/enumerate-features.js features.json
25+
- run: node ./scripts/diff-features.js --no-github --format=json > features.diff.json
2626
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
2727
with:
2828
name: enumerate-features

.lefthook.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pre-commit:
88
stage_fixed: true
99

1010
- name: eslint
11-
glob: "*.{js,jsx,tsx}"
11+
glob: "*.js"
1212
run: npx eslint --fix --cache {staged_files}
1313
stage_fixed: true
1414

.mocharc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"extensions": ["ts", "tsx"]
2+
"extensions": ["js"]
33
}

eslint.config.js

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const compat = new FlatCompat({
2222
export default [
2323
{
2424
ignores: [
25+
'eslint.config.js',
2526
'**/*.json',
2627
'!*.json',
2728
'!schemas/*.json',
@@ -31,7 +32,7 @@ export default [
3132
'**/.editorconfig',
3233
'package-lock.json',
3334
'CODE_OF_CONDUCT.md',
34-
'**/build/',
35+
'build/',
3536
'**/coverage/',
3637
'**/types.d.ts',
3738
],
@@ -42,8 +43,7 @@ export default [
4243
'plugin:@typescript-eslint/strict',
4344
'plugin:@typescript-eslint/stylistic',
4445
'plugin:import/recommended',
45-
'plugin:import/typescript',
46-
'plugin:jsdoc/recommended-typescript',
46+
'plugin:jsdoc/recommended-typescript-flavor',
4747
),
4848
),
4949
{
@@ -64,25 +64,26 @@ export default [
6464
},
6565

6666
parser: ts.parser,
67-
ecmaVersion: 2020,
67+
ecmaVersion: 'latest',
6868
sourceType: 'module',
6969
},
7070

7171
settings: {
7272
'import/resolver': {
73-
typescript: true,
7473
node: true,
7574
},
7675
},
7776

7877
rules: {
7978
'@typescript-eslint/no-explicit-any': 'off',
8079
'@typescript-eslint/no-unused-expressions': 'error',
80+
'@typescript-eslint/no-unused-vars': 'off',
8181

82-
'@typescript-eslint/no-unused-vars': [
82+
'no-unused-vars': [
8383
'error',
8484
{
85-
caughtErrors: 'none',
85+
argsIgnorePattern: '^_',
86+
varsIgnorePattern: '^_',
8687
},
8788
],
8889

@@ -100,7 +101,17 @@ export default [
100101
],
101102

102103
'import/no-named-as-default-member': 'off',
104+
'import/no-unresolved': [
105+
'error',
106+
{
107+
ignore: [
108+
// https://github.com/import-js/eslint-plugin-import/issues/1810
109+
'^yargs/helpers$',
110+
],
111+
},
112+
],
103113
'jsdoc/check-param-names': 'error',
114+
'jsdoc/prefer-import-tag': 'error',
104115
'jsdoc/require-description': 'warn',
105116

106117
'jsdoc/require-jsdoc': [
@@ -117,6 +128,25 @@ export default [
117128
},
118129
],
119130

131+
'jsdoc/no-restricted-syntax': [
132+
'error',
133+
{
134+
contexts: [
135+
{
136+
comment:
137+
'JsdocBlock:has(JsdocTag[tag="typedef"]:has(JsdocTypeImport))',
138+
context: 'any',
139+
message: 'Use @import JSDoc instead of @typedef.',
140+
},
141+
{
142+
comment: 'JsdocBlock:has(JsdocTypeName[value="unknown"])',
143+
context: 'any',
144+
message: 'Avoid using unknown type in JSDoc.',
145+
},
146+
],
147+
},
148+
],
149+
120150
'jsdoc/require-returns': 'error',
121151
'jsdoc/require-yields': 'error',
122152
'linebreak-style': ['error', 'unix'],
@@ -135,7 +165,7 @@ export default [
135165
'no-lone-blocks': 'error',
136166
'no-return-assign': 'error',
137167
'no-self-compare': 'error',
138-
'no-unused-expressions': 'off',
168+
'no-unused-expressions': 'error',
139169
'no-useless-call': 'error',
140170

141171
'prefer-arrow-functions/prefer-arrow-functions': [
Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
/* This file is a part of @mdn/browser-compat-data
22
* See LICENSE file for more information. */
33

4+
/** @import {CompatData} from './types/types.js' */
5+
46
import fs from 'node:fs/promises';
57
import path from 'node:path';
68
import { fileURLToPath } from 'node:url';
79

810
import { fdir } from 'fdir';
911

10-
import { CompatData } from './types/types.js';
1112
import extend from './scripts/lib/extend.js';
1213
import dataFolders from './scripts/lib/data-folders.js';
1314
import { normalizePath, walk } from './utils/index.js';
@@ -16,23 +17,26 @@ const dirname = fileURLToPath(new URL('.', import.meta.url));
1617

1718
/**
1819
* Recursively load one or more directories passed as arguments.
19-
* @param dirs The directories to load
20-
* @returns All of the browser compatibility data
20+
* @param {...string} dirs The directories to load
21+
* @returns {Promise<CompatData>} All of the browser compatibility data
2122
*/
22-
const load = async (...dirs: string[]): Promise<CompatData> => {
23+
const load = async (...dirs) => {
2324
const result = {};
2425

2526
for (const dir of dirs) {
26-
const paths = new fdir()
27-
.withBasePath()
28-
.filter((fp) => fp.endsWith('.json'))
29-
.crawl(path.join(dirname, dir))
30-
.sync() as string[];
27+
const paths = /** @type {string[]} */ (
28+
new fdir()
29+
.withBasePath()
30+
.filter((fp) => fp.endsWith('.json'))
31+
.crawl(path.join(dirname, dir))
32+
.sync()
33+
);
3134

3235
for (const fp of paths) {
3336
try {
3437
const rawcontents = await fs.readFile(fp);
35-
const contents: CompatData = JSON.parse(rawcontents.toString('utf8'));
38+
/** @type {CompatData} */
39+
const contents = JSON.parse(rawcontents.toString('utf8'));
3640

3741
// Add source_file props
3842
const walker = walk(undefined, contents);
@@ -42,15 +46,15 @@ const load = async (...dirs: string[]): Promise<CompatData> => {
4246

4347
extend(result, contents);
4448
/* c8 ignore start */
45-
} catch (e) {
49+
} catch {
4650
// Skip invalid JSON. Tests will flag the problem separately.
4751
continue;
4852
}
4953
/* c8 ignore stop */
5054
}
5155
}
5256

53-
return result as CompatData;
57+
return /** @type {CompatData} */ (result);
5458
};
5559

5660
export default await load(...dataFolders);
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
/* This file is a part of @mdn/browser-compat-data
22
* See LICENSE file for more information. */
33

4-
import assert from 'node:assert/strict';
4+
/** @import {CompatStatement} from './types/types.js' */
55

6-
import { CompatStatement } from './types/types.js';
6+
import assert from 'node:assert/strict';
77

88
import bcd from './index.js';
99

1010
describe('Using BCD', () => {
1111
it('subscript notation', () => {
12-
const data: CompatStatement | undefined =
13-
bcd['api']['AbortController']['__compat'];
12+
/** @type {CompatStatement | undefined} */
13+
const data = bcd['api']['AbortController']['__compat'];
1414
assert.ok(data);
1515
});
1616

1717
it('dot notation', () => {
18-
const data: CompatStatement | undefined = bcd.api.AbortController.__compat;
18+
/** @type {CompatStatement | undefined} */
19+
const data = bcd.api.AbortController.__compat;
1920
assert.ok(data);
2021
});
2122
});
Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,20 @@
44
import chalk from 'chalk-template';
55
import { compareVersions } from 'compare-versions';
66

7-
import { Logger, createStatementGroupKey } from '../utils.js';
8-
import {
9-
BrowserName,
10-
SimpleSupportStatement,
11-
SupportStatement,
12-
} from '../../types/types.js';
7+
import { createStatementGroupKey } from '../utils.js';
138
import compareStatements from '../../scripts/lib/compare-statements.js';
149

10+
/** @import {Logger} from '../utils.js' */
11+
/** @import {BrowserName, SimpleSupportStatement, SupportStatement} from '../../types/types.js' */
12+
1513
/**
1614
* Groups statements by group key.
17-
* @param data The support statements to group.
18-
* @returns the statement groups
15+
* @param {SimpleSupportStatement[]} data The support statements to group.
16+
* @returns {Map<string, SimpleSupportStatement[]>} the statement groups
1917
*/
20-
const groupByStatementKey = (data: SimpleSupportStatement[]) => {
21-
const groups = new Map<string, SimpleSupportStatement[]>();
18+
const groupByStatementKey = (data) => {
19+
/** @type {Map<string, SimpleSupportStatement[]>} */
20+
const groups = new Map();
2221

2322
for (const support of data) {
2423
const key = createStatementGroupKey(support);
@@ -34,11 +33,12 @@ const groupByStatementKey = (data: SimpleSupportStatement[]) => {
3433

3534
/**
3635
* Formats a support statement as a simplified JSON-like version range.
37-
* @param support The statement to format
38-
* @returns The formatted range
36+
* @param {SimpleSupportStatement} support The statement to format
37+
* @returns {string} The formatted range
3938
*/
40-
const formatRange = (support: SimpleSupportStatement): string => {
41-
const result: string[] = [];
39+
const formatRange = (support) => {
40+
/** @type {string[]} */
41+
const result = [];
4242
if (support.version_added) {
4343
result.push(`added: ${support.version_added}`);
4444
}
@@ -51,18 +51,14 @@ const formatRange = (support: SimpleSupportStatement): string => {
5151

5252
/**
5353
* Process data and check to make sure there aren't support statements whose version ranges overlap.
54-
* @param data The data to test
55-
* @param browser The name of the browser
56-
* @param options The check options
57-
* @param options.logger The logger to output errors to
58-
* @param options.fix Whether the statements should be fixed (if possible)
59-
* @returns the data (with fixes, if specified)
54+
* @param {SupportStatement} data The data to test
55+
* @param {BrowserName} browser The name of the browser
56+
* @param {object} options The check options
57+
* @param {Logger} [options.logger] The logger to output errors to
58+
* @param {boolean} [options.fix] Whether the statements should be fixed (if possible)
59+
* @returns {SupportStatement} the data (with fixes, if specified)
6060
*/
61-
export const checkOverlap = (
62-
data: SupportStatement,
63-
browser: BrowserName,
64-
{ logger, fix = false }: { logger?: Logger; fix?: boolean },
65-
): SupportStatement => {
61+
export const checkOverlap = (data, browser, { logger, fix = false }) => {
6662
if (!Array.isArray(data)) {
6763
// If there's only one statement, skip since this is a linter for multiple statements
6864
return data;
@@ -76,8 +72,8 @@ export const checkOverlap = (
7672
const statements = groupData.slice().sort(compareStatements).reverse();
7773

7874
for (let i = 0; i < statements.length - 1; i++) {
79-
const current = statements.at(i) as SimpleSupportStatement;
80-
const next = statements.at(i + 1) as SimpleSupportStatement;
75+
const current = /** @type {SimpleSupportStatement} */ (statements.at(i));
76+
const next = /** @type {SimpleSupportStatement} */ (statements.at(i + 1));
8177

8278
if (!statementsOverlap(current, next)) {
8379
continue;
@@ -109,14 +105,11 @@ export const checkOverlap = (
109105

110106
/**
111107
* Checks if the support statements overlap in terms of their version ranges.
112-
* @param current the current statement.
113-
* @param next the chronologically following statement.
114-
* @returns Whether the support statements overlap.
108+
* @param {SimpleSupportStatement} current the current statement.
109+
* @param {SimpleSupportStatement} next the chronologically following statement.
110+
* @returns {boolean} Whether the support statements overlap.
115111
*/
116-
const statementsOverlap = (
117-
current: SimpleSupportStatement,
118-
next: SimpleSupportStatement,
119-
): boolean => {
112+
const statementsOverlap = (current, next) => {
120113
if (typeof current.version_removed === 'string') {
121114
// If previous has no removed version, we always have an overlap.
122115

0 commit comments

Comments
 (0)