Skip to content

Commit d06ae53

Browse files
authored
fix plugins TS setup and tests, update workflow (facebook#4962)
1 parent 6dce89d commit d06ae53

16 files changed

Lines changed: 288 additions & 100 deletions

File tree

.github/workflows/pre-merge.yml

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,41 @@ jobs:
3030
- name: Check dependencies alignment
3131
run: yarn check-dependencies
3232

33-
- name: Run Workspace Lint
34-
run: yarn lint
33+
- name: Run packages lint
34+
run: yarn lint:packages
35+
36+
- name: Run plugins lint
37+
run: yarn lint:plugins
38+
39+
- name: Run remark-codeblock-language-as-title plugin checks
40+
working-directory: plugins/remark-codeblock-language-as-title
41+
run: yarn tsc
42+
43+
- name: Run remark-lint-no-dead-urls plugin checks
44+
working-directory: plugins/remark-lint-no-dead-urls
45+
run: yarn tsc && yarn test
46+
47+
- name: Run remark-snackplayer plugin checks
48+
working-directory: plugins/remark-snackplayer
49+
run: yarn tsc && yarn test
50+
51+
lint-website:
52+
runs-on: ubuntu-latest
53+
steps:
54+
- name: Checkout repository
55+
uses: actions/checkout@v6
56+
57+
- name: Enable Corepack
58+
run: corepack enable
59+
60+
- name: Set up Node.js
61+
uses: actions/setup-node@v6
62+
with:
63+
node-version: "22"
64+
cache: yarn
65+
66+
- name: Install dependencies
67+
run: yarn install --immutable
3568

3669
- name: Run Website Specific Lints
3770
working-directory: website

plugins/remark-codeblock-language-as-title/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
},
2222
"devDependencies": {
2323
"@types/mdast": "^4.0.4",
24-
"remark": "^15.0.1"
24+
"remark": "^15.0.1",
25+
"typescript": "^5.9.3"
2526
}
2627
}
Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
{
2-
"extends": "@react-native/typescript-config/tsconfig.json",
3-
"include": ["./src"],
2+
"compilerOptions": {
3+
"types": ["react", "node"],
4+
"lib": ["ES2022", "DOM"],
5+
"target": "es2022",
6+
"module": "NodeNext",
7+
"moduleResolution": "NodeNext",
8+
"allowSyntheticDefaultImports": true,
9+
"allowImportingTsExtensions": true,
10+
"isolatedModules": true,
11+
"noEmit": true
12+
},
13+
"include": ["./src"]
414
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module.exports = {
2+
preset: 'ts-jest/presets/default-esm',
3+
testEnvironment: 'node',
4+
extensionsToTreatAsEsm: ['.ts'],
5+
moduleFileExtensions: ['js', 'ts'],
6+
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.ts$',
7+
transform: {
8+
'^.+\\.ts$': [
9+
'ts-jest',
10+
{
11+
useESM: true,
12+
tsconfig: 'tsconfig.json',
13+
},
14+
],
15+
},
16+
};

plugins/remark-lint-no-dead-urls/package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@
1818
"test": "yarn node --experimental-vm-modules $(yarn bin jest)"
1919
},
2020
"dependencies": {
21-
"got": "^14.6.4",
21+
"got": "^14.6.6",
2222
"unified-lint-rule": "^3.0.1",
2323
"unist-util-visit": "^5.0.0",
2424
"vfile": "^6.0.3"
2525
},
2626
"devDependencies": {
27+
"@types/jest": "^29.5.14",
2728
"@types/mdast": "^4.0.4",
28-
"dedent": "^1.7.0",
29+
"dedent": "^1.7.1",
2930
"jest": "^29.7.0",
30-
"remark": "^15.0.1"
31+
"remark": "^15.0.1",
32+
"ts-jest": "^29.4.6",
33+
"typescript": "^5.9.3"
3134
}
3235
}

plugins/remark-lint-no-dead-urls/src/__tests__/index.js renamed to plugins/remark-lint-no-dead-urls/src/__tests__/index.ts

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,41 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8-
import remark from 'remark';
8+
import {remark} from 'remark';
99
import dedent from 'dedent';
10-
import {jest} from '@jest/globals';
10+
import {jest, describe, beforeEach, test, expect} from '@jest/globals';
1111

