@fgv/ts-utils 5.0.1-9 → 5.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/dist/index.js +32 -0
- package/dist/packlets/base/brand.js +23 -0
- package/dist/packlets/base/index.js +28 -0
- package/dist/packlets/base/mapResults.js +217 -0
- package/dist/packlets/base/messageAggregator.js +110 -0
- package/dist/packlets/base/normalize.js +132 -0
- package/dist/packlets/base/result.js +611 -0
- package/dist/packlets/base/utils.js +185 -0
- package/dist/packlets/collections/collectible.js +82 -0
- package/dist/packlets/collections/collector.js +189 -0
- package/dist/packlets/collections/collectorValidator.js +94 -0
- package/dist/packlets/collections/common.js +23 -0
- package/dist/packlets/collections/convertingCollector.js +118 -0
- package/dist/packlets/collections/convertingCollectorValidator.js +95 -0
- package/dist/packlets/collections/index.js +37 -0
- package/dist/packlets/collections/keyValueConverters.js +100 -0
- package/dist/packlets/collections/readonlyResultMap.js +23 -0
- package/dist/packlets/collections/resultMap.js +214 -0
- package/dist/packlets/collections/resultMapValidator.js +122 -0
- package/dist/packlets/collections/utils.js +31 -0
- package/dist/packlets/collections/validatingCollector.js +63 -0
- package/dist/packlets/collections/validatingConvertingCollector.js +64 -0
- package/dist/packlets/collections/validatingResultMap.js +57 -0
- package/dist/packlets/conversion/baseConverter.js +242 -0
- package/dist/packlets/conversion/converter.js +2 -0
- package/dist/packlets/conversion/converters.js +637 -0
- package/dist/packlets/conversion/defaultingConverter.js +149 -0
- package/dist/packlets/conversion/index.js +29 -0
- package/dist/packlets/conversion/objectConverter.js +141 -0
- package/dist/packlets/conversion/stringConverter.js +93 -0
- package/dist/packlets/hash/crcNormalizer.js +114 -0
- package/dist/packlets/hash/hashingNormalizer.js +92 -0
- package/dist/packlets/hash/index.js +24 -0
- package/dist/packlets/logging/index.js +24 -0
- package/dist/packlets/logging/logReporter.js +114 -0
- package/dist/packlets/logging/logger.js +258 -0
- package/dist/packlets/validation/array.js +64 -0
- package/dist/packlets/validation/boolean.js +52 -0
- package/dist/packlets/validation/classes.js +31 -0
- package/dist/packlets/validation/common.js +23 -0
- package/dist/packlets/validation/field.js +67 -0
- package/dist/packlets/validation/genericValidator.js +160 -0
- package/dist/packlets/validation/index.js +29 -0
- package/dist/packlets/validation/number.js +52 -0
- package/dist/packlets/validation/object.js +134 -0
- package/dist/packlets/validation/oneOf.js +58 -0
- package/dist/packlets/validation/string.js +52 -0
- package/dist/packlets/validation/traits.js +56 -0
- package/dist/packlets/validation/typeGuard.js +59 -0
- package/dist/packlets/validation/validator.js +23 -0
- package/dist/packlets/validation/validatorBase.js +37 -0
- package/dist/packlets/validation/validators.js +191 -0
- package/dist/test/helpers/jest/helpers/fsHelpers.js +139 -0
- package/dist/test/helpers/jest/helpers/index.js +2 -0
- package/dist/test/helpers/jest/index.js +17 -0
- package/dist/test/helpers/jest/matchers/index.js +14 -0
- package/dist/test/helpers/jest/matchers/toFail/index.js +23 -0
- package/dist/test/helpers/jest/matchers/toFail/predicate.js +5 -0
- package/dist/test/helpers/jest/matchers/toFailTest/index.js +28 -0
- package/dist/test/helpers/jest/matchers/toFailTest/predicate.js +8 -0
- package/dist/test/helpers/jest/matchers/toFailTestAndMatchSnapshot/index.js +24 -0
- package/dist/test/helpers/jest/matchers/toFailTestAndMatchSnapshot/predicate.js +11 -0
- package/dist/test/helpers/jest/matchers/toFailTestWith/index.js +29 -0
- package/dist/test/helpers/jest/matchers/toFailTestWith/predicate.js +26 -0
- package/dist/test/helpers/jest/matchers/toFailWith/index.js +27 -0
- package/dist/test/helpers/jest/matchers/toFailWith/predicate.js +16 -0
- package/dist/test/helpers/jest/matchers/toFailWithDetail/index.js +27 -0
- package/dist/test/helpers/jest/matchers/toFailWithDetail/predicate.js +22 -0
- package/dist/test/helpers/jest/matchers/toSucceed/index.js +23 -0
- package/dist/test/helpers/jest/matchers/toSucceed/predicate.js +5 -0
- package/dist/test/helpers/jest/matchers/toSucceedAndMatchInlineSnapshot/index.js +24 -0
- package/dist/test/helpers/jest/matchers/toSucceedAndMatchSnapshot/index.js +24 -0
- package/dist/test/helpers/jest/matchers/toSucceedAndSatisfy/index.js +53 -0
- package/dist/test/helpers/jest/matchers/toSucceedAndSatisfy/predicate.js +17 -0
- package/dist/test/helpers/jest/matchers/toSucceedWith/index.js +27 -0
- package/dist/test/helpers/jest/matchers/toSucceedWith/predicate.js +12 -0
- package/dist/test/helpers/jest/matchers/toSucceedWithDetail/index.js +27 -0
- package/dist/test/helpers/jest/matchers/toSucceedWithDetail/predicate.js +17 -0
- package/dist/test/helpers/jest/resolvers/cli.js +10 -0
- package/dist/test/helpers/jest/resolvers/ide.js +10 -0
- package/dist/test/helpers/jest/ts-utils.js +2 -0
- package/dist/test/helpers/jest/types/index.js +3 -0
- package/dist/test/helpers/jest/utils/matcherHelpers.js +47 -0
- package/dist/test/helpers/jest/utils/snapshotResolver.js +11 -0
- package/dist/test/unit/collections/helpers.js +106 -0
- package/dist/test/unit/hashTextEncodeCompat.js +23 -0
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/packlets/hash/crcNormalizer.js +42 -2
- package/package.json +12 -2
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2020 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
import { succeed } from '../base';
|
|
23
|
+
/**
|
|
24
|
+
* Generic {@link Conversion.DefaultingConverter | DefaultingConverter}, which wraps another converter
|
|
25
|
+
* to substitute a supplied default value for any errors returned by the inner converter.
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export class GenericDefaultingConverter {
|
|
29
|
+
/**
|
|
30
|
+
* {@inheritdoc Converter.isOptional}
|
|
31
|
+
*/
|
|
32
|
+
get isOptional() {
|
|
33
|
+
return this._converter.isOptional;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* {@inheritdoc Converter.isOptional}
|
|
37
|
+
*/
|
|
38
|
+
get brand() {
|
|
39
|
+
return this._converter.brand;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Constructs a new {@link Conversion.GenericDefaultingConverter | generic defaulting converter}.
|
|
43
|
+
* @param converter - inner {@link Converter | Converter} used for the base conversion.
|
|
44
|
+
* @param defaultValue - default value to be supplied if the inner conversion fails.
|
|
45
|
+
*/
|
|
46
|
+
constructor(converter, defaultValue) {
|
|
47
|
+
this.defaultValue = defaultValue;
|
|
48
|
+
this._converter = converter;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* {@inheritdoc Converter.convert}
|
|
52
|
+
*/
|
|
53
|
+
convert(from, ctx) {
|
|
54
|
+
return this._applyDefault(this._converter.convert(from, ctx));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* {@inheritdoc Converter.convertOptional}
|
|
58
|
+
*/
|
|
59
|
+
convertOptional(from, context, onError) {
|
|
60
|
+
const converted = this._converter.convertOptional(from, context, onError);
|
|
61
|
+
if (converted.isFailure()) {
|
|
62
|
+
return succeed(this.defaultValue);
|
|
63
|
+
}
|
|
64
|
+
return converted;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* {@inheritdoc Converter.optional}
|
|
68
|
+
*/
|
|
69
|
+
optional(onError) {
|
|
70
|
+
// need to let the inner converter do its optional thing first or our default
|
|
71
|
+
// steps on everything
|
|
72
|
+
return this._converter.optional(onError).withAction((result) => this._applyDefault(result));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* {@inheritdoc Converter.map}
|
|
76
|
+
*/
|
|
77
|
+
map(mapper) {
|
|
78
|
+
return this._converter.withAction((result) => this._applyDefault(result)).map(mapper);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* {@inheritdoc Converter.mapConvert}
|
|
82
|
+
*/
|
|
83
|
+
mapConvert(mapConverter) {
|
|
84
|
+
return this._converter.withAction((result) => this._applyDefault(result)).mapConvert(mapConverter);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* {@inheritdoc Converter.mapItems}
|
|
88
|
+
*/
|
|
89
|
+
mapItems(mapper) {
|
|
90
|
+
return this._converter.withAction((result) => this._applyDefault(result)).mapItems(mapper);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* {@inheritdoc Converter.mapConvertItems}
|
|
94
|
+
*/
|
|
95
|
+
mapConvertItems(mapConverter) {
|
|
96
|
+
return this._converter.withAction((result) => this._applyDefault(result)).mapConvertItems(mapConverter);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* {@inheritdoc Converter.withAction}
|
|
100
|
+
*/
|
|
101
|
+
withAction(action) {
|
|
102
|
+
return this._converter.withAction((result) => this._applyDefault(result)).withAction(action);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* {@inheritdoc Converter.withTypeGuard}
|
|
106
|
+
*/
|
|
107
|
+
withTypeGuard(guard, message) {
|
|
108
|
+
return this._converter.withAction((result) => this._applyDefault(result)).withTypeGuard(guard);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* {@inheritdoc Converter.withItemTypeGuard}
|
|
112
|
+
*/
|
|
113
|
+
withItemTypeGuard(guard, message) {
|
|
114
|
+
return this._converter.withAction((result) => this._applyDefault(result)).withItemTypeGuard(guard);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* {@inheritdoc Converter.withConstraint}
|
|
118
|
+
*/
|
|
119
|
+
withConstraint(constraint, options) {
|
|
120
|
+
return this._converter.withAction((result) => this._applyDefault(result)).withConstraint(constraint);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* {@inheritdoc Converter.withBrand}
|
|
124
|
+
*/
|
|
125
|
+
withBrand(brand) {
|
|
126
|
+
return this._converter.withAction((result) => this._applyDefault(result)).withBrand(brand);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* {@inheritdoc Converter.withFormattedError}
|
|
130
|
+
*/
|
|
131
|
+
withFormattedError(formatter) {
|
|
132
|
+
// formatter should never actually be invoked for a defaulting converter
|
|
133
|
+
return this._converter.withAction((result) => this._applyDefault(result)).withFormattedError(formatter);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Returns a Converter which always succeeds with the supplied default value rather
|
|
137
|
+
* than failing.
|
|
138
|
+
*
|
|
139
|
+
* Note that the supplied default value *overrides* the default value of this
|
|
140
|
+
* {@link Conversion.DefaultingConverter | DefaultingConverter}.
|
|
141
|
+
*/
|
|
142
|
+
withDefault(dflt) {
|
|
143
|
+
return new GenericDefaultingConverter(this._converter, dflt);
|
|
144
|
+
}
|
|
145
|
+
_applyDefault(converted) {
|
|
146
|
+
return converted.success ? converted : succeed(this.defaultValue);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=defaultingConverter.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
import * as Converters from './converters';
|
|
23
|
+
export * from './baseConverter';
|
|
24
|
+
export * from './converter';
|
|
25
|
+
export * from './defaultingConverter';
|
|
26
|
+
export * from './objectConverter';
|
|
27
|
+
export * from './stringConverter';
|
|
28
|
+
export { Converters };
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
import { fail, isKeyOf, succeed } from '../base';
|
|
23
|
+
import { BaseConverter } from './baseConverter';
|
|
24
|
+
import { field, optionalField } from './converters';
|
|
25
|
+
/**
|
|
26
|
+
* A {@link Converter | Converter} which converts an object of type `<T>` without changing shape, given
|
|
27
|
+
* a {@link Conversion.FieldConverters | FieldConverters<T>} for the fields in the object.
|
|
28
|
+
* @remarks
|
|
29
|
+
* By default, if all of the required fields exist and can be converted, returns a new object with
|
|
30
|
+
* the converted values under the original key names. If any required fields do not exist or cannot
|
|
31
|
+
* be converted, the entire conversion fails. See {@link Conversion.ObjectConverterOptions | ObjectConverterOptions}
|
|
32
|
+
* for other conversion options.
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export class ObjectConverter extends BaseConverter {
|
|
36
|
+
/**
|
|
37
|
+
* Concrete implementation of {@link Converters.(ObjectConverter:constructor)}
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
constructor(fields, opt) {
|
|
41
|
+
const options = Array.isArray(opt) ? { optionalFields: opt } : opt !== null && opt !== void 0 ? opt : { optionalFields: [] };
|
|
42
|
+
super((from, __self, context) => ObjectConverter._convert(from, context, fields, options));
|
|
43
|
+
this.fields = fields;
|
|
44
|
+
this.options = options;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Converts the supplied object using the {@link Conversion.ObjectConverter | ObjectConverter}
|
|
48
|
+
* with all fields optional.
|
|
49
|
+
* @param from - The object to be converted.
|
|
50
|
+
* @param context - An optional context object passed to the field converters.
|
|
51
|
+
* @returns A {@link Result} containing the converted object or an error message.
|
|
52
|
+
*/
|
|
53
|
+
convertPartial(from, context) {
|
|
54
|
+
const options = Object.assign(Object.assign({}, this.options), { modifier: 'partial' });
|
|
55
|
+
return ObjectConverter._convert(from, context, this.fields, options);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Converts the supplied object using the {@link Conversion.ObjectConverter | ObjectConverter}
|
|
59
|
+
* with all fields required.
|
|
60
|
+
* @param from - The object to be converted.
|
|
61
|
+
* @param context - An optional context object passed to the field converters.
|
|
62
|
+
* @returns A {@link Result} containing the converted object or an error message.
|
|
63
|
+
*/
|
|
64
|
+
convertRequired(from, context) {
|
|
65
|
+
const options = Object.assign(Object.assign({}, this.options), { modifier: 'required' });
|
|
66
|
+
return ObjectConverter._convert(from, context, this.fields, options);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Concrete implementation of
|
|
70
|
+
* {@link Conversion.ObjectConverter.(partial:1) | ObjectConverter.partial(ObjectConverterOptions)} and
|
|
71
|
+
* {@link Conversion.ObjectConverter.(partial:2) | ObjectConverter.partial((keyof T))[]}.
|
|
72
|
+
* @internal
|
|
73
|
+
*/
|
|
74
|
+
partial(opt) {
|
|
75
|
+
const options = opt === undefined
|
|
76
|
+
? Object.assign(Object.assign({}, this.options), { modifier: 'partial' }) : Array.isArray(opt)
|
|
77
|
+
? Object.assign(Object.assign({}, this.options), { optionalFields: [...opt] }) : opt;
|
|
78
|
+
return new ObjectConverter(this.fields, options)._with(this._traits());
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Creates a new {@link Conversion.ObjectConverter | ObjectConverter} derived from this one but with
|
|
82
|
+
* new optional properties as specified by a supplied array of `keyof T`.
|
|
83
|
+
* @param addOptionalProperties - The keys to be made optional.
|
|
84
|
+
* @returns A new {@link Conversion.ObjectConverter | ObjectConverter} with the additional optional source
|
|
85
|
+
* properties.
|
|
86
|
+
*/
|
|
87
|
+
addPartial(addOptionalProperties) {
|
|
88
|
+
var _a;
|
|
89
|
+
/* c8 ignore next 1 - coverage having a bad day */
|
|
90
|
+
const myOptional = (_a = this.options.optionalFields) !== null && _a !== void 0 ? _a : [];
|
|
91
|
+
const optional = [...myOptional, ...addOptionalProperties];
|
|
92
|
+
return this.partial(optional)._with(this._traits());
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Creates a new {@link Conversion.ObjectConverter | ObjectConverter} derived from this one but with
|
|
96
|
+
* all properties required.
|
|
97
|
+
* @returns A new {@link Conversion.ObjectConverter | ObjectConverter} with the additional required source properties.
|
|
98
|
+
*/
|
|
99
|
+
required() {
|
|
100
|
+
const options = Object.assign(Object.assign({}, this.options), { modifier: 'required' });
|
|
101
|
+
return new ObjectConverter(this.fields, options)._with(this._traits());
|
|
102
|
+
}
|
|
103
|
+
static _convert(from, context, fields, options) {
|
|
104
|
+
// eslint bug thinks key is used before defined
|
|
105
|
+
var _a;
|
|
106
|
+
const converted = {};
|
|
107
|
+
const errors = [];
|
|
108
|
+
for (const key in fields) {
|
|
109
|
+
if (fields[key]) {
|
|
110
|
+
const isOptional = options.modifier === 'partial' ||
|
|
111
|
+
(options.modifier !== 'required' &&
|
|
112
|
+
(fields[key].isOptional === true || ((_a = options.optionalFields) === null || _a === void 0 ? void 0 : _a.includes(key)) === true));
|
|
113
|
+
const result = isOptional
|
|
114
|
+
? optionalField(key, fields[key]).convert(from, context)
|
|
115
|
+
: field(key, fields[key]).convert(from, context);
|
|
116
|
+
if (result.isSuccess() && result.value !== undefined) {
|
|
117
|
+
converted[key] = result.value;
|
|
118
|
+
}
|
|
119
|
+
else if (result.isFailure()) {
|
|
120
|
+
errors.push(result.message);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (options.strict === true) {
|
|
125
|
+
if (typeof from === 'object' && !Array.isArray(from)) {
|
|
126
|
+
for (const key in from) {
|
|
127
|
+
if (from.hasOwnProperty(key) && (!isKeyOf(key, fields) || fields[key] === undefined)) {
|
|
128
|
+
errors.push(`${key}: unexpected property in source object`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
errors.push('source is not an object');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return errors.length === 0
|
|
137
|
+
? succeed(converted)
|
|
138
|
+
: fail(options.description ? `${options.description}: ${errors.join('\n')}` : errors.join('\n'));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=objectConverter.js.map
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
import { fail, succeed } from '../base';
|
|
23
|
+
import { BaseConverter } from './baseConverter';
|
|
24
|
+
/**
|
|
25
|
+
* The {@link Conversion.StringConverter | StringConverter} class extends
|
|
26
|
+
* {@link Conversion.BaseConverter | BaseConverter} to provide string-specific
|
|
27
|
+
* helper methods.
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export class StringConverter extends BaseConverter {
|
|
31
|
+
/**
|
|
32
|
+
* Construct a new {@link Conversion.StringConverter | StringConverter}.
|
|
33
|
+
* @param defaultContext - Optional context used by the conversion.
|
|
34
|
+
* @param traits - Optional traits to be applied to the conversion.
|
|
35
|
+
* @param converter - Optional conversion function to be used for the conversion.
|
|
36
|
+
*/
|
|
37
|
+
constructor(defaultContext, traits, converter = StringConverter._convert) {
|
|
38
|
+
super(converter, defaultContext, traits);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
static _convert(from) {
|
|
44
|
+
return typeof from === 'string' ? succeed(from) : fail(`Not a string: ${JSON.stringify(from)}`);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
49
|
+
static _wrap(wrapped, converter, traits) {
|
|
50
|
+
return new StringConverter(undefined, undefined, (from) => {
|
|
51
|
+
return wrapped.convert(from).onSuccess(converter);
|
|
52
|
+
})._with(wrapped._traits(traits));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Concrete implementation of {@link Conversion.StringConverter.matching#string | StringConverter.matching(string)},
|
|
56
|
+
* {@link Conversion.StringConverter.matching#array | StringConverter.matching(string[])},
|
|
57
|
+
* {@link Conversion.StringConverter.matching#set | StringConverter.matching(Set<string>)}, and
|
|
58
|
+
* {@link Conversion.StringConverter.matching#regexp | StringConverter.matching(RegExp)}.
|
|
59
|
+
* @internal
|
|
60
|
+
*/
|
|
61
|
+
matching(match, options) {
|
|
62
|
+
const message = options === null || options === void 0 ? void 0 : options.message;
|
|
63
|
+
if (typeof match === 'string') {
|
|
64
|
+
return StringConverter._wrap(this, (from) => {
|
|
65
|
+
return match === from
|
|
66
|
+
? succeed(from)
|
|
67
|
+
: fail(message ? `"${from}": ${message}` : `"${from}": does not match "${match}"`);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else if (match instanceof RegExp) {
|
|
71
|
+
return StringConverter._wrap(this, (from) => {
|
|
72
|
+
return match.test(from)
|
|
73
|
+
? succeed(from)
|
|
74
|
+
: fail(message ? `"${from}": ${message}` : `"${from}": does not match "${match}"`);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else if (match instanceof Set) {
|
|
78
|
+
return StringConverter._wrap(this, (from) => {
|
|
79
|
+
return match.has(from)
|
|
80
|
+
? succeed(from)
|
|
81
|
+
: fail(message ? `"${from}": ${message}` : `"${from}": not found in set`);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
return StringConverter._wrap(this, (from) => {
|
|
86
|
+
return match.includes(from)
|
|
87
|
+
? succeed(from)
|
|
88
|
+
: fail(message ? `"${from}": ${message}` : `"${from}": not found in [${match.join(',')}]`);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=stringConverter.js.map
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
import { HashingNormalizer } from './hashingNormalizer';
|
|
23
|
+
function encodeUtf8(input) {
|
|
24
|
+
// Prefer built-in TextEncoder when available (browsers and modern Node)
|
|
25
|
+
// @ts-ignore - global TextEncoder may be unavailable in some environments
|
|
26
|
+
const GlobalTextEncoder = typeof TextEncoder !== 'undefined' ? TextEncoder : undefined;
|
|
27
|
+
if (GlobalTextEncoder) {
|
|
28
|
+
return new GlobalTextEncoder().encode(input);
|
|
29
|
+
}
|
|
30
|
+
// Very small manual UTF-8 encoder as a last resort
|
|
31
|
+
/* eslint-disable no-bitwise */
|
|
32
|
+
const bytes = [];
|
|
33
|
+
for (let i = 0; i < input.length; i++) {
|
|
34
|
+
let codePoint = input.charCodeAt(i);
|
|
35
|
+
if (codePoint >= 0xd800 && codePoint <= 0xdbff && i + 1 < input.length) {
|
|
36
|
+
const next = input.charCodeAt(i + 1);
|
|
37
|
+
if (next >= 0xdc00 && next <= 0xdfff) {
|
|
38
|
+
codePoint = ((codePoint - 0xd800) << 10) + (next - 0xdc00) + 0x10000;
|
|
39
|
+
i++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (codePoint < 0x80) {
|
|
43
|
+
bytes.push(codePoint);
|
|
44
|
+
}
|
|
45
|
+
else if (codePoint < 0x800) {
|
|
46
|
+
bytes.push(0xc0 | (codePoint >> 6));
|
|
47
|
+
bytes.push(0x80 | (codePoint & 0x3f));
|
|
48
|
+
}
|
|
49
|
+
else if (codePoint < 0x10000) {
|
|
50
|
+
bytes.push(0xe0 | (codePoint >> 12));
|
|
51
|
+
bytes.push(0x80 | ((codePoint >> 6) & 0x3f));
|
|
52
|
+
bytes.push(0x80 | (codePoint & 0x3f));
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
bytes.push(0xf0 | (codePoint >> 18));
|
|
56
|
+
bytes.push(0x80 | ((codePoint >> 12) & 0x3f));
|
|
57
|
+
bytes.push(0x80 | ((codePoint >> 6) & 0x3f));
|
|
58
|
+
bytes.push(0x80 | (codePoint & 0x3f));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/* eslint-enable no-bitwise */
|
|
62
|
+
return new Uint8Array(bytes);
|
|
63
|
+
}
|
|
64
|
+
const POLYNOMIAL = 0xedb88320;
|
|
65
|
+
const crc32Table = [];
|
|
66
|
+
function crc32(bytes, crc = 0xffffffff) {
|
|
67
|
+
if (crc32Table.length === 0) {
|
|
68
|
+
buildCrc32Table();
|
|
69
|
+
}
|
|
70
|
+
for (let i = 0; i < bytes.length; ++i) {
|
|
71
|
+
// eslint-disable-next-line no-bitwise
|
|
72
|
+
crc = crc32Table[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8);
|
|
73
|
+
}
|
|
74
|
+
return (crc ^ -1) >>> 0;
|
|
75
|
+
}
|
|
76
|
+
const toUInt32 = (n) => {
|
|
77
|
+
if (n >= 0) {
|
|
78
|
+
return n;
|
|
79
|
+
}
|
|
80
|
+
return 0xffffffff - n * -1 + 1;
|
|
81
|
+
};
|
|
82
|
+
function buildCrc32Table() {
|
|
83
|
+
if (crc32Table.length === 0) {
|
|
84
|
+
for (let n = 0; n < 256; n++) {
|
|
85
|
+
let r = n;
|
|
86
|
+
for (let i = 0; i < 8; i++) {
|
|
87
|
+
// eslint-disable-next-line no-bitwise
|
|
88
|
+
if (r & 1) {
|
|
89
|
+
r = (r >>> 1) ^ POLYNOMIAL;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
r = r >>> 1;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
crc32Table.push(toUInt32(r));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* A {@link Hash.HashingNormalizer | hashing normalizer} which computes object
|
|
101
|
+
* hash using the CRC32 algorithm.
|
|
102
|
+
* @public
|
|
103
|
+
*/
|
|
104
|
+
export class Crc32Normalizer extends HashingNormalizer {
|
|
105
|
+
constructor() {
|
|
106
|
+
super(Crc32Normalizer.crc32Hash);
|
|
107
|
+
}
|
|
108
|
+
static crc32Hash(parts) {
|
|
109
|
+
return crc32(encodeUtf8(parts.join('|')))
|
|
110
|
+
.toString(16)
|
|
111
|
+
.padStart(8, '0');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=crcNormalizer.js.map
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2021 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
import { Normalizer, captureResult, fail, mapResults, succeed } from '../base';
|
|
23
|
+
/**
|
|
24
|
+
* Normalizes an arbitrary JSON object
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export class HashingNormalizer extends Normalizer {
|
|
28
|
+
constructor(hash) {
|
|
29
|
+
super();
|
|
30
|
+
this._hash = hash;
|
|
31
|
+
}
|
|
32
|
+
computeHash(from) {
|
|
33
|
+
switch (typeof from) {
|
|
34
|
+
case 'string':
|
|
35
|
+
case 'bigint':
|
|
36
|
+
case 'boolean':
|
|
37
|
+
case 'number':
|
|
38
|
+
case 'symbol':
|
|
39
|
+
case 'undefined':
|
|
40
|
+
return this._normalizeLiteralToString(from).onSuccess((v) => {
|
|
41
|
+
return captureResult(() => this._hash([v]));
|
|
42
|
+
});
|
|
43
|
+
case 'object':
|
|
44
|
+
if (from === null || from instanceof Date || from instanceof RegExp) {
|
|
45
|
+
return this._normalizeLiteralToString(from).onSuccess((v) => {
|
|
46
|
+
return captureResult(() => this._hash([v]));
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
else if (Array.isArray(from)) {
|
|
50
|
+
return mapResults(from.map((e) => this.computeHash(e))).onSuccess((a) => {
|
|
51
|
+
return captureResult(() => this._hash(['array', ...a]));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
else if (from instanceof Map || from instanceof Set) {
|
|
55
|
+
const type = from instanceof Map ? 'map' : 'set';
|
|
56
|
+
return this.computeHash([type, ...this.normalizeEntries(from.entries())]);
|
|
57
|
+
}
|
|
58
|
+
return this.computeHash(['object', ...this.normalizeEntries(Object.entries(from))]);
|
|
59
|
+
}
|
|
60
|
+
return fail(`computeHash: Unexpected type - cannot hash '${typeof from}'`);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Constructs a normalized string representation of some literal value.
|
|
64
|
+
* @param from - The literal value to be normalized.
|
|
65
|
+
* @returns A normalized string representation of the literal.
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
_normalizeLiteralToString(from) {
|
|
69
|
+
switch (typeof from) {
|
|
70
|
+
case 'string':
|
|
71
|
+
return succeed(from);
|
|
72
|
+
case 'bigint':
|
|
73
|
+
case 'boolean':
|
|
74
|
+
case 'number':
|
|
75
|
+
case 'symbol':
|
|
76
|
+
case 'undefined':
|
|
77
|
+
return succeed(`${typeof from}:[[[${String(from)}]]]`);
|
|
78
|
+
}
|
|
79
|
+
if (from === null) {
|
|
80
|
+
return succeed('object:[[[null]]');
|
|
81
|
+
}
|
|
82
|
+
if (from instanceof Date) {
|
|
83
|
+
return succeed(`Date:[[[${String(from.valueOf())}]]]`);
|
|
84
|
+
}
|
|
85
|
+
if (from instanceof RegExp) {
|
|
86
|
+
return succeed(`RegExp:[[[${from.toString()}]]]`);
|
|
87
|
+
}
|
|
88
|
+
/* c8 ignore next 2 */
|
|
89
|
+
return fail(`cannot normalize ${JSON.stringify(from)}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=hashingNormalizer.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2020 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
export * from './crcNormalizer';
|
|
23
|
+
export * from './hashingNormalizer';
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2020 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
export * from './logger';
|
|
23
|
+
export * from './logReporter';
|
|
24
|
+
//# sourceMappingURL=index.js.map
|