@fgv/ts-utils 5.0.2 → 5.1.0-1
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/README.md +152 -84
- package/dist/index.js +2 -2
- package/dist/packlets/base/messageAggregator.js +6 -6
- package/dist/packlets/base/result.js +39 -39
- package/dist/packlets/base/utils.js +47 -0
- package/dist/packlets/collections/aggregatedResultMap.js +722 -0
- package/dist/packlets/collections/collector.js +9 -9
- package/dist/packlets/collections/collectorValidator.js +4 -4
- package/dist/packlets/collections/converters.js +39 -0
- package/dist/packlets/collections/convertingCollectorValidator.js +3 -3
- package/dist/packlets/collections/convertingResultMap.js +208 -0
- package/dist/packlets/collections/index.js +4 -0
- package/dist/packlets/collections/keyValueConverters.js +1 -4
- package/dist/packlets/collections/readOnlyConvertingResultMap.js +193 -0
- package/dist/packlets/collections/resultMapValidator.js +50 -6
- package/dist/packlets/collections/validatingConvertingResultMap.js +78 -0
- package/dist/packlets/conversion/advancedConverters.js +249 -0
- package/dist/packlets/conversion/baseConverter.js +23 -16
- package/dist/packlets/conversion/basicConverters.js +571 -0
- package/dist/packlets/conversion/converters.js +3 -617
- package/dist/packlets/conversion/defaultingConverter.js +21 -15
- package/dist/packlets/logging/bootLogger.js +122 -0
- package/dist/packlets/logging/index.js +1 -0
- package/dist/packlets/logging/logReporter.js +32 -1
- package/dist/packlets/logging/logger.js +25 -5
- package/dist/packlets/validation/classes.js +1 -0
- package/dist/packlets/validation/compositeId.js +60 -0
- package/dist/packlets/validation/field.js +1 -1
- package/dist/packlets/validation/genericValidator.js +24 -10
- package/dist/packlets/validation/object.js +3 -6
- package/dist/packlets/validation/validators.js +12 -0
- package/dist/ts-utils.d.ts +1633 -200
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -1
- package/lib/packlets/base/mapResults.d.ts +3 -3
- package/lib/packlets/base/messageAggregator.d.ts +6 -6
- package/lib/packlets/base/messageAggregator.js +6 -6
- package/lib/packlets/base/result.d.ts +74 -51
- package/lib/packlets/base/result.js +39 -39
- package/lib/packlets/base/utils.d.ts +42 -0
- package/lib/packlets/base/utils.js +52 -0
- package/lib/packlets/collections/aggregatedResultMap.d.ts +433 -0
- package/lib/packlets/collections/aggregatedResultMap.js +728 -0
- package/lib/packlets/collections/collector.d.ts +11 -10
- package/lib/packlets/collections/collector.js +9 -9
- package/lib/packlets/collections/collectorValidator.d.ts +12 -10
- package/lib/packlets/collections/collectorValidator.js +4 -4
- package/lib/packlets/collections/converters.d.ts +18 -0
- package/lib/packlets/collections/converters.js +42 -0
- package/lib/packlets/collections/convertingCollector.d.ts +4 -4
- package/lib/packlets/collections/convertingCollectorValidator.d.ts +10 -7
- package/lib/packlets/collections/convertingCollectorValidator.js +3 -3
- package/lib/packlets/collections/convertingResultMap.d.ts +176 -0
- package/lib/packlets/collections/convertingResultMap.js +213 -0
- package/lib/packlets/collections/index.d.ts +4 -0
- package/lib/packlets/collections/index.js +4 -0
- package/lib/packlets/collections/keyValueConverters.d.ts +1 -4
- package/lib/packlets/collections/keyValueConverters.js +1 -4
- package/lib/packlets/collections/readOnlyConvertingResultMap.d.ts +153 -0
- package/lib/packlets/collections/readOnlyConvertingResultMap.js +197 -0
- package/lib/packlets/collections/readonlyResultMap.d.ts +7 -7
- package/lib/packlets/collections/resultMap.d.ts +108 -2
- package/lib/packlets/collections/resultMapValidator.d.ts +45 -11
- package/lib/packlets/collections/resultMapValidator.js +52 -7
- package/lib/packlets/collections/validatingCollector.d.ts +5 -5
- package/lib/packlets/collections/validatingConvertingCollector.d.ts +3 -3
- package/lib/packlets/collections/validatingConvertingResultMap.d.ts +102 -0
- package/lib/packlets/collections/validatingConvertingResultMap.js +83 -0
- package/lib/packlets/collections/validatingResultMap.d.ts +1 -1
- package/lib/packlets/conversion/advancedConverters.d.ts +170 -0
- package/lib/packlets/conversion/advancedConverters.js +258 -0
- package/lib/packlets/conversion/baseConverter.d.ts +39 -23
- package/lib/packlets/conversion/baseConverter.js +23 -16
- package/lib/packlets/conversion/basicConverters.d.ts +470 -0
- package/lib/packlets/conversion/basicConverters.js +595 -0
- package/lib/packlets/conversion/converter.d.ts +7 -0
- package/lib/packlets/conversion/converters.d.ts +2 -535
- package/lib/packlets/conversion/converters.js +17 -639
- package/lib/packlets/conversion/defaultingConverter.d.ts +20 -16
- package/lib/packlets/conversion/defaultingConverter.js +21 -15
- package/lib/packlets/logging/bootLogger.d.ts +84 -0
- package/lib/packlets/logging/bootLogger.js +126 -0
- package/lib/packlets/logging/index.d.ts +1 -0
- package/lib/packlets/logging/index.js +1 -0
- package/lib/packlets/logging/logReporter.d.ts +18 -3
- package/lib/packlets/logging/logReporter.js +31 -0
- package/lib/packlets/logging/logger.d.ts +39 -6
- package/lib/packlets/logging/logger.js +26 -5
- package/lib/packlets/validation/classes.d.ts +1 -0
- package/lib/packlets/validation/classes.js +3 -1
- package/lib/packlets/validation/compositeId.d.ts +29 -0
- package/lib/packlets/validation/compositeId.js +64 -0
- package/lib/packlets/validation/field.d.ts +1 -1
- package/lib/packlets/validation/field.js +1 -1
- package/lib/packlets/validation/genericValidator.d.ts +15 -11
- package/lib/packlets/validation/genericValidator.js +24 -10
- package/lib/packlets/validation/object.d.ts +3 -6
- package/lib/packlets/validation/object.js +3 -6
- package/lib/packlets/validation/traits.d.ts +3 -3
- package/lib/packlets/validation/validator.d.ts +7 -0
- package/lib/packlets/validation/validators.d.ts +10 -0
- package/lib/packlets/validation/validators.js +13 -0
- package/package.json +27 -27
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { Validator } from '../validation';
|
|
2
|
+
import { ConverterResultTypes } from './baseConverter';
|
|
3
|
+
import { Converter } from './converter';
|
|
4
|
+
import { FieldConverters } from './objectConverter';
|
|
5
|
+
/**
|
|
6
|
+
* Represents a composite ID constructed of two strongly-typed string IDs
|
|
7
|
+
* separated by a delimiter.
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export interface ICompositeId<TCOLLECTIONID extends string, TITEMID extends string> {
|
|
11
|
+
readonly collectionId: TCOLLECTIONID;
|
|
12
|
+
readonly separator: string;
|
|
13
|
+
readonly itemId: TITEMID;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Represents a partial composite ID, where separator is optional.
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
export interface IPartialCompositeId<TCOLLECTIONID extends string, TITEMID extends string> {
|
|
20
|
+
readonly collectionId: TCOLLECTIONID;
|
|
21
|
+
readonly separator?: string;
|
|
22
|
+
readonly itemId: TITEMID;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates an {@link ObjectConverter | ObjectConverter} for a strongly-typed {@link Converters.ICompositeId | CompositeId}.
|
|
26
|
+
* @param collectionIdValidator - {@link Converter | Converter} or {@link Validator | Validator} for the collection ID portion.
|
|
27
|
+
* @param separator - The separator string.
|
|
28
|
+
* @param itemIdValidator - {@link Converter | Converter} or {@link Validator | Validator} for the item ID portion.
|
|
29
|
+
* @returns An {@link ObjectConverter | ObjectConverter} for the strongly-typed composite ICompositeId.
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
export declare function compositeIdFromObject<TCOLLECTIONID extends string, TITEMID extends string, TC = unknown>(collectionIdValidator: Converter<TCOLLECTIONID, TC> | Validator<TCOLLECTIONID, TC>, separator: string, itemIdValidator: Converter<TITEMID, TC> | Validator<TITEMID, TC>): Converter<ICompositeId<TCOLLECTIONID, TITEMID>, TC>;
|
|
33
|
+
/**
|
|
34
|
+
* Converts a composite ID string into a strongly-typed {@link Converters.ICompositeId | CompositeId}.
|
|
35
|
+
* @param collectionIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the collection ID portion.
|
|
36
|
+
* @param separator - The separator string.
|
|
37
|
+
* @param itemIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the item ID portion.
|
|
38
|
+
* @returns A {@link Converter | Converter} for the strongly-typed {@link Converters.ICompositeId | CompositeId}.
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export declare function compositeIdFromString<TCOLLECTIONID extends string, TITEMID extends string, TC = unknown>(collectionIdConverter: Converter<TCOLLECTIONID, TC> | Validator<TCOLLECTIONID, TC>, separator: string, itemIdConverter: Converter<TITEMID, TC> | Validator<TITEMID, TC>): Converter<ICompositeId<TCOLLECTIONID, TITEMID>, TC>;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a {@link Converter | Converter} for a strongly-typed {@link Converters.ICompositeId | CompositeId} from
|
|
44
|
+
* either a string or an object representation.
|
|
45
|
+
* @param collectionIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the collection ID portion.
|
|
46
|
+
* @param separator - The separator string.
|
|
47
|
+
* @param itemIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the item ID portion.
|
|
48
|
+
* @returns A {@link Converter | Converter} for the strongly-typed {@link Converters.ICompositeId | CompositeId}.
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
export declare function compositeId<TCOLLECTIONID extends string, TITEMID extends string, TC = unknown>(collectionIdConverter: Converter<TCOLLECTIONID, TC> | Validator<TCOLLECTIONID, TC>, separator: string, itemIdConverter: Converter<TITEMID, TC> | Validator<TITEMID, TC>): Converter<ICompositeId<TCOLLECTIONID, TITEMID>, TC>;
|
|
52
|
+
/**
|
|
53
|
+
* Converts a strongly-typed {@link Converters.ICompositeId | CompositeId} into a string.
|
|
54
|
+
* @param compositeIdConverter - {@link Converter | Converter} or {@link Validator | Validator} that validates/converts the composite ID string.
|
|
55
|
+
* @param collectionIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the collection ID portion.
|
|
56
|
+
* @param separator - The separator string.
|
|
57
|
+
* @param itemIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the item ID portion.
|
|
58
|
+
* @returns A {@link Converter | Converter} which produces a composite ID string.
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
export declare function compositeIdString<T extends string, TCOLLECTIONID extends string, TITEMID extends string, TC = unknown>(compositeIdConverter: Validator<T, TC> | Converter<T, TC>, collectionIdConverter: Converter<TCOLLECTIONID, TC> | Validator<TCOLLECTIONID, TC>, separator: string, itemIdConverter: Converter<TITEMID, TC> | Validator<TITEMID, TC>): Converter<T, TC>;
|
|
62
|
+
/**
|
|
63
|
+
* Helper to create a {@link Converter | Converter} which converts a source object to a new object with a
|
|
64
|
+
* different shape.
|
|
65
|
+
*
|
|
66
|
+
* @remarks
|
|
67
|
+
* On successful conversion, the resulting {@link Converter | Converter} returns {@link Success | Success} with a new
|
|
68
|
+
* object, which contains the converted values under the key names specified at initialization time.
|
|
69
|
+
* It returns {@link Failure | Failure} with an error message if any fields to be extracted do not exist
|
|
70
|
+
* or cannot be converted.
|
|
71
|
+
*
|
|
72
|
+
* Fields that succeed but convert to undefined are omitted from the result object but do not
|
|
73
|
+
* fail the conversion.
|
|
74
|
+
*
|
|
75
|
+
* @param properties - An object with key names that correspond to the target object and an
|
|
76
|
+
* appropriate {@link Conversion.FieldConverters | FieldConverter} which extracts and converts
|
|
77
|
+
* a single filed from the source object.
|
|
78
|
+
* @returns A {@link Converter | Converter} with the specified conversion behavior.
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
export declare function transform<T, TC = unknown>(properties: FieldConverters<T, TC>): Converter<T, TC>;
|
|
82
|
+
/**
|
|
83
|
+
* Per-property converters and configuration for each field in the destination object of
|
|
84
|
+
* a {@link Converters.transformObject} call.
|
|
85
|
+
* @public
|
|
86
|
+
*/
|
|
87
|
+
export type FieldTransformers<TSRC, TDEST, TC = unknown> = {
|
|
88
|
+
[key in keyof TDEST]: {
|
|
89
|
+
/**
|
|
90
|
+
* The name of the property in the source object to be converted.
|
|
91
|
+
*/
|
|
92
|
+
from: keyof TSRC;
|
|
93
|
+
/**
|
|
94
|
+
* The converter or validator used to convert the property.
|
|
95
|
+
*/
|
|
96
|
+
converter: Converter<TDEST[key], TC> | Validator<TDEST[key], TC>;
|
|
97
|
+
/**
|
|
98
|
+
* If `true` then a missing source property is ignored. If `false` or omitted
|
|
99
|
+
* then a missing source property causes an error.
|
|
100
|
+
*/
|
|
101
|
+
optional?: boolean;
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Options for a {@link Converters.transformObject} call.
|
|
106
|
+
* @public
|
|
107
|
+
*/
|
|
108
|
+
export interface TransformObjectOptions<TSRC> {
|
|
109
|
+
/**
|
|
110
|
+
* If `strict` is `true` then unused properties in the source object cause
|
|
111
|
+
* an error, otherwise they are ignored.
|
|
112
|
+
*/
|
|
113
|
+
strict: true;
|
|
114
|
+
/**
|
|
115
|
+
* An optional list of source properties to be ignored when strict mode
|
|
116
|
+
* is enabled.
|
|
117
|
+
*/
|
|
118
|
+
ignore?: (keyof TSRC)[];
|
|
119
|
+
/**
|
|
120
|
+
* An optional description of this transform to be used for error messages.
|
|
121
|
+
*/
|
|
122
|
+
description?: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Helper to create a strongly-typed {@link Converter | Converter} which converts a source object to a
|
|
126
|
+
* new object with a different shape.
|
|
127
|
+
*
|
|
128
|
+
* @remarks
|
|
129
|
+
* On successful conversion, the resulting {@link Converter | Converter} returns {@link Success | Success} with a new
|
|
130
|
+
* object, which contains the converted values under the key names specified at initialization time.
|
|
131
|
+
*
|
|
132
|
+
* It returns {@link Failure | Failure} with an error message if any fields to be extracted do not exist
|
|
133
|
+
* or cannot be converted.
|
|
134
|
+
*
|
|
135
|
+
* @param destinationFields - An object with key names that correspond to the target object and an
|
|
136
|
+
* appropriate {@link Converters.FieldTransformers | FieldTransformers} which specifies the name
|
|
137
|
+
* of the corresponding property in the source object, the converter or validator used for each source
|
|
138
|
+
* property and any other configuration to guide the conversion.
|
|
139
|
+
* @param options - Options which affect the transformation.
|
|
140
|
+
*
|
|
141
|
+
* @returns A {@link Converter | Converter} with the specified conversion behavior.
|
|
142
|
+
* @public
|
|
143
|
+
*/
|
|
144
|
+
export declare function transformObject<TSRC, TDEST, TC = unknown>(destinationFields: FieldTransformers<TSRC, TDEST, TC>, options?: TransformObjectOptions<TSRC>): Converter<TDEST, TC>;
|
|
145
|
+
/**
|
|
146
|
+
* Creates a {@link Converter | Converter} that converts an array to a strongly-typed tuple,
|
|
147
|
+
* using the supplied tuple of {@link Converter | Converters} to convert each element.
|
|
148
|
+
*
|
|
149
|
+
* @remarks
|
|
150
|
+
* The resulting {@link Converter | Converter} returns {@link Success | Success} with a tuple
|
|
151
|
+
* containing the converted values if all conversions succeed. Returns {@link Failure | Failure}
|
|
152
|
+
* with an error message if the source is not an array, has the wrong number of elements, or
|
|
153
|
+
* any element conversion fails.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const converter = tuple([Converters.string, Converters.number, Converters.boolean]);
|
|
158
|
+
* // Type is Converter<[string, number, boolean]>
|
|
159
|
+
*
|
|
160
|
+
* converter.convert(['hello', 42, true]);
|
|
161
|
+
* // Returns Success with ['hello', 42, true]
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* @param converters - A tuple of {@link Converter | Converters} defining the expected types
|
|
165
|
+
* for each element of the tuple.
|
|
166
|
+
* @returns A {@link Converter | Converter} that returns a strongly-typed tuple.
|
|
167
|
+
* @public
|
|
168
|
+
*/
|
|
169
|
+
export declare function tuple<T extends readonly Converter<unknown, TC>[], TC = unknown>(converters: [...T]): Converter<ConverterResultTypes<T>, TC>;
|
|
170
|
+
//# sourceMappingURL=advancedConverters.d.ts.map
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2020 Erik Fortune
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
* in the Software without restriction, including without limitation the rights
|
|
8
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
* furnished to do so, subject to the following conditions:
|
|
11
|
+
*
|
|
12
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
* copies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
* SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.compositeIdFromObject = compositeIdFromObject;
|
|
25
|
+
exports.compositeIdFromString = compositeIdFromString;
|
|
26
|
+
exports.compositeId = compositeId;
|
|
27
|
+
exports.compositeIdString = compositeIdString;
|
|
28
|
+
exports.transform = transform;
|
|
29
|
+
exports.transformObject = transformObject;
|
|
30
|
+
exports.tuple = tuple;
|
|
31
|
+
const base_1 = require("../base");
|
|
32
|
+
const baseConverter_1 = require("./baseConverter");
|
|
33
|
+
const basicConverters_1 = require("./basicConverters");
|
|
34
|
+
const objectConverter_1 = require("./objectConverter");
|
|
35
|
+
/**
|
|
36
|
+
* Creates an {@link ObjectConverter | ObjectConverter} for a strongly-typed {@link Converters.ICompositeId | CompositeId}.
|
|
37
|
+
* @param collectionIdValidator - {@link Converter | Converter} or {@link Validator | Validator} for the collection ID portion.
|
|
38
|
+
* @param separator - The separator string.
|
|
39
|
+
* @param itemIdValidator - {@link Converter | Converter} or {@link Validator | Validator} for the item ID portion.
|
|
40
|
+
* @returns An {@link ObjectConverter | ObjectConverter} for the strongly-typed composite ICompositeId.
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
function compositeIdFromObject(collectionIdValidator, separator, itemIdValidator) {
|
|
44
|
+
return new objectConverter_1.ObjectConverter({
|
|
45
|
+
collectionId: collectionIdValidator,
|
|
46
|
+
separator: (0, basicConverters_1.literal)(separator).optional(),
|
|
47
|
+
itemId: itemIdValidator
|
|
48
|
+
}).map((obj) => {
|
|
49
|
+
var _a;
|
|
50
|
+
return base_1.Success.with({
|
|
51
|
+
collectionId: obj.collectionId,
|
|
52
|
+
separator: (_a = obj.separator) !== null && _a !== void 0 ? _a : separator,
|
|
53
|
+
itemId: obj.itemId
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Converts a composite ID string into a strongly-typed {@link Converters.ICompositeId | CompositeId}.
|
|
59
|
+
* @param collectionIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the collection ID portion.
|
|
60
|
+
* @param separator - The separator string.
|
|
61
|
+
* @param itemIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the item ID portion.
|
|
62
|
+
* @returns A {@link Converter | Converter} for the strongly-typed {@link Converters.ICompositeId | CompositeId}.
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
function compositeIdFromString(collectionIdConverter, separator, itemIdConverter) {
|
|
66
|
+
return new baseConverter_1.BaseConverter((from, __self, context) => {
|
|
67
|
+
if (typeof from !== 'string') {
|
|
68
|
+
return (0, base_1.fail)(`${from}: invalid non-string composite ID.`);
|
|
69
|
+
}
|
|
70
|
+
const parts = from.split(separator);
|
|
71
|
+
if (parts.length < 2) {
|
|
72
|
+
return (0, base_1.fail)(`${from}: invalid composite ID - separator '${separator}' not found.`);
|
|
73
|
+
}
|
|
74
|
+
else if (parts.length > 2) {
|
|
75
|
+
return (0, base_1.fail)(`${from}: invalid composite ID - multiple separators '${separator}.' found.`);
|
|
76
|
+
}
|
|
77
|
+
return collectionIdConverter.convert(parts[0], context).onSuccess((collectionId) => {
|
|
78
|
+
return itemIdConverter.convert(parts[1], context).onSuccess((itemId) => {
|
|
79
|
+
return (0, base_1.succeed)({
|
|
80
|
+
collectionId,
|
|
81
|
+
separator,
|
|
82
|
+
itemId
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Creates a {@link Converter | Converter} for a strongly-typed {@link Converters.ICompositeId | CompositeId} from
|
|
90
|
+
* either a string or an object representation.
|
|
91
|
+
* @param collectionIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the collection ID portion.
|
|
92
|
+
* @param separator - The separator string.
|
|
93
|
+
* @param itemIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the item ID portion.
|
|
94
|
+
* @returns A {@link Converter | Converter} for the strongly-typed {@link Converters.ICompositeId | CompositeId}.
|
|
95
|
+
* @public
|
|
96
|
+
*/
|
|
97
|
+
function compositeId(collectionIdConverter, separator, itemIdConverter) {
|
|
98
|
+
return compositeIdFromObject(collectionIdConverter, separator, itemIdConverter).or(compositeIdFromString(collectionIdConverter, separator, itemIdConverter));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Converts a strongly-typed {@link Converters.ICompositeId | CompositeId} into a string.
|
|
102
|
+
* @param compositeIdConverter - {@link Converter | Converter} or {@link Validator | Validator} that validates/converts the composite ID string.
|
|
103
|
+
* @param collectionIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the collection ID portion.
|
|
104
|
+
* @param separator - The separator string.
|
|
105
|
+
* @param itemIdConverter - {@link Converter | Converter} or {@link Validator | Validator} for the item ID portion.
|
|
106
|
+
* @returns A {@link Converter | Converter} which produces a composite ID string.
|
|
107
|
+
* @public
|
|
108
|
+
*/
|
|
109
|
+
function compositeIdString(compositeIdConverter, collectionIdConverter, separator, itemIdConverter) {
|
|
110
|
+
const objectConverter = compositeIdFromObject(collectionIdConverter, separator, itemIdConverter);
|
|
111
|
+
return new baseConverter_1.BaseConverter((from, __self, context) => {
|
|
112
|
+
if (typeof from === 'string') {
|
|
113
|
+
return compositeIdConverter.convert(from, context);
|
|
114
|
+
}
|
|
115
|
+
return objectConverter.convert(from, context).onSuccess((compositeId) => {
|
|
116
|
+
return compositeIdConverter.convert(`${compositeId.collectionId}${separator}${compositeId.itemId}`);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Helper to create a {@link Converter | Converter} which converts a source object to a new object with a
|
|
122
|
+
* different shape.
|
|
123
|
+
*
|
|
124
|
+
* @remarks
|
|
125
|
+
* On successful conversion, the resulting {@link Converter | Converter} returns {@link Success | Success} with a new
|
|
126
|
+
* object, which contains the converted values under the key names specified at initialization time.
|
|
127
|
+
* It returns {@link Failure | Failure} with an error message if any fields to be extracted do not exist
|
|
128
|
+
* or cannot be converted.
|
|
129
|
+
*
|
|
130
|
+
* Fields that succeed but convert to undefined are omitted from the result object but do not
|
|
131
|
+
* fail the conversion.
|
|
132
|
+
*
|
|
133
|
+
* @param properties - An object with key names that correspond to the target object and an
|
|
134
|
+
* appropriate {@link Conversion.FieldConverters | FieldConverter} which extracts and converts
|
|
135
|
+
* a single filed from the source object.
|
|
136
|
+
* @returns A {@link Converter | Converter} with the specified conversion behavior.
|
|
137
|
+
* @public
|
|
138
|
+
*/
|
|
139
|
+
function transform(properties) {
|
|
140
|
+
return new baseConverter_1.BaseConverter((from, __self, context) => {
|
|
141
|
+
// eslint bug thinks key is used before defined
|
|
142
|
+
const converted = {};
|
|
143
|
+
const errors = [];
|
|
144
|
+
for (const key in properties) {
|
|
145
|
+
if (properties[key]) {
|
|
146
|
+
const result = properties[key].convert(from, context);
|
|
147
|
+
if (result.isSuccess() && result.value !== undefined) {
|
|
148
|
+
converted[key] = result.value;
|
|
149
|
+
}
|
|
150
|
+
else if (result.isFailure()) {
|
|
151
|
+
errors.push(result.message);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return errors.length === 0 ? (0, base_1.succeed)(converted) : (0, base_1.fail)(errors.join('\n'));
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Helper to create a strongly-typed {@link Converter | Converter} which converts a source object to a
|
|
160
|
+
* new object with a different shape.
|
|
161
|
+
*
|
|
162
|
+
* @remarks
|
|
163
|
+
* On successful conversion, the resulting {@link Converter | Converter} returns {@link Success | Success} with a new
|
|
164
|
+
* object, which contains the converted values under the key names specified at initialization time.
|
|
165
|
+
*
|
|
166
|
+
* It returns {@link Failure | Failure} with an error message if any fields to be extracted do not exist
|
|
167
|
+
* or cannot be converted.
|
|
168
|
+
*
|
|
169
|
+
* @param destinationFields - An object with key names that correspond to the target object and an
|
|
170
|
+
* appropriate {@link Converters.FieldTransformers | FieldTransformers} which specifies the name
|
|
171
|
+
* of the corresponding property in the source object, the converter or validator used for each source
|
|
172
|
+
* property and any other configuration to guide the conversion.
|
|
173
|
+
* @param options - Options which affect the transformation.
|
|
174
|
+
*
|
|
175
|
+
* @returns A {@link Converter | Converter} with the specified conversion behavior.
|
|
176
|
+
* @public
|
|
177
|
+
*/
|
|
178
|
+
function transformObject(destinationFields, options) {
|
|
179
|
+
return new baseConverter_1.BaseConverter((from, __self, context) => {
|
|
180
|
+
// eslint bug thinks key is used before defined
|
|
181
|
+
const converted = {};
|
|
182
|
+
const errors = [];
|
|
183
|
+
const used = new Set(options === null || options === void 0 ? void 0 : options.ignore);
|
|
184
|
+
if (typeof from === 'object' && !Array.isArray(from) && from !== null) {
|
|
185
|
+
for (const destinationKey in destinationFields) {
|
|
186
|
+
if (destinationFields[destinationKey]) {
|
|
187
|
+
const srcKey = destinationFields[destinationKey].from;
|
|
188
|
+
const converter = destinationFields[destinationKey].converter;
|
|
189
|
+
if ((0, base_1.isKeyOf)(srcKey, from)) {
|
|
190
|
+
const result = converter.convert(from[srcKey], context);
|
|
191
|
+
if (result.isSuccess() && result.value !== undefined) {
|
|
192
|
+
converted[destinationKey] = result.value;
|
|
193
|
+
}
|
|
194
|
+
else if (result.isFailure()) {
|
|
195
|
+
errors.push(`${srcKey}->${destinationKey}: ${result.message}`);
|
|
196
|
+
}
|
|
197
|
+
used.add(srcKey);
|
|
198
|
+
}
|
|
199
|
+
else if (destinationFields[destinationKey].optional !== true) {
|
|
200
|
+
errors.push(`${String(srcKey)}: required property missing in source object.`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if ((options === null || options === void 0 ? void 0 : options.strict) === true) {
|
|
205
|
+
for (const key in from) {
|
|
206
|
+
if ((0, base_1.isKeyOf)(key, from) && !used.has(key)) {
|
|
207
|
+
errors.push(`${key}: unexpected property in source object`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
errors.push('source is not an object');
|
|
214
|
+
}
|
|
215
|
+
return errors.length === 0
|
|
216
|
+
? (0, base_1.succeed)(converted)
|
|
217
|
+
: (0, base_1.fail)((options === null || options === void 0 ? void 0 : options.description) ? `${options.description}:\n ${errors.join('\n ')}` : errors.join('\n'));
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Creates a {@link Converter | Converter} that converts an array to a strongly-typed tuple,
|
|
222
|
+
* using the supplied tuple of {@link Converter | Converters} to convert each element.
|
|
223
|
+
*
|
|
224
|
+
* @remarks
|
|
225
|
+
* The resulting {@link Converter | Converter} returns {@link Success | Success} with a tuple
|
|
226
|
+
* containing the converted values if all conversions succeed. Returns {@link Failure | Failure}
|
|
227
|
+
* with an error message if the source is not an array, has the wrong number of elements, or
|
|
228
|
+
* any element conversion fails.
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* const converter = tuple([Converters.string, Converters.number, Converters.boolean]);
|
|
233
|
+
* // Type is Converter<[string, number, boolean]>
|
|
234
|
+
*
|
|
235
|
+
* converter.convert(['hello', 42, true]);
|
|
236
|
+
* // Returns Success with ['hello', 42, true]
|
|
237
|
+
* ```
|
|
238
|
+
*
|
|
239
|
+
* @param converters - A tuple of {@link Converter | Converters} defining the expected types
|
|
240
|
+
* for each element of the tuple.
|
|
241
|
+
* @returns A {@link Converter | Converter} that returns a strongly-typed tuple.
|
|
242
|
+
* @public
|
|
243
|
+
*/
|
|
244
|
+
function tuple(converters) {
|
|
245
|
+
return new baseConverter_1.BaseConverter((from, __self, context) => {
|
|
246
|
+
if (!Array.isArray(from)) {
|
|
247
|
+
return (0, base_1.fail)(`Not an array: ${JSON.stringify(from)}`);
|
|
248
|
+
}
|
|
249
|
+
if (from.length !== converters.length) {
|
|
250
|
+
return (0, base_1.fail)(`Expected array of length ${converters.length}, got ${from.length}: ${JSON.stringify(from)}`);
|
|
251
|
+
}
|
|
252
|
+
const results = converters.map((converter, index) => {
|
|
253
|
+
return converter.convert(from[index], context);
|
|
254
|
+
});
|
|
255
|
+
return (0, base_1.mapResults)(results);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=advancedConverters.js.map
|
|
@@ -1,22 +1,37 @@
|
|
|
1
1
|
import { Brand, Result } from '../base';
|
|
2
2
|
import { ConstraintOptions, ConversionErrorFormatter, Converter, ConverterTraits, DefaultingConverter, OnError } from './converter';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Internal helper that recursively unwraps converter and array types.
|
|
5
|
+
* @internal
|
|
5
6
|
*/
|
|
6
7
|
type InnerInferredType<TCONV> = TCONV extends Converter<infer TTO> ? TTO extends Array<infer TTOELEM> ? InnerInferredType<TTOELEM>[] : TTO : TCONV extends Array<infer TELEM> ? InnerInferredType<TELEM>[] : TCONV;
|
|
7
8
|
/**
|
|
8
|
-
* Infers the type that will be returned by an instantiated converter.
|
|
9
|
-
* for complex as well as simple types.
|
|
9
|
+
* Infers the type that will be returned by an instantiated converter. Works
|
|
10
|
+
* for complex as well as simple types, including nested arrays.
|
|
10
11
|
* @example `Infer<typeof Converters.mapOf(Converters.stringArray)>` is `Map<string, string[]>`
|
|
11
|
-
* @
|
|
12
|
+
* @public
|
|
12
13
|
*/
|
|
13
14
|
export type Infer<TCONV> = TCONV extends Converter<infer TTO, unknown> ? InnerInferredType<TTO> : never;
|
|
14
15
|
/**
|
|
15
|
-
* Deprecated name for Infer
|
|
16
|
-
*
|
|
17
|
-
* @
|
|
16
|
+
* Deprecated name for {@link Conversion.Infer | Infer
|
|
17
|
+
* } retained for compatibility.
|
|
18
|
+
* @deprecated Use {@link Conversion.Infer | Infer} instead.
|
|
19
|
+
* @public
|
|
18
20
|
*/
|
|
19
21
|
export type ConvertedToType<TCONV> = Infer<TCONV>;
|
|
22
|
+
/**
|
|
23
|
+
* Helper type to extract the result type from a {@link Converter | Converter}.
|
|
24
|
+
* For simple single-level extraction. For complex nested types, use {@link Conversion.Infer | Infer}.
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export type ConverterResultType<C> = C extends Converter<infer T, unknown> ? T : never;
|
|
28
|
+
/**
|
|
29
|
+
* Helper type to map a tuple of {@link Converter | Converters} to a tuple of their result types.
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
export type ConverterResultTypes<T extends readonly Converter<unknown, unknown>[]> = {
|
|
33
|
+
[K in keyof T]: T[K] extends Converter<infer R, unknown> ? R : never;
|
|
34
|
+
};
|
|
20
35
|
/**
|
|
21
36
|
* Function signature for a converter function.
|
|
22
37
|
* @public
|
|
@@ -49,71 +64,72 @@ export declare class BaseConverter<T, TC = unknown> implements Converter<T, TC>
|
|
|
49
64
|
*/
|
|
50
65
|
constructor(converter: ConverterFunc<T, TC>, defaultContext?: TC, traits?: ConverterTraits);
|
|
51
66
|
/**
|
|
52
|
-
* {@
|
|
67
|
+
* {@inheritDoc Converter.isOptional}
|
|
53
68
|
*/
|
|
54
69
|
get isOptional(): boolean;
|
|
55
70
|
/**
|
|
56
|
-
* {@
|
|
71
|
+
* {@inheritDoc Converter.brand}
|
|
57
72
|
*/
|
|
58
73
|
get brand(): string | undefined;
|
|
59
74
|
/**
|
|
60
|
-
* {@
|
|
75
|
+
* {@inheritDoc Converter.convert}
|
|
61
76
|
*/
|
|
62
77
|
convert(from: unknown, context?: TC): Result<T>;
|
|
63
78
|
/**
|
|
64
|
-
* {@
|
|
79
|
+
* {@inheritDoc Converter.convertOptional}
|
|
65
80
|
*/
|
|
66
81
|
convertOptional(from: unknown, context?: TC, onError?: OnError): Result<T | undefined>;
|
|
67
82
|
/**
|
|
68
|
-
* {@
|
|
83
|
+
* {@inheritDoc Converter.optional}
|
|
69
84
|
*/
|
|
70
85
|
optional(onError?: OnError): Converter<T | undefined, TC>;
|
|
71
86
|
/**
|
|
72
|
-
* {@
|
|
87
|
+
* {@inheritDoc Converter.map}
|
|
73
88
|
*/
|
|
74
89
|
map<T2>(mapper: (from: T, context?: TC) => Result<T2>): Converter<T2, TC>;
|
|
75
90
|
/**
|
|
76
|
-
* {@
|
|
91
|
+
* {@inheritDoc Converter.mapConvert}
|
|
77
92
|
*/
|
|
78
93
|
mapConvert<T2>(mapConverter: Converter<T2>): Converter<T2, TC>;
|
|
79
94
|
/**
|
|
80
|
-
* {@
|
|
95
|
+
* {@inheritDoc Converter.mapItems}
|
|
81
96
|
*/
|
|
82
97
|
mapItems<TI>(mapper: (from: unknown, context?: TC) => Result<TI>): Converter<TI[], TC>;
|
|
83
98
|
/**
|
|
84
|
-
* {@
|
|
99
|
+
* {@inheritDoc Converter.mapConvertItems}
|
|
85
100
|
*/
|
|
86
101
|
mapConvertItems<TI>(mapConverter: Converter<TI, unknown>): Converter<TI[], TC>;
|
|
87
102
|
/**
|
|
88
|
-
* {@
|
|
103
|
+
* {@inheritDoc Converter.withAction}
|
|
89
104
|
*/
|
|
90
105
|
withAction<TI>(action: (result: Result<T>, context?: TC) => Result<TI>): Converter<TI, TC>;
|
|
91
106
|
/**
|
|
92
|
-
* {@
|
|
107
|
+
* {@inheritDoc Converter.withTypeGuard}
|
|
93
108
|
*/
|
|
94
109
|
withTypeGuard<TI>(guard: (from: unknown, context?: TC) => from is TI, message?: string): Converter<TI, TC>;
|
|
95
110
|
/**
|
|
96
|
-
* {@
|
|
111
|
+
* {@inheritDoc Converter.withItemTypeGuard}
|
|
97
112
|
*/
|
|
98
113
|
withItemTypeGuard<TI>(guard: (from: unknown, context?: TC) => from is TI, message?: string): Converter<TI[], TC>;
|
|
99
114
|
/**
|
|
100
|
-
* {@
|
|
115
|
+
* {@inheritDoc Converter.withConstraint}
|
|
101
116
|
*/
|
|
102
117
|
withConstraint(constraint: (val: T, context?: TC) => boolean | Result<T>, options?: ConstraintOptions): Converter<T, TC>;
|
|
103
118
|
/**
|
|
104
|
-
* {@
|
|
119
|
+
* {@inheritDoc Converter.withBrand}
|
|
105
120
|
*/
|
|
106
121
|
withBrand<B extends string>(brand: B): Converter<Brand<T, B>, TC>;
|
|
107
122
|
/**
|
|
108
|
-
* {@
|
|
123
|
+
* {@inheritDoc Converter.withDefault}
|
|
109
124
|
*/
|
|
110
125
|
withDefault<TD = T>(defaultValue: TD): DefaultingConverter<T, TD, TC>;
|
|
126
|
+
or(other: Converter<T, TC>): Converter<T, TC>;
|
|
111
127
|
/**
|
|
112
128
|
* @internal
|
|
113
129
|
*/
|
|
114
130
|
protected _context(supplied?: TC): TC | undefined;
|
|
115
131
|
/**
|
|
116
|
-
* {@
|
|
132
|
+
* {@inheritDoc Converter.withFormattedError}
|
|
117
133
|
*/
|
|
118
134
|
withFormattedError(formatter: ConversionErrorFormatter<TC>): Converter<T, TC>;
|
|
119
135
|
/**
|