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

@omen.dog/sdk

v1.2.0

Published

Official server-side TypeScript SDK for the Omen platform

Downloads

344

Readme

@omen.dog/sdk

Official server-side TypeScript SDK for the Omen platform.

Install

npm install @omen.dog/sdk

Requires Node.js 18+ (uses native fetch). Zero dependencies.

Quick Start

import { OmenClient } from '@omen.dog/sdk';

const omen = new OmenClient({
  token: process.env.OMEN_TOKEN!,  // dev_yourorg_abc123...
  appId: 'your-app-id',           // from the Developer Portal
});

Namespaces

Users

const profile = await omen.users.get('pistolphoenix');
const { friends, onlineCount } = await omen.users.friends('pistolphoenix', {
  status: 'online',
  limit: 10,
});

Storage

Per-user key-value storage scoped to your app.

const { data } = await omen.storage.get();
await omen.storage.set({ highScore: 100, level: 5 });
await omen.storage.merge({ highScore: 200 }); // keeps 'level' intact

Items

Issue achievements, collectibles, and in-game items to users.

const item = await omen.items.issue({
  userId: 'cmm0tzco8...',
  name: 'Dragon Slayer',
  type: 'achievement',
  rarity: 'legendary',
});

// Batch issue (up to 100)
const { items } = await omen.items.issueBatch([
  { userId: 'user1', name: 'Gold Medal', type: 'achievement' },
  { userId: 'user2', name: 'Silver Medal', type: 'achievement' },
]);

// Revoke
await omen.items.revoke(item.id, 'Violated terms');

Collections

Structured data storage — like a simple document database.

// Create a collection with schema
await omen.collections.create({
  name: 'player_stats',
  schema: { score: 'number', level: 'number', name: 'string' },
  indexedFields: ['score'],
});

// Insert documents
const doc = await omen.collections.insert('player_stats', {
  score: 1500, level: 12, name: 'PistolPhoenix',
});

// Query with filters
const { documents } = await omen.collections.query('player_stats', {
  where: { level: { $gte: 10 } },
  sort: { score: -1 },
  limit: 20,
});

// Atomic transactions (Pro+ tier)
const { results } = await omen.collections.transaction('game_state', [
  { type: 'get', id: 'player_1' },
  { type: 'update', id: 'player_1', data: { health: 50 } },
]);

Webhooks

// Register (secret is only returned once!)
const webhook = await omen.webhooks.create({
  url: 'https://myapp.com/webhooks/omen',
  events: ['item.issued', 'friend.added'],
});
console.log(webhook.secret); // save this!

// Verify incoming webhooks
const valid = await omen.webhooks.verify(rawBody, signature, secret);

Sparks (partner awards)

Award money-backed Sparks and catalog items to your users from a prepaid pool (buy/manage it in the Developer Portal → Sparks Pool).

Approved Partner Apps only. Awarding mints real Sparks, so award, awardBatch, and items.awardCatalog require the app to be an approved Partner App (Developer Portal → Partner Program). Unapproved apps get 403 partner_required. Funding a pool does not require approval.

// Award Sparks (pass idempotencyKey to make retries safe)
await omen.sparks.award({
  userId, amount: 250, reason: 'Beat level 10',
  idempotencyKey: `level10:${userId}`,
});

// Batch (≤100, best-effort per item)
await omen.sparks.awardBatch([
  { userId: 'u1', amount: 100 },
  { userId: 'u2', amount: 100 },
]);

// Award an open-shop item or avatar trait — paid from your pool at list price
await omen.items.awardCatalog({ userId, catalogType: 'store', catalogItemId: 'theme_lava' });

// Pool status
const pool = await omen.sparks.pool();

// Mint a short-lived display token for the UI kit (backend only — needs your
// app's OAuth client secret). Pass it to <omen-sparks-balance>/<omen-inventory>.
const token = omen.sparks.displayToken({ userId, secret: process.env.OMEN_CLIENT_SECRET! });

UI kit (embeddable widgets)

<script src="https://sdk.omen.dog/v1/ui-kit.js"></script>
<omen-sparks-balance token="DISPLAY_TOKEN"></omen-sparks-balance>
<omen-inventory token="DISPLAY_TOKEN" limit="24"></omen-inventory>
<script>OmenUI.toast({ amount: 250, message: 'Level cleared!' })</script>

Restyle via CSS variables (--omen-bg, --omen-accent, --omen-spark, …), ::part() selectors, or theme="bare" to ship your own CSS entirely.

Shared avatar (Embedded Avatar Kit)

Put the shared Omen avatar inside your app — display it, let users edit it in-place, browse the trait catalog, and gift traits from your Sparks pool.

// Public render URL (pass version from avatar:saved / user.avatar_updated to bust caches)
const url = omen.avatar.renderUrl(userId, { version });

