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

@d-ai/media-sdk

v0.2.0

Published

Universal TypeScript SDK for D.AI image, video, and audio generation

Readme

@d-ai/media-sdk

Universal TypeScript client for D.AI image, video, and audio generation. It runs on Node.js 18+, modern browsers, Workers, Bun, and other Fetch API runtimes.

Install

npm install @d-ai/media-sdk

Configure

import { DaiMediaClient } from "@d-ai/media-sdk";

const client = new DaiMediaClient({ apiKey: process.env.DAI_API_KEY!, baseUrl: "https://gateway.example.com/dai", timeoutMs: 90_000, });


A path prefix in `baseUrl` is preserved. Authentication and content-type headers are managed by the SDK and cannot be overridden by global headers. A custom `fetch` implementation can be injected for Workers, tests, or instrumented transports.

## Image

```ts
const result = await client.images.openai.generate({
  model: "gpt-image-2",
  prompt: "A glass greenhouse at sunrise",
  size: "1024x1024",
});

console.log(result.images[0]?.url);

For GPT Image 2.5(经济·非官方), explicitly choose gpt-image-2.5 and the asynchronous method. It is a separate, lower-cost unofficial channel: latency, reliability, and output may differ from official flare/sunburst. Official calls never switch channels automatically.

const job = await client.images.openai.gptGenerate({
  model: "gpt-image-2.5",
  prompt: "Draw a glass greenhouse at sunrise",
  n: 1,
});
const economyImage = await client.jobs.wait(job);
console.log(economyImage.assets[0]);

Economy requests generate one image (n omitted or 1) and do not support size, quality, aspect_ratio, response_format, background, or output_format; unsupported controls are rejected, not ignored. Use generate with gpt-image-2.5-flare / gpt-image-2.5-sunburst for the official channel. Sending the economy model to generate is an error.

Flux image jobs are asynchronous:

const job = await client.images.flux.generate({
  model: "flux1-dev",
  prompt: "A cinematic portrait of a fox in neon rain",
  size: "1024x1024",
});
const flux = await client.jobs.wait(job);
console.log(flux.assets[0]);

flux1-schnell is edits-only (client.images.flux.edits).

Grok Image is asynchronous. The model catalog exposes grok-image; generation and editing share the same polling endpoint:

const generated = await client.images.grok.generate({
  model: "grok-image",
  prompt: "A glass greenhouse at sunrise",
  aspectRatio: "16:9",
});
const generatedImage = await client.jobs.wait(generated);

const edited = await client.images.grok.edits({
  model: "grok-image",
  prompt: "Add warm lantern light",
  images: ["https://cdn.example.com/greenhouse.png"],
});
const editedImage = await client.jobs.wait(edited);

Both methods return a MediaJobHandle. The SDK submits to /api/image/grok/v1/generations or /api/image/grok/v1/edits, then polls /api/image/grok/v1/fetch through client.jobs.fetch or client.jobs.wait.

Video and jobs

const job = await client.videos.gemini.generate({
  prompt: "A slow orbital camera move around a glass greenhouse",
  model: "veo-3.1-fast",
  aspectRatio: "16:9",
});

const result = await client.jobs.wait(job, {
  pollIntervalMs: 2_000,
  maxWaitMs: 20 * 60_000,
});

The SDK rebuilds every polling URL from the configured baseUrl. An absolute fetchUrl returned by the server is informational and never changes the polling host.

Grok Imagine Video 1.5 is also asynchronous. The model catalog exposes grok-imagine-video-1.5; it requires exactly one reference image and supports 1–15 seconds at 480p, 720p, or 1080p:

const grokVideo = await client.videos.grok.generate({
  model: "grok-imagine-video-1.5",
  prompt: "A slow orbital camera move around the greenhouse",
  aspectRatio: "16:9",
  resolutionName: "720p",
  videoLength: 10,
  referImages: ["https://cdn.example.com/greenhouse.png"],
  referenceAudios: [{ voiceId: "voice-id" }],
});
const video = await client.jobs.wait(grokVideo, {
  pollIntervalMs: 2_000,
  maxWaitMs: 20 * 60_000,
});

The request maps aspectRatio, resolutionName, videoLength, referImages, and referenceAudios to the API's aspect_ratio, resolution_name, video_length, refer_images, and reference_audios fields. Polling uses /api/video/grok/v1/fetch on the configured host.

Wan 3.0 Video is asynchronous and supports prompt-only, frame, reference-media, URL, and file inputs. Supply the exact wan3.0-video model and optional output parameters; polling uses /api/video/wan/v1/fetch through the configured host:

const wanJob = await client.videos.wan.generate({
  model: "wan3.0-video",
  input: {
    prompt: "A slow camera move through a misty bamboo forest",
    media: [{ type: "reference_image", url: "https://cdn.example.com/forest.png" }],
  },
  parameters: {
    resolution: "1080P",
    ratio: "16:9",
    duration: 5,
    audio: true,
  },
});
const wanVideo = await client.jobs.wait(wanJob);
console.log(wanVideo.assets[0]);

Wan parameters.duration accepts integer seconds 2..30 or -1 for smart duration. parameters.resolution accepts 480P, 720P, or 1080P; media types are first_frame, last_frame, reference_image, reference_video, reference_audio, link, and file.

Cancellation

Every request accepts AbortSignal:

const controller = new AbortController();
const request = client.audio.suno.music(
  {
    custom: false,
    instrumental: true,
    mv: "chirp-v5",
    gptDescriptionPrompt: "Night city lo-fi piano",
  },
  { signal: controller.signal },
);
controller.abort();
await request;

Billed POST requests are never automatically retried.

Browser security

Do not embed an application-owned long-lived API key in public JavaScript. Browser execution is appropriate for user-supplied keys, trusted internal applications, or future short-lived scoped tokens. Public products should call D.AI from their own backend; see examples/nextjs-media.