Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 55 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,62 @@
# Meet Jane

> Less boilerplate. More flow.
> **Less boilerplate**. **More flow**.

Zero‑side‑effect normalization and validation helpers for JavaScript.
Zero‑side‑effect normalization, validation, and safe parsing for JavaScript and TypeScript.

Jane is a small, clarity‑first helper library for **normalizing**, **validating**, and **safely parsing** unknown input in JavaScript and TypeScript.

It’s built for developers who want predictable behavior, composable pipelines, and zero surprises — without schema systems, decorators, or framework lock‑in.
Jane is a clarity‑first helper library for turning unknown input into predictable, typed values — without schema systems, decorators, or framework lock‑in. It gives you the small, explicit building blocks you wish the language shipped with.

Jane is intentionally small. Intentionally explicit. Intentionally boring in all the right ways.

---

## Why Jane?

Most validation libraries try to be everything: schema builders, type generators, transformers, parsers, refiners, and runtime type systems.
Most validation libraries try to do everything: schemas, inference, coercion, transformations, refinements, and runtime type systems.

Jane takes the opposite approach.

Jane is:

- ✅ **Pure**: No side effects, no hidden mutations.
- ✅ **Deterministic**: Same input, same output, every time.
- ✅ **Composable**: Build pipelines with `pipe()`.
- ✅ **Zero‑dependency**: No runtime weight.
- ✅ **Framework‑agnostic**: Works in Node, serverless, workers, Express, Fastify, Bun, Deno.
- ✅ **Focused**: Normalization → validation → result.
- **Pure**: No side effects, no hidden mutations, no surprises.
- **Deterministic**: Same input, same output, every time.
- **Composable**: Build safe pipelines with `pipe()`, `compose()`, and `tap()`.
- **Zero‑dependency**: No runtime weight, no bloat.
- **Framework‑agnostic**: Works anywhere: Node, serverless, workers, Express, Fastify, Bun, Deno.
- **TypeScript‑aligned**: Every helper narrows types cleanly and predictably.
- **Focused**: Normalize → validate → parse → result. Nothing more. Nothing hidden.

If you want a dependable “standard library for runtime safety,” Jane is your girl.

## What makes Jane different?

Jane isn’t a schema engine. It isn’t a DSL. It isn’t magic.

Jane gives you:

If you want a dependable “standard library” for data sanity, Jane is your girl.
- **Primitives, not frameworks**: Small, explicit helpers you can compose however you want.
- **Zero coercion**: If you pass `"123"` to a number validator, you get a failure — not a silent conversion.
- **Safe parsing**: Every parser returns a structured result. Nothing throws.
- **A complete lattice of runtime checks**: Type guards → validators → normalizers → parsers → functional helpers.
- **Perfect for TypeScript**: Jane’s helpers narrow types exactly the way TS expects. No inference tricks. No decorators. No metadata.
- **Predictable control flow**: Every operation returns a `ValidationResult<T>`.

---
You always know what you’re getting.

## Who is Jane for?

Jane is designed for developers who:

- Prefer **explicit, predictable behavior** over magic.
- Want **pure functions** instead of schema DSLs.
- Need **safe parsing** for config, requests, queries, and internal boundaries.
- Value **clarity and maintainability** in long‑lived codebases.
- Dislike validators that throw.
- Want **small, composable building blocks** instead of monolithic schemas.
- Prefer explicit, predictable behavior over clever abstractions.
- Want pure functions instead of schema builders.
- Need safe parsing for config, requests, environment variables, and API boundaries.
- Value clarity and maintainability in long‑lived codebases.
- Dislike validators that throw or coerce.
- Want small, composable building blocks instead of monolithic schemas.

If you’ve ever written your own tiny normalizers and validators because existing libraries felt too heavy — Jane was built for you.

---

## Installation

```bash
```ts
npm install @clementine-solutions/jane
```

Expand All @@ -63,7 +71,11 @@ import {
validateEnum,
} from "@clementine-solutions/jane";

const port = pipe(process.env.PORT, normalizeInteger, (value) => validateInteger(value, "PORT"));
const port = pipe(
process.env.PORT,
normalizeInteger,
(value) => validateInteger(value, "PORT"),
);

const logLevel = pipe(
process.env.LOG_LEVEL,
Expand All @@ -74,9 +86,9 @@ const logLevel = pipe(

Jane encourages a simple, predictable flow:

- Normalize unknown input
- Validate the normalized value
- Return a Result — never throw
- Normalize unknown input.
- Validate the normalized value.
- Return a `Result<T>` — never throw.

## Result and error shapes

Expand All @@ -85,13 +97,17 @@ Jane never throws.
Every validator returns a discriminated union:

```ts
type SafeResult<T> = { ok: true; value: T } | { ok: false; error: string };
type SafeResult<T> =
| { ok: true; value: T }
| { ok: false; error: string };
```

Validators that operate on names fields return:
Validators that operate on named fields return:

```ts
type ValidationResult<T> = { ok: true; value: T } | { ok: false; field: string; message: string };
type ValidationResult<T> =
| { ok: true; value: T }
| { ok: false; field: string; message: string };
```

These shapes are intentionally minimal:
Expand All @@ -113,14 +129,14 @@ const validated = {

Every field becomes a `Result<T>`.

No exceptions. No coercion surprises. No hidden behavior.
- No exceptions.
- No coercion surprises.
- No hidden behavior.

## Documentation

Documentation is available at:

- [Project overview](./index.md)
- [Reference](./reference/overview.md)
- Project overview
- Reference

```bash
npm run format
Expand All @@ -129,9 +145,9 @@ npm run lint
npm run typecheck
```

## License
### License

Jane is licensed under the Apache License, Version 2.0.
Apache License, Version 2.0

<http://www.apache.org/licenses/LICENSE-2.0>

Expand Down
148 changes: 106 additions & 42 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,88 +1,152 @@
# Meet Jane

**Less boilerplate. More workflow.**
> **Less boilerplate. More workflow.**

>Zero‑side‑effect helpers for predictable data sanity.
Zero‑side‑effect normalization, validation, and safe parsing for JavaScript and TypeScript.

---

Jane is a small, clarity‑first helper library for *normalizing*, *validating*, and *safely parsing* unknown input in JavaScript and TypeScript.

It’s built for developers who want predictable behavior, composable pipelines, and zero surprises — without schema systems, decorators, or framework lock‑in.

- Jane is not a schema builder.
- Jane is not a type generator.
- Jane is not a runtime type system.
Jane is a clarity‑first helper library for turning unknown input into predictable, typed values — without schema systems, decorators, or framework lock‑in. It gives you the small, explicit building blocks you wish the language shipped with.

Jane is intentionally small. Intentionally explicit. Intentionally boring in all the right ways.

---

## Why Jane?

Most validation libraries try to be everything: schema builders, type generators, transformers, parsers, refiners, and runtime type systems.
Most validation libraries try to do everything: schemas, inference, coercion, transformations, refinements, and runtime type systems.

Jane takes the opposite approach.

Jane is:

- **Pure**: No side effects, no hidden mutations.
- **Pure**: No side effects, no hidden mutations, no surprises.
- **Deterministic**: Same input, same output, every time.
- **Composable**: Build pipelines with `pipe()`.
- **Zero‑dependency**: No runtime weight.
- **Framework‑agnostic**: Works in Node, serverless, workers, Express, Fastify, Bun, Deno.
- **Focused**: Normalization → validation → result.
- **Composable**: Build safe pipelines with `pipe()`, `compose()`, and `tap()`.
- **Zero‑dependency**: No runtime weight, no bloat.
- **Framework‑agnostic**: Works anywhere: Node, serverless, workers, Express, Fastify, Bun, Deno.
- **TypeScript‑aligned**: Every helper narrows types cleanly and predictably.
- **Focused**: Normalize → validate → parse → result. Nothing more. Nothing hidden.

If you want a dependable "standard library" for data sanity, Jane is your girl.
If you want a dependable standard library for runtime safety,” Jane is your girl.

---
## What makes Jane different?

Jane isn’t a schema engine. It isn’t a DSL. It isn’t magic.

Jane gives you:

- **Primitives, not frameworks**: Small, explicit helpers you can compose however you want.
- **Zero coercion**: If you pass `"123"` to a number validator, you get a failure — not a silent conversion.
- **Safe parsing**: Every parser returns a structured result. Nothing throws.
- **A complete lattice of runtime checks**: Type guards → validators → normalizers → parsers → functional helpers.
- **Perfect for TypeScript**: Jane’s helpers narrow types exactly the way TS expects. No inference tricks. No decorators. No metadata.
- **Predictable control flow**: Every operation returns a `ValidationResult<T>`.

You always know what you’re getting.

## Who is Jane for?

Jane is designed for developers who:

- Prefer *explicit, predictable behavior* over magic.
- Want *pure functions* instead of schema DSLs.
- Need *safe parsing* for config, requests, queries, and internal boundaries.
- Value *clarity and maintainability* in long‑lived codebases.
- Dislike validators that throw.
- Want *small, composable building blocks* instead of monolithic schemas.
- Prefer explicit, predictable behavior over clever abstractions.
- Want pure functions instead of schema builders.
- Need safe parsing for config, requests, environment variables, and API boundaries.
- Value clarity and maintainability in long‑lived codebases.
- Dislike validators that throw or coerce.
- Want small, composable building blocks instead of monolithic schemas.

If you’ve ever written your own tiny normalizers and validators because existing libraries felt too heavy — Jane was built for you.

## A tiny example
## Installation

```ts
npm install @clementine-solutions/jane
```

## Quick start

```ts
import {
normalizeString,
validateNumber,
pipe
} from "@steven-clements/jane";

const parsePort = pipe(
normalizeString,
validateNumber,
pipe,
normalizeInteger,
validateInteger,
normalizeEnum,
validateEnum,
} from "@clementine-solutions/jane";

const port = pipe(
process.env.PORT,
normalizeInteger,
(value) => validateInteger(value, "PORT"),
);

parsePort("3000"); // { ok: true, value: 3000 }
parsePort("abc"); // { ok: false, error: ... }
const logLevel = pipe(
process.env.LOG_LEVEL,
(value) => normalizeEnum(value, ["debug", "info", "warn", "error"]),
(value) => validateEnum(value, ["debug", "info", "warn", "error"], "LOG_LEVEL"),
);
```

Jane stays out of your way. No schemas. No decorators. No magic.
Jane encourages a simple, predictable flow:

## Installation
- Normalize unknown input.
- Validate the normalized value.
- Return a `Result<T>` — never throw.

```bash
npm install @steven-clements/jane
## Result and error shapes

Jane never throws.

Every validator returns a discriminated union:

```ts
type SafeResult<T> =
| { ok: true; value: T }
| { ok: false; error: string };
```

Validators that operate on named fields return:

```ts
type ValidationResult<T> =
| { ok: true; value: T }
| { ok: false; field: string; message: string };
```

These shapes are intentionally minimal:

- Easy to test
- Easy to log
- Easy to compose
- Impossible to misuse

## Example: Validating request input

```ts
const validated = {
name: pipe(body.name, normalizeString, (v) => validateNonEmptyString(v, "name")),
age: pipe(body.age, normalizeInteger, (v) => validateInteger(v, "age")),
newsletter: pipe(body.newsletter, normalizeBoolean),
};
```

Every field becomes a `Result<T>`.

- No exceptions.
- No coercion surprises.
- No hidden behavior.

## Documentation

Explore our comprehensive documentation:

- [Reference](reference/overview.md)
- [Contributing](contributing/overview.md)

```bash
npm run format
npm run test
npm run lint
npm run typecheck
```

## License

Jane is licensed under the Apache License, Version 2.0.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ validateNegativeInteger("5", 'stringVal'); // → { ok: false, field: 'stringVal

## Notes

- Only integer number primitives greater than zero are valid.
- Only integer number primitives less than zero are valid.
- Fractional numbers, zero, positive numbers, strings, `NaN`, `Infinity`, and non-numeric types fail.

Use [normalizeNegativeInteger](../../normalizers/primitives/normalize-negative-integer.md) if input may be a string before validation.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# validateNonEmptyString

Checks whether a value is a **nonempty string**. This helper performs a strict string check using isNonEmptyString and ensures the string has length > 0. Whitespace and zero-width characters count as non-empty.
Validates that a value is a **non-empty string with meaningful content**.

It never throws and never mutates input. Use it when you need a string with meaningful content before running normalization or further validation.
This helper trims leading and trailing whitespace and rejects strings that are empty after trimming. Zero-width characters (`\u200B`) are treated as empty. Non-string values are also rejected.

## Signature

Expand Down Expand Up @@ -53,4 +53,3 @@ validateNonEmptyString(123, "age")
## Notes

- Use [validateNonEmptyString](validate-non-empty-string.md) when a string with meaningful content is required.
- Combine with [normalizeString](../../normalizers/primitives/normalize-string.md) if trimming or other normalization is desired before validation.
Loading