Skip to content

Latest commit

Β 

History

550 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

QuickModel Logo

Important

Pre-release / active development

This project is not published to npm yet. The public API and installation process may change before the first stable release.

quickmodel

TypeScript model system with automatic type transformation and SOLID architecture.

License: Custom TypeScript CI codecov npm version Bundle Size Sponsor

πŸ“š Complete Documentation

✨ Key Features

  • πŸ”„ Explicit Type Transformation - Transform 30+ JavaScript/TypeScript types (Date, BigInt, Symbol, RegExp, Set, Map, WeakMap, WeakSet, etc.)
  • 🎯 Simple API - Use @Quick({}) decorator to specify transformations explicitly
  • πŸ’‘ Type-Safe - Full TypeScript support with interface segregation
  • πŸ“¦ Nested Models - Infinite nesting with automatic transformation
  • βœ… Business Validation - @QRule declarative rules + @QGroup group filtering. Works on any class via the quickmodel/forms subpath β€” no QModel required
  • πŸ” Schema Generation - Export your model as JSON Schema, Zod, OpenAPI, Mongoose, TypeScript, GraphQL, or AJV via getSchema()
  • πŸ€– MCP Server - AI assistant integration with 20 public tools, 20 internal tools, and 20 guided prompts (Claude, Copilot, etc.)
  • πŸ—οΈ SOLID Architecture - Clean, maintainable, extensible code
  • 🎭 Built-in Mocking - Testing utilities with @faker-js/faker
  • πŸ§ͺ Well Tested - 3300+ tests covering all features
  • 🏷️ TC39 Decorator Support - Works with both legacy (experimentalDecorators: true) and TC39 standard decorators (TypeScript 5+ default mode)

Development status

QuickModel is currently in pre-release development and is not available on npm yet.

Run locally

git clone https://github.com/CartagoGit/quickmodel.git
cd quickmodel
bun install
bun test

## πŸ“¦ Installation

