New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@coderule/clients

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@coderule/clients

TypeScript HTTP clients for core Coderule microservices (Auth, Sync, Retrieval, AST)

latest
npmnpm
Version
2.3.0
Version published
Maintainers
1
Created
Source

Coderule TypeScript Client SDK

TypeScript HTTP clients for core Coderule microservices (Auth, Sync, Retrieval, AST) with automatic fetch polyfill support.

Requirements

  • Node.js 14+ (automatically uses node-fetch for versions < 18, native fetch for 18+)
  • TypeScript 5.0+

Node.js Version Compatibility

  • Node.js 18+: Uses native fetch API (no additional dependencies needed)
  • Node.js 14-17: Requires node-fetch to be installed:
    npm install node-fetch@2
    

The library automatically detects your Node.js version and uses the appropriate fetch implementation.

Installation

npm install
npm run build

Usage Examples

Unified client access

import { CoderuleClients, consoleLogger } from '@coderule/clients';

const clients = new CoderuleClients({
  token: process.env.CODERULE_TOKEN!,
  auth: { baseUrl: 'https://r.coderule.ai:16803' }, // optional, defaults to this host
  logger: consoleLogger, // optional, defaults to nullLogger (silent)
});

const snapshotStatus = await clients.sync.checkSnapshotStatus(snapshotHash);
const retrieval = await clients.retrieval.query(snapshotHash, 'Find the entrypoint');
const visitorRules = await clients.ast.getVisitorRulesV2();

clients.close();

The unified client automatically exchanges your long-lived token for short-lived JWTs using the Auth service. Tokens are cached and refreshed halfway through their lifetime. Whenever the Auth service returns a JWT with a different server_url, the AST, Retrieval, and Sync clients update their base URLs on the fly.

You can override individual service hosts or timeouts:

const clients = new CoderuleClients({
  token,
  auth: { baseUrl: 'https://internal-auth.example.com' },
  retrieval: { timeout: 90_000 },
  sync: { baseUrl: 'http://localhost:8002' }, // static override keeps sync on localhost
});

Manual wiring

If you prefer to manage dependency injection yourself, wire the Auth client and JWT factory and pass the provider into the other clients.

import {
  AuthHttpClient,
  JWTFactory,
  RetrievalHttpClient,
  SyncHttpClient,
  ASTHttpClient,
} from '@coderule/clients';

const authClient = new AuthHttpClient('http://localhost:8001');
const jwtFactory = new JWTFactory(authClient, longLivedToken);

const syncClient = new SyncHttpClient({
  baseUrl: 'http://localhost:8002',
  jwtProvider: jwtFactory,
});

const astClient = new ASTHttpClient({
  baseUrl: 'http://localhost:8003',
  jwtProvider: jwtFactory,
});

const retrievalClient = new RetrievalHttpClient({
  baseUrl: 'http://localhost:8004',
  jwtProvider: jwtFactory,
});

const status = await syncClient.checkSnapshotStatus(snapshotHash);
const queryResult = await retrievalClient.query(snapshotHash, 'Find the entrypoint');
const rules = await astClient.getVisitorRulesV2();

Authentication service

const authClient = new AuthHttpClient('http://localhost:8001');

try {
  const authResponse = await authClient.authenticate('your-token');
  console.log(`JWT expires at: ${authResponse.expires_at}`);

  const health = await authClient.health();
  console.log(`Auth service status: ${health.status}`);
} finally {
  authClient.close();
}

Sync service

const syncClient = new SyncHttpClient({
  baseUrl: 'http://localhost:8002',
  jwtProvider: jwtFactory,
});

const files = [
  { file_path: 'src/main.ts', content: 'const x = 1;' },
  { file_path: 'src/utils.ts', content: 'export function util() {}' },
  { file_path: 'package.json', content: '{"name": "test"}' },
];

const filesInfo = [];
const fileHashes = [];
const fileContents = new Map();

for (const file of files) {
  const fileHash = SyncHttpClient.calculateFileHash(file.file_path, file.content);
  filesInfo.push({ file_path: file.file_path, file_hash: fileHash });
  fileContents.set(fileHash, {
    path: file.file_path,
    content: Buffer.from(file.content),
  });
  fileHashes.push(fileHash);
}

const snapshotHash = SyncHttpClient.calculateSnapshotHash(fileHashes);

const status = await syncClient.checkSnapshotStatus(snapshotHash);
if (status.status === 'NOT_FOUND') {
  const result = await syncClient.createSnapshot(snapshotHash, filesInfo);

  if (result.status === 'MISSING_CONTENT' && result.missing_files) {
    const missingContent = new Map();
    for (const missingFile of result.missing_files) {
      if (fileContents.has(missingFile.file_hash)) {
        missingContent.set(
          missingFile.file_hash,
          fileContents.get(missingFile.file_hash)!,
        );
      }
    }

    if (missingContent.size > 0) {
      await syncClient.uploadFileContent(missingContent);
      await syncClient.createSnapshot(snapshotHash, filesInfo);
    }
  }
}

// Download a self-contained HDF5 bush file for offline use
const bushBuffer = await syncClient.downloadSnapshotBush(snapshotHash);
fs.writeFileSync('snapshot.h5', Buffer.from(bushBuffer));

