Skip to content
Open
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
4 changes: 1 addition & 3 deletions scripts/common/types/neverCoalescing.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { type IsEqual } from "./isEqual";

export type NeverCoalescing<
GenericValue extends unknown,
GenericCoalescingValue extends unknown,
> = IsEqual<GenericValue, never> extends true
> = [GenericValue] extends [never]
? GenericCoalescingValue
: GenericValue;
22 changes: 14 additions & 8 deletions scripts/dataParser/parsers/array/checkers/max.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@ import { createDataParserKind } from "../../../kind";
import { DataParserCheckerBase, type DataParserCheckerDefinition } from "../../../baseChecker";
import { type DataParser } from "../../../base";

export interface DataParserCheckerDefinitionArrayMax extends DataParserCheckerDefinition {
max: number;
export interface DataParserCheckerDefinitionArrayMax<
GenericMax extends number = number,
> extends DataParserCheckerDefinition {
max: GenericMax;
}

export const checkerArrayMaxKind = createDataParserKind("checker-array-max");

export class DataParserCheckerArrayMax extends DataParserCheckerBase.init(
checkerArrayMaxKind,
)<
DataParserCheckerDefinitionArrayMax,
export class DataParserCheckerArrayMax<
GenericMax extends number = number,
> extends DataParserCheckerBase.init(
checkerArrayMaxKind,
)<
DataParserCheckerDefinitionArrayMax<GenericMax>,
unknown[]
> {
public get classConstructor() {
Expand All @@ -40,8 +44,10 @@ export class DataParserCheckerArrayMax extends DataParserCheckerBase.init(
);
}

public static override create(
max: number,
public static override create<
GenericMax extends number,
>(
max: GenericMax,
definition: Partial<
Omit<DataParserCheckerDefinitionArrayMax, "max">
> = {},
Expand Down
24 changes: 15 additions & 9 deletions scripts/dataParser/parsers/array/checkers/min.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { detachObjectMethod } from "@scripts/common";
import { detachObjectMethod, NeverCoalescing, type SimplifyTopLevel } from "@scripts/common";
import { addIssue, type DataParserError } from "@scripts/dataParser/error";
import { createDataParserKind } from "../../../kind";
import { DataParserCheckerBase, type DataParserCheckerDefinition } from "../../../baseChecker";
import { type DataParser } from "../../../base";

export interface DataParserCheckerDefinitionArrayMin extends DataParserCheckerDefinition {
min: number;
export interface DataParserCheckerDefinitionArrayMin<
GenericMin extends number = number,
> extends DataParserCheckerDefinition {
min: GenericMin;
}

export const checkerArrayMinKind = createDataParserKind("checker-array-min");

export class DataParserCheckerArrayMin extends DataParserCheckerBase.init(
checkerArrayMinKind,
)<
DataParserCheckerDefinitionArrayMin,
export class DataParserCheckerArrayMin<
GenericMin extends number = number,
> extends DataParserCheckerBase.init(
checkerArrayMinKind,
)<
DataParserCheckerDefinitionArrayMin<GenericMin>,
unknown[]
> {
public get classConstructor() {
Expand All @@ -40,8 +44,10 @@ export class DataParserCheckerArrayMin extends DataParserCheckerBase.init(
);
}

public static override create(
min: number,
public static override create<
GenericMin extends number,
>(
min: GenericMin,
definition: Partial<
Omit<DataParserCheckerDefinitionArrayMin, "min">
> = {},
Expand Down
7 changes: 5 additions & 2 deletions scripts/dataParser/parsers/array/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createDataParserKind } from "@scripts/dataParser/kind";
import { DataParserBase, type DataParser, type DataParserDefinition } from "../../base";
import { addIssue, popErrorPath, setErrorPath, type DataParserError, SymbolDataParserError } from "@scripts/dataParser/error";
import { type DataParserChecker } from "../../baseChecker";
import { type AddCheckersToDefinition, type GetEligibleChecker, type Input, type MergeDefinition, type Output, type PrepareDataParserDefinition } from "../../types";
import { type ApplyRefinementOfChecker, type AddCheckersToDefinition, type GetEligibleChecker, type Input, type MergeDefinition, type Output, type PrepareDataParserDefinition } from "../../types";

export * from "./checkers";

Expand All @@ -27,7 +27,10 @@ export class DataParserArray<
arrayKind,
)<
GenericDefinition,
Output<GenericDefinition["element"]>[],
ApplyRefinementOfChecker<
Output<GenericDefinition["element"]>[],
GenericDefinition
>,
Input<GenericDefinition["element"]>[]
> {
public get classConstructor() {
Expand Down
53 changes: 40 additions & 13 deletions scripts/dataParser/parsers/refine.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { detachObjectMethod, callThen, type NeverCoalescing, type SimplifyTopLevel, type MaybePromise } from "@scripts/common";
import { detachObjectMethod, callThen, type NeverCoalescing, type SimplifyTopLevel, type MaybePromise, type AnyFunction } from "@scripts/common";
import { DataParserCheckerBase, type DataParserCheckerDefinition } from "../baseChecker";
import { type DataParser } from "../base";
import { addIssue, type DataParserError } from "@scripts/dataParser/error";
Expand Down Expand Up @@ -54,6 +54,28 @@ export class DataParserCheckerRefine<
);
}

public static override create<
GenericInput extends unknown,
GenericPredicate extends GenericInput,
const GenericDefinition extends Partial<
Omit<DataParserCheckerDefinitionRefine, "theFunction">
> = never,
>(
theFunction: (input: GenericInput) => input is GenericPredicate,
definition?: GenericDefinition,
): DataParserCheckerRefine<
SimplifyTopLevel<
& NeverCoalescing<
GenericDefinition,
DataParserCheckerDefinitionRefine<GenericInput>
>
& {
theFunction(input: GenericInput): input is GenericPredicate;
}
>,
GenericInput
>;

public static override create<
GenericInput extends unknown,
const GenericDefinition extends Partial<
Expand All @@ -63,21 +85,26 @@ export class DataParserCheckerRefine<
theFunction: (input: GenericInput) => MaybePromise<boolean>,
definition?: GenericDefinition,
): DataParserCheckerRefine<
SimplifyTopLevel<
& NeverCoalescing<
GenericDefinition,
DataParserCheckerDefinitionRefine<GenericInput>
>
& {
theFunction(input: GenericInput): MaybePromise<boolean>;
}
>,
GenericInput
> {
SimplifyTopLevel<
& NeverCoalescing<
GenericDefinition,
DataParserCheckerDefinitionRefine<GenericInput>
>
& {
theFunction(input: GenericInput): MaybePromise<boolean>;
}
>,
GenericInput
>;

public static override create(
theFunction: AnyFunction,
definition?: Partial<DataParserCheckerDefinitionRefine>,
) {
return new DataParserCheckerRefine({
...definition,
theFunction,
}) as never;
});
}
}

Expand Down
7 changes: 5 additions & 2 deletions scripts/dataParser/parsers/string/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createDataParserKind } from "@scripts/dataParser/kind";
import { DataParserBase, type DataParserDefinition } from "../../base";
import { addIssue, type DataParserError, type SymbolDataParserError } from "@scripts/dataParser/error";
import { type DataParserChecker } from "../../baseChecker";
import { type GetEligibleChecker, type AddCheckersToDefinition, type MergeDefinition, type Output, type PrepareDataParserDefinition } from "../../types";
import { type GetEligibleChecker, type AddCheckersToDefinition, type MergeDefinition, type Output, type PrepareDataParserDefinition, type ApplyRefinementOfChecker } from "../../types";

export * from "./checkers";

Expand All @@ -23,7 +23,10 @@ export class DataParserString<
stringKind,
)<
GenericDefinition,
string,
ApplyRefinementOfChecker<
string,
GenericDefinition
>,
string
> {
public get classConstructor() {
Expand Down
56 changes: 53 additions & 3 deletions scripts/dataParser/types/checkers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { type IsExtends } from "@scripts/common";
import { type NeverCoalescing, type UnionToIntersection, type AnyPredicate, type IsExtends } from "@scripts/common";
import { type DataParserChecker } from "../baseChecker";
import type * as AllDataParser from "../parsers";
import { type TheTime } from "@scripts/date";
import type * as DDate from "@scripts/date";
import type * as DArray from "@scripts/array";
import { type DataParserDefinition } from "../base";

export interface CheckerCustom {
base: DataParserChecker;
Expand Down Expand Up @@ -65,7 +67,7 @@ export interface EligibleChecker<
| AllDataParser.DataParserCheckerUuid
)
: never;
time: IsExtends<GenericValue, TheTime> extends true
time: IsExtends<GenericValue, DDate.TheTime> extends true
? (
| AllDataParser.DataParserCheckerTimeMax
| AllDataParser.DataParserCheckerTimeMin
Expand All @@ -83,3 +85,51 @@ export type GetEligibleChecker<
>
>
: never;

export interface RefinementOfChecker<
GenericValue extends unknown,
GenericChecker extends DataParserChecker,
> {
refine: GenericChecker extends AllDataParser.DataParserCheckerRefine
? GenericChecker["definition"]["theFunction"] extends AnyPredicate<any, any[], infer InferredPredicate>
? InferredPredicate
: never
: never;

arrayMin: GenericChecker extends AllDataParser.DataParserCheckerArrayMin
? number extends GenericChecker["definition"]["min"]
? never
: GenericValue extends readonly unknown[]
? [
...DArray.CreateTuple<GenericValue[number], GenericChecker["definition"]["min"]>,
...GenericValue[number][],
]
: never
: never;
arrayMax: GenericChecker extends AllDataParser.DataParserCheckerArrayMax
? number extends GenericChecker["definition"]["max"]
? never
: GenericValue & DArray.MaxElements<GenericChecker["definition"]["max"]>
: never;
}

export type ApplyRefinementOfChecker<
GenericValue extends unknown,
GenericDataParserDefinition extends DataParserDefinition,
> = GenericDataParserDefinition["checkers"][number] extends infer inferredChecker extends DataParserChecker
? NeverCoalescing<
UnionToIntersection<
inferredChecker extends any
? RefinementOfChecker<GenericValue, inferredChecker> extends infer InferredResult
? InferredResult[keyof InferredResult]
: never
: never
> extends infer InferredResult extends GenericValue
? (
& InferredResult
& GenericValue
)
: never,
GenericValue
>
: never;
8 changes: 7 additions & 1 deletion tests/dataParser/parsers/array/checkers/max.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DDataParser, DEither } from "@scripts";
import { type DArray, DDataParser, DEither, type ExpectType } from "@scripts";

describe("DDataParser array checker max", () => {
it("accepts arrays at or below maximum length", () => {
Expand All @@ -12,6 +12,12 @@ describe("DDataParser array checker max", () => {
},
);

type check = ExpectType<
DDataParser.Output<typeof schema>,
string[] & DArray.MaxElements<3>,
"strict"
>;

expect(schema.parse(["a", "b"])).toStrictEqual(DEither.success(["a", "b"]));
expect(schema.parse(["one", "two", "three"])).toStrictEqual(
DEither.success(["one", "two", "three"]),
Expand Down
8 changes: 7 additions & 1 deletion tests/dataParser/parsers/array/checkers/min.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DDataParser, DEither } from "@scripts";
import { DDataParser, DEither, type ExpectType } from "@scripts";

describe("DDataParser array checker min", () => {
it("accepts arrays at or above minimum length", () => {
Expand All @@ -12,6 +12,12 @@ describe("DDataParser array checker min", () => {
},
);

type check = ExpectType<
DDataParser.Output<typeof schema>,
[string, string, ...string[]] & string[],
"strict"
>;

expect(schema.parse(["a", "b"])).toStrictEqual(DEither.success(["a", "b"]));
expect(schema.parse(["one", "two", "three"])).toStrictEqual(
DEither.success(["one", "two", "three"]),
Expand Down
25 changes: 23 additions & 2 deletions tests/dataParser/parsers/array/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DDataParser, DEither, type ExpectType } from "@scripts";
import { DArray, DDataParser, DEither, type ExpectType } from "@scripts";

describe("DDataParser array", () => {
it("create data parser with checker", () => {
Expand All @@ -20,7 +20,28 @@ describe("DDataParser array", () => {
}),
);

void dataParser;
type _CheckOut = ExpectType<
DDataParser.Output<typeof dataParser>,
string[],
"strict"
>;
});

it("create data parser with refine predicate checker", () => {
const dataParser = DDataParser.array(DDataParser.string(), {
checkers: [DDataParser.checkerRefine(DArray.maxElements(10))],
}).addChecker(
DDataParser.checkerRefine((value) => {
type check = ExpectType<typeof value, string[] & DArray.MaxElements<10>, "strict">;
return true;
}),
);

type _CheckOut = ExpectType<
DDataParser.Output<typeof dataParser>,
string[] & DArray.MaxElements<10>,
"strict"
>;
});

it("success parsing", () => {
Expand Down
25 changes: 23 additions & 2 deletions tests/dataParser/parsers/string/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DDataParser, DEither, type ExpectType } from "@scripts";
import { DDataParser, DEither, DString, type ExpectType } from "@scripts";

describe("DDataParser string", () => {
it("create data parser with checker", () => {
Expand All @@ -16,7 +16,28 @@ describe("DDataParser string", () => {
}),
);

void dataParser;
type _CheckOut = ExpectType<
DDataParser.Output<typeof dataParser>,
string,
"strict"
>;
});

it("create data parser with refine predicate checker", () => {
const dataParser = DDataParser.string({
checkers: [DDataParser.checkerRefine(DString.startsWith("test"))],
}).addChecker(
DDataParser.checkerRefine((value) => {
type check = ExpectType<typeof value, `test${string}`, "strict">;
return true;
}),
);

type _CheckOut = ExpectType<
DDataParser.Output<typeof dataParser>,
`test${string}`,
"strict"
>;
});

it("succes parsing", () => {
Expand Down
Loading