Socket
Socket
Sign inDemoInstall

tsutils

Package Overview
Dependencies
Maintainers
1
Versions
94
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tsutils - npm Package Compare versions

Comparing version 3.10.0 to 3.11.0

19

CHANGELOG.md

@@ -0,1 +1,20 @@

# 3.11.0
**Features:**
* typeguards: `isNumericOrStringLikeLiteral`, `isTupleTypeReference`
* `intersectionTypeParts` as counterpart to `unionTypeParts`
* `someTypePart` to execute a callback for each union or intersection constituent until the callback returns true
* `getPropertyOfType` looks up a property by its escaped name
* `isPropertyReadonlyInType` determines whether a property in a given type cannot be written to
* `symbolHasReadonlyDeclaration` determines if a Symbol has any readonly or constant declaration
* `isNumericPropertyName` determines whether a property name would match an index signature
* `isBindableObjectDefinePropertyCall` returns true for statically analyzable forms of `Object.defineProperty(o, 'p', {value, writable})`
* `isReadonlyAssignmentDeclaration` determines whether an `Object.defineProperty` call is known to result in a readonly property
* `getLateBoundPropertyNames` returns all known property names of an expression
* `getPropertyNameFromType` extracts the property name of literal types
* `isWellKnownSymbolLiterally` to recognize expressions in the form of `Symbol.<name>`
* `getPropertyNameOfWellKnownSymbol` returns the escaped name for a well known symbol literal
* `unwrapParentheses` returns the first child expression that is not a `ParenthesizedExpression`
# 3.10.0

@@ -2,0 +21,0 @@

6

