Skip to content

Commit 4363626

Browse files
yungstersfacebook-github-bot
authored andcommitted
RN: Enforce flow-typed Signatures
Summary: Creates a new `valid-flow-typed-signature` ESLint rule that validates the `flow-typed` signatures at the top of each file. This lint rule will discourage contributors from locally forking the `flow-typed` definitions. Instead, any changes should be submitted as patches to the upstream definition in: https://github.com/flow-typed/flow-typed Changelog: [Internal] Reviewed By: rickhanlonii Differential Revision: D39868721 fbshipit-source-id: e5e3ffe7568dbe52c9b598b53110b0fcbcad3e38
1 parent b846849 commit 4363626

File tree

4 files changed

+121
-1
lines changed

4 files changed

+121
-1
lines changed

.eslintignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
**/staticBundle.js
33
docs/generatedComponentApiDocs.js
44
flow/
5-
flow-typed/
65
Libraries/Renderer/*
76
Libraries/vendor/**/*
87
node_modules/

.eslintrc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ module.exports = {
4949
{
5050
files: ['flow-typed/**/*.js'],
5151
rules: {
52+
'lint/valid-flow-typed-signature': 2,
53+
'no-unused-vars': 0,
5254
quotes: 0,
5355
},
5456
},
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
'use strict';
11+
12+
const rule = require('../valid-flow-typed-signature.js');
13+
const {RuleTester} = require('eslint');
14+
15+
const ruleTester = new RuleTester({
16+
parser: require.resolve('hermes-eslint'),
17+
parserOptions: {
18+
ecmaVersion: 6,
19+
sourceType: 'module',
20+
},
21+
});
22+
23+
ruleTester.run('valid-flow-typed-signature', rule, {
24+
valid: [
25+
{
26+
code: `// ...`,
27+
},
28+
{
29+
code: [
30+
`// flow-typed signature: 9333721862f426d869c32ea6f7cecfda`,
31+
`// flow-typed version: 123456/xyz_v1.x.x/flow_>=v0.83.x`,
32+
``,
33+
`declare module "xyz" {}`,
34+
].join('\n'),
35+
},
36+
],
37+
invalid: [
38+
{
39+
code: [
40+
`// flow-typed signature: 90affbd9a1954ec9ff029b7ad7183a16`,
41+
`// flow-typed version: 123456/xyz_v1.x.x/flow_>=v0.83.x`,
42+
``,
43+
`declare module "xyz" {}`,
44+
].join('\n'),
45+
errors: [{messageId: 'invalidSignature'}],
46+
},
47+
],
48+
});
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
'use strict';
11+
12+
const crypto = require('node:crypto');
13+
14+
// @see https://github.com/flow-typed/flow-typed
15+
const HASH_COMMENT_RE = /\/\/ flow-typed signature: (.*)$/;
16+
17+
module.exports = {
18+
meta: {
19+
type: 'problem',
20+
docs: {
21+
description: 'Require valid flow-typed signatures',
22+
recommended: true,
23+
},
24+
messages: {
25+
invalidSignature:
26+
'Invalid flow-typed signature; avoid local modifications',
27+
},
28+
schema: [],
29+
},
30+
31+
create(context) {
32+
return {
33+
Program() {
34+
const sourceText = context.getSourceCode().getText();
35+
36+
const firstLineEndIndex = sourceText.indexOf('\n');
37+
const firstLine = sourceText.substr(0, firstLineEndIndex);
38+
39+
const match = firstLine.match(HASH_COMMENT_RE);
40+
if (match == null) {
41+
// Not a signed flow-typed definition file.
42+
return;
43+
}
44+
45+
const hash = match[1];
46+
const versionedCode = sourceText.substr(firstLineEndIndex + 1);
47+
if (md5(versionedCode) === hash) {
48+
return;
49+
}
50+
51+
context.report({
52+
loc: {
53+
start: {
54+
line: 1,
55+
column: firstLine.length - hash.length,
56+
},
57+
end: {
58+
line: 1,
59+
column: firstLine.length,
60+
},
61+
},
62+
messageId: 'invalidSignature',
63+
});
64+
},
65+
};
66+
},
67+
};
68+
69+
function md5(string) {
70+
return crypto.createHash('md5').update(string).digest('hex');
71+
}

0 commit comments

Comments
 (0)