diff --git a/docs/en/v1/api/array/find.md b/docs/en/v1/api/array/find.md
index b104825d..ab0d7b38 100644
--- a/docs/en/v1/api/array/find.md
+++ b/docs/en/v1/api/array/find.md
@@ -5,8 +5,8 @@ prev:
text: "isLastIndex"
link: "/en/v1/api/array/isLastIndex"
next:
- text: "findLast"
- link: "/en/v1/api/array/findLast"
+ text: "findDuplicates"
+ link: "/en/v1/api/array/findDuplicates"
---
# find
diff --git a/docs/en/v1/api/array/findDuplicates.md b/docs/en/v1/api/array/findDuplicates.md
new file mode 100644
index 00000000..9811a721
--- /dev/null
+++ b/docs/en/v1/api/array/findDuplicates.md
@@ -0,0 +1,48 @@
+---
+outline: [2, 3]
+description: "The findDuplicates() function returns duplicated values from an array and keeps a single occurrence for each duplicated value."
+prev:
+ text: "find"
+ link: "/en/v1/api/array/find"
+next:
+ text: "findLast"
+ link: "/en/v1/api/array/findLast"
+---
+
+# findDuplicates
+
+The **`findDuplicates()`** function returns duplicated values from an array and keeps a single occurrence for each duplicated value.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Classic signature
+
+```typescript
+function findDuplicates<
+ GenericInput extends readonly EligibleDuplicateElement[],
+>(
+ array: GenericInput,
+): undefined | AnyTuple
+```
+
+## Parameters
+
+- `array`: Input array to scan for duplicates.
+
+## Return value
+
+Returns `undefined` when no duplicate is found, otherwise returns a tuple containing duplicated values (one occurrence per value).
+
+## See also
+
+- [`find`](/en/v1/api/array/find) - Finds a value matching a predicate
+- [`group`](/en/v1/api/array/group) - Groups values by key
+- [`includes`](/en/v1/api/array/includes) - Checks value presence in an array
diff --git a/docs/en/v1/api/array/findLast.md b/docs/en/v1/api/array/findLast.md
index 17054e7a..f1c6aa88 100644
--- a/docs/en/v1/api/array/findLast.md
+++ b/docs/en/v1/api/array/findLast.md
@@ -2,8 +2,8 @@
outline: [2, 3]
description: "The findLast() method returns the last element of an array that satisfies a given condition."
prev:
- text: "find"
- link: "/en/v1/api/array/find"
+ text: "findDuplicates"
+ link: "/en/v1/api/array/findDuplicates"
next:
text: "findIndex"
link: "/en/v1/api/array/findIndex"
diff --git a/docs/en/v1/api/array/index.md b/docs/en/v1/api/array/index.md
index be4d8021..fd15b033 100644
--- a/docs/en/v1/api/array/index.md
+++ b/docs/en/v1/api/array/index.md
@@ -68,6 +68,9 @@ Indicates whether an index corresponds to the last element of the array.
### [find](/en/v1/api/array/find)
Finds the first element that satisfies a condition.
+### [findDuplicates](/en/v1/api/array/findDuplicates)
+Finds duplicated values and keeps one occurrence per duplicate.
+
### [findLast](/en/v1/api/array/findLast)
Finds the last element that satisfies a condition.
diff --git a/docs/examples/v1/api/array/findDuplicates/tryout.doc.ts b/docs/examples/v1/api/array/findDuplicates/tryout.doc.ts
new file mode 100644
index 00000000..20482216
--- /dev/null
+++ b/docs/examples/v1/api/array/findDuplicates/tryout.doc.ts
@@ -0,0 +1,25 @@
+import { A, DDate, pipe, type ExpectType } from "@duplojs/utils";
+
+const primitiveResult = A.findDuplicates(["apple", "banana", "apple", "banana", "pear"]);
+// ["apple", "banana"]
+
+const dateValue = DDate.create("2024-01-01");
+const timeValue = DDate.createTime(90, "minute");
+const dateAndTimeResult = A.findDuplicates([
+ dateValue,
+ DDate.create("2024-01-01"),
+ timeValue,
+ DDate.createTime(90, "minute"),
+]);
+// [dateValue, timeValue]
+
+const pipedResult = pipe(
+ [true, false, true, false],
+ A.findDuplicates,
+);
+
+type check = ExpectType<
+ typeof pipedResult,
+ undefined | readonly [boolean, ...boolean[]],
+ "strict"
+>;
diff --git a/docs/fr/v1/api/array/find.md b/docs/fr/v1/api/array/find.md
index 95539186..4e87a387 100644
--- a/docs/fr/v1/api/array/find.md
+++ b/docs/fr/v1/api/array/find.md
@@ -5,8 +5,8 @@ prev:
text: "isLastIndex"
link: "/fr/v1/api/array/isLastIndex"
next:
- text: "findLast"
- link: "/fr/v1/api/array/findLast"
+ text: "findDuplicates"
+ link: "/fr/v1/api/array/findDuplicates"
---
# find
diff --git a/docs/fr/v1/api/array/findDuplicates.md b/docs/fr/v1/api/array/findDuplicates.md
new file mode 100644
index 00000000..3e5b1b53
--- /dev/null
+++ b/docs/fr/v1/api/array/findDuplicates.md
@@ -0,0 +1,48 @@
+---
+outline: [2, 3]
+description: "La fonction findDuplicates() retourne les valeurs dupliquées d'un tableau et conserve une seule occurrence pour chaque valeur dupliquée."
+prev:
+ text: "find"
+ link: "/fr/v1/api/array/find"
+next:
+ text: "findLast"
+ link: "/fr/v1/api/array/findLast"
+---
+
+# findDuplicates
+
+La fonction **`findDuplicates()`** retourne les valeurs dupliquées d'un tableau et conserve une seule occurrence pour chaque valeur dupliquée.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Signature classique
+
+```typescript
+function findDuplicates<
+ GenericInput extends readonly EligibleDuplicateElement[],
+>(
+ array: GenericInput,
+): undefined | AnyTuple
+```
+
+## Paramètres
+
+- `array` : Tableau d'entrée à parcourir pour détecter les doublons.
+
+## Valeur de retour
+
+Retourne `undefined` lorsqu'aucun doublon n'est trouvé, sinon retourne un tuple contenant les valeurs dupliquées (une occurrence par valeur).
+
+## Voir aussi
+
+- [`find`](/fr/v1/api/array/find) - Trouve une valeur correspondant à un prédicat
+- [`group`](/fr/v1/api/array/group) - Regroupe les valeurs par clé
+- [`includes`](/fr/v1/api/array/includes) - Vérifie la présence d'une valeur dans un tableau
diff --git a/docs/fr/v1/api/array/findLast.md b/docs/fr/v1/api/array/findLast.md
index de2d7396..fe7ff66a 100644
--- a/docs/fr/v1/api/array/findLast.md
+++ b/docs/fr/v1/api/array/findLast.md
@@ -2,8 +2,8 @@
outline: [2, 3]
description: "La méthode findLast() retourne le dernier élément d'un tableau qui satisfait une condition donnée."
prev:
- text: "find"
- link: "/fr/v1/api/array/find"
+ text: "findDuplicates"
+ link: "/fr/v1/api/array/findDuplicates"
next:
text: "findIndex"
link: "/fr/v1/api/array/findIndex"
diff --git a/docs/fr/v1/api/array/index.md b/docs/fr/v1/api/array/index.md
index e84f1f55..8d20f5c3 100644
--- a/docs/fr/v1/api/array/index.md
+++ b/docs/fr/v1/api/array/index.md
@@ -68,6 +68,9 @@ Indique si un index correspond au dernier élément du tableau.
### [find](/fr/v1/api/array/find)
Trouve le premier élément qui satisfait une condition.
+### [findDuplicates](/fr/v1/api/array/findDuplicates)
+Trouve les valeurs dupliquées et conserve une occurrence par doublon.
+
### [findLast](/fr/v1/api/array/findLast)
Trouve le dernier élément qui satisfait une condition.
diff --git a/docs/public/libs/v1/array/findDuplicates.cjs b/docs/public/libs/v1/array/findDuplicates.cjs
new file mode 100644
index 00000000..950fd274
--- /dev/null
+++ b/docs/public/libs/v1/array/findDuplicates.cjs
@@ -0,0 +1,38 @@
+'use strict';
+
+var is = require('../date/is.cjs');
+var isTime = require('../date/isTime.cjs');
+
+function findDuplicates(array) {
+ const store = new Map();
+ let storeTimeObject = undefined;
+ let result = undefined;
+ for (let index$1 = 0; index$1 < array.length; index$1++) {
+ const element = array[index$1];
+ if (is.is(element) || isTime.isTime(element)) {
+ storeTimeObject ??= new Map();
+ const serializedValue = element.toJSON();
+ const storedElement = storeTimeObject.get(serializedValue) ?? element;
+ const storedCount = store.get(storedElement);
+ if (storedCount === 1) {
+ result ??= [];
+ result.push(storedElement);
+ }
+ store.set(storedElement, (storedCount ?? 0) + 1);
+ if (storedElement === element) {
+ storeTimeObject.set(serializedValue, element);
+ }
+ }
+ else {
+ const storedCount = store.get(element);
+ if (storedCount === 1) {
+ result ??= [];
+ result.push(element);
+ }
+ store.set(element, (storedCount ?? 0) + 1);
+ }
+ }
+ return result;
+}
+
+exports.findDuplicates = findDuplicates;
diff --git a/docs/public/libs/v1/array/findDuplicates.d.ts b/docs/public/libs/v1/array/findDuplicates.d.ts
new file mode 100644
index 00000000..b41d2ff1
--- /dev/null
+++ b/docs/public/libs/v1/array/findDuplicates.d.ts
@@ -0,0 +1,4 @@
+import { type AnyTuple } from "../common";
+import * as DDate from "../date";
+export type EligibleDuplicateElement = (string | boolean | null | number | bigint | undefined | DDate.TheDate | DDate.TheTime);
+export declare function findDuplicates(array: GenericInput): undefined | AnyTuple;
diff --git a/docs/public/libs/v1/array/findDuplicates.mjs b/docs/public/libs/v1/array/findDuplicates.mjs
new file mode 100644
index 00000000..19b29fbc
--- /dev/null
+++ b/docs/public/libs/v1/array/findDuplicates.mjs
@@ -0,0 +1,36 @@
+import { is } from '../date/is.mjs';
+import { isTime } from '../date/isTime.mjs';
+
+function findDuplicates(array) {
+ const store = new Map();
+ let storeTimeObject = undefined;
+ let result = undefined;
+ for (let index$1 = 0; index$1 < array.length; index$1++) {
+ const element = array[index$1];
+ if (is(element) || isTime(element)) {
+ storeTimeObject ??= new Map();
+ const serializedValue = element.toJSON();
+ const storedElement = storeTimeObject.get(serializedValue) ?? element;
+ const storedCount = store.get(storedElement);
+ if (storedCount === 1) {
+ result ??= [];
+ result.push(storedElement);
+ }
+ store.set(storedElement, (storedCount ?? 0) + 1);
+ if (storedElement === element) {
+ storeTimeObject.set(serializedValue, element);
+ }
+ }
+ else {
+ const storedCount = store.get(element);
+ if (storedCount === 1) {
+ result ??= [];
+ result.push(element);
+ }
+ store.set(element, (storedCount ?? 0) + 1);
+ }
+ }
+ return result;
+}
+
+export { findDuplicates };
diff --git a/docs/public/libs/v1/array/index.cjs b/docs/public/libs/v1/array/index.cjs
index 4f61be94..70b267a6 100644
--- a/docs/public/libs/v1/array/index.cjs
+++ b/docs/public/libs/v1/array/index.cjs
@@ -45,6 +45,7 @@ var isLastIndex = require('./isLastIndex.cjs');
var select = require('./select.cjs');
var lengthEqual = require('./lengthEqual.cjs');
var mapTuple = require('./mapTuple.cjs');
+var findDuplicates = require('./findDuplicates.cjs');
var _delete = require('./splice/delete.cjs');
var insert = require('./splice/insert.cjs');
var replace = require('./splice/replace.cjs');
@@ -110,6 +111,7 @@ exports.select = select.select;
exports.selectTools = select.selectTools;
exports.lengthEqual = lengthEqual.lengthEqual;
exports.mapTuple = mapTuple.mapTuple;
+exports.findDuplicates = findDuplicates.findDuplicates;
exports.spliceDelete = _delete.spliceDelete;
exports.spliceInsert = insert.spliceInsert;
exports.spliceReplace = replace.spliceReplace;
diff --git a/docs/public/libs/v1/array/index.d.ts b/docs/public/libs/v1/array/index.d.ts
index 81f94d52..60b00351 100644
--- a/docs/public/libs/v1/array/index.d.ts
+++ b/docs/public/libs/v1/array/index.d.ts
@@ -75,3 +75,4 @@ export * from "./isLastIndex";
export * from "./select";
export * from "./lengthEqual";
export * from "./mapTuple";
+export * from "./findDuplicates";
diff --git a/docs/public/libs/v1/array/index.mjs b/docs/public/libs/v1/array/index.mjs
index 25efc14c..a0b52463 100644
--- a/docs/public/libs/v1/array/index.mjs
+++ b/docs/public/libs/v1/array/index.mjs
@@ -43,6 +43,7 @@ export { isLastIndex } from './isLastIndex.mjs';
export { select, selectTools } from './select.mjs';
export { lengthEqual } from './lengthEqual.mjs';
export { mapTuple } from './mapTuple.mjs';
+export { findDuplicates } from './findDuplicates.mjs';
export { spliceDelete } from './splice/delete.mjs';
export { spliceInsert } from './splice/insert.mjs';
export { spliceReplace } from './splice/replace.mjs';
diff --git a/docs/public/libs/v1/clean/constraint/base.d.ts b/docs/public/libs/v1/clean/constraint/base.d.ts
index bc8a84eb..fda5c6fc 100644
--- a/docs/public/libs/v1/clean/constraint/base.d.ts
+++ b/docs/public/libs/v1/clean/constraint/base.d.ts
@@ -101,7 +101,7 @@ export interface ConstraintHandler Error & Kind, unknown> & Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind, unknown> & Kind, unknown>;
export declare class CreateConstrainedTypeError extends CreateConstrainedTypeError_base {
constrainedTypeName: string;
data: unknown;
diff --git a/docs/public/libs/v1/clean/constraint/set.d.ts b/docs/public/libs/v1/clean/constraint/set.d.ts
index 32586358..a924160f 100644
--- a/docs/public/libs/v1/clean/constraint/set.d.ts
+++ b/docs/public/libs/v1/clean/constraint/set.d.ts
@@ -107,7 +107,7 @@ export interface ConstraintsSetHandler Error & Kind, unknown> & Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind, unknown> & Kind, unknown>;
export declare class CreateConstraintsSetError extends CreateConstraintsSetError_base {
data: unknown;
dataParserError: DDataParser.DataParserError;
diff --git a/docs/public/libs/v1/clean/entity/index.d.ts b/docs/public/libs/v1/clean/entity/index.d.ts
index ba0959d8..072e8673 100644
--- a/docs/public/libs/v1/clean/entity/index.d.ts
+++ b/docs/public/libs/v1/clean/entity/index.d.ts
@@ -117,7 +117,7 @@ export interface EntityHandler Error & Kind, unknown> & Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind, unknown> & Kind, unknown>;
export declare class CreateEntityError extends CreateEntityError_base {
rawProperties: PropertiesToMapOfEntity;
dataParserError: DDataParser.DataParserError;
diff --git a/docs/public/libs/v1/clean/flag.d.ts b/docs/public/libs/v1/clean/flag.d.ts
index 92a80486..f54b7166 100644
--- a/docs/public/libs/v1/clean/flag.d.ts
+++ b/docs/public/libs/v1/clean/flag.d.ts
@@ -15,7 +15,7 @@ export interface FlagHandler("majorUser");
* export type MajorFlag = C.GetFlag;
*
* export function isMajor(entity: Entity) {
* if (C.greaterThan(entity.age, 18)) {
* return E.success(
- * MajorFlag.append(entity, entity.age),
+ * MajorFlag.append(entity, { age: entity.age }),
* );
* }
* return E.left("not-major");
@@ -94,7 +94,7 @@ export interface Flag | E.Right<"not-thirsty-anymore", undefined>
*
- * const flagged = User.MajorFlag.append(user, user.age);
+ * const flagged = User.MajorFlag.append(user, { age: user.age });
* const value = User.MajorFlag.getValue(flagged);
*
* ```
diff --git a/docs/public/libs/v1/clean/newType.d.ts b/docs/public/libs/v1/clean/newType.d.ts
index 9d4df133..42bff169 100644
--- a/docs/public/libs/v1/clean/newType.d.ts
+++ b/docs/public/libs/v1/clean/newType.d.ts
@@ -114,7 +114,7 @@ export interface NewTypeHandler Error & Kind, unknown> & Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind, unknown> & Kind, unknown>;
export declare class CreateNewTypeError extends CreateNewTypeError_base {
newTypeName: string;
data: unknown;
diff --git a/docs/public/libs/v1/clean/primitive/base.d.ts b/docs/public/libs/v1/clean/primitive/base.d.ts
index 9dd0c020..d374ce8e 100644
--- a/docs/public/libs/v1/clean/primitive/base.d.ts
+++ b/docs/public/libs/v1/clean/primitive/base.d.ts
@@ -70,7 +70,7 @@ export interface PrimitiveHandler Error & Kind, unknown> & Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind, unknown> & Kind, unknown>;
export declare class CreatePrimitiveError extends CreatePrimitiveError_base {
data: unknown;
dataParserError: DDataParser.DataParserError;
diff --git a/docs/public/libs/v1/clean/toMapDataParser.cjs b/docs/public/libs/v1/clean/toMapDataParser.cjs
index 20da7ffa..e2b14c50 100644
--- a/docs/public/libs/v1/clean/toMapDataParser.cjs
+++ b/docs/public/libs/v1/clean/toMapDataParser.cjs
@@ -1,10 +1,11 @@
'use strict';
var newType = require('./newType.cjs');
+var hasSomeKinds = require('../common/hasSomeKinds.cjs');
+var property = require('./entity/property.cjs');
var base = require('./primitive/base.cjs');
var base$1 = require('./constraint/base.cjs');
var set = require('./constraint/set.cjs');
-var hasSomeKinds = require('../common/hasSomeKinds.cjs');
var index = require('../pattern/match/index.cjs');
var transform = require('../dataParser/parsers/transform.cjs');
var index$1 = require('../dataParser/parsers/string/index.cjs');
@@ -18,6 +19,15 @@ var nil = require('../dataParser/parsers/nil.cjs');
var wrapValue = require('../common/wrapValue.cjs');
function toMapDataParser(input, params) {
+ if (hasSomeKinds.hasSomeKinds(input, [
+ property.entityPropertyNullableKind,
+ property.entityPropertyArrayKind,
+ property.entityPropertyStructureKind,
+ property.entityPropertyIdentifierKind,
+ property.entityPropertyUnionKind,
+ ])) {
+ return property.entityPropertyDefinitionToDataParser(input, (newTypeHandler) => toMapDataParser(newTypeHandler, params));
+ }
const dataParser = (base.primitiveHandlerKind.has(input)
? input.dataParser.clone()
: input.internal.dataParser.clone());
diff --git a/docs/public/libs/v1/clean/toMapDataParser.d.ts b/docs/public/libs/v1/clean/toMapDataParser.d.ts
index 8ef67f6a..51d9afa7 100644
--- a/docs/public/libs/v1/clean/toMapDataParser.d.ts
+++ b/docs/public/libs/v1/clean/toMapDataParser.d.ts
@@ -1,9 +1,9 @@
import * as DDataParser from "../dataParser";
import { type ConstraintHandler, type ConstraintsSetHandler, type GetConstraint, type GetConstraints } from "./constraint";
-import { type GetNewType, type NewTypeHandler } from "./newType";
import { type PrimitiveHandler } from "./primitive";
-type ToMapDataParserInput = NewTypeHandler | ConstraintHandler | ConstraintsSetHandler | PrimitiveHandler;
-type OutputDataParser = GenericInput extends NewTypeHandler ? GetNewType : GenericInput extends ConstraintHandler ? GetConstraint : GenericInput extends ConstraintsSetHandler ? GetConstraints : GenericInput extends PrimitiveHandler ? ReturnType : never;
+import { type EntityPropertyDefinition, type EntityProperty } from "./entity";
+type ToMapDataParserInput = (ConstraintHandler | ConstraintsSetHandler | PrimitiveHandler | EntityPropertyDefinition);
+type OutputDataParser = GenericInput extends ConstraintHandler ? GetConstraint : GenericInput extends ConstraintsSetHandler ? GetConstraints : GenericInput extends PrimitiveHandler ? ReturnType : GenericInput extends EntityPropertyDefinition ? EntityProperty : never;
interface ToMapDataParserParams {
coerce?: boolean;
}
@@ -41,7 +41,7 @@ interface ToMapDataParserParams {
* ```
*
* @remarks
- * - Supported inputs: `NewTypeHandler`, `ConstraintHandler`, `ConstraintsSetHandler`, and `PrimitiveHandler`.
+ * - Supported inputs: `NewTypeHandler`, `ConstraintHandler`, `ConstraintsSetHandler`, `PrimitiveHandler`, and `EntityProperty`.
* - Use `coerce: true` to allow conversions (e.g. number to string) on compatible parsers.
*
* @see https://utils.duplojs.dev/en/v1/api/clean/toMapDataParser
@@ -49,5 +49,5 @@ interface ToMapDataParserParams {
* @namespace C
*
*/
-export declare function toMapDataParser(input: GenericInput, params?: ToMapDataParserParams): DDataParser.Contract, GenericInputDataParser>;
+export declare function toMapDataParser>(input: GenericInput, params?: ToMapDataParserParams): DDataParser.Contract, unknown>;
export {};
diff --git a/docs/public/libs/v1/clean/toMapDataParser.mjs b/docs/public/libs/v1/clean/toMapDataParser.mjs
index 9e841245..03ba64df 100644
--- a/docs/public/libs/v1/clean/toMapDataParser.mjs
+++ b/docs/public/libs/v1/clean/toMapDataParser.mjs
@@ -1,8 +1,9 @@
import { newTypeHandlerKind, newTypeKind } from './newType.mjs';
+import { hasSomeKinds } from '../common/hasSomeKinds.mjs';
+import { entityPropertyDefinitionToDataParser, entityPropertyNullableKind, entityPropertyArrayKind, entityPropertyStructureKind, entityPropertyIdentifierKind, entityPropertyUnionKind } from './entity/property.mjs';
import { primitiveHandlerKind } from './primitive/base.mjs';
import { constrainedTypeKind, constraintHandlerKind } from './constraint/base.mjs';
import { constraintsSetHandlerKind } from './constraint/set.mjs';
-import { hasSomeKinds } from '../common/hasSomeKinds.mjs';
import { match } from '../pattern/match/index.mjs';
import { transform } from '../dataParser/parsers/transform.mjs';
import { stringKind } from '../dataParser/parsers/string/index.mjs';
@@ -16,6 +17,15 @@ import { nilKind } from '../dataParser/parsers/nil.mjs';
import { keyWrappedValue } from '../common/wrapValue.mjs';
function toMapDataParser(input, params) {
+ if (hasSomeKinds(input, [
+ entityPropertyNullableKind,
+ entityPropertyArrayKind,
+ entityPropertyStructureKind,
+ entityPropertyIdentifierKind,
+ entityPropertyUnionKind,
+ ])) {
+ return entityPropertyDefinitionToDataParser(input, (newTypeHandler) => toMapDataParser(newTypeHandler, params));
+ }
const dataParser = (primitiveHandlerKind.has(input)
? input.dataParser.clone()
: input.internal.dataParser.clone());
diff --git a/docs/public/libs/v1/common/asserts.d.ts b/docs/public/libs/v1/common/asserts.d.ts
index 6018cdc3..60a12610 100644
--- a/docs/public/libs/v1/common/asserts.d.ts
+++ b/docs/public/libs/v1/common/asserts.d.ts
@@ -1,6 +1,6 @@
declare const AssertsError_base: new (params: {
"@DuplojsUtilsError/asserts-error"?: unknown;
-}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("./kind").Kind, unknown> & import("./kind").Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("./kind").Kind, unknown> & import("./kind").Kind, unknown>;
export declare class AssertsError extends AssertsError_base {
value: unknown;
constructor(value: unknown);
diff --git a/docs/public/libs/v1/common/stringToBytes.d.ts b/docs/public/libs/v1/common/stringToBytes.d.ts
index 23f0ee81..11587812 100644
--- a/docs/public/libs/v1/common/stringToBytes.d.ts
+++ b/docs/public/libs/v1/common/stringToBytes.d.ts
@@ -1,6 +1,6 @@
declare const InvalidBytesInStringError_base: new (params: {
"@DuplojsUtilsError/missing-builder-methods-error"?: unknown;
-}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("./kind").Kind, unknown> & import("./kind").Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("./kind").Kind, unknown> & import("./kind").Kind, unknown>;
export declare class InvalidBytesInStringError extends InvalidBytesInStringError_base {
input: string;
constructor(input: string);
diff --git a/docs/public/libs/v1/common/toRegExp.cjs b/docs/public/libs/v1/common/toRegExp.cjs
index d6c24f81..7d5707f7 100644
--- a/docs/public/libs/v1/common/toRegExp.cjs
+++ b/docs/public/libs/v1/common/toRegExp.cjs
@@ -1,7 +1,6 @@
'use strict';
var escapeRegExp = require('./escapeRegExp.cjs');
-var is = require('../array/is.cjs');
/**
* {@include common/toRegExp/index.md}
@@ -10,7 +9,7 @@ function toRegExp(input) {
if (typeof input === "string") {
return new RegExp(`^${escapeRegExp.escapeRegExp(input)}$`);
}
- if (is.is(input)) {
+ if (input instanceof Array) {
const result = input.map(escapeRegExp.escapeRegExp).join("|");
return new RegExp(`^(?:${result})$`);
}
diff --git a/docs/public/libs/v1/common/toRegExp.mjs b/docs/public/libs/v1/common/toRegExp.mjs
index 6992cbe8..fbeee25c 100644
--- a/docs/public/libs/v1/common/toRegExp.mjs
+++ b/docs/public/libs/v1/common/toRegExp.mjs
@@ -1,5 +1,4 @@
import { escapeRegExp } from './escapeRegExp.mjs';
-import { is } from '../array/is.mjs';
/**
* {@include common/toRegExp/index.md}
@@ -8,7 +7,7 @@ function toRegExp(input) {
if (typeof input === "string") {
return new RegExp(`^${escapeRegExp(input)}$`);
}
- if (is(input)) {
+ if (input instanceof Array) {
const result = input.map(escapeRegExp).join("|");
return new RegExp(`^(?:${result})$`);
}
diff --git a/docs/public/libs/v1/dataParser/base.cjs b/docs/public/libs/v1/dataParser/base.cjs
index fa2de3cc..089fe286 100644
--- a/docs/public/libs/v1/dataParser/base.cjs
+++ b/docs/public/libs/v1/dataParser/base.cjs
@@ -45,7 +45,7 @@ function dataParserInit(kind, definition, exec, specificOverrideHandler) {
if (result !== SDPE
&& self.definition.checkers.length) {
for (const checker of self.definition.checkers) {
- const checkerResult = checker.exec(result, error, checker);
+ const checkerResult = checker.exec(result, error, checker, self);
if (checkerResult === SDPE) {
return SDPE;
}
@@ -61,7 +61,7 @@ function dataParserInit(kind, definition, exec, specificOverrideHandler) {
if (result !== SDPE
&& self.definition.checkers.length) {
for (const checker of self.definition.checkers) {
- const checkerResult = checker.exec(result, error, checker);
+ const checkerResult = checker.exec(result, error, checker, self);
if (checkerResult === SDPE) {
return SDPE;
}
diff --git a/docs/public/libs/v1/dataParser/base.d.ts b/docs/public/libs/v1/dataParser/base.d.ts
index 29133be2..4da9d2ec 100644
--- a/docs/public/libs/v1/dataParser/base.d.ts
+++ b/docs/public/libs/v1/dataParser/base.d.ts
@@ -8,7 +8,7 @@ export interface DataParserCheckerDefinition {
}
export interface DataParserChecker extends Kind {
readonly definition: GenericDefinition;
- exec(data: GenericInput, error: DataParserError, self: this): GenericOutput | SymbolDataParserError;
+ exec(data: GenericInput, error: DataParserError, self: this, dataParser: DataParser): GenericOutput | SymbolDataParserError;
}
export type InputChecker = Parameters[0];
export declare function dataParserCheckerInit(kind: Exclude, typeof checkerKind>, params: NoInfer, "exec">>, exec: (...args: Parameters) => InputChecker | SymbolDataParserError): GenericDataParserChecker;
@@ -245,7 +245,7 @@ interface DataParserInitExecParams {
}
declare const DataParserThrowError_base: new (params: {
"@DuplojsUtilsError/dataParserThrowError"?: unknown;
-}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind, unknown> & Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind, unknown> & Kind, unknown>;
export declare class DataParserThrowError extends DataParserThrowError_base {
value: unknown;
constructor(value: unknown);
diff --git a/docs/public/libs/v1/dataParser/base.mjs b/docs/public/libs/v1/dataParser/base.mjs
index 8f56f5aa..3f862bbd 100644
--- a/docs/public/libs/v1/dataParser/base.mjs
+++ b/docs/public/libs/v1/dataParser/base.mjs
@@ -43,7 +43,7 @@ function dataParserInit(kind, definition, exec, specificOverrideHandler) {
if (result !== SDPE
&& self.definition.checkers.length) {
for (const checker of self.definition.checkers) {
- const checkerResult = checker.exec(result, error, checker);
+ const checkerResult = checker.exec(result, error, checker, self);
if (checkerResult === SDPE) {
return SDPE;
}
@@ -59,7 +59,7 @@ function dataParserInit(kind, definition, exec, specificOverrideHandler) {
if (result !== SDPE
&& self.definition.checkers.length) {
for (const checker of self.definition.checkers) {
- const checkerResult = checker.exec(result, error, checker);
+ const checkerResult = checker.exec(result, error, checker, self);
if (checkerResult === SDPE) {
return SDPE;
}
diff --git a/docs/public/libs/v1/dataParser/parsers/array/checkers/max.cjs b/docs/public/libs/v1/dataParser/parsers/array/checkers/max.cjs
index a3b6f807..8b27aba4 100644
--- a/docs/public/libs/v1/dataParser/parsers/array/checkers/max.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/array/checkers/max.cjs
@@ -11,9 +11,9 @@ function checkerArrayMax(max, definition = {}) {
...definition,
max,
},
- }, (data, error$1, self) => data.length <= self.definition.max
+ }, (data, error$1, self, dataParser) => data.length <= self.definition.max
? data
- : error.addIssue(error$1, `array.length <= ${self.definition.max}`, data, self.definition.errorMessage));
+ : error.addIssue(error$1, `array.length <= ${self.definition.max}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
exports.checkerArrayMax = checkerArrayMax;
diff --git a/docs/public/libs/v1/dataParser/parsers/array/checkers/max.mjs b/docs/public/libs/v1/dataParser/parsers/array/checkers/max.mjs
index 3957498a..e5535ca8 100644
--- a/docs/public/libs/v1/dataParser/parsers/array/checkers/max.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/array/checkers/max.mjs
@@ -9,9 +9,9 @@ function checkerArrayMax(max, definition = {}) {
...definition,
max,
},
- }, (data, error, self) => data.length <= self.definition.max
+ }, (data, error, self, dataParser) => data.length <= self.definition.max
? data
- : addIssue(error, `array.length <= ${self.definition.max}`, data, self.definition.errorMessage));
+ : addIssue(error, `array.length <= ${self.definition.max}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
export { checkerArrayMax, checkerArrayMaxKind };
diff --git a/docs/public/libs/v1/dataParser/parsers/array/checkers/min.cjs b/docs/public/libs/v1/dataParser/parsers/array/checkers/min.cjs
index be0b35bd..6c3e4d2f 100644
--- a/docs/public/libs/v1/dataParser/parsers/array/checkers/min.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/array/checkers/min.cjs
@@ -11,9 +11,9 @@ function checkerArrayMin(min, definition = {}) {
...definition,
min,
},
- }, (data, error$1, self) => data.length >= self.definition.min
+ }, (data, error$1, self, dataParser) => data.length >= self.definition.min
? data
- : error.addIssue(error$1, `array.length >= ${self.definition.min}`, data, self.definition.errorMessage));
+ : error.addIssue(error$1, `array.length >= ${self.definition.min}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
exports.checkerArrayMin = checkerArrayMin;
diff --git a/docs/public/libs/v1/dataParser/parsers/array/checkers/min.mjs b/docs/public/libs/v1/dataParser/parsers/array/checkers/min.mjs
index fa75795e..ee7520f2 100644
--- a/docs/public/libs/v1/dataParser/parsers/array/checkers/min.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/array/checkers/min.mjs
@@ -9,9 +9,9 @@ function checkerArrayMin(min, definition = {}) {
...definition,
min,
},
- }, (data, error, self) => data.length >= self.definition.min
+ }, (data, error, self, dataParser) => data.length >= self.definition.min
? data
- : addIssue(error, `array.length >= ${self.definition.min}`, data, self.definition.errorMessage));
+ : addIssue(error, `array.length >= ${self.definition.min}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
export { checkerArrayMin, checkerArrayMinKind };
diff --git a/docs/public/libs/v1/dataParser/parsers/bigint/checkers/max.cjs b/docs/public/libs/v1/dataParser/parsers/bigint/checkers/max.cjs
index 24d06fc6..3a0c8e43 100644
--- a/docs/public/libs/v1/dataParser/parsers/bigint/checkers/max.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/bigint/checkers/max.cjs
@@ -11,9 +11,9 @@ function checkerBigIntMax(max, definition = {}) {
...definition,
max,
},
- }, (value, error$1, self) => {
+ }, (value, error$1, self, dataParser) => {
if (value > self.definition.max) {
- return error.addIssue(error$1, `bigint <= ${self.definition.max}n`, value, self.definition.errorMessage);
+ return error.addIssue(error$1, `bigint <= ${self.definition.max}n`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage);
}
return value;
});
diff --git a/docs/public/libs/v1/dataParser/parsers/bigint/checkers/max.mjs b/docs/public/libs/v1/dataParser/parsers/bigint/checkers/max.mjs
index 5cadd5a4..525935e2 100644
--- a/docs/public/libs/v1/dataParser/parsers/bigint/checkers/max.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/bigint/checkers/max.mjs
@@ -9,9 +9,9 @@ function checkerBigIntMax(max, definition = {}) {
...definition,
max,
},
- }, (value, error, self) => {
+ }, (value, error, self, dataParser) => {
if (value > self.definition.max) {
- return addIssue(error, `bigint <= ${self.definition.max}n`, value, self.definition.errorMessage);
+ return addIssue(error, `bigint <= ${self.definition.max}n`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage);
}
return value;
});
diff --git a/docs/public/libs/v1/dataParser/parsers/bigint/checkers/min.cjs b/docs/public/libs/v1/dataParser/parsers/bigint/checkers/min.cjs
index f27213b5..f2dddd22 100644
--- a/docs/public/libs/v1/dataParser/parsers/bigint/checkers/min.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/bigint/checkers/min.cjs
@@ -11,9 +11,9 @@ function checkerBigIntMin(min, definition = {}) {
...definition,
min,
},
- }, (value, error$1, self) => {
+ }, (value, error$1, self, dataParser) => {
if (value < self.definition.min) {
- return error.addIssue(error$1, `bigint >= ${self.definition.min}n`, value, self.definition.errorMessage);
+ return error.addIssue(error$1, `bigint >= ${self.definition.min}n`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage);
}
return value;
});
diff --git a/docs/public/libs/v1/dataParser/parsers/bigint/checkers/min.mjs b/docs/public/libs/v1/dataParser/parsers/bigint/checkers/min.mjs
index 51b816d8..3a3a7a44 100644
--- a/docs/public/libs/v1/dataParser/parsers/bigint/checkers/min.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/bigint/checkers/min.mjs
@@ -9,9 +9,9 @@ function checkerBigIntMin(min, definition = {}) {
...definition,
min,
},
- }, (value, error, self) => {
+ }, (value, error, self, dataParser) => {
if (value < self.definition.min) {
- return addIssue(error, `bigint >= ${self.definition.min}n`, value, self.definition.errorMessage);
+ return addIssue(error, `bigint >= ${self.definition.min}n`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage);
}
return value;
});
diff --git a/docs/public/libs/v1/dataParser/parsers/number/checkers/int.cjs b/docs/public/libs/v1/dataParser/parsers/number/checkers/int.cjs
index 5fa131ca..c832b55c 100644
--- a/docs/public/libs/v1/dataParser/parsers/number/checkers/int.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/number/checkers/int.cjs
@@ -9,11 +9,11 @@ const checkerIntKind = kind.createDataParserKind("checker-number-int");
function checkerInt(definition = {}) {
return base.dataParserCheckerInit(checkerIntKind, {
definition,
- }, (data, error$1, self) => {
+ }, (data, error$1, self, dataParser) => {
if (Number.isInteger(data)) {
return data;
}
- return error.addIssue(error$1, "integer", data, self.definition.errorMessage);
+ return error.addIssue(error$1, "integer", data, self.definition.errorMessage ?? dataParser.definition.errorMessage);
});
}
function int(definition) {
diff --git a/docs/public/libs/v1/dataParser/parsers/number/checkers/int.mjs b/docs/public/libs/v1/dataParser/parsers/number/checkers/int.mjs
index 2c7abaef..08a776a5 100644
--- a/docs/public/libs/v1/dataParser/parsers/number/checkers/int.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/number/checkers/int.mjs
@@ -7,11 +7,11 @@ const checkerIntKind = createDataParserKind("checker-number-int");
function checkerInt(definition = {}) {
return dataParserCheckerInit(checkerIntKind, {
definition,
- }, (data, error, self) => {
+ }, (data, error, self, dataParser) => {
if (Number.isInteger(data)) {
return data;
}
- return addIssue(error, "integer", data, self.definition.errorMessage);
+ return addIssue(error, "integer", data, self.definition.errorMessage ?? dataParser.definition.errorMessage);
});
}
function int(definition) {
diff --git a/docs/public/libs/v1/dataParser/parsers/number/checkers/max.cjs b/docs/public/libs/v1/dataParser/parsers/number/checkers/max.cjs
index 7d2455aa..fef70252 100644
--- a/docs/public/libs/v1/dataParser/parsers/number/checkers/max.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/number/checkers/max.cjs
@@ -11,9 +11,9 @@ function checkerNumberMax(max, definition = {}) {
...definition,
max,
},
- }, (value, error$1, self) => value <= self.definition.max
+ }, (value, error$1, self, dataParser) => value <= self.definition.max
? value
- : error.addIssue(error$1, `number <= ${self.definition.max}`, value, self.definition.errorMessage));
+ : error.addIssue(error$1, `number <= ${self.definition.max}`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
exports.checkerNumberMax = checkerNumberMax;
diff --git a/docs/public/libs/v1/dataParser/parsers/number/checkers/max.mjs b/docs/public/libs/v1/dataParser/parsers/number/checkers/max.mjs
index 6e908a90..67ee0bfd 100644
--- a/docs/public/libs/v1/dataParser/parsers/number/checkers/max.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/number/checkers/max.mjs
@@ -9,9 +9,9 @@ function checkerNumberMax(max, definition = {}) {
...definition,
max,
},
- }, (value, error, self) => value <= self.definition.max
+ }, (value, error, self, dataParser) => value <= self.definition.max
? value
- : addIssue(error, `number <= ${self.definition.max}`, value, self.definition.errorMessage));
+ : addIssue(error, `number <= ${self.definition.max}`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
export { checkerNumberMax, checkerNumberMaxKind };
diff --git a/docs/public/libs/v1/dataParser/parsers/number/checkers/min.cjs b/docs/public/libs/v1/dataParser/parsers/number/checkers/min.cjs
index 59058c68..c160ffa8 100644
--- a/docs/public/libs/v1/dataParser/parsers/number/checkers/min.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/number/checkers/min.cjs
@@ -11,9 +11,9 @@ function checkerNumberMin(min, definition = {}) {
...definition,
min,
},
- }, (value, error$1, self) => value >= self.definition.min
+ }, (value, error$1, self, dataParser) => value >= self.definition.min
? value
- : error.addIssue(error$1, `number >= ${self.definition.min}`, value, self.definition.errorMessage));
+ : error.addIssue(error$1, `number >= ${self.definition.min}`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
exports.checkerNumberMin = checkerNumberMin;
diff --git a/docs/public/libs/v1/dataParser/parsers/number/checkers/min.mjs b/docs/public/libs/v1/dataParser/parsers/number/checkers/min.mjs
index 11138be6..330ab008 100644
--- a/docs/public/libs/v1/dataParser/parsers/number/checkers/min.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/number/checkers/min.mjs
@@ -9,9 +9,9 @@ function checkerNumberMin(min, definition = {}) {
...definition,
min,
},
- }, (value, error, self) => value >= self.definition.min
+ }, (value, error, self, dataParser) => value >= self.definition.min
? value
- : addIssue(error, `number >= ${self.definition.min}`, value, self.definition.errorMessage));
+ : addIssue(error, `number >= ${self.definition.min}`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
export { checkerNumberMin, checkerNumberMinKind };
diff --git a/docs/public/libs/v1/dataParser/parsers/refine.cjs b/docs/public/libs/v1/dataParser/parsers/refine.cjs
index 4bf0161d..4adc336d 100644
--- a/docs/public/libs/v1/dataParser/parsers/refine.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/refine.cjs
@@ -11,9 +11,9 @@ function checkerRefine(theFunction, definition) {
...definition,
theFunction,
},
- }, (value, error$1, self) => self.definition.theFunction(value)
+ }, (value, error$1, self, dataParser) => self.definition.theFunction(value)
? value
- : error.addIssue(error$1, "value matching refine predicate", value, self.definition.errorMessage));
+ : error.addIssue(error$1, "value matching refine predicate", value, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
exports.checkerRefine = checkerRefine;
diff --git a/docs/public/libs/v1/dataParser/parsers/refine.mjs b/docs/public/libs/v1/dataParser/parsers/refine.mjs
index ecdc64ec..9df26766 100644
--- a/docs/public/libs/v1/dataParser/parsers/refine.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/refine.mjs
@@ -9,9 +9,9 @@ function checkerRefine(theFunction, definition) {
...definition,
theFunction,
},
- }, (value, error, self) => self.definition.theFunction(value)
+ }, (value, error, self, dataParser) => self.definition.theFunction(value)
? value
- : addIssue(error, "value matching refine predicate", value, self.definition.errorMessage));
+ : addIssue(error, "value matching refine predicate", value, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
export { checkerRefine, dataParserCheckerRefineKind };
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/email.cjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/email.cjs
index abfeec3e..95a1cafc 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/email.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/email.cjs
@@ -13,9 +13,9 @@ function checkerEmail(definition = {}) {
...definition,
regex: emailRegex,
},
- }, (data, error$1, self) => self.definition.regex.test(data)
+ }, (data, error$1, self, dataParser) => self.definition.regex.test(data)
? data
- : error.addIssue(error$1, "email", data, self.definition.errorMessage));
+ : error.addIssue(error$1, "email", data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
function email(definition) {
return index.string({
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/email.mjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/email.mjs
index 3b6a3cab..026c2c86 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/email.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/email.mjs
@@ -11,9 +11,9 @@ function checkerEmail(definition = {}) {
...definition,
regex: emailRegex,
},
- }, (data, error, self) => self.definition.regex.test(data)
+ }, (data, error, self, dataParser) => self.definition.regex.test(data)
? data
- : addIssue(error, "email", data, self.definition.errorMessage));
+ : addIssue(error, "email", data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
function email(definition) {
return string({
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/max.cjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/max.cjs
index aa59dac1..947e57da 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/max.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/max.cjs
@@ -11,9 +11,9 @@ function checkerStringMax(max, definition = {}) {
...definition,
max,
},
- }, (data, error$1, self) => data.length <= self.definition.max
+ }, (data, error$1, self, dataParser) => data.length <= self.definition.max
? data
- : error.addIssue(error$1, `string.length <= ${self.definition.max}`, data, self.definition.errorMessage));
+ : error.addIssue(error$1, `string.length <= ${self.definition.max}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
exports.checkerStringMax = checkerStringMax;
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/max.mjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/max.mjs
index c42e8992..80833edc 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/max.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/max.mjs
@@ -9,9 +9,9 @@ function checkerStringMax(max, definition = {}) {
...definition,
max,
},
- }, (data, error, self) => data.length <= self.definition.max
+ }, (data, error, self, dataParser) => data.length <= self.definition.max
? data
- : addIssue(error, `string.length <= ${self.definition.max}`, data, self.definition.errorMessage));
+ : addIssue(error, `string.length <= ${self.definition.max}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
export { checkerStringMax, checkerStringMaxKind };
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/min.cjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/min.cjs
index 46fb6460..0aceb3af 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/min.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/min.cjs
@@ -11,9 +11,9 @@ function checkerStringMin(min, definition = {}) {
...definition,
min,
},
- }, (data, error$1, self) => data.length >= self.definition.min
+ }, (data, error$1, self, dataParser) => data.length >= self.definition.min
? data
- : error.addIssue(error$1, `string.length >= ${self.definition.min}`, data, self.definition.errorMessage));
+ : error.addIssue(error$1, `string.length >= ${self.definition.min}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
exports.checkerStringMin = checkerStringMin;
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/min.mjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/min.mjs
index 2c31566a..0749d348 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/min.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/min.mjs
@@ -9,9 +9,9 @@ function checkerStringMin(min, definition = {}) {
...definition,
min,
},
- }, (data, error, self) => data.length >= self.definition.min
+ }, (data, error, self, dataParser) => data.length >= self.definition.min
? data
- : addIssue(error, `string.length >= ${self.definition.min}`, data, self.definition.errorMessage));
+ : addIssue(error, `string.length >= ${self.definition.min}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
export { checkerStringMin, checkerStringMinKind };
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/regex.cjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/regex.cjs
index 8ca92aef..129282c7 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/regex.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/regex.cjs
@@ -11,9 +11,9 @@ function checkerRegex(regex, definition = {}) {
...definition,
regex,
},
- }, (data, error$1, self) => self.definition.regex.test(data)
+ }, (data, error$1, self, dataParser) => self.definition.regex.test(data)
? data
- : error.addIssue(error$1, `string with pattern ${self.definition.regex.source.toString()}`, data, self.definition.errorMessage));
+ : error.addIssue(error$1, `string with pattern ${self.definition.regex.source.toString()}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
exports.checkerRegex = checkerRegex;
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/regex.mjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/regex.mjs
index e6fb9cfa..eb22bc62 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/regex.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/regex.mjs
@@ -9,9 +9,9 @@ function checkerRegex(regex, definition = {}) {
...definition,
regex,
},
- }, (data, error, self) => self.definition.regex.test(data)
+ }, (data, error, self, dataParser) => self.definition.regex.test(data)
? data
- : addIssue(error, `string with pattern ${self.definition.regex.source.toString()}`, data, self.definition.errorMessage));
+ : addIssue(error, `string with pattern ${self.definition.regex.source.toString()}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
export { checkerRegex, checkerRegexKind };
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/url.cjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/url.cjs
index b78c361e..1454c3a3 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/url.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/url.cjs
@@ -10,19 +10,19 @@ const regexRemoveDote = /:$/;
function checkerUrl(definition = {}) {
return base.dataParserCheckerInit(checkerUrlKind, {
definition: definition,
- }, (data, error$1, self) => {
+ }, (data, error$1, self, dataParser) => {
try {
const url = new URL(data);
if (self.definition.hostname) {
self.definition.hostname.lastIndex = 0;
if (!self.definition.hostname.test(url.hostname)) {
- return error.addIssue(error$1, `URL with hostname matching ${self.definition.hostname.source}`, data, self.definition.errorMessage);
+ return error.addIssue(error$1, `URL with hostname matching ${self.definition.hostname.source}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage);
}
}
if (self.definition.protocol) {
self.definition.protocol.lastIndex = 0;
if (!self.definition.protocol.test(url.protocol.replace(regexRemoveDote, ""))) {
- return error.addIssue(error$1, `URL with protocol matching ${self.definition.protocol.source}`, data, self.definition.errorMessage);
+ return error.addIssue(error$1, `URL with protocol matching ${self.definition.protocol.source}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage);
}
}
if (self.definition.normalize) {
@@ -33,7 +33,7 @@ function checkerUrl(definition = {}) {
}
}
catch {
- return error.addIssue(error$1, "valid URL", data, self.definition.errorMessage);
+ return error.addIssue(error$1, "valid URL", data, self.definition.errorMessage ?? dataParser.definition.errorMessage);
}
});
}
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/url.mjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/url.mjs
index 4f2d4b73..c0c1b187 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/url.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/url.mjs
@@ -8,19 +8,19 @@ const regexRemoveDote = /:$/;
function checkerUrl(definition = {}) {
return dataParserCheckerInit(checkerUrlKind, {
definition: definition,
- }, (data, error, self) => {
+ }, (data, error, self, dataParser) => {
try {
const url = new URL(data);
if (self.definition.hostname) {
self.definition.hostname.lastIndex = 0;
if (!self.definition.hostname.test(url.hostname)) {
- return addIssue(error, `URL with hostname matching ${self.definition.hostname.source}`, data, self.definition.errorMessage);
+ return addIssue(error, `URL with hostname matching ${self.definition.hostname.source}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage);
}
}
if (self.definition.protocol) {
self.definition.protocol.lastIndex = 0;
if (!self.definition.protocol.test(url.protocol.replace(regexRemoveDote, ""))) {
- return addIssue(error, `URL with protocol matching ${self.definition.protocol.source}`, data, self.definition.errorMessage);
+ return addIssue(error, `URL with protocol matching ${self.definition.protocol.source}`, data, self.definition.errorMessage ?? dataParser.definition.errorMessage);
}
}
if (self.definition.normalize) {
@@ -31,7 +31,7 @@ function checkerUrl(definition = {}) {
}
}
catch {
- return addIssue(error, "valid URL", data, self.definition.errorMessage);
+ return addIssue(error, "valid URL", data, self.definition.errorMessage ?? dataParser.definition.errorMessage);
}
});
}
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/uuid.cjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/uuid.cjs
index a3d89d03..a7995ec8 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/uuid.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/uuid.cjs
@@ -13,9 +13,9 @@ function checkerUuid(definition = {}) {
...definition,
regex: uuidRegex,
},
- }, (data, error$1, self) => uuidRegex.test(data)
+ }, (data, error$1, self, dataParser) => uuidRegex.test(data)
? data
- : error.addIssue(error$1, "uuid", data, self.definition.errorMessage));
+ : error.addIssue(error$1, "uuid", data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
/**
* {@include dataParser/classic/uuid/index.md}
diff --git a/docs/public/libs/v1/dataParser/parsers/string/checkers/uuid.mjs b/docs/public/libs/v1/dataParser/parsers/string/checkers/uuid.mjs
index e2db8be4..363698b7 100644
--- a/docs/public/libs/v1/dataParser/parsers/string/checkers/uuid.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/string/checkers/uuid.mjs
@@ -11,9 +11,9 @@ function checkerUuid(definition = {}) {
...definition,
regex: uuidRegex,
},
- }, (data, error, self) => uuidRegex.test(data)
+ }, (data, error, self, dataParser) => uuidRegex.test(data)
? data
- : addIssue(error, "uuid", data, self.definition.errorMessage));
+ : addIssue(error, "uuid", data, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
/**
* {@include dataParser/classic/uuid/index.md}
diff --git a/docs/public/libs/v1/dataParser/parsers/time/checkers/max.cjs b/docs/public/libs/v1/dataParser/parsers/time/checkers/max.cjs
index 3b97bf6d..cdbc7341 100644
--- a/docs/public/libs/v1/dataParser/parsers/time/checkers/max.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/time/checkers/max.cjs
@@ -15,9 +15,9 @@ function checkerTimeMax(max, definition = {}) {
...definition,
max,
},
- }, (value, error$1, self) => lessTime.lessTime(value, self.definition.max)
+ }, (value, error$1, self, dataParser) => lessTime.lessTime(value, self.definition.max)
? value
- : error.addIssue(error$1, `time <= ${self.definition.max.toString()}`, value, self.definition.errorMessage));
+ : error.addIssue(error$1, `time <= ${self.definition.max.toString()}`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
exports.checkerTimeMax = checkerTimeMax;
diff --git a/docs/public/libs/v1/dataParser/parsers/time/checkers/max.mjs b/docs/public/libs/v1/dataParser/parsers/time/checkers/max.mjs
index 4b4416b7..e921578e 100644
--- a/docs/public/libs/v1/dataParser/parsers/time/checkers/max.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/time/checkers/max.mjs
@@ -13,9 +13,9 @@ function checkerTimeMax(max, definition = {}) {
...definition,
max,
},
- }, (value, error, self) => lessTime(value, self.definition.max)
+ }, (value, error, self, dataParser) => lessTime(value, self.definition.max)
? value
- : addIssue(error, `time <= ${self.definition.max.toString()}`, value, self.definition.errorMessage));
+ : addIssue(error, `time <= ${self.definition.max.toString()}`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
export { checkerTimeMax, checkerTimeMaxKind };
diff --git a/docs/public/libs/v1/dataParser/parsers/time/checkers/min.cjs b/docs/public/libs/v1/dataParser/parsers/time/checkers/min.cjs
index 3e548c47..883755e0 100644
--- a/docs/public/libs/v1/dataParser/parsers/time/checkers/min.cjs
+++ b/docs/public/libs/v1/dataParser/parsers/time/checkers/min.cjs
@@ -15,9 +15,9 @@ function checkerTimeMin(min, definition = {}) {
...definition,
min,
},
- }, (value, error$1, self) => greaterTime.greaterTime(value, self.definition.min)
+ }, (value, error$1, self, dataParser) => greaterTime.greaterTime(value, self.definition.min)
? value
- : error.addIssue(error$1, `time >= ${self.definition.min.toString()}`, value, self.definition.errorMessage));
+ : error.addIssue(error$1, `time >= ${self.definition.min.toString()}`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
exports.checkerTimeMin = checkerTimeMin;
diff --git a/docs/public/libs/v1/dataParser/parsers/time/checkers/min.mjs b/docs/public/libs/v1/dataParser/parsers/time/checkers/min.mjs
index 71d0f7d2..a1a60335 100644
--- a/docs/public/libs/v1/dataParser/parsers/time/checkers/min.mjs
+++ b/docs/public/libs/v1/dataParser/parsers/time/checkers/min.mjs
@@ -13,9 +13,9 @@ function checkerTimeMin(min, definition = {}) {
...definition,
min,
},
- }, (value, error, self) => greaterTime(value, self.definition.min)
+ }, (value, error, self, dataParser) => greaterTime(value, self.definition.min)
? value
- : addIssue(error, `time >= ${self.definition.min.toString()}`, value, self.definition.errorMessage));
+ : addIssue(error, `time >= ${self.definition.min.toString()}`, value, self.definition.errorMessage ?? dataParser.definition.errorMessage));
}
export { checkerTimeMin, checkerTimeMinKind };
diff --git a/docs/public/libs/v1/date/createOrThrow.cjs b/docs/public/libs/v1/date/createOrThrow.cjs
index e53beb9b..8eaea183 100644
--- a/docs/public/libs/v1/date/createOrThrow.cjs
+++ b/docs/public/libs/v1/date/createOrThrow.cjs
@@ -1,10 +1,10 @@
'use strict';
-var create = require('./create.cjs');
var kind = require('../common/kind.cjs');
+var unwrap = require('../common/unwrap.cjs');
var errorKindNamespace = require('../common/errorKindNamespace.cjs');
+var create = require('./create.cjs');
var is = require('../either/left/is.cjs');
-var unwrap = require('../common/unwrap.cjs');
class CreateTheDateError extends kind.kindHeritage("create-the-date-error", errorKindNamespace.createErrorKind("create-the-date-error"), Error) {
input;
diff --git a/docs/public/libs/v1/date/createOrThrow.d.ts b/docs/public/libs/v1/date/createOrThrow.d.ts
index 83c45fc5..c701bff0 100644
--- a/docs/public/libs/v1/date/createOrThrow.d.ts
+++ b/docs/public/libs/v1/date/createOrThrow.d.ts
@@ -2,7 +2,7 @@ import type { SerializedTheDate, SpoolingDate } from "./types";
import type { TheDate } from "./theDate";
declare const CreateTheDateError_base: new (params: {
"@DuplojsUtilsError/create-the-date-error"?: unknown;
-}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("../common").Kind, unknown> & import("../common").Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => import("../common/kind").Kind, unknown> & import("../common/kind").Kind, unknown> & Error;
export declare class CreateTheDateError extends CreateTheDateError_base {
input: string | Date | number | SpoolingDate | TheDate;
constructor(input: string | Date | number | SpoolingDate | TheDate);
diff --git a/docs/public/libs/v1/date/createOrThrow.mjs b/docs/public/libs/v1/date/createOrThrow.mjs
index 3047659e..74b54de7 100644
--- a/docs/public/libs/v1/date/createOrThrow.mjs
+++ b/docs/public/libs/v1/date/createOrThrow.mjs
@@ -1,8 +1,8 @@
-import { create } from './create.mjs';
import { kindHeritage } from '../common/kind.mjs';
+import { unwrap } from '../common/unwrap.mjs';
import { createErrorKind } from '../common/errorKindNamespace.mjs';
+import { create } from './create.mjs';
import { isLeft } from '../either/left/is.mjs';
-import { unwrap } from '../common/unwrap.mjs';
class CreateTheDateError extends kindHeritage("create-the-date-error", createErrorKind("create-the-date-error"), Error) {
input;
diff --git a/docs/public/libs/v1/date/createTimeOrThrow.cjs b/docs/public/libs/v1/date/createTimeOrThrow.cjs
index dce20138..a2f806c4 100644
--- a/docs/public/libs/v1/date/createTimeOrThrow.cjs
+++ b/docs/public/libs/v1/date/createTimeOrThrow.cjs
@@ -2,9 +2,9 @@
var createTime = require('./createTime.cjs');
var kind = require('../common/kind.cjs');
+var errorKindNamespace = require('../common/errorKindNamespace.cjs');
var is = require('../either/left/is.cjs');
var unwrap = require('../common/unwrap.cjs');
-var errorKindNamespace = require('../common/errorKindNamespace.cjs');
class CreateTheTimeError extends kind.kindHeritage("create-the-time-error", errorKindNamespace.createErrorKind("create-the-time-error"), Error) {
input;
diff --git a/docs/public/libs/v1/date/createTimeOrThrow.d.ts b/docs/public/libs/v1/date/createTimeOrThrow.d.ts
index a424b59a..14b30280 100644
--- a/docs/public/libs/v1/date/createTimeOrThrow.d.ts
+++ b/docs/public/libs/v1/date/createTimeOrThrow.d.ts
@@ -2,7 +2,7 @@ import type { SerializedTheTime, SpoolingTime } from "./types";
import { type TheTime } from "./theTime";
declare const CreateTheTimeError_base: new (params: {
"@DuplojsUtilsError/create-the-time-error"?: unknown;
-}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("../common").Kind, unknown> & import("../common").Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("../common").Kind, unknown> & import("../common").Kind, unknown>;
export declare class CreateTheTimeError extends CreateTheTimeError_base {
input: TheTime | number | SpoolingTime | SerializedTheTime;
constructor(input: TheTime | number | SpoolingTime | SerializedTheTime);
diff --git a/docs/public/libs/v1/date/createTimeOrThrow.mjs b/docs/public/libs/v1/date/createTimeOrThrow.mjs
index 6a7b3901..36a63dca 100644
--- a/docs/public/libs/v1/date/createTimeOrThrow.mjs
+++ b/docs/public/libs/v1/date/createTimeOrThrow.mjs
@@ -1,8 +1,8 @@
import { createTime } from './createTime.mjs';
import { kindHeritage } from '../common/kind.mjs';
+import { createErrorKind } from '../common/errorKindNamespace.mjs';
import { isLeft } from '../either/left/is.mjs';
import { unwrap } from '../common/unwrap.mjs';
-import { createErrorKind } from '../common/errorKindNamespace.mjs';
class CreateTheTimeError extends kindHeritage("create-the-time-error", createErrorKind("create-the-time-error"), Error) {
input;
diff --git a/docs/public/libs/v1/date/theDate.d.ts b/docs/public/libs/v1/date/theDate.d.ts
index 70e266d0..d4e657d4 100644
--- a/docs/public/libs/v1/date/theDate.d.ts
+++ b/docs/public/libs/v1/date/theDate.d.ts
@@ -1,7 +1,7 @@
import type { SerializedTheDate } from "./types/serializedTheDate";
declare const TheDate_base: new (params: {
"@DuplojsUtilsDate/the-date"?: unknown;
-}, parentParams: readonly [value: string | number | Date]) => Date & import("../common/kind").Kind, unknown> & import("../common/kind").Kind, unknown>;
+}, parentParams: readonly [value: string | number | Date]) => import("../common/kind").Kind, unknown> & import("../common/kind").Kind, unknown> & Date;
/**
* Represents an immutable date-time object (`TheDate`) based on UTC.
*
diff --git a/docs/public/libs/v1/date/theTime.d.ts b/docs/public/libs/v1/date/theTime.d.ts
index 2ee349b2..d5d8a403 100644
--- a/docs/public/libs/v1/date/theTime.d.ts
+++ b/docs/public/libs/v1/date/theTime.d.ts
@@ -1,7 +1,7 @@
import type { SerializedTheTime } from "./types";
declare const TheTime_base: new (params?: {
"@DuplojsUtilsDate/the-time"?: unknown;
-} | undefined) => import("../common/kind").Kind, unknown> & import("../common/kind").Kind, unknown>;
+} | undefined) => import("../common/kind").Kind, unknown> & import("../common/kind").Kind, unknown>;
/**
* Represents an immutable signed time value object (`TheTime`) stored in milliseconds.
*
diff --git a/docs/public/libs/v1/flow/run.d.ts b/docs/public/libs/v1/flow/run.d.ts
index 84efc95c..5ce299bf 100644
--- a/docs/public/libs/v1/flow/run.d.ts
+++ b/docs/public/libs/v1/flow/run.d.ts
@@ -24,7 +24,7 @@ export interface FlowDetails = (GenericFlow extends TheFlow ? InferredFunction extends TheFlowFunction ? InferredGenerator extends TheFlowGenerator ? ((InferredEffect extends Exit ? InferredValue : InferredEffect extends Break ? InferredValue : InferredEffect extends Throttling ? InferredValue : InferredEffect extends Debounce ? InferredValue : never) | InferredOutput) extends infer InferredResult ? IsEqual extends true ? FlowDetails ? InferredName : never> : InferredResult : never : never : never : never) extends infer InferredResult ? ExtractFlowGenerator extends AsyncGenerator ? Promise : InferredResult : never;
declare const MissingDependenceError_base: new (params: {
"@DuplojsUtilsFlow/missing-dependence-error"?: unknown;
-}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("../common").Kind, unknown> & import("../common").Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("../common").Kind, unknown> & import("../common").Kind, unknown>;
export declare class MissingDependenceError extends MissingDependenceError_base {
dependenceHandler: DependenceHandler;
constructor(dependenceHandler: DependenceHandler);
diff --git a/docs/public/libs/v1/metadata.json b/docs/public/libs/v1/metadata.json
index dcde8a5f..03d0aef3 100644
--- a/docs/public/libs/v1/metadata.json
+++ b/docs/public/libs/v1/metadata.json
@@ -251,6 +251,15 @@
{
"name": "findAndReplace.mjs"
},
+ {
+ "name": "findDuplicates.cjs"
+ },
+ {
+ "name": "findDuplicates.d.ts"
+ },
+ {
+ "name": "findDuplicates.mjs"
+ },
{
"name": "findIndex.cjs"
},
diff --git a/docs/public/libs/v1/pattern/match/builder.d.ts b/docs/public/libs/v1/pattern/match/builder.d.ts
index 9e9a9c76..33d6bce0 100644
--- a/docs/public/libs/v1/pattern/match/builder.d.ts
+++ b/docs/public/libs/v1/pattern/match/builder.d.ts
@@ -23,7 +23,7 @@ export interface MatchBuilder Error & import("../../common").Kind, unknown> & import("../../common").Kind, unknown>;
+}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("../../common").Kind, unknown> & import("../../common").Kind, unknown>;
export declare class InvalidExhaustivePatternError extends InvalidExhaustivePatternError_base {
input: unknown;
constructor(input: unknown);
diff --git a/jsDoc/array/findDuplicates/example.ts b/jsDoc/array/findDuplicates/example.ts
new file mode 100644
index 00000000..e8a8a546
--- /dev/null
+++ b/jsDoc/array/findDuplicates/example.ts
@@ -0,0 +1,25 @@
+import { A, DDate, pipe, type ExpectType } from "@scripts";
+
+const primitiveDuplicates = A.findDuplicates(["apple", "banana", "apple", "banana", "pear"]);
+// primitiveDuplicates: ["apple", "banana"]
+
+const dateValue = DDate.create("2024-01-01");
+const timeValue = DDate.createTime(90, "minute");
+const dateAndTimeDuplicates = A.findDuplicates([
+ dateValue,
+ DDate.create("2024-01-01"),
+ timeValue,
+ DDate.createTime(90, "minute"),
+]);
+// dateAndTimeDuplicates: [dateValue, timeValue]
+
+const pipedDuplicates = pipe(
+ [true, false, true, false],
+ A.findDuplicates,
+);
+
+type check = ExpectType<
+ typeof pipedDuplicates,
+ undefined | readonly [boolean, ...boolean[]],
+ "strict"
+>;
diff --git a/jsDoc/array/findDuplicates/index.md b/jsDoc/array/findDuplicates/index.md
new file mode 100644
index 00000000..ed3a620b
--- /dev/null
+++ b/jsDoc/array/findDuplicates/index.md
@@ -0,0 +1,21 @@
+Finds duplicated values in an array and returns each duplicated value once.
+
+**Supported call styles:**
+- Classic: `findDuplicates(array)` → returns duplicates or `undefined`
+
+Accepts primitive values plus `TheDate` and `TheTime` values from the date namespace.
+For date/time values, duplicates are matched by serialized value.
+
+```ts
+{@include array/findDuplicates/example.ts[3,24]}
+```
+
+@remarks
+- Returns `undefined` when no duplicates are found
+- Keeps one occurrence per duplicated value in the result
+
+@see [`A.includes`](https://utils.duplojs.dev/en/v1/api/array/includes) For checking a single value presence
+@see [`A.group`](https://utils.duplojs.dev/en/v1/api/array/group) For grouping values by key
+@see https://utils.duplojs.dev/en/v1/api/array/findDuplicates
+
+@namespace A
diff --git a/scripts/array/findDuplicates.ts b/scripts/array/findDuplicates.ts
new file mode 100644
index 00000000..736b2dcc
--- /dev/null
+++ b/scripts/array/findDuplicates.ts
@@ -0,0 +1,66 @@
+/* eslint-disable @typescript-eslint/prefer-for-of */
+import { type AnyTuple } from "@scripts/common";
+import * as DDate from "@scripts/date";
+
+export type EligibleDuplicateElement = (
+ | string
+ | boolean
+ | null
+ | number
+ | bigint
+ | undefined
+ | DDate.TheDate
+ | DDate.TheTime
+);
+
+export function findDuplicates<
+ GenericInput extends readonly EligibleDuplicateElement[],
+>(array: GenericInput): undefined | AnyTuple;
+
+export function findDuplicates(array: EligibleDuplicateElement[]): any {
+ const store = new Map<
+ EligibleDuplicateElement,
+ number
+ >();
+ let storeTimeObject: (
+ | undefined
+ | Map<
+ DDate.SerializedTheDate | DDate.SerializedTheTime,
+ DDate.TheDate | DDate.TheTime
+ >
+ ) = undefined;
+ let result: undefined | any[] = undefined;
+
+ for (let index = 0; index < array.length; index++) {
+ const element = array[index];
+
+ if (DDate.is(element) || DDate.isTime(element)) {
+ storeTimeObject ??= new Map();
+
+ const serializedValue = element.toJSON();
+ const storedElement = storeTimeObject.get(serializedValue) ?? element;
+ const storedCount = store.get(storedElement);
+
+ if (storedCount === 1) {
+ result ??= [];
+ result.push(storedElement);
+ }
+
+ store.set(storedElement, (storedCount ?? 0) + 1);
+ if (storedElement === element) {
+ storeTimeObject.set(serializedValue, element);
+ }
+ } else {
+ const storedCount = store.get(element);
+
+ if (storedCount === 1) {
+ result ??= [];
+ result.push(element);
+ }
+
+ store.set(element, (storedCount ?? 0) + 1);
+ }
+ }
+
+ return result;
+}
diff --git a/scripts/array/index.ts b/scripts/array/index.ts
index ebd80256..dff17cbe 100644
--- a/scripts/array/index.ts
+++ b/scripts/array/index.ts
@@ -52,3 +52,4 @@ export * from "./isLastIndex";
export * from "./select";
export * from "./lengthEqual";
export * from "./mapTuple";
+export * from "./findDuplicates";
diff --git a/scripts/common/createKindIdentifier.ts b/scripts/common/createKindIdentifier.ts
index da24bd27..f65cd370 100644
--- a/scripts/common/createKindIdentifier.ts
+++ b/scripts/common/createKindIdentifier.ts
@@ -1,6 +1,6 @@
import { type GetKindHandler, type Kind, type KindDefinition, type KindHandler } from "./kind";
import { type UnionContain, type UnionToIntersection } from "./types";
-import * as DArray from "@scripts/array";
+import { coalescing } from "@scripts/array/coalescing";
export function createKindIdentifier<
GenericParent extends Kind,
@@ -81,7 +81,7 @@ export function createKindIdentifier<
const [input, kind] = args;
- const formattedKind = DArray.coalescing(kind);
+ const formattedKind = coalescing(kind);
for (const kind of formattedKind) {
if (!kind.has(input)) {
diff --git a/scripts/common/instanceOf.ts b/scripts/common/instanceOf.ts
index 828ec6db..af2b415f 100644
--- a/scripts/common/instanceOf.ts
+++ b/scripts/common/instanceOf.ts
@@ -1,4 +1,4 @@
-import * as DArray from "@scripts/array";
+import { coalescing } from "@scripts/array/coalescing";
import { type AnyConstructor } from "./types";
/**
@@ -37,7 +37,7 @@ export function instanceOf(
const [input, constructor] = args;
- const formattedConstructor = DArray.coalescing(constructor);
+ const formattedConstructor = coalescing(constructor);
for (const constructor of formattedConstructor) {
if (input instanceof constructor) {
diff --git a/scripts/common/toRegExp.ts b/scripts/common/toRegExp.ts
index 59c347cd..552f7045 100644
--- a/scripts/common/toRegExp.ts
+++ b/scripts/common/toRegExp.ts
@@ -1,6 +1,5 @@
import type { AnyTuple } from "./types";
import { escapeRegExp } from "./escapeRegExp";
-import * as DArray from "@scripts/array";
/**
* {@include common/toRegExp/index.md}
@@ -10,7 +9,7 @@ export function toRegExp(input: string | AnyTuple | RegExp): RegExp {
return new RegExp(`^${escapeRegExp(input)}$`);
}
- if (DArray.is(input)) {
+ if (input instanceof Array) {
const result = input.map(escapeRegExp).join("|");
return new RegExp(`^(?:${result})$`);
diff --git a/scripts/date/createOrThrow.ts b/scripts/date/createOrThrow.ts
index 90b5043e..71343a2f 100644
--- a/scripts/date/createOrThrow.ts
+++ b/scripts/date/createOrThrow.ts
@@ -1,4 +1,6 @@
-import { createErrorKind, kindHeritage, unwrap } from "@scripts/common";
+import { kindHeritage } from "@scripts/common/kind";
+import { unwrap } from "@scripts/common/unwrap";
+import { createErrorKind } from "@scripts/common/errorKindNamespace";
import { create } from "./create";
import type { SerializedTheDate, SpoolingDate } from "./types";
import * as DEither from "@scripts/either";
diff --git a/tests/array/findDuplicates.test.ts b/tests/array/findDuplicates.test.ts
new file mode 100644
index 00000000..a1d59738
--- /dev/null
+++ b/tests/array/findDuplicates.test.ts
@@ -0,0 +1,70 @@
+import { type AnyTuple, DArray, type ExpectType, pipe, DDate } from "@scripts";
+
+describe("findDuplicates", () => {
+ it("returns undefined when array has no duplicates", () => {
+ const result = DArray.findDuplicates(["a", 1, true, null, undefined]);
+
+ expect(result).toBeUndefined();
+
+ type check = ExpectType<
+ typeof result,
+ undefined | AnyTuple,
+ "strict"
+ >;
+ });
+
+ it("returns each duplicated primitive only once", () => {
+ const result = DArray.findDuplicates(["a", "b", "a", "a", "b", 1, 1, 1]);
+
+ expect(result).toStrictEqual(["a", "b", 1]);
+
+ type check = ExpectType<
+ typeof result,
+ undefined | readonly [string | number, ...(string | number)[]],
+ "strict"
+ >;
+ });
+
+ it("handles nullish and bigint duplicates", () => {
+ const result = DArray.findDuplicates([undefined, null, 1n, undefined, 1n, null, 1n]);
+
+ expect(result).toStrictEqual([undefined, 1n, null]);
+ });
+
+ it("works in pipe", () => {
+ const result = pipe(
+ [true, false, true, false, false],
+ DArray.findDuplicates,
+ );
+
+ expect(result).toStrictEqual([true, false]);
+
+ type check = ExpectType<
+ typeof result,
+ undefined | readonly [boolean, ...boolean[]],
+ "strict"
+ >;
+ });
+
+ it("returns only one duplicate for TheDate values sharing same serialized value", () => {
+ const dateA = DDate.create("2024-01-01");
+ const dateB = DDate.create("2024-01-01");
+ const dateC = DDate.create("2024-01-01");
+
+ const result = DArray.findDuplicates([dateA, dateB, dateC]);
+
+ expect(result).toStrictEqual([dateA]);
+ expect(result?.[0]).toBe(dateA);
+ });
+
+ it("returns only one duplicate for TheTime values sharing same serialized value", () => {
+ const timeA = DDate.createTime(5, "minute");
+ const timeB = DDate.createTime(5, "minute");
+ const timeC = DDate.createTime(5, "minute");
+
+ const result = DArray.findDuplicates([timeA, timeB, timeC]);
+
+ expect(result).toStrictEqual([timeA]);
+ expect(result?.[0]).toBe(timeA);
+ });
+});