@fintekkers/ledger-models 0.1.137 → 0.1.138
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/node/wrappers/models/position/measure.d.ts +29 -0
- package/node/wrappers/models/position/measure.js +43 -0
- package/node/wrappers/models/position/measure.js.map +1 -0
- package/node/wrappers/models/position/measure.test.d.ts +1 -0
- package/node/wrappers/models/position/measure.test.js +98 -0
- package/node/wrappers/models/position/measure.test.js.map +1 -0
- package/node/wrappers/models/position/measure.test.ts +105 -0
- package/node/wrappers/models/position/measure.ts +45 -0
- package/package.json +1 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { MeasureProto } from '../../../fintekkers/models/position/measure_pb';
|
|
2
|
+
/**
|
|
3
|
+
* Static helpers around the MeasureProto enum, mirroring the wrapper pattern
|
|
4
|
+
* shipped in v0.1.133–v0.1.135 (PRs #188 Identifier, #189 SecurityType +
|
|
5
|
+
* AssetClass, #190 PositionFilterOperator).
|
|
6
|
+
*
|
|
7
|
+
* Strict: takes / returns proto enum NAMES ("PRESENT_VALUE",
|
|
8
|
+
* "MODIFIED_DURATION", ...). Consumers (including UI URL conventions and
|
|
9
|
+
* dropdown labels) should standardize on proto names — ledger-models is
|
|
10
|
+
* the source-of-truth vocabulary and should not absorb consumer-side
|
|
11
|
+
* naming conventions. See FinTekkers/ui-service#149 for the consumer
|
|
12
|
+
* surface that motivated this wrapper.
|
|
13
|
+
*/
|
|
14
|
+
export declare class Measure {
|
|
15
|
+
/**
|
|
16
|
+
* Returns the names of all known MeasureProto values, EXCLUDING the
|
|
17
|
+
* sentinel `UNKNOWN_MEASURE`. Drives UI dropdowns / pickers so adding
|
|
18
|
+
* a new proto enum variant auto-propagates to consumers.
|
|
19
|
+
*
|
|
20
|
+
* Order matches proto declaration order.
|
|
21
|
+
*/
|
|
22
|
+
static getAllTypeNames(): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a proto enum NAME (e.g., "PRESENT_VALUE", "DIRTY_PRICE") to
|
|
25
|
+
* its numeric MeasureProto value. Throws on unknown name; the error
|
|
26
|
+
* lists the valid names so typos are fixable without grepping the proto.
|
|
27
|
+
*/
|
|
28
|
+
static fromName(name: string): MeasureProto;
|
|
29
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Measure = void 0;
|
|
4
|
+
const measure_pb_1 = require("../../../fintekkers/models/position/measure_pb");
|
|
5
|
+
/**
|
|
6
|
+
* Static helpers around the MeasureProto enum, mirroring the wrapper pattern
|
|
7
|
+
* shipped in v0.1.133–v0.1.135 (PRs #188 Identifier, #189 SecurityType +
|
|
8
|
+
* AssetClass, #190 PositionFilterOperator).
|
|
9
|
+
*
|
|
10
|
+
* Strict: takes / returns proto enum NAMES ("PRESENT_VALUE",
|
|
11
|
+
* "MODIFIED_DURATION", ...). Consumers (including UI URL conventions and
|
|
12
|
+
* dropdown labels) should standardize on proto names — ledger-models is
|
|
13
|
+
* the source-of-truth vocabulary and should not absorb consumer-side
|
|
14
|
+
* naming conventions. See FinTekkers/ui-service#149 for the consumer
|
|
15
|
+
* surface that motivated this wrapper.
|
|
16
|
+
*/
|
|
17
|
+
class Measure {
|
|
18
|
+
/**
|
|
19
|
+
* Returns the names of all known MeasureProto values, EXCLUDING the
|
|
20
|
+
* sentinel `UNKNOWN_MEASURE`. Drives UI dropdowns / pickers so adding
|
|
21
|
+
* a new proto enum variant auto-propagates to consumers.
|
|
22
|
+
*
|
|
23
|
+
* Order matches proto declaration order.
|
|
24
|
+
*/
|
|
25
|
+
static getAllTypeNames() {
|
|
26
|
+
return Object.keys(measure_pb_1.MeasureProto).filter(k => k !== 'UNKNOWN_MEASURE');
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve a proto enum NAME (e.g., "PRESENT_VALUE", "DIRTY_PRICE") to
|
|
30
|
+
* its numeric MeasureProto value. Throws on unknown name; the error
|
|
31
|
+
* lists the valid names so typos are fixable without grepping the proto.
|
|
32
|
+
*/
|
|
33
|
+
static fromName(name) {
|
|
34
|
+
const enumObj = measure_pb_1.MeasureProto;
|
|
35
|
+
const enumValue = enumObj[name];
|
|
36
|
+
if (enumValue === undefined) {
|
|
37
|
+
throw new Error(`Unknown Measure name: '${name}'. Valid names: ${Measure.getAllTypeNames().join(', ')}`);
|
|
38
|
+
}
|
|
39
|
+
return enumValue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.Measure = Measure;
|
|
43
|
+
//# sourceMappingURL=measure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure.js","sourceRoot":"","sources":["measure.ts"],"names":[],"mappings":";;;AAAA,+EAA8E;AAE9E;;;;;;;;;;;GAWG;AACH,MAAa,OAAO;IAEhB;;;;;;OAMG;IACH,MAAM,CAAC,eAAe;QAClB,OAAO,MAAM,CAAC,IAAI,CAAC,yBAAY,CAAC,CAAC,MAAM,CACnC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,iBAAiB,CAC/B,CAAC;IACN,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAY;QACxB,MAAM,OAAO,GAAG,yBAAiD,CAAC;QAClE,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,SAAS,KAAK,SAAS,EAAE;YACzB,MAAM,IAAI,KAAK,CACX,0BAA0B,IAAI,mBAAmB,OAAO,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC1F,CAAC;SACL;QACD,OAAO,SAAyB,CAAC;IACrC,CAAC;CACJ;AA9BD,0BA8BC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const measure_1 = require("./measure");
|
|
4
|
+
const measure_pb_1 = require("../../../fintekkers/models/position/measure_pb");
|
|
5
|
+
describe('Measure.fromName', () => {
|
|
6
|
+
test.each(measure_1.Measure.getAllTypeNames())('fromName("%s") returns the matching numeric enum value', (name) => {
|
|
7
|
+
const value = measure_1.Measure.fromName(name);
|
|
8
|
+
const expected = measure_pb_1.MeasureProto[name];
|
|
9
|
+
expect(value).toBe(expected);
|
|
10
|
+
});
|
|
11
|
+
test('throws on unknown name and lists valid names in the error', () => {
|
|
12
|
+
let err;
|
|
13
|
+
try {
|
|
14
|
+
measure_1.Measure.fromName('NOT_A_REAL_MEASURE');
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
err = e;
|
|
18
|
+
}
|
|
19
|
+
expect(err).toBeDefined();
|
|
20
|
+
expect(err.message).toContain('NOT_A_REAL_MEASURE');
|
|
21
|
+
// Hint with known valid entries.
|
|
22
|
+
expect(err.message).toContain('PRESENT_VALUE');
|
|
23
|
+
expect(err.message).toContain('DIRTY_PRICE');
|
|
24
|
+
});
|
|
25
|
+
test('throws on lowercase / friendly-label input (proto-name strict)', () => {
|
|
26
|
+
// ledger-models is the source-of-truth vocabulary; consumers
|
|
27
|
+
// (UI dropdown labels, URL params) standardize on proto names.
|
|
28
|
+
// Pin the strict behavior so this contract is loudly tested.
|
|
29
|
+
expect(() => measure_1.Measure.fromName('present_value')).toThrow();
|
|
30
|
+
expect(() => measure_1.Measure.fromName('Dirty Price')).toThrow();
|
|
31
|
+
});
|
|
32
|
+
test('accepts UNKNOWN_MEASURE — sentinel is a valid enum key', () => {
|
|
33
|
+
// Excluded from getAllTypeNames (no dropdown surface) but still a
|
|
34
|
+
// valid proto enum value. Mirrors Identifier / SecurityType /
|
|
35
|
+
// AssetClass / PositionFilterOperator behavior.
|
|
36
|
+
expect(measure_1.Measure.fromName('UNKNOWN_MEASURE')).toBe(measure_pb_1.MeasureProto.UNKNOWN_MEASURE);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe('Measure.getAllTypeNames', () => {
|
|
40
|
+
test('returns the expected set in proto-declaration order, excluding UNKNOWN_MEASURE', () => {
|
|
41
|
+
// Proto-declared order in measure.proto (post-PR #192 additions):
|
|
42
|
+
// UNKNOWN_MEASURE = 0; (excluded)
|
|
43
|
+
// DIRECTED_QUANTITY = 1;
|
|
44
|
+
// MARKET_VALUE = 2;
|
|
45
|
+
// UNADJUSTED_COST_BASIS = 3;
|
|
46
|
+
// ADJUSTED_COST_BASIS = 4;
|
|
47
|
+
// CURRENT_YIELD = 5;
|
|
48
|
+
// YIELD_TO_MATURITY = 7; (note: no tag 6)
|
|
49
|
+
// MACAULAY_DURATION = 8;
|
|
50
|
+
// PRESENT_VALUE = 9;
|
|
51
|
+
// REAL_YIELD = 10;
|
|
52
|
+
// INFLATION_ADJUSTED_PRINCIPAL = 11;
|
|
53
|
+
// PRESENT_VALUE_CASHFLOWS = 12;
|
|
54
|
+
// DISCOUNT_MARGIN = 13;
|
|
55
|
+
// SPREAD_DURATION = 14;
|
|
56
|
+
// PAR_YIELD = 15;
|
|
57
|
+
// SPOT_YIELD = 16;
|
|
58
|
+
// FORWARD_YIELD = 17;
|
|
59
|
+
// PROFIT_LOSS = 18;
|
|
60
|
+
// PROFIT_LOSS_PERCENT = 19;
|
|
61
|
+
// ACCRUED_INTEREST = 20;
|
|
62
|
+
// CONVEXITY = 21;
|
|
63
|
+
// DIRTY_PRICE = 22;
|
|
64
|
+
// CLEAN_PRICE = 23;
|
|
65
|
+
// MODIFIED_DURATION = 24;
|
|
66
|
+
// DV01 = 25;
|
|
67
|
+
expect(measure_1.Measure.getAllTypeNames()).toEqual([
|
|
68
|
+
'DIRECTED_QUANTITY',
|
|
69
|
+
'MARKET_VALUE',
|
|
70
|
+
'UNADJUSTED_COST_BASIS',
|
|
71
|
+
'ADJUSTED_COST_BASIS',
|
|
72
|
+
'CURRENT_YIELD',
|
|
73
|
+
'YIELD_TO_MATURITY',
|
|
74
|
+
'MACAULAY_DURATION',
|
|
75
|
+
'PRESENT_VALUE',
|
|
76
|
+
'REAL_YIELD',
|
|
77
|
+
'INFLATION_ADJUSTED_PRINCIPAL',
|
|
78
|
+
'PRESENT_VALUE_CASHFLOWS',
|
|
79
|
+
'DISCOUNT_MARGIN',
|
|
80
|
+
'SPREAD_DURATION',
|
|
81
|
+
'PAR_YIELD',
|
|
82
|
+
'SPOT_YIELD',
|
|
83
|
+
'FORWARD_YIELD',
|
|
84
|
+
'PROFIT_LOSS',
|
|
85
|
+
'PROFIT_LOSS_PERCENT',
|
|
86
|
+
'ACCRUED_INTEREST',
|
|
87
|
+
'CONVEXITY',
|
|
88
|
+
'DIRTY_PRICE',
|
|
89
|
+
'CLEAN_PRICE',
|
|
90
|
+
'MODIFIED_DURATION',
|
|
91
|
+
'DV01',
|
|
92
|
+
]);
|
|
93
|
+
});
|
|
94
|
+
test('excludes the UNKNOWN_MEASURE sentinel', () => {
|
|
95
|
+
expect(measure_1.Measure.getAllTypeNames()).not.toContain('UNKNOWN_MEASURE');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=measure.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure.test.js","sourceRoot":"","sources":["measure.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Measure } from './measure';
|
|
2
|
+
import { MeasureProto } from '../../../fintekkers/models/position/measure_pb';
|
|
3
|
+
|
|
4
|
+
describe('Measure.fromName', () => {
|
|
5
|
+
test.each(Measure.getAllTypeNames())(
|
|
6
|
+
'fromName("%s") returns the matching numeric enum value',
|
|
7
|
+
(name: string) => {
|
|
8
|
+
const value = Measure.fromName(name);
|
|
9
|
+
const expected = (MeasureProto as unknown as Record<string, number>)[name];
|
|
10
|
+
expect(value).toBe(expected);
|
|
11
|
+
}
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
test('throws on unknown name and lists valid names in the error', () => {
|
|
15
|
+
let err: Error | undefined;
|
|
16
|
+
try {
|
|
17
|
+
Measure.fromName('NOT_A_REAL_MEASURE');
|
|
18
|
+
} catch (e) {
|
|
19
|
+
err = e as Error;
|
|
20
|
+
}
|
|
21
|
+
expect(err).toBeDefined();
|
|
22
|
+
expect(err!.message).toContain('NOT_A_REAL_MEASURE');
|
|
23
|
+
// Hint with known valid entries.
|
|
24
|
+
expect(err!.message).toContain('PRESENT_VALUE');
|
|
25
|
+
expect(err!.message).toContain('DIRTY_PRICE');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('throws on lowercase / friendly-label input (proto-name strict)', () => {
|
|
29
|
+
// ledger-models is the source-of-truth vocabulary; consumers
|
|
30
|
+
// (UI dropdown labels, URL params) standardize on proto names.
|
|
31
|
+
// Pin the strict behavior so this contract is loudly tested.
|
|
32
|
+
expect(() => Measure.fromName('present_value')).toThrow();
|
|
33
|
+
expect(() => Measure.fromName('Dirty Price')).toThrow();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('accepts UNKNOWN_MEASURE — sentinel is a valid enum key', () => {
|
|
37
|
+
// Excluded from getAllTypeNames (no dropdown surface) but still a
|
|
38
|
+
// valid proto enum value. Mirrors Identifier / SecurityType /
|
|
39
|
+
// AssetClass / PositionFilterOperator behavior.
|
|
40
|
+
expect(Measure.fromName('UNKNOWN_MEASURE')).toBe(
|
|
41
|
+
MeasureProto.UNKNOWN_MEASURE
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe('Measure.getAllTypeNames', () => {
|
|
47
|
+
test('returns the expected set in proto-declaration order, excluding UNKNOWN_MEASURE', () => {
|
|
48
|
+
// Proto-declared order in measure.proto (post-PR #192 additions):
|
|
49
|
+
// UNKNOWN_MEASURE = 0; (excluded)
|
|
50
|
+
// DIRECTED_QUANTITY = 1;
|
|
51
|
+
// MARKET_VALUE = 2;
|
|
52
|
+
// UNADJUSTED_COST_BASIS = 3;
|
|
53
|
+
// ADJUSTED_COST_BASIS = 4;
|
|
54
|
+
// CURRENT_YIELD = 5;
|
|
55
|
+
// YIELD_TO_MATURITY = 7; (note: no tag 6)
|
|
56
|
+
// MACAULAY_DURATION = 8;
|
|
57
|
+
// PRESENT_VALUE = 9;
|
|
58
|
+
// REAL_YIELD = 10;
|
|
59
|
+
// INFLATION_ADJUSTED_PRINCIPAL = 11;
|
|
60
|
+
// PRESENT_VALUE_CASHFLOWS = 12;
|
|
61
|
+
// DISCOUNT_MARGIN = 13;
|
|
62
|
+
// SPREAD_DURATION = 14;
|
|
63
|
+
// PAR_YIELD = 15;
|
|
64
|
+
// SPOT_YIELD = 16;
|
|
65
|
+
// FORWARD_YIELD = 17;
|
|
66
|
+
// PROFIT_LOSS = 18;
|
|
67
|
+
// PROFIT_LOSS_PERCENT = 19;
|
|
68
|
+
// ACCRUED_INTEREST = 20;
|
|
69
|
+
// CONVEXITY = 21;
|
|
70
|
+
// DIRTY_PRICE = 22;
|
|
71
|
+
// CLEAN_PRICE = 23;
|
|
72
|
+
// MODIFIED_DURATION = 24;
|
|
73
|
+
// DV01 = 25;
|
|
74
|
+
expect(Measure.getAllTypeNames()).toEqual([
|
|
75
|
+
'DIRECTED_QUANTITY',
|
|
76
|
+
'MARKET_VALUE',
|
|
77
|
+
'UNADJUSTED_COST_BASIS',
|
|
78
|
+
'ADJUSTED_COST_BASIS',
|
|
79
|
+
'CURRENT_YIELD',
|
|
80
|
+
'YIELD_TO_MATURITY',
|
|
81
|
+
'MACAULAY_DURATION',
|
|
82
|
+
'PRESENT_VALUE',
|
|
83
|
+
'REAL_YIELD',
|
|
84
|
+
'INFLATION_ADJUSTED_PRINCIPAL',
|
|
85
|
+
'PRESENT_VALUE_CASHFLOWS',
|
|
86
|
+
'DISCOUNT_MARGIN',
|
|
87
|
+
'SPREAD_DURATION',
|
|
88
|
+
'PAR_YIELD',
|
|
89
|
+
'SPOT_YIELD',
|
|
90
|
+
'FORWARD_YIELD',
|
|
91
|
+
'PROFIT_LOSS',
|
|
92
|
+
'PROFIT_LOSS_PERCENT',
|
|
93
|
+
'ACCRUED_INTEREST',
|
|
94
|
+
'CONVEXITY',
|
|
95
|
+
'DIRTY_PRICE',
|
|
96
|
+
'CLEAN_PRICE',
|
|
97
|
+
'MODIFIED_DURATION',
|
|
98
|
+
'DV01',
|
|
99
|
+
]);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('excludes the UNKNOWN_MEASURE sentinel', () => {
|
|
103
|
+
expect(Measure.getAllTypeNames()).not.toContain('UNKNOWN_MEASURE');
|
|
104
|
+
});
|
|
105
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { MeasureProto } from '../../../fintekkers/models/position/measure_pb';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Static helpers around the MeasureProto enum, mirroring the wrapper pattern
|
|
5
|
+
* shipped in v0.1.133–v0.1.135 (PRs #188 Identifier, #189 SecurityType +
|
|
6
|
+
* AssetClass, #190 PositionFilterOperator).
|
|
7
|
+
*
|
|
8
|
+
* Strict: takes / returns proto enum NAMES ("PRESENT_VALUE",
|
|
9
|
+
* "MODIFIED_DURATION", ...). Consumers (including UI URL conventions and
|
|
10
|
+
* dropdown labels) should standardize on proto names — ledger-models is
|
|
11
|
+
* the source-of-truth vocabulary and should not absorb consumer-side
|
|
12
|
+
* naming conventions. See FinTekkers/ui-service#149 for the consumer
|
|
13
|
+
* surface that motivated this wrapper.
|
|
14
|
+
*/
|
|
15
|
+
export class Measure {
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Returns the names of all known MeasureProto values, EXCLUDING the
|
|
19
|
+
* sentinel `UNKNOWN_MEASURE`. Drives UI dropdowns / pickers so adding
|
|
20
|
+
* a new proto enum variant auto-propagates to consumers.
|
|
21
|
+
*
|
|
22
|
+
* Order matches proto declaration order.
|
|
23
|
+
*/
|
|
24
|
+
static getAllTypeNames(): string[] {
|
|
25
|
+
return Object.keys(MeasureProto).filter(
|
|
26
|
+
k => k !== 'UNKNOWN_MEASURE'
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a proto enum NAME (e.g., "PRESENT_VALUE", "DIRTY_PRICE") to
|
|
32
|
+
* its numeric MeasureProto value. Throws on unknown name; the error
|
|
33
|
+
* lists the valid names so typos are fixable without grepping the proto.
|
|
34
|
+
*/
|
|
35
|
+
static fromName(name: string): MeasureProto {
|
|
36
|
+
const enumObj = MeasureProto as unknown as Record<string, number>;
|
|
37
|
+
const enumValue = enumObj[name];
|
|
38
|
+
if (enumValue === undefined) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Unknown Measure name: '${name}'. Valid names: ${Measure.getAllTypeNames().join(', ')}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return enumValue as MeasureProto;
|
|
44
|
+
}
|
|
45
|
+
}
|