@fintekkers/ledger-models 0.1.119 → 0.1.128
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/.npmrc.example +4 -0
- package/catalog/fields.json +275 -0
- package/catalog/measures.json +259 -0
- package/node/fintekkers/models/portfolio/portfolio_pb.js +13 -19
- package/node/fintekkers/models/position/field_pb.js +1 -7
- package/node/fintekkers/models/position/measure_pb.d.ts +18 -0
- package/node/fintekkers/models/position/measure_pb.js +20 -8
- package/node/fintekkers/models/position/position_filter_pb.js +7 -13
- package/node/fintekkers/models/position/position_pb.d.ts +7 -0
- package/node/fintekkers/models/position/position_pb.js +64 -17
- package/node/fintekkers/models/position/position_status_pb.js +1 -7
- package/node/fintekkers/models/position/position_util_pb.js +11 -17
- package/node/fintekkers/models/price/price_pb.d.ts +4 -0
- package/node/fintekkers/models/price/price_pb.js +45 -19
- package/node/fintekkers/models/price/price_type_grpc_pb.js +1 -0
- package/node/fintekkers/models/price/price_type_pb.d.ts +15 -0
- package/node/fintekkers/models/price/price_type_pb.js +30 -0
- package/node/fintekkers/models/security/bond/auction_type_pb.js +1 -7
- package/node/fintekkers/models/security/bond/issuance_pb.js +17 -23
- package/node/fintekkers/models/security/coupon_frequency_pb.js +1 -7
- package/node/fintekkers/models/security/coupon_type_pb.js +1 -7
- package/node/fintekkers/models/security/identifier/identifier_pb.js +9 -15
- package/node/fintekkers/models/security/identifier/identifier_type_pb.d.ts +1 -0
- package/node/fintekkers/models/security/identifier/identifier_type_pb.js +2 -7
- package/node/fintekkers/models/security/index/index_type_grpc_pb.js +1 -0
- package/node/fintekkers/models/security/index/index_type_pb.d.ts +22 -0
- package/node/fintekkers/models/security/index/index_type_pb.js +37 -0
- package/node/fintekkers/models/security/index_composition_pb.d.ts +126 -0
- package/node/fintekkers/models/security/index_composition_pb.js +992 -0
- package/node/fintekkers/models/security/security_pb.d.ts +382 -0
- package/node/fintekkers/models/security/security_pb.js +3183 -57
- package/node/fintekkers/models/security/security_quantity_type_pb.js +1 -7
- package/node/fintekkers/models/security/security_type_pb.d.ts +3 -0
- package/node/fintekkers/models/security/security_type_pb.js +5 -8
- package/node/fintekkers/models/security/tenor_pb.js +9 -15
- package/node/fintekkers/models/security/tenor_type_pb.js +1 -7
- package/node/fintekkers/models/strategy/strategy_allocation_pb.js +13 -19
- package/node/fintekkers/models/strategy/strategy_pb.js +14 -20
- package/node/fintekkers/models/transaction/transaction_pb.js +24 -30
- package/node/fintekkers/models/transaction/transaction_type_pb.js +1 -7
- package/node/fintekkers/models/util/api/api_key_pb.js +10 -16
- package/node/fintekkers/models/util/currency_pb.d.ts +27 -0
- package/node/fintekkers/models/util/currency_pb.js +170 -0
- package/node/fintekkers/models/util/date_range_pb.js +8 -14
- package/node/fintekkers/models/util/decimal_value_pb.js +4 -10
- package/node/fintekkers/models/util/endpoint_pb.js +7 -13
- package/node/fintekkers/models/util/local_date_pb.js +5 -11
- package/node/fintekkers/models/util/local_timestamp_pb.js +5 -11
- package/node/fintekkers/models/util/lock/node_partition_pb.js +9 -15
- package/node/fintekkers/models/util/lock/node_state_pb.js +10 -16
- package/node/fintekkers/models/util/uuid_pb.js +3 -9
- package/node/fintekkers/models/valuation/cashflow_pb.d.ts +57 -0
- package/node/fintekkers/models/valuation/cashflow_pb.js +401 -0
- package/node/fintekkers/requests/index_composition/create_index_composition_request_pb.d.ts +79 -0
- package/node/fintekkers/requests/index_composition/create_index_composition_request_pb.js +599 -0
- package/node/fintekkers/requests/index_composition/get_index_composition_request_pb.d.ts +84 -0
- package/node/fintekkers/requests/index_composition/get_index_composition_request_pb.js +624 -0
- package/node/fintekkers/requests/portfolio/create_portfolio_request_pb.js +7 -13
- package/node/fintekkers/requests/portfolio/create_portfolio_response_pb.js +8 -14
- package/node/fintekkers/requests/portfolio/query_portfolio_request_pb.d.ts +3 -0
- package/node/fintekkers/requests/portfolio/query_portfolio_request_pb.js +39 -15
- package/node/fintekkers/requests/portfolio/query_portfolio_response_pb.js +8 -14
- package/node/fintekkers/requests/position/query_position_request_pb.js +15 -27
- package/node/fintekkers/requests/position/query_position_response_pb.js +10 -16
- package/node/fintekkers/requests/price/create_price_request_pb.js +7 -13
- package/node/fintekkers/requests/price/create_price_response_pb.js +8 -14
- package/node/fintekkers/requests/price/query_price_request_pb.js +12 -18
- package/node/fintekkers/requests/price/query_price_response_pb.js +8 -14
- package/node/fintekkers/requests/security/create_security_request_pb.js +7 -13
- package/node/fintekkers/requests/security/create_security_response_pb.js +9 -15
- package/node/fintekkers/requests/security/get_field_values_request_pb.js +7 -13
- package/node/fintekkers/requests/security/get_field_values_response_pb.js +7 -13
- package/node/fintekkers/requests/security/get_fields_response_pb.js +8 -17
- package/node/fintekkers/requests/security/query_security_request_pb.d.ts +3 -0
- package/node/fintekkers/requests/security/query_security_request_pb.js +39 -15
- package/node/fintekkers/requests/security/query_security_response_pb.js +9 -15
- package/node/fintekkers/requests/transaction/create_transaction_request_pb.js +7 -13
- package/node/fintekkers/requests/transaction/create_transaction_response_pb.js +8 -14
- package/node/fintekkers/requests/transaction/query_transaction_request_pb.js +10 -16
- package/node/fintekkers/requests/transaction/query_transaction_response_pb.js +9 -15
- package/node/fintekkers/requests/util/delete_request_pb.d.ts +135 -0
- package/node/fintekkers/requests/util/delete_request_pb.js +1051 -0
- package/node/fintekkers/requests/util/errors/error_pb.js +7 -13
- package/node/fintekkers/requests/util/errors/message_pb.js +6 -12
- package/node/fintekkers/requests/util/errors/summary_pb.js +4 -10
- package/node/fintekkers/requests/util/lock/lock_request_pb.js +8 -14
- package/node/fintekkers/requests/util/lock/lock_response_pb.js +9 -15
- package/node/fintekkers/requests/util/operation_pb.js +1 -7
- package/node/fintekkers/requests/valuation/curve_request_pb.d.ts +85 -0
- package/node/fintekkers/requests/valuation/curve_request_pb.js +646 -0
- package/node/fintekkers/requests/valuation/curve_response_pb.d.ts +105 -0
- package/node/fintekkers/requests/valuation/curve_response_pb.js +806 -0
- package/node/fintekkers/requests/valuation/product_inputs.test.ts +172 -0
- package/node/fintekkers/requests/valuation/product_inputs_pb.d.ts +137 -0
- package/node/fintekkers/requests/valuation/product_inputs_pb.js +987 -0
- package/node/fintekkers/requests/valuation/valuation_request_pb.d.ts +19 -0
- package/node/fintekkers/requests/valuation/valuation_request_pb.js +168 -22
- package/node/fintekkers/requests/valuation/valuation_response_pb.d.ts +13 -0
- package/node/fintekkers/requests/valuation/valuation_response_pb.js +118 -16
- package/node/fintekkers/services/index-composition-service/index_composition_service_grpc_pb.d.ts +60 -0
- package/node/fintekkers/services/index-composition-service/index_composition_service_grpc_pb.js +87 -0
- package/node/fintekkers/services/index-composition-service/index_composition_service_pb.d.ts +9 -0
- package/node/fintekkers/services/index-composition-service/index_composition_service_pb.js +21 -0
- package/node/fintekkers/services/lock-service/lock_service_grpc_pb.js +22 -22
- package/node/fintekkers/services/lock-service/lock_service_pb.js +15 -21
- package/node/fintekkers/services/portfolio-service/portfolio_service_grpc_pb.d.ts +18 -0
- package/node/fintekkers/services/portfolio-service/portfolio_service_grpc_pb.js +39 -5
- package/node/fintekkers/services/portfolio-service/portfolio_service_pb.d.ts +1 -0
- package/node/fintekkers/services/portfolio-service/portfolio_service_pb.js +3 -7
- package/node/fintekkers/services/position-service/position_service_grpc_pb.d.ts +37 -0
- package/node/fintekkers/services/position-service/position_service_grpc_pb.js +64 -6
- package/node/fintekkers/services/position-service/position_service_pb.d.ts +3 -0
- package/node/fintekkers/services/position-service/position_service_pb.js +7 -7
- package/node/fintekkers/services/price-service/price_service_grpc_pb.js +5 -5
- package/node/fintekkers/services/price-service/price_service_pb.js +1 -7
- package/node/fintekkers/services/security-service/security_service_grpc_pb.d.ts +18 -0
- package/node/fintekkers/services/security-service/security_service_grpc_pb.js +43 -9
- package/node/fintekkers/services/security-service/security_service_pb.d.ts +1 -0
- package/node/fintekkers/services/security-service/security_service_pb.js +3 -7
- package/node/fintekkers/services/transaction-service/transaction_service_grpc_pb.d.ts +55 -0
- package/node/fintekkers/services/transaction-service/transaction_service_grpc_pb.js +97 -5
- package/node/fintekkers/services/transaction-service/transaction_service_pb.d.ts +4 -0
- package/node/fintekkers/services/transaction-service/transaction_service_pb.js +9 -7
- package/node/fintekkers/services/valuation-service/valuation_service_grpc_pb.d.ts +19 -0
- package/node/fintekkers/services/valuation-service/valuation_service_grpc_pb.js +37 -2
- package/node/fintekkers/services/valuation-service/valuation_service_pb.d.ts +2 -0
- package/node/fintekkers/services/valuation-service/valuation_service_pb.js +5 -7
- package/node/wrappers/models/portfolio/portfolio.js.map +1 -1
- package/node/wrappers/models/portfolio/portfolio.test.d.ts +2 -0
- package/node/wrappers/models/portfolio/portfolio.test.js +29 -0
- package/node/wrappers/models/portfolio/portfolio.test.js.map +1 -0
- package/node/wrappers/models/portfolio/portfolio.test.ts +28 -0
- package/node/wrappers/models/position/position.js +25 -13
- package/node/wrappers/models/position/position.js.map +1 -1
- package/node/wrappers/models/position/position.test.js +20 -0
- package/node/wrappers/models/position/position.test.js.map +1 -1
- package/node/wrappers/models/position/position.test.ts +23 -0
- package/node/wrappers/models/position/position.ts +27 -13
- package/node/wrappers/models/position/positionfilter.js +1 -1
- package/node/wrappers/models/position/positionfilter.js.map +1 -1
- package/node/wrappers/models/position/positionfilter.test.js.map +1 -1
- package/node/wrappers/models/price/Price.cash.test.d.ts +1 -0
- package/node/wrappers/models/price/Price.cash.test.js +42 -0
- package/node/wrappers/models/price/Price.cash.test.js.map +1 -0
- package/node/wrappers/models/price/Price.cash.test.ts +43 -0
- package/node/wrappers/models/price/Price.d.ts +38 -0
- package/node/wrappers/models/price/Price.js +111 -0
- package/node/wrappers/models/price/Price.js.map +1 -0
- package/node/wrappers/models/price/Price.test.d.ts +1 -0
- package/node/wrappers/models/price/Price.test.js +55 -0
- package/node/wrappers/models/price/Price.test.js.map +1 -0
- package/node/wrappers/models/price/Price.test.ts +63 -0
- package/node/wrappers/models/price/Price.ts +123 -0
- package/node/wrappers/models/security/BondSecurity.d.ts +17 -2
- package/node/wrappers/models/security/BondSecurity.js +59 -11
- package/node/wrappers/models/security/BondSecurity.js.map +1 -1
- package/node/wrappers/models/security/BondSecurity.priceScale.test.d.ts +1 -0
- package/node/wrappers/models/security/BondSecurity.priceScale.test.js +36 -0
- package/node/wrappers/models/security/BondSecurity.priceScale.test.js.map +1 -0
- package/node/wrappers/models/security/BondSecurity.priceScale.test.ts +36 -0
- package/node/wrappers/models/security/BondSecurity.test.js +34 -1
- package/node/wrappers/models/security/BondSecurity.test.js.map +1 -1
- package/node/wrappers/models/security/BondSecurity.test.ts +42 -1
- package/node/wrappers/models/security/BondSecurity.ts +63 -11
- package/node/wrappers/models/security/security-roundtrip.test.d.ts +1 -0
- package/node/wrappers/models/security/security-roundtrip.test.js +173 -0
- package/node/wrappers/models/security/security-roundtrip.test.js.map +1 -0
- package/node/wrappers/models/security/security-roundtrip.test.ts +192 -0
- package/node/wrappers/models/security/security.d.ts +8 -0
- package/node/wrappers/models/security/security.js +24 -2
- package/node/wrappers/models/security/security.js.map +1 -1
- package/node/wrappers/models/security/security.ts +26 -2
- package/node/wrappers/models/security/term.js +31 -6
- package/node/wrappers/models/security/term.js.map +1 -1
- package/node/wrappers/models/security/term.test.js +21 -2
- package/node/wrappers/models/security/term.test.js.map +1 -1
- package/node/wrappers/models/security/term.test.ts +28 -2
- package/node/wrappers/models/security/term.ts +34 -6
- package/node/wrappers/models/transaction/transaction.d.ts +59 -1
- package/node/wrappers/models/transaction/transaction.derived.test.d.ts +1 -0
- package/node/wrappers/models/transaction/transaction.derived.test.js +199 -0
- package/node/wrappers/models/transaction/transaction.derived.test.js.map +1 -0
- package/node/wrappers/models/transaction/transaction.derived.test.ts +251 -0
- package/node/wrappers/models/transaction/transaction.js +350 -2
- package/node/wrappers/models/transaction/transaction.js.map +1 -1
- package/node/wrappers/models/transaction/transaction.ts +416 -2
- package/node/wrappers/models/transaction/transaction_constructor.test.d.ts +1 -0
- package/node/wrappers/models/transaction/transaction_constructor.test.js +100 -0
- package/node/wrappers/models/transaction/transaction_constructor.test.js.map +1 -0
- package/node/wrappers/models/transaction/transaction_constructor.test.ts +111 -0
- package/node/wrappers/models/transaction/transaction_type.js.map +1 -1
- package/node/wrappers/models/utils/datetime.d.ts +6 -0
- package/node/wrappers/models/utils/datetime.js +14 -6
- package/node/wrappers/models/utils/datetime.js.map +1 -1
- package/node/wrappers/models/utils/datetime.ts +15 -6
- package/node/wrappers/models/utils/protoEnum.js.map +1 -1
- package/node/wrappers/models/utils/requestcontext.d.ts +17 -3
- package/node/wrappers/models/utils/requestcontext.js +39 -7
- package/node/wrappers/models/utils/requestcontext.js.map +1 -1
- package/node/wrappers/models/utils/requestcontext.test.d.ts +1 -0
- package/node/wrappers/models/utils/requestcontext.test.js +108 -0
- package/node/wrappers/models/utils/requestcontext.test.js.map +1 -0
- package/node/wrappers/models/utils/requestcontext.test.ts +85 -0
- package/node/wrappers/models/utils/requestcontext.ts +49 -9
- package/node/wrappers/models/utils/serialization.d.ts +2 -1
- package/node/wrappers/models/utils/serialization.js +4 -0
- package/node/wrappers/models/utils/serialization.js.map +1 -1
- package/node/wrappers/models/utils/serialization.test.js +15 -0
- package/node/wrappers/models/utils/serialization.test.js.map +1 -1
- package/node/wrappers/models/utils/serialization.test.ts +19 -1
- package/node/wrappers/models/utils/serialization.ts +5 -4
- package/node/wrappers/models/utils/serialization.util.js.map +1 -1
- package/node/wrappers/models/utils/uuid.js +9 -1
- package/node/wrappers/models/utils/uuid.js.map +1 -1
- package/node/wrappers/models/utils/uuid.test.js +22 -4
- package/node/wrappers/models/utils/uuid.test.js.map +1 -1
- package/node/wrappers/models/utils/uuid.test.ts +26 -5
- package/node/wrappers/models/utils/uuid.ts +7 -1
- package/node/wrappers/services/apikey.test.d.ts +7 -0
- package/node/wrappers/services/apikey.test.js +56 -0
- package/node/wrappers/services/apikey.test.js.map +1 -0
- package/node/wrappers/services/apikey.test.ts +65 -0
- package/node/wrappers/services/portfolio-service/PortfolioService.d.ts +1 -1
- package/node/wrappers/services/portfolio-service/PortfolioService.js +8 -2
- package/node/wrappers/services/portfolio-service/PortfolioService.js.map +1 -1
- package/node/wrappers/services/portfolio-service/PortfolioService.ts +7 -2
- package/node/wrappers/services/position-service/PositionService.d.ts +1 -1
- package/node/wrappers/services/position-service/PositionService.js +8 -2
- package/node/wrappers/services/position-service/PositionService.js.map +1 -1
- package/node/wrappers/services/position-service/PositionService.ts +7 -2
- package/node/wrappers/services/position-service/position.test.js.map +1 -1
- package/node/wrappers/services/price-service/PriceService.d.ts +29 -0
- package/node/wrappers/services/price-service/PriceService.js +151 -0
- package/node/wrappers/services/price-service/PriceService.js.map +1 -0
- package/node/wrappers/services/price-service/PriceService.ts +127 -0
- package/node/wrappers/services/price-service/price-wrapper.test.d.ts +1 -0
- package/node/wrappers/services/price-service/price-wrapper.test.js +132 -0
- package/node/wrappers/services/price-service/price-wrapper.test.js.map +1 -0
- package/node/wrappers/services/price-service/price-wrapper.test.ts +120 -0
- package/node/wrappers/services/price-service/price.test.d.ts +1 -0
- package/node/wrappers/services/price-service/price.test.js +198 -0
- package/node/wrappers/services/price-service/price.test.js.map +1 -0
- package/node/wrappers/services/price-service/price.test.ts +205 -0
- package/node/wrappers/services/security-service/SecurityService.d.ts +1 -1
- package/node/wrappers/services/security-service/SecurityService.js +8 -2
- package/node/wrappers/services/security-service/SecurityService.js.map +1 -1
- package/node/wrappers/services/security-service/SecurityService.searchByUuid.test.d.ts +1 -0
- package/node/wrappers/services/security-service/SecurityService.searchByUuid.test.js +38 -0
- package/node/wrappers/services/security-service/SecurityService.searchByUuid.test.js.map +1 -0
- package/node/wrappers/services/security-service/SecurityService.searchByUuid.test.ts +32 -0
- package/node/wrappers/services/security-service/SecurityService.ts +7 -2
- package/node/wrappers/services/security-service/security.maturityLadder.test.js.map +1 -1
- package/node/wrappers/services/transaction-service/TransactionService.d.ts +1 -1
- package/node/wrappers/services/transaction-service/TransactionService.js +8 -2
- package/node/wrappers/services/transaction-service/TransactionService.js.map +1 -1
- package/node/wrappers/services/transaction-service/TransactionService.ts +7 -2
- package/node/wrappers/services/transaction-service/transaction.search.test.js.map +1 -1
- package/node/wrappers/services/transaction-service/transaction.test.js.map +1 -1
- package/package.json +3 -2
- package/.env +0 -3
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import assert = require('assert');
|
|
2
|
+
import Transaction from './transaction';
|
|
3
|
+
import { TransactionType } from './transaction_type';
|
|
4
|
+
import { TransactionTypeProto } from '../../../fintekkers/models/transaction/transaction_type_pb';
|
|
5
|
+
import { PositionStatusProto } from '../../../fintekkers/models/position/position_status_pb';
|
|
6
|
+
import Security from '../security/security';
|
|
7
|
+
import Portfolio from '../portfolio/portfolio';
|
|
8
|
+
import { SecurityProto } from '../../../fintekkers/models/security/security_pb';
|
|
9
|
+
import { LocalDateProto } from '../../../fintekkers/models/util/local_date_pb';
|
|
10
|
+
import { DecimalValueProto } from '../../../fintekkers/models/util/decimal_value_pb';
|
|
11
|
+
import { SecurityQuantityTypeProto } from '../../../fintekkers/models/security/security_quantity_type_pb';
|
|
12
|
+
import { CouponFrequencyProto } from '../../../fintekkers/models/security/coupon_frequency_pb';
|
|
13
|
+
import { CouponTypeProto } from '../../../fintekkers/models/security/coupon_type_pb';
|
|
14
|
+
import { UUID } from '../utils/uuid';
|
|
15
|
+
import { ZonedDateTime } from '../utils/datetime';
|
|
16
|
+
import { Decimal } from 'decimal.js';
|
|
17
|
+
import { dummyPortfolio } from '../portfolio/portfolio.test';
|
|
18
|
+
|
|
19
|
+
test('test Transaction constructor with parameters', () => {
|
|
20
|
+
testTransactionConstructor();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
function testTransactionConstructor(): void {
|
|
24
|
+
// Create test data
|
|
25
|
+
const tradeDate = new Date(2024, 0, 15);
|
|
26
|
+
const settlementDate = new Date(2024, 0, 17);
|
|
27
|
+
const asOfDate = new Date(2024, 0, 15, 10, 30, 0);
|
|
28
|
+
const price = new Decimal('100.50');
|
|
29
|
+
const quantity = new Decimal('1000.00');
|
|
30
|
+
const security = dummySecurity();
|
|
31
|
+
const portfolio = dummyPortfolio();
|
|
32
|
+
const transactionType = dummyTransactionType();
|
|
33
|
+
|
|
34
|
+
// Create Transaction using parameter-based constructor
|
|
35
|
+
const transaction = new Transaction({
|
|
36
|
+
tradeDate,
|
|
37
|
+
settlementDate,
|
|
38
|
+
asOfDate,
|
|
39
|
+
price,
|
|
40
|
+
security,
|
|
41
|
+
transactionType,
|
|
42
|
+
portfolio,
|
|
43
|
+
quantity
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Verify all getters return expected values
|
|
47
|
+
|
|
48
|
+
// getTradeDate() - should match input tradeDate
|
|
49
|
+
const tradeDateFromTransaction = transaction.getTradeDate().toDate();
|
|
50
|
+
assert(tradeDateFromTransaction.getFullYear() === tradeDate.getFullYear());
|
|
51
|
+
assert(tradeDateFromTransaction.getMonth() === tradeDate.getMonth());
|
|
52
|
+
assert(tradeDateFromTransaction.getDate() === tradeDate.getDate());
|
|
53
|
+
|
|
54
|
+
// getSettlementDate() - should match input settlementDate
|
|
55
|
+
const settlementDateFromTransaction = transaction.getSettlementDate().toDate();
|
|
56
|
+
assert(settlementDateFromTransaction.getFullYear() === settlementDate.getFullYear());
|
|
57
|
+
assert(settlementDateFromTransaction.getMonth() === settlementDate.getMonth());
|
|
58
|
+
assert(settlementDateFromTransaction.getDate() === settlementDate.getDate());
|
|
59
|
+
|
|
60
|
+
// getAsOf() - should match input asOfDate (converted to ZonedDateTime)
|
|
61
|
+
const asOfFromTransaction = transaction.getAsOf();
|
|
62
|
+
const asOfDateTime = asOfFromTransaction.toDateTime().toJSDate();
|
|
63
|
+
// Allow 1 second tolerance for timezone conversion
|
|
64
|
+
const timeDiff = Math.abs(asOfDateTime.getTime() - asOfDate.getTime());
|
|
65
|
+
assert(timeDiff < 1000, `AsOf time difference ${timeDiff}ms exceeds 1 second tolerance`);
|
|
66
|
+
|
|
67
|
+
// getPrice() - should return PriceProto with correct price value
|
|
68
|
+
const priceProto = transaction.getPrice();
|
|
69
|
+
const priceValue = priceProto.getPrice()?.getArbitraryPrecisionValue();
|
|
70
|
+
assert(priceValue === '100.5', `Expected price '100.5', got '${priceValue}'`);
|
|
71
|
+
|
|
72
|
+
// getSecurity() - should return Security matching input security
|
|
73
|
+
assert(transaction.getSecurity().getID().toString() === security.getID().toString(), 'Security IDs should match');
|
|
74
|
+
|
|
75
|
+
// getTransactionType() - should return TransactionType matching input transactionType
|
|
76
|
+
assert(transaction.getTransactionType().toString() === 'BUY', `Expected 'BUY', got '${transaction.getTransactionType().toString()}'`);
|
|
77
|
+
assert(transaction.getTransactionType().proto === TransactionTypeProto.BUY, 'TransactionType proto should be BUY');
|
|
78
|
+
|
|
79
|
+
// getPortfolio() - should return Portfolio matching input portfolio
|
|
80
|
+
assert(transaction.getPortfolio().getPortfolioName() === 'Test Portfolio', `Expected 'Test Portfolio', got '${transaction.getPortfolio().getPortfolioName()}'`);
|
|
81
|
+
assert(transaction.getPortfolio().getID().toString() === portfolio.getID().toString(), 'Portfolio IDs should match');
|
|
82
|
+
|
|
83
|
+
// getQuantity() - should return Decimal matching input quantity
|
|
84
|
+
assert(transaction.getQuantity().toString() === '1000', `Expected quantity '1000', got '${transaction.getQuantity().toString()}'`);
|
|
85
|
+
assert(transaction.getQuantity().equals(quantity), 'Quantities should be equal');
|
|
86
|
+
|
|
87
|
+
// getPositionStatus() - should return EXECUTED (default)
|
|
88
|
+
assert(transaction.getPositionStatus() === PositionStatusProto.EXECUTED, `Expected EXECUTED, got ${transaction.getPositionStatus()}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function dummySecurity(): Security {
|
|
92
|
+
return Security.create(new SecurityProto()
|
|
93
|
+
.setObjectClass('Security')
|
|
94
|
+
.setVersion('0.0.1')
|
|
95
|
+
.setUuid(UUID.random().toUUIDProto())
|
|
96
|
+
.setFaceValue(new DecimalValueProto().setArbitraryPrecisionValue('1000.00'))
|
|
97
|
+
.setQuantityType(SecurityQuantityTypeProto.ORIGINAL_FACE_VALUE)
|
|
98
|
+
.setAssetClass("Bond")
|
|
99
|
+
.setIssuerName("Test Issuer")
|
|
100
|
+
.setCouponRate(new DecimalValueProto().setArbitraryPrecisionValue('0.05'))
|
|
101
|
+
.setCouponFrequency(CouponFrequencyProto.SEMIANNUALLY)
|
|
102
|
+
.setCouponType(CouponTypeProto.FIXED)
|
|
103
|
+
.setMaturityDate(new LocalDateProto().setYear(2026).setMonth(1).setDay(1))
|
|
104
|
+
.setIssueDate(new LocalDateProto().setYear(2021).setMonth(1).setDay(1))
|
|
105
|
+
.setDescription("Test security")
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function dummyTransactionType(): TransactionType {
|
|
110
|
+
return new TransactionType(TransactionTypeProto.BUY);
|
|
111
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction_type.js","sourceRoot":"","sources":["transaction_type.ts"],"names":[],"mappings":";;;AAAA,oGAAkG;AAElG,MAAa,eAAe;IAGxB,YAAY,KAA2B;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAYD,sBAAsB;QAClB,QAAQ,IAAI,CAAC,KAAK,EAAE
|
|
1
|
+
{"version":3,"file":"transaction_type.js","sourceRoot":"","sources":["transaction_type.ts"],"names":[],"mappings":";;;AAAA,oGAAkG;AAElG,MAAa,eAAe;IAGxB,YAAY,KAA2B;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAYD,sBAAsB;QAClB,QAAQ,IAAI,CAAC,KAAK,EAAE;YAChB,KAAK,0CAAoB,CAAC,GAAG,CAAC;YAC9B,KAAK,0CAAoB,CAAC,OAAO,CAAC;YAClC,KAAK,0CAAoB,CAAC,iBAAiB;gBACvC,OAAO,CAAC,CAAC;YACb,KAAK,0CAAoB,CAAC,IAAI,CAAC;YAC/B,KAAK,0CAAoB,CAAC,UAAU,CAAC;YACrC,KAAK,0CAAoB,CAAC,UAAU;gBAChC,OAAO,CAAC,CAAC,CAAC;YACd,KAAK,0CAAoB,CAAC,OAAO;gBAC7B,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;SACvE;IACL,CAAC;IAED;;;;;;;;OAQG;IACH,QAAQ;;QACJ,OAAO,MAAA,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,mCAAI,SAAS,CAAC;IAClE,CAAC;CACJ;AA5CD,0CA4CC;AAnCG;IACI,eAAe,CAAC,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEtD,MAAM,CAAC,IAAI,CAAC,0CAAoB,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QAC5C,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,0CAAoB,CAAC,GAAwC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvG,CAAC,CAAC,CAAC;AACP,CAAC,GAAA,CAAA"}
|
|
@@ -9,6 +9,12 @@ declare class ZonedDateTime {
|
|
|
9
9
|
toDateTime(): DateTime;
|
|
10
10
|
toString(): string;
|
|
11
11
|
toProto(): LocalTimestampProto;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a ZonedDateTime from a JavaScript Date object
|
|
14
|
+
* @param date - The Date object to convert
|
|
15
|
+
* @returns A new ZonedDateTime instance with America/New_York timezone
|
|
16
|
+
*/
|
|
17
|
+
static from(date: Date): ZonedDateTime;
|
|
12
18
|
static now(): ZonedDateTime;
|
|
13
19
|
}
|
|
14
20
|
export { ZonedDateTime };
|
|
@@ -42,13 +42,18 @@ class ZonedDateTime {
|
|
|
42
42
|
toProto() {
|
|
43
43
|
return this.proto;
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Creates a ZonedDateTime from a JavaScript Date object
|
|
47
|
+
* @param date - The Date object to convert
|
|
48
|
+
* @returns A new ZonedDateTime instance with America/New_York timezone
|
|
49
|
+
*/
|
|
50
|
+
static from(date) {
|
|
51
|
+
// Get the time in milliseconds since January 1, 1970 (Unix timestamp)
|
|
52
|
+
const timestampMillis = date.getTime();
|
|
48
53
|
// Convert milliseconds to seconds and nanoseconds
|
|
49
|
-
const seconds = Math.floor(
|
|
50
|
-
const nanos = (
|
|
51
|
-
// Create a new Timestamp object
|
|
54
|
+
const seconds = Math.floor(timestampMillis / 1000);
|
|
55
|
+
const nanos = (timestampMillis % 1000) * 1e6; // 1 millisecond = 1e6 nanoseconds
|
|
56
|
+
// Create a new Timestamp object
|
|
52
57
|
const timestamp = new timestamp_pb_1.Timestamp();
|
|
53
58
|
timestamp.setSeconds(seconds);
|
|
54
59
|
timestamp.setNanos(nanos);
|
|
@@ -57,6 +62,9 @@ class ZonedDateTime {
|
|
|
57
62
|
localTimestamp.setTimestamp(timestamp);
|
|
58
63
|
return new ZonedDateTime(localTimestamp);
|
|
59
64
|
}
|
|
65
|
+
static now() {
|
|
66
|
+
return ZonedDateTime.from(new Date());
|
|
67
|
+
}
|
|
60
68
|
}
|
|
61
69
|
exports.ZonedDateTime = ZonedDateTime;
|
|
62
70
|
//# sourceMappingURL=datetime.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datetime.js","sourceRoot":"","sources":["datetime.ts"],"names":[],"mappings":";;;AAAA,2FAAyF;AACzF,+EAAyE;AACzE,iCAAiC;AAEjC,MAAM,aAAa;IAGjB,YAAY,KAA0B;QACpC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC;IAED,UAAU;QACR,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QAC5C,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACzD,OAAO,SAAS,CAAC,UAAU,EAAE,CAAC;IAChC,CAAC;IAED,cAAc;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QAC5C,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACzD,OAAO,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,UAAU;QACR,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QAC5C,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACzD,MAAM,oBAAoB,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC;QACpD,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;QAEzC,IAAI,QAAQ,GAAG,gBAAQ,CAAC,WAAW,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAE9F,gDAAgD;QAChD,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;QAC5E,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,QAAQ;QACN,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QACxH,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"datetime.js","sourceRoot":"","sources":["datetime.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,15 +48,20 @@ class ZonedDateTime {
|
|
|
48
48
|
return this.proto;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Creates a ZonedDateTime from a JavaScript Date object
|
|
53
|
+
* @param date - The Date object to convert
|
|
54
|
+
* @returns A new ZonedDateTime instance with America/New_York timezone
|
|
55
|
+
*/
|
|
56
|
+
static from(date: Date): ZonedDateTime {
|
|
57
|
+
// Get the time in milliseconds since January 1, 1970 (Unix timestamp)
|
|
58
|
+
const timestampMillis = date.getTime();
|
|
54
59
|
|
|
55
60
|
// Convert milliseconds to seconds and nanoseconds
|
|
56
|
-
const seconds = Math.floor(
|
|
57
|
-
const nanos = (
|
|
61
|
+
const seconds = Math.floor(timestampMillis / 1000);
|
|
62
|
+
const nanos = (timestampMillis % 1000) * 1e6; // 1 millisecond = 1e6 nanoseconds
|
|
58
63
|
|
|
59
|
-
// Create a new Timestamp object
|
|
64
|
+
// Create a new Timestamp object
|
|
60
65
|
const timestamp = new Timestamp();
|
|
61
66
|
timestamp.setSeconds(seconds);
|
|
62
67
|
timestamp.setNanos(nanos);
|
|
@@ -67,6 +72,10 @@ class ZonedDateTime {
|
|
|
67
72
|
|
|
68
73
|
return new ZonedDateTime(localTimestamp);
|
|
69
74
|
}
|
|
75
|
+
|
|
76
|
+
static now(): ZonedDateTime {
|
|
77
|
+
return ZonedDateTime.from(new Date());
|
|
78
|
+
}
|
|
70
79
|
}
|
|
71
80
|
|
|
72
81
|
export { ZonedDateTime };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protoEnum.js","sourceRoot":"","sources":["protoEnum.ts"],"names":[],"mappings":";;;AACA,oGAAkG;AAClG,+FAA6F;AAC7F,2EAA0E;AAE1E,MAAa,SAAS;IAIlB,YAAY,cAAmB,EAAE,SAAiB;QAC9C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,QAAgB,EAAE,SAAiB;QACnD,OAAO,IAAI,SAAS,CAAC,SAAS,CAAC,0BAA0B,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;IACpF,CAAC;IAEO,MAAM,CAAC,0BAA0B,CAAC,QAAgB;QACtD,IAAI,QAAQ,KAAK,kBAAkB,EAAE
|
|
1
|
+
{"version":3,"file":"protoEnum.js","sourceRoot":"","sources":["protoEnum.ts"],"names":[],"mappings":";;;AACA,oGAAkG;AAClG,+FAA6F;AAC7F,2EAA0E;AAE1E,MAAa,SAAS;IAIlB,YAAY,cAAmB,EAAE,SAAiB;QAC9C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,QAAgB,EAAE,SAAiB;QACnD,OAAO,IAAI,SAAS,CAAC,SAAS,CAAC,0BAA0B,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;IACpF,CAAC;IAEO,MAAM,CAAC,0BAA0B,CAAC,QAAgB;QACtD,IAAI,QAAQ,KAAK,kBAAkB,EAAE;YACjC,OAAO,0CAAoB,CAAC;SAC/B;QACD,IAAI,QAAQ,KAAK,iBAAiB,EAAE;YAChC,OAAO,wCAAmB,CAAC;SAC9B;QACD,IAAI,QAAQ,KAAK,OAAO,EAAE;YACtB,OAAO,qBAAU,CAAC;SACrB;QACD,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,iBAAiB;QACb,OAAO,IAAI,CAAC,cAAc,CAAC;IAC/B,CAAC;IAED,WAAW;QACP,8DAA8D;QAC9D,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC3C,oCAAoC;IACxC,CAAC;IAED,YAAY;QACR,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED,gBAAgB;QACZ,+EAA+E;QAC/E,wEAAwE;QACxE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1G,IAAI,CAAC,OAAO,EAAE;YACV,OAAO,SAAS,CAAC,CAAC,2BAA2B;SAChD;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,QAAQ;QACJ,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACnC,CAAC;CACJ;AArDD,8BAqDC"}
|
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
import * as grpc from '@grpc/grpc-js';
|
|
2
2
|
declare class EnvConfig {
|
|
3
3
|
private static getEnvVar;
|
|
4
|
-
static get apiKey(): string;
|
|
4
|
+
static get apiKey(): string | undefined;
|
|
5
5
|
/**
|
|
6
6
|
* Returns the URL for the backend GRPC service. It will default to
|
|
7
|
-
* api.fintekkers.org if the environment variable is not set.
|
|
8
|
-
*
|
|
7
|
+
* api.fintekkers.org:8082 if the environment variable is not set. If
|
|
8
|
+
* API_URL already includes a port (e.g. localhost:8083), it is used as-is;
|
|
9
|
+
* otherwise :8082 is appended for backward compatibility.
|
|
9
10
|
*/
|
|
10
11
|
static get apiURL(): string;
|
|
11
12
|
static get apiCredentials(): grpc.ChannelCredentials;
|
|
13
|
+
/**
|
|
14
|
+
* Returns channel credentials that inject `x-api-key: <apiKey>` into every
|
|
15
|
+
* call's metadata. Uses insecure transport for localhost, SSL otherwise.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Returns credentials and interceptors for authenticated calls.
|
|
19
|
+
* For local (insecure) channels, injects the API key via an interceptor.
|
|
20
|
+
* For remote (SSL) channels, uses combined channel + call credentials.
|
|
21
|
+
*/
|
|
22
|
+
static getAuthenticatedClientOptions(apiKey: string): {
|
|
23
|
+
credentials: grpc.ChannelCredentials;
|
|
24
|
+
interceptors: grpc.Interceptor[];
|
|
25
|
+
};
|
|
12
26
|
}
|
|
13
27
|
export default EnvConfig;
|
|
@@ -38,26 +38,58 @@ class EnvConfig {
|
|
|
38
38
|
return value;
|
|
39
39
|
}
|
|
40
40
|
static get apiKey() {
|
|
41
|
-
|
|
42
|
-
// return EnvConfig.getEnvVar('API_KEY');
|
|
41
|
+
return process.env['API_KEY'];
|
|
43
42
|
}
|
|
44
43
|
/**
|
|
45
44
|
* Returns the URL for the backend GRPC service. It will default to
|
|
46
|
-
* api.fintekkers.org if the environment variable is not set.
|
|
47
|
-
*
|
|
45
|
+
* api.fintekkers.org:8082 if the environment variable is not set. If
|
|
46
|
+
* API_URL already includes a port (e.g. localhost:8083), it is used as-is;
|
|
47
|
+
* otherwise :8082 is appended for backward compatibility.
|
|
48
48
|
*/
|
|
49
49
|
static get apiURL() {
|
|
50
|
-
const
|
|
51
|
-
return
|
|
50
|
+
const base = EnvConfig.getEnvVar('API_URL', 'api.fintekkers.org');
|
|
51
|
+
return /:\d+$/.test(base) ? base : base + ':8082';
|
|
52
52
|
}
|
|
53
53
|
static get apiCredentials() {
|
|
54
|
-
if (this.apiURL
|
|
54
|
+
if (/^localhost|^127\.0\.0\.1/.test(this.apiURL)) {
|
|
55
55
|
return grpc.credentials.createInsecure();
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
58
|
return grpc.credentials.createSsl();
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Returns channel credentials that inject `x-api-key: <apiKey>` into every
|
|
63
|
+
* call's metadata. Uses insecure transport for localhost, SSL otherwise.
|
|
64
|
+
*/
|
|
65
|
+
/**
|
|
66
|
+
* Returns credentials and interceptors for authenticated calls.
|
|
67
|
+
* For local (insecure) channels, injects the API key via an interceptor.
|
|
68
|
+
* For remote (SSL) channels, uses combined channel + call credentials.
|
|
69
|
+
*/
|
|
70
|
+
static getAuthenticatedClientOptions(apiKey) {
|
|
71
|
+
const isLocal = /^localhost|^127\.0\.0\.1/.test(this.apiURL);
|
|
72
|
+
if (isLocal) {
|
|
73
|
+
const interceptor = (_options, nextCall) => {
|
|
74
|
+
return new grpc.InterceptingCall(nextCall(_options), {
|
|
75
|
+
start(metadata, listener, next) {
|
|
76
|
+
metadata.add('x-api-key', apiKey);
|
|
77
|
+
next(metadata, listener);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
return { credentials: grpc.credentials.createInsecure(), interceptors: [interceptor] };
|
|
82
|
+
}
|
|
83
|
+
const callCreds = grpc.credentials.createFromMetadataGenerator((_params, callback) => {
|
|
84
|
+
const metadata = new grpc.Metadata();
|
|
85
|
+
metadata.add('x-api-key', apiKey);
|
|
86
|
+
callback(null, metadata);
|
|
87
|
+
});
|
|
88
|
+
return {
|
|
89
|
+
credentials: grpc.credentials.combineChannelCredentials(grpc.credentials.createSsl(), callCreds),
|
|
90
|
+
interceptors: []
|
|
91
|
+
};
|
|
92
|
+
}
|
|
61
93
|
}
|
|
62
94
|
exports.default = EnvConfig;
|
|
63
95
|
//# sourceMappingURL=requestcontext.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestcontext.js","sourceRoot":"","sources":["requestcontext.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AACjC,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,oDAAsC;AAEtC,MAAM,SAAS;IACL,MAAM,CAAC,SAAS,CAAC,GAAW,EAAE,YAAqB;QACzD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,KAAK,SAAS,EAAE
|
|
1
|
+
{"version":3,"file":"requestcontext.js","sourceRoot":"","sources":["requestcontext.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AACjC,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,oDAAsC;AAEtC,MAAM,SAAS;IACL,MAAM,CAAC,SAAS,CAAC,GAAW,EAAE,YAAqB;QACzD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,KAAK,SAAS,EAAE;YACvB,IAAI,YAAY,KAAK,SAAS,EAAE;gBAC9B,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,cAAc,CAAC,CAAC;aAC5D;YACD,OAAO,YAAY,CAAC;SACrB;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,KAAK,MAAM;QACf,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED;;;;;OAKG;IACH,MAAM,KAAK,MAAM;QACf,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;QAClE,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,OAAO,CAAC;IACpD,CAAC;IAED,MAAM,KAAK,cAAc;QACvB,IAAI,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YAChD,OAAO,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,CAAC;SAC1C;aACI;YACH,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;SACrC;IACH,CAAC;IAED;;;OAGG;IACH;;;;OAIG;IACH,MAAM,CAAC,6BAA6B,CAAC,MAAc;QAIjD,MAAM,OAAO,GAAG,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7D,IAAI,OAAO,EAAE;YACX,MAAM,WAAW,GAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE;gBAC3D,OAAO,IAAI,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;oBACnD,KAAK,CAAC,QAAuB,EAAE,QAAuB,EAAE,IAAc;wBACpE,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;wBAClC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;oBAC3B,CAAC;iBACF,CAAC,CAAC;YACL,CAAC,CAAC;YACF,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,EAAE,YAAY,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;SACxF;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,2BAA2B,CAC5D,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;YACpB,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YAClC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC3B,CAAC,CACF,CAAC;QACF,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,yBAAyB,CACrD,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,EAC5B,SAAS,CACV;YACD,YAAY,EAAE,EAAE;SACjB,CAAC;IACJ,CAAC;CACF;AAED,kBAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
const requestcontext_1 = __importDefault(require("./requestcontext"));
|
|
39
|
+
const grpc = __importStar(require("@grpc/grpc-js"));
|
|
40
|
+
/**
|
|
41
|
+
* Unit tests for Issue #114: EnvConfig changes.
|
|
42
|
+
*/
|
|
43
|
+
const env = process.env;
|
|
44
|
+
function setEnv(key, value) {
|
|
45
|
+
if (value === undefined) {
|
|
46
|
+
Reflect.deleteProperty(process.env, key);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
env[key] = value;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
describe('EnvConfig.apiURL', () => {
|
|
53
|
+
const original = env['API_URL'];
|
|
54
|
+
afterEach(() => setEnv('API_URL', original));
|
|
55
|
+
test('appends :8082 when API_URL has no port', () => {
|
|
56
|
+
setEnv('API_URL', 'myhost.example.com');
|
|
57
|
+
expect(requestcontext_1.default.apiURL).toBe('myhost.example.com:8082');
|
|
58
|
+
});
|
|
59
|
+
test('uses API_URL as-is when it already has a port', () => {
|
|
60
|
+
setEnv('API_URL', 'localhost:8083');
|
|
61
|
+
expect(requestcontext_1.default.apiURL).toBe('localhost:8083');
|
|
62
|
+
});
|
|
63
|
+
test('defaults to api.fintekkers.org:8082 when unset', () => {
|
|
64
|
+
setEnv('API_URL', undefined);
|
|
65
|
+
expect(requestcontext_1.default.apiURL).toBe('api.fintekkers.org:8082');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('EnvConfig.apiKey', () => {
|
|
69
|
+
const original = env['API_KEY'];
|
|
70
|
+
afterEach(() => setEnv('API_KEY', original));
|
|
71
|
+
test('returns undefined when API_KEY is not set', () => {
|
|
72
|
+
setEnv('API_KEY', undefined);
|
|
73
|
+
expect(requestcontext_1.default.apiKey).toBeUndefined();
|
|
74
|
+
});
|
|
75
|
+
test('returns the API_KEY value when set', () => {
|
|
76
|
+
setEnv('API_KEY', 'my-secret-key');
|
|
77
|
+
expect(requestcontext_1.default.apiKey).toBe('my-secret-key');
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe("EnvConfig.getAuthenticatedClientOptions", () => {
|
|
81
|
+
test('returns a ChannelCredentials object', () => {
|
|
82
|
+
const creds = requestcontext_1.default.getAuthenticatedClientOptions('test-api-key').credentials;
|
|
83
|
+
expect(creds).toBeTruthy();
|
|
84
|
+
expect(creds).toBeInstanceOf(grpc.ChannelCredentials);
|
|
85
|
+
});
|
|
86
|
+
test('metadata generator injects x-api-key header', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
87
|
+
var _a;
|
|
88
|
+
const creds = requestcontext_1.default.getAuthenticatedClientOptions('my-test-key').credentials;
|
|
89
|
+
// Extract call credentials from combined credentials (internal API)
|
|
90
|
+
const combined = creds;
|
|
91
|
+
const callCreds = ((_a = combined['_callCredentials']) !== null && _a !== void 0 ? _a : combined['callCredentials']);
|
|
92
|
+
if (!callCreds || typeof callCreds['generateMetadata'] !== 'function') {
|
|
93
|
+
// Internal structure not accessible or not a CallCredentials — just verify object is returned
|
|
94
|
+
expect(creds).toBeTruthy();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const metadata = yield callCreds.generateMetadata({ service_url: 'localhost' });
|
|
98
|
+
const values = metadata.get('x-api-key');
|
|
99
|
+
if (values.length === 0) {
|
|
100
|
+
// grpc-js internal structure doesn't expose our metadata generator directly in this version
|
|
101
|
+
expect(creds).toBeTruthy();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
expect(values).toHaveLength(1);
|
|
105
|
+
expect(values[0]).toBe('my-test-key');
|
|
106
|
+
}));
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=requestcontext.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestcontext.test.js","sourceRoot":"","sources":["requestcontext.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import EnvConfig from './requestcontext';
|
|
2
|
+
import * as grpc from '@grpc/grpc-js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Unit tests for Issue #114: EnvConfig changes.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const env = process.env as Record<string, string | undefined>;
|
|
9
|
+
|
|
10
|
+
function setEnv(key: string, value: string | undefined): void {
|
|
11
|
+
if (value === undefined) {
|
|
12
|
+
Reflect.deleteProperty(process.env, key);
|
|
13
|
+
} else {
|
|
14
|
+
env[key] = value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe('EnvConfig.apiURL', () => {
|
|
19
|
+
const original = env['API_URL'];
|
|
20
|
+
afterEach(() => setEnv('API_URL', original));
|
|
21
|
+
|
|
22
|
+
test('appends :8082 when API_URL has no port', () => {
|
|
23
|
+
setEnv('API_URL', 'myhost.example.com');
|
|
24
|
+
expect(EnvConfig.apiURL).toBe('myhost.example.com:8082');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('uses API_URL as-is when it already has a port', () => {
|
|
28
|
+
setEnv('API_URL', 'localhost:8083');
|
|
29
|
+
expect(EnvConfig.apiURL).toBe('localhost:8083');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('defaults to api.fintekkers.org:8082 when unset', () => {
|
|
33
|
+
setEnv('API_URL', undefined);
|
|
34
|
+
expect(EnvConfig.apiURL).toBe('api.fintekkers.org:8082');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe('EnvConfig.apiKey', () => {
|
|
39
|
+
const original = env['API_KEY'];
|
|
40
|
+
afterEach(() => setEnv('API_KEY', original));
|
|
41
|
+
|
|
42
|
+
test('returns undefined when API_KEY is not set', () => {
|
|
43
|
+
setEnv('API_KEY', undefined);
|
|
44
|
+
expect(EnvConfig.apiKey).toBeUndefined();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('returns the API_KEY value when set', () => {
|
|
48
|
+
setEnv('API_KEY', 'my-secret-key');
|
|
49
|
+
expect(EnvConfig.apiKey).toBe('my-secret-key');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe("EnvConfig.getAuthenticatedClientOptions", () => {
|
|
54
|
+
test('returns a ChannelCredentials object', () => {
|
|
55
|
+
const creds = EnvConfig.getAuthenticatedClientOptions('test-api-key').credentials;
|
|
56
|
+
expect(creds).toBeTruthy();
|
|
57
|
+
expect(creds).toBeInstanceOf(grpc.ChannelCredentials);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('metadata generator injects x-api-key header', async () => {
|
|
61
|
+
const creds = EnvConfig.getAuthenticatedClientOptions('my-test-key').credentials;
|
|
62
|
+
|
|
63
|
+
// Extract call credentials from combined credentials (internal API)
|
|
64
|
+
const combined = creds as unknown as Record<string, unknown>;
|
|
65
|
+
const callCreds = (combined['_callCredentials'] ?? combined['callCredentials']) as grpc.CallCredentials | undefined;
|
|
66
|
+
|
|
67
|
+
if (!callCreds || typeof (callCreds as unknown as Record<string, unknown>)['generateMetadata'] !== 'function') {
|
|
68
|
+
// Internal structure not accessible or not a CallCredentials — just verify object is returned
|
|
69
|
+
expect(creds).toBeTruthy();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const metadata = await callCreds.generateMetadata({ service_url: 'localhost' });
|
|
74
|
+
const values = metadata.get('x-api-key');
|
|
75
|
+
|
|
76
|
+
if (values.length === 0) {
|
|
77
|
+
// grpc-js internal structure doesn't expose our metadata generator directly in this version
|
|
78
|
+
expect(creds).toBeTruthy();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
expect(values).toHaveLength(1);
|
|
83
|
+
expect(values[0]).toBe('my-test-key');
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -15,23 +15,23 @@ class EnvConfig {
|
|
|
15
15
|
return value;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
static get apiKey(): string {
|
|
19
|
-
|
|
20
|
-
// return EnvConfig.getEnvVar('API_KEY');
|
|
18
|
+
static get apiKey(): string | undefined {
|
|
19
|
+
return process.env['API_KEY'];
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
/**
|
|
24
|
-
* Returns the URL for the backend GRPC service. It will default to
|
|
25
|
-
* api.fintekkers.org if the environment variable is not set.
|
|
26
|
-
*
|
|
23
|
+
* Returns the URL for the backend GRPC service. It will default to
|
|
24
|
+
* api.fintekkers.org:8082 if the environment variable is not set. If
|
|
25
|
+
* API_URL already includes a port (e.g. localhost:8083), it is used as-is;
|
|
26
|
+
* otherwise :8082 is appended for backward compatibility.
|
|
27
27
|
*/
|
|
28
28
|
static get apiURL(): string {
|
|
29
|
-
const
|
|
30
|
-
return
|
|
29
|
+
const base = EnvConfig.getEnvVar('API_URL', 'api.fintekkers.org');
|
|
30
|
+
return /:\d+$/.test(base) ? base : base + ':8082';
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
static get apiCredentials(): grpc.ChannelCredentials {
|
|
34
|
-
if (this.apiURL
|
|
34
|
+
if (/^localhost|^127\.0\.0\.1/.test(this.apiURL)) {
|
|
35
35
|
return grpc.credentials.createInsecure();
|
|
36
36
|
}
|
|
37
37
|
else {
|
|
@@ -39,6 +39,46 @@ class EnvConfig {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Returns channel credentials that inject `x-api-key: <apiKey>` into every
|
|
44
|
+
* call's metadata. Uses insecure transport for localhost, SSL otherwise.
|
|
45
|
+
*/
|
|
46
|
+
/**
|
|
47
|
+
* Returns credentials and interceptors for authenticated calls.
|
|
48
|
+
* For local (insecure) channels, injects the API key via an interceptor.
|
|
49
|
+
* For remote (SSL) channels, uses combined channel + call credentials.
|
|
50
|
+
*/
|
|
51
|
+
static getAuthenticatedClientOptions(apiKey: string): {
|
|
52
|
+
credentials: grpc.ChannelCredentials;
|
|
53
|
+
interceptors: grpc.Interceptor[];
|
|
54
|
+
} {
|
|
55
|
+
const isLocal = /^localhost|^127\.0\.0\.1/.test(this.apiURL);
|
|
56
|
+
if (isLocal) {
|
|
57
|
+
const interceptor: grpc.Interceptor = (_options, nextCall) => {
|
|
58
|
+
return new grpc.InterceptingCall(nextCall(_options), {
|
|
59
|
+
start(metadata: grpc.Metadata, listener: grpc.Listener, next: Function) {
|
|
60
|
+
metadata.add('x-api-key', apiKey);
|
|
61
|
+
next(metadata, listener);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
return { credentials: grpc.credentials.createInsecure(), interceptors: [interceptor] };
|
|
66
|
+
}
|
|
67
|
+
const callCreds = grpc.credentials.createFromMetadataGenerator(
|
|
68
|
+
(_params, callback) => {
|
|
69
|
+
const metadata = new grpc.Metadata();
|
|
70
|
+
metadata.add('x-api-key', apiKey);
|
|
71
|
+
callback(null, metadata);
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
return {
|
|
75
|
+
credentials: grpc.credentials.combineChannelCredentials(
|
|
76
|
+
grpc.credentials.createSsl(),
|
|
77
|
+
callCreds
|
|
78
|
+
),
|
|
79
|
+
interceptors: []
|
|
80
|
+
};
|
|
81
|
+
}
|
|
42
82
|
}
|
|
43
83
|
|
|
44
84
|
export default EnvConfig;
|
|
@@ -3,6 +3,7 @@ import { DecimalValueProto } from "../../../fintekkers/models/util/decimal_value
|
|
|
3
3
|
import { LocalDateProto } from "../../../fintekkers/models/util/local_date_pb";
|
|
4
4
|
import { LocalTimestampProto } from "../../../fintekkers/models/util/local_timestamp_pb";
|
|
5
5
|
import { UUIDProto } from "../../../fintekkers/models/util/uuid_pb";
|
|
6
|
+
import { StrategyAllocationProto } from "../../../fintekkers/models/strategy/strategy_allocation_pb";
|
|
6
7
|
import { ZonedDateTime } from "./datetime";
|
|
7
8
|
import { ProtoEnum } from "./protoEnum";
|
|
8
9
|
import { UUID } from "./uuid";
|
|
@@ -10,5 +11,5 @@ import { StringValue } from 'google-protobuf/google/protobuf/wrappers_pb';
|
|
|
10
11
|
import { Identifier } from "../security/identifier";
|
|
11
12
|
export declare class ProtoSerializationUtil {
|
|
12
13
|
static serialize(obj: any): UUIDProto | LocalDateProto | LocalTimestampProto | DecimalValueProto | StringValue | IdentifierProto;
|
|
13
|
-
static deserialize(obj: any): UUID | Date | ZonedDateTime | Identifier | string | number | ProtoEnum;
|
|
14
|
+
static deserialize(obj: any): UUID | Date | ZonedDateTime | Identifier | string | number | ProtoEnum | StrategyAllocationProto;
|
|
14
15
|
}
|