Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

flow-remove-types

Package Overview
Dependencies
Maintainers
1
Versions
258
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

flow-remove-types - npm Package Compare versions

Comparing version 1.2.3 to 2.99.0

273

index.js

@@ -1,2 +0,9 @@

var babylon = require('babylon');
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var parse = require('flow-parser').parse;
var vlq = require('vlq');

@@ -45,10 +52,12 @@

// Babylon is one of the sources of truth for Flow syntax. This parse
// configuration is intended to be as permissive as possible.
var ast = babylon.parse(source, {
allowImportExportEverywhere: true,
allowReturnOutsideFunction: true,
allowSuperOutsideMethod: true,
sourceType: 'module',
plugins: [ '*', 'jsx', 'flow' ],
// This parse configuration is intended to be as permissive as possible.
var ast = parse(source, {
esproposal_decorators: true,
esproposal_class_instance_fields: true,
esproposal_class_static_fields: true,
esproposal_export_star_as: true,
esproposal_optional_chaining: true,
esproposal_nullish_coalescing: true,
types: true,
tokens: true,
});

@@ -62,3 +71,3 @@

removedNodes: removedNodes,
pretty: Boolean(options && options.pretty)
pretty: Boolean(options && options.pretty),
};

@@ -68,6 +77,9 @@

if (pragmaStart !== -1) {
var pragmaIdx = findTokenIndex(ast.tokens, pragmaStart);
var pragmaType = ast.tokens[pragmaIdx].type;
if (pragmaType === 'CommentLine' || pragmaType === 'CommentBlock') {
removedNodes.push(getPragmaNode(context, pragmaStart, pragmaSize));
var comments = getComments(ast);
var pragmaIdx = findTokenIndex(comments, pragmaStart);
if (pragmaIdx >= 0 && pragmaIdx < comments.length) {
var pragmaType = comments[pragmaIdx].type;
if (pragmaType === 'Line' || pragmaType === 'Block') {
removedNodes.push(getPragmaNode(context, pragmaStart, pragmaSize));
}
}

@@ -80,3 +92,3 @@ }

return resultPrinter(options, source, removedNodes);
}
};

