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

@calculator-5329/cloud-proxy

v0.3.1

Published

TypeScript client SDK for the Cloud Run proxy server

Readme

@calculator-5329/cloud-proxy

TypeScript client SDK for the Cloud Run proxy server. Zero runtime dependencies, fully typed, ESM-only.

Install

npm install @calculator-5329/cloud-proxy

Requirements: Node 18+ (uses global fetch)

Quick Start

import { createClient } from "@calculator-5329/cloud-proxy";

const proxy = createClient({
  baseUrl: process.env.PROXY_URL!,
  token: process.env.PROXY_TOKEN!,
});

// Health check
const { status } = await proxy.health();

Set two environment variables and you're done:

PROXY_URL=https://your-service-xyz.run.app
PROXY_TOKEN=your-static-bearer-token

Modules

Every module is accessible as a property on the client object. Modules are lazily instantiated on first access.

| Module | Accessor | Description | |--------|----------|-------------| | AI | proxy.ai | OpenAI, Anthropic, Gemini, OpenRouter passthrough | | Auth | proxy.auth | Firebase Auth user management | | Firestore | proxy.firestore | Firestore CRUD, queries, batch, aggregates | | Storage | proxy.storage | GCS upload, download, signed URLs, buckets | | Vectors | proxy.vectors | Vector search + Gemini embeddings | | Setup | proxy.setup | Provisioning + project bootstrap | | Agent | proxy.agent | Wikipedia lookup, Brave Search, event enrichment |


AI

// Direct provider passthrough
const response = await proxy.ai.openai("/v1/chat/completions", {
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello" }],
});

// Convenience chat — normalized response across all providers
const reply = await proxy.ai.chat({
  provider: "anthropic",
  model: "claude-sonnet-4-20250514",
  messages: [{ role: "user", content: "Explain quantum computing" }],
  maxTokens: 1024,
});
console.log(reply.content);

// Streaming
const stream = await proxy.ai.chatStream({
  provider: "openai",
  model: "gpt-4o",
  messages: [{ role: "user", content: "Write a poem" }],
});
for await (const chunk of stream) {
  process.stdout.write(new TextDecoder().decode(chunk));
}

Auth

const user = await proxy.auth.createUser({
  email: "[email protected]",
  password: "securepassword",
  displayName: "Alice",
});

await proxy.auth.setClaims(user.uid, { admin: true });

const users = await proxy.auth.listUsers({ limit: 50 });

// Email links
const { link } = await proxy.auth.generatePasswordResetLink("[email protected]");

// Session cookies
const { cookie } = await proxy.auth.createSessionCookie(idToken, 7 * 24 * 60 * 60 * 1000);
const decoded = await proxy.auth.verifySessionCookie(cookie, true);

setClaims() and createSessionCookie() now send the request shape expected by the proxy service.

Firestore

// CRUD
const post = await proxy.firestore.create("posts", { title: "Hello", body: "World" });
const doc = await proxy.firestore.get<{ title: string }>("posts/abc123");
await proxy.firestore.update("posts/abc123", { title: "Updated" });
await proxy.firestore.delete("posts/abc123");

// Query
const published = await proxy.firestore.query("posts", {
  filters: [{ field: "status", op: "==", value: "published" }],
  orderBy: [{ field: "createdAt", direction: "desc" }],
  limit: 50,
});

// Subcollections
const comments = await proxy.firestore.list("posts/abc123/comments");
// Or scoped:
const scoped = proxy.firestore.sub("posts/abc123");
await scoped.list("comments");

// Atomic field operations
import { FieldOp } from "@calculator-5329/cloud-proxy";

await proxy.firestore.patch("posts/abc123", {
  views: FieldOp.increment(1),
  tags: FieldOp.arrayUnion("featured"),
});

// Batch
await proxy.firestore.batch([
  { type: "create", collection: "posts", data: { title: "A" } },
  { type: "delete", collection: "posts", docId: "old" },
]);

// Aggregates
const stats = await proxy.firestore.aggregate("orders", {
  aggregations: [
    { type: "count", alias: "total" },
    { type: "sum", field: "amount", alias: "revenue" },
  ],
  filters: [{ field: "status", op: "==", value: "completed" }],
});

// Collection group queries
const allComments = await proxy.firestore.query("comments", {
  collectionGroup: true,
  filters: [{ field: "flagged", op: "==", value: true }],
});

Storage

// Direct upload
const result = await proxy.storage.upload("my-bucket", file, {
  path: "avatars",
  public: true,
});

// Signed URL upload (large files)
const { uploadUrl } = await proxy.storage.getUploadUrl("my-bucket", {
  filename: "video.mp4",
  contentType: "video/mp4",
  expiresInMinutes: 30,
});

// Download
const { downloadUrl } = await proxy.storage.getDownloadUrl("my-bucket", "photo.jpg", 120);
const response = await proxy.storage.download("my-bucket", "report.pdf");

// List & delete
const files = await proxy.storage.listFiles("my-bucket", { prefix: "avatars/" });
await proxy.storage.deleteFile("my-bucket", "old-file.txt");

// Bucket management
await proxy.storage.createBucket({ name: "new-bucket", location: "US" });
const { buckets } = await proxy.storage.listBuckets();

Vectors

// Embed and store
const doc = await proxy.vectors.embed("articles", "Quantum computing uses qubits...", {
  data: { title: "Intro to Quantum", category: "science" },
});

// Batch embed
await proxy.vectors.embedBatch("articles", [
  { text: "First article...", data: { title: "AI" } },
  { text: "Second article...", data: { title: "ML" } },
]);

// Semantic search
const hits = await proxy.vectors.semanticSearch("articles", "quantum physics basics", {
  topK: 5,
  filters: [{ field: "category", op: "==", value: "science" }],
});

// Update & delete
await proxy.vectors.update("articles", doc.id, { text: "Updated content..." });
await proxy.vectors.delete("articles", doc.id);

store() now sends { data, embedding, docId? }, matching the server contract.

Setup

// Bootstrap an entire project
const status = await proxy.setup.bootstrapProject({
  projectName: "my-app",
  firestore: {
    collections: [
      { name: "users" },
      { name: "documents", vectorIndex: true },
    ],
  },
  storage: { bucketName: "my-app-assets", public: true },
  auth: { enableEmailPassword: true },
});

// Check status
const current = await proxy.setup.getStatus();

Error Handling

All errors are thrown as ProxyError with code, status, and details:

import { ProxyError } from "@calculator-5329/cloud-proxy";

try {
  await proxy.firestore.get("posts/nonexistent");
} catch (err) {
  if (err instanceof ProxyError && err.code === "FIRESTORE_NOT_FOUND") {
    // handle 404
  }
}

License

MIT