@rainbow-o23/n1 1.0.49 → 1.0.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -6
- package/index.cjs +641 -78
- package/index.d.ts +1 -0
- package/index.js +598 -54
- package/lib/pipeline/index.d.ts +2 -1
- package/lib/pipeline/step-helpers-utils.d.ts +28 -3
- package/lib/pipeline/step-helpers-value-operator.d.ts +34 -0
- package/lib/pipeline/step-helpers.d.ts +9 -23
- package/lib/pipeline/types.d.ts +1 -0
- package/lib/pipeline/value-operators/action-types.d.ts +18 -0
- package/lib/pipeline/value-operators/index.d.ts +8 -0
- package/lib/pipeline/value-operators/test-any-actions.d.ts +10 -0
- package/lib/pipeline/value-operators/test-decimal-actions.d.ts +25 -0
- package/lib/pipeline/value-operators/test-string-actions.d.ts +2 -0
- package/lib/pipeline/value-operators/testers.d.ts +36 -0
- package/lib/pipeline/value-operators/transform-decimal-actions.d.ts +21 -0
- package/lib/pipeline/value-operators/transform-string-actions.d.ts +10 -0
- package/lib/pipeline/value-operators/transformers.d.ts +31 -0
- package/package.json +25 -3
- package/rollup.config.base.js +1 -2
- package/src/index.ts +3 -0
- package/src/lib/pipeline/index.ts +2 -1
- package/src/lib/pipeline/step-helpers-utils.ts +105 -29
- package/src/lib/pipeline/step-helpers-value-operator.ts +307 -0
- package/src/lib/pipeline/step-helpers.ts +24 -50
- package/src/lib/pipeline/types.ts +7 -0
- package/src/lib/pipeline/value-operators/action-types.ts +8 -0
- package/src/lib/pipeline/value-operators/index.ts +10 -0
- package/src/lib/pipeline/value-operators/test-any-actions.ts +58 -0
- package/src/lib/pipeline/value-operators/test-decimal-actions.ts +85 -0
- package/src/lib/pipeline/value-operators/test-string-actions.ts +15 -0
- package/src/lib/pipeline/value-operators/testers.ts +59 -0
- package/src/lib/pipeline/value-operators/transform-decimal-actions.ts +88 -0
- package/src/lib/pipeline/value-operators/transform-string-actions.ts +49 -0
- package/src/lib/pipeline/value-operators/transformers.ts +34 -0
- package/test/value-test.test.ts +55 -0
- /package/lib/{pipeline/envs.d.ts → envs.d.ts} +0 -0
- /package/src/lib/{pipeline/envs.ts → envs.ts} +0 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import Decimal from 'decimal.js';
|
|
2
|
+
import {ValueAction} from './action-types';
|
|
3
|
+
|
|
4
|
+
export enum Rounding {
|
|
5
|
+
ROUND_UP = 'up',
|
|
6
|
+
ROUND_DOWN = 'down',
|
|
7
|
+
ROUND_CEIL = 'ceil',
|
|
8
|
+
ROUND_FLOOR = 'floor',
|
|
9
|
+
ROUND_HALF_UP = 'half-up',
|
|
10
|
+
ROUND_HALF_DOWN = 'half-down',
|
|
11
|
+
ROUND_HALF_EVEN = 'half-even',
|
|
12
|
+
ROUND_HALF_CEIL = 'half-ceil',
|
|
13
|
+
ROUND_HALF_FLOOR = 'half-floor'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const ToDecimalJsRounding = {
|
|
17
|
+
[Rounding.ROUND_UP]: Decimal.ROUND_UP,
|
|
18
|
+
[Rounding.ROUND_DOWN]: Decimal.ROUND_DOWN,
|
|
19
|
+
[Rounding.ROUND_CEIL]: Decimal.ROUND_CEIL,
|
|
20
|
+
[Rounding.ROUND_FLOOR]: Decimal.ROUND_FLOOR,
|
|
21
|
+
[Rounding.ROUND_HALF_UP]: Decimal.ROUND_HALF_UP,
|
|
22
|
+
[Rounding.ROUND_HALF_DOWN]: Decimal.ROUND_HALF_DOWN,
|
|
23
|
+
[Rounding.ROUND_HALF_EVEN]: Decimal.ROUND_HALF_EVEN,
|
|
24
|
+
[Rounding.ROUND_HALF_CEIL]: Decimal.ROUND_HALF_CEIL,
|
|
25
|
+
[Rounding.ROUND_HALF_FLOOR]: Decimal.ROUND_HALF_FLOOR
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
+
export const toDecimal: ValueAction<any, Decimal> = (value?: any) => {
|
|
30
|
+
if (value == null) {
|
|
31
|
+
return {test: false, value};
|
|
32
|
+
} else if (value instanceof Decimal) {
|
|
33
|
+
return {test: true, value};
|
|
34
|
+
} else if (['string', 'number'].includes(typeof value)) {
|
|
35
|
+
try {
|
|
36
|
+
return {test: true, value: new Decimal(value)};
|
|
37
|
+
} catch {
|
|
38
|
+
return {test: false, value};
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
return {test: false, value};
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* May cause precision loss or value truncation.
|
|
46
|
+
*/
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
+
export const toNumber: ValueAction<any, number> = (value?: any) => {
|
|
49
|
+
const {test, value: parsed} = toDecimal(value);
|
|
50
|
+
if (!test) {
|
|
51
|
+
return {test: false, value};
|
|
52
|
+
}
|
|
53
|
+
return {test: true, value: parsed.toNumber()};
|
|
54
|
+
};
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
56
|
+
export const toFixed = (fractionDigits: number, rounding: Rounding = Rounding.ROUND_HALF_UP): ValueAction<any, string> => {
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
|
+
return (value?: any) => {
|
|
59
|
+
const {test, value: parsed} = toDecimal(value);
|
|
60
|
+
if (!test) {
|
|
61
|
+
return {test: false, value};
|
|
62
|
+
}
|
|
63
|
+
return {test: true, value: parsed.toFixed(fractionDigits, ToDecimalJsRounding[rounding])};
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
const baseRound = (rounding: Rounding = Rounding.ROUND_HALF_UP) => {
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
return (fractionDigits: number): ValueAction<any, Decimal> => {
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
70
|
+
return (value?: any) => {
|
|
71
|
+
const {test, value: parsed} = toDecimal(value);
|
|
72
|
+
if (!test) {
|
|
73
|
+
return {test: false, value};
|
|
74
|
+
}
|
|
75
|
+
return {test: true, value: parsed.toDecimalPlaces(fractionDigits, ToDecimalJsRounding[rounding])};
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
/** half up */
|
|
80
|
+
export const roundUp = baseRound(Rounding.ROUND_HALF_UP);
|
|
81
|
+
/** half down */
|
|
82
|
+
export const roundDown = baseRound(Rounding.ROUND_HALF_DOWN);
|
|
83
|
+
export const floor = baseRound(Rounding.ROUND_FLOOR);
|
|
84
|
+
export const ceil = baseRound(Rounding.ROUND_CEIL);
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
86
|
+
export const roundBy = (fractionDigits: number, rounding: Rounding = Rounding.ROUND_HALF_UP): ValueAction<any, Decimal> => {
|
|
87
|
+
return baseRound(rounding)(fractionDigits);
|
|
88
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {ValueAction} from './action-types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* always pass, and trim if given value is string
|
|
5
|
+
*/
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
|
+
export const trim: ValueAction = (value?: any) => {
|
|
8
|
+
if (value == null) {
|
|
9
|
+
return {test: true, value};
|
|
10
|
+
} else if (typeof value === 'string') {
|
|
11
|
+
return {test: true, value: value.trim()};
|
|
12
|
+
} else {
|
|
13
|
+
return {test: true, value};
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
export type PadOptions = {
|
|
17
|
+
length: number;
|
|
18
|
+
char?: string;
|
|
19
|
+
direction?: 'left' | 'right';
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* return value must be a string if padding could perform, otherwise return given value itself no matter what it is.
|
|
23
|
+
* could perform means performed, or not performed when length of given value is greater than or equal to given length.
|
|
24
|
+
*/
|
|
25
|
+
export const pad = (options: PadOptions): ValueAction => {
|
|
26
|
+
const {length, char = ' ', direction = 'right'} = options;
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
return (value?: any) => {
|
|
29
|
+
if (value == null) {
|
|
30
|
+
return {test: false, value};
|
|
31
|
+
}
|
|
32
|
+
const type = typeof value;
|
|
33
|
+
if (['string', 'number', 'bigint', 'boolean'].includes(type)) {
|
|
34
|
+
const stringified = `${value}`;
|
|
35
|
+
const len = stringified.length;
|
|
36
|
+
if (len >= length) {
|
|
37
|
+
return {test: true, value: stringified};
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
test: true,
|
|
41
|
+
value: direction === 'left' ? stringified.padStart(length, char) : stringified.padEnd(length, char)
|
|
42
|
+
};
|
|
43
|
+
} else {
|
|
44
|
+
return {test: false, value};
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
export const padStart = (options: Omit<PadOptions, 'direction'>): ValueAction => pad({...options, direction: 'left'});
|
|
49
|
+
export const padEnd = (options: Omit<PadOptions, 'direction'>): ValueAction => pad({...options, direction: 'right'});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {RegisteredValueAction, RegisteredValueActionWithParams} from './action-types';
|
|
2
|
+
import {ceil, floor, roundBy, roundDown, roundUp, toDecimal, toFixed, toNumber} from './transform-decimal-actions';
|
|
3
|
+
import {pad, padEnd, padStart, trim} from './transform-string-actions';
|
|
4
|
+
|
|
5
|
+
const transformers = {
|
|
6
|
+
// string
|
|
7
|
+
trim: {type: 'func', func: trim} as RegisteredValueAction,
|
|
8
|
+
pad: {type: 'param', func: pad} as RegisteredValueActionWithParams<typeof pad>,
|
|
9
|
+
padStart: {type: 'param', func: padStart} as RegisteredValueActionWithParams<typeof padStart>,
|
|
10
|
+
padLeft: {type: 'param', func: padStart} as RegisteredValueActionWithParams<typeof padStart>,
|
|
11
|
+
lpad: {type: 'param', func: padStart} as RegisteredValueActionWithParams<typeof padStart>,
|
|
12
|
+
padEnd: {type: 'param', func: padEnd} as RegisteredValueActionWithParams<typeof padEnd>,
|
|
13
|
+
padRight: {type: 'param', func: padEnd} as RegisteredValueActionWithParams<typeof padEnd>,
|
|
14
|
+
rpad: {type: 'param', func: padEnd} as RegisteredValueActionWithParams<typeof padEnd>,
|
|
15
|
+
// decimal
|
|
16
|
+
toDecimal: {type: 'func', func: toDecimal} as RegisteredValueAction,
|
|
17
|
+
toNumber: {type: 'func', func: toNumber} as RegisteredValueAction,
|
|
18
|
+
toFixed0: {type: 'func', func: toFixed(0)} as RegisteredValueAction,
|
|
19
|
+
toFixed1: {type: 'func', func: toFixed(1)} as RegisteredValueAction,
|
|
20
|
+
toFixed2: {type: 'func', func: toFixed(2)} as RegisteredValueAction,
|
|
21
|
+
toFixed3: {type: 'func', func: toFixed(3)} as RegisteredValueAction,
|
|
22
|
+
toFixed4: {type: 'func', func: toFixed(4)} as RegisteredValueAction,
|
|
23
|
+
toFixed5: {type: 'func', func: toFixed(5)} as RegisteredValueAction,
|
|
24
|
+
toFixed6: {type: 'func', func: toFixed(6)} as RegisteredValueAction,
|
|
25
|
+
// decimal with params
|
|
26
|
+
toFixed: {type: 'param', func: toFixed} as RegisteredValueActionWithParams<typeof toFixed>,
|
|
27
|
+
round: {type: 'param', func: roundUp} as RegisteredValueActionWithParams<typeof roundUp>,
|
|
28
|
+
roundUp: {type: 'param', func: roundUp} as RegisteredValueActionWithParams<typeof roundUp>,
|
|
29
|
+
roundDown: {type: 'param', func: roundDown} as RegisteredValueActionWithParams<typeof roundDown>,
|
|
30
|
+
floor: {type: 'param', func: floor} as RegisteredValueActionWithParams<typeof floor>,
|
|
31
|
+
ceil: {type: 'param', func: ceil} as RegisteredValueActionWithParams<typeof ceil>,
|
|
32
|
+
roundBy: {type: 'param', func: roundBy} as RegisteredValueActionWithParams<typeof roundBy>
|
|
33
|
+
};
|
|
34
|
+
export const AllTransformers: Readonly<typeof transformers> = transformers;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// noinspection ES6PreferShortImport
|
|
2
|
+
|
|
3
|
+
import Decimal from 'decimal.js';
|
|
4
|
+
import * as math from 'mathjs';
|
|
5
|
+
import {ValueOperator as VO} from '../src/lib/pipeline/step-helpers-value-operator';
|
|
6
|
+
|
|
7
|
+
describe('Value test chain', () => {
|
|
8
|
+
test('Test 1', async () => {
|
|
9
|
+
expect(VO.from('abc').isNotBlank().orUseDefault('default').value()).toEqual('abc');
|
|
10
|
+
expect(VO.from('').isNotBlank.withDefault('default').value()).toEqual('default');
|
|
11
|
+
expect(VO.from('123').isNumber().toFixed(2).value()).toEqual('123.00');
|
|
12
|
+
expect(VO.from(void 0).isNumber.useDefault(100).value()).toEqual(100);
|
|
13
|
+
expect(VO.with(123).isInt.toFixed2.value()).toEqual('123.00');
|
|
14
|
+
expect(VO.of('123.45').within({min: 100, max: 200}).toFixed3().orElse(150).value()).toEqual('123.450');
|
|
15
|
+
console.log({
|
|
16
|
+
'math: number, 5.0000000000000001': math.isInteger(5.0000000000000001),
|
|
17
|
+
'math: string, 5.0000000000000001': math.isInteger('5.0000000000000001' as any),
|
|
18
|
+
'decimal: number, 5.0000000000000001': new Decimal(5.0000000000000001).isInteger(),
|
|
19
|
+
'decimal: string, 5.0000000000000001': new Decimal('5.0000000000000001').isInteger(),
|
|
20
|
+
'math: 0.1 + 0.2': math.chain(0.1).add(0.2).done(),
|
|
21
|
+
'math: add("0.1 + 0.2")': math.evaluate('0.1 + 0.2'),
|
|
22
|
+
'decimal: 0.1 + 0.2': new Decimal(0.1).add(0.2).toNumber()
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
VO.of(123).isPositive
|
|
26
|
+
.success((value: number) => console.log('isPositive', value))
|
|
27
|
+
.failure((value: number) => console.log('isNotPositive', value));
|
|
28
|
+
VO.of(-123).isPositive
|
|
29
|
+
.success((value: number) => console.log('isPositive', value))
|
|
30
|
+
.failure((value: number) => console.log('isNotPositive', value));
|
|
31
|
+
expect(VO.of(123).isPositive.ok()).toEqual(true);
|
|
32
|
+
expect(VO.of(-123).isPositive.ok()).toEqual(false);
|
|
33
|
+
try {
|
|
34
|
+
const v = await VO.of(123).isPositive.toNumber.promise();
|
|
35
|
+
expect(v).toEqual(123);
|
|
36
|
+
await VO.of(-123).isPositive.promise();
|
|
37
|
+
} catch (v) {
|
|
38
|
+
expect(v).toEqual(-123);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// console.log(new Decimal({} as any).isInteger());
|
|
42
|
+
interface AskImportConfigRequest {
|
|
43
|
+
type?: string;
|
|
44
|
+
pageSize?: number;
|
|
45
|
+
pageNumber?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const {type, pageSize, pageNumber} = {} as AskImportConfigRequest;
|
|
49
|
+
const criteria: AskImportConfigRequest = {type};
|
|
50
|
+
criteria.pageSize = VO.of(pageSize).isPositive.toFixed0.toNumber.orUseDefault(20).value();
|
|
51
|
+
criteria.pageNumber = VO.of(pageNumber).isPositive.toFixed0.toNumber.orUseDefault(1).value();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
afterAll((done) => done());
|
|
55
|
+
});
|
|
File without changes
|
|
File without changes
|