```bash
npm install quickmodel
# or: yarn add / pnpm add / bun add

πŸš€ Quick Start

Basic Usage Pattern

QuickModel transforms JSON data into TypeScript runtime types. All special types must be explicitly declared - no automatic detection.

1️⃣ Simplest Case - Primitives only (no transformations)

import { QModel } from 'quickmodel';

interface IUser {
	id: number;
	name: string;
}

class User extends QModel<IUser> {
	declare id: number;
	declare name: string;
}

const user = new User({ id: 1, name: 'John' });

2️⃣ With @Quick() - Auto-apply QType to all properties

import { QModel, Quick } from 'quickmodel';

interface IUser {
	id: number;
	name: string;
}

@Quick() // Automatically decorates all properties
class User extends QModel<IUser> {
	declare id: number;
	declare name: string;
}

3️⃣ With Type Transformations - Explicit mapping required

import { QModel, Quick, IQImplements } from 'quickmodel';

// Backend interface (JSON-compatible types)
interface IUser {
	id: number;
	createdAt: string; // ISO date string from backend
	balance: string; // BigInt as string from backend
	tags: string[]; // Array from backend
	metadata: [string, any][]; // Map as array from backend
}

// Specify transformations explicitly
// ⚠️ IMPORTANT: Use [Type] syntax for arrays: [Date], [BigInt], etc.
@Quick({
	createdAt: Date, // Single Date (not array)
	balance: BigInt, // Single BigInt (not array)
	tags: Set, // Single Set (receives array of strings)
	metadata: Map, // Single Map (receives array of tuples)
})
class User extends QModel<IUser> {
	declare id: number; // No transformation needed
	declare createdAt: Date; // Explicitly mapped
	declare balance: bigint; // Explicitly mapped
	declare tags: Set<string>; // Explicitly mapped
	declare metadata: Map<string, any>; // Explicitly mapped
}

// Use with JSON data
const user = new User({
	id: 1,
	createdAt: '2026-01-08T10:00:00.000Z',
	balance: '999999999999999',
	tags: ['typescript', 'node'],
	metadata: [
		['key1', 'value1'],
		['key2', 'value2'],
	],
});

// Access transformed types
console.log(user.createdAt); // Date object
console.log(user.balance); // bigint: 999999999999999n
console.log(user.tags); // Set<string>
console.log(user.metadata); // Map<string, any>

4️⃣ Type-Safe with IQImplements (Recommended)

Although optional, using IQImplements is highly recommended to ensure your class definitions match your data contracts and transformations, preventing silent type errors.

import { QModel, Quick, IQImplements } from 'quickmodel';

// Backend interface (JSON types)
interface IUser {
	id: number;
	createdAt: string;
	balance: string;
	tags: string[];
	metadata: [string, any][];
}

// Transformation interface (runtime types)
interface IUserTransform {
	createdAt: Date;
	balance: bigint;
	tags: Set<string>;
	metadata: Map<string, any>;
}

@Quick({
	createdAt: Date,
	balance: BigInt,
	tags: Set,
	metadata: Map,
})
class User
	extends QModel<IUser>
	implements IQImplements<IUser, IUserTransform>
{
	declare id: number;
	declare createdAt: Date; // TypeScript enforces this matches IUserTransform
	declare balance: bigint; // TypeScript enforces this matches IUserTransform
	declare tags: Set<string>; // TypeScript enforces this matches IUserTransform
	declare metadata: Map<string, any>; // TypeScript enforces this matches IUserTransform
}

5️⃣ Use create() for Type-Safety

The static create() method provides a convenient factory for your models.

Option A: Explicit declare (RECOMMENDED)

For automatic type inference of transformed properties, use declare keywords in your class. This is the standard, most robust way and works with both new User() and User.create().

import { QModel, Quick } from 'quickmodel';

interface IUser {
	id: number;
	createdAt: string; // Backend: ISO string
}

@Quick({ createdAt: Date })
class User extends QModel<IUser> {
	declare id: number;
	declare createdAt: Date; // ← Explicit runtime type (REQUIRED for inference)
}

// Automatic type inference works perfectly
const user = User.create({ id: 1, createdAt: '2026-01-01' });

user.createdAt; // βœ… Date

Option B: Using IQTransform (Alternative)

If you prefer NOT to use declare properties (e.g. to keep classes smaller), you can use the IQTransform helper to manually specify the transformed type in the create() call.

import { QModel, Quick, IQTransform } from 'quickmodel';

interface IUser {
	id: number;
	createdAt: string;
}

// 1. Define your runtime transformations
type UserTransforms = { createdAt: Date };

@Quick({ createdAt: Date })
class User extends QModel<IUser> {
	// No declare needed
}

// 2. Pass transformation type to create()
const user = User.create<IQTransform<IUser, UserTransforms>>({
	id: 1,
	createdAt: '2026-01-08',
});

user.createdAt; // βœ… Date (inferred via IQTransform)

user.email // βœ… TypeScript: string user.createdAt // βœ… TypeScript: Date (transformed)


**When to use `create()`:**
- βœ… You want concise code (no property declarations)
- βœ… Your interface already defines all types
- βœ… You prefer DRY (Don't Repeat Yourself)

**When to use `declare`:**
- βœ… You prefer explicit property declarations
- βœ… You want standard constructor usage (`new`)
- βœ… You need property visibility in IDE

πŸ’– Support the Project

If QuickModel saves you time or adds value to your work, consider buying me a coffee! Every contribution helps keep the project maintained and growing.

Donate via PayPal

πŸ“– Core Concepts

Explicit Type Mapping

QuickModel does NOT auto-detect types from data. All special types must be explicitly declared:

// ❌ WRONG - Date won't be transformed automatically
@Quick()
class User extends QModel<IUser> {
	declare createdAt: Date; // Will stay as string!
}

// βœ… CORRECT - Explicit mapping required
@Quick({ createdAt: Date })
class User extends QModel<IUser> {
	declare createdAt: Date; // Will transform string β†’ Date
}

Two-Interface Pattern

QuickModel uses interface segregation (SOLID principle):

  • IUser - Serialization format (JSON-compatible): string, number, boolean, arrays
  • IUserTransform - Runtime types: Date, bigint, RegExp, Set, Map

This allows type-safe serialization while maintaining clean runtime code.

Supported Transformations

Primitives:

  • BigInt - Large integers (from string)
  • Date - Dates and timestamps (from ISO string)
  • RegExp - Regular expressions (from string/object)
  • Symbol - Symbols (using Symbol.for)
  • Error - Error objects

Collections:

  • Set<T> - Unique values (from array)
  • Map<K, V> - Key-value pairs (from array of tuples)
  • Array<T> - Arrays with nested transformations
  • WeakMap<object, V> - Runtime-only cache, not serialized (GC-friendly)
  • WeakSet<object> - Runtime-only object set, not serialized (GC-friendly)

Binary:

  • ArrayBuffer, TypedArrays (Int8Array, etc.), DataView

Web APIs:

  • URL, URLSearchParams

Array Syntax (IMPORTANT)

Always use explicit array syntax [Type] for arrays:

// βœ… CORRECT - Explicit array syntax
@Quick({
  dates: [Date],        // Date[] - array of dates
  tags: [Set],          // Set[] - array of sets
  posts: [Post],        // Post[] - array of models
  matrix: [[Date]]      // Date[][] - 2D array of dates
})
class Data extends QModel<IData> {
  declare dates: Date[];
  declare tags: Set<string>[];
  declare posts: Post[];
  declare matrix: Date[][];
}

// ❌ WRONG - Ambiguous without brackets
@Quick({
  dates: Date,    // This means single Date, not Date[]
  tags: Set,      // This means single Set, not Set[]
  posts: Post     // This means single Post, not Post[]
})

Why? Clear distinction between:

  • tags: Set β†’ Single Set receiving ['a', 'b', 'c']
  • tags: [Set] β†’ Array of Sets receiving [['a', 'b'], ['c', 'd']]
  • metadata: Map β†’ Single Map receiving [['k1', 'v1'], ['k2', 'v2']]
  • metadata: [Map] β†’ Array of Maps receiving [[['k1', 'v1']], [['k2', 'v2']]]

Multi-Dimensional Arrays

Nesting depth is explicit:

@Quick({
  posts: [Post],      // Post[] - 1D array
  matrix: [[Post]],   // Post[][] - 2D array
  cube: [[[Post]]]    // Post[][][] - 3D array
})

Property Declaration

All three TypeScript property declaration styles work identically with @Quick:

// βœ… Style 1: declare (cleaner, no runtime code)
@Quick({ createdAt: Date, dates: [Date] })
class User extends QModel<IUser> {
	declare id: number;
	declare createdAt: Date;
	declare dates: Date[];
}

// βœ… Style 2: Definite assignment (!)
@Quick({ createdAt: Date, dates: [Date] })
class User extends QModel<IUser> {
	id!: number;
	createdAt!: Date;
	dates!: Date[];
}

// βœ… Style 3: Optional (?)
@Quick({ createdAt: Date, dates: [Date] })
class User extends QModel<IUser> {
	id?: number;
	createdAt?: Date;
	dates?: Date[];
}

All three styles produce identical behavior - choose based on your preference or team conventions.

TC39 mode note: When using @QType as a field decorator in TC39 mode (experimentalDecorators absent), decorated fields require ! instead of declare. Fields decorated only via the @Quick class decorator work with all three styles in both modes. See TC39 decorator support below.

Collections Example

interface IPost {
	tags: string[]; // Array β†’ Set (single Set)
	categories: string[][]; // Array β†’ Set[] (array of Sets)
	metadata: [string, any][]; // Tuples β†’ Map (single Map)
}

interface IPostTransform {
	tags: Set<string>;
	categories: Set<string>[];
	metadata: Map<string, any>;
}

// ⚠️ Note the [Set] syntax for arrays of Sets
@Quick({
	tags: Set, // Single Set
	categories: [Set], // Array of Sets - explicit syntax!
	metadata: Map, // Single Map
})
class Post
	extends QModel<IPost>
	implements IQImplements<IPost, IPostTransform>
{
	declare id: string;
	declare tags: Set<string>; // Single Set
	declare categories: Set<string>[]; // Array of Sets
	declare metadata: Map<string, any>; // Single Map
}

const post = new Post({
	id: '1',
	tags: ['typescript', 'node'], // Single Set from array
	categories: [['js', 'ts'], ['node']], // Array of Sets
	metadata: [['key', 'value']], // Single Map from tuples
});

// Access transformed types
console.log(post.tags); // Set { 'typescript', 'node' }
console.log(post.categories[0]); // Set { 'js', 'ts' }
console.log(post.metadata); // Map { 'key' => 'value' }

Nested Models

@Quick({ birthDate: Date })
class Profile extends QModel<IProfile> {
	declare birthDate: Date;
	declare address: Address;
}

@Quick({ profile: Profile })
class User extends QModel<IUser> {
	declare id: string;
	declare profile: Profile;
}

const user = new User({
	id: '1',
	profile: {
		birthDate: '1990-01-01',
		address: { city: 'NYC' },
	},
});

WeakMap & WeakSet (Runtime-only)

Use WeakMap and WeakSet for runtime-only data that should not be serialized (garbage-collection-friendly caches, event listener sets, etc.).

interface ISession {
	id: string;
}

@Quick(
	{ cache: WeakMap, listeners: WeakSet },
	{ excludeFields: ['cache', 'listeners'] } // never appear in toJSON()
)
class Session extends QModel<ISession> {
	declare id: string;
	declare cache: WeakMap<object, any>; // Auto GC when keys die
	declare listeners: WeakSet<object>; // Auto GC when objects die
}

const session = new Session({ id: 'abc', cache: [], listeners: [] } as any);

console.log(session.cache); // WeakMap {} β€” available on instance
console.log(JSON.stringify(session)); // { "id": "abc" } β€” WeakMap/WeakSet excluded

⚠️ WeakMap and WeakSet are never serialized to JSON. Use Map/Set if you need persistence.

excludeFields β€” Permanent Field Exclusion

Use excludeFields in @Quick() options to permanently exclude fields from all serialization output. Unlike omit (which is per-call), excludeFields is declared once and always applied.

@Quick({}, { excludeFields: ['password', '_checksum'] })
class User extends QModel<IUser> {
	declare id: number;
	declare name: string;
	declare password: string; // always excluded from toJSON() / serialize()
	declare _checksum: string; // always excluded
}

const user = new User({
	id: 1,
	name: 'Alice',
	password: 'secret',
	_checksum: 'abc',
});

user.password; // βœ… 'secret'  β€” available on instance
JSON.stringify(user); // βœ… { "id": 1, "name": "Alice" } β€” no password/checksum
user.serialize(undefined, { omit: ['name'] }); // also applies omit at runtime
Option Scope Declaration
excludeFields Always excluded (per-model decorator) @Quick({}, { excludeFields: [...] })
omit Excluded per-call model.serialize(undefined, { omit: [...] })
pick Keep only these per-call model.serialize(undefined, { pick: [...] })

Dot Notation for Nested Properties

QuickModel supports dot notation to specify transformations for nested properties without decorating the nested class:

// Option 1: Decorate nested class (recommended for reusable models)
@Quick({ price: BigInt, createdAt: Date })
class Product extends QModel<IProduct> {
	price!: bigint;
	createdAt!: Date;
}

@Quick({ product: Product })
class CartItem extends QModel<ICartItem> {
	product!: Product; // Product already decorated
}

// Option 2: Use dot notation (useful for third-party classes or context-specific transforms)
@Quick({
	product: Product,
	'product.price': BigInt, // ← Dot notation
	'product.createdAt': Date, // ← Dot notation
})
class CartItem extends QModel<ICartItem> {
	product!: Product; // All transformations in one place
}

πŸ“– Complete Dot Notation Guide - Learn when and how to use nested transformations

πŸ›‘οΈ Robustness & Security

QuickModel includes built-in protections for robust serialization:

  • Circular Reference Protection: toJSON() calls safely handle circular references in Objects, Arrays, Maps, and Sets by returning a { __circular: true } marker instead of crashing.
  • Deep Serialization: Collections like Map and Set are IQSerialized recursively, ensuring that nested complex types (like BigInt or Date) are properly converted to their JSON-compatible formats.
  • Internal Property Protection: Properties starting with __ are automatically excluded from serialization to prevent leaking internal state.
  • Injection Protection: Automatic validation for URLs (blocks javascript:) and limits on RegExp length.

⚠️ Security Notice: QuickModel strips unknown properties by default (unknownPropertyPolicy: 'strip'). For strictest validation on public APIs, use error policy: @Quick({}, { unknownPropertyPolicy: 'error' }). See SECURITY.md for full security guidelines and best practices.

βœ… Validation

QuickModel has two independent validation layers:

1. Transformer integrity β€” checkIntegrity() / isValid()

Checks that each property value conforms to its declared transformer type (no type mismatches, no DoS limits exceeded).

@Quick({
	birthDate: Date,
	tags: [Set], // Array of Sets
})
class User extends QModel<IUser> {
	declare birthDate: Date;
	declare tags: Set<string>[];
}

const invalidUser = new User({
	birthDate: 'invalid-date',
	tags: 'not-an-array',
});

const errors = invalidUser.checkIntegrity();
// [
//   { isValid: false, error: "User.birthDate: Invalid Date string: invalid-date" },
//   { isValid: false, error: "User.tags: Expected array for Set[], got string" }
// ]

2. Business rules β€” @QRule + checkRules()

Declarative per-field rules for your own business logic. Works on any class β€” no need to extend QModel.

import { QRule, QGroup } from 'quickmodel';
import { qGroups, qCheckRules, qCheckRulesByGroup } from 'quickmodel/forms';

const Groups = qGroups('identity', 'security');

class SignupForm {
	@QRule((val: string) => val.length >= 2, 'Name too short')
	@QGroup(Groups.identity)
	name = '';

	@QRule((val: string) => /^[^@]+@[^@]+\.[^@]+$/.test(val), 'Invalid email')
	@QGroup(Groups.identity)
	email = '';

	@QRule((val: string) => val.length >= 8, 'Password too short')
	@QRule((val: string) => /[A-Z]/.test(val), 'Must contain uppercase')
	@QGroup(Groups.security)
	password = '';
}

const form = new SignupForm();
form.name = 'A';
form.email = 'alice@example.com';
form.password = 'weak';

// All rules:
const result = qCheckRules(form);
// { valid: false, errors: [{ field: 'name', message: 'Name too short', value: 'A' }, ...] }

// Only a specific group (e.g. step-by-step form):
const identityResult = qCheckRules(form, { group: Groups.identity });
// { valid: false, errors: [{ field: 'name', ... }] }

// All groups as a map β€” one entry per @QGroup:
const byGroup = qCheckRulesByGroup(form);
// { identity: { valid: false, errors: [...] }, security: { valid: false, errors: [...] } }

Async rules (e.g. DB uniqueness checks), timeout per predicate, and serial/parallel execution modes are supported via qCheckRulesAsync.

πŸ“– Form Validation guide β€” Full reference for the /forms subpath: qGroups, qCheckRules, qCheckRulesAsync, qCheckRulesByGroup, qCheckRulesByGroupAsync

Combining both layers β€” isValid() / validationReport()

When using QModel subclasses, isValid() and validationReport() combine both checks in a single call:

const user = new User({ name: 'Alice', age: -1, email: 'alice@example.com' });

if (!user.isValid()) {
	const report = user.validationReport();
	report.integrity; // transformer-level failures
	report.rules.errors; // @QRule business failures
}

πŸ” Schema Generation

QuickModel can export your model's structure as different schema formats for documentation, validation, and interoperability. Available via the static getSchema() method or the instance method:

@Quick({ createdAt: Date, tags: Set })
class User extends QModel<IUser> {
	declare id: number;
	declare name: string;
	declare createdAt: Date;
	declare tags: Set<string>;
}

// Static: generate schema from class definition
const jsonSchema = User.getSchema('json'); // JSON Schema Draft-07
const openapiComp = User.getSchema('openapi'); // OpenAPI 3.0 component
const zodSchema = User.getSchema('zod'); // Zod validator string
const mongoSchema = User.getSchema('mongo'); // Mongoose SchemaTypes
const tsInterface = User.getSchema('typescript'); // TypeScript interface
const graphqlType = User.getSchema('graphql'); // GraphQL SDL type
const ajvSchema = User.getSchema('ajv'); // AJV validator schema

// Instance: same output, works on a live model
const user = new User({
	id: 1,
	name: 'Alice',
	createdAt: '2025-01-01',
	tags: ['ts'],
});
const schema = user.getSchema('json');

Supported formats:

Format Description
'json' JSON Schema Draft-07
'openapi' OpenAPI 3.0 schema component
'zod' Zod validation schema string
'mongo' Mongoose / MongoDB SchemaTypes
'typescript' TypeScript interface string
'graphql' GraphQL SDL type definition
'ajv' AJV-compatible validator schema

🎭 Testing with Mocks

// Generate mock with defaults
const mockUser = User.mock();

// Override specific fields
const customUser = User.mock({
	name: 'Custom Name',
});

// Generate array of mocks
const users = User.mock(5);

Powered by @faker-js/faker.

πŸ€– MCP Server Integration

QuickModel ships a built-in Model Context Protocol (MCP) server that gives AI assistants (Claude, GitHub Copilot, etc.) direct access to QuickModel capabilities.

Start the MCP server

bun run mcp
# or: npx quickmodel mcp

Configure in Claude Desktop (~/.config/claude/claude_desktop_config.json)

{
	"mcpServers": {
		"quickmodel": {
			"command": "npx",
			"args": ["-y", "quickmodel", "mcp"]
		}
	}
}

Public tools (20)

Tool Description
create_model Generate TypeScript QModel class from properties
validate_usage Validate a snippet: detects @Quick, @QRule, @QField, @QAlias, @QGroup, @QComputed; returns detectedDecorators[] and warns on @QField without @QRule
list_transformers List all available type transformers
list_validators List all built-in validator decorators with usage signatures and descriptions
generate_mock Generate mock data for a model
inspect_model Inspect a model's structure, transformers, and detected QuickModel decorators (decorators[])
search_docs Search the QuickModel documentation
interface_to_model Convert a TypeScript interface to a QModel class
export_json_schema Export a model as JSON Schema
explain_error Explain a validation error in plain language
simulate_transformation Simulate a type transformation on sample data
json_to_model Generate a QModel class from a JSON object
simulate_validation Simulate @QRule-style predicate validation on a data object; returns { valid, errors[], evaluated }
get_model_schema Generate a model schema in any of the 7 formats (json, openapi, zod, mongo, typescript, graphql, ajv) using the real QModel.getSchema() API
get_form_schema Extract form schema from @QField / @QGroup decorators using the real QModel.getFormSchema() / getFormSchemaGrouped() API
check_integrity Run transformer-level integrity checks (invalid Date, BigInt range, RegExp) using instance.checkIntegrity(); returns { valid, errors[], evaluated, summary }
simulate_rules Run business-logic rules via the real instance.checkRules() API; predicates have access to value and data; returns { valid, errors[], evaluated }
simulate_async_rules Run async business-logic rules via instance.checkRulesAsync(); supports timeoutMs, timeoutMessage, mode (parallel/serial); returns { valid, errors[], evaluated }
roundtrip Verify that serialize() β†’ re-create β†’ serialize() is lossless; returns { lossless, serialized, roundtrip_serialized, diff, summary }
diff_models Compare two QModel class definitions (as source strings) and report added/removed fields, changed transformers, and decorator changes; pure static analysis

AI-guided prompts / skills (20)

Skill Description
quickmodel_from_typescript Generate a QModel from a TypeScript interface (step-by-step)
quickmodel_debug Diagnose and fix a QuickModel issue
quickmodel_generate_test_data Create test data strategies for a model
quickmodel_inspect_and_schema Inspect a model and export its schema in all formats
quickmodel_form_validation Guided workflow to add @QField, @QRule and @QGroup to a model
quickmodel_full_pipeline Walk the complete pipeline: create() β†’ checkIntegrity() β†’ checkRules() β†’ serialize()
quickmodel_mixin Extend a base class (TypeORM entity, NestJS DTO) with QModel via QModel.extends(BaseClass)
quickmodel_alias_computed Explain and apply @QAlias (field name remapping) and @QComputed (getter in serialize output)
quickmodel_migration Migrate legacy TypeScript classes to idiomatic QuickModel patterns
quickmodel_async_rules ⚠️ Async-only: guide checkRulesAsync() with timeoutMs, parallel/serial mode, NestJS context
quickmodel_add_qgroup Add @QGroup field grouping to a model and use checkGroups() for group-level validation
quickmodel_security_review Security audit: mass assignment, DoS limits, prototype pollution, ReDoS via check_security
quickmodel_transformer_guide Choose the right transformer for a TypeScript type and validate it with simulate_transformation
quickmodel_form_data fromFormData() / toFormData() / streaming (toReadableStream, fromStream, pipeStream)
quickmodel_implement_feature Full TDD cycle: write test β†’ implement β†’ lint_check gate β†’ typecheck gate β†’ done
quickmodel_fix_lint Step-by-step ESLint fix with lint_check + pre_commit_check gates; use after any hook failure
quickmodel_fix_typecheck Step-by-step TS type fix with typecheck + pre_commit_check gates; use after typecheck fails
quickmodel_refactor Safe refactor cycle: green baseline β†’ apply β†’ run_tests + lint_check + typecheck gates
quickmodel_apply_solid Guided SOLID review: analyse each principle, propose targeted refactors, gated by all checks
quickmodel_sync_project Sync all project layers: project_status health snapshot β†’ fix failures β†’ regenerate docs

πŸ“š MCP Documentation β€” Full tool reference and AI integration guide

πŸ—οΈ Architecture (SOLID)

  • Single Responsibility: Each transformer handles one type
  • Open/Closed: Extensible via transformer registry
  • Liskov Substitution: Models work like TypeScript classes
  • Interface Segregation: Separate serialization/runtime interfaces
  • Dependency Inversion: Depends on abstractions

πŸ“š Documentation

🀝 Contributing

Contributions welcome! See development guide.

πŸ‘€ Author

Mario Cabrero Volarich

πŸ“ License

QuickModel Custom License Β© 2026 Cartago β€” free to use, not to sell or fork without permission. See LICENSE for full terms.

About

TypeScript model serialization and deserialization library built around SOLID principles.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages