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
2 changes: 2 additions & 0 deletions .codex/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ La librairie est organisée par namespaces (`DArray`, `DObject`, etc.) et couvre
- outils orientés DDD (`DClean`)
- concepts monadiques (`DEither`)
- pattern matching (`DPattern`)
- Process et flux (`DFlow`)

## Philosophie

Expand Down Expand Up @@ -40,6 +41,7 @@ DPattern
DDataParser
DDate
DClean
DFlow

## Répertoires de travail
- `scripts/` : code source
Expand Down
4 changes: 2 additions & 2 deletions .codex/config.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
model = "gpt-5.2-codex"
review_model = "gpt-5.2-codex"
model = "gpt-5.3-codex"
review_model = "gpt-5.3-codex"
model_provider = "openai"

approval_policy = "untrusted"
Expand Down
78 changes: 76 additions & 2 deletions docs/en/v1/api/clean/constraints.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,24 +171,44 @@ Validates an integer.

### `Positive`

Validates a strictly positive number (>= 1).
Validates a positive or zero number (>= 0).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/positive.doc.ts"
majorVersion="v1"
height="240px"
/>

### `StrictPositive`

Validates a strictly positive number (> 0).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/strictPositive.doc.ts"
majorVersion="v1"
height="240px"
/>

### `Negative`

Validates a strictly negative number (<= -1).
Validates a negative or zero number (<= 0).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/negative.doc.ts"
majorVersion="v1"
height="240px"
/>

### `StrictNegative`

Validates a strictly negative number (< 0).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/strictNegative.doc.ts"
majorVersion="v1"
height="240px"
/>

### `NumberMin`

Validates a number greater than or equal to min.
Expand Down Expand Up @@ -229,6 +249,60 @@ Validates a strictly negative duration (<= -1 millisecond) on the `C.Time` primi
height="271px"
/>

## Constraint sets provided by the library

The library also exports ready-to-use constraint sets via `C.*`. They group multiple constraints and can be used directly with `C.createNewType(...)` or as validation handlers.

### `PositiveInt`

Validates a positive or zero integer (`Positive` + `Int`).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/positiveInt.doc.ts"
majorVersion="v1"
height="240px"
/>

### `StrictPositiveInt`

Validates a strictly positive integer (`StrictPositive` + `Int`).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/strictPositiveInt.doc.ts"
majorVersion="v1"
height="240px"
/>

### `NegativeInt`

Validates a negative or zero integer (`Negative` + `Int`).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/negativeInt.doc.ts"
majorVersion="v1"
height="240px"
/>

### `StrictNegativeInt`

Validates a strictly negative integer (`StrictNegative` + `Int`).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/strictNegativeInt.doc.ts"
majorVersion="v1"
height="240px"
/>

### `Percent`

Validates a number between 0 and 100 included (`NumberMin(0)` + `NumberMax(100)`).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/percent.doc.ts"
majorVersion="v1"
height="240px"
/>

## See also

- [Primitives](/en/v1/api/clean/primitives/)
Expand Down
11 changes: 11 additions & 0 deletions docs/examples/v1/api/clean/constraints/negativeInt.doc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { type ExpectType, C, DP } from "@duplojs/utils";

const Balance = C.createNewType("balance", DP.number(), C.NegativeInt);

const balance = Balance.createOrThrow(0);

type check = ExpectType<
typeof balance,
C.NewType<"balance", 0, "negative" | "int">,
"strict"
>;
11 changes: 11 additions & 0 deletions docs/examples/v1/api/clean/constraints/percent.doc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { type ExpectType, C, DP } from "@duplojs/utils";

const Progress = C.createNewType("progress", DP.number(), C.Percent);

const progress = Progress.createOrThrow(100);

type check = ExpectType<
typeof progress,
C.NewType<"progress", 100, "number-min-0" | "number-max-100">,
"strict"
>;
11 changes: 11 additions & 0 deletions docs/examples/v1/api/clean/constraints/positiveInt.doc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { type ExpectType, C, DP } from "@duplojs/utils";