12-
jest.unstable_mockModule('../lib.js', () => ({
13-
fetch: jest.fn(),
12+
const mockFetch = jest.fn() as jest.MockedFunction<
13+
(url: string, method: unknown, options?: object) => Promise<number>
14+
>;
15+
16+
jest.unstable_mockModule('../lib.ts', () => ({
17+
fetch: mockFetch,
1418
}));
1519

16-
const {fetch} = await import('../lib.js');
17-
const plugin = (await import('../')).default;
20+
const plugin = (await import('../index.ts')).default;
1821

19-
const processMarkdown = (md, opts) => {
22+
function processMarkdown(md: string, opts = {}) {
2023
return remark().use(plugin, opts).process(md);
21-
};
24+
}
2225

2326
describe('remark-lint-no-dead-urls', () => {
24-
beforeEach(() => fetch.mockReset());
27+
beforeEach(() => mockFetch.mockReset());
2528

26-
test('works with no URLs', () => {
29+
test('works with no URLs', async () => {
2730
const lint = processMarkdown(dedent`
2831
# Title
2932
3033
No URLs in here.
3134
`);
3235

33-
return lint.then(vFile => {
34-
expect(fetch).toHaveBeenCalledTimes(0);
35-
expect(vFile.messages.length).toBe(0);
36-
});
36+
const vFile = await lint;
37+
expect(mockFetch).toHaveBeenCalledTimes(0);
38+
expect(vFile.messages.length).toBe(0);
3739
});
3840

39-
test('works a good, bad a local link', () => {
40-
fetch.mockReturnValueOnce(200).mockReturnValueOnce(404);
41+
test('works a good, bad a local link', async () => {
42+
mockFetch.mockResolvedValueOnce(200).mockResolvedValueOnce(404);
4143

4244
const lint = processMarkdown(
4345
dedent`
@@ -51,17 +53,16 @@ describe('remark-lint-no-dead-urls', () => {
5153
`
5254
);
5355

54-
return lint.then(vFile => {
55-
expect(fetch).toHaveBeenCalledTimes(2);
56-
expect(vFile.messages.length).toBe(1);
57-
expect(vFile.messages[0].reason).toBe(
58-
'Link to https://github.com/unified/oops is broken'
59-
);
60-
});
56+
const vFile = await lint;
57+
expect(mockFetch).toHaveBeenCalledTimes(2);
58+
expect(vFile.messages.length).toBe(1);
59+
expect(vFile.messages[0].reason).toBe(
60+
'Link to https://github.com/unified/oops is broken'
61+
);
6162
}, 15000);
6263

63-
test('works with definitions and images', () => {
64-
fetch.mockReturnValueOnce(200).mockReturnValueOnce(404);
64+
test('works with definitions and images', async () => {
65+
mockFetch.mockResolvedValueOnce(200).mockResolvedValueOnce(404);
6566

6667
const lint = processMarkdown(
6768
dedent`
@@ -80,27 +81,25 @@ describe('remark-lint-no-dead-urls', () => {
8081
}
8182
);
8283

83-
return lint.then(vFile => {
84-
expect(fetch).toHaveBeenCalledTimes(2);
85-
expect(vFile.messages.length).toBe(1);
86-
expect(vFile.messages[0].reason).toBe('Link to /oops/broken is broken');
87-
});
84+
const vFile = await lint;
85+
expect(mockFetch).toHaveBeenCalledTimes(2);
86+
expect(vFile.messages.length).toBe(1);
87+
expect(vFile.messages[0].reason).toBe('Link to /oops/broken is broken');
8888
});
8989

90-
test('skips URLs with unsupported protocols', () => {
90+
test('skips URLs with unsupported protocols', async () => {
9191
const lint = processMarkdown(dedent`
9292
[Send me an email.](mailto:me@me.com)
9393
[Look at this file.](ftp://path/to/file.txt)
9494
[Special schema.](flopper://a/b/c)
9595
`);
9696

97-
return lint.then(vFile => {
98-
expect(fetch).toHaveBeenCalledTimes(0);
99-
expect(vFile.messages.length).toBe(0);
100-
});
97+
const vFile = await lint;
98+
expect(mockFetch).toHaveBeenCalledTimes(0);
99+
expect(vFile.messages.length).toBe(0);
101100
});
102101

103-
test('localhost', () => {
102+
test('localhost', async () => {
104103
const lint = processMarkdown(
105104
dedent`
106105
- [http://localhost](http://localhost)
@@ -114,12 +113,11 @@ describe('remark-lint-no-dead-urls', () => {
114113
`
115114
);
116115

117-
return lint.then(vFile => {
118-
expect(vFile.messages.length).toBe(0);
119-
});
116+
const vFile = await lint;
117+
expect(vFile.messages.length).toBe(0);
120118
});
121119

122-
test('local IP 127.0.0.1', () => {
120+
test('local IP 127.0.0.1', async () => {
123121
const lint = processMarkdown(
124122
dedent`
125123
- [http://127.0.0.1](http://127.0.0.1)
@@ -133,23 +131,21 @@ describe('remark-lint-no-dead-urls', () => {
133131
`
134132
);
135133

136-
return lint.then(vFile => {
137-
expect(vFile.messages.length).toBe(0);
138-
});
134+
const vFile = await lint;
135+
expect(vFile.messages.length).toBe(0);
139136
});
140137

141138
test.each([
142139
'[Ignore this](http://www.url-to-ignore.com)',
143140
'[Ignore this](http://www.url-to-ignore.com/somePath)',
144141
'[Ignore this](http://www.url-to-ignore.com/somePath?withQuery=wow)',
145142
'[its complicated](http://url-to-ignore.com/somePath/maybe)',
146-
])('skipUrlPatterns for content: %s', markdownContent => {
143+
])('skipUrlPatterns for content: %s', async markdownContent => {
147144
const lint = processMarkdown(markdownContent, {
148145
skipUrlPatterns: [/^http:\/\/(.*)url-to-ignore\.com/],
149146
});
150147

151-
return lint.then(vFile => {
152-
expect(vFile.messages.length).toBe(0);
153-
});
148+
const vFile = await lint;
149+
expect(vFile.messages.length).toBe(0);
154150
});
155151
});

plugins/remark-lint-no-dead-urls/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {lintRule} from 'unified-lint-rule';
1414
import {visit} from 'unist-util-visit';
1515
import type {VFile} from 'vfile';
1616

17-
import {fetch} from './lib.js';
17+
import {fetch} from './lib.ts';
1818

1919
const linkCache = new Map();
2020

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
{
2-
"extends": "@react-native/typescript-config/tsconfig.json",
3-
"include": ["./src"],
2+
"compilerOptions": {
3+
"types": ["react", "node"],
4+
"lib": ["ES2022", "DOM"],
5+
"target": "es2022",
6+
"module": "NodeNext",
7+
"moduleResolution": "NodeNext",
8+
"allowSyntheticDefaultImports": true,
9+
"allowImportingTsExtensions": true,
10+
"isolatedModules": true,
11+
"noEmit": true
12+
},
13+
"include": ["./src"]
414
}

plugins/remark-snackplayer/package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,15 @@
2020
"test": "yarn tape tests/index.ts"
2121
},
2222
"dependencies": {
23-
"dedent": "^1.7.0",
24-
"object.fromentries": "^2.0.8",
23+
"dedent": "^1.7.1",
2524
"unist-util-visit-parents": "^3.1.1"
2625
},
2726
"devDependencies": {
2827
"@types/mdast": "^4.0.4",
29-
"@types/object.fromentries": "^2.0.4",
3028
"@types/tape": "^5.8.1",
3129
"remark": "^15.0.1",
3230
"remark-mdx": "^3.1.1",
33-
"tape": "^5.9.0"
31+
"tape": "^5.9.0",
32+
"typescript": "^5.9.3"
3433
}
3534
}

plugins/remark-snackplayer/src/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@
88
'use strict';
99

1010
import visit from 'unist-util-visit-parents';
11-
import fromEntries from 'object.fromentries';
1211
import type {Code} from 'mdast';
1312
import type {Node} from 'unist';
1413

1514
function parseParams(paramString = '') {
16-
const params = fromEntries(new URLSearchParams(paramString));
15+
const params = Object.fromEntries(new URLSearchParams(paramString).entries());
1716

1817
if (!params.platform) {
1918
params.platform = 'web';
@@ -90,7 +89,7 @@ export default function SnackPlayer() {
9089
const nodesToProcess: Promise<void>[] = [];
9190
visit(tree, 'code', (node: Node) => {
9291
if ('lang' in node && node.lang === 'SnackPlayer') {
93-
nodesToProcess.push(toJsxNode(node as Code));
92+
nodesToProcess.push(toJsxNode(node as unknown as Code));
9493
}
9594
});
9695
await Promise.all(nodesToProcess);

0 commit comments

Comments
 (0)