New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

tyforge

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tyforge

Type-safe schema validation, Result pattern, and DDD building blocks for TypeScript

latest
Source
npmnpm
Version
0.3.0
Version published
Weekly downloads
5
400%
Maintainers
1
Weekly downloads
 
Created
Source

TyForge

Português

npm version license TypeScript Node.js

Type-safe schema validation, Result pattern and DDD building blocks for TypeScript.

Zero boilerplate — install, import, use. Every validation, every naming convention, every architectural pattern already exists in TyForge. You write domain logic, not infrastructure.

Why TyForge?

For humans: standardized code, zero debate

TyForge eliminates one of the biggest hidden costs in software teams: deciding how to do things.

Every project that adopts TyForge speaks the same language — same prefixes, same conventions, same validation flow and error handling. A developer familiar with TyForge can open any project based on it and quickly understand the entire structure.

This goes beyond aesthetics. When validation, naming, domain rules, and error handling are already built into the framework, developers stop writing repetitive code and focus exclusively on business logic.

The gain is cumulative:

  • Faster onboarding
  • More objective code reviews
  • Fewer inconsistencies
  • Safer refactoring

Because every project follows the exact same mental model.

For AI: less ambiguity, better results

AI coding assistants work best when the environment is predictable. TyForge provides exactly that: a closed set of patterns, rules, and structures that eliminate ambiguity.

Instead of inferring conventions, the AI follows a system already defined — and validated by the code itself.

In practice, this results in:

  • High first-try accuracy — generated code tends to compile and pass validations without adjustments, thanks to the type system and linter constraints
  • Consistent output — regardless of model or session, the structure generated for Entities, UseCases, and TypeFields follows the same pattern
  • Automatic self-correction — errors are quickly caught by tsc and tyforge-lint, reducing manual iteration
  • Safe composition — AI can build complex models by combining TypeFields, schemas, and domain events without relying on global context

The result: less trial and error, more usable code from the first generation.

TyForge provides the structure. AI provides the speed.

Full-stack: one single source of truth

TyForge runs anywhere TypeScript runs — Node.js, Deno, Bun, Angular, React, Vue, Next.js, React Native, Electron. The same TypeFields that validate input on your API validate forms on your UI.

This means:

  • Validations don't need to be rewritten
  • Formatting doesn't diverge between client and server
  • Business rules aren't scattered

A single schema definition becomes the source of truth for the entire stack.

TyForge centralizes the rules. Both sides just consume.

Installation

npm install tyforge

Quick Start

Schema validation with automatic type inference

import { SchemaBuilder, FString, FEmail, FInt, isSuccess } from "tyforge";
import type { ISchema, InferProps, InferJson } from "tyforge";

const userSchema = {
  name:  { type: FString },
  email: { type: FEmail },
  age:   { type: FInt, required: false },
} satisfies ISchema;

// Types inferred automatically — zero manual annotation
type TUserJson = InferJson<typeof userSchema>;
// => { name: string; email: string; age?: number }

type TUserProps = InferProps<typeof userSchema>;
// => { name: FString; email: FEmail; age?: FInt }

const validator = SchemaBuilder.compile(userSchema);
const result = validator.create({ name: "Maria Silva", email: "maria@navegar.com" });

if (isSuccess(result)) {
  result.value.name.getValue();  // "Maria Silva"
  result.value.email.getValue(); // "maria@navegar.com"
}

Result pattern — functional error handling

import { ok, err, isSuccess, isFailure } from "tyforge";
import type { Result } from "tyforge";

function divide(a: number, b: number): Result<number, Error> {
  if (b === 0) return err(new Error("Division by zero"));
  return ok(a / b);
}

const result = divide(10, 2)
  .map(v => v * 100)           // 500
  .flatMap(v => divide(v, 5))  // 100
  .fold(
    value => `Result: ${value}`,
    error => `Error: ${error.message}`,
  );
// "Result: 100"

TypeFields — validated Value Objects

import { FEmail, FDocumentCpf, FCurrency, FPassword, TypeField } from "tyforge";

// Every TypeField validates on creation
const email = FEmail.createOrThrow("user@company.com");
email.getValue();  // "user@company.com"
email.formatted(); // "user@company.com"

// CPF with mod 11 check digit validation
const cpf = FDocumentCpf.createOrThrow("52998224725");
cpf.formatted(); // "529.982.247-25" (progressive mask)

// Password with complexity rules (uppercase, lowercase, digit, special, 8+ chars)
const pwd = FPassword.createOrThrow("S3cur3!Pass");

// Currency with locale-aware formatting
TypeField.configure({ localeDisplay: "br" });
const price = FCurrency.createOrThrow(1234.50);
price.getValue();       // 123450 (stored as integer cents)
price.toDecimalValue(); // 1234.5
price.formatted();      // "1.234,50" (Brazilian format)

Money arithmetic — zero floating point issues

import { FMoney, FCurrency } from "tyforge";

