drimion 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +955 -0
  3. package/dist/cli/index.js +1045 -0
  4. package/dist/cli/templates/aggregate.ts.hbs +22 -0
  5. package/dist/cli/templates/entity.ts.hbs +16 -0
  6. package/dist/cli/templates/repository.ts.hbs +24 -0
  7. package/dist/cli/templates/use-case.ts.hbs +20 -0
  8. package/dist/cli/templates/value-object.ts.hbs +16 -0
  9. package/dist/kernel/core/aggregate.ts +234 -0
  10. package/dist/kernel/core/entity.ts +348 -0
  11. package/dist/kernel/core/id.ts +207 -0
  12. package/dist/kernel/core/index.ts +5 -0
  13. package/dist/kernel/core/repository.ts +81 -0
  14. package/dist/kernel/core/value-object.ts +309 -0
  15. package/dist/kernel/events/browser-event-manager.ts +241 -0
  16. package/dist/kernel/events/domain-event.ts +76 -0
  17. package/dist/kernel/events/event-bus.ts +158 -0
  18. package/dist/kernel/events/event-context.ts +95 -0
  19. package/dist/kernel/events/event-manager.ts +20 -0
  20. package/dist/kernel/events/event-utils.ts +19 -0
  21. package/dist/kernel/events/index.ts +7 -0
  22. package/dist/kernel/events/server-event-manager.ts +169 -0
  23. package/dist/kernel/helpers/auto-mapper.ts +222 -0
  24. package/dist/kernel/helpers/domain-classes.ts +162 -0
  25. package/dist/kernel/helpers/domain-error.ts +52 -0
  26. package/dist/kernel/helpers/getters-setters.ts +385 -0
  27. package/dist/kernel/helpers/index.ts +7 -0
  28. package/dist/kernel/index.ts +73 -0
  29. package/dist/kernel/libs/crypto.ts +33 -0
  30. package/dist/kernel/libs/index.ts +5 -0
  31. package/dist/kernel/libs/iterator.ts +298 -0
  32. package/dist/kernel/libs/result.ts +252 -0
  33. package/dist/kernel/libs/utils.ts +260 -0
  34. package/dist/kernel/libs/validator.ts +353 -0
  35. package/dist/kernel/types/adapter.types.ts +26 -0
  36. package/dist/kernel/types/command.types.ts +37 -0
  37. package/dist/kernel/types/entity.types.ts +60 -0
  38. package/dist/kernel/types/event.types.ts +129 -0
  39. package/dist/kernel/types/index.ts +26 -0
  40. package/dist/kernel/types/iterator.types.ts +39 -0
  41. package/dist/kernel/types/result.types.ts +122 -0
  42. package/dist/kernel/types/uid.types.ts +18 -0
  43. package/dist/kernel/types/utils.types.ts +120 -0
  44. package/dist/kernel/types/value-object.types.ts +20 -0
  45. package/dist/kernel/utils/date.utils.ts +111 -0
  46. package/dist/kernel/utils/index.ts +32 -0
  47. package/dist/kernel/utils/number.utils.ts +341 -0
  48. package/dist/kernel/utils/object.utils.ts +61 -0
  49. package/dist/kernel/utils/string.utils.ts +128 -0
  50. package/dist/kernel/utils/type.utils.ts +33 -0
  51. package/package.json +59 -0
