@fjell/core 4.4.50 → 4.4.51
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/package.json +3 -3
- package/src/AItemService.ts +0 -38
- package/src/Coordinate.ts +0 -35
- package/src/dictionary.ts +0 -84
- package/src/errors/ActionError.ts +0 -69
- package/src/errors/BusinessLogicError.ts +0 -24
- package/src/errors/DuplicateError.ts +0 -57
- package/src/errors/NotFoundError.ts +0 -24
- package/src/errors/PermissionError.ts +0 -31
- package/src/errors/ValidationError.ts +0 -27
- package/src/errors/index.ts +0 -7
- package/src/event/emitter.ts +0 -247
- package/src/event/events.ts +0 -178
- package/src/event/index.ts +0 -130
- package/src/event/matching.ts +0 -264
- package/src/event/subscription.ts +0 -181
- package/src/event/types.ts +0 -282
- package/src/index.ts +0 -70
- package/src/item/IFactory.ts +0 -122
- package/src/item/IQFactory.ts +0 -163
- package/src/item/IQUtils.ts +0 -392
- package/src/item/IUtils.ts +0 -40
- package/src/item/ItemQuery.ts +0 -88
- package/src/items.ts +0 -120
- package/src/key/KUtils.ts +0 -484
- package/src/keys.ts +0 -95
- package/src/logger.ts +0 -5
- package/src/operations/OperationContext.ts +0 -12
- package/src/operations/Operations.ts +0 -357
- package/src/operations/contained.ts +0 -134
- package/src/operations/errorEnhancer.ts +0 -204
- package/src/operations/index.ts +0 -2
- package/src/operations/methods.ts +0 -363
- package/src/operations/primary.ts +0 -101
- package/src/operations/specialized.ts +0 -71
- package/src/operations/wrappers/createActionWrapper.ts +0 -108
- package/src/operations/wrappers/createAllActionWrapper.ts +0 -109
- package/src/operations/wrappers/createAllFacetWrapper.ts +0 -98
- package/src/operations/wrappers/createAllWrapper.ts +0 -103
- package/src/operations/wrappers/createCreateWrapper.ts +0 -117
- package/src/operations/wrappers/createFacetWrapper.ts +0 -97
- package/src/operations/wrappers/createFindOneWrapper.ts +0 -105
- package/src/operations/wrappers/createFindWrapper.ts +0 -105
- package/src/operations/wrappers/createGetWrapper.ts +0 -96
- package/src/operations/wrappers/createOneWrapper.ts +0 -128
- package/src/operations/wrappers/createRemoveWrapper.ts +0 -91
- package/src/operations/wrappers/createUpdateWrapper.ts +0 -106
- package/src/operations/wrappers/createUpsertWrapper.ts +0 -108
- package/src/operations/wrappers/index.ts +0 -39
- package/src/operations/wrappers/types.ts +0 -63
- package/src/validation/ItemValidator.ts +0 -131
- package/src/validation/KeyValidator.ts +0 -365
- package/src/validation/LocationValidator.ts +0 -136
- package/src/validation/QueryValidator.ts +0 -250
- package/src/validation/index.ts +0 -32
- package/src/validation/types.ts +0 -45
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wrapper for find() operation
|
|
3
|
-
*
|
|
4
|
-
* Provides automatic validation for find() operation parameters.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Item } from "../../items";
|
|
8
|
-
import type { LocKeyArray } from "../../keys";
|
|
9
|
-
import type { Coordinate } from "../../Coordinate";
|
|
10
|
-
import type { OperationParams } from "../Operations";
|
|
11
|
-
import { validateFinderName, validateLocations, validateOperationParams, validatePK } from "../../validation";
|
|
12
|
-
import type { FindMethod } from "../methods";
|
|
13
|
-
import type { ErrorContext, WrapperOptions } from "./types";
|
|
14
|
-
import LibLogger from "../../logger";
|
|
15
|
-
|
|
16
|
-
const logger = LibLogger.get('operations', 'wrappers', 'find');
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Creates a wrapped find() method with automatic parameter validation.
|
|
20
|
-
*
|
|
21
|
-
* @param coordinate - The coordinate defining the item hierarchy
|
|
22
|
-
* @param implementation - The core logic for the operation
|
|
23
|
-
* @param options - Optional configuration
|
|
24
|
-
* @returns A fully validated find() method
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```typescript
|
|
28
|
-
* const find = createFindWrapper(
|
|
29
|
-
* coordinate,
|
|
30
|
-
* async (finder, params, locations) => {
|
|
31
|
-
* return await database.executeFinder(finder, params, locations);
|
|
32
|
-
* }
|
|
33
|
-
* );
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
export function createFindWrapper<
|
|
37
|
-
V extends Item<S, L1, L2, L3, L4, L5>,
|
|
38
|
-
S extends string,
|
|
39
|
-
L1 extends string = never,
|
|
40
|
-
L2 extends string = never,
|
|
41
|
-
L3 extends string = never,
|
|
42
|
-
L4 extends string = never,
|
|
43
|
-
L5 extends string = never
|
|
44
|
-
>(
|
|
45
|
-
coordinate: Coordinate<S, L1, L2, L3, L4, L5>,
|
|
46
|
-
implementation: FindMethod<V, S, L1, L2, L3, L4, L5>,
|
|
47
|
-
options: WrapperOptions = {}
|
|
48
|
-
): FindMethod<V, S, L1, L2, L3, L4, L5> {
|
|
49
|
-
|
|
50
|
-
const operationName = options.operationName || 'find';
|
|
51
|
-
|
|
52
|
-
return async (
|
|
53
|
-
finder: string,
|
|
54
|
-
params?: OperationParams,
|
|
55
|
-
locations?: LocKeyArray<L1, L2, L3, L4, L5> | []
|
|
56
|
-
): Promise<V[]> => {
|
|
57
|
-
|
|
58
|
-
if (options.debug) {
|
|
59
|
-
logger.debug(`[${operationName}] Called:`, { finder, params, locations });
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Validate
|
|
63
|
-
if (!options.skipValidation) {
|
|
64
|
-
validateFinderName(finder, operationName);
|
|
65
|
-
validateOperationParams(params, operationName);
|
|
66
|
-
validateLocations(locations, coordinate, operationName);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Normalize
|
|
70
|
-
const normalizedParams = params ?? {};
|
|
71
|
-
const normalizedLocations = (locations ?? []) as LocKeyArray<L1, L2, L3, L4, L5> | [];
|
|
72
|
-
|
|
73
|
-
// Execute
|
|
74
|
-
try {
|
|
75
|
-
const result = await implementation(finder, normalizedParams, normalizedLocations);
|
|
76
|
-
|
|
77
|
-
if (options.debug) {
|
|
78
|
-
logger.debug(`[${operationName}] Found ${result.length} items for finder "${finder}"`);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Validate primary key types for all items
|
|
82
|
-
if (!options.skipValidation) {
|
|
83
|
-
return validatePK(result, coordinate.kta[0]) as V[];
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return result;
|
|
87
|
-
|
|
88
|
-
} catch (error) {
|
|
89
|
-
if (options.onError) {
|
|
90
|
-
const context: ErrorContext = {
|
|
91
|
-
operationName,
|
|
92
|
-
params: [finder, params, locations],
|
|
93
|
-
coordinate
|
|
94
|
-
};
|
|
95
|
-
throw options.onError(error as Error, context);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
throw new Error(
|
|
99
|
-
`[${operationName}] Operation failed for finder "${finder}": ${(error as Error).message}`,
|
|
100
|
-
{ cause: error }
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wrapper for get() operation
|
|
3
|
-
*
|
|
4
|
-
* Provides automatic validation for get() operation parameters.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Item } from "../../items";
|
|
8
|
-
import type { ComKey, PriKey } from "../../keys";
|
|
9
|
-
import type { Coordinate } from "../../Coordinate";
|
|
10
|
-
import { validateKey, validatePK } from "../../validation";
|
|
11
|
-
import type { GetMethod } from "../methods";
|
|
12
|
-
import type { ErrorContext, WrapperOptions } from "./types";
|
|
13
|
-
import LibLogger from "../../logger";
|
|
14
|
-
|
|
15
|
-
const logger = LibLogger.get('operations', 'wrappers', 'get');
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Creates a wrapped get() method with automatic parameter validation.
|
|
19
|
-
*
|
|
20
|
-
* @param coordinate - The coordinate defining the item hierarchy
|
|
21
|
-
* @param implementation - The core logic for the operation
|
|
22
|
-
* @param options - Optional configuration
|
|
23
|
-
* @returns A fully validated get() method
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```typescript
|
|
27
|
-
* const get = createGetWrapper(
|
|
28
|
-
* coordinate,
|
|
29
|
-
* async (key) => {
|
|
30
|
-
* return await database.findByKey(key);
|
|
31
|
-
* }
|
|
32
|
-
* );
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
export function createGetWrapper<
|
|
36
|
-
V extends Item<S, L1, L2, L3, L4, L5>,
|
|
37
|
-
S extends string,
|
|
38
|
-
L1 extends string = never,
|
|
39
|
-
L2 extends string = never,
|
|
40
|
-
L3 extends string = never,
|
|
41
|
-
L4 extends string = never,
|
|
42
|
-
L5 extends string = never
|
|
43
|
-
>(
|
|
44
|
-
coordinate: Coordinate<S, L1, L2, L3, L4, L5>,
|
|
45
|
-
implementation: GetMethod<V, S, L1, L2, L3, L4, L5>,
|
|
46
|
-
options: WrapperOptions = {}
|
|
47
|
-
): GetMethod<V, S, L1, L2, L3, L4, L5> {
|
|
48
|
-
|
|
49
|
-
const operationName = options.operationName || 'get';
|
|
50
|
-
|
|
51
|
-
return async (
|
|
52
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>
|
|
53
|
-
): Promise<V | null> => {
|
|
54
|
-
|
|
55
|
-
if (options.debug) {
|
|
56
|
-
logger.debug(`[${operationName}] Called with key:`, key);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Validate key structure
|
|
60
|
-
if (!options.skipValidation) {
|
|
61
|
-
validateKey(key, coordinate, operationName);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Execute
|
|
65
|
-
try {
|
|
66
|
-
const result = await implementation(key);
|
|
67
|
-
|
|
68
|
-
if (options.debug) {
|
|
69
|
-
logger.debug(`[${operationName}] Result:`, result ? 'found' : 'not found');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Validate primary key type if result exists
|
|
73
|
-
if (result && !options.skipValidation) {
|
|
74
|
-
return validatePK(result, coordinate.kta[0]) as V;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return result;
|
|
78
|
-
|
|
79
|
-
} catch (error) {
|
|
80
|
-
if (options.onError) {
|
|
81
|
-
const context: ErrorContext = {
|
|
82
|
-
operationName,
|
|
83
|
-
params: [key],
|
|
84
|
-
coordinate
|
|
85
|
-
};
|
|
86
|
-
throw options.onError(error as Error, context);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
throw new Error(
|
|
90
|
-
`[${operationName}] Operation failed: ${(error as Error).message}`,
|
|
91
|
-
{ cause: error }
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wrapper for one() operation
|
|
3
|
-
*
|
|
4
|
-
* Provides automatic validation for one() operation parameters.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Item } from "../../items";
|
|
8
|
-
import type { ItemQuery } from "../../item/ItemQuery";
|
|
9
|
-
import type { LocKeyArray } from "../../keys";
|
|
10
|
-
import type { Coordinate } from "../../Coordinate";
|
|
11
|
-
import { validateLocations, validatePK, validateQuery } from "../../validation";
|
|
12
|
-
import type { OneMethod } from "../methods";
|
|
13
|
-
import type { ErrorContext, WrapperOptions } from "./types";
|
|
14
|
-
import LibLogger from "../../logger";
|
|
15
|
-
|
|
16
|
-
const logger = LibLogger.get('operations', 'wrappers', 'one');
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Creates a wrapped one() method with automatic parameter validation.
|
|
20
|
-
*
|
|
21
|
-
* The wrapper handles:
|
|
22
|
-
* - Query validation
|
|
23
|
-
* - Location array validation against coordinate
|
|
24
|
-
* - Parameter normalization (undefined → defaults)
|
|
25
|
-
* - Consistent error handling
|
|
26
|
-
*
|
|
27
|
-
* @param coordinate - The coordinate defining the item hierarchy
|
|
28
|
-
* @param implementation - The core logic for the operation (no validation needed)
|
|
29
|
-
* @param options - Optional configuration
|
|
30
|
-
* @returns A fully validated one() method
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* ```typescript
|
|
34
|
-
* const one = createOneWrapper(
|
|
35
|
-
* coordinate,
|
|
36
|
-
* async (query, locations) => {
|
|
37
|
-
* // Just implement the logic - validation is automatic
|
|
38
|
-
* return await database.findOne(query, locations);
|
|
39
|
-
* }
|
|
40
|
-
* );
|
|
41
|
-
*
|
|
42
|
-
* // Usage
|
|
43
|
-
* const item = await one({ status: 'active' }, [{ kt: 'org', lk: '123' }]);
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
export function createOneWrapper<
|
|
47
|
-
V extends Item<S, L1, L2, L3, L4, L5>,
|
|
48
|
-
S extends string,
|
|
49
|
-
L1 extends string = never,
|
|
50
|
-
L2 extends string = never,
|
|
51
|
-
L3 extends string = never,
|
|
52
|
-
L4 extends string = never,
|
|
53
|
-
L5 extends string = never
|
|
54
|
-
>(
|
|
55
|
-
coordinate: Coordinate<S, L1, L2, L3, L4, L5>,
|
|
56
|
-
implementation: OneMethod<V, S, L1, L2, L3, L4, L5>,
|
|
57
|
-
options: WrapperOptions = {}
|
|
58
|
-
): OneMethod<V, S, L1, L2, L3, L4, L5> {
|
|
59
|
-
|
|
60
|
-
const operationName = options.operationName || 'one';
|
|
61
|
-
|
|
62
|
-
return async (
|
|
63
|
-
query?: ItemQuery,
|
|
64
|
-
locations?: LocKeyArray<L1, L2, L3, L4, L5> | []
|
|
65
|
-
): Promise<V | null> => {
|
|
66
|
-
|
|
67
|
-
// Debug logging if enabled
|
|
68
|
-
if (options.debug) {
|
|
69
|
-
logger.debug(`[${operationName}] Called with:`, { query, locations });
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// 1. Validate parameters (unless explicitly skipped)
|
|
73
|
-
if (!options.skipValidation) {
|
|
74
|
-
try {
|
|
75
|
-
validateQuery(query, operationName);
|
|
76
|
-
validateLocations(locations, coordinate, operationName);
|
|
77
|
-
} catch (error) {
|
|
78
|
-
// Validation errors are already well-formatted
|
|
79
|
-
throw error;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// 2. Normalize parameters
|
|
84
|
-
const normalizedQuery = query ?? {};
|
|
85
|
-
const normalizedLocations = (locations ?? []) as LocKeyArray<L1, L2, L3, L4, L5> | [];
|
|
86
|
-
|
|
87
|
-
// 3. Call implementation with validated params
|
|
88
|
-
try {
|
|
89
|
-
const result = await implementation(normalizedQuery, normalizedLocations);
|
|
90
|
-
|
|
91
|
-
if (options.debug) {
|
|
92
|
-
logger.debug(`[${operationName}] Result:`, result ? 'found' : 'not found');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Validate primary key type if result exists
|
|
96
|
-
if (result && !options.skipValidation) {
|
|
97
|
-
return validatePK(result, coordinate.kta[0]) as V;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return result;
|
|
101
|
-
|
|
102
|
-
} catch (error) {
|
|
103
|
-
// 4. Handle errors
|
|
104
|
-
if (options.onError) {
|
|
105
|
-
const context: ErrorContext = {
|
|
106
|
-
operationName,
|
|
107
|
-
params: [query, locations],
|
|
108
|
-
coordinate
|
|
109
|
-
};
|
|
110
|
-
throw options.onError(error as Error, context);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Default error enhancement
|
|
114
|
-
const enhanced = new Error(
|
|
115
|
-
`[${operationName}] Operation failed: ${(error as Error).message}`,
|
|
116
|
-
{ cause: error }
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
// Preserve stack trace
|
|
120
|
-
if ((error as Error).stack) {
|
|
121
|
-
enhanced.stack = (error as Error).stack;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
throw enhanced;
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wrapper for remove() operation
|
|
3
|
-
*
|
|
4
|
-
* Provides automatic validation for remove() operation parameters.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Item } from "../../items";
|
|
8
|
-
import type { ComKey, PriKey } from "../../keys";
|
|
9
|
-
import type { Coordinate } from "../../Coordinate";
|
|
10
|
-
import { validateKey } from "../../validation";
|
|
11
|
-
import type { RemoveMethod } from "../methods";
|
|
12
|
-
import type { ErrorContext, WrapperOptions } from "./types";
|
|
13
|
-
import LibLogger from "../../logger";
|
|
14
|
-
|
|
15
|
-
const logger = LibLogger.get('operations', 'wrappers', 'remove');
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Creates a wrapped remove() method with automatic parameter validation.
|
|
19
|
-
*
|
|
20
|
-
* @param coordinate - The coordinate defining the item hierarchy
|
|
21
|
-
* @param implementation - The core logic for the operation
|
|
22
|
-
* @param options - Optional configuration
|
|
23
|
-
* @returns A fully validated remove() method
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```typescript
|
|
27
|
-
* const remove = createRemoveWrapper(
|
|
28
|
-
* coordinate,
|
|
29
|
-
* async (key) => {
|
|
30
|
-
* return await database.delete(key);
|
|
31
|
-
* }
|
|
32
|
-
* );
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
export function createRemoveWrapper<
|
|
36
|
-
V extends Item<S, L1, L2, L3, L4, L5>,
|
|
37
|
-
S extends string,
|
|
38
|
-
L1 extends string = never,
|
|
39
|
-
L2 extends string = never,
|
|
40
|
-
L3 extends string = never,
|
|
41
|
-
L4 extends string = never,
|
|
42
|
-
L5 extends string = never
|
|
43
|
-
>(
|
|
44
|
-
coordinate: Coordinate<S, L1, L2, L3, L4, L5>,
|
|
45
|
-
implementation: RemoveMethod<V, S, L1, L2, L3, L4, L5>,
|
|
46
|
-
options: WrapperOptions = {}
|
|
47
|
-
): RemoveMethod<V, S, L1, L2, L3, L4, L5> {
|
|
48
|
-
|
|
49
|
-
const operationName = options.operationName || 'remove';
|
|
50
|
-
|
|
51
|
-
return async (
|
|
52
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>
|
|
53
|
-
): Promise<V | void> => {
|
|
54
|
-
|
|
55
|
-
if (options.debug) {
|
|
56
|
-
logger.debug(`[${operationName}] Called with key:`, key);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Validate key structure
|
|
60
|
-
if (!options.skipValidation) {
|
|
61
|
-
validateKey(key, coordinate, operationName);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Execute
|
|
65
|
-
try {
|
|
66
|
-
const result = await implementation(key);
|
|
67
|
-
|
|
68
|
-
if (options.debug) {
|
|
69
|
-
logger.debug(`[${operationName}] Removed item:`, key);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return result;
|
|
73
|
-
|
|
74
|
-
} catch (error) {
|
|
75
|
-
if (options.onError) {
|
|
76
|
-
const context: ErrorContext = {
|
|
77
|
-
operationName,
|
|
78
|
-
params: [key],
|
|
79
|
-
coordinate
|
|
80
|
-
};
|
|
81
|
-
throw options.onError(error as Error, context);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
throw new Error(
|
|
85
|
-
`[${operationName}] Operation failed: ${(error as Error).message}`,
|
|
86
|
-
{ cause: error }
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wrapper for update() operation
|
|
3
|
-
*
|
|
4
|
-
* Provides automatic validation for update() operation parameters.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Item } from "../../items";
|
|
8
|
-
import type { ComKey, PriKey } from "../../keys";
|
|
9
|
-
import type { Coordinate } from "../../Coordinate";
|
|
10
|
-
import { validateKey, validatePK } from "../../validation";
|
|
11
|
-
import type { UpdateMethod } from "../methods";
|
|
12
|
-
import type { ErrorContext, WrapperOptions } from "./types";
|
|
13
|
-
import LibLogger from "../../logger";
|
|
14
|
-
|
|
15
|
-
const logger = LibLogger.get('operations', 'wrappers', 'update');
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Creates a wrapped update() method with automatic parameter validation.
|
|
19
|
-
*
|
|
20
|
-
* @param coordinate - The coordinate defining the item hierarchy
|
|
21
|
-
* @param implementation - The core logic for the operation
|
|
22
|
-
* @param options - Optional configuration
|
|
23
|
-
* @returns A fully validated update() method
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```typescript
|
|
27
|
-
* const update = createUpdateWrapper(
|
|
28
|
-
* coordinate,
|
|
29
|
-
* async (key, item) => {
|
|
30
|
-
* return await database.update(key, item);
|
|
31
|
-
* }
|
|
32
|
-
* );
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
export function createUpdateWrapper<
|
|
36
|
-
V extends Item<S, L1, L2, L3, L4, L5>,
|
|
37
|
-
S extends string,
|
|
38
|
-
L1 extends string = never,
|
|
39
|
-
L2 extends string = never,
|
|
40
|
-
L3 extends string = never,
|
|
41
|
-
L4 extends string = never,
|
|
42
|
-
L5 extends string = never
|
|
43
|
-
>(
|
|
44
|
-
coordinate: Coordinate<S, L1, L2, L3, L4, L5>,
|
|
45
|
-
implementation: UpdateMethod<V, S, L1, L2, L3, L4, L5>,
|
|
46
|
-
options: WrapperOptions = {}
|
|
47
|
-
): UpdateMethod<V, S, L1, L2, L3, L4, L5> {
|
|
48
|
-
|
|
49
|
-
const operationName = options.operationName || 'update';
|
|
50
|
-
|
|
51
|
-
return async (
|
|
52
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,
|
|
53
|
-
item: Partial<Item<S, L1, L2, L3, L4, L5>>
|
|
54
|
-
): Promise<V> => {
|
|
55
|
-
|
|
56
|
-
if (options.debug) {
|
|
57
|
-
logger.debug(`[${operationName}] Called with:`, { key, item });
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Validate
|
|
61
|
-
if (!options.skipValidation) {
|
|
62
|
-
validateKey(key, coordinate, operationName);
|
|
63
|
-
|
|
64
|
-
if (!item || typeof item !== 'object' || Array.isArray(item)) {
|
|
65
|
-
throw new Error(
|
|
66
|
-
`[${operationName}] Invalid item parameter.\n` +
|
|
67
|
-
`\n` +
|
|
68
|
-
`Expected: object\n` +
|
|
69
|
-
`Received: ${Array.isArray(item) ? 'array' : typeof item}`
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Execute
|
|
75
|
-
try {
|
|
76
|
-
const result = await implementation(key, item);
|
|
77
|
-
|
|
78
|
-
if (options.debug) {
|
|
79
|
-
logger.debug(`[${operationName}] Updated item:`, result.key);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Validate primary key type
|
|
83
|
-
if (!options.skipValidation) {
|
|
84
|
-
return validatePK(result, coordinate.kta[0]) as V;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return result;
|
|
88
|
-
|
|
89
|
-
} catch (error) {
|
|
90
|
-
if (options.onError) {
|
|
91
|
-
const context: ErrorContext = {
|
|
92
|
-
operationName,
|
|
93
|
-
params: [key, item],
|
|
94
|
-
coordinate
|
|
95
|
-
};
|
|
96
|
-
throw options.onError(error as Error, context);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
throw new Error(
|
|
100
|
-
`[${operationName}] Operation failed: ${(error as Error).message}`,
|
|
101
|
-
{ cause: error }
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wrapper for upsert() operation
|
|
3
|
-
*
|
|
4
|
-
* Provides automatic validation for upsert() operation parameters.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Item } from "../../items";
|
|
8
|
-
import type { ComKey, LocKeyArray, PriKey } from "../../keys";
|
|
9
|
-
import type { Coordinate } from "../../Coordinate";
|
|
10
|
-
import { validateKey, validateLocations, validatePK } from "../../validation";
|
|
11
|
-
import type { UpsertMethod } from "../methods";
|
|
12
|
-
import type { ErrorContext, WrapperOptions } from "./types";
|
|
13
|
-
import LibLogger from "../../logger";
|
|
14
|
-
|
|
15
|
-
const logger = LibLogger.get('operations', 'wrappers', 'upsert');
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Creates a wrapped upsert() method with automatic parameter validation.
|
|
19
|
-
*
|
|
20
|
-
* @param coordinate - The coordinate defining the item hierarchy
|
|
21
|
-
* @param implementation - The core logic for the operation
|
|
22
|
-
* @param options - Optional configuration
|
|
23
|
-
* @returns A fully validated upsert() method
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```typescript
|
|
27
|
-
* const upsert = createUpsertWrapper(
|
|
28
|
-
* coordinate,
|
|
29
|
-
* async (key, item, locations) => {
|
|
30
|
-
* return await database.upsert(key, item, locations);
|
|
31
|
-
* }
|
|
32
|
-
* );
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
export function createUpsertWrapper<
|
|
36
|
-
V extends Item<S, L1, L2, L3, L4, L5>,
|
|
37
|
-
S extends string,
|
|
38
|
-
L1 extends string = never,
|
|
39
|
-
L2 extends string = never,
|
|
40
|
-
L3 extends string = never,
|
|
41
|
-
L4 extends string = never,
|
|
42
|
-
L5 extends string = never
|
|
43
|
-
>(
|
|
44
|
-
coordinate: Coordinate<S, L1, L2, L3, L4, L5>,
|
|
45
|
-
implementation: UpsertMethod<V, S, L1, L2, L3, L4, L5>,
|
|
46
|
-
options: WrapperOptions = {}
|
|
47
|
-
): UpsertMethod<V, S, L1, L2, L3, L4, L5> {
|
|
48
|
-
|
|
49
|
-
const operationName = options.operationName || 'upsert';
|
|
50
|
-
|
|
51
|
-
return async (
|
|
52
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,
|
|
53
|
-
item: Partial<Item<S, L1, L2, L3, L4, L5>>,
|
|
54
|
-
locations?: LocKeyArray<L1, L2, L3, L4, L5>
|
|
55
|
-
): Promise<V> => {
|
|
56
|
-
|
|
57
|
-
if (options.debug) {
|
|
58
|
-
logger.debug(`[${operationName}] Called with:`, { key, item, locations });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Validate
|
|
62
|
-
if (!options.skipValidation) {
|
|
63
|
-
validateKey(key, coordinate, operationName);
|
|
64
|
-
validateLocations(locations, coordinate, operationName);
|
|
65
|
-
|
|
66
|
-
if (!item || typeof item !== 'object' || Array.isArray(item)) {
|
|
67
|
-
throw new Error(
|
|
68
|
-
`[${operationName}] Invalid item parameter.\n` +
|
|
69
|
-
`\n` +
|
|
70
|
-
`Expected: object\n` +
|
|
71
|
-
`Received: ${Array.isArray(item) ? 'array' : typeof item}`
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Execute
|
|
77
|
-
try {
|
|
78
|
-
const result = await implementation(key, item);
|
|
79
|
-
|
|
80
|
-
if (options.debug) {
|
|
81
|
-
logger.debug(`[${operationName}] Upserted item:`, result.key);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Validate primary key type
|
|
85
|
-
if (!options.skipValidation) {
|
|
86
|
-
return validatePK(result, coordinate.kta[0]) as V;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return result;
|
|
90
|
-
|
|
91
|
-
} catch (error) {
|
|
92
|
-
if (options.onError) {
|
|
93
|
-
const context: ErrorContext = {
|
|
94
|
-
operationName,
|
|
95
|
-
params: [key, item, locations],
|
|
96
|
-
coordinate
|
|
97
|
-
};
|
|
98
|
-
throw options.onError(error as Error, context);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
throw new Error(
|
|
102
|
-
`[${operationName}] Operation failed: ${(error as Error).message}`,
|
|
103
|
-
{ cause: error }
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Operation wrapper functions that provide automatic parameter validation.
|
|
3
|
-
*
|
|
4
|
-
* These wrappers eliminate boilerplate validation code in Operations implementations.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```typescript
|
|
8
|
-
* import { createOneWrapper } from '@fjell/core';
|
|
9
|
-
*
|
|
10
|
-
* const one = createOneWrapper(
|
|
11
|
-
* coordinate,
|
|
12
|
-
* async (query, locations) => {
|
|
13
|
-
* // Validation happens automatically
|
|
14
|
-
* return await database.findOne(query, locations);
|
|
15
|
-
* }
|
|
16
|
-
* );
|
|
17
|
-
* ```
|
|
18
|
-
*
|
|
19
|
-
* @module wrappers
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
// Types
|
|
23
|
-
export type { WrapperOptions, ErrorContext, WrapperContext } from './types';
|
|
24
|
-
|
|
25
|
-
// Wrapper functions
|
|
26
|
-
export { createOneWrapper } from './createOneWrapper';
|
|
27
|
-
export { createAllWrapper } from './createAllWrapper';
|
|
28
|
-
export { createGetWrapper } from './createGetWrapper';
|
|
29
|
-
export { createCreateWrapper } from './createCreateWrapper';
|
|
30
|
-
export { createUpdateWrapper } from './createUpdateWrapper';
|
|
31
|
-
export { createUpsertWrapper } from './createUpsertWrapper';
|
|
32
|
-
export { createRemoveWrapper } from './createRemoveWrapper';
|
|
33
|
-
export { createFindWrapper } from './createFindWrapper';
|
|
34
|
-
export { createFindOneWrapper } from './createFindOneWrapper';
|
|
35
|
-
export { createActionWrapper } from './createActionWrapper';
|
|
36
|
-
export { createAllActionWrapper } from './createAllActionWrapper';
|
|
37
|
-
export { createFacetWrapper } from './createFacetWrapper';
|
|
38
|
-
export { createAllFacetWrapper } from './createAllFacetWrapper';
|
|
39
|
-
|