const a = FCurrency.createOrThrow(0.1);
const b = FCurrency.createOrThrow(0.2);
const sum = a.add(b);
// 0.1 + 0.2 = 0.30 (not 0.30000000000000004)
// Internally: 10 + 20 = 30 cents

const price = FMoney.createOrThrow(1050);  // 1050 cents
price.toDecimal();    // 10.50
price.isPositive();   // true
price.isZero();       // false

const discount = FMoney.createOrThrow(200);
const final = price.subtract(discount); // 850 cents

Domain Models — Entity, Aggregate, Domain Events

import { SchemaBuilder, FId, FString, FEmail, ok, isFailure } from "tyforge";
import { Aggregate, DomainEvent } from "tyforge";
import type { ISchema, InferProps, InferJson } from "tyforge";

const userSchema = {
  id:    { type: FId, required: false },
  name:  { type: FString },
  email: { type: FEmail },
} satisfies ISchema;

type TUserProps = InferProps<typeof userSchema>;
type TUserJson = InferJson<typeof userSchema>;

class EventUserCreated extends DomainEvent<{ userId: string; email: string }> {
  readonly queueName = "user-events";
  static create(userId: string, email: string): EventUserCreated {
    return new EventUserCreated("user.created", { userId, email });
  }
}

class User extends Aggregate<TUserProps, TUserJson> implements TUserProps {
  readonly id: FId | undefined;
  readonly name: FString;
  readonly email: FEmail;

  protected readonly _classInfo = { name: "User", version: "1.0.0", description: "User aggregate" };

  private constructor(props: TUserProps) {
    super();
    this.id = props.id;
    this.name = props.name;
    this.email = props.email;
  }

  static create(data: TUserJson) {
    const validator = SchemaBuilder.compile(userSchema);
    const result = validator.create(data);
    if (isFailure(result)) return result;

    const user = new User(result.value);
    const id = user.id?.getValue() ?? FId.generateId();
    user.addDomainEvent(EventUserCreated.create(id, user.email.getValue()));
    return ok(user);
  }
}

Expose / Redaction — control JSON output

const schema = {
  name:     { type: FString },
  email:    { type: FEmail, expose: "private" },
  password: { type: FPassword, expose: "redacted" },
} satisfies ISchema;

// toJSON() or toJSON(config, "public") — hides private + redacted
// => { name: "Maria" }

// toJSON(config, "private") — shows private, hides redacted
// => { name: "Maria", email: "maria@email.com" }

// toJSON(config, "redacted") — shows everything
// => { name: "Maria", email: "maria@email.com", password: "S3cur3!Pass" }

Locale system — display + region + data, independently configured

import { TypeField, FBankCode, FCurrency, FDocumentCpf } from "tyforge";

// Configure three axes separately: display, region rules, and data formatting
TypeField.configure({ localeDisplay: "br", localeRegion: "br", localeData: "br" });

// localeRegion: "br" → enforces ISPB 8-digit format
FBankCode.createOrThrow("60701190"); // OK (Itau ISPB)

// localeDisplay: "br" → formats with Brazilian separators
FCurrency.createOrThrow(1234.50).formatted(); // "1.234,50"

// localeData: "br" → formatted("data") for API/persistence formatting
FCurrency.createOrThrow(1234.50).formatted("data"); // API-ready format

// Strict types (TLocaleDisplay, TLocaleRegion, TLocaleData) with exhaustive switch:
// adding a new locale causes compile errors wherever handling is missing

Form input normalization

import { FCurrency, FInt } from "tyforge";

// formCreate/formAssign normalize string inputs from HTML forms
FCurrency.formCreate("1234,50");  // "1234,50" → 1234.50 → 123450 cents
FInt.formCreate("42");            // "42" → 42
FInt.formCreate("0x1A");          // rejected (hex not allowed)
FInt.formCreate("1e5");           // rejected (scientific notation not allowed)

Batch validation with parallel workers

import { SchemaBuilder, FString, FEmail, batchCreate } from "tyforge";
import type { ISchema } from "tyforge";

const schema = {
  name:  { type: FString },
  email: { type: FEmail },
} satisfies ISchema;

const items = Array.from({ length: 10000 }, (_, i) => ({
  name: `User ${i}`,
  email: `user${i}@company.com`,
}));

// Sequential
const result = await batchCreate(schema, items);

// Parallel with 4 worker threads
const result = await batchCreate(schema, items, { concurrency: 4 });
// result.successes: validated items
// result.errors: items that failed with index + error detail

Exceptions — RFC 7807 with lazy stack trace

import { ExceptionValidation, ExceptionBusiness, ExceptionNotFound, OHttpStatus } from "tyforge";

const err = ExceptionValidation.create("email", "Invalid email format");
err.status; // 400
err.toJSON();
// {
//   type: "validation",
//   title: "Validation Error",
//   status: 400,
//   detail: "Invalid email format",
//   code: "email"
// }

// Stack trace captured only when accessed (lazy) — zero cost in batch validation

Nested schemas and arrays