// Fetch the HDF5 bush reader skill (public, no auth required)
const skillMarkdown = await syncClient.getHdf5BushReaderSkill();

AST service

const astClient = new ASTHttpClient({
  baseUrl: 'http://localhost:8003',
  jwtProvider: jwtFactory,
});

const health = await astClient.health();
console.log(`AST service status: ${health.status}`);

const rules = await astClient.getVisitorRulesV2();
console.log(`Rules format: ${rules.format}`);

const compiled = ASTHttpClient.compileRulesV2(rules);
const ignoredPredicate = ASTHttpClient.buildIgnoredPredicate(compiled);

Retrieval service

const retrievalClient = new RetrievalHttpClient({
  baseUrl: 'http://localhost:8004',
  jwtProvider: jwtFactory,
});

const result = await retrievalClient.query(
  snapshotHash,
  'Find the main authentication logic',
  3000,
  {
    formatter: 'compact',
    flow_strength: 1.5,
    blend_alpha: 0.8,
  },
);

console.log(result.formatted_output);

const status = await retrievalClient.checkSnapshotStatus(snapshotHash);
console.log(`Snapshot indexing status: ${status.status}`);

const cacheStats = await retrievalClient.getCacheStats();
console.log(`Cached snapshots: ${cacheStats.cached_snapshots}`);

Utility Methods

The SyncHttpClient provides static utility methods for hash calculation:

import { SyncHttpClient } from '@coderule/clients';

// Calculate file hash from path and content
const fileHash = SyncHttpClient.calculateFileHash('src/main.ts', 'const x = 1;');
console.log(`File hash: ${fileHash}`);

// Calculate snapshot hash from file hashes
const fileHashes = ['hash1', 'hash2', 'hash3'];
const snapshotHash = SyncHttpClient.calculateSnapshotHash(fileHashes);
console.log(`Snapshot hash: ${snapshotHash}`);

Error Handling

All clients throw errors with descriptive messages on failures:

try {
  const result = await client.someMethod();
} catch (error) {
  if (error.message.includes('timeout')) {
    console.error('Request timed out');
  } else if (error.message.includes('401')) {
    console.error('Authentication failed');
  } else {
    console.error('Unexpected error:', error.message);
  }
}

Configuration

All clients support timeout configuration in milliseconds:

// Custom timeout of 30 seconds
const retrievalClient = new RetrievalHttpClient({
  baseUrl: 'http://localhost:8004',
  timeout: 30_000,
  jwtProvider: jwtFactory,
  logger: consoleLogger, // optional
});

CoderuleClients also accepts per-service overrides via the auth, ast, retrieval, and sync options. JWTFactory exposes an onTokenRefreshed callback if you need to observe token rotations (for example, to log the current server_url).

Logging

The SDK includes a flexible logging interface that allows you to integrate with any logging library:

import { Logger, nullLogger, consoleLogger } from '@coderule/clients';

// Use the built-in silent logger (default)
const silentClients = new CoderuleClients({
  token,
  logger: nullLogger, // or omit for default
});

// Use the built-in console logger for debugging
const debugClients = new CoderuleClients({
  token,
  logger: consoleLogger,
});

// Implement your own logger
const customLogger: Logger = {
  error: (message, ...meta) => myLogger.error(message, meta),
  warn: (message, ...meta) => myLogger.warn(message, meta),
  info: (message, ...meta) => myLogger.info(message, meta),
  debug: (message, ...meta) => myLogger.debug(message, meta),
};

const clients = new CoderuleClients({
  token,
  logger: customLogger,
});

All individual clients also accept an optional logger parameter:

const authClient = new AuthHttpClient('http://localhost:8001', 30000, consoleLogger);

Breaking Changes

v1.6.0

  • Logger interface added: All clients now accept an optional logger parameter
  • Default behavior is silent: By default, clients use nullLogger which produces no output
  • Backward compatible: The logger parameter is optional, existing code continues to work

v1.4.0

  • Clients now require a JWT provider: SyncHttpClient, RetrievalHttpClient, and ASTHttpClient no longer accept JWT strings per method. Inject a JWTFactory or any JWTProvider implementation through the constructor instead.
  • Unified entry point: CoderuleClients centralises token exchange. Auth defaults to https://r.coderule.ai:16803, and other clients automatically adopt the server_url provided by the Auth service unless explicitly overridden.

Notes

  • Automatic fetch detection: Works with Node.js 14+ (uses node-fetch for < 18, native fetch for 18+)
  • Optional dependency: node-fetch is only required for Node.js versions < 18
  • Zero dependencies for Node.js 18+: Uses native fetch API
  • Clients automatically handle JSON serialization/deserialization
  • JWT handling is centralised through a JWTProvider (JWTFactory or CoderuleClients)
  • AST, Retrieval, and Sync clients update their base URLs when the JWT refresh returns a different server_url (unless a manual override is configured)
  • Health check endpoints don't require authentication
  • All clients have a close() method for consistency, though fetch doesn't maintain persistent connections

Building from Source

# Install dependencies
npm install

# Build TypeScript to JavaScript
npm run build

# Output will be in dist/ directory

License

ISC

Keywords

coderule

FAQs

Package last updated on 20 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts