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

@volter/twin-azure

v0.1.37

Published

Local Azure twin — ONE faithful, stateful local Azure API your unmodified Azure SDKs talk to, organized as SERVICE AREAS over a shared auth/error core (SharedKey HMAC + connection strings + Entra bearer). Area 1, Blob Storage (`@azure/storage-blob`): cont

Readme

@volter/twin-azure

Legacy connector helpers: this package still has callable helpers using the retired v1 syncPull API. Those paths require migration before use on the current kernel; older helper descriptions below do not establish current compatibility. Check the generated index for protocol standing and use the shared model for current state semantics.

Blob Storage simulation writes keep immutable SHA-256-addressed payloads under the service's resources/blobs/ directory. Blob and block actions carry references in the internal data_b64 slot; copies share payloads. Legacy inline data remains readable. Move the complete service directory, not just its logs; reads verify hashes and fail on missing/corrupt blobs.

Within one serving host, mutations to the same World are ordered across asynchronous blob I/O, preserving revision, block-length validation and commit ordering. Reads and separate World roots remain concurrent; idle ordering entries are removed. This is not cross-process mutation isolation, and simultaneous large requests can still hold their current bodies in memory.

Connector pulls and confirmed observations stay inline for self-contained event-only forks. The memory reduction covers local writes, not large mirror imports. Downloads and block-list completion still buffer the requested object. Overwritten/discarded blocks and other immutable payloads remain until world teardown because history may reference them; no automatic history rewrite or blob GC occurs.

A local Azure twin — ONE faithful, stateful local Azure API your real Azure SDKs talk to unmodified, organized as service areas over a single shared auth / error core. Azure is one vendor; Blob Storage, Azure OpenAI and Entra ID are service-areas of it (the same ruling the aws pack applies to S3 / DynamoDB / Timestream), so they share this pack — one router, one server, one manifest — while each area keeps its own kernel service namespace so state never collides. Built on the shared @volter/world-core kernel (durable append-only event log + projection + local actions + egress ledger). Mirror real Azure, simulate locally, fork, and reconcile.

Unlike AWS, Azure's areas do not share a wire format. That is the one structural difference this family carries: the shared core holds an error envelope per wire, and the router answers a request in the envelope its caller expects.

Service areas

| area | status | hosts | wire | |---|---|---|---| | Blob Storage | BUILT | *.blob.core.windows.net (+ the emulator path form) | REST + XML | | Azure OpenAI / AI inference | BUILT | *.openai.azure.com, *.cognitiveservices.azure.com under /openai/ | OpenAI-shaped JSON | | Entra ID | declared, deferred | login.microsoftonline.com | OAuth2 JSON |

AZURE_AREAS (src/azure-areas.ts) is the machine-readable registry behind that table: each area declares its hosts, its wire, its kernel namespace, its spec source and — for a deferred area — the recorded reason it is not served. Adding area 2 or 3 is: flip status to 'built', add the handler to the router's dispatch, and declare the area's hosts on the pack descriptor.

A deferred area is refused, never faked. A request that routes to one gets that area's own error envelope (invalid_request 400 for Entra), because answering it with a storage XML document would make a caller's SDK report a transport bug instead of the truth. And the pack descriptor claims only the built areas' hosts: routing a vendor host into a twin that does not serve it is the injector's version of a fake success.

The shared-domain split. *.cognitiveservices.azure.com is the per-resource domain every Azure AI service is addressed on, and the azureformrecognizer pack serves Document Intelligence there. Neither pack may claim the bare suffix, so both carry a pathPattern and the two are provably disjoint — this pack owns ^/openai/, azureformrecognizer owns ^/(documentintelligence|formrecognizer)/. A pathname cannot begin with both, so routing does not depend on table order, and a Cognitive Services path belonging to neither (a Speech or Language call) resolves to no vendor and gets the injector's loud refusal rather than a plausible answer from the wrong twin. scripts/vendor-hosts.test.ts pins both directions — and the in-process router agrees with the injector: a Cognitive Services path neither pack owns is refused in the JSON wire before dispatch, rather than falling through to storage and answering an Azure AI caller with an XML document.

