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

neuwo-api

v1.0.1

Published

TypeScript/JavaScript SDK client for the Neuwo content classification API

Readme

Neuwo API JavaScript/TypeScript SDK

JavaScript/TypeScript SDK client for the Neuwo content classification API.

npm version npm bundle size JSR JSR Score TypeScript Node.js License: MIT

Support

Installation

Install the package using npm:

npm install neuwo-api

Requirements

  • Node.js 18.0.0 or higher (for native fetch API support)
  • Modern browsers with fetch support

Browser Compatibility

The SDK uses native fetch API which is supported in:

  • Chrome/Edge: 42+
  • Firefox: 39+
  • Safari: 10.1+
  • Node.js: 18.0+

For older browsers, you'll need to provide a fetch polyfill.

Quick Start

For more detailed examples and use cases, see the examples folder in the repository.

Usage in Different Environments

Node.js (ESM)

import { NeuwoRestClient, NeuwoEdgeClient } from "neuwo-api";

Node.js (CommonJS)

const { NeuwoRestClient, NeuwoEdgeClient } = require("neuwo-api");

Browser (ESM)

<script type="module">
  import { NeuwoEdgeClient } from "https://cdn.jsdelivr.net/npm/neuwo-api/+esm";
</script>

REST API Client

import { NeuwoRestClient } from "neuwo-api";

// Initialise client
const client = new NeuwoRestClient({
  token: "your-rest-api-token",
  baseUrl: "https://custom.api.com",
});

// Analyse text content
const response = await client.getAiTopics({
  content: "Cats make wonderful pets for modern households.",
  documentId: "article-123",
  headline: "Why Cats Make Great Pets",
});

// Access results
console.log(`Tags: ${response.tags.length}`);
response.tags.forEach((tag) => {
  console.log(`  - ${tag.value} (score: ${tag.score})`);
});

console.log(`Brand Safe: ${response.brandSafety.isSafe}`);
console.log(`IAB Categories: ${response.marketingCategories.iabTier1.length}`);

EDGE API Client

import { NeuwoEdgeClient } from "neuwo-api";

// Initialise client
const client = new NeuwoEdgeClient({
  token: "your-edge-api-token",
  baseUrl: "https://custom.api.com",
  defaultOrigin: "https://yourwebsite.com", // Optional: default origin for requests
});

// Analyse article by URL
const response = await client.getAiTopics({
  url: "https://example.com/article",
});

// Or wait for analysis to complete (with automatic retry)
const responseWithWait = await client.getAiTopicsWait({
  url: "https://example.com/new-article",
  maxRetries: 10,
  retryInterval: 6,
});

console.log(`Found ${responseWithWait.tags.length} tags for the article`);

Configuration

REST Client Parameters

| Parameter | Type | Default | Description | | --------- | -------- | ------------ | ----------------------------- | | token | string | Required | REST API authentication token | | baseUrl | string | Required | Base URL for the API | | timeout | number | 60 | Request timeout in seconds |

const client = new NeuwoRestClient({
  token: "your-token",
  baseUrl: "https://custom.api.com",
  timeout: 120,
});

EDGE Client Parameters

| Parameter | Type | Default | Description | | --------------- | -------- | ------------ | ---------------------------------- | | token | string | Required | EDGE API authentication token | | baseUrl | string | Required | Base URL for the API | | timeout | number | 60 | Request timeout in seconds | | defaultOrigin | string | undefined | Default Origin header for requests |

const client = new NeuwoEdgeClient({
  token: "your-token",
  baseUrl: "https://custom.api.com",
  defaultOrigin: "https://yoursite.com",
  timeout: 90,
});

API Methods

REST API

