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 🙏

© 2025 – Pkg Stats / Ryan Hefner

cql2-filters-parser

v0.9.14

Published

A browser-oriented implementation of OGC CQL2 filters in TypeScript

Downloads

22

Readme

Open Geospatial Consortium (OGC) Common Query Language (CQL2) filter tooling

A browser-oriented implementation of OGC CQL2 filters in TypeScript. The goal of this library is to enable Javascript based application (Web apps, Node.js, etc) to search STAC catalogs.

OGC CQL2 Filters playground. Sourcemaps are available, feel free to look under the hood.

NPM Version

Installation

Getting cql2-filters-parser from npm:

npm install cql2-filters-parser

Browsers can load the library directly from unpkg.com:

import { parse } from "https://unpkg.com/cql2-filters-parser"

cql2-filters-parser library is published as ES module and is dependency free.

Usage

Both CQL2 Text and JSON encodings are supported. Parsing functions return an expression in tree structure. Expressions have toText and toJSON methods, which produce encoding in string or object respectively.

  • parseText(string) parses CQL2 Text
  • parseJSON(object) parses CQL2 JSON
  • parse(input) wraps parsing functions + simple heuristic

Using library in node module

import { parse, parseJSON, parseText } from "cql2-filters-parser";

const filter = parse("2+3");
console.log(filter.encoding); // Text
console.log(filter.expression.toJSON()); // { op: '+', args: [ 2, 3 ] }
console.log(filter.expression.toText()); // 2 + 3

Using from terminal

The npm run parse "my cql" script will parse and print both Text and JSON results

npm run parse "depth BETWEEN 100.0 AND 150.0"

Will output:

CQL2 Text:
depth BETWEEN 100 AND 150

CQL2 JSON:
{
  "op": "between",
  "args": [
    {
      "property": "depth"
    },
    100,
    150
  ]
}

Links

Implemented classes

High level design

---
Note: Mermaid diagrams don't work in npm. Please head over to GitHub.
title: CQL2 filter parser high level design
---
flowchart TD
    JS[JavaScript] --> IN[Input]
    SI["Standard input (stdin)"] --> IN[Input]
    FI[File input] --> IN[Input]
    IN --> |" parse(input) "| D{Detect encoding}

    %% CQL2 Text
    D --> | CQL2 Text | TS[Text scanner]
    TS --> | Tokens | TP[Text parser]

    %% CQL2 JSON
    D --> | CQL2 JSON | JSONP["JSON.parse()"]
    JSONP --> | JS object | JP[JSON parser]
    JP --> E

    %% Results
    TP --> E["Expression tree (AST)"]
    E --> TT[".toText()"]
    E --> VIS[".accept(visitor)"]
    E --> TJ[".toJSON()"]

    %% Visitor
    VIS --> | extend | Val[Validation]
    VIS --> | extend | UI[UI]
    VIS --> | extend | Eval[Evaluation]

Visitor

Expression tree also has accept(visitor, context) method that receive a visitor object as input. The visitor object should implement all visit functions. This enable producing output when traversing the expression tree. The optional context parameter enabled passing additional information for the visitor, such as current path to the expression.

import { parse } from "cql2-filters-parser";

const minimalArithmeticVisitor = {
  visitBinaryExpression: (expr) => {
    return [
      "Left side is " + expr.left.accept(minimalArithmeticVisitor),
      "Operator is " + expr.operator.accept(minimalArithmeticVisitor),
      "Right side is " + expr.right.accept(minimalArithmeticVisitor),
    ].join(". ");
  },
  visitLiteralExpression: (expr) => `${expr.type} ${expr.toText()}`,
  visitOperatorExpression: (expr) => expr.label,
};

const expr = parseText("2 + 3");
console.log(filter.expression.accept(minimalArithmeticVisitor)); // Left side is number 2. Operator is addition. Right side is number 3

More Visitor examples can be found in Expression.test.ts suite, or check out ReactVisitor for an advanced implementation.

Dependencies

The parsers runtime are dependency free. I'd like to publish the parsers as a separate module, but ATM that's not the case. In development there are multiple dependencies, but trying to keep them to minimum.

Playground is built with React.

Development

PRs welcome.

Folder structure

  • src - library root.
    • parse.ts - main parse function.
    • main.ts - for CLI.
    • entities - Expression classes, Tokens, operator's metadata.
    • parser - Text and JSON parsers.
    • types - folder with types that don't belong directly to either parser or entities folders.
  • examples - ATM only one: filter builder react app.
  • ci - Continues integration related files.

First time only

  • Clone the repository
  • Install dependencies npm install

Parsers development

Test driven development is advised, using npm run test. Vitest is the test runner.

Playground development

The Playground is powered by Vite and React, and can be found in examples folder. Run npm run dev to start dev server. For real experience use npm run build && npm run preview.

Checking everything

In no particular order:

  • Make sure you created a new branch, and commit changes
  • Run all checks (lint, type check, tests) - npm run checks.
  • ESlint + Prettier - npm run lint.
  • TypeScript type check - npm run type-check.
  • Tests - npm run tests for continues running test suite on fule change, or run just once using npm run tests:once.
  • Code coverage - npm run test:coverage - coverage is not enforced, but for parsers I try to have close to 100%. Exceptions are edge cases, which should throw.
  • Increment version - Each PR must increment version properly using npm version <major | minor | patch>. The CI test (npm run test:ci) enforces that.

When done, push branch and create a PR. Github Actions will run checks.

Publishing

Done manually. npm run publish:dry will run checks, create fresh build and display which files will be bundled. If everything's OK, npm publish will publish. Note that version must be incremented.