@fgv/ts-utils 5.0.0-2 → 5.0.0-20
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/.vscode/launch.json +16 -0
- package/.vscode/settings.json +36 -0
- package/config/api-extractor.json +343 -0
- package/config/rig.json +16 -0
- package/dist/ts-utils.d.ts +20 -8
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/packlets/base/result.d.ts +8 -0
- package/lib/packlets/base/result.js +11 -0
- package/lib/packlets/hash/crcNormalizer.js +3 -1
- package/lib/packlets/validation/array.d.ts +2 -1
- package/lib/packlets/validation/array.js +2 -1
- package/lib/packlets/validation/common.d.ts +0 -8
- package/lib/packlets/validation/field.d.ts +1 -1
- package/lib/packlets/validation/field.js +1 -1
- package/lib/packlets/validation/genericValidator.d.ts +1 -6
- package/lib/packlets/validation/genericValidator.js +11 -11
- package/lib/packlets/validation/object.d.ts +1 -1
- package/lib/packlets/validation/object.js +1 -1
- package/lib/packlets/validation/oneOf.d.ts +2 -1
- package/lib/packlets/validation/oneOf.js +2 -1
- package/lib/packlets/validation/typeGuard.d.ts +3 -2
- package/lib/packlets/validation/typeGuard.js +2 -1
- package/lib/packlets/validation/validator.d.ts +7 -0
- package/lib/packlets/validation/validatorBase.d.ts +2 -1
- package/lib/packlets/validation/validatorBase.js +1 -1
- package/lib/packlets/validation/validators.d.ts +2 -2
- package/lib/packlets/validation/validators.js +3 -3
- package/lib/test/helpers/jest/helpers/fsHelpers.d.ts +52 -0
- package/lib/test/helpers/jest/helpers/fsHelpers.js +180 -0
- package/lib/test/helpers/jest/helpers/index.d.ts +2 -0
- package/lib/test/helpers/jest/helpers/index.js +18 -0
- package/lib/test/helpers/jest/index.d.ts +3 -0
- package/lib/test/helpers/jest/index.js +27 -0
- package/lib/test/helpers/jest/matchers/index.d.ts +16 -0
- package/lib/test/helpers/jest/matchers/index.js +19 -0
- package/lib/test/helpers/jest/matchers/toFail/index.d.ts +16 -0
- package/lib/test/helpers/jest/matchers/toFail/index.js +25 -0
- package/lib/test/helpers/jest/matchers/toFail/predicate.d.ts +4 -0
- package/lib/test/helpers/jest/matchers/toFail/predicate.js +9 -0
- package/lib/test/helpers/jest/matchers/toFailTest/index.d.ts +16 -0
- package/lib/test/helpers/jest/matchers/toFailTest/index.js +30 -0
- package/lib/test/helpers/jest/matchers/toFailTest/predicate.d.ts +3 -0
- package/lib/test/helpers/jest/matchers/toFailTest/predicate.js +12 -0
- package/lib/test/helpers/jest/matchers/toFailTestAndMatchSnapshot/index.d.ts +17 -0
- package/lib/test/helpers/jest/matchers/toFailTestAndMatchSnapshot/index.js +26 -0
- package/lib/test/helpers/jest/matchers/toFailTestAndMatchSnapshot/predicate.d.ts +4 -0
- package/lib/test/helpers/jest/matchers/toFailTestAndMatchSnapshot/predicate.js +15 -0
- package/lib/test/helpers/jest/matchers/toFailTestWith/index.d.ts +18 -0
- package/lib/test/helpers/jest/matchers/toFailTestWith/index.js +31 -0
- package/lib/test/helpers/jest/matchers/toFailTestWith/predicate.d.ts +4 -0
- package/lib/test/helpers/jest/matchers/toFailTestWith/predicate.js +30 -0
- package/lib/test/helpers/jest/matchers/toFailWith/index.d.ts +18 -0
- package/lib/test/helpers/jest/matchers/toFailWith/index.js +29 -0
- package/lib/test/helpers/jest/matchers/toFailWith/predicate.d.ts +4 -0
- package/lib/test/helpers/jest/matchers/toFailWith/predicate.js +20 -0
- package/lib/test/helpers/jest/matchers/toFailWithDetail/index.d.ts +19 -0
- package/lib/test/helpers/jest/matchers/toFailWithDetail/index.js +29 -0
- package/lib/test/helpers/jest/matchers/toFailWithDetail/predicate.d.ts +4 -0
- package/lib/test/helpers/jest/matchers/toFailWithDetail/predicate.js +26 -0
- package/lib/test/helpers/jest/matchers/toSucceed/index.d.ts +16 -0
- package/lib/test/helpers/jest/matchers/toSucceed/index.js +25 -0
- package/lib/test/helpers/jest/matchers/toSucceed/predicate.d.ts +4 -0
- package/lib/test/helpers/jest/matchers/toSucceed/predicate.js +9 -0
- package/lib/test/helpers/jest/matchers/toSucceedAndMatchInlineSnapshot/index.d.ts +17 -0
- package/lib/test/helpers/jest/matchers/toSucceedAndMatchInlineSnapshot/index.js +26 -0
- package/lib/test/helpers/jest/matchers/toSucceedAndMatchSnapshot/index.d.ts +17 -0
- package/lib/test/helpers/jest/matchers/toSucceedAndMatchSnapshot/index.js +26 -0
- package/lib/test/helpers/jest/matchers/toSucceedAndSatisfy/index.d.ts +19 -0
- package/lib/test/helpers/jest/matchers/toSucceedAndSatisfy/index.js +55 -0
- package/lib/test/helpers/jest/matchers/toSucceedAndSatisfy/predicate.d.ts +4 -0
- package/lib/test/helpers/jest/matchers/toSucceedAndSatisfy/predicate.js +21 -0
- package/lib/test/helpers/jest/matchers/toSucceedWith/index.d.ts +18 -0
- package/lib/test/helpers/jest/matchers/toSucceedWith/index.js +29 -0
- package/lib/test/helpers/jest/matchers/toSucceedWith/predicate.d.ts +4 -0
- package/lib/test/helpers/jest/matchers/toSucceedWith/predicate.js +16 -0
- package/lib/test/helpers/jest/matchers/toSucceedWithDetail/index.d.ts +18 -0
- package/lib/test/helpers/jest/matchers/toSucceedWithDetail/index.js +29 -0
- package/lib/test/helpers/jest/matchers/toSucceedWithDetail/predicate.d.ts +4 -0
- package/lib/test/helpers/jest/matchers/toSucceedWithDetail/predicate.js +21 -0
- package/lib/test/helpers/jest/resolvers/cli.d.ts +5 -0
- package/lib/test/helpers/jest/resolvers/cli.js +48 -0
- package/lib/test/helpers/jest/resolvers/ide.d.ts +5 -0
- package/lib/test/helpers/jest/resolvers/ide.js +48 -0
- package/lib/test/helpers/jest/ts-utils.d.ts +2 -0
- package/lib/test/helpers/jest/ts-utils.js +18 -0
- package/lib/test/helpers/jest/types/index.d.ts +79 -0
- package/lib/test/helpers/jest/types/index.js +4 -0
- package/lib/test/helpers/jest/utils/matcherHelpers.d.ts +6 -0
- package/lib/test/helpers/jest/utils/matcherHelpers.js +53 -0
- package/lib/test/helpers/jest/utils/snapshotResolver.d.ts +4 -0
- package/lib/test/helpers/jest/utils/snapshotResolver.js +19 -0
- package/lib/test/unit/collections/collectible.test.d.ts +2 -0
- package/lib/test/unit/collections/collector.test.d.ts +2 -0
- package/lib/test/unit/collections/collectors.test.d.ts +2 -0
- package/lib/test/unit/collections/convertingCollector.test.d.ts +2 -0
- package/lib/test/unit/collections/helpers.d.ts +44 -0
- package/lib/test/unit/collections/helpers.js +115 -0
- package/lib/test/unit/collections/resultMap.test.d.ts +2 -0
- package/lib/test/unit/collections/validatingCollector.test.d.ts +2 -0
- package/lib/test/unit/collections/validatingConvertingCollector.test.d.ts +2 -0
- package/lib/test/unit/collections/validatingResultMap.test.d.ts +2 -0
- package/lib/test/unit/converter.test.d.ts +2 -0
- package/lib/test/unit/converters.test.d.ts +2 -0
- package/lib/test/unit/defaultingConverter.test.d.ts +2 -0
- package/lib/test/unit/file-tree/fileItem.test.d.ts +2 -0
- package/lib/test/unit/file-tree/fileTree.test.d.ts +2 -0
- package/lib/test/unit/file-tree/fsTree.test.d.ts +2 -0
- package/lib/test/unit/file-tree/inMemoryTree.test.d.ts +2 -0
- package/lib/test/unit/file-tree/sample/rootFile.json +1 -0
- package/lib/test/unit/file-tree/sample/some/other/path/file2.json +1 -0
- package/lib/test/unit/file-tree/sample/some/path/below/file4.json +1 -0
- package/lib/test/unit/file-tree/sample/some/path/file1.json +1 -0
- package/lib/test/unit/file-tree/sample/some/path/file3.json +1 -0
- package/lib/test/unit/hash.test.d.ts +2 -0
- package/lib/test/unit/logger.test.d.ts +2 -0
- package/lib/test/unit/mapResults.test.d.ts +3 -0
- package/lib/test/unit/messageAggregator.test.d.ts +3 -0
- package/lib/test/unit/normalize.test.d.ts +2 -0
- package/lib/test/unit/result.test.d.ts +3 -0
- package/lib/test/unit/utils.test.d.ts +3 -0
- package/lib/test/unit/validation/array.test.d.ts +2 -0
- package/lib/test/unit/validation/boolean.test.d.ts +2 -0
- package/lib/test/unit/validation/genericValidator.test.d.ts +2 -0
- package/lib/test/unit/validation/number.test.d.ts +2 -0
- package/lib/test/unit/validation/object.test.d.ts +2 -0
- package/lib/test/unit/validation/oneOf.test.d.ts +2 -0
- package/lib/test/unit/validation/recordOf.test.d.ts +2 -0
- package/lib/test/unit/validation/recursiveValidation.test.d.ts +2 -0
- package/lib/test/unit/validation/string.test.d.ts +2 -0
- package/lib/test/unit/validation/traits.test.d.ts +2 -0
- package/lib/test/unit/validation/typeGuard.test.d.ts +2 -0
- package/lib/test/unit/validation/validators.test.d.ts +2 -0
- package/package.json +9 -9
- package/src/index.ts +63 -0
- package/src/packlets/base/brand.ts +28 -0
- package/src/packlets/base/index.ts +31 -0
- package/src/packlets/base/logger.ts +156 -0
- package/src/packlets/base/mapResults.ts +302 -0
- package/src/packlets/base/messageAggregator.ts +120 -0
- package/src/packlets/base/normalize.ts +144 -0
- package/src/packlets/base/result.ts +961 -0
- package/src/packlets/base/utils.ts +236 -0
- package/src/packlets/collections/collectible.ts +238 -0
- package/src/packlets/collections/collector.ts +273 -0
- package/src/packlets/collections/collectorValidator.ts +178 -0
- package/src/packlets/collections/common.ts +27 -0
- package/src/packlets/collections/convertingCollector.ts +223 -0
- package/src/packlets/collections/convertingCollectorValidator.ts +164 -0
- package/src/packlets/collections/index.ts +39 -0
- package/src/packlets/collections/keyValueConverters.ts +142 -0
- package/src/packlets/collections/readonlyResultMap.ts +99 -0
- package/src/packlets/collections/resultMap.ts +322 -0
- package/src/packlets/collections/resultMapValidator.ts +188 -0
- package/src/packlets/collections/utils.ts +33 -0
- package/src/packlets/collections/validatingCollector.ts +123 -0
- package/src/packlets/collections/validatingConvertingCollector.ts +113 -0
- package/src/packlets/collections/validatingResultMap.ts +94 -0
- package/src/packlets/conversion/baseConverter.ts +330 -0
- package/src/packlets/conversion/converter.ts +260 -0
- package/src/packlets/conversion/converters.ts +1039 -0
- package/src/packlets/conversion/defaultingConverter.ts +188 -0
- package/src/packlets/conversion/index.ts +30 -0
- package/src/packlets/conversion/objectConverter.ts +259 -0
- package/src/packlets/conversion/stringConverter.ts +165 -0
- package/src/packlets/file-tree/directoryItem.ts +84 -0
- package/src/packlets/file-tree/fileItem.ts +119 -0
- package/src/packlets/file-tree/fileTree.ts +152 -0
- package/src/packlets/file-tree/fileTreeAccessors.ts +176 -0
- package/src/packlets/file-tree/fsTree.ts +118 -0
- package/src/packlets/file-tree/in-memory/inMemoryTree.ts +171 -0
- package/src/packlets/file-tree/in-memory/index.ts +23 -0
- package/src/packlets/file-tree/in-memory/treeBuilder.ts +203 -0
- package/src/packlets/file-tree/index.ts +31 -0
- package/src/packlets/hash/crcNormalizer.ts +81 -0
- package/src/packlets/hash/hashingNormalizer.ts +102 -0
- package/src/packlets/hash/index.ts +24 -0
- package/src/packlets/validation/array.ts +84 -0
- package/src/packlets/validation/boolean.ts +63 -0
- package/src/packlets/validation/classes.ts +38 -0
- package/src/packlets/validation/common.ts +28 -0
- package/src/packlets/validation/field.ts +99 -0
- package/src/packlets/validation/genericValidator.ts +204 -0
- package/src/packlets/validation/index.ts +31 -0
- package/src/packlets/validation/number.ts +66 -0
- package/src/packlets/validation/object.ts +208 -0
- package/src/packlets/validation/oneOf.ts +78 -0
- package/src/packlets/validation/string.ts +66 -0
- package/src/packlets/validation/traits.ts +113 -0
- package/src/packlets/validation/typeGuard.ts +83 -0
- package/src/packlets/validation/validator.ts +157 -0
- package/src/packlets/validation/validatorBase.ts +66 -0
- package/src/packlets/validation/validators.ts +254 -0
- package/CHANGELOG.md +0 -135
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/packlets/base/brand.d.ts.map +0 -1
- package/lib/packlets/base/brand.js.map +0 -1
- package/lib/packlets/base/index.d.ts.map +0 -1
- package/lib/packlets/base/index.js.map +0 -1
- package/lib/packlets/base/logger.d.ts.map +0 -1
- package/lib/packlets/base/logger.js.map +0 -1
- package/lib/packlets/base/mapResults.d.ts.map +0 -1
- package/lib/packlets/base/mapResults.js.map +0 -1
- package/lib/packlets/base/messageAggregator.d.ts.map +0 -1
- package/lib/packlets/base/messageAggregator.js.map +0 -1
- package/lib/packlets/base/normalize.d.ts.map +0 -1
- package/lib/packlets/base/normalize.js.map +0 -1
- package/lib/packlets/base/result.d.ts.map +0 -1
- package/lib/packlets/base/result.js.map +0 -1
- package/lib/packlets/base/utils.d.ts.map +0 -1
- package/lib/packlets/base/utils.js.map +0 -1
- package/lib/packlets/collections/collectible.d.ts.map +0 -1
- package/lib/packlets/collections/collectible.js.map +0 -1
- package/lib/packlets/collections/collector.d.ts.map +0 -1
- package/lib/packlets/collections/collector.js.map +0 -1
- package/lib/packlets/collections/collectorValidator.d.ts.map +0 -1
- package/lib/packlets/collections/collectorValidator.js.map +0 -1
- package/lib/packlets/collections/common.d.ts.map +0 -1
- package/lib/packlets/collections/common.js.map +0 -1
- package/lib/packlets/collections/convertingCollector.d.ts.map +0 -1
- package/lib/packlets/collections/convertingCollector.js.map +0 -1
- package/lib/packlets/collections/convertingCollectorValidator.d.ts.map +0 -1
- package/lib/packlets/collections/convertingCollectorValidator.js.map +0 -1
- package/lib/packlets/collections/index.d.ts.map +0 -1
- package/lib/packlets/collections/index.js.map +0 -1
- package/lib/packlets/collections/keyValueConverters.d.ts.map +0 -1
- package/lib/packlets/collections/keyValueConverters.js.map +0 -1
- package/lib/packlets/collections/readonlyResultMap.d.ts.map +0 -1
- package/lib/packlets/collections/readonlyResultMap.js.map +0 -1
- package/lib/packlets/collections/resultMap.d.ts.map +0 -1
- package/lib/packlets/collections/resultMap.js.map +0 -1
- package/lib/packlets/collections/resultMapValidator.d.ts.map +0 -1
- package/lib/packlets/collections/resultMapValidator.js.map +0 -1
- package/lib/packlets/collections/utils.d.ts.map +0 -1
- package/lib/packlets/collections/utils.js.map +0 -1
- package/lib/packlets/collections/validatingCollector.d.ts.map +0 -1
- package/lib/packlets/collections/validatingCollector.js.map +0 -1
- package/lib/packlets/collections/validatingConvertingCollector.d.ts.map +0 -1
- package/lib/packlets/collections/validatingConvertingCollector.js.map +0 -1
- package/lib/packlets/collections/validatingResultMap.d.ts.map +0 -1
- package/lib/packlets/collections/validatingResultMap.js.map +0 -1
- package/lib/packlets/conversion/baseConverter.d.ts.map +0 -1
- package/lib/packlets/conversion/baseConverter.js.map +0 -1
- package/lib/packlets/conversion/converter.d.ts.map +0 -1
- package/lib/packlets/conversion/converter.js.map +0 -1
- package/lib/packlets/conversion/converters.d.ts.map +0 -1
- package/lib/packlets/conversion/converters.js.map +0 -1
- package/lib/packlets/conversion/defaultingConverter.d.ts.map +0 -1
- package/lib/packlets/conversion/defaultingConverter.js.map +0 -1
- package/lib/packlets/conversion/index.d.ts.map +0 -1
- package/lib/packlets/conversion/index.js.map +0 -1
- package/lib/packlets/conversion/objectConverter.d.ts.map +0 -1
- package/lib/packlets/conversion/objectConverter.js.map +0 -1
- package/lib/packlets/conversion/stringConverter.d.ts.map +0 -1
- package/lib/packlets/conversion/stringConverter.js.map +0 -1
- package/lib/packlets/file-tree/directoryItem.d.ts.map +0 -1
- package/lib/packlets/file-tree/directoryItem.js.map +0 -1
- package/lib/packlets/file-tree/fileItem.d.ts.map +0 -1
- package/lib/packlets/file-tree/fileItem.js.map +0 -1
- package/lib/packlets/file-tree/fileTree.d.ts.map +0 -1
- package/lib/packlets/file-tree/fileTree.js.map +0 -1
- package/lib/packlets/file-tree/fileTreeAccessors.d.ts.map +0 -1
- package/lib/packlets/file-tree/fileTreeAccessors.js.map +0 -1
- package/lib/packlets/file-tree/fsTree.d.ts.map +0 -1
- package/lib/packlets/file-tree/fsTree.js.map +0 -1
- package/lib/packlets/file-tree/in-memory/inMemoryTree.d.ts.map +0 -1
- package/lib/packlets/file-tree/in-memory/inMemoryTree.js.map +0 -1
- package/lib/packlets/file-tree/in-memory/index.d.ts.map +0 -1
- package/lib/packlets/file-tree/in-memory/index.js.map +0 -1
- package/lib/packlets/file-tree/in-memory/treeBuilder.d.ts.map +0 -1
- package/lib/packlets/file-tree/in-memory/treeBuilder.js.map +0 -1
- package/lib/packlets/file-tree/index.d.ts.map +0 -1
- package/lib/packlets/file-tree/index.js.map +0 -1
- package/lib/packlets/hash/crcNormalizer.d.ts.map +0 -1
- package/lib/packlets/hash/crcNormalizer.js.map +0 -1
- package/lib/packlets/hash/hashingNormalizer.d.ts.map +0 -1
- package/lib/packlets/hash/hashingNormalizer.js.map +0 -1
- package/lib/packlets/hash/index.d.ts.map +0 -1
- package/lib/packlets/hash/index.js.map +0 -1
- package/lib/packlets/validation/array.d.ts.map +0 -1
- package/lib/packlets/validation/array.js.map +0 -1
- package/lib/packlets/validation/boolean.d.ts.map +0 -1
- package/lib/packlets/validation/boolean.js.map +0 -1
- package/lib/packlets/validation/classes.d.ts.map +0 -1
- package/lib/packlets/validation/classes.js.map +0 -1
- package/lib/packlets/validation/common.d.ts.map +0 -1
- package/lib/packlets/validation/common.js.map +0 -1
- package/lib/packlets/validation/field.d.ts.map +0 -1
- package/lib/packlets/validation/field.js.map +0 -1
- package/lib/packlets/validation/genericValidator.d.ts.map +0 -1
- package/lib/packlets/validation/genericValidator.js.map +0 -1
- package/lib/packlets/validation/index.d.ts.map +0 -1
- package/lib/packlets/validation/index.js.map +0 -1
- package/lib/packlets/validation/number.d.ts.map +0 -1
- package/lib/packlets/validation/number.js.map +0 -1
- package/lib/packlets/validation/object.d.ts.map +0 -1
- package/lib/packlets/validation/object.js.map +0 -1
- package/lib/packlets/validation/oneOf.d.ts.map +0 -1
- package/lib/packlets/validation/oneOf.js.map +0 -1
- package/lib/packlets/validation/string.d.ts.map +0 -1
- package/lib/packlets/validation/string.js.map +0 -1
- package/lib/packlets/validation/traits.d.ts.map +0 -1
- package/lib/packlets/validation/traits.js.map +0 -1
- package/lib/packlets/validation/typeGuard.d.ts.map +0 -1
- package/lib/packlets/validation/typeGuard.js.map +0 -1
- package/lib/packlets/validation/validator.d.ts.map +0 -1
- package/lib/packlets/validation/validator.js.map +0 -1
- package/lib/packlets/validation/validatorBase.d.ts.map +0 -1
- package/lib/packlets/validation/validatorBase.js.map +0 -1
- package/lib/packlets/validation/validators.d.ts.map +0 -1
- package/lib/packlets/validation/validators.js.map +0 -1
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 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
|
+
|
|
23
|
+
import {
|
|
24
|
+
captureResult,
|
|
25
|
+
DetailedResult,
|
|
26
|
+
failWithDetail,
|
|
27
|
+
Result,
|
|
28
|
+
fail,
|
|
29
|
+
succeed,
|
|
30
|
+
succeedWithDetail
|
|
31
|
+
} from '../base';
|
|
32
|
+
import { CollectibleFactoryCallback, CollectibleKey, ICollectible } from './collectible';
|
|
33
|
+
import { KeyValueEntry } from './common';
|
|
34
|
+
import { IReadOnlyResultMap, ResultMapForEachCb, ResultMapResultDetail } from './readonlyResultMap';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Additional success or failure details for mutating collector calls.
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
export type CollectorResultDetail = ResultMapResultDetail | 'invalid-index';
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A read-only interface exposing only the non-mutating methods of a {@link Collections.Collector | ICollector}.
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export interface IReadOnlyCollector<
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
+
TITEM extends ICollectible<any, any>
|
|
49
|
+
> extends IReadOnlyResultMap<CollectibleKey<TITEM>, TITEM> {
|
|
50
|
+
/**
|
|
51
|
+
* Gets the item at a specified index.
|
|
52
|
+
* @param index - The index of the item to retrieve.
|
|
53
|
+
* @returns Returns {@link Success | Success} with the item if it exists, or {@link Failure | Failure}
|
|
54
|
+
* with an error if the index is out of range.
|
|
55
|
+
*/
|
|
56
|
+
getAt(index: number): Result<TITEM>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Parameters for constructing a {@link Collections.Collector | ICollector}.
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
export interface ICollectorConstructorParams<
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
65
|
+
TITEM extends ICollectible<any, any>
|
|
66
|
+
> {
|
|
67
|
+
items?: TITEM[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A {@link Collections.Collector | Collector} that is a specialized collection
|
|
72
|
+
* which contains items of type {@link Collections.ICollectible | ICollectible},
|
|
73
|
+
* which have a unique key and a write-once index.
|
|
74
|
+
*
|
|
75
|
+
* Items are assigned an index sequentially as they are added to the collection.
|
|
76
|
+
* Once added, items are immutable - they cannot be removed or replaced.
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
79
|
+
export class Collector<
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
+
TITEM extends ICollectible<any, any>
|
|
82
|
+
> implements IReadOnlyCollector<TITEM>
|
|
83
|
+
{
|
|
84
|
+
private readonly _byKey: Map<CollectibleKey<TITEM>, TITEM>;
|
|
85
|
+
private readonly _byIndex: TITEM[];
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* {@inheritdoc Collections.ResultMap.size}
|
|
89
|
+
*/
|
|
90
|
+
public get size(): number {
|
|
91
|
+
return this._byIndex.length;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Constructs a new {@link Collections.Collector | Collector}.
|
|
96
|
+
* @param params - Optional {@link Collections.ICollectorConstructorParams | initialization parameters} used
|
|
97
|
+
* to construct the collector.
|
|
98
|
+
*/
|
|
99
|
+
public constructor(params?: ICollectorConstructorParams<TITEM>) {
|
|
100
|
+
this._byKey = new Map<CollectibleKey<TITEM>, TITEM>();
|
|
101
|
+
this._byIndex = [];
|
|
102
|
+
for (const item of params?.items ?? []) {
|
|
103
|
+
this.add(item).orThrow();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Creates a new {@link Collections.Collector | Collector} instance.
|
|
109
|
+
* @param params - Optional {@link Collections.ICollectorConstructorParams | initialization parameters} used
|
|
110
|
+
* to create the collector.
|
|
111
|
+
* @returns Returns {@link Success | Success} with the new collector if it was created successfully,
|
|
112
|
+
* or {@link Failure | Failure} with an error if the collector could not be created.
|
|
113
|
+
*/
|
|
114
|
+
public static createCollector<
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
116
|
+
TITEM extends ICollectible<any, any>
|
|
117
|
+
>(params?: ICollectorConstructorParams<TITEM>): Result<Collector<TITEM>> {
|
|
118
|
+
return captureResult(() => new Collector(params));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Adds an item to the collection, failing if a different item with the same key already exists. Note
|
|
123
|
+
* that adding an object that is already in the collection again will succeed without updating the collection.
|
|
124
|
+
* @param item - The item to add.
|
|
125
|
+
* @returns Returns {@link DetailedSuccess | Success} with the item and detail `added` if it was added
|
|
126
|
+
* or detail `exists` if the item was already in the map. Returns {@link DetailedFailure | Failure} with
|
|
127
|
+
* an error message and appropriate detail if the item could not be added.
|
|
128
|
+
*/
|
|
129
|
+
public add(item: TITEM): DetailedResult<TITEM, CollectorResultDetail> {
|
|
130
|
+
const existing = this._byKey.get(item.key);
|
|
131
|
+
if (existing === item) {
|
|
132
|
+
return succeedWithDetail(item, 'exists');
|
|
133
|
+
} else if (existing) {
|
|
134
|
+
return failWithDetail(`${item.key}: already exists`, 'exists');
|
|
135
|
+
}
|
|
136
|
+
const indexResult = item.setIndex(this._byIndex.length);
|
|
137
|
+
if (indexResult.isFailure()) {
|
|
138
|
+
return failWithDetail(`${item.key}: ${indexResult.message}`, 'invalid-index');
|
|
139
|
+
} else if (item.index !== this._byIndex.length) {
|
|
140
|
+
return failWithDetail(`${item.key}: index mismatch - built item has ${item.index}`, 'invalid-index');
|
|
141
|
+
}
|
|
142
|
+
this._byKey.set(item.key, item);
|
|
143
|
+
this._byIndex.push(item);
|
|
144
|
+
return succeedWithDetail(item, 'added');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* {@inheritdoc Collections.ResultMap.entries}
|
|
149
|
+
*/
|
|
150
|
+
public entries(): IterableIterator<KeyValueEntry<CollectibleKey<TITEM>, TITEM>> {
|
|
151
|
+
return this._byKey.entries();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* {@inheritdoc Collections.ResultMap.forEach}
|
|
156
|
+
*/
|
|
157
|
+
public forEach(callback: ResultMapForEachCb<CollectibleKey<TITEM>, TITEM>, arg?: unknown): void {
|
|
158
|
+
for (const [key, value] of this._byKey.entries()) {
|
|
159
|
+
callback(value, key, this, arg);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* {@inheritdoc Collections.ResultMap.get}
|
|
165
|
+
*/
|
|
166
|
+
public get(key: CollectibleKey<TITEM>): DetailedResult<TITEM, ResultMapResultDetail> {
|
|
167
|
+
const item = this._byKey.get(key);
|
|
168
|
+
return item ? succeedWithDetail(item, 'exists') : failWithDetail(`${key}: not found`, 'not-found');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* {@inheritdoc Collections.IReadOnlyCollector.getAt}
|
|
173
|
+
*/
|
|
174
|
+
public getAt(index: number): Result<TITEM> {
|
|
175
|
+
if (index < 0 || index >= this._byIndex.length) {
|
|
176
|
+
return fail(`${index}: out of range.`);
|
|
177
|
+
}
|
|
178
|
+
return succeed(this._byIndex[index]);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Gets an existing item with a key matching that of a supplied item, or adds the supplied
|
|
183
|
+
* item to the collector if no item with that key exists.
|
|
184
|
+
* @param item - The item to get or add.
|
|
185
|
+
* @returns Returns {@link DetailedSuccess | Success} with the item stored in the collector -
|
|
186
|
+
* detail `exists` indicates that an existing item return and detail `added` indicates that the
|
|
187
|
+
* item was added. Returns {@link DetailedFailure | Failure} with an error and appropriate
|
|
188
|
+
* detail if the item could not be added.
|
|
189
|
+
*/
|
|
190
|
+
public getOrAdd(item: TITEM): DetailedResult<TITEM, CollectorResultDetail>;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Gets an existing item with a key matching the supplied key, or adds a new item to the collector
|
|
194
|
+
* using a factory callback if no item with that key exists.
|
|
195
|
+
* @param key - The key of the item to add.
|
|
196
|
+
* @param callback - The factory callback to create the item.
|
|
197
|
+
* @returns Returns {@link DetailedSuccess | Success} with the item stored in the collector -
|
|
198
|
+
* detail `exists` indicates that an existing item return and detail `added` indicates that the
|
|
199
|
+
* item was added. Returns {@link DetailedFailure | Failure} with an error and appropriate
|
|
200
|
+
* detail if the item could not be added.
|
|
201
|
+
*/
|
|
202
|
+
public getOrAdd(
|
|
203
|
+
key: CollectibleKey<TITEM>,
|
|
204
|
+
factory: CollectibleFactoryCallback<TITEM>
|
|
205
|
+
): DetailedResult<TITEM, CollectorResultDetail>;
|
|
206
|
+
|
|
207
|
+
public getOrAdd(
|
|
208
|
+
keyOrItem: CollectibleKey<TITEM> | TITEM,
|
|
209
|
+
factory?: CollectibleFactoryCallback<TITEM>
|
|
210
|
+
): DetailedResult<TITEM, CollectorResultDetail> {
|
|
211
|
+
const key = !this._isItem(keyOrItem) ? keyOrItem : keyOrItem.key;
|
|
212
|
+
const existing = this._byKey.get(key);
|
|
213
|
+
if (existing) {
|
|
214
|
+
return succeedWithDetail(existing, 'exists');
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const itemResult = !this._isItem(keyOrItem)
|
|
218
|
+
? factory!(keyOrItem, this._byIndex.length)
|
|
219
|
+
: succeed(keyOrItem);
|
|
220
|
+
if (itemResult.isFailure()) {
|
|
221
|
+
return failWithDetail(`${key}: ${itemResult.message}`, 'invalid-value');
|
|
222
|
+
}
|
|
223
|
+
const item = itemResult.value;
|
|
224
|
+
|
|
225
|
+
if (item.key !== key) {
|
|
226
|
+
return failWithDetail(`${key}: key mismatch - built item has ${key}`, 'invalid-key');
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return itemResult.withFailureDetail<CollectorResultDetail>('invalid-index').onSuccess((item) => {
|
|
230
|
+
return this.add(item);
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* {@inheritdoc Collections.ResultMap.has}
|
|
236
|
+
*/
|
|
237
|
+
public has(key: CollectibleKey<TITEM>): boolean {
|
|
238
|
+
return this._byKey.has(key);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* {@inheritdoc Collections.ResultMap.keys}
|
|
243
|
+
*/
|
|
244
|
+
public keys(): IterableIterator<CollectibleKey<TITEM>> {
|
|
245
|
+
return this._byKey.keys();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* {@inheritdoc Collections.ResultMap.values}
|
|
250
|
+
*/
|
|
251
|
+
public values(): IterableIterator<TITEM> {
|
|
252
|
+
return this._byKey.values();
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Gets a read-only version of this collector.
|
|
257
|
+
*/
|
|
258
|
+
public toReadOnly(): IReadOnlyCollector<TITEM> {
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Gets an iterator over the map entries.
|
|
264
|
+
* @returns An iterator over the map entries.
|
|
265
|
+
*/
|
|
266
|
+
public [Symbol.iterator](): IterableIterator<KeyValueEntry<CollectibleKey<TITEM>, TITEM>> {
|
|
267
|
+
return this._byKey[Symbol.iterator]();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
protected _isItem(keyOrItem: CollectibleKey<TITEM> | TITEM): keyOrItem is TITEM {
|
|
271
|
+
return typeof keyOrItem !== 'string';
|
|
272
|
+
}
|
|
273
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 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
|
+
|
|
23
|
+
import { DetailedResult } from '../base';
|
|
24
|
+
import { IReadOnlyResultMap, ResultMapResultDetail } from './readonlyResultMap';
|
|
25
|
+
import { ResultMapValueFactory } from './resultMap';
|
|
26
|
+
import { KeyValueConverters } from './keyValueConverters';
|
|
27
|
+
import { Collector, CollectorResultDetail } from './collector';
|
|
28
|
+
import { IReadOnlyResultMapValidator } from './resultMapValidator';
|
|
29
|
+
import { CollectibleKey, ICollectible } from './collectible';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A read-only interface exposing non-mutating methods of a
|
|
33
|
+
* {@link Collections.CollectorValidator | CollectorValidator}.
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
export interface IReadOnlyCollectorValidator<
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
TITEM extends ICollectible<any, any>
|
|
39
|
+
> extends IReadOnlyResultMapValidator<CollectibleKey<TITEM>, TITEM> {
|
|
40
|
+
/**
|
|
41
|
+
* {@inheritdoc Collections.ConvertingCollectorValidator.map}
|
|
42
|
+
*/
|
|
43
|
+
readonly map: IReadOnlyResultMap<CollectibleKey<TITEM>, TITEM>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* {@inheritdoc Collections.Collector.get}
|
|
47
|
+
*/
|
|
48
|
+
get(key: string): DetailedResult<TITEM, ResultMapResultDetail>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* {@inheritdoc Collections.ResultMap.has}
|
|
52
|
+
*/
|
|
53
|
+
has(key: string): boolean;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* {@inheritdoc Collections.Collector.(getOrAdd:2)}
|
|
57
|
+
*/
|
|
58
|
+
getOrAdd(
|
|
59
|
+
key: string,
|
|
60
|
+
factory: ResultMapValueFactory<CollectibleKey<TITEM>, TITEM>
|
|
61
|
+
): DetailedResult<TITEM, CollectorResultDetail>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Parameters for constructing a {@link Collections.CollectorValidator | CollectorValidator}.
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
export interface ICollectorValidatorCreateParams<
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
70
|
+
TITEM extends ICollectible<any, any>
|
|
71
|
+
> {
|
|
72
|
+
readonly collector: Collector<TITEM>;
|
|
73
|
+
readonly converters: KeyValueConverters<CollectibleKey<TITEM>, TITEM>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A {@link Collections.Collector | Collector} wrapper which validates weakly-typed keys
|
|
78
|
+
* and values before calling the wrapped collector.
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
export class CollectorValidator<
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
|
+
TITEM extends ICollectible<any, any>
|
|
84
|
+
> implements IReadOnlyCollectorValidator<TITEM>
|
|
85
|
+
{
|
|
86
|
+
public readonly converters: KeyValueConverters<CollectibleKey<TITEM>, TITEM>;
|
|
87
|
+
|
|
88
|
+
public get map(): IReadOnlyResultMap<CollectibleKey<TITEM>, TITEM> {
|
|
89
|
+
return this._collector.toReadOnly();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
protected _collector: Collector<TITEM>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Constructs a new {@link Collections.ConvertingCollectorValidator | ConvertingCollectorValidator}.
|
|
96
|
+
* @param params - Required parameters for constructing the collector validator.
|
|
97
|
+
*/
|
|
98
|
+
public constructor(params: ICollectorValidatorCreateParams<TITEM>) {
|
|
99
|
+
this._collector = params.collector;
|
|
100
|
+
this.converters = params.converters;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* {@inheritdoc Collections.Collector.add}
|
|
105
|
+
*/
|
|
106
|
+
public add(item: unknown): DetailedResult<TITEM, CollectorResultDetail> {
|
|
107
|
+
return this._convertValue(item).onSuccess((i) => {
|
|
108
|
+
return this._collector.add(i);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* {@inheritdoc Collections.Collector.get}
|
|
114
|
+
*/
|
|
115
|
+
public get(key: string): DetailedResult<TITEM, ResultMapResultDetail> {
|
|
116
|
+
return this.converters.convertKey(key).onSuccess((k) => {
|
|
117
|
+
return this._collector.get(k);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* {@inheritdoc Collections.Collector.(getOrAdd:2)}
|
|
123
|
+
*/
|
|
124
|
+
public getOrAdd(
|
|
125
|
+
key: string,
|
|
126
|
+
factory: ResultMapValueFactory<CollectibleKey<TITEM>, TITEM>
|
|
127
|
+
): DetailedResult<TITEM, CollectorResultDetail>;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* {@inheritdoc Collections.Collector.(getOrAdd:1)}
|
|
131
|
+
* @param item - The item to add to the collector.
|
|
132
|
+
*/
|
|
133
|
+
public getOrAdd(item: unknown): DetailedResult<TITEM, CollectorResultDetail>;
|
|
134
|
+
|
|
135
|
+
public getOrAdd(
|
|
136
|
+
keyOrItem: string | unknown,
|
|
137
|
+
factoryCb?: ResultMapValueFactory<CollectibleKey<TITEM>, TITEM>
|
|
138
|
+
): DetailedResult<TITEM, CollectorResultDetail> {
|
|
139
|
+
if (factoryCb === undefined) {
|
|
140
|
+
return this._convertValue(keyOrItem).onSuccess((item) => this._collector.getOrAdd(item));
|
|
141
|
+
} else {
|
|
142
|
+
return this.converters
|
|
143
|
+
.convertKey(keyOrItem)
|
|
144
|
+
.withDetail<CollectorResultDetail>('invalid-key', 'success')
|
|
145
|
+
.onSuccess((key) => this._collector.getOrAdd(key, factoryCb));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* {@inheritdoc Collections.ResultMap.has}
|
|
151
|
+
*/
|
|
152
|
+
public has(key: string): boolean {
|
|
153
|
+
return this._collector.has(key as CollectibleKey<TITEM>);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* {@inheritdoc Collections.Collector.toReadOnly}
|
|
158
|
+
*/
|
|
159
|
+
public toReadOnly(): IReadOnlyCollectorValidator<TITEM> {
|
|
160
|
+
return this;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Helper to convert a value, returning a {@link DetailedResult | DetailedResult}
|
|
165
|
+
* and formatting the error message.
|
|
166
|
+
* @param value - The value to convert.
|
|
167
|
+
* @returns {@link DetailedSuccess | DetailedSuccess} with the converted value
|
|
168
|
+
* and detail `success` if conversion is successful, or
|
|
169
|
+
* {@link DetailedFailure | DetailedFailure} with the error message and detail `invalid-value`
|
|
170
|
+
* if conversion fails.
|
|
171
|
+
*/
|
|
172
|
+
protected _convertValue(value: unknown): DetailedResult<TITEM, CollectorResultDetail> {
|
|
173
|
+
return this.converters
|
|
174
|
+
.convertValue(value)
|
|
175
|
+
.withErrorFormat((message) => `invalid item: ${message}`)
|
|
176
|
+
.withDetail<CollectorResultDetail>('invalid-value', 'success');
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 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
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Generic key-value entry.
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export type KeyValueEntry<TK extends string = string, TV = unknown> = [TK, TV];
|