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

@decoloop/aistudio-client

v0.1.0

Published

Professional TypeScript client for creating secure AI Studio sessions on the server and generating product visualizations in the browser.

Downloads

157

Readme

@decoloop/aistudio-client

Professional TypeScript client for creating secure AI Studio sessions on the server and generating product visualizations in the browser.

Overview

@decoloop/aistudio-client is split into two focused clients:

  • AiStudioServerClient creates short-lived browser session tokens from a trusted server environment.
  • AiStudioBrowserClient uses those session tokens from the browser to submit room photos, product metadata, and optional texture data for image generation.

This split keeps the permanent AI Studio API key out of browser code. The server owns the secret API key and exchanges it for a constrained session token. The browser only receives that temporary session token and uses it for generation requests.

Token authentication flow

The API key must only be used by backend code. Browser code must authenticate with a session token returned by AiStudioServerClient.createSession.

+-------------+        1. Request session        +------------------+
|   Browser   | -------------------------------> |  Your backend    |
+-------------+                                  +------------------+
       ^                                                   |
       |                                                   | 2. Create session
       |                                                   |    with API key
       |                                                   v
       |                                          +------------------+
       |                                          |    AI Studio     |
       |                                          +------------------+
       |                                                   |
       |            3. Return session token                |
       +---------------------------------------------------+
       |
       | 4. Generate image with session token
       v
+-------------+                                  +------------------+
|   Browser   | -------------------------------> |    AI Studio     |
+-------------+                                  +------------------+

Recommended flow:

  1. The browser calls an endpoint on your backend to request an AI Studio session.
  2. Your backend uses AiStudioServerClient with the permanent API key.
  3. AI Studio returns a session token.
  4. Your backend returns only the session token to the browser.
  5. The browser uses AiStudioBrowserClient with the session token to generate images.

Installation & imports

Install the package from the workspace package registry or consume it directly from the monorepo library.

npm install @decoloop/aistudio-client

Import the server client only from backend code:

import {
  AiStudioServerClient,
  type SessionRequest,
  type SessionResponse,
} from '@decoloop/aistudio-client';

Import the browser client from frontend code:

import {
  AiStudioBrowserClient,
  ModelId,
  ProductType,
  type ImageGenerationOptions,
} from '@decoloop/aistudio-client';

Server-side usage

Use AiStudioServerClient in a trusted server runtime. The constructor intentionally throws when instantiated in a browser environment to prevent accidental API key exposure.

import {
  AiStudioServerClient,
  type SessionRequest,
  type SessionResponse,
} from '@decoloop/aistudio-client';

const aiStudio = new AiStudioServerClient({
  apiKey: process.env.AISTUDIO_API_KEY!,
  baseUrl: 'https://api.example.com',
});

export async function createAiStudioSession(): Promise<SessionResponse> {
  const request: SessionRequest = {
    maxUses: 3,
    expiresInSeconds: 900,
    allowedOrigins: ['https://customer.example.com'],
    metadata: 'customer-project-123',
  };

  return await aiStudio.createSession(request);
}

Example Express route:

import express from 'express';
import { AiStudioServerClient } from '@decoloop/aistudio-client';

const router = express.Router();

const aiStudio = new AiStudioServerClient({
  apiKey: process.env.AISTUDIO_API_KEY!,
  baseUrl: process.env.AISTUDIO_BASE_URL!,
});

router.post('/aistudio/session', async (_request, response, next) => {
  try {
    const session = await aiStudio.createSession({
      maxUses: 1,
      expiresInSeconds: 600,
      allowedOrigins: ['https://customer.example.com'],
      metadata: 'image-generation-checkout',
    });

    response.json(session);
  } catch (error) {
    next(error);
  }
});

export default router;

AiStudioServerClient configuration

| Parameter | Type | Required | Description | | --- | --- | --- | --- | | apiKey | string | Yes | Permanent AI Studio API key. Keep this value on the server only. | | baseUrl | string | Yes | Base URL of the AI Studio API. A trailing slash is removed automatically. |

createSession(request) parameters

| Parameter | Type | Required | Description | | --- | --- | --- | --- | | maxUses | number | No | Maximum number of generation requests allowed for the returned session token. | | expiresInSeconds | number | No | Session lifetime in seconds. Prefer short-lived tokens. | | allowedOrigins | string[] | No | Browser origins allowed to use the session token. Use exact production origins. | | metadata | string | No | Application-defined metadata for tracing or auditing the session. |

createSession(request) response

interface SessionResponse {
  token: string;
}

Return token to the browser. Do not return the permanent API key or any server-side configuration.

Browser-side usage

Use AiStudioBrowserClient after your frontend has obtained a session token from your backend.

import {
  AiStudioBrowserClient,
  ModelId,
  ProductType,
  type ImageGenerationOptions,
} from '@decoloop/aistudio-client';

async function generateCurtainPreview(roomPhoto: File): Promise<string> {
  const sessionResponse = await fetch('/api/aistudio/session', {
    method: 'POST',
  });

  if (!sessionResponse.ok) {
    throw new Error('Unable to create AI Studio session.');
  }

  const { token } = (await sessionResponse.json()) as { token: string };

  const client = new AiStudioBrowserClient({
    sessionToken: token,
    baseUrl: 'https://api.example.com',
  });

  const options: ImageGenerationOptions = {
    textureId: 'linen-warm-white',
    width: 280,
    height: 240,
    lining: 'blackout',
  };

  const imageBlob = await client.generateImage(
    roomPhoto,
    ProductType.Curtains,
    ModelId.DoublePleat,
    options,
  );

  return URL.createObjectURL(imageBlob);
}

