npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

estree-sentry

v0.4.1

Published

A more precise [ESTree](https://github.com/estree/estree) type with support for generic annotations.

Downloads

92

Readme

ESTreeSentry

A more precise ESTree type with support for generic annotations.

Relationship between estree and estree-sentry

ESTree and its typescript type definition @types/estree are great but many valid estree.Program are nonsensical, which limits the benefits TypeScript's type system provides. The presence of nonsensical nodes in ESTree is intentional and due to its contextless philosophy. For instance, the key of a non-computed member expression can be an arbitrary expression but only an identifier or a private identifier would be sensible. This forces consumers to bypass the type system with ugly type assertions such as the as Identifier | PrivateIdentifier below:

import { MemberExpression, Identifier, PrivateIdentifier } from "estree";
export const getNonComputedKey = (node: MemberExpression): string | null =>
  node.computed ? null : (node.property as Identifier | PrivateIdentifier).name;

ESTreeSentry is almost a subset of ESTree that removes many nonsensical nodes at the price of abandoning its contextless philosophy and adding more type definitions. This makes nodes easier to consume but harder to produce.

import { MemberExpression } from "estree-sentry";
export const getNonComputedKey = (node: MemberExpression<{}>): string | null =>
  node.computed ? null : node.property.name;

Additionally, ESTreeSentry offers two features that leverage the TypeScript type system further:

  • Nodes are recursively parameterized by annotations. This makes it possible to enforce type constraints on annotations such as code location. For instance, the JSON below is a valid Expression<{foo:123}>:
    {
      "type": "UnaryExpression",
      "operator": "!",
      "prefix": true,
      "argument": {
        "type": "Identifier",
        "name": "x",
        "foo": 123
      },
      "foo": 123
    }
  • Arbitrary strings are branded to make types more explicit and prevent mix-ups. For instance, VariableName brands the name of identifiers when used in an expression context and LabelName brands the name of identifiers when used in a label context.

Removed Nonsensical Nodes

  • Module declarations cannot appear in script programs.
  • Optional expressions cannot appear outside chain expressions.
  • Rest elements cannot appear outside object patterns, array patterns, or function parameters.
  • In module declarations, the source literal and the specifier literals are always strings.
  • In expression arrows, the body is an expression. And in block arrows, the body is a block.
  • In update expressions, the argument can only be an identifier or a member expression.
  • In Assignment expressions with compound operator (eg: +=), the left-hand side can only be an identifier, a member expression, or a call expression.
  • In non-computed member expressions, the key can only be an identifier or a private identifier.
  • In non-computed object properties, the key can only be an identifier or a literal.
  • In non-computed class definitions, the key can only be an identifier, a private identifier, or a literal.
  • In class constructor definitions, the key is always constructor and the function value does not have an id, cannot be a generator, and cannot be asynchronous.
  • In object method properties and class method definition, the value can only be a function expression without id.
  • In object accessor properties and class accessor definitions, the value:
    • con only be function expression (only relevant for object properties)
    • has the correct arity (0 for getters and 1 for setters).
    • does not have in id
    • cannot be a generator
    • cannot be asynchronous

Additional Nodes

  • In binary expressions with in operator, the left operand can be a private identifier.
  • In assignment expressions, the left-hand side can be a call expression. Yes, this is valid JavaScript. I'm not aware of any functions that will make this not through a ReferenceError though.

API

typedoc

  • Node Complete list of node types
  • KindRecord Grouping of node types as they appear in Node properties.
  • guardProgram Return a deep copy of the given node if it is a valid ESTreeSentry program. Throws a EstreeSentrySyntaxError otherwise.
  • annotateProgram Return a deep copy of the given node with annotations if it is a valid ESTreeSentry program. Throws a EstreeSentrySyntaxError otherwise.
  • EstreeSentrySyntaxError Class of errors thrown by guard functions. It has a cause property if the message property does not provide enough information.
  • listChildren Returns the children of the given node in a new array.
  • ROOT_PATH The default root path: "$".
  • splitPath Split a path into segments who each represents a property name.
  • walkPath Walk a split path from a root node to a target node.