Skip to content
Draft
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
8,717 changes: 4,021 additions & 4,696 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/Resolved.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import { ValueOf } from "./typings/ValueOf";
*
* Before | After
* ------------------------|---------------------------------------- `Boolean` |
* `boolean` `Number` | `number` `BigInt` | `bigint` `String` | `string` `Class`
* `boolean` `Number` | `number` `BigInt` | `bigint` `String` | `string`
* `Class`
*
* | `interface` Native Class or Others | No change
*
* @author Jeongho Nam - https://github.com/samchon
Expand Down
6 changes: 3 additions & 3 deletions src/TypeGuardError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export namespace TypeGuardError {
* The name of the typia method that threw the error.
*
* @example
* typia.assert, "typia.assertEquals";
* (typia.assert, "typia.assertEquals");
*/
method: string;

Expand All @@ -179,15 +179,15 @@ export namespace TypeGuardError {
* (optional).
*
* @example
* input.age, "input.profile.email";
* (input.age, "input.profile.email");
*/
path?: undefined | string;

/**
* String representation of the expected type at the error location.
*
* @example
* string, "number & ExclusiveMinimum<19>";
* (string, "number & ExclusiveMinimum<19>");
*/
expected: string;

Expand Down
76 changes: 76 additions & 0 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,55 @@ export function is(): never {
NoTransformConfigurationError("is");
}

/**
* Tests a value type with limited depth checking.
*
* Tests a parametric value type and returns whether it's following the type `T`
* or not, but only checks up to a specified depth. This is useful for
* discriminated unions where you only need to check a few properties to
* determine the type.
*
* If the parametric value matches the type `T` at the specified depth level,
* `true` value will be returned. Otherwise, `false` value will be returned.
*
* When `maxDepth` is not specified, defaults to 2 levels of checking.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Type of the input value
* @param input A value to be tested
* @param maxDepth Maximum depth to check (default: 2)
* @returns Whether the parametric value is following the type `T` at the
* specified depth
*/
export function isShallow<T>(input: T, maxDepth?: number): input is T;

/**
* Tests a value type with limited depth checking.
*
* Tests a parametric value type and returns whether it's following the type `T`
* or not, but only checks up to a specified depth. This is useful for
* discriminated unions where you only need to check a few properties to
* determine the type.
*
* If the parametric value matches the type `T` at the specified depth level,
* `true` value will be returned. Otherwise, `false` value will be returned.
*
* When `maxDepth` is not specified, defaults to 2 levels of checking.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Type of the input value
* @param input A value to be tested
* @param maxDepth Maximum depth to check (default: 2)
* @returns Whether the parametric value is following the type `T` at the
* specified depth
*/
export function isShallow<T>(input: unknown, maxDepth?: number): input is T;

/** @internal */
export function isShallow(): never {
NoTransformConfigurationError("isShallow");
}

/**
* Validates a value type.
*
Expand Down Expand Up @@ -690,6 +739,33 @@ export function createIs<T>(): (input: unknown) => input is T {
NoTransformConfigurationError("createIs");
}

/**
* Creates a reusable {@link isShallow} function.
*
* @author Jeongho Nam - https://github.com/samchon
* @returns Nothing until you configure the generic argument `T`
* @throws Compile error
* @danger You must configure the generic argument `T`
*/
export function createIsShallow(maxDepth?: number): never;

/**
* Creates a reusable {@link isShallow} function.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Type of the input value
* @param maxDepth Maximum depth to check (default: 2)
* @returns A reusable `isShallow` function
*/
export function createIsShallow<T>(
maxDepth?: number,
): (input: unknown) => input is T;

/** @internal */
export function createIsShallow<T>(): (input: unknown) => input is T {
NoTransformConfigurationError("createIsShallow");
}

/**
* Creates a reusable {@link validate} function.
*
Expand Down
45 changes: 31 additions & 14 deletions src/programmers/CheckerProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export namespace CheckerProgrammer {
trace: boolean;
equals: boolean;
numeric: boolean;
maxDepth?: number;
addition?: () => ts.Statement[];
decoder?: (props: {
metadata: Metadata;
Expand Down Expand Up @@ -417,6 +418,14 @@ export namespace CheckerProgrammer {
}): ts.Expression => {
if (props.metadata.any) return props.config.success;

// Check if max depth is reached
if (
props.explore.maxDepth !== undefined &&
props.explore.depth !== undefined &&
props.explore.depth >= props.explore.maxDepth
)
return props.config.success;

const top: IBinary[] = [];
const binaries: IBinary[] = [];
const add = (next: {
Expand Down Expand Up @@ -671,10 +680,10 @@ export namespace CheckerProgrammer {
functor: props.functor,
sets: props.metadata.sets,
input: props.input,
explore: {
explore: incrementDepth({
...props.explore,
from: "array",
},
}),
}),
);
}
Expand Down Expand Up @@ -702,10 +711,10 @@ export namespace CheckerProgrammer {
functor: props.functor,
maps: props.metadata.maps,
input: props.input,
explore: {
explore: incrementDepth({
...props.explore,
from: "array",
},
}),
}),
);
}
Expand Down Expand Up @@ -740,10 +749,10 @@ export namespace CheckerProgrammer {
functor: props.functor,
tuple: props.metadata.tuples[0]!,
input: props.input,
explore: {
explore: incrementDepth({
...props.explore,
from: "array",
},
}),
}),
);
// TUPLE ONLY
Expand All @@ -755,10 +764,10 @@ export namespace CheckerProgrammer {
functor: props.functor,
tuples: props.metadata.tuples,
input: props.input,
explore: {
explore: incrementDepth({
...props.explore,
from: "array",
},
}),
}),
);
else if (props.metadata.arrays.some((elem) => elem.type.value.any))
Expand All @@ -773,10 +782,10 @@ export namespace CheckerProgrammer {
functor: props.functor,
array: props.metadata.arrays[0]!,
input: props.input,
explore: {
explore: incrementDepth({
...props.explore,
from: "array",
},
}),
}),
);
else
Expand All @@ -787,10 +796,10 @@ export namespace CheckerProgrammer {
functor: props.functor,
arrays: props.metadata.arrays,
input: props.input,
explore: {
explore: incrementDepth({
...props.explore,
from: "array",
},
}),
}),
);
else
Expand Down Expand Up @@ -826,10 +835,10 @@ export namespace CheckerProgrammer {
functor: props.functor,
metadata: props.metadata,
input: props.input,
explore: {
explore: incrementDepth({
...props.explore,
from: "object",
},
}),
}),
});

Expand Down Expand Up @@ -1600,6 +1609,14 @@ export namespace CheckerProgrammer {
);
}

const incrementDepth = (
explore: CheckerProgrammer.IExplore,
): CheckerProgrammer.IExplore => ({
...explore,
depth:
explore.maxDepth !== undefined ? (explore.depth ?? 0) + 1 : explore.depth,
});

const create_add = (props: {
binaries: CheckerProgrammer.IBinary[];
default: ts.Expression;
Expand Down
7 changes: 7 additions & 0 deletions src/programmers/FeatureProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export namespace FeatureProgrammer {
/** Whether to trace exception or not. */
trace: boolean;

/** Maximum depth for shallow checks. */
maxDepth?: number;

addition?: undefined | ((collection: MetadataCollection) => ts.Statement[]);

/** Initializer of metadata. */
Expand Down Expand Up @@ -183,6 +186,8 @@ export namespace FeatureProgrammer {
from: "top" | "array" | "object";
postfix: string;
start?: undefined | number;
depth?: undefined | number;
maxDepth?: undefined | number;
}

export type Decoder<
Expand Down Expand Up @@ -227,6 +232,8 @@ export namespace FeatureProgrammer {
source: "top",
from: "top",
postfix: '""',
depth: props.config.maxDepth !== undefined ? 0 : undefined,
maxDepth: props.config.maxDepth,
},
}),
statements: props.config.addition
Expand Down
4 changes: 4 additions & 0 deletions src/programmers/IsProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ export namespace IsProgrammer {
options?: Partial<CONFIG.IOptions>;
context: ITypiaContext;
functor: FunctionProgrammer;
maxDepth?: number;
}): CheckerProgrammer.IConfig => ({
prefix: "_i",
equals: !!props.options?.object,
trace: false,
path: false,
maxDepth: props.maxDepth,
numeric: OptionPredicator.numeric({
numeric: props.options?.numeric,
}),
Expand Down Expand Up @@ -105,6 +107,7 @@ export namespace IsProgrammer {
----------------------------------------------------------- */
export interface IConfig {
equals: boolean;
maxDepth?: number;
}
export interface IProps extends IProgrammerProps {
config: IConfig;
Expand Down Expand Up @@ -139,6 +142,7 @@ export namespace IsProgrammer {
},
context: props.context,
functor: props.functor,
maxDepth: props.config.maxDepth,
}),
trace: props.config.equals,
};
Expand Down
4 changes: 2 additions & 2 deletions src/programmers/json/JsonStringifyProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ export namespace JsonStringifyProgrammer {
if (props.metadata.templates.length)
if (AtomicPredicator.template(props.metadata)) {
const partial = Metadata.initialize();
partial.atomics.push(
(partial.atomics.push(
MetadataAtomic.create({ type: "string", tags: [] }),
),
unions.push({
Expand All @@ -278,7 +278,7 @@ export namespace JsonStringifyProgrammer {
...props,
type: "string",
}),
});
}));
}