package.json
{
"name": "tsutils",
"version": "3.10.0",
"version": "3.11.0",
"description": "utilities for working with typescript's AST",

@@ -50,6 +50,6 @@ "scripts": {

"ttypescript": "^1.5.5",
"typescript": "^3.4.1"
"typescript": "^3.4.5"
},
"peerDependencies": {
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev"
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev"
},

@@ -56,0 +56,0 @@ "dependencies": {

@@ -108,2 +108,3 @@ import * as ts from 'typescript';

export declare function isNumericLiteral(node: ts.Node): node is ts.NumericLiteral;
export declare function isNumericOrStringLikeLiteral(node: ts.Node): node is ts.NumericLiteral | ts.StringLiteral | ts.NoSubstitutionTemplateLiteral;
export declare function isObjectBindingPattern(node: ts.Node): node is ts.ObjectBindingPattern;

@@ -110,0 +111,0 @@ export declare function isObjectLiteralExpression(node: ts.Node): node is ts.ObjectLiteralExpression;

@@ -509,2 +509,13 @@ "use strict";

exports.isNumericLiteral = isNumericLiteral;
function isNumericOrStringLikeLiteral(node) {
switch (node.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
return true;
default:
return false;
}
}
exports.isNumericOrStringLikeLiteral = isNumericOrStringLikeLiteral;
function isObjectBindingPattern(node) {

@@ -511,0 +522,0 @@ return node.kind === ts.SyntaxKind.ObjectBindingPattern;

export * from '../2.9/type';
import * as ts from 'typescript';
export declare function isTupleType(type: ts.Type): type is ts.TupleType;
export declare function isTupleTypeReference(type: ts.Type): type is ts.TypeReference & {
target: ts.TupleType;
};

@@ -6,2 +6,3 @@ "use strict";

const ts = require("typescript");
const _3_2_1 = require("../3.2");
function isTupleType(type) {

@@ -11,1 +12,5 @@ return (type.flags & ts.TypeFlags.Object && type.objectFlags & ts.ObjectFlags.Tuple) !== 0;

exports.isTupleType = isTupleType;
function isTupleTypeReference(type) {
return _3_2_1.isTypeReference(type) && isTupleType(type.target);
}
exports.isTupleTypeReference = isTupleTypeReference;
import * as ts from 'typescript';
import { PropertyName } from './util';
export declare function isEmptyObjectType(type: ts.Type): type is ts.ObjectType;

@@ -8,4 +9,11 @@ export declare function removeOptionalityFromType(checker: ts.TypeChecker, type: ts.Type): ts.Type;

export declare function unionTypeParts(type: ts.Type): ts.Type[];
export declare function intersectionTypeParts(type: ts.Type): ts.Type[];
export declare function someTypePart(type: ts.Type, predicate: (t: ts.Type) => t is ts.UnionOrIntersectionType, cb: (t: ts.Type) => boolean): boolean;
export declare function isThenableType(checker: ts.TypeChecker, node: ts.Node, type: ts.Type): boolean;
export declare function isThenableType(checker: ts.TypeChecker, node: ts.Expression, type?: ts.Type): boolean;
export declare function isFalsyType(type: ts.Type): boolean;
export declare function isBooleanLiteralType(type: ts.Type, literal: boolean): boolean;
export declare function getPropertyOfType(type: ts.Type, name: ts.__String): ts.Symbol | undefined;
export declare function isPropertyReadonlyInType(type: ts.Type, name: ts.__String, checker: ts.TypeChecker): boolean;
export declare function symbolHasReadonlyDeclaration(symbol: ts.Symbol, checker: ts.TypeChecker): boolean;
export declare function getPropertyNameFromType(type: ts.Type): PropertyName | undefined;

@@ -6,2 +6,3 @@ "use strict";

const util_1 = require("./util");
const node_1 = require("../typeguard/node");
function isEmptyObjectType(type) {

@@ -95,2 +96,10 @@ if (type_1.isObjectType(type) &&

exports.unionTypeParts = unionTypeParts;
function intersectionTypeParts(type) {
return type_1.isIntersectionType(type) ? type.types : [type];
}
exports.intersectionTypeParts = intersectionTypeParts;
function someTypePart(type, predicate, cb) {
return predicate(type) ? type.types.some(cb) : cb(type);
}
exports.someTypePart = someTypePart;
function isThenableType(checker, node, type = checker.getTypeAtLocation(node)) {

@@ -127,6 +136,86 @@ for (const ty of unionTypeParts(checker.getApparentType(type))) {

return !type.value;
if (type.flags & ts.TypeFlags.BooleanLiteral)
return type.intrinsicName === 'false';
return isBooleanLiteralType(type, false);
}
exports.isFalsyType = isFalsyType;
function isBooleanLiteralType(type, literal) {
return util_1.isTypeFlagSet(type, ts.TypeFlags.BooleanLiteral) &&
type.intrinsicName === (literal ? 'true' : 'false');
}
exports.isBooleanLiteralType = isBooleanLiteralType;
function getPropertyOfType(type, name) {
return type.getProperties().find((s) => s.escapedName === name);
}
exports.getPropertyOfType = getPropertyOfType;
function isPropertyReadonlyInType(type, name, checker) {
let seenProperty = false;
let seenReadonlySignature = false;
for (const t of unionTypeParts(type)) {
if (getPropertyOfType(t, name) === undefined) {
const index = (util_1.isNumericPropertyName(name) ? checker.getIndexInfoOfType(t, ts.IndexKind.Number) : undefined) ||
checker.getIndexInfoOfType(t, ts.IndexKind.String);
if (index !== undefined && index.isReadonly) {
if (seenProperty)
return true;
seenReadonlySignature = true;
}
}
else if (seenReadonlySignature || isReadonlyPropertyIntersection(t, name, checker)) {
return true;
}
else {
seenProperty = true;
}
}
return false;
}
exports.isFalsyType = isFalsyType;
exports.isPropertyReadonlyInType = isPropertyReadonlyInType;
function isReadonlyPropertyIntersection(type, name, checker) {
return someTypePart(type, type_1.isIntersectionType, (t) => {
const prop = getPropertyOfType(t, name);
if (prop === undefined)
return false;
if (prop.flags & ts.SymbolFlags.Transient) {
if (/^(?:[1-9]\d*|0)$/.test(name) && type_1.isTupleTypeReference(t))
return t.target.readonly;
switch (isReadonlyPropertyFromMappedType(t, name, checker)) {
case true:
return true;
case false:
return false;
default:
}
}
return (util_1.isSymbolFlagSet(prop, ts.SymbolFlags.ValueModule) ||
symbolHasReadonlyDeclaration(prop, checker));
});
}
function isReadonlyPropertyFromMappedType(type, name, checker) {
if (!type_1.isObjectType(type) || !util_1.isObjectFlagSet(type, ts.ObjectFlags.Mapped))
return;
const declaration = type.symbol.declarations[0];
if (declaration.readonlyToken !== undefined && !/^__@[^@]+$/.test(name))
return declaration.readonlyToken.kind !== ts.SyntaxKind.MinusToken;
return isPropertyReadonlyInType(type.modifiersType, name, checker);
}
function symbolHasReadonlyDeclaration(symbol, checker) {
return (symbol.flags & ts.SymbolFlags.Accessor) === ts.SymbolFlags.GetAccessor ||
symbol.declarations !== undefined &&
symbol.declarations.some((node) => util_1.isModifierFlagSet(node, ts.ModifierFlags.Readonly) ||
node_1.isVariableDeclaration(node) && util_1.isNodeFlagSet(node.parent, ts.NodeFlags.Const) ||
node_1.isCallExpression(node) && util_1.isReadonlyAssignmentDeclaration(node, checker) ||
node_1.isEnumMember(node) ||
(node_1.isPropertyAssignment(node) || node_1.isShorthandPropertyAssignment(node)) && util_1.isInConstContext(node.parent));
}
exports.symbolHasReadonlyDeclaration = symbolHasReadonlyDeclaration;
function getPropertyNameFromType(type) {
if (type.flags & (ts.TypeFlags.StringLiteral | ts.TypeFlags.NumberLiteral)) {
const value = String(type.value);
return { displayName: value, symbolName: ts.escapeLeadingUnderscores(value) };
}
if (type_1.isUniqueESSymbolType(type))
return {
displayName: `[${type.symbol ? type.symbol.name : type.escapedName.replace(/^__@|@\d+$/g, '')}]`,
symbolName: type.escapedName,
};
}
exports.getPropertyNameFromType = getPropertyNameFromType;

@@ -82,2 +82,3 @@ import * as ts from 'typescript';

export declare function isValidJsxIdentifier(text: string): boolean;
export declare function isNumericPropertyName(name: string | ts.__String): boolean;
export declare function isSameLine(sourceFile: ts.SourceFile, pos1: number, pos2: number): boolean;

@@ -137,1 +138,21 @@ export declare enum SideEffectOptions {

export declare function isInConstContext(node: ts.Expression): boolean;
export declare function isReadonlyAssignmentDeclaration(node: ts.CallExpression, checker: ts.TypeChecker): boolean;
export declare function isBindableObjectDefinePropertyCall(node: ts.CallExpression): boolean;
export interface WellKnownSymbolLiteral extends ts.PropertyAccessExpression {
expression: ts.Identifier & {
text: 'Symbol';
escapedText: 'symbol';
};
}
export declare function isWellKnownSymbolLiterally(node: ts.Expression): node is WellKnownSymbolLiteral;
export interface PropertyName {
displayName: string;
symbolName: ts.__String;
}
export declare function getPropertyNameOfWellKnownSymbol(node: WellKnownSymbolLiteral): PropertyName;
export interface LateBoundPropertyNames {
known: boolean;
names: PropertyName[];
}
export declare function getLateBoundPropertyNames(node: ts.Expression, checker: ts.TypeChecker): LateBoundPropertyNames;
export declare function unwrapParentheses(node: ts.Expression): ts.Expression;

@@ -6,2 +6,3 @@ "use strict";

const _3_2_1 = require("../typeguard/3.2");
const type_1 = require("./type");
function getChildOfKind(node, kind, sourceFile) {

@@ -547,2 +548,6 @@ for (const child of node.getChildren(sourceFile))

exports.isValidJsxIdentifier = isValidJsxIdentifier;
function isNumericPropertyName(name) {
return String(+name) === name;
}
exports.isNumericPropertyName = isNumericPropertyName;
function isSameLine(sourceFile, pos1, pos2) {

@@ -1226,1 +1231,69 @@ return ts.getLineAndCharacterOfPosition(sourceFile, pos1).line === ts.getLineAndCharacterOfPosition(sourceFile, pos2).line;

exports.isInConstContext = isInConstContext;
function isReadonlyAssignmentDeclaration(node, checker) {
if (!isBindableObjectDefinePropertyCall(node))
return false;
const descriptorType = checker.getTypeAtLocation(node.arguments[2]);
if (descriptorType.getProperty('value') === undefined)
return descriptorType.getProperty('set') === undefined;
const writableProp = descriptorType.getProperty('writable');
if (writableProp === undefined)
return false;
const writableType = writableProp.valueDeclaration !== undefined && node_1.isPropertyAssignment(writableProp.valueDeclaration)
? checker.getTypeAtLocation(writableProp.valueDeclaration.initializer)
: checker.getTypeOfSymbolAtLocation(writableProp, node.arguments[2]);
return type_1.isBooleanLiteralType(writableType, false);
}
exports.isReadonlyAssignmentDeclaration = isReadonlyAssignmentDeclaration;
function isBindableObjectDefinePropertyCall(node) {
return node.arguments.length === 3 &&
node_1.isEntityNameExpression(node.arguments[0]) &&
node_1.isNumericOrStringLikeLiteral(node.arguments[1]) &&
node_1.isPropertyAccessExpression(node.expression) &&
node.expression.name.escapedText === 'defineProperty' &&
node_1.isIdentifier(node.expression.expression) &&
node.expression.expression.escapedText === 'Object';
}
exports.isBindableObjectDefinePropertyCall = isBindableObjectDefinePropertyCall;
function isWellKnownSymbolLiterally(node) {
return ts.isPropertyAccessExpression(node) &&
ts.isIdentifier(node.expression) &&
node.expression.escapedText === 'Symbol';
}
exports.isWellKnownSymbolLiterally = isWellKnownSymbolLiterally;
function getPropertyNameOfWellKnownSymbol(node) {
return {
displayName: `[Symbol.${node.name.text}]`,
symbolName: ('__@' + node.name.text),
};
}
exports.getPropertyNameOfWellKnownSymbol = getPropertyNameOfWellKnownSymbol;
function getLateBoundPropertyNames(node, checker) {
const result = {
known: true,
names: [],
};
node = unwrapParentheses(node);
if (isWellKnownSymbolLiterally(node)) {
result.names.push(getPropertyNameOfWellKnownSymbol(node));
}
else {
const type = checker.getTypeAtLocation(node);
for (const key of type_1.unionTypeParts(checker.getBaseConstraintOfType(type) || type)) {
const propertyName = type_1.getPropertyNameFromType(key);
if (propertyName) {
result.names.push(propertyName);
}
else {
result.known = false;
}
}
}
return result;
}
exports.getLateBoundPropertyNames = getLateBoundPropertyNames;
function unwrapParentheses(node) {
while (node.kind === ts.SyntaxKind.ParenthesizedExpression)
node = node.expression;
return node;
}
exports.unwrapParentheses = unwrapParentheses;
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