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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@stain-win/gaia-client

v0.0.1-rc.8

Published

TypeScript/JavaScript client library for Gaia secret management daemon

Readme

'@stain-win/gaia-client'

TypeScript/JavaScript client library for Gaia - a secure, self-hosted secret management daemon.

Installation

npm install '@stain-win/gaia-client'

Quick Start

import { createClient } from @stain-win/gaia-client';

// Connect to Gaia daemon
const client = await createClient({
  address: 'localhost:50051',
  caCertFile: './certs/ca.crt',
  clientCertFile: './certs/client.crt',
  clientKeyFile: './certs/client.key'
});

try {
  // Fetch a secret
  const dbUrl = await client.getSecret('production', 'database_url');
  console.log('Database URL:', dbUrl);

  // Get all common secrets
  const secrets = await client.getCommonSecrets();
  console.log('All secrets:', secrets);

  // Load secrets into environment variables
  await client.loadEnv();
  // Now accessible as: process.env.GAIA_PRODUCTION_DATABASE_URL

} finally {
  await client.close();
}

API Reference

createClient(config: GaiaClientConfig): Promise<GaiaClient>

Creates and connects a Gaia client in one step.

Parameters:

  • config.address (string, required): Address of the Gaia gRPC server (e.g., "localhost:50051")
  • config.caCertFile (string, optional): Path to the CA certificate file
  • config.clientCertFile (string, optional): Path to the client's certificate file
  • config.clientKeyFile (string, optional): Path to the client's private key file
  • config.timeout (number, optional): Connection timeout in milliseconds (default: 5000)
  • config.insecure (boolean, optional): Allow insecure connections (default: false, for development only)

Returns: Connected GaiaClient instance

Example:

const client = await createClient({
  address: 'localhost:50051',
  caCertFile: './certs/ca.crt',
  clientCertFile: './certs/client.crt',
  clientKeyFile: './certs/client.key',
  timeout: 10000
});

GaiaClient

High-level client for interacting with the Gaia daemon.

Constructor

new GaiaClient(config: GaiaClientConfig)

Creates a new Gaia client. You must call connect() before using other methods.

Methods

connect(): Promise<void>

Establishes connection to the Gaia daemon.

const client = new GaiaClient(config);
await client.connect();
getSecret(namespace: string, id: string): Promise<string>

Fetches a single secret from a specific namespace.

Parameters:

  • namespace: The namespace containing the secret
  • id: The secret ID

Returns: The secret value

Example:

const apiKey = await client.getSecret('production', 'api_key');
getCommonSecrets(namespace?: string): Promise<SecretsMap>

Fetches secrets from the "common" area.

Parameters:

  • namespace (optional): If provided, returns secrets only for this namespace

Returns: Map of namespace names to their secrets (key-value pairs)

Example:

// Get all common secrets
const allSecrets = await client.getCommonSecrets();
// { production: { api_key: '...', db_url: '...' }, staging: { ... } }

// Get secrets from specific namespace
const prodSecrets = await client.getCommonSecrets('production');
// { production: { api_key: '...', db_url: '...' } }
loadEnv(): Promise<void>

Loads all common secrets into process.env.

Environment variables are formatted as GAIA_NAMESPACE_KEY.

  • Namespace and key names are uppercased
  • Hyphens are replaced with underscores

Example:

await client.loadEnv();

// Secrets are now available as environment variables:
console.log(process.env.GAIA_PRODUCTION_DATABASE_URL);
console.log(process.env.GAIA_PRODUCTION_API_KEY);
getStatus(): Promise<string>

Checks the current operational status of the Gaia daemon.

Returns: Status string (e.g., "locked", "unlocked", "offline")

Example:

const status = await client.getStatus();
console.log('Daemon status:', status);
getNamespaces(): Promise<string[]>

Lists all namespaces the authenticated client has access to.

Returns: Array of namespace names

Example:

const namespaces = await client.getNamespaces();
console.log('Available namespaces:', namespaces);
// ['common', 'production', 'staging']
close(): Promise<void>

Closes the connection to the Gaia daemon. Should be called when done.

await client.close();

TypeScript Types

interface GaiaClientConfig {
  address: string;
  caCertFile?: string;
  clientCertFile?: string;
  clientKeyFile?: string;
  timeout?: number;
  insecure?: boolean;
}

interface Secret {
  id: string;
  value: string;
}

interface Namespace {
  name: string;
  secrets: Secret[];
}

type SecretsMap = Record<string, Record<string, string>>;

Advanced Usage

Manual Connection Management

import { GaiaClient } from ''@stain-win/gaia-client'';

const client = new GaiaClient({
  address: 'localhost:50051',
  caCertFile: './certs/ca.crt',
  clientCertFile: './certs/client.crt',
  clientKeyFile: './certs/client.key'
});

try {
  await client.connect();
  
  // Use client...
  const secret = await client.getSecret('production', 'api_key');
  
} catch (error) {
  console.error('Failed:', error);
} finally {
  await client.close();
}

Insecure Connection (Development Only)

const client = await createClient({
  address: 'localhost:50051',
  insecure: true  // WARNING: For development only!
});

Error Handling

try {
  const secret = await client.getSecret('production', 'api_key');
} catch (error) {
  if (error.code === grpc.status.NOT_FOUND) {
    console.error('Secret not found');
  } else if (error.code === grpc.status.PERMISSION_DENIED) {
    console.error('Access denied');
  } else {
    console.error('Error:', error.message);
  }
}

Using with Express.js

import express from 'express';
import { createClient } from ''@stain-win/gaia-client'';

const app = express();

// Load secrets on startup
const client = await createClient({
  address: 'localhost:50051',
  caCertFile: './certs/ca.crt',
  clientCertFile: './certs/client.crt',
  clientKeyFile: './certs/client.key'
});

await client.loadEnv();

// Access secrets via environment variables
const dbUrl = process.env.GAIA_PRODUCTION_DATABASE_URL;

app.listen(3000, () => {
  console.log('Server started');
});

// Cleanup on shutdown
process.on('SIGTERM', async () => {
  await client.close();
  process.exit(0);
});

Requirements

  • Node.js >= 14.x
  • Gaia daemon running and accessible
  • Valid mTLS certificates (unless using insecure mode)

License

MIT


Links