Get AI Topics
const response = await client.getAiTopics({
  content: "Text to analyse", // Required
  documentId: "doc123", // Optional: save to database
  lang: "en", // Optional: ISO 639-1 code
  publicationId: "pub1", // Optional
  headline: "Article Headline", // Optional
  tagLimit: 15, // Optional: max tags (default: 15)
  tagMinScore: 0.1, // Optional: min score (default: 0.1)
  marketingLimit: undefined, // Optional
  marketingMinScore: 0.3, // Optional (default: 0.3)
  includeInSim: true, // Optional (default: true)
  articleUrl: "https://example.com", // Optional
});
Get Similar Articles
const articles = await client.getSimilar({
  documentId: "doc123", // Required
  maxRows: 10, // Optional: limit results
  pastDays: 30, // Optional: limit by date
  publicationIds: ["pub1", "pub2"], // Optional: filter by publication
});
Update Article
const article = await client.updateArticle({
  documentId: "doc123", // Required
  published: new Date("2024-01-15"), // Optional
  headline: "Updated Headline", // Optional
  writer: "Author Name", // Optional
  category: "News", // Optional
  content: "Updated content", // Optional
  summary: "Summary", // Optional
  publicationId: "pub1", // Optional
  articleUrl: "https://example.com", // Optional
  includeInSim: true, // Optional
});
Train AI Topics
const trainingTags = await client.trainAiTopics({
  documentId: "doc123", // Required
  tags: ["tag1", "tag2", "tag3"], // Required
});

EDGE API

Get AI Topics (Single URL)
const response = await client.getAiTopics({
  url: "https://example.com/article", // Required
  origin: "https://yoursite.com", // Optional: override default origin
});
Get AI Topics with Auto-Retry
const response = await client.getAiTopicsWait({
  url: "https://example.com/article", // Required
  origin: "https://yoursite.com", // Optional
  maxRetries: 10, // Optional (default: 10)
  retryInterval: 6, // Optional (default: 6s)
  initialDelay: 2, // Optional (default: 2s)
});

Raw Response Methods

All methods have *Raw variants that return the raw Response object:

// REST
const rawResponse = await client.getAiTopicsRaw({
  content: "Text",
});
console.log(rawResponse.status);
console.log(await rawResponse.text());

// EDGE
const rawResponse = await client.getAiTopicsRaw({
  url: "https://example.com",
});
console.log(await rawResponse.json());

Error Handling

The SDK provides specific exceptions for different error scenarios:

import {
  NeuwoRestClient,
  ValidationError,
  AuthenticationError,
  NoDataAvailableError,
  ContentNotAvailableError,
  NetworkError,
} from "neuwo-api";

const client = new NeuwoRestClient({
  token: "your-token",
  baseUrl: "https://custom.api.com",
});

try {
  const response = await client.getAiTopics({
    content: "Your content here",
  });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error(`Invalid input: ${error.message}`);
  } else if (error instanceof AuthenticationError) {
    console.error(`Authentication failed: ${error.message}`);
  } else if (error instanceof NoDataAvailableError) {
    console.error(`Data not yet available: ${error.message}`);
  } else if (error instanceof ContentNotAvailableError) {
    console.error(`Content could not be analysed: ${error.message}`);
  } else if (error instanceof NetworkError) {
    console.error(`Network error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error.message}`);
  }
}

Exception Hierarchy

  • NeuwoAPIError - Base exception for all API errors
    • AuthenticationError - Invalid or missing token (401)
    • ForbiddenError - Token lacks permissions (403)
    • NotFoundError - Resource not found (404)
      • NoDataAvailableError - URL not yet processed (404)
    • BadRequestError - Malformed request (400)
    • ValidationError - Request validation failed (422)
    • RateLimitError - Rate limit exceeded (429)
    • ServerError - Server error (5xx)
    • NetworkError - Network communication failed
    • ContentNotAvailableError - Content tagging failed

Logging

The SDK provides configurable logging for debugging and monitoring:

import { setupLogger, disableLogger, LogLevel } from "neuwo-api";

// Enable debug logging
setupLogger(LogLevel.DEBUG);

// Only show warnings and errors (default)
setupLogger(LogLevel.WARNING);

// Disable logging
disableLogger();

Available log levels:

  • LogLevel.DEBUG - Detailed API request/response information
  • LogLevel.INFO - General operation info
  • LogLevel.WARNING - Warnings (default)
  • LogLevel.ERROR - Errors only
  • LogLevel.NONE - Disable all logging

Note: Sensitive information like tokens are automatically sanitised in log output.

TypeScript Support

The SDK is written in TypeScript and includes full type definitions. All models and parameters are fully typed:

import { NeuwoRestClient, GetAiTopicsResponse, Tag } from "neuwo-api";

const client = new NeuwoRestClient({
  token: "your-token",
  baseUrl: "https://api.example.com",
});

const response: GetAiTopicsResponse = await client.getAiTopics({
  content: "Sample text",
  tagLimit: 10,
});

response.tags.forEach((tag: Tag) => {
  console.log(`${tag.value}: ${tag.score}`);
});

Development

Setup Development Environment

# Clone repository
git clone https://github.com/neuwoai/neuwo-api-sdk-js-ts.git
cd neuwo-api-sdk-js-ts

# Install dependencies
npm install

Running Tests

# Run all tests
npm test

# Run with coverage
npm run test:coverage

# Generate coverage report
npm run test:coverage:report

Code Quality

# Format code
npm run format

# Check formatting without changes
npm run format:check

# Lint code
npm run lint

# Lint and auto-fix issues
npm run lint:fix

# Type checking
npm run type-check

# Run all checks (format, lint, type-check)
npm run check

# Run all checks including tests
npm run check:all

# Auto-fix formatting and linting issues
npm run fix

Building Distribution

# Build for production
npm run rebuild

# Build both CJS and ESM
npm run build

# Build only CJS
npm run build:cjs

# Build only ESM
npm run build:esm

# Clean build output
npm run clean

Pre-publish Package Validation

Before publishing, validate your package to ensure it's configured correctly:

# Clean build the package first
npm run rebuild

# Verify package contents (dry-run)
npm pack --dry-run

# Check for type issues in the package
npx @arethetypeswrong/cli --pack

# Validate package.json configuration
npx publint --strict

# Test npm publish (dry-run)
npm publish --dry-run

# Test JSR publish (dry-run)
npx jsr publish --dry-run

These validation steps are automatically run in the CI/CD pipeline before publishing.

CI/CD

Automated Testing

The Unit Tests Coverage workflow automatically runs on every push to main or dev branches and on pull requests:

  • Node.js versions tested: 18, 20, 22
  • Coverage reporting: Results uploaded to Codecov
  • Test execution: Full test suite with coverage analysis

Publishing Pipeline

The Publish JavaScript/TypeScript SDK workflow enables manual deployment with the following options:

Workflow Features:

  • Manual trigger via GitHub Actions UI
  • Deploy to npm registry
  • Deploy to JSR (JavaScript Registry)
  • Auto-create GitHub releases with tags
  • Automatic version extraction from package.json
  • Package validation with @arethetypeswrong/cli and publint

Setup Requirements:

Add GitHub secrets for API tokens:

  • NPM_TOKEN - npm registry authentication token
  • JSR_TOKEN - JSR registry authentication token

Workflow Inputs

| Input | Type | Default | Description | | ---------------- | ------- | ------- | ------------------------------------ | | publish_to_npm | boolean | true | Publish to npm registry | | publish_to_jsr | boolean | true | Publish to JSR (JavaScript Registry) | | create_release | boolean | true | Create GitHub release with tag |

Usage:

  1. Prepare release:

  2. Publish:

    • Go to Actions > Publish JavaScript/TypeScript SDK > Run workflow
    • Select desired options (npm, JSR, GitHub release)
    • Creates tag (e.g., v0.1.0), GitHub release, and publishes to selected registries
  3. Verify:

    • Check npm: https://www.npmjs.com/package/neuwo-api
    • Check JSR: https://jsr.io/@neuwo/neuwo-api
    • Check GitHub Release: https://github.com/neuwoai/neuwo-api-sdk-js-ts/releases
    • Test installation: npm install neuwo-api@latest

What gets created:

  • npm package: https://www.npmjs.com/package/neuwo-api
  • JSR package: https://jsr.io/@neuwo/neuwo-api
  • GitHub release with .tgz and distribution files
  • Git tag following v{VERSION} format
  • CDN links (unpkg, jsDelivr, esm.sh)

Versioning:

Follow Semantic Versioning (MAJOR.MINOR.PATCH):

  • MAJOR: Breaking changes
  • MINOR: New features (backward compatible)
  • PATCH: Bug fixes (backward compatible)

License

This project is licensed under the MIT License - see the LICENCE file for details.