// Mint a short-lived editor token for <omen-avatar-editor> (backend only)
const token = omen.avatar.editorToken({ userId, secret: process.env.OMEN_CLIENT_SECRET! });

// Enumerate the shared catalog — trait ids, names, rarities, ✦ prices (public, no auth).
// Pass { editorToken } and each trait's `locked` reflects that user's ownership.
const { catalog, rarityPricing } = await omen.avatar.catalog();

// Gift a trait app-funded — your pool pays list price, the user pays nothing
await omen.items.awardCatalog({
  userId, catalogType: 'avatar_trait', catalogItemId: 'hair/export-01.svg',
});

Trait ids are category/file.svg paths and double as public preview SVGs at https://omen.dog/avatar/{traitId}. Common traits are free for everyone and can't be awarded.

App-owned assets & image generation

Host content art your app owns (shared across all your users, not a single user's upload) and serve it from a public, immutable, CDN-cacheable URL — exempt from the per-user asset cap. Bring your own bytes, or generate them on Omen billed to your prepaid Sparks pool.

// Host bytes you already have (Buffer / Uint8Array / base64). Max 10 MB.
const asset = await omen.assets.upload(pngBuffer, { name: 'Apple', contentType: 'image/png' });
console.log(asset.url); // /api/v1/assets/…/file — embed anywhere

// List / fetch / evict (eviction is yours to control — never purged on a timer)
const { assets, nextCursor } = await omen.assets.list({ limit: 50 });
await omen.assets.delete(asset.id);

// Generate one image, billed to your pool, hosted app-owned. Requires an
// approved Partner App + a funded pool. Output is child-safety-filtered.
const { asset: img, cost, poolBalance } = await omen.images.generate({
  prompt: 'a friendly red apple with a smiling face',
  aspectRatio: '4:3',            // 1:1 | 4:3 | 3:4 | 16:9 | 9:16
  style: 'storybook',           // optional preset; omit for raw-prompt mode
  idempotencyKey: `apple:${pageId}`,
});

// Keep a recurring character consistent across story pages — pass an identity ref
await omen.images.generate({
  prompt: 'the same fox, now jumping over a log',
  aspectRatio: '3:4',
  referenceImages: [{ data: foxPngBase64, tag: 'identity' }], // up to 4, ≤4 MB each
});

A depleted pool fails closed (402, throws OmenError); a rejected prompt or blocked image throws OmenValidationError (400 content_rejected) and your pool is not charged.

Creation Runtime Types

For creation developers — get autocomplete for the omen.* global:

/// <reference types="@omen.dog/sdk/creation" />

const save = await omen.load();
omen.score(100);

Child Re-Login (ChildLogin)

A safe, thin wrapper over the child device-grant flow for Tier-3 apps that sign in Omen child accounts (F263). It's a separate export — it uses your OAuth clientId/clientSecret, not a dev_ token — and is also available from the server-only subpath @omen.dog/sdk/child-login. scope:'child' is always sent, RFC 8628 errors map to a calm status union instead of throwing, and scope is preserved across refresh rotation. Tokens never leave your server.

import { ChildLogin } from '@omen.dog/sdk/child-login';

const child = new ChildLogin({
  clientId: process.env.OMEN_CLIENT_ID!,
  clientSecret: process.env.OMEN_CLIENT_SECRET!,   // omit for public/PKCE clients
  webhookSecret: process.env.OMEN_WEBHOOK_SECRET!,
});

const grant = await child.deviceStart({ deviceName: "Astrid's iPad" });
await child.notify({ device_code: grant.device_code, username: 'astrid' }); // cold start
const res = await child.pollUntil(grant.device_code);  // honors interval + slow_down
if (res.status === 'approved') {
  const session = child.seal(res.tokens!); // store in your httpOnly session; res.rebind = card data
}

// flip the child's screen the instant a parent approves:
if (child.verifyWebhook(rawBody, req.headers['x-omen-signature'])) { /* notify the device */ }

Pair it with the in-context <omen-child-login> web component (zero-dep, themeable, talks only to your own routes). See omen.dog/docs#child-relogin-kit.

The canonical child-side state machine is exported too (deriveInitialState, reduce, displayGroup, CHILD_LOGIN_STATES) for apps building custom UI on the same kindness.

Error Handling

import { OmenClient, OmenNotFoundError, OmenRateLimitError } from '@omen.dog/sdk';

try {
  await omen.users.get('nonexistent');
} catch (err) {
  if (err instanceof OmenNotFoundError) {
    console.log('User not found');
  }
  if (err instanceof OmenRateLimitError) {
    console.log(`Rate limited. Retry after ${err.retryAfter}s`);
  }
}

API Reference

Full documentation at omen.dog/docs.

License

MIT