const Count = C.createNewType("count", DP.number(), C.PositiveInt);

const count = Count.createOrThrow(0);

type check = ExpectType<
typeof count,
C.NewType<"count", 0, "positive" | "int">,
"strict"
>;
11 changes: 11 additions & 0 deletions docs/examples/v1/api/clean/constraints/strictNegative.doc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { type ExpectType, C, DP } from "@duplojs/utils";

const Delta = C.createNewType("delta", DP.number(), C.StrictNegative);

const delta = Delta.createOrThrow(-1);

type check = ExpectType<
typeof delta,
C.NewType<"delta", -1, "strict-negative">,
"strict"
>;
11 changes: 11 additions & 0 deletions docs/examples/v1/api/clean/constraints/strictNegativeInt.doc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { type ExpectType, C, DP } from "@duplojs/utils";

const Debt = C.createNewType("debt", DP.number(), C.StrictNegativeInt);

const debt = Debt.createOrThrow(-1);

type check = ExpectType<
typeof debt,
C.NewType<"debt", -1, "strict-negative" | "int">,
"strict"
>;
11 changes: 11 additions & 0 deletions docs/examples/v1/api/clean/constraints/strictPositive.doc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { type ExpectType, C, DP } from "@duplojs/utils";

const Rating = C.createNewType("rating", DP.number(), C.StrictPositive);

const rating = Rating.createOrThrow(1);

type check = ExpectType<
typeof rating,
C.NewType<"rating", 1, "strict-positive">,
"strict"
>;
11 changes: 11 additions & 0 deletions docs/examples/v1/api/clean/constraints/strictPositiveInt.doc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { type ExpectType, C, DP } from "@duplojs/utils";

const Quantity = C.createNewType("quantity", DP.number(), C.StrictPositiveInt);

const quantity = Quantity.createOrThrow(1);

type check = ExpectType<
typeof quantity,
C.NewType<"quantity", 1, "strict-positive" | "int">,
"strict"
>;
78 changes: 76 additions & 2 deletions docs/fr/v1/api/clean/constraints.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,24 +171,44 @@ Valide un nombre entier.

### `Positive`

Valide un nombre strictement positif (>= 1).
Valide un nombre positif ou nul (>= 0).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/positive.doc.ts"
majorVersion="v1"
height="240px"
/>

### `StrictPositive`

Valide un nombre strictement positif (> 0).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/strictPositive.doc.ts"
majorVersion="v1"
height="240px"
/>

### `Negative`

Valide un nombre strictement négatif (<= -1).
Valide un nombre négatif ou nul (<= 0).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/negative.doc.ts"
majorVersion="v1"
height="240px"
/>

### `StrictNegative`

Valide un nombre strictement négatif (< 0).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/strictNegative.doc.ts"
majorVersion="v1"
height="240px"
/>

### `NumberMin`