// CONSTANTS
Expand Down
20 changes: 8 additions & 12 deletions src/schemas/json/IJsonSchemaApplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,15 @@ export namespace IJsonSchemaApplication {
: OpenApiV3.IJsonSchema;

export interface IComponents<
Schema extends
| OpenApi.IJsonSchema
| OpenApiV3.IJsonSchema = OpenApi.IJsonSchema,
Schema extends OpenApi.IJsonSchema | OpenApiV3.IJsonSchema =
OpenApi.IJsonSchema,
> {
schemas?: Record<string, Schema>;
}

export interface IFunction<
Schema extends
| OpenApi.IJsonSchema
| OpenApiV3.IJsonSchema = OpenApi.IJsonSchema,
Schema extends OpenApi.IJsonSchema | OpenApiV3.IJsonSchema =
OpenApi.IJsonSchema,
> {
async: boolean;
name: string;
Expand All @@ -42,9 +40,8 @@ export namespace IJsonSchemaApplication {
}

export interface IParameter<
Schema extends
| OpenApi.IJsonSchema
| OpenApiV3.IJsonSchema = OpenApi.IJsonSchema,
Schema extends OpenApi.IJsonSchema | OpenApiV3.IJsonSchema =
OpenApi.IJsonSchema,
> {
name: string;
required: boolean;
Expand All @@ -54,9 +51,8 @@ export namespace IJsonSchemaApplication {
}

export interface IOutput<
Schema extends
| OpenApi.IJsonSchema
| OpenApiV3.IJsonSchema = OpenApi.IJsonSchema,
Schema extends OpenApi.IJsonSchema | OpenApiV3.IJsonSchema =
OpenApi.IJsonSchema,
> {
schema: Schema;
required: boolean;
Expand Down
2 changes: 1 addition & 1 deletion src/tags/JsonSchemaPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { TagBase } from "./TagBase";
* "x-format": "currency",
* "x-example": 19.99
* }>;
* ```
* ```;
*
* @template Schema - Object containing custom properties to add to the JSON
* Schema
Expand Down
2 changes: 1 addition & 1 deletion src/tags/Sequence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { TagBase } from "./TagBase";
*
* // Generate Protocol Buffer message
* const message = typia.protobuf.message<User>();
* ```
* ```;
*
* @template N - Field number (positive integer from 1 to 536,870,911, excluding
* 19000-19999)
Expand Down
Loading