Example with a custom texture file:

const imageBlob = await client.generateImage(
  roomPhoto,
  ProductType.RollerBlind,
  ModelId.RollerStandard,
  {
    customTexture: textureFile,
    opacity: 0.92,
    chainSide: 'right',
  },
);

AiStudioBrowserClient configuration

| Parameter | Type | Required | Description | | --- | --- | --- | --- | | sessionToken | string | Yes | Short-lived token created by AiStudioServerClient.createSession. | | baseUrl | string | Yes | Base URL of the AI Studio API. A trailing slash is removed automatically. |

generateImage(roomPhoto, productType, modelId, options) parameters

| Parameter | Type | Required | Description | | --- | --- | --- | --- | | roomPhoto | Blob \| File | Yes | Source room image to use for visualization. | | productType | ProductType | Yes | Product category to render, such as curtains or roller blinds. | | modelId | ModelId | Yes | Product model identifier. Use a model compatible with the selected product type. | | options | ImageGenerationOptions | No | Optional texture and product settings. |

generateImage(...) response

generateImage returns a Promise<Blob> containing the generated image. Convert it to an object URL for previewing in the browser, upload it to storage, or pass it to another browser API.

const imageBlob = await client.generateImage(
  roomPhoto,
  ProductType.Curtains,
  ModelId.Wave,
);

const previewUrl = URL.createObjectURL(imageBlob);

How options is serialized

AiStudioBrowserClient sends generation requests as multipart/form-data with these parts:

| Form part | Content | Description | | --- | --- | --- | | metadata | JSON Blob | Contains productType, modelId, optional textureId, and a settings object. | | roomPhoto | Blob \| File | Source room image. | | customTexture | Blob \| File | Optional texture image when options.customTexture is provided. |

The metadata JSON is shaped as follows:

{
  "productType": "Curtains",
  "modelId": "double_pleat",
  "textureId": "linen-warm-white",
  "settings": {
    "width": "280",
    "height": "240",
    "lining": "blackout"
  }
}

Serialization rules:

  • productType and modelId are always included in metadata.
  • options.textureId is copied to metadata.textureId.
  • options.customTexture is appended as the separate customTexture form part.
  • customTexture and textureId are not copied into metadata.settings.
  • Every other defined, non-null option is copied into metadata.settings and converted with String(value).
  • The browser request uses Authorization: Bearer <sessionToken> and does not manually set Content-Type, allowing the browser to add the multipart boundary.

Types & API references

ProductType

enum ProductType {
  Curtains = 'Curtains',
  RollerBlind = 'RollerBlind',
}

ModelId

enum ModelId {
  SinglePleat = 'single_pleat',
  DoublePleat = 'double_pleat',
  Wave = 'wave',
  Eyelet = 'eyelet',
  RomanBlind = 'roman_blind',
  RollerStandard = 'roller_standard',
}

SessionRequest

interface SessionRequest {
  maxUses?: number;
  expiresInSeconds?: number;
  allowedOrigins?: string[];
  metadata?: string;
}

SessionResponse

interface SessionResponse {
  token: string;
}

ImageGenerationOptions

interface ImageGenerationOptions {
  customTexture?: Blob | File;
  textureId?: string;
  [key: string]: any;
}

Use textureId for server-known textures and customTexture for user-provided texture files. Additional keys are supported for product-specific settings and are serialized into the settings object.

Security & best practices

  • Never instantiate AiStudioServerClient in browser code.
  • Never expose the permanent AI Studio API key to frontend bundles, HTML, logs, telemetry, or network responses.
  • Store the API key in a secure server-side secret store or environment variable.
  • Create short-lived session tokens with the smallest practical expiresInSeconds value.
  • Limit maxUses to the number of generations required for the current user action.
  • Set allowedOrigins to exact trusted origins instead of broad wildcard-like values.
  • Validate uploaded images before passing them to AI Studio, including file size, MIME type, and user permissions.
  • Avoid logging session tokens, generated image payloads, room photos, or custom texture files.
  • Revoke or rotate permanent API keys according to your organization security policy.

Error handling and license

Both clients throw an Error when AI Studio responds with a non-success HTTP status.

  • Session creation failures use the message format AiStudio session creation failed: <status> <statusText>.
  • Image generation failures use the message format AiStudio image generation failed: <status> <statusText>.
  • Network failures and malformed responses are surfaced by the underlying fetch implementation.

Recommended handling:

try {
  const imageBlob = await client.generateImage(
    roomPhoto,
    ProductType.Curtains,
    ModelId.SinglePleat,
  );

  return URL.createObjectURL(imageBlob);
} catch (error) {
  console.error('AI Studio generation failed.', error);
  throw new Error('The preview could not be generated. Please try again.');
}

This package is proprietary software owned by Sieval. All rights are reserved. Usage, copying, modification, and distribution are only permitted under an agreement with Sieval or another explicitly granted written license.