Valide un nombre supérieur ou égal à min.
Expand Down Expand Up @@ -229,6 +249,60 @@ Valide une durée strictement négative (<= -1 milliseconde) sur la primitive `C
height="271px"
/>

## Ensembles de contraintes fournis par la librairie

La librairie exporte aussi des ensembles de contraintes prêts à l'emploi via `C.*`. Ils regroupent plusieurs contraintes et peuvent être utilisés directement avec `C.createNewType(...)` ou comme handlers de validation.

### `PositiveInt`

Valide un nombre entier positif ou nul (`Positive` + `Int`).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/positiveInt.doc.ts"
majorVersion="v1"
height="240px"
/>

### `StrictPositiveInt`

Valide un nombre entier strictement positif (`StrictPositive` + `Int`).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/strictPositiveInt.doc.ts"
majorVersion="v1"
height="240px"
/>

### `NegativeInt`

Valide un nombre entier négatif ou nul (`Negative` + `Int`).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/negativeInt.doc.ts"
majorVersion="v1"
height="240px"
/>

### `StrictNegativeInt`

Valide un nombre entier strictement négatif (`StrictNegative` + `Int`).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/strictNegativeInt.doc.ts"
majorVersion="v1"
height="240px"
/>

### `Percent`

Valide un nombre compris entre 0 et 100 inclus (`NumberMin(0)` + `NumberMax(100)`).

<MonacoTSEditor
src="/examples/v1/api/clean/constraints/percent.doc.ts"
majorVersion="v1"
height="240px"
/>

## Voir aussi

- [Primitives](/fr/v1/api/clean/primitives/)
Expand Down
46 changes: 5 additions & 41 deletions docs/public/libs/v1/clean/chainedFunction.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,34 +45,6 @@ export type ChainedFunction<GenericValue extends FunctionChain = FunctionChain>
* Use it inside a Clean Architecture use case when several pure domain operations that update different entities must belong to the same business consistency boundary. Each link exposes exactly one named action, yields `Left` values to short-circuit the implementation, and provides the next link until the last step returns `chainEnd(value)`. Repository calls stay in the use case through the library repository system; functions passed to `chainedFunction` remain pure domain functions.
*
* ```ts
* interface CommentDraft {
* articleId: number;
* content: string;
* }
*
* interface Comment {
* id: number;
* articleId: number;
* content: string;
* }
*
* interface Article {
* id: number;
* commentCount: number;
* }
*
* interface CommentRepository {
* save(comment: Comment): Comment | E.Fail;
* }
*
* interface ArticleRepository {
* findById(articleId: number): Article | E.Fail;
* save(article: Article): Article | E.Fail;
* }
*
* const CommentRepository = C.createRepository<CommentRepository>();
* const ArticleRepository = C.createRepository<ArticleRepository>();
*
* const CommentPublicationAggregate = C.chainedFunction(
* [
* "createComment",
Expand Down Expand Up @@ -101,27 +73,18 @@ export type ChainedFunction<GenericValue extends FunctionChain = FunctionChain>
* ({
* commentRepository,
* articleRepository,
* }) => (draft: CommentDraft) => CommentPublicationAggregate(function *(link1) {
* }) => (draft: CommentDraft) => CommentPublicationAggregate(function *(link1, { breakIfLeft }) {
* const [comment, link2] = yield *link1(({ createComment }) => createComment(draft));
*
* const savedComment = commentRepository.save(comment);
* if (E.isLeft(savedComment)) {
* return savedComment;
* }
* const savedComment = yield *breakIfLeft(commentRepository.save(comment));
*
* const article = articleRepository.findById(savedComment.articleId);
* if (E.isLeft(article)) {
* return article;
* }
* const article = yield *breakIfLeft(articleRepository.findById(savedComment.articleId));
*
* const [updatedArticle, chainEnd] = yield *link2(
* ({ incrementArticleCommentCount }) => incrementArticleCommentCount(article),
* );
*
* const savedArticle = articleRepository.save(updatedArticle);
* if (E.isLeft(savedArticle)) {
* return savedArticle;
* }
* const savedArticle = yield *breakIfLeft(articleRepository.save(updatedArticle));
*
* return chainEnd({
* comment: savedComment,
Expand Down Expand Up @@ -200,6 +163,7 @@ export type ChainedFunction<GenericValue extends FunctionChain = FunctionChain>
* ```
*
* @remarks `chainedFunction` expects at least two functions in the chain. It does not catch thrown exceptions or rejected promises; model handled business errors with `Either.Left`.
* The callback receives `(firstLink, { breakIfLeft })`. `breakIfLeft` is synchronous and narrows `value | Left` to `value`, yielding the `Left` branch to short-circuit when needed.
*
* @see https://utils.duplojs.dev/en/v1/api/clean/chainedFunction
* @see [`C.createUseCase`](https://utils.duplojs.dev/en/v1/api/clean/useCase)
Expand Down
Loading
Loading