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

tsoap-cli

v0.0.4

Published

End-to-end type-safe SOAP client for TypeScript. Generate typed RPC wrappers directly from WSDLs.

Readme

tsoap-cli

npm License: MIT

Code generator that reads a WSDL file and emits a fully typed TypeScript client. Designed to replace the manual client.describe() + any-cast workflow you're used to with the soap package.

Why

If you've used the soap package, you know the drill:

import soap from 'soap';

const client = await soap.createClientAsync('http://example.com?wsdl');

// No types, no autocomplete — everything is `any`
const [result] = await client.MyOperationAsync({ foo: 'bar' });

tsoap-cli generates TypeScript interfaces and a typed factory function from your WSDL so you get full autocomplete, compile-time type checking, and a cleaner async API.

Install

# npm
npm install -D tsoap-cli

# pnpm
pnpm add -D tsoap-cli

# yarn
yarn add -D tsoap-cli

You also need the runtime package as a production dependency:

npm install typed-soap

Usage

Generate types from a WSDL

npx tsoap generate --input <path-or-url> --output <dir>

| Flag | Alias | Description | Required | |------|-------|-------------|----------| | --input <path> | -i | Path to a local .wsdl file or a URL | Yes | | --output <dir> | -o | Directory where the generated .ts file is written | Yes |

Examples

# Local WSDL file
npx tsoap generate -i ./wsdl/weather.wsdl -o ./src/generated

# Remote WSDL URL
npx tsoap generate -i https://api.example.com/weather?wsdl -o ./src/generated

The output file is named after the input file — weather.wsdl produces weather.ts.

Use the generated client

import { createWeatherServiceClient } from './src/generated/weather.js';

const client = await createWeatherServiceClient('http://example.com/weather?wsdl');

// Fully typed: service -> port -> operation
const result = await client.WeatherService.WeatherPort.GetWeather({ city: 'NYC' });
console.log(result.temperature); // number — autocompleted and type-checked

What gets generated

Given a WSDL that defines a WeatherService with a GetWeather operation, the CLI produces a file like this:

// Auto-generated by tsoap-cli — do not edit

import { createSoapClient } from "typed-soap";
import type { ServiceDefinition, InferClient, SoapClientOptions } from "typed-soap";

// --- Enums (if the WSDL has XSD enumerations) ---
export type WeatherCondition = "SUNNY" | "CLOUDY" | "RAINY";

// --- Interfaces for every input/output type ---
export interface GetWeatherRequest {
  city: string;
}

export interface GetWeatherResponse {
  temperature: number;
  condition: WeatherCondition;
  description?: string;
}

// --- Service definition (maps the WSDL structure) ---
export interface WeatherServiceDefinition extends ServiceDefinition {
  WeatherService: {
    WeatherPort: {
      GetWeather: {
        input: GetWeatherRequest;
        output: GetWeatherResponse;
      };
    };
  };
}

// --- Typed factory function ---
export type WeatherServiceClient = InferClient<WeatherServiceDefinition>;

export async function createWeatherServiceClient(
  wsdlUrl: string,
  options?: SoapClientOptions,
): Promise<WeatherServiceClient> {
  return createSoapClient<WeatherServiceDefinition>(wsdlUrl, options);
}

Naming conventions

| WSDL concept | Generated name | |---|---| | Service definition type | {ServiceName}Definition | | Client type | {ServiceName}Client | | Factory function | create{ServiceName}Client | | Input/output types | Named after the WSDL element names (e.g. GetWeatherRequest) | | Enums | Named after the XSD simpleType (PascalCase) |

If the WSDL contains multiple services, the names fall back to GeneratedServiceDefinition, GeneratedClient, and createGeneratedClient.

Coming from the soap package

| Before (soap) | After (tsoap-cli + typed-soap) | |---|---| | client.MyOpAsync(args) returns [result, rawResponse, soapHeader, rawRequest] | client.Service.Port.MyOp(args) returns the result directly | | No types — everything is any | Full interfaces generated from WSDL | | You guess at field names | Autocomplete on every field | | Typos in operation names fail silently at runtime | Caught at compile time | | Numeric XSD types like unsignedInt arrive as strings | Custom deserializers convert them to number |

Supported XSD types

| XSD Type | TypeScript | Notes | |---|---|---| | int, short, byte, float, double | number | | | unsignedInt, unsignedShort, unsignedByte | number | Custom deserializer | | long, unsignedLong, integer, decimal | number | Precision warning emitted | | boolean | boolean | | | dateTime, date | Date | | | string, normalizedString, token, anyURI, base64Binary | string | | | anyType | unknown | | | Enumerations | Union literal type | e.g. "A" \| "B" | | maxOccurs="unbounded" | T[] | | | minOccurs="0" | Optional property (?) | |

Adding to your build

A common pattern is to add a generate script to your package.json:

{
  "scripts": {
    "generate:types": "tsoap generate -i ./wsdl/my-service.wsdl -o ./src/generated"
  }
}

Then run npm run generate:types whenever the WSDL changes. The generated file should be checked into source control so your CI doesn't need access to the WSDL at build time.

Requirements

  • Node.js 18+
  • TypeScript 5.x (for consuming the generated types)

License

MIT