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
This commit is contained in:
Tim Yung
2022-09-30 14:28:48 -07:00
committed by Facebook GitHub Bot
parent b846849f69
commit 4363626701
4 changed files with 121 additions and 1 deletions
-1
View File
@@ -2,7 +2,6 @@
**/staticBundle.js
docs/generatedComponentApiDocs.js
flow/
flow-typed/
Libraries/Renderer/*
Libraries/vendor/**/*
node_modules/
+2
View File
@@ -49,6 +49,8 @@ module.exports = {
{
files: ['flow-typed/**/*.js'],
rules: {
'lint/valid-flow-typed-signature': 2,
'no-unused-vars': 0,
quotes: 0,
},
},
@@ -0,0 +1,48 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
'use strict';
const rule = require('../valid-flow-typed-signature.js');
const {RuleTester} = require('eslint');
const ruleTester = new RuleTester({
parser: require.resolve('hermes-eslint'),
parserOptions: {
ecmaVersion: 6,
sourceType: 'module',
},
});
ruleTester.run('valid-flow-typed-signature', rule, {
valid: [
{
code: `// ...`,
},
{
code: [
`// flow-typed signature: 9333721862f426d869c32ea6f7cecfda`,
`// flow-typed version: 123456/xyz_v1.x.x/flow_>=v0.83.x`,
``,
`declare module "xyz" {}`,
].join('\n'),
},
],
invalid: [
{
code: [
`// flow-typed signature: 90affbd9a1954ec9ff029b7ad7183a16`,
`// flow-typed version: 123456/xyz_v1.x.x/flow_>=v0.83.x`,
``,
`declare module "xyz" {}`,
].join('\n'),
errors: [{messageId: 'invalidSignature'}],
},
],
});
@@ -0,0 +1,71 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
'use strict';
const crypto = require('node:crypto');
// @see https://github.com/flow-typed/flow-typed
const HASH_COMMENT_RE = /\/\/ flow-typed signature: (.*)$/;
module.exports = {
meta: {
type: 'problem',
docs: {
description: 'Require valid flow-typed signatures',
recommended: true,
},
messages: {
invalidSignature:
'Invalid flow-typed signature; avoid local modifications',
},
schema: [],
},
create(context) {
return {
Program() {
const sourceText = context.getSourceCode().getText();
const firstLineEndIndex = sourceText.indexOf('\n');
const firstLine = sourceText.substr(0, firstLineEndIndex);
const match = firstLine.match(HASH_COMMENT_RE);
if (match == null) {
// Not a signed flow-typed definition file.
return;
}
const hash = match[1];
const versionedCode = sourceText.substr(firstLineEndIndex + 1);
if (md5(versionedCode) === hash) {
return;
}
context.report({
loc: {
start: {
line: 1,
column: firstLine.length - hash.length,
},
end: {
line: 1,
column: firstLine.length,
},
},
messageId: 'invalidSignature',
});
},
};
},
};
function md5(string) {
return crypto.createHash('md5').update(string).digest('hex');
}