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

@fimbul/mimir

Package Overview
Dependencies
Maintainers
2
Versions
125
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fimbul/mimir - npm Package Compare versions

Comparing version 0.9.0-dev.20180505 to 0.9.0

docs/no-inferred-empty-object.md

5

docs/await-only-promise.md

@@ -5,3 +5,3 @@ # await-only-promise

Disallows `await`ing a non-Promise value. Also disallows `for-await-of` looping over an Iterable instead of AsyncIterable value.
Disallows `await`ing a non-Promise value. Also enforces `for-await-of` to loop over an `AsyncIterable<any>` or an `Iterable<PromiseLike<any>>` value.

@@ -35,4 +35,5 @@ ## Rationale

for await (const e of iterable) {} // iterating `AsyncIterable`
for await (const e of iterable) {} // iterating `AsyncIterable<any>`
for await (const v of [Promise.resolve(promise)]) {} // iterating `Iterable<PromiseLike<any>>`
}
```

4

docs/no-duplicate-spread-property.md

@@ -7,2 +7,6 @@ # no-duplicate-spread-property

## Requirements
This rule requires the compiler option `strictNullChecks` to be enabled and TypeScript 2.5 or newer.
## Rationale

@@ -9,0 +13,0 @@

{
"name": "@fimbul/mimir",
"version": "0.9.0-dev.20180505",
"version": "0.9.0",
"description": "Core rules of the Fimbullinter project",

@@ -28,3 +28,3 @@ "main": "recommended.yaml",

"dependencies": {
"@fimbul/ymir": "0.9.0-dev.20180505",
"@fimbul/ymir": "^0.9.0",
"chalk": "^2.3.2",

@@ -31,0 +31,0 @@ "debug": "^3.1.0",

@@ -33,8 +33,8 @@ # Mímir

[`no-fallthrough`](docs/no-fallthrough.md) | Prevents unintentional fallthough in `switch` statements from one case to another. | Allows more comment variants such as `fallthrough` or `fall through`.
`no-inferred-empty-object` | Warns if a type parameter is inferred as `{}` because the compiler cannot find any inference site. *requires type information* | Really checks every type parameter of function, method and constructor calls. Correctly handles type parameters from JSDoc comments. Recognises type parameter defaults on all merged declarations.
`no-invalid-assertion` | Disallows asserting a literal type to a different literal type of the same widened type, e.g. `'foo' as 'bar'`. *requires type information* | TSLint has no similar rule.
`no-misused-generics` | Detects generic type parameters that cannot be inferred from the functions parameters. It also detects generics that don't enforce any constraint between types. | There's no similar TSLint rule.
`no-nan-compare` | Don't compare with `NaN`, use `isNaN(number)` or `Number.isNaN(number)` instead. | Performance!
`no-return-await` | Warns for unnecesary `return await foo;` when you can simply `return foo;` | The same as TSLint's rule. I wrote both, but this one is faster.
`no-unassigned-variable` | Detects variables that are not initialized and never assigned a value. | There's no similar TSLint rule.
[`no-inferred-empty-object`](docs/no-inferred-empty-object.md) | :mag: Detects type parameters that are inferred as `{}` because the compiler cannot infer a type. | Really checks every type parameter of function, method and constructor calls. Correctly handles type parameters from JSDoc comments. Recognises type parameter defaults on all merged declarations.
[`no-invalid-assertion`](docs/no-invalid-assertion.md) | :mag: Disallows asserting a literal type to a different literal type of the same widened type, e.g. `'foo' as 'bar'`.| TSLint has no similar rule.
[`no-misused-generics`](docs/no-misused-generics.md) | Detects generic type parameters that cannot be inferred from the functions parameters. It also detects generics that don't enforce any constraint between types. | There's no similar TSLint rule.
[`no-nan-compare`](docs/no-nan-compare.md) | Disallows comparing with `NaN`, use `isNaN(number)` or `Number.isNaN(number)` instead. | Performance!
[`no-return-await`](docs/no-return-await.md) | Disallows unnecesary `return await foo;` when you can simply `return foo;` | The same as TSLint's rule. I wrote both, but this one is faster.
[`no-unassigned-variable`](docs/no-unassigned-variable.md) | Detects variables that are not initialized and never assigned a value. | There's no similar TSLint rule.
`no-unreachable-code` | Warns about statements that will never be executed. Works like TypeScript's dead code detection but doesn't fail compilation because it's a lint error. | TSLint removed their `no-unreachable` rule in v4.0.0.

@@ -41,0 +41,0 @@ `no-unsafe-finally` | Forbids control flow statements `return`, `throw`, `break` and `continue` inside the `finally` block of a try statement. | Performance!

import { TypedRule } from '@fimbul/ymir';
export declare class Rule extends TypedRule {
apply(): void;
private isPromiseLike(node);
private maybePromiseLike(type, node);
private isThenable(type, node);
private isAsyncIterable(node);
private hasSymbolAsyncIterator(type);
private isIterableOfPromises(type, node);
}

@@ -14,3 +14,4 @@ "use strict";

if (tsutils_1.isAwaitExpression(node)) {
if (node.expression.pos === re.lastIndex && !this.isPromiseLike(node.expression))
if (node.expression.pos === re.lastIndex &&
!this.maybePromiseLike(this.checker.getTypeAtLocation(node.expression), node.expression))
this.addFailure(match.index, node.end, "Unnecessary 'await' of a non-Promise value.", ymir_1.Replacement.delete(match.index, node.expression.getStart(this.sourceFile)));

@@ -27,4 +28,4 @@ }

}
isPromiseLike(node) {
const type = this.checker.getApparentType(this.checker.getTypeAtLocation(node));
maybePromiseLike(type, node) {
type = this.checker.getApparentType(type);
if (type.flags & ts.TypeFlags.Any)

@@ -46,3 +47,3 @@ return true;

for (const t of tsutils_1.unionTypeParts(type))
if (this.hasSymbolAsyncIterator(t))
if (this.hasSymbolAsyncIterator(t) || this.isIterableOfPromises(t, node))
return true;

@@ -52,4 +53,32 @@ return false;

hasSymbolAsyncIterator(type) {
return type.getProperties().some((prop) => prop.name === '__@asyncIterator');
return type.getProperties().some((prop) => symbolName(prop) === '__@asyncIterator');
}
isIterableOfPromises(type, node) {
const symbol = type.getProperties().find((prop) => symbolName(prop) === '__@iterator');
if (symbol === undefined)
return false;
const t = this.checker.getApparentType(this.checker.getTypeOfSymbolAtLocation(symbol, node));
if (t.flags & ts.TypeFlags.Any)
return true;
for (const signature of t.getCallSignatures()) {
const returnType = this.checker.getApparentType(signature.getReturnType());
if (returnType.flags & ts.TypeFlags.Any)
return true;
const next = returnType.getProperty('next');
if (next === undefined)
continue;
const nextType = this.checker.getApparentType(this.checker.getTypeOfSymbolAtLocation(next, node));
if (nextType.flags & ts.TypeFlags.Any)
return true;
for (const nextSignature of nextType.getCallSignatures()) {
const nextReturnType = this.checker.getApparentType(nextSignature.getReturnType());
if (nextReturnType.flags & ts.TypeFlags.Any)
return true;
const value = nextReturnType.getProperty('value');
if (value !== undefined && this.maybePromiseLike(this.checker.getTypeOfSymbolAtLocation(value, node), node))
return true;
}
}
return false;
}
};

@@ -60,2 +89,5 @@ Rule = tslib_1.__decorate([

exports.Rule = Rule;
function symbolName(s) {
return s.escapedName === undefined ? s.name : s.escapedName;
}
//# sourceMappingURL=await-only-promise.js.map
import { AbstractRule } from '@fimbul/ymir';
export declare class Rule extends AbstractRule {
apply(): void;
private getLiteralValue(node, cb);
private getLiteralValue(node);
}

@@ -22,11 +22,19 @@ "use strict";

expressionsSeen.add(text);
this.getLiteralValue(clause.expression, (v) => {
if (valuesSeen.has(v))
return this.addFailureAtNode(clause.expression, `Duplicate 'case ${typeof v === 'string' ? `"${v}"` : String(v)}'.`);
valuesSeen.add(v);
});
const literals = this.getLiteralValue(clause.expression);
switch (literals.length) {
case 0:
break;
case 1:
if (valuesSeen.has(literals[0]))
this.addFailureAtNode(clause.expression, `Duplicate 'case ${formatPrimitive(literals[0])}'.`);
valuesSeen.add(literals[0]);
break;
default:
if (literals.every((v) => valuesSeen.has(v)))
this.addFailureAtNode(clause.expression, `Duplicate 'case ${literals.map(formatPrimitive).join(' | ')}'.`);
}
}
}
}
getLiteralValue(node, cb) {
getLiteralValue(node) {
let prefixFn = identity;

@@ -36,3 +44,3 @@ while (tsutils_1.isPrefixUnaryExpression(node)) {

if (next === undefined)
return;
return [];
prefixFn = next;

@@ -42,26 +50,37 @@ node = node.operand;

if (tsutils_1.isTextualLiteral(node))
return cb(prefixFn(node.text));
return [prefixFn(node.text)];
if (tsutils_1.isNumericLiteral(node))
return cb(prefixFn(+node.text));
return [prefixFn(+node.text)];
if (node.kind === ts.SyntaxKind.NullKeyword)
return cb(prefixFn(null));
return [prefixFn(null)];
if (tsutils_1.isIdentifier(node) && node.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword)
return cb(prefixFn(undefined));
return [prefixFn(undefined)];
if (node.kind === ts.SyntaxKind.TrueKeyword)
return cb(prefixFn(true));
return [prefixFn(true)];
if (node.kind === ts.SyntaxKind.FalseKeyword)
return cb(prefixFn(false));
return [prefixFn(false)];
if (this.program === undefined)
return;
return [];
const checker = this.program.getTypeChecker();
let type = checker.getTypeAtLocation(node);
type = checker.getBaseConstraintOfType(type) || type;
if (tsutils_1.isLiteralType(type))
return cb(prefixFn(type.value));
if (type.flags & ts.TypeFlags.BooleanLiteral)
return cb(prefixFn(type.intrinsicName === 'true'));
if (type.flags & ts.TypeFlags.Undefined)
return cb(prefixFn(undefined));
if (type.flags & ts.TypeFlags.Null)
return cb(prefixFn(null));
const result = new Set();
for (const t of tsutils_1.unionTypeParts(type)) {
if (tsutils_1.isLiteralType(t)) {
result.add(prefixFn(t.value));
}
else if (t.flags & ts.TypeFlags.BooleanLiteral) {
result.add(prefixFn(t.intrinsicName === 'true'));
}
else if (t.flags & ts.TypeFlags.Undefined) {
result.add(prefixFn(undefined));
}
else if (t.flags & ts.TypeFlags.Null) {
result.add(prefixFn(null));
}
else {
return [];
}
}
return Array.from(result);
}

@@ -90,2 +109,5 @@ };

}
function formatPrimitive(v) {
return typeof v === 'string' ? `"${v}"` : String(v);
}
//# sourceMappingURL=no-duplicate-case.js.map

@@ -31,5 +31,12 @@ "use strict";

for (let i = properties.length - 1; i >= 0; --i) {
const info = this.getPropertyInfo(properties[i]);
if (info.known && info.names.every((name) => propertiesSeen.has(name)))
this.addFailureAtNode(properties[i], 'Property is overridden later.');
const property = properties[i];
const info = this.getPropertyInfo(property);
if (info.known && info.names.every((name) => propertiesSeen.has(name))) {
if (property.kind === ts.SyntaxKind.SpreadAssignment) {
this.addFailureAtNode(property, 'All properties of this object are overridden later.');
}
else {
this.addFailureAtNode(property.name, `Property '${property.name.getText(this.sourceFile)}' is overridden later.`);
}
}
for (const name of info.assignedNames)

@@ -36,0 +43,0 @@ propertiesSeen.add(name);

@@ -125,2 +125,4 @@ "use strict";

function getTypeParameters(node) {
if (node.typeParameters !== undefined)
return node.typeParameters;
if (node.flags & ts.NodeFlags.JavaScriptFile) {

@@ -130,4 +132,4 @@ const tag = ts.getJSDocTemplateTag(node);

}
return node.typeParameters;
return;
}
//# sourceMappingURL=no-inferred-empty-object.js.map

@@ -141,3 +141,7 @@ "use strict";

return false;
return findupFunction(node.parent.parent.parent) === findupFunction(declaration.parent.parent.parent);
const declaringFunctionScope = findupFunction(declaration.parent.parent.parent);
let useFunctionScope = findupFunction(node.parent.parent);
while (useFunctionScope !== declaringFunctionScope && isIife(useFunctionScope))
useFunctionScope = findupFunction(useFunctionScope.parent.parent);
return useFunctionScope === declaringFunctionScope;
}

@@ -149,2 +153,14 @@ function findupFunction(node) {

}
function isIife(node) {
if (!tsutils_1.isFunctionExpression(node) && !tsutils_1.isArrowFunction(node) ||
node.asteriskToken !== undefined ||
tsutils_1.hasModifier(node.modifiers, ts.SyntaxKind.AsyncKeyword))
return false;
let prev;
do {
prev = node;
node = node.parent;
} while (node.kind === ts.SyntaxKind.ParenthesizedExpression);
return tsutils_1.isCallExpression(node) && node.expression === prev;
}
function couldBeTupleType(type) {

@@ -151,0 +167,0 @@ const properties = type.getProperties();

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

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