const orderSchema = {
  id:      { type: FId },
  address: {
    street: { type: FString },
    city:   { type: FString },
    state:  { type: FStateCode },
  },
  items: [{
    type: {
      productId: { type: FId },
      quantity:  { type: FInt },
      price:    { type: FMoney },
    },
  }],
} satisfies ISchema;

// Deeply nested validation with indexed error paths:
// "items[2].price" → "Value must be an integer (cents)"

Linter — enforces conventions automatically

npx tyforge-lint              # check all .ts files
npx tyforge-lint --staged     # check only staged files
npx tyforge-lint --fix        # auto-fix what's possible
npx tyforge-lint --init       # setup pre-commit hooks (Husky/Lefthook/native)

10 rules: no-any, no-cast, no-non-null, no-ts-ignore, no-export-default, no-to-json-lowercase, no-new-type-field, no-magic-http-status, no-declare, no-satisfies-without-prefix.

Modules

ModuleDescription
Result Patternok(), err(), map, flatMap, fold, match, all, allSettled, toPromise — functional error handling with zero exceptions
Schema BuilderCompiled schema validation with InferProps/InferJson type inference, nested objects, arrays, batchCreate, composeSchema
Type FieldsValidator Value Objects — strings, emails, currency, banking, documents, PIX, security, enums, dates, identifiers
Domain ModelsEntity, ValueObject, Aggregate (with domain events), Dto, DtoReq, DtoRes — full DDD building blocks
ExceptionsRFC 7807 exception types with lazy stack trace and OHttpStatus constants
ApplicationUseCase, IMapper, Saga, DomainEventDispatcher, CQRS interfaces
InfrastructureRepository, RepositoryRead, RepositoryWrite, RepositoryCrud, Paginated, ServiceBase, IUnitOfWork, IOutbox
HTTP ClientServiceHttp abstract base class — secure HTTP client with Result pattern, SSRF/CRLF/path traversal protection, timeout, ExceptionHttp
GraphQL ClientServiceGraphQL abstract base class — secure GraphQL client with Result pattern, introspection blocking, prototype pollution protection, UNAUTHENTICATED detection, ExceptionGraphQL
WebSocket ClientServiceWebSocket abstract base class — WebSocket client with connect/disconnect/send/subscribe, reconnect with jitter and delay cap, DNS rebinding protection, ExceptionWebSocket
ToolsTypeGuard, ToolObjectTransform (flatten/unflatten), ToolCliParser, ToolFileDiscovery, ToolGit, ToolNetworkSecurity
Linternpx tyforge-lint — 10 rules with --init / --fix / --format json for CI
Configtyforge.config.json — global validation levels (full, type, none) and linter settings

Type Fields by Category

CategoryFields
StringsFString, FText, FDescription, FFullName, FBusinessName, FEmail
NumericFInt, FFloat
PaginationFPageNumber, FPageSize, FSortOrder
CurrencyFMoney (integer cents), FCurrency (decimal convenience) — arithmetic, comparisons, fromDecimal()
DatesFDate, FDateISODate, FDateTimeISOZ, FDateTimeISOZMillis, FDateISOCompact, FDateTimeISOCompact, FDateTimeISOFullCompact
IdentifiersFId, FIdReq, FTransactionId, FDeviceId, FCorrelationId, FReconciliationId, FIdempotencyKey, FCertificateThumbprint
DocumentsFDocumentCpf, FDocumentCnpj, FDocumentCpfOrCnpj, FDocumentRg, FDocumentId, FDocumentType, FDocumentStateRegistration, FDocumentMunicipalRegistration
BankingFBankCode, FBankBranch, FBankAccountNumber, FBankNsu, FBankE2eId, FEmvQrCodePayload
PIXFPixKey, FPixKeyType
SecurityFApiKey, FBearer, FPassword, FSignature, FPublicKeyPem, FTotpCode, FTotpSecret, FHashAlgorithm
HTTPFHttpMethod, FHttpFormat, FHttpStatus
GraphQLFGraphQLDocument, FGraphQLOperationName, FFetchPolicy
URLFUrlOrigin, FUrlFull, FUrlPath, FUrlDns, FUrlQuery
EnumsFAppStatus, FBoolInt, FPersonType, FGender, FMaritalStatus, FTransactionStatus, FStateCode
OtherFBoolean, FJson, FTraceId

Subpath Exports

import { ok, err } from "tyforge/result";
import { FString, FEmail } from "tyforge/type-fields";
import { ExceptionValidation } from "tyforge/exceptions";
import { SchemaBuilder } from "tyforge/schema";
import { TypeGuard } from "tyforge/tools";
import { ServiceHttp, ExceptionHttp } from "tyforge/http";
import { ServiceGraphQL, ExceptionGraphQL } from "tyforge/graphql";

Documentation

Full documentation at tyforge.navegarsistemas.com.br.

License

MIT - Navegar Sistemas

Keywords

typescript

FAQs

Package last updated on 27 May 2026

Related posts