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
1 change: 1 addition & 0 deletions docs/reference/types/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Jane’s utility types enforce non-nullability where possible and focus on clear

These are the essential TypeScript types used to define and communicate predictable data states:

- [JSONValue](./json-value.md): JSONValue is the standard type representing all valid JSON data in Jane.
- [ValidationResult](./validation-result.md): The mandatory return type for all **Validator** functions. It is a discriminated union that enforces a clear success or failure contract.

## When to Refer to Type Definitions
Expand Down
72 changes: 72 additions & 0 deletions docs/reference/types/json-value.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# JSON value

`JSONValue` is the standard type representing all valid JSON data in Jane. It provides a fully typed, recursive definition of JSON-compatible values for strict validation, normalization, and serialization.

Every validator that works with structured JSON, such as [validateJSON](../validators/semantic/validate-json.md), uses `JSONValue` to ensure type safety and predictability.

## Definition

```ts
export type JSONValue =
| null
| boolean
| number
| string
| JSONValue[]
| { [key: string]: JSONValue };
```

## Shape

- Primitive JSON values
- `null`: Represents a JSON null.
- `boolean`: Represents a JSON boolean (`true` or `false`).
- `number`: Represents a finite JSON number. `NaN`, `Infinity`, and `-Infinity` are not allowed.
- `string`: Represents a JSON string.

## Composite JSON values

- `JSONValue[]`: An array of valid JSON values. Arrays are recursively typed.
- `{ [key: string]: JSONValue }`: A plain object whose property values are valid JSON values.
- Non-plain prototypes (like `Date` or `Map`) are not allowed.

## Behavior

- Fully recursive: Arrays and nested objects are validated against the JSONValue contract.
- Strict: No coercion of types. Strings like `"123"` do not count as numbers, and boxed primitives are rejected.
- Circular references are not allowed. Validators using `JSONValue` detect and reject them.
- Designed to work with all structured validators in Jane, including [validateJSON](../../reference/validators/semantic/validate-json.md).

## Examples

```ts
// Primitives
const a: JSONValue = null;
const b: JSONValue = true;
const c: JSONValue = 42;
const d: JSONValue = "hello";

// Arrays
const arr: JSONValue = [1, "two", true, null, [3, 4]];

// Plain objects
const obj: JSONValue = {
a: 1,
b: "x",
c: [true, null],
d: { nested: "value" },
};

// Invalid examples (not assignable to JSONValue)
const invalid1 = undefined;
const invalid2 = () => {};
const invalid3 = Symbol("s");
const invalid4 = new Date(); // non-plain object
```

## Notes

- `JSONValue` ensures strict JSON compliance at the type level.
- Validators like [validateJSON](../validators/semantic/validate-json.md) leverage `JSONValue` to provide zero side-effect, deterministic validation.
- Using `JSONValue` allows TypeScript to guarantee that any accepted value is safe to serialize with `JSON.stringify`.
- Suitable for API payload validation, configuration files, state storage, and any scenario requiring strict JSON-compatible data.
4 changes: 3 additions & 1 deletion docs/reference/validators/protocols/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Protocols define the core interfaces and behaviors required for composable utili

Protocols are defined as TypeScript interfaces, ensuring that all implementations provide the necessary methods for processing data without side effects.

-
- [validateAsyncIterable](validate-async-iterable.md)
- [validateIterable](validate-iterable.md)
- [validatePromise](validate-promise.md)

All protocols are pure, contract-driven, and designed to promote a consistent, decoupled architecture across the entire library.
64 changes: 64 additions & 0 deletions docs/reference/validators/protocols/validate-async-iterable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# validateAsyncIterable

Checks whether a value is an **async iterable**. This helper uses the [isAsyncIterable](../../type-guards/protocols/is-async-iterable.md) type guard internally.

A value is considered an async iterable if it is not `null` or `undefined` and exposes a callable `[Symbol.asyncIterator]` method. This matches the semantics used by `for await...of` and other async iteration constructs.

It never throws and never mutates input. Use it when you need a guaranteed async iterable before consuming streamed, paginated, or deferred data.

## Signature

```ts
function validateAsyncIterable<T>(
value: unknown,
field: string
): ValidationResult<AsyncIterable<T>>
```

## Parameters

| Name | Data type | Description |
|---|---|---|
| value | `unknown` | The value to validate. |
| field | `string` | The name of the field being validated, used in error reporting. |

## Returns

One of:

- `{ ok: true, value: AsyncIterable<T> }`: If the value implements a callable [Symbol.asyncIterator].
- `{ ok: false, field: string, message: string }`: If the value is `null`, `undefined`, or does not support async iteration.

## Behavior

- Uses [isAsyncIterable](../../type-guards/protocols/is-async-iterable.md) internally.
- Accepts native async generators and custom async iterable objects.
- Rejects synchronous iterables such as arrays.
- Rejects objects where `Symbol.asyncIterator` exists but is not callable.
- Never throws or mutates input.

## Examples

```ts
async function* stream() {
yield 1;
yield 2;
}

validateAsyncIterable(stream(), "stream")
// { ok: true, value: AsyncIterable<number> }

validateAsyncIterable([], "array")
// { ok: false, field: "array", message: "Value must be an async iterable" }

validateAsyncIterable(null, "data")
// { ok: false, field: "data", message: "Value must be an async iterable" }
```

## Notes

- This validator does not coerce values. Synchronous iterables (Array, Set, Map) are rejected even though they support [Symbol.iterator].
- Boxed values, primitives, and plain objects fail unless they explicitly implement [Symbol.asyncIterator].
- Because it relies on [isAsyncIterable](../../type-guards/protocols/is-async-iterable.md), values that would fail in `for await...of` also fail here.
- Suitable for validating streams, async generators, paginated data sources, and any API that yields values asynchronously.
- The validator never throws and never mutates input. All error reporting is handled through structured `ValidationResult` objects.
60 changes: 60 additions & 0 deletions docs/reference/validators/protocols/validate-iterable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# validateIterable

Checks whether a value is **iterable**. This helper uses the [isIterable](../../type-guards/protocols/is-iterable.md) type guard internally.

A value is considered iterable if it is not `null` or `undefined` and exposes a callable `[Symbol.iterator]` method. This matches the semantics used by `for...of`, spread syntax, and `Array.from`.

It never throws and never mutates input. Use it when you need a guaranteed iterable before iteration or collection.

## Signature

```ts
function validateIterable<T>(
value: unknown,
field: string
): ValidationResult<Iterable<T>>
```

# Parameters

| Name | Data type | Description |
|---|---|---|
| value | `unknown` | The value to validate. |
| field | `string` | The name of the field being validated, used in error reporting. |

## Returns

One of:

- `{ ok: true, value: Iterable<T> }`: If the value implements a callable `[Symbol.iterator]`.
- `{ ok: false, field: string, message: string }`: If the value is not iterable.

## Behavior

- Uses [isIterable](../../type-guards/protocols/is-iterable.md) internally.
- Accepts arrays, strings, sets, maps, and custom iterables.
- Rejects non-iterable objects.
- Rejects values where `[Symbol.iterator]` exists but is not callable.
- Never throws and mutates input.

### Examples

```ts
validateIterable([1, 2, 3], "items")
// { ok: true, value: Iterable<number> }

validateIterable("abc", "text")
// { ok: true, value: Iterable<string> }

validateIterable({ a: 1 }, "object")
// { ok: false, field: "object", message: "Value must be iterable" }
```

## Notes

- This validator does not coerce values. Boxed primitives and plain objects fail unless they explicitly implement `[Symbol.iterator]`.
- Synchronous iteration only. Async iterables must be validated with [validateAsyncIterable](../../type-guards/protocols/is-async-iterable.md).
- Because it relies on [isIterable](../../type-guards/protocols/is-iterable.md), values that would fail in `for...of` also fail here.
- Suitable for validating collections, input sequences, configuration lists, and any context where safe synchronous iteration is required.

The validator never throws and never mutates input. All error reporting is handled through structured `ValidationResult` objects.
59 changes: 59 additions & 0 deletions docs/reference/validators/protocols/validate-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# validatePromise

Checks whether a value is a **Promise**. This helper uses the [isPromise](../../type-guards/protocols/is-promise.md) type guard internally.

This validator performs a strict `instanceof Promise` check. It accepts native Promises and `Promise` subclasses, but intentionally rejects arbitrary thenables.

It never throws and never mutates input. Use it when you require a guaranteed `Promise` instance before chaining or awaiting.

## Signature

```ts
function validatePromise<T>(
value: unknown,
field: string
): ValidationResult<Promise<T>>
```

## Parameters

| Name | Data type | Description |
|---|---|---|
| value | `unknown` | The value to validate. |
| field | `string` | The name of the field being validated, used in error reporting. |

## Returns

One of:

- `{ ok: true, value: Promise<T> }`: If the value is a `Promise` instance.
- `{ ok: false, field: string, message: string }`: If the value is not a Promise.

## Behavior

- Uses [isPromise](../../type-guards/protocols/is-promise.md) internally.
- Accepts native Promises and `Promise` subclasses.
Rejects arbitrary thenables (`{ then() {} }`).
- Rejects `async` functions unless invoked.
- Never throws or mutates input.

## Examples

```ts
validatePromise(Promise.resolve(1), "result")
// { ok: true, value: Promise<number> }

validatePromise({ then: () => {} }, "thenable")
// { ok: false, field: "thenable", message: "Value must be a Promise" }

validatePromise(async () => 1, "fn")
// { ok: false, field: "fn", message: "Value must be a Promise" }
```

## Notes

- This validator is intentionally stricter than `Promise`-like checks found in some libraries. Thenables are rejected by design.
- The behavior matches JavaScript’s native `instanceof Promise` semantics.
- Because it relies on [isPromise](../../type-guards/protocols/is-promise.md), values that cannot safely be awaited as true Promises fail the check.
- Suitable for validating return values, deferred computations, async APIs, and concurrency primitives where `Promise` identity matters.
- The validator never throws and never mutates input. All error reporting is handled through structured `ValidationResult` objects.
9 changes: 8 additions & 1 deletion docs/reference/validators/semantic/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

Semantic validators ensure that a value not only meets its basic primitive or structural type but also conforms to a conventional meaning or format, such as date strings, email addresses, or specific identifier patterns. They return a structured `ValidationResult<T>`, never throw exceptions, and never mutate the input value.

-
- [validateDate](validate-date.md): Ensures a value is a valid Date instance with a finite timestamp. Rejects invalid Date objects such as new Date("invalid")
- [validateEnumValue](validate-enum-value.md): Ensures a value is one of the allowed values of a specific enum, including both string and numeric enums.
- [validateError](validate-error.md): Ensures a value is an Error object, including native error types and custom error subclasses.
- [validateFunction](validate-function.md): Ensures a value is a callable function with a specific parameter and return type, including arrow functions and class constructors.
- [validateJSON](validate-json.md): Ensures a value is a valid JSONValue, including primitives, arrays, and plain objects; rejects circular references and non-plain prototypes.
- [validatePort](validate-port.md): Ensures a value is an integer between 0 and 65535 inclusive, representing a valid TCP/UDP port number.
- [validateRegExp](validate-reg-exp.md): Ensures a value is a genuine RegExp instance, not a wrapper or custom object.
- [validateTimestamp](validate-timestamp.md): Ensures a value is a finite integer number representing a Unix timestamp in milliseconds.

All semantic validators are pure, predictable, and crucial for enforcing data quality based on domain-specific conventions and industry standards.
54 changes: 54 additions & 0 deletions docs/reference/validators/semantic/validate-date.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# validateDate

Checks whether a value is a valid **Date instance**. This helper uses [isDate](../../type-guards/semantic/is-date.md) internally.

A valid `Date` is an object created using `new Date(...)` whose internal timestamp is finite. Invalid Date objects (`new Date("invalid")`) are rejected.

This helper never throws and never mutates input.

## Signature

```ts
function validateDate(value: unknown, field: string): ValidationResult<Date>
```

## Parameters

| Name | Data type | Description |
|---|---|---|
| value | `unknown` | The value to validate. |
| field | `string` | The name of the field being validated, used in error reporting. |

## Returns

One of:

- `{ ok: true, value: Date }`: If the value is a valid `Date` instance.
- `{ ok: false, field: string, message: string }`: If the value is not a valid `Date` instance.

## Behavior

- Accepts only Date objects.
- Rejects invalid Dates (date.getTime() is NaN).
- Performs no coercion.
- Never throws or mutates input.

## Examples

```ts
validateDate(new Date("2025-12-12"), "date")
// { ok: true, value: 2025-12-12T00:00:00.000Z }

validateDate(new Date("invalid"), "date")
// { ok: false, field: "date", message: "Value must be a valid Date" }

validateDate("2025-12-12", "date")
// { ok: false, field: "date", message: "Value must be a valid Date" }
```

## Notes

- TypeScript strict mode is satisfied with explicit type casts inside the validator.
- Strings, numbers, and other primitives are not coerced.
- Suitable for API input validation, configuration, and internal data integrity checks.
- All error reporting goes through `ValidationResult`.
Loading