@@ -0,0 +1,60 @@
1
+ import type { UID } from "./uid.types";
2
+
3
+ /**
4
+ * @description
5
+ * Represents the static side (constructor + factory contract) of an `Aggregate` subclass.
6
+ *
7
+ * Mirrors `EntityConstructor` but scoped to `Aggregate` subclasses, enabling the same
8
+ * polymorphic `this`-typed factory pattern used by `Entity.create()` and `Entity.init()`.
9
+ *
10
+ * @template Props The shape of the aggregate's user-defined domain properties.
11
+ * @template T The concrete `Aggregate` subclass type.
12
+ */
13
+ export type AggregateConstructor<Props extends object, T> = {
14
+ isValidProps(props: Props): boolean;
15
+ readonly name: string;
16
+ prototype: T;
17
+ };
18
+
19
+ /**
20
+ * @description
21
+ * Represents the static side (constructor + factory contract) of an `Entity` subclass.
22
+ *
23
+ * Used by `Entity.create()` and `Entity.init()` to enable the polymorphic
24
+ * `this`-typed factory pattern — calling `User.create(props)` infers `T = User`
25
+ * automatically without requiring subclasses to override the factory.
26
+ *
27
+ * @template Props The shape of the entity's user-defined domain properties.
28
+ * @template T The concrete `Entity` subclass type.
29
+ */
30
+ export type EntityConstructor<Props extends object, T> = {
31
+ isValidProps(props: Props): boolean;
32
+ readonly name: string;
33
+ prototype: T;
34
+ };
35
+
36
+ /**
37
+ * @description
38
+ * Merges user-defined `Props` with the implicit Entity lifecycle fields.
39
+ */
40
+ export type EntityProps<T extends object> = T & {
41
+ id?: string | number | UID<string>;
42
+ createdAt?: Date;
43
+ updatedAt?: Date;
44
+ };
45
+
46
+ /**
47
+ * @description
48
+ * Represents the base constraint for an entity's user-defined properties.
49
+ * Must be a plain object (no primitives, arrays, or class instances).
50
+ */
51
+ export type IEntityProps = object;
52
+
53
+ /**
54
+ * @description
55
+ * Configuration options for getter and setter behavior on an entity instance.
56
+ */
57
+ export interface IEntitySettings {
58
+ disableGetters?: boolean;
59
+ disableSetters?: boolean;
60
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @description
3
+ * Represents a domain event — an immutable record of something that happened
4
+ * within an aggregate boundary.
5
+ *
6
+ * Domain events are plain data. They carry no behaviour, no handlers, and no
7
+ * knowledge of how they will be consumed. The `type` field is the only
8
+ * required identifier; every other field provides tracing context.
9
+ *
10
+ * Naming convention: past-tense, `aggregate:fact` format.
11
+ * @example `'order:placed'`, `'user:registered'`, `'pokemon:caught'`
12
+ *
13
+ * @template TPayload The shape of the event-specific data.
14
+ */
15
+ export interface DomainEvent<TPayload = unknown> {
16
+ /**
17
+ * @description
18
+ * The event type identifier. Use past-tense, colon-separated format:
19
+ * `'<aggregate>:<fact>'` — e.g. `'order:placed'`, `'user:email-changed'`.
20
+ */
21
+ readonly type: string;
22
+
23
+ /**
24
+ * @description
25
+ * The string value of the aggregate's `id` at the time the event was emitted.
26
+ */
27
+ readonly aggregateId?: string;
28
+
29
+ /**
30
+ * @description
31
+ * The class name of the aggregate that emitted this event.
32
+ * Useful for logging, filtering, and debugging across aggregate boundaries.
33
+ *
34
+ * @example `'Order'`, `'User'`, `'Pokemon'`
35
+ */
36
+ readonly aggregateName?: string;
37
+
38
+ /**
39
+ * @description
40
+ * The timestamp at which this event was created inside the aggregate.
41
+ * Reflects domain time, not infrastructure time.
42
+ */
43
+ readonly occurredAt?: Date;
44
+
45
+ /**
46
+ * @description
47
+ * Event-specific data. Keep this flat and serializable — avoid class
48
+ * instances, functions, or circular references so the event can be safely
49
+ * transmitted across process boundaries.
50
+ */
51
+ readonly payload?: TPayload;
52
+ }
53
+
54
+ /**
55
+ * @description
56
+ * Represents a generic browser / server event payload wrapper.
57
+ * Used internally by `BrowserEventManager` and `ServerEventManager`.
58
+ *
59
+ * @internal
60
+ */
61
+ export type DomainEventPayload = { detail?: unknown[] };
62
+
63
+ /**
64
+ * @description
65
+ * Stores a registered event name and its associated callback.
66
+ * Used internally by the built-in event managers.
67
+ *
68
+ * @internal
69
+ */
70
+ export interface EventEntry {
71
+ eventName: string;
72
+ callback: (event: DomainEventPayload) => void | Promise<void>;
73
+ }
74
+
75
+ /**
76
+ * @description
77
+ * Subscriber callback type — receives a fully-typed `DomainEvent` and may
78
+ * return a `Promise` for async side effects.
79
+ */
80
+ export type EventSubscriber<TPayload = unknown> = (
81
+ event: DomainEvent<TPayload>,
82
+ ) => void | Promise<void>;
83
+
84
+ /**
85
+ * @description
86
+ * Contract for an application-level event bus.
87
+ *
88
+ * Implement this interface to integrate any pub-sub mechanism — an in-process
89
+ * `EventEmitter`, a Redis Streams adapter, BullMQ, NATS, or any other
90
+ * transport — with the domain event system produced by `Aggregate.pullEvents()`.
91
+ *
92
+ * The library ships with a `EventBus` implementation that works
93
+ * out-of-the-box in both Node.js and browser environments. Swap it for your
94
+ * own at the application layer without touching any domain code.
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * class RedisEventBus implements IEventBus {
99
+ * async publish(event: DomainEvent): Promise<void> {
100
+ * await redis.xadd(event.type, '*', 'data', JSON.stringify(event));
101
+ * }
102
+ * async publishAll(events: ReadonlyArray<DomainEvent>): Promise<void> {
103
+ * for (const event of events) await this.publish(event);
104
+ * }
105
+ * }
106
+ * ```
107
+ */
108
+ export interface IEventBus {
109
+ /**
110
+ * @description Publishes a single domain event.
111
+ */
112
+ publish(event: DomainEvent): Promise<void>;
113
+
114
+ /**
115
+ * @description
116
+ * Publishes all domain events in the provided array.
117
+ * Implementations should preserve order.
118
+ */
119
+ publishAll(events: ReadonlyArray<DomainEvent>): Promise<void>;
120
+ }
121
+
122
+ /**
123
+ * @description
124
+ * Internal registry entry stored per event type.
125
+ */
126
+ export interface SubscriberEntry {
127
+ type: string;
128
+ subscriber: EventSubscriber;
129
+ }
@@ -0,0 +1,26 @@
1
+ export type {
2
+ Adapter,
3
+ IAdapter,
4
+ } from "./adapter.types";
5
+
6
+ export type { ICommand, IQuery, IUseCase } from "./command.types";
7
+ export type { IEntityProps, IEntitySettings } from "./entity.types";
8
+ export type { IIterator, IIteratorConfig } from "./iterator.types";
9
+ export type {
10
+ IResult,
11
+ IResultExecuteFn,
12
+ IResultHook,
13
+ IResultObject,
14
+ IResultOption,
15
+ } from "./result.types";
16
+
17
+ export type { UID } from "./uid.types";
18
+ export type {
19
+ AnyObject,
20
+ BuiltIns,
21
+ CalcOpt,
22
+ Primitive,
23
+ ReadonlyDeep,
24
+ } from "./utils.types";
25
+
26
+ export type { IValueObjectSettings } from "./value-object.types";
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @description
3
+ * Defines the operations supported by an iterator for managing sequential traversal of items.
4
+ *
5
+ * @template T The type of items in the iterator.
6
+ */
7
+ export interface IIterator<T> {
8
+ addToEnd(data: T): IIterator<T>;
9
+ add(data: T): IIterator<T>;
10
+ addToStart(data: T): IIterator<T>;
11
+ clear(): IIterator<T>;
12
+ clone(): IIterator<T>;
13
+ first(): T;
14
+ hasNext(): boolean;
15
+ hasPrev(): boolean;
16
+ isEmpty(): boolean;
17
+ last(): T;
18
+ next(): T;
19
+ prev(): T;
20
+ removeFirst(): IIterator<T>;
21
+ removeItem(item: T): void;
22
+ removeLast(): IIterator<T>;
23
+ toArray(): Array<T>;
24
+ toFirst(): IIterator<T>;
25
+ toLast(): IIterator<T>;
26
+ total(): number;
27
+ }
28
+
29
+ /**
30
+ * @description
31
+ * Configuration options for creating an iterator.
32
+ *
33
+ * @template T The type of items in the iterator.
34
+ */
35
+ export interface IIteratorConfig<T> {
36
+ initialData?: Array<T>;
37
+ restartOnFinish?: boolean;
38
+ returnCurrentOnReversion?: boolean;
39
+ }
@@ -0,0 +1,122 @@
1
+ import type { ICommand } from "./command.types";
2
+ import type { AnyObject } from "./utils.types";
3
+
4
+ /**
5
+ * @description
6
+ * Represents the result of an operation, encapsulating its state, value, error, and metadata.
7
+ *
8
+ * @template T The type of the result's value.
9
+ * @template D The type of the result's error (default: string).
10
+ * @template M The type of the result's metadata (default: empty object).
11
+ */
12
+ export interface IResult<T, D = string, M = AnyObject> {
13
+ /**
14
+ * @description
15
+ * Retrieves the error of the result. Returns null if the result represents success.
16
+ *
17
+ * @returns The result's error or null.
18
+ */
19
+ error(): D;
20
+ /**
21
+ * @description
22
+ * Executes a command based on the result's state (success or failure).
23
+ *
24
+ * @template X The input type for the command.
25
+ * @template Y The output type of the command.
26
+ * @param command The command to execute.
27
+ * @returns An object containing hooks for further execution.
28
+ */
29
+ execute: <X, Y>(command: ICommand<X, Y>) => IResultExecuteFn<X, Y>;
30
+ /**
31
+ * @description
32
+ * Checks if the result represents a failure.
33
+ *
34
+ * @returns True if the result is a failure, false otherwise.
35
+ */
36
+ isError(): boolean;
37
+ /**
38
+ * @description
39
+ * Checks if the result contains a null value.
40
+ *
41
+ * @returns True if the value is null, false otherwise.
42
+ */
43
+ isNull(): boolean;
44
+ /**
45
+ * @description
46
+ * Checks if the result represents success.
47
+ *
48
+ * @returns True if the result is a success, false otherwise.
49
+ */
50
+ isSuccess(): boolean;
51
+ /**
52
+ * @description
53
+ * Retrieves the metadata associated with the result.
54
+ *
55
+ * @returns The result's metadata.
56
+ */
57
+ metaData(): M;
58
+ /**
59
+ * @description
60
+ * Converts the result into an object representing its current state.
61
+ *
62
+ * @returns An object containing the result's value, error, and metadata.
63
+ */
64
+ toObject(): IResultObject<T, D, M>;
65
+ /**
66
+ * @description
67
+ * Retrieves the value of the result. Returns null if the result represents a failure.
68
+ *
69
+ * @returns The result's value or null.
70
+ */
71
+ value(): T;
72
+ }
73
+
74
+ /**
75
+ * @description
76
+ * Represents the possible states of a result: success (`success`) or failure (`error`).
77
+ */
78
+ export type IResultOption = "error" | "success";
79
+
80
+ /**
81
+ * @description
82
+ * Hook for handling specific result states during execution.
83
+ *
84
+ * @template Y The type of the hook's output.
85
+ */
86
+ export interface IResultHook<Y> {
87
+ /**
88
+ * @description
89
+ * Executes a function based on the result state.
90
+ *
91
+ * @param option The result state to handle (`success` or `error`).
92
+ * @returns The result of the function execution, if applicable.
93
+ */
94
+ on(option: IResultOption): Promise<IResult<Y, string>> | undefined;
95
+ }
96
+
97
+ /**
98
+ * @description
99
+ * Extends `IResultHook` with support for data input.
100
+ *
101
+ * @template X The input type for the hook.
102
+ * @template Y The output type for the hook.
103
+ */
104
+ export interface IResultExecuteFn<X, Y> extends IResultHook<Y> {
105
+ withData(data: X): IResultHook<Y>;
106
+ }
107
+
108
+ /**
109
+ * @description
110
+ * Represents the state of a result, including its value, error, and metadata.
111
+ *
112
+ * @template T The type of the result's value.
113
+ * @template D The type of the result's error.
114
+ * @template M The type of the result's metadata.
115
+ */
116
+ export interface IResultObject<T, D, M> {
117
+ data: T | null;
118
+ error: D | null;
119
+ isError: boolean;
120
+ isSuccess: boolean;
121
+ metaData: M;
122
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @description
3
+ * Represents a unique identifier (UID) with methods for manipulation and comparison.
4
+ *
5
+ * @template T The type of the UID's value (default: string).
6
+ */
7
+ export interface UID<T = string> {
8
+ clone(): UID<T>;
9
+ cloneAsNew(): UID<string>;
10
+ createdAt(): Date;
11
+ deepEqual(id: UID<string>): boolean;
12
+ equal(id: UID<string>): boolean;
13
+ isEqual(id: UID<string>): boolean;
14
+ isNew(): boolean;
15
+ isShort(): boolean;
16
+ value(): string;
17
+ toShort(): UID<string>;
18
+ }
@@ -0,0 +1,120 @@
1
+ /**
2
+ * @description
3
+ * Represents an unknown object.
4
+ */
5
+ export type AnyObject = Record<string, unknown>;
6
+
7
+ /**
8
+ * @description
9
+ * Built-in types that are excluded from recursive transformations.
10
+ */
11
+ export type BuiltIns = Primitive | Date | RegExp;
12
+
13
+ /**
14
+ * @description
15
+ * Options for calculations, such as specifying precision.
16
+ */
17
+ export type CalcOpt = { fractionDigits: number };
18
+
19
+ /**
20
+ * @description
21
+ * Utility type to determine if a function type has multiple call signatures.
22
+ *
23
+ * Used to differentiate simple functions from overloaded functions.
24
+ *
25
+ * @template T The function type to analyze.
26
+ */
27
+ type HasMultipleCallSignatures<
28
+ T extends (...arguments_: unknown[]) => unknown,
29
+ > = T extends {
30
+ (...arguments_: infer A): unknown;
31
+ (...arguments_: infer B): unknown;
32
+ }
33
+ ? B extends A
34
+ ? A extends B
35
+ ? false // Single call signature.
36
+ : true // Multiple call signatures.
37
+ : true
38
+ : false;
39
+
40
+ /**
41
+ * @description
42
+ * Primitive types that are not recursively transformed.
43
+ */
44
+ export type Primitive =
45
+ | null
46
+ | undefined
47
+ | string
48
+ | number
49
+ | boolean
50
+ | symbol
51
+ | bigint;
52
+
53
+ /**
54
+ * @description
55
+ * A utility type to recursively make all properties of a type `T` deeply readonly.
56
+ *
57
+ * Handles built-in types, objects, arrays, tuples, sets, and maps.
58
+ * Special cases include skipping class constructors and functions.
59
+ *
60
+ * @template T The type to be made deeply readonly.
61
+ */
62
+ export type ReadonlyDeep<T> = T extends BuiltIns
63
+ ? T // Built-in types remain unchanged.
64
+ : T extends new (
65
+ ...arguments_: unknown[]
66
+ ) => unknown
67
+ ? T // Skip class constructors to preserve mutability.
68
+ : T extends (...arguments_: unknown[]) => unknown
69
+ ? AnyObject extends ReadonlyObjectDeep<T>
70
+ ? T // Skip plain functions with no call signatures.
71
+ : HasMultipleCallSignatures<T> extends true
72
+ ? T // Preserve functions with multiple call signatures.
73
+ : ((...arguments_: Parameters<T>) => ReturnType<T>) &
74
+ ReadonlyObjectDeep<T>
75
+ : T extends Readonly<ReadonlyMap<infer KeyType, infer ValueType>>
76
+ ? ReadonlyMapDeep<KeyType, ValueType> // Recursively make map keys and values readonly.
77
+ : T extends Readonly<ReadonlySet<infer ItemType>>
78
+ ? ReadonlySetDeep<ItemType> // Recursively make set items readonly.
79
+ : T extends readonly [] | readonly [...never[]]
80
+ ? readonly [] // Handle empty or unspecific tuples as empty arrays.
81
+ : T extends readonly [infer U, ...infer V]
82
+ ? readonly [ReadonlyDeep<U>, ...ReadonlyDeep<V>] // Handle tuples with specific types.
83
+ : T extends readonly [...infer U, infer V]
84
+ ? readonly [...ReadonlyDeep<U>, ReadonlyDeep<V>] // Handle generic tuples.
85
+ : T extends ReadonlyArray<infer ItemType>
86
+ ? ReadonlyArray<ReadonlyDeep<ItemType>> // Recursively make array items readonly.
87
+ : T extends object
88
+ ? ReadonlyObjectDeep<T> // Recursively make object properties readonly.
89
+ : unknown; // For unknown types, no transformation is applied.
90
+
91
+ /**
92
+ * @description
93
+ * Makes all key-value pairs of a `ReadonlyMap` deeply readonly.
94
+ *
95
+ * @template KeyType Type of the keys in the map.
96
+ * @template ValueType Type of the values in the map.
97
+ */
98
+ type ReadonlyMapDeep<KeyType, ValueType> = {} & Readonly<
99
+ ReadonlyMap<ReadonlyDeep<KeyType>, ReadonlyDeep<ValueType>>
100
+ >;
101
+
102
+ /**
103
+ * @description
104
+ * Makes all properties of an object type deeply readonly.
105
+ *
106
+ * @template ObjectType The type of the object to be made deeply readonly.
107
+ */
108
+ type ReadonlyObjectDeep<ObjectType extends object> = {
109
+ readonly [KeyType in keyof ObjectType]: ReadonlyDeep<ObjectType[KeyType]>;
110
+ };
111
+
112
+ /**
113
+ * @description
114
+ * Makes all elements of a `ReadonlySet` deeply readonly.
115
+ *
116
+ * @template ItemType Type of the items in the set.
117
+ */
118
+ type ReadonlySetDeep<ItemType> = {} & Readonly<
119
+ ReadonlySet<ReadonlyDeep<ItemType>>
120
+ >;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @description
3
+ * Represents the static side (constructor + factory contract) of a `ValueObject` subclass.
4
+ *
5
+ * @template Props The shape of the value object's properties.
6
+ * @template T The concrete `ValueObject` subclass type.
7
+ */
8
+ export type ValueObjectConstructor<Props, T> = {
9
+ isValidProps(props: Props): boolean;
10
+ readonly name: string;
11
+ prototype: T;
12
+ };
13
+
14
+ /**
15
+ * @description
16
+ * Configuration for value object settings.
17
+ */
18
+ export interface IValueObjectSettings {
19
+ disableGetters?: boolean;
20
+ }
@@ -0,0 +1,111 @@
1
+ /** Supported time units for operations like incrementing or decrementing time. */
2
+ export type Unit = "minute" | "hour" | "day" | "week" | "month" | "year";
3
+
4
+ /** Milliseconds in common time units. */
5
+ export const ONE_MINUTE = 60000;
6
+ export const ONE_HOUR = ONE_MINUTE * 60;
7
+ export const ONE_DAY = ONE_HOUR * 24;
8
+ export const ONE_WEEK = ONE_DAY * 7;
9
+ export const ONE_MONTH = ONE_DAY * 30;
10
+ export const ONE_YEAR = ONE_DAY * 365;
11
+
12
+ /**
13
+ * @description Decreases a given date by a specified amount of time based on the unit provided.
14
+ *
15
+ * @param date The starting date from which the time will be decremented.
16
+ * @param value The number of units to decrement. If not a valid number, the original timestamp is returned.
17
+ * @param unit The unit of time to decrement. Possible values are:
18
+ * - `'day'`: Decrement by days.
19
+ * - `'hour'`: Decrement by hours.
20
+ * - `'minute'`: Decrement by minutes.
21
+ * - `'month'`: Decrement by months.
22
+ * - `'week'`: Decrement by weeks.
23
+ * - `'year'`: Decrement by years.
24
+ *
25
+ * @returns The decremented timestamp as a number. If the input date is invalid, the current timestamp is returned.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const now = new Date();
30
+ * const decrementedTime = DecrementTime(now, 2, 'day'); // Subtracts 2 days from the current date.
31
+ * console.log(new Date(decrementedTime)); // Logs the decremented date.
32
+ * ```
33
+ */
34
+ export const DecrementTime = (
35
+ date: Date,
36
+ value: number,
37
+ unit: Unit,
38
+ ): number => {
39
+ if (!(date instanceof Date)) return Date.now();
40
+
41
+ const time = date.getTime();
42
+ if (typeof value !== "number") return time;
43
+
44
+ switch (unit) {
45
+ case "day":
46
+ return time - ONE_DAY * value;
47
+ case "hour":
48
+ return time - ONE_HOUR * value;
49
+ case "minute":
50
+ return time - ONE_MINUTE * value;
51
+ case "month":
52
+ return time - ONE_MONTH * value;
53
+ case "week":
54
+ return time - ONE_WEEK * value;
55
+ case "year":
56
+ return time - ONE_YEAR * value;
57
+ default:
58
+ return time;
59
+ }
60
+ };
61
+
62
+ /**
63
+ * @description
64
+ * Increments a given date by a specified amount of time based on the unit provided.
65
+ *
66
+ * @param date The starting date to increment.
67
+ * @param value The number of units to increment. If not a valid number, the original timestamp is returned.
68
+ * @param unit The unit of time to increment. Possible values are:
69
+ * - `'day'`: Increment by days.
70
+ * - `'hour'`: Increment by hours.
71
+ * - `'minute'`: Increment by minutes.
72
+ * - `'month'`: Increment by months.
73
+ * - `'week'`: Increment by weeks.
74
+ * - `'year'`: Increment by years.
75
+ *
76
+ * @returns The incremented timestamp as a number. If the input date is invalid, the current timestamp is returned.
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * const now = new Date();
81
+ * const incrementedTime = IncrementTime(now, 3, 'day'); // Adds 3 days to the current date.
82
+ * console.log(new Date(incrementedTime)); // Logs the incremented date.
83
+ * ```
84
+ */
85
+ export const IncrementTime = (
86
+ date: Date,
87
+ value: number,
88
+ unit: Unit,
89
+ ): number => {
90
+ if (!(date instanceof Date)) return Date.now();
91
+
92
+ const time = date.getTime();
93
+ if (typeof value !== "number") return time;
94
+
95
+ switch (unit) {
96
+ case "day":
97
+ return ONE_DAY * value + time;
98
+ case "hour":
99
+ return ONE_HOUR * value + time;
100
+ case "minute":
101
+ return ONE_MINUTE * value + time;
102
+ case "month":
103
+ return ONE_MONTH * value + time;
104
+ case "week":
105
+ return ONE_WEEK * value + time;
106
+ case "year":
107
+ return ONE_YEAR * value + time;
108
+ default:
109
+ return time;
110
+ }
111
+ };
@@ -0,0 +1,32 @@
1
+ export {
2
+ DecrementTime,
3
+ IncrementTime,
4
+ ONE_DAY,
5
+ ONE_HOUR,
6
+ ONE_MINUTE,
7
+ ONE_MONTH,
8
+ ONE_WEEK,
9
+ ONE_YEAR,
10
+ } from "./date.utils";
11
+
12
+ export {
13
+ Divide,
14
+ EnsureNumber,
15
+ Float,
16
+ IsNaN,
17
+ Multiply,
18
+ Subtract,
19
+ Sum,
20
+ ToDecimal,
21
+ ToLong,
22
+ ToPrecision,
23
+ } from "./number.utils";
24
+
25
+ export { DeepFreeze, StableStringify } from "./object.utils";
26
+
27
+ export {
28
+ RemoveChars,
29
+ RemoveSpaces,
30
+ ReplaceChars,
31
+ Stringify,
32
+ } from "./string.utils";