@cosmneo/onion-lasagna 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.
- package/dist/backend/core/global.cjs +283 -0
- package/dist/backend/core/global.cjs.map +1 -0
- package/dist/backend/core/global.d.cts +294 -0
- package/dist/backend/core/global.d.ts +294 -0
- package/dist/backend/core/global.js +39 -0
- package/dist/backend/core/global.js.map +1 -0
- package/dist/backend/core/onion-layers.cjs +2302 -0
- package/dist/backend/core/onion-layers.cjs.map +1 -0
- package/dist/backend/core/onion-layers.d.cts +1675 -0
- package/dist/backend/core/onion-layers.d.ts +1675 -0
- package/dist/backend/core/onion-layers.js +1158 -0
- package/dist/backend/core/onion-layers.js.map +1 -0
- package/dist/backend/core/presentation.cjs +573 -0
- package/dist/backend/core/presentation.cjs.map +1 -0
- package/dist/backend/core/presentation.d.cts +5 -0
- package/dist/backend/core/presentation.d.ts +5 -0
- package/dist/backend/core/presentation.js +28 -0
- package/dist/backend/core/presentation.js.map +1 -0
- package/dist/backend/core/validators/arktype.cjs +947 -0
- package/dist/backend/core/validators/arktype.cjs.map +1 -0
- package/dist/backend/core/validators/arktype.d.cts +188 -0
- package/dist/backend/core/validators/arktype.d.ts +188 -0
- package/dist/backend/core/validators/arktype.js +287 -0
- package/dist/backend/core/validators/arktype.js.map +1 -0
- package/dist/backend/core/validators/typebox.cjs +939 -0
- package/dist/backend/core/validators/typebox.cjs.map +1 -0
- package/dist/backend/core/validators/typebox.d.cts +189 -0
- package/dist/backend/core/validators/typebox.d.ts +189 -0
- package/dist/backend/core/validators/typebox.js +281 -0
- package/dist/backend/core/validators/typebox.js.map +1 -0
- package/dist/backend/core/validators/valibot.cjs +942 -0
- package/dist/backend/core/validators/valibot.cjs.map +1 -0
- package/dist/backend/core/validators/valibot.d.cts +160 -0
- package/dist/backend/core/validators/valibot.d.ts +160 -0
- package/dist/backend/core/validators/valibot.js +294 -0
- package/dist/backend/core/validators/valibot.js.map +1 -0
- package/dist/backend/core/validators/zod.cjs +934 -0
- package/dist/backend/core/validators/zod.cjs.map +1 -0
- package/dist/backend/core/validators/zod.d.cts +188 -0
- package/dist/backend/core/validators/zod.d.ts +188 -0
- package/dist/backend/core/validators/zod.js +278 -0
- package/dist/backend/core/validators/zod.js.map +1 -0
- package/dist/backend/frameworks/elysia.cjs +715 -0
- package/dist/backend/frameworks/elysia.cjs.map +1 -0
- package/dist/backend/frameworks/elysia.d.cts +208 -0
- package/dist/backend/frameworks/elysia.d.ts +208 -0
- package/dist/backend/frameworks/elysia.js +251 -0
- package/dist/backend/frameworks/elysia.js.map +1 -0
- package/dist/backend/frameworks/fastify.cjs +677 -0
- package/dist/backend/frameworks/fastify.cjs.map +1 -0
- package/dist/backend/frameworks/fastify.d.cts +201 -0
- package/dist/backend/frameworks/fastify.d.ts +201 -0
- package/dist/backend/frameworks/fastify.js +213 -0
- package/dist/backend/frameworks/fastify.js.map +1 -0
- package/dist/backend/frameworks/hono.cjs +715 -0
- package/dist/backend/frameworks/hono.cjs.map +1 -0
- package/dist/backend/frameworks/hono.d.cts +163 -0
- package/dist/backend/frameworks/hono.d.ts +163 -0
- package/dist/backend/frameworks/hono.js +249 -0
- package/dist/backend/frameworks/hono.js.map +1 -0
- package/dist/backend/frameworks/nestjs.cjs +260 -0
- package/dist/backend/frameworks/nestjs.cjs.map +1 -0
- package/dist/backend/frameworks/nestjs.d.cts +168 -0
- package/dist/backend/frameworks/nestjs.d.ts +168 -0
- package/dist/backend/frameworks/nestjs.js +193 -0
- package/dist/backend/frameworks/nestjs.js.map +1 -0
- package/dist/base-dto.class-D7W9iqoU.d.cts +146 -0
- package/dist/base-dto.class-D7W9iqoU.d.ts +146 -0
- package/dist/base-uuid-v7.vo-BPGEIWLM.d.ts +799 -0
- package/dist/base-uuid-v7.vo-BjqKX44G.d.cts +799 -0
- package/dist/chunk-74IKUOSE.js +116 -0
- package/dist/chunk-74IKUOSE.js.map +1 -0
- package/dist/chunk-BKZOLGQW.js +29 -0
- package/dist/chunk-BKZOLGQW.js.map +1 -0
- package/dist/chunk-CGZBV6BD.js +54 -0
- package/dist/chunk-CGZBV6BD.js.map +1 -0
- package/dist/chunk-DDAHJZVK.js +258 -0
- package/dist/chunk-DDAHJZVK.js.map +1 -0
- package/dist/chunk-MQD5GXMT.js +171 -0
- package/dist/chunk-MQD5GXMT.js.map +1 -0
- package/dist/chunk-OKFXZHBC.js +43 -0
- package/dist/chunk-OKFXZHBC.js.map +1 -0
- package/dist/chunk-RLLWYFPI.js +168 -0
- package/dist/chunk-RLLWYFPI.js.map +1 -0
- package/dist/chunk-VCHFXT5W.js +425 -0
- package/dist/chunk-VCHFXT5W.js.map +1 -0
- package/dist/chunk-ZWLYNGO3.js +40 -0
- package/dist/chunk-ZWLYNGO3.js.map +1 -0
- package/dist/http-response-BAhi8lF4.d.cts +124 -0
- package/dist/http-response-BAhi8lF4.d.ts +124 -0
- package/dist/index-DingXh7B.d.cts +1187 -0
- package/dist/index-tOH7XBa3.d.ts +1187 -0
- package/dist/routing.type-DB4pt-d9.d.ts +184 -0
- package/dist/routing.type-DF2BIL7x.d.cts +184 -0
- package/dist/validation-error.type-kD4_qNZ9.d.cts +199 -0
- package/dist/validation-error.type-kD4_qNZ9.d.ts +199 -0
- package/package.json +191 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
export { B as BaseDto, a as BoundValidator, O as ObjectValidatorPort, S as SKIP_DTO_VALIDATION, V as ValidateObject } from '../../base-dto.class-D7W9iqoU.js';
|
|
2
|
+
import { C as CodedError, V as ValidationError, G as GlobalErrorCode } from '../../validation-error.type-kD4_qNZ9.js';
|
|
3
|
+
export { A as AppErrorCode, D as DomainErrorCode, a as ErrorCode, E as ErrorCodes, I as InfraErrorCode, P as PresentationErrorCode } from '../../validation-error.type-kD4_qNZ9.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Error thrown when object validation fails.
|
|
7
|
+
*
|
|
8
|
+
* Contains structured validation errors with field paths and messages,
|
|
9
|
+
* making it easy to report specific validation failures to clients.
|
|
10
|
+
* Thrown by all validator implementations (Zod, ArkType, TypeBox, Valibot).
|
|
11
|
+
*
|
|
12
|
+
* **Flow:**
|
|
13
|
+
* 1. Validator throws `ObjectValidationError` with field-level errors
|
|
14
|
+
* 2. Controller catches and converts to {@link InvalidRequestError}
|
|
15
|
+
* 3. HTTP layer maps to 400 Bad Request with error details
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* try {
|
|
20
|
+
* const dto = CreateUserDto.create(invalidData);
|
|
21
|
+
* } catch (error) {
|
|
22
|
+
* if (error instanceof ObjectValidationError) {
|
|
23
|
+
* console.log(error.validationErrors);
|
|
24
|
+
* // [
|
|
25
|
+
* // { field: 'email', message: 'Invalid email format' },
|
|
26
|
+
* // { field: 'age', message: 'Must be a positive number' }
|
|
27
|
+
* // ]
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
declare class ObjectValidationError extends CodedError {
|
|
33
|
+
/**
|
|
34
|
+
* Array of field-level validation errors.
|
|
35
|
+
*
|
|
36
|
+
* Each entry contains:
|
|
37
|
+
* - `field`: Dot-notation path to the invalid field (e.g., 'user.email')
|
|
38
|
+
* - `message`: Human-readable validation failure message
|
|
39
|
+
*/
|
|
40
|
+
validationErrors: ValidationError[];
|
|
41
|
+
/**
|
|
42
|
+
* Creates a new ObjectValidationError instance.
|
|
43
|
+
*
|
|
44
|
+
* @param options - Error configuration
|
|
45
|
+
* @param options.message - Human-readable summary message
|
|
46
|
+
* @param options.code - Machine-readable error code (default: 'OBJECT_VALIDATION_ERROR')
|
|
47
|
+
* @param options.cause - Optional underlying error from validation library
|
|
48
|
+
* @param options.validationErrors - Array of field-level validation errors
|
|
49
|
+
*/
|
|
50
|
+
constructor({ message, code, cause, validationErrors, }: {
|
|
51
|
+
message: string;
|
|
52
|
+
code?: GlobalErrorCode | string;
|
|
53
|
+
cause?: unknown;
|
|
54
|
+
validationErrors: ValidationError[];
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* Creates an ObjectValidationError from a caught error.
|
|
58
|
+
*
|
|
59
|
+
* @param cause - The original caught error
|
|
60
|
+
* @returns A new ObjectValidationError instance with the cause attached
|
|
61
|
+
*/
|
|
62
|
+
static fromError(cause: unknown): ObjectValidationError;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Checks if a field has changed by comparing the current value with a new value.
|
|
67
|
+
*
|
|
68
|
+
* Useful for detecting changes in update operations, supporting both partial
|
|
69
|
+
* and full update semantics.
|
|
70
|
+
*
|
|
71
|
+
* **Modes:**
|
|
72
|
+
* - **Partial update** (default): `undefined` means "keep existing value" (no change)
|
|
73
|
+
* - **Full update**: `undefined` means "set to undefined" (is a change if value !== undefined)
|
|
74
|
+
*
|
|
75
|
+
* **Limitation:** Uses strict equality (`!==`) for comparison, which only works
|
|
76
|
+
* correctly for primitives and reference equality. For objects or arrays, this
|
|
77
|
+
* compares references, not content. Two objects with identical content but
|
|
78
|
+
* different references will be considered "changed".
|
|
79
|
+
*
|
|
80
|
+
* For complex objects, either:
|
|
81
|
+
* - Compare by a unique identifier (e.g., `value.id !== newValue?.id`)
|
|
82
|
+
* - Use value objects with `.equals()` methods
|
|
83
|
+
* - Implement deep equality checking in your update logic
|
|
84
|
+
*
|
|
85
|
+
* @typeParam T - The type of the field being compared
|
|
86
|
+
* @param options - Comparison options
|
|
87
|
+
* @param options.value - The current field value
|
|
88
|
+
* @param options.newValue - The incoming value (may be undefined)
|
|
89
|
+
* @param options.partialUpdate - Whether to use partial update semantics (default: true)
|
|
90
|
+
* @returns `true` if the field has changed, `false` otherwise
|
|
91
|
+
*
|
|
92
|
+
* @example Partial update (PATCH semantics)
|
|
93
|
+
* ```typescript
|
|
94
|
+
* // undefined means "don't change"
|
|
95
|
+
* fieldChanged({ value: 'John', newValue: undefined }); // false
|
|
96
|
+
* fieldChanged({ value: 'John', newValue: 'Jane' }); // true
|
|
97
|
+
* fieldChanged({ value: 'John', newValue: 'John' }); // false
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @example Full update (PUT semantics)
|
|
101
|
+
* ```typescript
|
|
102
|
+
* // undefined means "set to undefined"
|
|
103
|
+
* fieldChanged({ value: 'John', newValue: undefined, partialUpdate: false }); // true
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @example Object comparison (reference-based)
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const obj1 = { name: 'John' };
|
|
109
|
+
* const obj2 = { name: 'John' };
|
|
110
|
+
* fieldChanged({ value: obj1, newValue: obj2 }); // true (different references)
|
|
111
|
+
* fieldChanged({ value: obj1, newValue: obj1 }); // false (same reference)
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function fieldChanged<T>({ value, newValue, partialUpdate, }: {
|
|
115
|
+
value: T;
|
|
116
|
+
newValue: T | undefined;
|
|
117
|
+
partialUpdate?: boolean;
|
|
118
|
+
}): boolean;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Error wrapping utilities for boundary error handling.
|
|
122
|
+
*
|
|
123
|
+
* Provides functions to wrap code execution with error transformation,
|
|
124
|
+
* converting caught errors into typed Error instances.
|
|
125
|
+
* Useful at layer boundaries (infra, use case, controller) to normalize errors.
|
|
126
|
+
*
|
|
127
|
+
* @example Wrapping async database calls
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const user = await wrapErrorAsync(
|
|
130
|
+
* () => this.db.query('SELECT * FROM users WHERE id = ?', [id]),
|
|
131
|
+
* (cause) => new DbError({ message: 'Failed to fetch user', cause }),
|
|
132
|
+
* );
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
* @example Wrapping sync operations
|
|
136
|
+
* ```typescript
|
|
137
|
+
* const parsed = wrapError(
|
|
138
|
+
* () => JSON.parse(data),
|
|
139
|
+
* (cause) => new InvariantViolationError({
|
|
140
|
+
* message: 'Invalid JSON format',
|
|
141
|
+
* cause,
|
|
142
|
+
* }),
|
|
143
|
+
* );
|
|
144
|
+
* ```
|
|
145
|
+
*
|
|
146
|
+
* @module
|
|
147
|
+
*/
|
|
148
|
+
/**
|
|
149
|
+
* Factory function that creates an Error from a caught error.
|
|
150
|
+
*
|
|
151
|
+
* @typeParam E - The specific Error subclass to create
|
|
152
|
+
* @param cause - The original caught error
|
|
153
|
+
* @returns A new Error instance
|
|
154
|
+
*/
|
|
155
|
+
type ErrorFactory<E extends Error> = (cause: unknown) => E;
|
|
156
|
+
/**
|
|
157
|
+
* Wraps a synchronous function with error transformation.
|
|
158
|
+
*
|
|
159
|
+
* Executes the provided function and catches any thrown errors,
|
|
160
|
+
* transforming them using the error factory.
|
|
161
|
+
*
|
|
162
|
+
* @typeParam T - The return type of the wrapped function
|
|
163
|
+
* @typeParam E - The Error subclass to throw on error
|
|
164
|
+
* @param fn - The function to execute
|
|
165
|
+
* @param errorFactory - Factory to create the typed error from the caught error
|
|
166
|
+
* @returns The result of the function if successful
|
|
167
|
+
* @throws {E} The transformed error if the function throws
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* const config = wrapError(
|
|
172
|
+
* () => JSON.parse(configString),
|
|
173
|
+
* (cause) => new InvariantViolationError({
|
|
174
|
+
* message: 'Invalid configuration format',
|
|
175
|
+
* code: 'CONFIG_PARSE_ERROR',
|
|
176
|
+
* cause,
|
|
177
|
+
* }),
|
|
178
|
+
* );
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
declare function wrapError<T, E extends Error>(fn: () => T, errorFactory: ErrorFactory<E>): T;
|
|
182
|
+
/**
|
|
183
|
+
* Wraps an asynchronous function with error transformation.
|
|
184
|
+
*
|
|
185
|
+
* Executes the provided async function and catches any thrown errors,
|
|
186
|
+
* transforming them using the error factory.
|
|
187
|
+
*
|
|
188
|
+
* @typeParam T - The return type of the wrapped function
|
|
189
|
+
* @typeParam E - The Error subclass to throw on error
|
|
190
|
+
* @param fn - The async function to execute
|
|
191
|
+
* @param errorFactory - Factory to create the typed error from the caught error
|
|
192
|
+
* @returns A promise resolving to the result if successful
|
|
193
|
+
* @throws {E} The transformed error if the function throws
|
|
194
|
+
*
|
|
195
|
+
* @example Repository usage
|
|
196
|
+
* ```typescript
|
|
197
|
+
* async findById(id: string): Promise<User | null> {
|
|
198
|
+
* return wrapErrorAsync(
|
|
199
|
+
* () => this.db.users.findUnique({ where: { id } }),
|
|
200
|
+
* (cause) => new DbError({
|
|
201
|
+
* message: `Failed to find user by ID: ${id}`,
|
|
202
|
+
* cause,
|
|
203
|
+
* }),
|
|
204
|
+
* );
|
|
205
|
+
* }
|
|
206
|
+
* ```
|
|
207
|
+
*
|
|
208
|
+
* @example External service usage
|
|
209
|
+
* ```typescript
|
|
210
|
+
* async sendEmail(to: string, body: string): Promise<void> {
|
|
211
|
+
* await wrapErrorAsync(
|
|
212
|
+
* () => this.emailClient.send({ to, body }),
|
|
213
|
+
* (cause) => new ExternalServiceError({
|
|
214
|
+
* message: 'Email delivery failed',
|
|
215
|
+
* code: 'EMAIL_SEND_FAILED',
|
|
216
|
+
* cause,
|
|
217
|
+
* }),
|
|
218
|
+
* );
|
|
219
|
+
* }
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
declare function wrapErrorAsync<T, E extends Error>(fn: () => Promise<T>, errorFactory: ErrorFactory<E>): Promise<T>;
|
|
223
|
+
/**
|
|
224
|
+
* Constructor type for error classes (including abstract classes).
|
|
225
|
+
*
|
|
226
|
+
* Used to specify error types that should pass through without transformation.
|
|
227
|
+
*/
|
|
228
|
+
type ErrorConstructor = abstract new (...args: any[]) => Error;
|
|
229
|
+
/**
|
|
230
|
+
* Wraps a synchronous function with conditional error transformation.
|
|
231
|
+
*
|
|
232
|
+
* Executes the provided function and catches any thrown errors.
|
|
233
|
+
* Errors matching any of the passthrough types are re-thrown as-is.
|
|
234
|
+
* All other errors are transformed using the error factory.
|
|
235
|
+
*
|
|
236
|
+
* @typeParam T - The return type of the wrapped function
|
|
237
|
+
* @typeParam E - The Error subclass to throw for unknown errors
|
|
238
|
+
* @param fn - The function to execute
|
|
239
|
+
* @param errorFactory - Factory to create the typed error from unknown errors
|
|
240
|
+
* @param passthroughTypes - Array of error classes to re-throw without transformation
|
|
241
|
+
* @returns The result of the function if successful
|
|
242
|
+
* @throws The original error if it matches a passthrough type
|
|
243
|
+
* @throws {E} The transformed error for unknown error types
|
|
244
|
+
*
|
|
245
|
+
* @example Controller boundary
|
|
246
|
+
* ```typescript
|
|
247
|
+
* const result = wrapErrorUnless(
|
|
248
|
+
* () => this.requestMapper(input),
|
|
249
|
+
* (cause) => new ControllerError({ message: 'Mapping failed', cause }),
|
|
250
|
+
* [CodedError],
|
|
251
|
+
* );
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
declare function wrapErrorUnless<T, E extends Error>(fn: () => T, errorFactory: ErrorFactory<E>, passthroughTypes: ErrorConstructor[]): T;
|
|
255
|
+
/**
|
|
256
|
+
* Wraps an asynchronous function with conditional error transformation.
|
|
257
|
+
*
|
|
258
|
+
* Executes the provided async function and catches any thrown errors.
|
|
259
|
+
* Errors matching any of the passthrough types are re-thrown as-is.
|
|
260
|
+
* All other errors are transformed using the error factory.
|
|
261
|
+
*
|
|
262
|
+
* @typeParam T - The return type of the wrapped function
|
|
263
|
+
* @typeParam E - The Error subclass to throw for unknown errors
|
|
264
|
+
* @param fn - The async function to execute
|
|
265
|
+
* @param errorFactory - Factory to create the typed error from unknown errors
|
|
266
|
+
* @param passthroughTypes - Array of error classes to re-throw without transformation
|
|
267
|
+
* @returns A promise resolving to the result if successful
|
|
268
|
+
* @throws The original error if it matches a passthrough type
|
|
269
|
+
* @throws {E} The transformed error for unknown error types
|
|
270
|
+
*
|
|
271
|
+
* @example Use case boundary
|
|
272
|
+
* ```typescript
|
|
273
|
+
* return wrapErrorUnlessAsync(
|
|
274
|
+
* () => this.handle(input),
|
|
275
|
+
* (cause) => new UseCaseError({ message: 'Unexpected error', cause }),
|
|
276
|
+
* [ObjectValidationError, UseCaseError, DomainError, InfraError],
|
|
277
|
+
* );
|
|
278
|
+
* ```
|
|
279
|
+
*
|
|
280
|
+
* @example Controller boundary
|
|
281
|
+
* ```typescript
|
|
282
|
+
* return wrapErrorUnlessAsync(
|
|
283
|
+
* async () => {
|
|
284
|
+
* const result = await this.useCase.execute(input);
|
|
285
|
+
* return this.responseMapper(result);
|
|
286
|
+
* },
|
|
287
|
+
* (cause) => new ControllerError({ message: 'Controller failed', cause }),
|
|
288
|
+
* [CodedError],
|
|
289
|
+
* );
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
declare function wrapErrorUnlessAsync<T, E extends Error>(fn: () => Promise<T>, errorFactory: ErrorFactory<E>, passthroughTypes: ErrorConstructor[]): Promise<T>;
|
|
293
|
+
|
|
294
|
+
export { CodedError, type ErrorConstructor, type ErrorFactory, GlobalErrorCode, ObjectValidationError, ValidationError, fieldChanged, wrapError, wrapErrorAsync, wrapErrorUnless, wrapErrorUnlessAsync };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
wrapError,
|
|
3
|
+
wrapErrorAsync,
|
|
4
|
+
wrapErrorUnless,
|
|
5
|
+
wrapErrorUnlessAsync
|
|
6
|
+
} from "../../chunk-OKFXZHBC.js";
|
|
7
|
+
import {
|
|
8
|
+
BaseDto,
|
|
9
|
+
SKIP_DTO_VALIDATION
|
|
10
|
+
} from "../../chunk-BKZOLGQW.js";
|
|
11
|
+
import {
|
|
12
|
+
CodedError,
|
|
13
|
+
ErrorCodes,
|
|
14
|
+
ObjectValidationError
|
|
15
|
+
} from "../../chunk-MQD5GXMT.js";
|
|
16
|
+
import "../../chunk-CGZBV6BD.js";
|
|
17
|
+
|
|
18
|
+
// src/backend/core/global/utils/field-changed.util.ts
|
|
19
|
+
function fieldChanged({
|
|
20
|
+
value,
|
|
21
|
+
newValue,
|
|
22
|
+
partialUpdate = true
|
|
23
|
+
}) {
|
|
24
|
+
if (partialUpdate && newValue === void 0) return false;
|
|
25
|
+
return value !== newValue;
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
BaseDto,
|
|
29
|
+
CodedError,
|
|
30
|
+
ErrorCodes,
|
|
31
|
+
ObjectValidationError,
|
|
32
|
+
SKIP_DTO_VALIDATION,
|
|
33
|
+
fieldChanged,
|
|
34
|
+
wrapError,
|
|
35
|
+
wrapErrorAsync,
|
|
36
|
+
wrapErrorUnless,
|
|
37
|
+
wrapErrorUnlessAsync
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=global.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/backend/core/global/utils/field-changed.util.ts"],"sourcesContent":["/**\n * Checks if a field has changed by comparing the current value with a new value.\n *\n * Useful for detecting changes in update operations, supporting both partial\n * and full update semantics.\n *\n * **Modes:**\n * - **Partial update** (default): `undefined` means \"keep existing value\" (no change)\n * - **Full update**: `undefined` means \"set to undefined\" (is a change if value !== undefined)\n *\n * **Limitation:** Uses strict equality (`!==`) for comparison, which only works\n * correctly for primitives and reference equality. For objects or arrays, this\n * compares references, not content. Two objects with identical content but\n * different references will be considered \"changed\".\n *\n * For complex objects, either:\n * - Compare by a unique identifier (e.g., `value.id !== newValue?.id`)\n * - Use value objects with `.equals()` methods\n * - Implement deep equality checking in your update logic\n *\n * @typeParam T - The type of the field being compared\n * @param options - Comparison options\n * @param options.value - The current field value\n * @param options.newValue - The incoming value (may be undefined)\n * @param options.partialUpdate - Whether to use partial update semantics (default: true)\n * @returns `true` if the field has changed, `false` otherwise\n *\n * @example Partial update (PATCH semantics)\n * ```typescript\n * // undefined means \"don't change\"\n * fieldChanged({ value: 'John', newValue: undefined }); // false\n * fieldChanged({ value: 'John', newValue: 'Jane' }); // true\n * fieldChanged({ value: 'John', newValue: 'John' }); // false\n * ```\n *\n * @example Full update (PUT semantics)\n * ```typescript\n * // undefined means \"set to undefined\"\n * fieldChanged({ value: 'John', newValue: undefined, partialUpdate: false }); // true\n * ```\n *\n * @example Object comparison (reference-based)\n * ```typescript\n * const obj1 = { name: 'John' };\n * const obj2 = { name: 'John' };\n * fieldChanged({ value: obj1, newValue: obj2 }); // true (different references)\n * fieldChanged({ value: obj1, newValue: obj1 }); // false (same reference)\n * ```\n */\nexport function fieldChanged<T>({\n value,\n newValue,\n partialUpdate = true,\n}: {\n value: T;\n newValue: T | undefined;\n partialUpdate?: boolean;\n}): boolean {\n if (partialUpdate && newValue === undefined) return false;\n // For full updates, undefined means \"set to undefined\" which is a change if value !== undefined\n return value !== newValue;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiDO,SAAS,aAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,gBAAgB;AAClB,GAIY;AACV,MAAI,iBAAiB,aAAa,OAAW,QAAO;AAEpD,SAAO,UAAU;AACnB;","names":[]}
|