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

@marc-newton/solid-class-js

v1.0.0

Published

> A robust TypeScript/JavaScript library for building SOLID, strictly-typed data models. Safely ingest, sanitize, and cast raw API responses into structured class instances.

Readme

Solid Class JS

A robust TypeScript/JavaScript library for building SOLID, strictly-typed data models. Safely ingest, sanitize, and cast raw API responses into structured class instances.

Solid Class JS provides a foundational base class and a suite of TypeScript decorators to help you map messy, untrusted data to strict, predictable data models. By defining the expected attributes, data types, and nested relationships in your classes, Solid Class JS automatically handles type-casting, strips out unrecognized keys, and enriches your data payloads.

Features

  • SOLID by Design: Extend the core base class to keep your data models modular, single-purpose, and strictly defined.
  • Safe Data Assimilation: The assign method takes raw JSON/objects, matches them against your defined properties, and ignores any unexpected keys to prevent prototype pollution or data leaks.
  • Automatic Type Casting: Ensures incoming data matches your expected types (e.g., parsing numeric strings into actual JavaScript numbers).
  • Decorator-Driven: Clean, declarative syntax using TypeScript experimental decorators to define types, default values, and data enrichment rules.
  • Recursive Structures: Easily handle complex API responses with nested objects and arrays of class instances.

Installation

Use your preferred package manager to install solid-class-js.

npm install solid-class-js
pnpm add solid-class-js
yarn add solid-class-js
bun add solid-class-js

Note: Because solid-class-js relies on TypeScript decorators, you must enable experimentalDecorators and emitDecoratorMetadata in your tsconfig.json.

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Quick Start

1. Define Your Models

Extend the BaseModel to inherit the assign functionality. Use decorators to define your property types and nested structures.

import { BaseModel, Cast, CastArray, Enrich } from 'solid-class-js';

// A nested class model
class Address extends BaseModel {
  @Cast('string')
  street!: string;

  @Cast('string')
  city!: string;
}

// Your primary data model
class User extends BaseModel {
  @Cast('number')
  id!: number;

  @Cast('string')
  username!: string;

  // Use decorators to handle arrays of other class instances
  @CastArray(() => Address)
  addresses!: Address[];

  // Use custom enrichment logic
  @Enrich((data) => data.firstName + ' ' + data.lastName)
  fullName!: string;
}

2. Ingest API Data

When you receive a payload from your API, simply instantiate your class and use the assign method. Unmapped keys will be safely ignored, and nested arrays will automatically instantiate their respective classes.

// Messy API response with extra, unneeded data
const apiResponse = {
  id: "123", // Note: String type from API, but we want a Number
  username: "johndoe",
  firstName: "John",
  lastName: "Doe",
  secretToken: "xyz123", // We don't want this in our model!
  addresses: [
    { street: "123 Main St", city: "Manchester", extraKey: "ignore me" }
  ]
};

// Assimilate the data
const user = new User();
user.assign(apiResponse);

console.log(user.id); 
// Output: 123 (Successfully cast to a number)

console.log(user.secretToken); 
// Output: undefined (Ignored because it wasn't defined in the User class)

console.log(user.fullName); 
// Output: "John Doe" (Generated via the @Enrich decorator)

console.log(user.addresses[0] instanceof Address); 
// Output: true (Recursively mapped to the Address class)

API Reference

BaseModel

The core class your models must extend.

  • assign(data: Partial<this>): this - Parses the incoming object, applying validation, casting, and decorator logic based on the class definition. Returns the mutated class instance for chaining.
  • commit(): void - Snapshots the current instance state implicitly natively creating a baseline to revert back to safely. Useful for capturing exactly what a fresh API GET resolves as or solidifying the state explicitly following a database POST.
  • reset(): void - Drops all current patch modifications natively running through .assign() forcefully rolling the data state natively backward safely to the last explicitly commit()ted snapshot!

Decorators

  • @Cast(type: 'string' | 'number' | 'boolean') - Forces the incoming value into the specified primitive type.
  • @CastDate() - Instantiates a native Date object from numeric timestamps or valid ISO 8601 strings.
  • @CastObject(() => ClassName) - Maps an incoming object to a specific solid-class-js model instance.
  • @CastArray(() => ClassName) - Maps an incoming array of objects to an array of specific solid-class-js model instances.
  • @Enrich(callback) - Computes a property's value dynamically based on the raw incoming data.
  • @MapFrom(alias: string) - Ingests a missing property securely from an alternative API layout sequence (e.g. grabbing first_name to map onto firstName).
  • @Exclude(...contexts: string[]) - Hides a specific parameter universally () or explicitly from a strictly contextual evaluation sequence ('POST', 'PUT') during serialization hooks.

Validation Decorators

Use these to enforce strict value conditions on defined properties. If any conditions are not met during assign(), a structured ValidationErrorsList exception is thrown containing an .errors array with every failed ValidationError.

  • @Default(value: any) - Assigns a fallback value before validation executing if the JSON payload is missing the property.
  • @IsRequired() - Throws if the property is missing from the API payload (even after Defaults evaluate).
  • @MinLength(length: number) - Enforces an array or string payload contains at least length items/characters.
  • @MaxLength(length: number) - Enforces an array or string payload contains a maximum of length items/characters.
  • @Min(value: number) - Enforces a primitive number is no less than value.
  • @Max(value: number) - Enforces a primitive number is no greater than value.
  • @Matches(pattern: RegExp) - Tests a parsed string against a regular expression.
  • @IsEmail() - A strict check assuring the string satisfies a standard format for an Email Address.
  • @IsUrl() - A strict check assuring the string resolves securely into a native URL instance.
  • @CustomValidator((value, instance) => boolean | string) - Escapes structural checking completely, passing the property value and parent model instance to evaluate explicitly scoped generic business rules.

.toJSON(context?: string)

By default, standard stringification securely calls .toJSON() across objects recursively. You may extract custom .toJSON('POST') payloads that securely iterate properties conditionally ignoring specific targets marked via explicitly identical context-mapped @Exclude() targets.

Testing

To run the test suite, ensure you have installed the dev dependencies and run:

npm run test

License

MIT

Publish

npm publish --access public