@fgv/ts-utils 5.0.1-0 → 5.0.1-10
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/ts-utils.d.ts +28 -16
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/packlets/base/result.d.ts +17 -12
- package/lib/packlets/base/result.js +20 -10
- package/lib/packlets/hash/crcNormalizer.js +42 -2
- package/lib/packlets/logging/logReporter.d.ts +11 -5
- package/lib/packlets/logging/logReporter.js +22 -9
- package/package.json +25 -15
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import { matcherHint } from 'jest-matcher-utils';
|
|
3
|
+
import { toMatchInlineSnapshot } from 'jest-snapshot';
|
|
4
|
+
import { printReceivedResult } from '../../utils/matcherHelpers';
|
|
5
|
+
const matcherName = 'toSucceedAndMatchInlineSnapshot';
|
|
6
|
+
export default {
|
|
7
|
+
toSucceedAndMatchInlineSnapshot: function (received, snapshot) {
|
|
8
|
+
const context = this;
|
|
9
|
+
if (received.isFailure()) {
|
|
10
|
+
return {
|
|
11
|
+
pass: false,
|
|
12
|
+
message: () => {
|
|
13
|
+
return [
|
|
14
|
+
matcherHint(`${matcherName}`, 'callback'),
|
|
15
|
+
'Expected:\n Callback to succeed with a result that matches the snapshot',
|
|
16
|
+
printReceivedResult(received)
|
|
17
|
+
].join('\n');
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return toMatchInlineSnapshot.call(context, received.value, {}, snapshot);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import { matcherHint } from 'jest-matcher-utils';
|
|
3
|
+
import { toMatchSnapshot } from 'jest-snapshot';
|
|
4
|
+
import { printReceivedResult } from '../../utils/matcherHelpers';
|
|
5
|
+
const matcherName = 'toSucceedAndMatchSnapshot';
|
|
6
|
+
export default {
|
|
7
|
+
toSucceedAndMatchSnapshot: function (received) {
|
|
8
|
+
const context = this;
|
|
9
|
+
if (received.isFailure()) {
|
|
10
|
+
return {
|
|
11
|
+
pass: false,
|
|
12
|
+
message: () => {
|
|
13
|
+
return [
|
|
14
|
+
matcherHint(`${matcherName}`, 'callback'),
|
|
15
|
+
'Expected:\n Callback to succeed with a result that matches the snapshot',
|
|
16
|
+
printReceivedResult(received)
|
|
17
|
+
].join('\n');
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return toMatchSnapshot.call(context, received.value, 'toSucceedAndMatchSnapshot');
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { printExpectedResult, printReceivedResult } from '../../utils/matcherHelpers';
|
|
2
|
+
import { matcherName, predicate } from './predicate';
|
|
3
|
+
import { matcherHint } from 'jest-matcher-utils';
|
|
4
|
+
function passMessage(received) {
|
|
5
|
+
const expected = 'successful callback';
|
|
6
|
+
const got = [printReceivedResult(received)];
|
|
7
|
+
got.push(' Callback returned true');
|
|
8
|
+
return () => [
|
|
9
|
+
matcherHint(`.not.${matcherName}`, 'result', 'callback'),
|
|
10
|
+
printExpectedResult('success', false, expected),
|
|
11
|
+
...got
|
|
12
|
+
].join('\n');
|
|
13
|
+
}
|
|
14
|
+
function failMessage(received, cbResult) {
|
|
15
|
+
const expected = 'successful callback';
|
|
16
|
+
const got = [printReceivedResult(received)];
|
|
17
|
+
/* c8 ignore else */
|
|
18
|
+
if (cbResult.isFailure()) {
|
|
19
|
+
got.push(cbResult.message);
|
|
20
|
+
}
|
|
21
|
+
else if (cbResult.value === false) {
|
|
22
|
+
got.push(' Callback returned false');
|
|
23
|
+
}
|
|
24
|
+
else if (cbResult.value === undefined) {
|
|
25
|
+
/* c8 ignore else */
|
|
26
|
+
got.push(' Callback was not invoked');
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
/* c8 ignore next */
|
|
30
|
+
throw new Error('Internal error: toSucceedAndSatisfy.failMessage passed success with true');
|
|
31
|
+
}
|
|
32
|
+
return () => [
|
|
33
|
+
matcherHint(`${matcherName}`, 'result', 'callback'),
|
|
34
|
+
printExpectedResult('success', true, expected),
|
|
35
|
+
...got
|
|
36
|
+
].join('\n');
|
|
37
|
+
}
|
|
38
|
+
export default {
|
|
39
|
+
toSucceedAndSatisfy: function (received, test) {
|
|
40
|
+
// For the normal (not '.not') case, we do not want to capture exceptions
|
|
41
|
+
// so that the IDE can display exactly the line on which the failure case.
|
|
42
|
+
// For the .not case, we want to swallow exceptions or expect failures since
|
|
43
|
+
// we're just testing failure and not the reason.
|
|
44
|
+
const capture = this.isNot;
|
|
45
|
+
const cbResult = predicate(received, test, !!capture);
|
|
46
|
+
const pass = cbResult.isSuccess() && cbResult.value === true;
|
|
47
|
+
if (pass) {
|
|
48
|
+
return { pass: true, message: passMessage(received) };
|
|
49
|
+
}
|
|
50
|
+
return { pass: false, message: failMessage(received, cbResult) };
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { captureResult, fail, succeed } from '../../ts-utils';
|
|
2
|
+
export const matcherName = 'toSucceedAndSatisfy';
|
|
3
|
+
// If the result is successful and callback does not throw, returns Success with the callback return value, or
|
|
4
|
+
// true if the callback returns undefined
|
|
5
|
+
// If the result is successful but the callback throws, returns Failure with the thrown error
|
|
6
|
+
// If the result is failure, returns Success with undefined
|
|
7
|
+
export function predicate(received, cb, capture) {
|
|
8
|
+
if (received.isSuccess()) {
|
|
9
|
+
const cbResult = capture ? captureResult(() => cb(received.value)) : succeed(cb(received.value));
|
|
10
|
+
if (cbResult.isSuccess()) {
|
|
11
|
+
return succeed(cbResult.value === true || cbResult.value === undefined);
|
|
12
|
+
}
|
|
13
|
+
return fail(` Callback failed with:\n ${cbResult.message}`);
|
|
14
|
+
}
|
|
15
|
+
return succeed(undefined);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=predicate.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { printExpectedResult, printReceivedResult } from '../../utils/matcherHelpers';
|
|
2
|
+
import { matcherName, predicate } from './predicate';
|
|
3
|
+
import { matcherHint } from 'jest-matcher-utils';
|
|
4
|
+
function passMessage(received, expected) {
|
|
5
|
+
return () => [
|
|
6
|
+
matcherHint(`.not.${matcherName}`),
|
|
7
|
+
printExpectedResult('success', false, expected),
|
|
8
|
+
printReceivedResult(received)
|
|
9
|
+
].join('\n');
|
|
10
|
+
}
|
|
11
|
+
function failMessage(received, expected) {
|
|
12
|
+
return () => [
|
|
13
|
+
matcherHint(`${matcherName}`),
|
|
14
|
+
printExpectedResult('success', true, expected),
|
|
15
|
+
printReceivedResult(received)
|
|
16
|
+
].join('\n');
|
|
17
|
+
}
|
|
18
|
+
export default {
|
|
19
|
+
toSucceedWith: function (received, expected) {
|
|
20
|
+
const pass = predicate(received, expected);
|
|
21
|
+
if (pass) {
|
|
22
|
+
return { pass: true, message: passMessage(received, expected) };
|
|
23
|
+
}
|
|
24
|
+
return { pass: false, message: failMessage(received, expected) };
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { equals } from '@jest/expect-utils';
|
|
2
|
+
export const matcherName = 'toSucceedWith';
|
|
3
|
+
export function predicate(received, expected) {
|
|
4
|
+
if (received.isSuccess()) {
|
|
5
|
+
if (typeof received.value === 'string' && expected instanceof RegExp) {
|
|
6
|
+
return expected.test(received.value);
|
|
7
|
+
}
|
|
8
|
+
return equals(received.value, expected);
|
|
9
|
+
}
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=predicate.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { printExpectedDetailedResult, printReceivedDetailedResult } from '../../utils/matcherHelpers';
|
|
2
|
+
import { matcherName, predicate } from './predicate';
|
|
3
|
+
import { matcherHint } from 'jest-matcher-utils';
|
|
4
|
+
function passMessage(received, expected, expectedDetail) {
|
|
5
|
+
return () => [
|
|
6
|
+
matcherHint(`.not.${matcherName}`),
|
|
7
|
+
printExpectedDetailedResult('success', false, expected, expectedDetail),
|
|
8
|
+
printReceivedDetailedResult(received)
|
|
9
|
+
].join('\n');
|
|
10
|
+
}
|
|
11
|
+
function failMessage(received, expected, expectedDetail) {
|
|
12
|
+
return () => [
|
|
13
|
+
matcherHint(`${matcherName}`),
|
|
14
|
+
printExpectedDetailedResult('success', true, expected, expectedDetail),
|
|
15
|
+
printReceivedDetailedResult(received)
|
|
16
|
+
].join('\n');
|
|
17
|
+
}
|
|
18
|
+
export default {
|
|
19
|
+
toSucceedWithDetail: function (received, expected, detail) {
|
|
20
|
+
const pass = predicate(received, expected, detail);
|
|
21
|
+
if (pass) {
|
|
22
|
+
return { pass: true, message: passMessage(received, expected, detail) };
|
|
23
|
+
}
|
|
24
|
+
return { pass: false, message: failMessage(received, expected, detail) };
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { equals } from '@jest/expect-utils';
|
|
2
|
+
export const matcherName = 'toSucceedWithDetail';
|
|
3
|
+
export function predicate(received, expected, detail) {
|
|
4
|
+
if (received.isSuccess()) {
|
|
5
|
+
let pass = false;
|
|
6
|
+
if (typeof received.value === 'string' && expected instanceof RegExp) {
|
|
7
|
+
pass = expected.test(received.value);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
pass = equals(received.value, expected);
|
|
11
|
+
}
|
|
12
|
+
pass = pass && equals(received.detail, detail);
|
|
13
|
+
return pass;
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=predicate.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as Resolver from '../utils/snapshotResolver';
|
|
2
|
+
export const CLI_SNAPSHOT_FOLDER = '__cli__';
|
|
3
|
+
export function resolveSnapshotPath(testPath, ext) {
|
|
4
|
+
return Resolver.resolveSnapshotPath(testPath, ext, CLI_SNAPSHOT_FOLDER);
|
|
5
|
+
}
|
|
6
|
+
export function resolveTestPath(snapshotPath, ext) {
|
|
7
|
+
return Resolver.resolveTestPath(snapshotPath, ext);
|
|
8
|
+
}
|
|
9
|
+
export const testPathForConsistencyCheck = Resolver.testPathForConsistencyCheck;
|
|
10
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as Resolver from '../utils/snapshotResolver';
|
|
2
|
+
export const CLI_SNAPSHOT_FOLDER = '__ide__';
|
|
3
|
+
export function resolveSnapshotPath(testPath, ext) {
|
|
4
|
+
return Resolver.resolveSnapshotPath(testPath, ext, CLI_SNAPSHOT_FOLDER);
|
|
5
|
+
}
|
|
6
|
+
export function resolveTestPath(snapshotPath, ext) {
|
|
7
|
+
return Resolver.resolveTestPath(snapshotPath, ext);
|
|
8
|
+
}
|
|
9
|
+
export const testPathForConsistencyCheck = Resolver.testPathForConsistencyCheck;
|
|
10
|
+
//# sourceMappingURL=ide.js.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { printExpected, printReceived } from 'jest-matcher-utils';
|
|
2
|
+
function printExpectedValue(outcome, expected) {
|
|
3
|
+
return expected !== undefined ? ` ${outcome} with ${printExpected(expected)}` : ` ${outcome}`;
|
|
4
|
+
}
|
|
5
|
+
export function printExpectedResult(expect, isNot, expected) {
|
|
6
|
+
return [
|
|
7
|
+
'Expected:',
|
|
8
|
+
isNot
|
|
9
|
+
? expect === 'success'
|
|
10
|
+
? printExpectedValue('Success', expected)
|
|
11
|
+
: printExpectedValue('Failure', expected)
|
|
12
|
+
: expect === 'success'
|
|
13
|
+
? printExpectedValue('Not success', expected)
|
|
14
|
+
: printExpectedValue('Not failure', expected)
|
|
15
|
+
].join('\n');
|
|
16
|
+
}
|
|
17
|
+
export function printExpectedDetailedResult(expect, isNot, expectedMessage, expectedDetail) {
|
|
18
|
+
/* c8 ignore next */
|
|
19
|
+
return [
|
|
20
|
+
'Expected:',
|
|
21
|
+
isNot
|
|
22
|
+
? expect === 'success'
|
|
23
|
+
? printExpectedValue('Success', expectedMessage)
|
|
24
|
+
: printExpectedValue('Failure', expectedMessage)
|
|
25
|
+
: expect === 'success'
|
|
26
|
+
? printExpectedValue('Not success', expectedMessage)
|
|
27
|
+
: printExpectedValue('Not failure', expectedMessage),
|
|
28
|
+
` Detail: "${printExpected(expectedDetail)}"`
|
|
29
|
+
].join('\n');
|
|
30
|
+
}
|
|
31
|
+
export function printReceivedResult(received) {
|
|
32
|
+
return [
|
|
33
|
+
'Received:',
|
|
34
|
+
received.isSuccess()
|
|
35
|
+
? ` Success with ${printReceived(received.value)}`
|
|
36
|
+
: ` Failure with "${received.message}"`
|
|
37
|
+
].join('\n');
|
|
38
|
+
}
|
|
39
|
+
export function printReceivedDetailedResult(received) {
|
|
40
|
+
return [
|
|
41
|
+
'Received:',
|
|
42
|
+
received.isSuccess()
|
|
43
|
+
? ` Success with "${printReceived(received.value)}"\n Detail: "${printReceived(received.detail)}"`
|
|
44
|
+
: ` Failure with "${received.message}"\n Detail: "${printReceived(received.detail)}"`
|
|
45
|
+
].join('\n');
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=matcherHelpers.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
export function resolveSnapshotPath(testPath, snapshotExtension, snapshotFolderName) {
|
|
3
|
+
const snapshotPath = path.join(path.join(path.dirname(testPath), '__snapshots__', snapshotFolderName), path.basename(testPath) + snapshotExtension);
|
|
4
|
+
return snapshotPath;
|
|
5
|
+
}
|
|
6
|
+
export function resolveTestPath(snapshotFilePath, snapshotExtension) {
|
|
7
|
+
const testPath = path.join(path.dirname(path.dirname(path.dirname(snapshotFilePath))), path.basename(snapshotFilePath, snapshotExtension));
|
|
8
|
+
return testPath;
|
|
9
|
+
}
|
|
10
|
+
export const testPathForConsistencyCheck = path.posix.join('consistency_check', '__tests__', 'subdir', 'example.test.js');
|
|
11
|
+
//# sourceMappingURL=snapshotResolver.js.map
|
|
@@ -0,0 +1,106 @@
|
|
|
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
|
+
import { captureResult, succeed } from '../../../packlets/base';
|
|
23
|
+
import { Collectible, ConvertingCollector } from '../../../packlets/collections';
|
|
24
|
+
import { Converters } from '../../../packlets/conversion';
|
|
25
|
+
export const testThingKey = Converters.string
|
|
26
|
+
.withConstraint((s) => /^thing\d{1,4}$/.test(s))
|
|
27
|
+
.withFormattedError((val) => `${val} is invalid TestThingKey`)
|
|
28
|
+
.withBrand('TestThingKey');
|
|
29
|
+
export const testThingIndex = Converters.number
|
|
30
|
+
.withConstraint((n) => n >= 0)
|
|
31
|
+
.withBrand('TestThingIndex');
|
|
32
|
+
export const testThing = Converters.strictObject({
|
|
33
|
+
str: Converters.string.optional(),
|
|
34
|
+
num: Converters.number.optional(),
|
|
35
|
+
bool: Converters.boolean.optional()
|
|
36
|
+
});
|
|
37
|
+
export class BrandedCollectibleTestThing extends Collectible {
|
|
38
|
+
constructor(thing, key, index) {
|
|
39
|
+
super({ key, index, indexConverter: testThingIndex });
|
|
40
|
+
this.str = thing.str;
|
|
41
|
+
this.num = thing.num;
|
|
42
|
+
this.bool = thing.bool;
|
|
43
|
+
}
|
|
44
|
+
static create(thing, key, index) {
|
|
45
|
+
return testThingKey.convert(key).onSuccess((convertedKey) => {
|
|
46
|
+
return testThingIndex.convert(index).onSuccess((convertedIndex) => {
|
|
47
|
+
return captureResult(() => new BrandedCollectibleTestThing(thing, convertedKey, convertedIndex));
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export class CollectibleTestThing extends Collectible {
|
|
53
|
+
constructor(thing, key, index) {
|
|
54
|
+
super({ key, index, indexConverter: Converters.number });
|
|
55
|
+
this.str = thing.str;
|
|
56
|
+
this.num = thing.num;
|
|
57
|
+
this.bool = thing.bool;
|
|
58
|
+
}
|
|
59
|
+
static create(thing, key, index) {
|
|
60
|
+
return captureResult(() => new CollectibleTestThing(thing, key, index));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export class BrokenCollectibleTestThing extends CollectibleTestThing {
|
|
64
|
+
constructor(thing, key, index) {
|
|
65
|
+
super(thing, key, index ? (index + 1) : undefined);
|
|
66
|
+
}
|
|
67
|
+
setIndex(index) {
|
|
68
|
+
this._index = index + 1;
|
|
69
|
+
return succeed(this.index);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export class TestCollector extends ConvertingCollector {
|
|
73
|
+
constructor(things) {
|
|
74
|
+
const entries = things
|
|
75
|
+
? { entries: things.map((thing, index) => [`thing${index}`, thing]) }
|
|
76
|
+
: {};
|
|
77
|
+
const params = Object.assign({ factory: TestCollector._factory }, entries);
|
|
78
|
+
super(params);
|
|
79
|
+
}
|
|
80
|
+
static _factory(key, index, item) {
|
|
81
|
+
return succeed(new CollectibleTestThing(item, key, index));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export function getTestThings() {
|
|
85
|
+
const things = [
|
|
86
|
+
{ str: 'thing0', num: 0, bool: false },
|
|
87
|
+
{ str: 'thing1', num: 1, bool: true },
|
|
88
|
+
{ str: 'thing2', num: 2, bool: false },
|
|
89
|
+
{ str: 'thing3', num: 3, bool: true },
|
|
90
|
+
{ str: 'thing4', num: 4, bool: false }
|
|
91
|
+
];
|
|
92
|
+
const collectibles = things.map((thing, index) => new CollectibleTestThing(thing, `thing${index}`, index));
|
|
93
|
+
return { things, collectibles };
|
|
94
|
+
}
|
|
95
|
+
export function getBrandedTestThings() {
|
|
96
|
+
const things = [
|
|
97
|
+
{ str: 'thing0', num: 0, bool: false },
|
|
98
|
+
{ str: 'thing1', num: 1, bool: true },
|
|
99
|
+
{ str: 'thing2', num: 2, bool: false },
|
|
100
|
+
{ str: 'thing3', num: 3, bool: true },
|
|
101
|
+
{ str: 'thing4', num: 4, bool: false }
|
|
102
|
+
];
|
|
103
|
+
const collectibles = things.map((thing, index) => BrandedCollectibleTestThing.create(thing, `thing${index}`, index).orThrow());
|
|
104
|
+
return { things, collectibles };
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Erik Fortune
|
|
3
|
+
*/
|
|
4
|
+
import '../helpers/jest';
|
|
5
|
+
import { Crc32Normalizer } from '../../packlets/hash';
|
|
6
|
+
describe('Crc32Normalizer TextEncoder/Buffer compatibility', () => {
|
|
7
|
+
test('falls back to a non-TextEncoder path when TextEncoder is unavailable', () => {
|
|
8
|
+
const expected = Crc32Normalizer.crc32Hash(['hello']);
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
10
|
+
const g = globalThis;
|
|
11
|
+
const originalTextEncoder = g.TextEncoder;
|
|
12
|
+
try {
|
|
13
|
+
delete g.TextEncoder;
|
|
14
|
+
const actual = Crc32Normalizer.crc32Hash(['hello']);
|
|
15
|
+
expect(actual).toEqual(expected);
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
// Restore environment
|
|
19
|
+
g.TextEncoder = originalTextEncoder;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=hashTextEncodeCompat.js.map
|
package/dist/ts-utils.d.ts
CHANGED
|
@@ -1114,7 +1114,7 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
1114
1114
|
/**
|
|
1115
1115
|
* {@inheritdoc IResult.report}
|
|
1116
1116
|
*/
|
|
1117
|
-
report(reporter?: IResultReporter<T,
|
|
1117
|
+
report(reporter?: IResultReporter<T, unknown>, options?: IResultReportOptions<unknown>): DetailedFailure<T, TD>;
|
|
1118
1118
|
orThrow(logOrFormat?: IResultLogger<TD> | ErrorFormatter<TD>): never;
|
|
1119
1119
|
orThrow(cb: ErrorFormatter): never;
|
|
1120
1120
|
/**
|
|
@@ -1206,7 +1206,7 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
1206
1206
|
/**
|
|
1207
1207
|
* {@inheritdoc IResult.report}
|
|
1208
1208
|
*/
|
|
1209
|
-
report(reporter?: IResultReporter<T,
|
|
1209
|
+
report(reporter?: IResultReporter<T, unknown>, options?: IResultReportOptions<unknown>): DetailedSuccess<T, TD>;
|
|
1210
1210
|
/**
|
|
1211
1211
|
* Creates a {@link DetailedSuccess | DetailedSuccess<T, TD>} with the supplied value and
|
|
1212
1212
|
* optional detail.
|
|
@@ -1406,7 +1406,7 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
1406
1406
|
/**
|
|
1407
1407
|
* {@inheritdoc IResult.report}
|
|
1408
1408
|
*/
|
|
1409
|
-
report(reporter?: IResultReporter<T>, options?: IResultReportOptions):
|
|
1409
|
+
report(reporter?: IResultReporter<T>, options?: IResultReportOptions<unknown>): Failure<T>;
|
|
1410
1410
|
/**
|
|
1411
1411
|
* Get a 'friendly' string representation of this object.
|
|
1412
1412
|
* @remarks
|
|
@@ -1967,6 +1967,16 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
1967
1967
|
toString(separator?: string): string;
|
|
1968
1968
|
}
|
|
1969
1969
|
|
|
1970
|
+
/**
|
|
1971
|
+
* Details for reporting a message.
|
|
1972
|
+
* @public
|
|
1973
|
+
*/
|
|
1974
|
+
export declare interface IMessageReportDetail<TD = unknown> {
|
|
1975
|
+
level?: MessageLogLevel;
|
|
1976
|
+
message?: ErrorFormatter<TD>;
|
|
1977
|
+
detail?: TD;
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1970
1980
|
/**
|
|
1971
1981
|
* Infers the type that will be returned by an instantiated converter. Works
|
|
1972
1982
|
* for complex as well as simple types.
|
|
@@ -2345,7 +2355,7 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
2345
2355
|
* @param reporter - The {@link IResultReporter | reporter} to which the result will be reported.
|
|
2346
2356
|
* @param options - The {@link IResultReportOptions | options} for reporting the result.
|
|
2347
2357
|
*/
|
|
2348
|
-
report(reporter?: IResultReporter<T>, options?: IResultReportOptions):
|
|
2358
|
+
report(reporter?: IResultReporter<T>, options?: IResultReportOptions<unknown>): Result<T>;
|
|
2349
2359
|
}
|
|
2350
2360
|
|
|
2351
2361
|
/**
|
|
@@ -2382,7 +2392,7 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
2382
2392
|
* @public
|
|
2383
2393
|
*/
|
|
2384
2394
|
export declare interface IResultReporter<T, TD = unknown> {
|
|
2385
|
-
reportSuccess(level: MessageLogLevel, value: T, detail?: TD): void;
|
|
2395
|
+
reportSuccess(level: MessageLogLevel, value: T, detail?: TD, message?: ErrorFormatter<TD>): void;
|
|
2386
2396
|
reportFailure(level: MessageLogLevel, message: string, detail?: TD): void;
|
|
2387
2397
|
}
|
|
2388
2398
|
|
|
@@ -2394,15 +2404,11 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
2394
2404
|
/**
|
|
2395
2405
|
* The level of reporting to be used for failure results. Default is 'error'.
|
|
2396
2406
|
*/
|
|
2397
|
-
failure?: MessageLogLevel
|
|
2407
|
+
failure?: MessageLogLevel | IMessageReportDetail<TD>;
|
|
2398
2408
|
/**
|
|
2399
2409
|
* The level of reporting to be used for success results. Default is 'quiet'.
|
|
2400
2410
|
*/
|
|
2401
|
-
success?: MessageLogLevel
|
|
2402
|
-
/**
|
|
2403
|
-
* The error formatter to be used for reporting an error result.
|
|
2404
|
-
*/
|
|
2405
|
-
message?: ErrorFormatter<TD>;
|
|
2411
|
+
success?: MessageLogLevel | IMessageReportDetail<TD>;
|
|
2406
2412
|
}
|
|
2407
2413
|
|
|
2408
2414
|
/**
|
|
@@ -2681,10 +2687,10 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
2681
2687
|
*/
|
|
2682
2688
|
declare class LogReporter<T, TD = unknown> implements ILogger, IResultReporter<T, TD> {
|
|
2683
2689
|
/**
|
|
2684
|
-
*
|
|
2685
|
-
* @
|
|
2690
|
+
* Base logger used to by this reporter.
|
|
2691
|
+
* @public
|
|
2686
2692
|
*/
|
|
2687
|
-
|
|
2693
|
+
readonly logger: ILogger;
|
|
2688
2694
|
/**
|
|
2689
2695
|
* The formatter to use for values.
|
|
2690
2696
|
* @internal
|
|
@@ -2727,11 +2733,17 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
2727
2733
|
/**
|
|
2728
2734
|
* {@inheritDoc IResultReporter.reportSuccess}
|
|
2729
2735
|
*/
|
|
2730
|
-
reportSuccess(level: MessageLogLevel, value: T, detail?: TD): void;
|
|
2736
|
+
reportSuccess(level: MessageLogLevel, value: T, detail?: TD, message?: ErrorFormatter<TD>): void;
|
|
2731
2737
|
/**
|
|
2732
2738
|
* {@inheritDoc IResultReporter.reportFailure}
|
|
2733
2739
|
*/
|
|
2734
2740
|
reportFailure(level: MessageLogLevel, message: string, detail?: TD): void;
|
|
2741
|
+
/**
|
|
2742
|
+
* Creates a new {@link Logging.LogReporter | LogReporter} with the same logger but a different value formatter.
|
|
2743
|
+
* @param valueFormatter - The value formatter to use.
|
|
2744
|
+
* @returns A new {@link Logging.LogReporter | LogReporter} with the same logger but a different value formatter.
|
|
2745
|
+
*/
|
|
2746
|
+
withValueFormatter<TN>(valueFormatter: LogValueFormatter<TN, TD>): LogReporter<TN, TD>;
|
|
2735
2747
|
/**
|
|
2736
2748
|
* Generic method to try to format an object for logging.
|
|
2737
2749
|
* @param value - The value to format.
|
|
@@ -4232,7 +4244,7 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
4232
4244
|
/**
|
|
4233
4245
|
* {@inheritdoc IResult.report}
|
|
4234
4246
|
*/
|
|
4235
|
-
report(reporter?: IResultReporter<T>, options?: IResultReportOptions):
|
|
4247
|
+
report(reporter?: IResultReporter<T>, options?: IResultReportOptions<unknown>): Success<T>;
|
|
4236
4248
|
/**
|
|
4237
4249
|
* Creates a {@link Success | Success<T>} with the supplied value.
|
|
4238
4250
|
* @param value - The value to be returned.
|
package/dist/tsdoc-metadata.json
CHANGED
|
@@ -58,6 +58,15 @@ export interface IResultLogger<TD = unknown> {
|
|
|
58
58
|
* @public
|
|
59
59
|
*/
|
|
60
60
|
export type MessageLogLevel = 'quiet' | 'detail' | 'info' | 'warning' | 'error';
|
|
61
|
+
/**
|
|
62
|
+
* Details for reporting a message.
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export interface IMessageReportDetail<TD = unknown> {
|
|
66
|
+
level?: MessageLogLevel;
|
|
67
|
+
message?: ErrorFormatter<TD>;
|
|
68
|
+
detail?: TD;
|
|
69
|
+
}
|
|
61
70
|
/**
|
|
62
71
|
* Options for reporting a result.
|
|
63
72
|
* @public
|
|
@@ -66,22 +75,18 @@ export interface IResultReportOptions<TD = unknown> {
|
|
|
66
75
|
/**
|
|
67
76
|
* The level of reporting to be used for failure results. Default is 'error'.
|
|
68
77
|
*/
|
|
69
|
-
failure?: MessageLogLevel
|
|
78
|
+
failure?: MessageLogLevel | IMessageReportDetail<TD>;
|
|
70
79
|
/**
|
|
71
80
|
* The level of reporting to be used for success results. Default is 'quiet'.
|
|
72
81
|
*/
|
|
73
|
-
success?: MessageLogLevel
|
|
74
|
-
/**
|
|
75
|
-
* The error formatter to be used for reporting an error result.
|
|
76
|
-
*/
|
|
77
|
-
message?: ErrorFormatter<TD>;
|
|
82
|
+
success?: MessageLogLevel | IMessageReportDetail<TD>;
|
|
78
83
|
}
|
|
79
84
|
/**
|
|
80
85
|
* Interface for reporting a result.
|
|
81
86
|
* @public
|
|
82
87
|
*/
|
|
83
88
|
export interface IResultReporter<T, TD = unknown> {
|
|
84
|
-
reportSuccess(level: MessageLogLevel, value: T, detail?: TD): void;
|
|
89
|
+
reportSuccess(level: MessageLogLevel, value: T, detail?: TD, message?: ErrorFormatter<TD>): void;
|
|
85
90
|
reportFailure(level: MessageLogLevel, message: string, detail?: TD): void;
|
|
86
91
|
}
|
|
87
92
|
/**
|
|
@@ -286,7 +291,7 @@ export interface IResult<T> {
|
|
|
286
291
|
* @param reporter - The {@link IResultReporter | reporter} to which the result will be reported.
|
|
287
292
|
* @param options - The {@link IResultReportOptions | options} for reporting the result.
|
|
288
293
|
*/
|
|
289
|
-
report(reporter?: IResultReporter<T>, options?: IResultReportOptions):
|
|
294
|
+
report(reporter?: IResultReporter<T>, options?: IResultReportOptions<unknown>): Result<T>;
|
|
290
295
|
}
|
|
291
296
|
/**
|
|
292
297
|
* Reports a successful {@link IResult | result} from some operation and the
|
|
@@ -376,7 +381,7 @@ export declare class Success<T> implements IResult<T> {
|
|
|
376
381
|
/**
|
|
377
382
|
* {@inheritdoc IResult.report}
|
|
378
383
|
*/
|
|
379
|
-
report(reporter?: IResultReporter<T>, options?: IResultReportOptions):
|
|
384
|
+
report(reporter?: IResultReporter<T>, options?: IResultReportOptions<unknown>): Success<T>;
|
|
380
385
|
/**
|
|
381
386
|
* Creates a {@link Success | Success<T>} with the supplied value.
|
|
382
387
|
* @param value - The value to be returned.
|
|
@@ -472,7 +477,7 @@ export declare class Failure<T> implements IResult<T> {
|
|
|
472
477
|
/**
|
|
473
478
|
* {@inheritdoc IResult.report}
|
|
474
479
|
*/
|
|
475
|
-
report(reporter?: IResultReporter<T>, options?: IResultReportOptions):
|
|
480
|
+
report(reporter?: IResultReporter<T>, options?: IResultReportOptions<unknown>): Failure<T>;
|
|
476
481
|
/**
|
|
477
482
|
* Get a 'friendly' string representation of this object.
|
|
478
483
|
* @remarks
|
|
@@ -598,7 +603,7 @@ export declare class DetailedSuccess<T, TD> extends Success<T> {
|
|
|
598
603
|
/**
|
|
599
604
|
* {@inheritdoc IResult.report}
|
|
600
605
|
*/
|
|
601
|
-
report(reporter?: IResultReporter<T,
|
|
606
|
+
report(reporter?: IResultReporter<T, unknown>, options?: IResultReportOptions<unknown>): DetailedSuccess<T, TD>;
|
|
602
607
|
/**
|
|
603
608
|
* Creates a {@link DetailedSuccess | DetailedSuccess<T, TD>} with the supplied value and
|
|
604
609
|
* optional detail.
|
|
@@ -668,7 +673,7 @@ export declare class DetailedFailure<T, TD> extends Failure<T> {
|
|
|
668
673
|
/**
|
|
669
674
|
* {@inheritdoc IResult.report}
|
|
670
675
|
*/
|
|
671
|
-
report(reporter?: IResultReporter<T,
|
|
676
|
+
report(reporter?: IResultReporter<T, unknown>, options?: IResultReportOptions<unknown>): DetailedFailure<T, TD>;
|
|
672
677
|
orThrow(logOrFormat?: IResultLogger<TD> | ErrorFormatter<TD>): never;
|
|
673
678
|
orThrow(cb: ErrorFormatter): never;
|
|
674
679
|
/**
|