Blob Storage (service area 1)

An unmodified @azure/storage-blob 12.33.0 talks to it — src/azure-sdk.integration.test.ts drives the real client, built from the twin's own connection string, through every claim below.

  • Containers — create (201 + a minted ETag), get properties, delete (which takes the container's blobs with it), set metadata (a wholesale replace), public-access ACL, and List Containers with prefix / maxresults / marker.
  • Block blobs with real bytes — Put Blob, Get Blob (exact bytes back), Get Blob Properties, Delete Blob, Set Blob Metadata, Set Blob HTTP Headers, and Copy Blob from another blob in the account. Content is stored, not summarized.
  • Block staging + block lists — Put Block, Put Block List (concatenated in list order, not staging order), Get Block List for committed / uncommitted / all, and the vendor's garbage-collection rule: blocks the committed list did not name are discarded, so a later commit naming one is InvalidBlockList, not a silent success over stale bytes.
  • Real hashes and ETags — base64 Content-MD5 (validated against a client-supplied one: a mismatch is Md5Mismatch 400 and nothing is stored), and Azure-shaped "0x8D…" ETags that change on every content or metadata write.
  • Conditional and ranged reads — If-Match → 412 ConditionNotMet, If-None-Match → 304, Range → 206 with Content-Range, out-of-range → 416 InvalidRange.
  • Listing — flat and hierarchical (delimiter folds into BlobPrefix), rendered as EnumerationResults with the ServiceEndpoint / ContainerName attributes the SDK's generated mappers expect, and RFC 1123 dates (an ISO string deserializes to an Invalid Date).
  • Service level — Get Blob Service Properties, Get Blob Service Stats, Get Account Information, List Containers.
  • The XML error envelope — <Error><Code>…</Code><Message>…</Message></Error> plus the x-ms-error-code header, which is what @azure/storage-blob actually reads to populate RestError.code.

Azure OpenAI (service area 2)

An unmodified openai (its AzureOpenAI class) and @ai-sdk/azure talk to it — the fidelity test drives both, plus the plain OpenAI client on the /openai/v1 surface, exactly as Microsoft's own v1 guidance configures it.

This is not "the OpenAI twin on a different host." What distinguishes Azure is mostly what it refuses and what it adds, and that is the surface modeled here:

  • You address a DEPLOYMENT, not a model. POST /openai/deployments/{deployment}/…, and an unknown deployment is DeploymentNotFound 404 — an error plain OpenAI has no analogue for. It is resolved before the body is validated, because the deployment lives in the URL.
  • ?api-version= is REQUIRED on the classic surface (the SDK will not even construct without one), and the two surfaces do not mix: api-version=v1 on a /deployments/… path is refused, while the /openai/v1 surface owns its own versioning and serves with no api-version at all — its parameter is a closed enum of v1|preview, so a dated version is refused there.
  • Two credentials, three schemes. The api-key header, a plain resource key carried as Authorization: Bearer (the scheme Microsoft's v1 quickstart uses), and an Entra bearer — accepted on shape against a Cognitive Services audience, so a storage token is refused here even though area 1 would take it.
  • Azure annotates content. prompt_filter_results and per-choice content_filter_results, with Azure's own asymmetry: jailbreak / indirect_attack exist on the prompt side only, the protected-material detections on the completion side only, and detections carry detected where severities carry severity. Streaming emits Azure's leading chunk — falsy id, created: 0, empty choices, prompt annotation only — the frame both openai and @ai-sdk/openai ship explicit workarounds for.
  • Azure renames the model. gpt-35-turbo, never OpenAI's gpt-3.5-turbo (a deployment name may not contain a dot). Asked for the latter, the twin 404s.
  • A retired operation stays retired. The data-plane deployment list/read existed only at api-versions 2022-12-01 and 2023-03-15-preview; at anything newer the twin refuses rather than modeling a surface Azure no longer has.
  • encoding_format: 'base64' is served, because the openai client sends it by default and then decodes it — a twin that ignored it would silently return wrong-length vectors on the SDK's default call path.

Deployments are twin state: they come from the connector's pull of a real resource, or from the twin-only POST /openai/_twin/deployments seed route, because Azure's data plane has no create-deployment operation at all (that is ARM, a different host this pack does not claim). Out of the box the resource carries one deployment per catalog model, named after the model.

Chat completions are scriptable through the shared kernel scenario engine (handlers/azure.json in a world dir; GET /twin explains, GET /twin/scenario lists handlers and misses). Its vocabulary adds deploymentEquals — two deployments of the same model are routine, and modelEquals alone could not tell them apart — and a contentFilter respond that scripts the Responsible AI outcome the twin cannot compute.

One shared Azure core

  • azure-auth.ts — the three credential shapes an integrator can point at the same endpoint, in one place: SharedKey HMAC (the twin RECOMPUTES the exact string-to-sign the vendor's own policy builds, so a wrong signature is refused AuthenticationFailed 403), connection strings (account form, SAS form, UseDevelopmentStorage=true), and Entra bearer acceptance. Nothing here ever contacts Azure.
  • azure-storage-headersort.ts — the .NET culture-aware collation the SharedKey CanonicalizedHeaders block is ordered with. This is not a lexicographic sort: - is ignorable at the primary level, so x-ms-meta-a collates after x-ms-metaa. Getting it wrong fails every request carrying two or more x-ms-* headers whose ASCII order differs.
  • azure-error.ts — one envelope per wire (storage XML, OpenAI JSON, OAuth2 JSON), plus the fixed request id and the REST version (2026-06-06, read off the installed SDK's own SERVICE_VERSION).
  • azure-areas.ts — the service-area registry (data only, so the manifest, the conformance check, the router and the tests all read the same facts).
  • azure-twin.ts — the router (handleAzureTwinRequest), dispatching by host then path, with storage as the fallback.

Auth

The twin fakes auth locally — no request ever leaves the process to check a credential — but it does not wave credentials through:

| presented | outcome | |---|---| | nothing (anonymous) | served | | SharedKey <account>:<sig> | signature RECOMPUTED; a wrong one is AuthenticationFailed 403 | | SharedKeyLite | refused (InvalidAuthenticationInfo) — its string-to-sign is not modeled, and accepting it would claim a verification that never happened | | Bearer <jwt> (Entra) | accepted on shape: three segments, decodable payload, a storage audience. The signature is not verified — that needs service area 3's JWKS, and the manifest declares the gap rather than claiming validation | | a SAS query token | served; SAS generation and validation are filed todo, not claimed | | any other scheme | refused |

The twin's account is devstoreaccount1 with the published Azurite development key, so a caller already configured for a local storage emulator points at this twin unchanged.

Wiring an app at the twin

world-azure serve --port 10000        # prints the blob endpoint, a connection string AND the Azure OpenAI endpoint
world-azure serve --scenario handlers/azure.json   # script area 2's chat completions
world-azure areas                     # the service-area registry, including what is NOT served
world-azure conformance               # probe every claimed endpoint, offline
import { BlobServiceClient } from '@azure/storage-blob';
// Either shape works — both are what a real integrator already has:
const svc = BlobServiceClient.fromConnectionString(process.env.AZURE_STORAGE_CONNECTION_STRING!);
// …or the endpoint URL directly: http://127.0.0.1:10000/devstoreaccount1
import { AzureOpenAI } from 'openai';
// The class appends `/openai` itself, so `endpoint` is the twin's BARE origin.
const ai = new AzureOpenAI({ endpoint: 'http://127.0.0.1:10000', apiKey: 'twin-key', apiVersion: '2024-10-21' });
await ai.chat.completions.create({ model: 'gpt-4o', messages: [{ role: 'user', content: 'hi' }] });

Coverage

Partial and honest. The denominator is the vendor's real surface, not what is built. Area 1 enumerates all 69 operations the installed @azure/storage-blob declares across its six operation groups (service / container / blob / blockBlob / appendBlob / pageBlob); area 2 enumerates the Azure OpenAI data plane's operation families across its three route surfaces; and the shared core's auth and error properties and every operation service area 3 will serve are enumerated too. Coverage rises by building, never by trimming the denominator.

Largest tracked area-1 gaps (all todo, none pretended): leases, snapshots and versioning, blob tags, access tiers, SAS generation and validation, Find Blobs by Tags, Blob Batch, and the whole page blob and append blob operation groups. Put Blob with x-ms-blob-type: PageBlob or AppendBlob is refused NotImplemented 501 — never silently stored as a block blob.

Largest tracked area-2 gaps: images, files, batch, fine-tuning, assistants and threads, vector stores, evaluations, realtime, On Your Data, and the rest of audio (translations / speech). A route Azure genuinely serves and this twin has not built answers 501 TwinOperationNotModeled, naming the manifest todo that tracks it — never a fabricated success, and never a borrowed Azure error code (a 404 Resource not found there would be a lie about the vendor: the route exists).

max_completion_tokens, audio transcription and the Responses API are built, and the order they were built in came from measured call sites rather than from the reference. Across the ladder corpus's Azure-using repos, max_completion_tokens appears in seven of them (LiteLLM 138 hits, sim 15, LibreChat 10, activepieces 6, langfuse 3, n8n 2, open-webui 1) — it is the single most-sent Azure OpenAI parameter this catalogue can point at. audio/transcriptions appears in two (open-webui 66, LibreChat 1). The Azure spelling of the Responses API appears in none of them, so it was built last and is recorded here as unproven demand rather than a leading gap.

  • max_completion_tokens / max_tokens cap the completion: the text is truncated at the cap, finish_reason becomes length (in the unary body and in the stream's terminal frame). The cap is PER CHOICE, as the vendor's is, so usage.completion_tokens — which sums choices — is bounded by cap x n rather than by the cap itself; a tool-call answer is not capped at all (azure.openai.chat.truncated_tool_call). The o-series exclusivity the spec describes is NOT modeled — this twin's catalogue holds no o-series deployment to refuse against, and the spec itself calls the restriction temporary; azure.openai.chat.reasoning_param_exclusivity tracks it.
  • POST /openai/deployments/{d}/audio/transcriptions speaks real multipart/form-data, holds the vendor's CLOSED response_format enum as an oracle, and answers text/srt/vtt as text/plain and json/verbose_json as JSON. No audio is decoded: the transcript is a labeled [twin-stub:…] string seeded from a sha256 of every uploaded byte, so the same file always transcribes identically and two different files do not collide. (The first version hashed only the length plus the first ~384 bytes through a 32-bit FNV, which made that second half false for any two same-length files sharing a header region — a §9 review caught it.) The /openai/v1 spelling is not served: the data-plane document declares this operation only on the deployment-based path and says nothing at all about the /openai/v1 surface, so the twin answers the ordinary not-found and records the uncertainty as azure.openai.audio.transcriptions_v1_surface rather than as a ruling.
  • POST /openai/responses (both path styles) answers the response document with its output[] message items, the output_text aggregate, the full ResponseUsage breakdown and the tools/tool_choice/text/reasoning/store members the shape requires; stream: true emits the response.* NAMED-event family in the documented order, numbers every frame with a sequence_number, carries the logprobs its two text events declare, and emits no [DONE] sentinel — a claim proven against the REAL LISTENER in azure-openai-twin.test.ts, because the in-process collector and the server's sink are two renderers and a §9 review found them disagreeing on exactly that frame. (Twice, in fact: the first repair deleted the sentinel at the source but left the collector's if (e.done) return, which meant the capability's assertion could not have failed. The special case is gone now, so the two renderers agree by construction rather than by two matching workarounds.) A refusal decided before the first frame is itself a NAMED event: error on this lane, and stays unnamed on chat, because the two readers differ. max_output_tokens really truncates and reports the vendor's own status: 'incomplete' + incomplete_details.reason: 'max_output_tokens', and a capped STREAM ends response.incomplete rather than response.completed. Nothing is stored — so GET/DELETE /openai/responses/{id}, its input_items, and a request carrying previous_response_id are all refused, and the served document says store: false whatever the request asked for. Fabricating a record for a response this twin never kept is exactly the false-green those refusals exist to avoid; the previous_response_id half is that same false-green reached from the create path, and a store: true echo would have been it a third time, in the document's own body. The Responses document is also the one place this pack currently serves a plain-OpenAI shape with no Azure-specific annotation (azure.openai.responses.content_filter), and it is served at any well-formed dated api-version including ones that predate the operation (azure.openai.responses.api_version_range).

Which error codes are Microsoft's, and which are the twin's

Microsoft publishes a literal error body for exactly one Azure OpenAI failure — the content-filtered prompt (content_filter + innererror.code: 'ResponsibleAIPolicyViolation') — and names exactly one other error by string (DeploymentNotFound). Those two are used verbatim. Every other area-2 refusal carries a Twin… code (TwinMissingApiVersion, TwinInvalidApiVersion, TwinBadRequest, TwinUnauthorized, TwinResourceNotFound, TwinMethodNotAllowed, TwinRetiredOperation, TwinOperationNotModeled). The status is grounded in each case; the code is not published, and emitting an unpublished-but-plausible Azure constant would be serving surface the vendor does not have. Area 2 also does not send x-ms-error-code — that header is Azure Storage's mechanism (area 1 does send it); Azure OpenAI's own specs declare apim-request-id and nothing else, so that is the one header this area emits.

No UI mirror

The API is the product. An integrator reaches Azure Blob Storage by calling it from code — an SDK, a connection string, a SAS URL — and the portal's storage browser is incidental tooling for keys, quotas and billing, not where the work happens. (the contributor recipe records the aws S3 bucket-browser explicitly as a legacy outlier, not precedent, so it is not cited here.) This pack therefore ships no client/ directory and declares no UI capabilities; azure-capabilities.test.ts asserts that directly, so a screen can never be claimed without existing.

What the generative and durability surfaces actually do

There are no weights here, and "cannot run the model" is an invariant rather than a gap. Area 2's generative routes return deterministic, clearly-labeled [twin-stub:azure-openai:<deployment>:<model>] payloads (or scripted scenario responses) under a faithful protocol envelope, byte-identical on replay. Embeddings are deterministic L2-normalized pseudo-vectors seeded from a hash: the shape, width, batching and determinism are faithful and the values carry no semantic meaning. The content-filter annotation shape is faithful and deterministic in the text while the verdict is a keyword heuristic — a flow that needs a specific verdict scripts it rather than hoping the heuristic guesses. Capacity is a provisioned resource and a region's fleet rather than a local process, so the twin has no TPM/RPM quota to run out of and does not fabricate a throttle.

On area 1, one process and one disk do not reproduce RA-GRS lag, a real secondary endpoint, or an account failover: Get Blob Service Stats serves a fixed live document and says so. The twin reports x-ms-server-encrypted: true because the protocol requires the header; there is no Key Vault and no encrypted disk behind it, and it claims nothing more.

Filed as todo: Storage Analytics (azure.blob.storage_analytics) — request logs into the $logs container and the hour/minute metrics tables computed over the twin's stored operations; and ARM deployment management (azure.openai.arm.deployment_management) — the management.azure.com create/update/delete operations with their own auth and api-version, which the connector today refuses by name, pointing at ARM rather than reporting a silent zero.

Service area 3 (Entra ID) is declared in AZURE_AREAS and enumerated in the manifest as todos: it is a follow-up build, and nothing answers today. Its AZUREAD env stem deliberately stays unclaimed so Entra-only repos read as uncovered.

Determinism

A served response is a pure function of (request, stored state). The request id is fixed, ETags are derived from (subject, revision, content digest) rather than a clock, and every write folds a per-subject revision ordinal — without it the kernel's content+millisecond action dedupe would silently drop the third write of an upload A; upload B; upload A sequence and serve stale bytes under a fresh ETag.