@@ -88,3 +100,3 @@ function resultPrinter(options, source, removedNodes) {

return {
toString: function () {
toString: function() {
if (!removedNodes || removedNodes.length === 0) {

@@ -100,6 +112,9 @@ return source;

var node = removedNodes[i];
result += source.slice(lastPos, node.start);
lastPos = node.end;
result += source.slice(lastPos, startOf(node));
lastPos = endOf(node);
if (typeof node.__spliceValue === 'string') {
result += node.__spliceValue;
}
if (!pretty) {
var toReplace = source.slice(node.start, node.end);
var toReplace = source.slice(startOf(node), endOf(node));
if (!node.loc || node.loc.start.line === node.loc.end.line) {

@@ -117,13 +132,13 @@ result += space(toReplace.length);

return result += source.slice(lastPos);
return (result += source.slice(lastPos));
},
generateMap: function () {
generateMap: function() {
return {
version: 3,
sources: [ 'source.js' ],
sources: ['source.js'],
names: [],
mappings: pretty ? generateSourceMappings(removedNodes) : ''
mappings: pretty ? generateSourceMappings(removedNodes) : '',
};
}
}
},
};
}

@@ -138,3 +153,3 @@

DeclareFunction: removeNode,
DeclareInterface:removeNode,
DeclareInterface: removeNode,
DeclareModule: removeNode,

@@ -152,9 +167,9 @@ DeclareTypeAlias: removeNode,

Identifier: function (context, node, ast) {
Identifier: function(context, node, ast) {
if (node.optional) {
// Find the optional token.
var idx = findTokenIndex(ast.tokens, node.start);
var idx = findTokenIndex(ast.tokens, startOf(node));
do {
idx++;
} while (ast.tokens[idx].type.label !== '?');
} while (getLabel(ast.tokens[idx]) !== '?');
removeNode(context, ast.tokens[idx]);

@@ -164,9 +179,9 @@ }

ClassProperty: function (context, node) {
ClassProperty: function(context, node) {
if (!node.value) {
return removeNode(context, node)
return removeNode(context, node);
}
},
ExportNamedDeclaration: function (context, node) {
ExportNamedDeclaration: function(context, node) {
if (node.exportKind === 'type' || node.exportKind === 'typeof') {

@@ -177,3 +192,3 @@ return removeNode(context, node);

ImportDeclaration: function (context, node) {
ImportDeclaration: function(context, node) {
if (node.importKind === 'type' || node.importKind === 'typeof') {

@@ -186,11 +201,26 @@ return removeNode(context, node);

if (node.importKind === 'type' || node.importKind === 'typeof') {
var ast = context.ast;
// Flow quirk: Remove importKind which is outside the node
var idxStart = findTokenIndex(ast.tokens, startOf(node));
var maybeImportKind = ast.tokens[idxStart - 1];
var maybeImportKindLabel = getLabel(maybeImportKind);
if (
maybeImportKindLabel === 'type' ||
maybeImportKindLabel === 'typeof'
) {
removeNode(context, maybeImportKind);
}
// Remove the node itself
removeNode(context, node);
// Remove trailing comma
var ast = context.ast;
var idx = findTokenIndex(ast.tokens, node.end);
var idx = findTokenIndex(ast.tokens, endOf(node));
while (isComment(ast.tokens[idx])) {
// NOTE: ast.tokens has no comments in Flow
idx++;
}
if (ast.tokens[idx].type.label === ',') {
if (getLabel(ast.tokens[idx]) === ',') {
removeNode(context, ast.tokens[idx]);

@@ -200,3 +230,48 @@ }

}
}
},
ArrowFunctionExpression: function(context, node) {
// Naively erasing a multi-line return type from an arrow function will
// leave a newline between the parameter list and the arrow, which is not
// valid JS. Detect this here and move the arrow up to the correct line.
if (context.pretty) {
// Pretty-printing solves this naturally. Good, because our arrow-fudging
// below doesn't play nice with source maps... Which are only created when
// using --pretty.
return;
}
var returnType = node.returnType;
if (returnType) {
var ast = context.ast;
var paramEndIdx = findTokenIndex(ast.tokens, startOf(returnType));
do {
paramEndIdx--;
} while (isComment(ast.tokens[paramEndIdx]));
var arrowIdx = findTokenIndex(ast.tokens, endOf(returnType));
while (getLabel(ast.tokens[arrowIdx]) !== '=>') {
arrowIdx++;
}
if (
ast.tokens[paramEndIdx].loc.end.line <
ast.tokens[arrowIdx].loc.start.line
) {
// Insert an arrow immediately after the parameter list.
removeNode(
context,
getSpliceNodeAtPos(
context,
endOf(ast.tokens[paramEndIdx]),
ast.tokens[paramEndIdx].loc.end,
' =>'
)
);
// Delete the original arrow token.
removeNode(context, ast.tokens[arrowIdx]);
}
}
},
};

@@ -210,3 +285,3 @@

var last = node.implements[node.implements.length - 1];
var idx = findTokenIndex(ast.tokens, first.start);
var idx = findTokenIndex(ast.tokens, startOf(first));
do {

@@ -216,5 +291,6 @@ idx--;

var lastIdx = findTokenIndex(ast.tokens, last.start);
var lastIdx = findTokenIndex(ast.tokens, startOf(last));
do {
if (!isComment(ast.tokens[idx])) {
// NOTE: ast.tokens has no comments in Flow
removeNode(context, ast.tokens[idx]);

@@ -237,3 +313,3 @@ }

while (index > 0 && removedNodes[index - 1].end > node.start) {
while (index > 0 && endOf(removedNodes[index - 1]) > startOf(node)) {
index--;

@@ -286,10 +362,10 @@ }

}
return {
return createNode({
start: start,
end: start + size,
loc: {
start: { line: line, column: column },
end: { line: line, column: column + size },
start: {line: line, column: column},
end: {line: line, column: column + size},
},
};
});
}

@@ -299,3 +375,3 @@

var source = context.source;
var end = node.start;
var end = startOf(node);
var start = end;

@@ -306,7 +382,7 @@ while (source[start - 1] === ' ' || source[start - 1] === '\t') {

if (start !== end) {
return {
return createNode({
start: start,
end: end,
loc: { start: node.loc.start, end: node.loc.start }
};
loc: {start: node.loc.start, end: node.loc.start},
});
}

@@ -317,3 +393,3 @@ }

var source = context.source;
var start = node.end;
var start = endOf(node);
var end = start;

@@ -332,7 +408,7 @@ while (source[end] === ' ' || source[end] === '\t') {

if (isLastNodeRemovedFromLine(context, node)) {
return {
return createNode({
start: start,
end: end,
loc: { start: node.loc.end, end: node.loc.end }
};
loc: {start: node.loc.end, end: node.loc.end},
});
}

@@ -342,6 +418,17 @@ }

// Creates a zero-width "node" with a value to splice at that position.
// WARNING: This is only safe to use when source maps are off!
function getSpliceNodeAtPos(context, pos, loc, value) {
return createNode({
start: pos,
end: pos,
loc: {start: loc, end: loc},
__spliceValue: value,
});
}
// Returns true if node is the last to be removed from a line.
function isLastNodeRemovedFromLine(context, node) {
var tokens = context.ast.tokens;
var priorTokenIdx = findTokenIndex(tokens, node.start) - 1;
var priorTokenIdx = findTokenIndex(tokens, startOf(node)) - 1;
var token = tokens[priorTokenIdx];

@@ -351,6 +438,8 @@ var line = node.loc.end.line;

// Find previous token that was not removed on the same line.
while (priorTokenIdx >= 0 &&
token.loc.end.line === line &&
isRemovedToken(context, token)) {
token = tokens[--priorTokenIdx]
while (
priorTokenIdx >= 0 &&
token.loc.end.line === line &&
isRemovedToken(context, token)
) {
token = tokens[--priorTokenIdx];
}

@@ -369,3 +458,3 @@

// Find the last removed node which could possibly contain this token.
while (nodeIdx >= 0 && removedNodes[nodeIdx].start > token.start) {
while (nodeIdx >= 0 && startOf(removedNodes[nodeIdx]) > startOf(token)) {
nodeIdx--;

@@ -377,3 +466,3 @@ }

// This token couldn't be removed if not contained within the removed node.
if (nodeIdx === -1 || node.end < token.end) {
if (nodeIdx === -1 || endOf(node) < endOf(token)) {
return false;

@@ -384,4 +473,4 @@ }

var tokens = context.ast.tokens;
var tokenIdx = findTokenIndex(tokens, node.start);
while (tokens[tokenIdx].end <= node.end) {
var tokenIdx = findTokenIndex(tokens, startOf(node));
while (endOf(tokens[tokenIdx]) <= endOf(node)) {
if (token === tokens[tokenIdx]) {

@@ -396,3 +485,3 @@ return true;

// Given the AST output of babylon parse, walk through in a depth-first order,
// Given the AST output from the parser, walk through in a depth-first order,
// calling methods on the given visitor, providing context as the first argument.

@@ -413,3 +502,3 @@ function visit(ast, context, visitor) {

} else {
var node = parent ? parent[keys[index]] : ast.program;
var node = parent ? parent[keys[index]] : getProgram(ast);
if (node && typeof node === 'object' && (node.type || node.length)) {

@@ -422,3 +511,3 @@ if (node.type) {

}
stack = { parent: parent, keys: keys, index: index, prev: stack };
stack = {parent: parent, keys: keys, index: index, prev: stack};
parent = node;

@@ -439,7 +528,7 @@ keys = Object.keys(node);

while (min <= max) {
var ptr = (min + max) / 2 | 0;
var ptr = ((min + max) / 2) | 0;
var token = tokens[ptr];
if (token.end <= offset) {
if (endOf(token) <= offset) {
min = ptr + 1;
} else if (token.start > offset) {
} else if (startOf(token) > offset) {
max = ptr - 1;

@@ -456,3 +545,3 @@ } else {

function isComment(token) {
return token.type === 'CommentBlock' || token.type === 'CommentLine';
return token.type === 'Block' || token.type === 'Line';
}

@@ -462,3 +551,3 @@

function space(size) {
var sp = ' '
var sp = ' ';
var result = '';

@@ -487,3 +576,3 @@

var end = { line: 1, column: 0 };
var end = {line: 1, column: 0};

@@ -498,3 +587,3 @@ for (var i = 0; i < removedNodes.length; i++) {

}
mappings += vlq.encode([ start.column, 0, lineDiff, columnDiff ]);
mappings += vlq.encode([start.column, 0, lineDiff, columnDiff]);
} else if (columnDiff) {

@@ -504,3 +593,3 @@ if (i) {

}
mappings += vlq.encode([ columnDiff, 0, lineDiff, columnDiff ]);
mappings += vlq.encode([columnDiff, 0, lineDiff, columnDiff]);
}

@@ -510,3 +599,8 @@

mappings += ',';
mappings += vlq.encode([ 0, 0, end.line - start.line, end.column - start.column ]);
mappings += vlq.encode([
0,
0,
end.line - start.line,
end.column - start.column,
]);
}

@@ -516,1 +610,34 @@

}
/**
* A lightweight layer to abstract over the slightly different ASTs returned by
* Flow vs Babylon.
*/
function startOf(token) {
return token.range[0];
}
function endOf(token) {
return token.range[1];
}
function getComments(ast) {
return ast.comments;
}
function createNode(data) {
return {
range: [data.start, data.end],
loc: data.loc,
__spliceValue: data.__spliceValue,
};
}
function getLabel(token) {
return token.value;
}
function getProgram(ast) {
return ast;
}
{
"name": "flow-remove-types",
"version": "1.2.3",
"version": "2.99.0",
"description": "Removes Flow type annotations from JavaScript files with speed and simplicity.",
"author": "Lee Byron <lee@leebyron.com> (http://leebyron.com/)",
"license": "BSD-3-Clause",
"author": {
"name": "Flow Team",
"email": "flow@fb.com"
},
"contributors": [
"Lee Byron <lee@leebyron.com> (http://leebyron.com/)"
],
"license": "MIT",
"main": "index.js",

@@ -17,17 +23,15 @@ "bin": {

"flow-node",
"LICENSE",
"PATENTS"
"LICENSE"
],
"homepage": "https://github.com/flowtype/flow-remove-types",
"homepage": "https://flow.org",
"bugs": {
"url": "https://github.com/flowtype/flow-remove-types/issues"
"url": "https://github.com/facebook/flow/issues"
},
"repository": {
"type": "git",
"url": "http://github.com/flowtype/flow-remove-types.git"
"url": "https://github.com/facebook/flow.git"
},
"scripts": {
"test": "./test.sh",
"test-update": "./test-update.sh",
"postpublish": "./publish-npm-alias.sh"
"test-update": "./test-update.sh"
},

@@ -43,5 +47,9 @@ "keywords": [

"dependencies": {
"babylon": "^6.15.0",
"flow-parser": "^0.99.0",
"pirates": "^3.0.2",
"vlq": "^0.2.1"
},
"engines": {
"node": ">=4"
}
}

@@ -16,3 +16,3 @@ flow-remove-types

done via adding a plugin to your [Babel](https://babeljs.io/) configuration,
however Babel may be overkill if you're only targetting modern versions of
however Babel may be overkill if you're only targeting modern versions of
Node.js or just not using the modern ES2015 features that may not be in

@@ -128,6 +128,6 @@ every browser.

Built atop the excellent [`babylon`](https://github.com/babel/babylon) parser,
`flow-remove-types` shares the same parse rules as the source of truth as
Flow Babel plugins. It also passes through other common non-standard syntax such
as [JSX](https://facebook.github.io/jsx/) and experimental ECMAScript proposals.
Built atop the official Flow [parser](https://github.com/facebook/flow/tree/master/packages/flow-parser),
`flow-remove-types` is designed to operate on the same syntax Flow itself understands.
It also passes through other common non-standard syntax such as [JSX](https://facebook.github.io/jsx/)
and experimental ECMAScript proposals that Flow supports.

@@ -201,2 +201,4 @@ **Before:**

> *NOTE*: These timings are for `flow-remove-types` v1.
### Install:

@@ -203,0 +205,0 @@

@@ -0,2 +1,10 @@

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var flowRemoveTypes = require('./index');
var pirates = require('pirates');

@@ -14,31 +22,31 @@ // Supported options:

options = newOptions;
}
};
// Swizzle Module#_compile on each applicable module instance.
// NOTE: if using alongside Babel or another require-hook which simply
// over-writes the require.extensions and does not continue execution, then
// this require hook must come after it. Encourage those module authors to call
// the prior loader in their require hooks.
var jsLoader = require.extensions['.js'];
var exts = [ '.js', '.mjs', '.jsx', '.flow', '.es6' ];
exts.forEach(function (ext) {
var superLoader = require.extensions[ext] || jsLoader;
require.extensions[ext] = function (module, filename) {
if (shouldTransform(filename, options)) {
var super_compile = module._compile;
module._compile = function _compile(code, filename) {
super_compile.call(this, flowRemoveTypes(code, options).toString(), filename);
};
var exts = ['.js', '.mjs', '.jsx', '.flow', '.es6'];
var revert = pirates.addHook(
function hook(code, filename) {
try {
return flowRemoveTypes(code, options).toString();
} catch (e) {
e.message = filename + ': ' + e.message;
throw e;
}
superLoader(module, filename);
};
});
},
{exts: exts, matcher: shouldTransform}
);
function shouldTransform(filename, options) {
function shouldTransform(filename) {
var includes = options && regexpPattern(options.includes || options.include);
var excludes =
options && 'excludes' in options ? regexpPattern(options.excludes) :
options && 'exclude' in options ? regexpPattern(options.exclude) :
/\/node_modules\//;
return (!includes || includes.test(filename)) && !(excludes && excludes.test(filename));
options && 'excludes' in options
? regexpPattern(options.excludes)
: options && 'exclude' in options
? regexpPattern(options.exclude)
: /\/node_modules\//;
return (
(!includes || includes.test(filename)) &&
!(excludes && excludes.test(filename))
);
}

@@ -65,4 +73,6 @@

throw new Error(
'flow-remove-types: includes and excludes must be RegExp or path strings. Got: ' + pattern
'flow-remove-types: ' +
'includes and excludes must be RegExp or path strings. Got: ' +
pattern
);
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc