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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@esposter/azure

v4.0.0

Published

The Azure wire conventions Esposter's clients and its mocks both speak — OData filter clauses, entity key casing, and service limits.

Readme

@esposter/azure

Apache-2.0 licensed NPM version NPM downloads NPM Unpacked Size (with version)

The parts of Azure's wire contract that both a real client and a fake one have to agree on: the OData filter clause vocabulary shared by Table Storage and Search, the entity key casing convention, and the service limits. No SDK client is constructed here and no credential is read — this package is pure data and pure functions, so it runs anywhere.

Table of Contents


🚀 Getting Started

pnpm add @esposter/azure

📖 Documentation

Clauses

A Clause<T> is a filter condition expressed against a property of T, and it is what the OData string is built from rather than the string being assembled by hand. BinaryOperator covers the comparisons Table Storage understands; SearchOperator covers the collection predicates only Azure Search does; UnaryOperator is how clauses are combined.

import type { Clause } from "@esposter/azure";

import { BinaryOperator } from "@esposter/azure";

const clause: Clause<{ createdAt: Date }> = { key: "createdAt", operator: BinaryOperator.Ge, value: new Date(0) };

Values

serializeValue renders a SerializableValue the way the target service expects — Table Storage wants a datetime'<iso>' literal for a Date, Search wants the bare ISO string, and isTableFilter selects between them. Strings go through escapeValue, which doubles embedded single quotes so a value can never close its own literal and append filter syntax of its own.

import { escapeValue, serializeValue } from "@esposter/azure";

Filters

serializeClauses turns a clause array into a Table Storage filter string and serializeSearchClauses into a Search one; the two differ only in how a Date renders, which is why they share a single core. Clauses on the same key are grouped — a range pair is joined with and, anything else with or — so a caller never assembles the boolean structure by hand. deserializeClause is the inverse, and is what lets a fake client evaluate a filter it was handed rather than pattern-matching the string.

import { BinaryOperator, CompositeKeyPropertyNames, getTableNullClause, serializeClauses } from "@esposter/azure";

const roomId = "00000000-0000-0000-0000-000000000000";
const filter = serializeClauses([
  { key: CompositeKeyPropertyNames.partitionKey, operator: BinaryOperator.Eq, value: roomId },
  getTableNullClause("deletedAt"),
]);

Null is where the two services diverge and the helpers carry the difference: Table Storage cannot compare against null at all, so getTableNullClause expresses "is null" as a negated NaN comparison, while Search supports it directly through getSearchNullClause / getSearchNonNullClause. getPartitionKeyFilter is the one-clause case worth naming, since a read, a count and a purge of the same entity must all start from it.

Keys

CompositeKey is the partitionKey/rowKey pair every Table entity carries, and CompositeKeyPropertyNames is how those names are referred to without restating the strings. The wire spells those two capitalized and JavaScript does not, so serializeKey and deserializeKey convert at the boundary and nothing in between has to know.

import { CompositeKey, CompositeKeyPropertyNames, serializeKey } from "@esposter/azure";

Limits

AZURE_MAX_BATCH_SIZE, AZURE_MAX_PAGE_SIZE and AZURE_MAX_QUEUE_VISIBILITY_TIMEOUT_MS are the service's own ceilings, named so a caller paginating, batching or enqueueing does not hard-code them.

Commands

Run from packages/azure/:

pnpm build        # compile to dist/
pnpm test         # vitest watch mode (coverage is run from the repo root)
pnpm lint:fix     # auto-fix lint
pnpm typecheck    # type check

⚖️ License

This project is licensed under the Apache-2.0 license.