@finatic/client 0.9.0 → 0.9.2
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/CHANGELOG.md +16 -0
- package/LICENSE +39 -0
- package/README.md +188 -363
- package/dist/index.d.ts +7335 -1579
- package/dist/index.js +8124 -6102
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8067 -6079
- package/dist/index.mjs.map +1 -1
- package/package.json +69 -33
- package/dist/custom/FinaticConnect.d.ts +0 -19
- package/dist/custom/FinaticConnect.d.ts.map +0 -1
- package/dist/custom/FinaticConnect.js +0 -24
- package/dist/custom/FinaticConnect.js.map +0 -1
- package/dist/custom/index.d.ts +0 -8
- package/dist/custom/index.d.ts.map +0 -1
- package/dist/custom/index.js +0 -20
- package/dist/custom/index.js.map +0 -1
- package/dist/custom/utils/logger-patch.d.ts +0 -13
- package/dist/custom/utils/logger-patch.d.ts.map +0 -1
- package/dist/custom/utils/logger-patch.js +0 -72
- package/dist/custom/utils/logger-patch.js.map +0 -1
- package/dist/custom/wrappers/brokers.d.ts +0 -17
- package/dist/custom/wrappers/brokers.d.ts.map +0 -1
- package/dist/custom/wrappers/brokers.js +0 -22
- package/dist/custom/wrappers/brokers.js.map +0 -1
- package/dist/custom/wrappers/market-data.d.ts +0 -13
- package/dist/custom/wrappers/market-data.d.ts.map +0 -1
- package/dist/custom/wrappers/market-data.js +0 -19
- package/dist/custom/wrappers/market-data.js.map +0 -1
- package/dist/custom/wrappers/session.d.ts +0 -16
- package/dist/custom/wrappers/session.d.ts.map +0 -1
- package/dist/custom/wrappers/session.js +0 -21
- package/dist/custom/wrappers/session.js.map +0 -1
- package/dist/generated/FinaticConnect.d.ts +0 -282
- package/dist/generated/FinaticConnect.d.ts.map +0 -1
- package/dist/generated/FinaticConnect.js +0 -890
- package/dist/generated/FinaticConnect.js.map +0 -1
- package/dist/generated/api/brokers-api.d.ts +0 -1126
- package/dist/generated/api/brokers-api.d.ts.map +0 -1
- package/dist/generated/api/brokers-api.js +0 -1430
- package/dist/generated/api/brokers-api.js.map +0 -1
- package/dist/generated/api/market-data-api.d.ts +0 -118
- package/dist/generated/api/market-data-api.d.ts.map +0 -1
- package/dist/generated/api/market-data-api.js +0 -155
- package/dist/generated/api/market-data-api.js.map +0 -1
- package/dist/generated/api/session-api.d.ts +0 -395
- package/dist/generated/api/session-api.d.ts.map +0 -1
- package/dist/generated/api/session-api.js +0 -577
- package/dist/generated/api/session-api.js.map +0 -1
- package/dist/generated/api.d.ts +0 -14
- package/dist/generated/api.d.ts.map +0 -1
- package/dist/generated/api.js +0 -31
- package/dist/generated/api.js.map +0 -1
- package/dist/generated/base.d.ts +0 -43
- package/dist/generated/base.d.ts.map +0 -1
- package/dist/generated/base.js +0 -48
- package/dist/generated/base.js.map +0 -1
- package/dist/generated/common.d.ts +0 -29
- package/dist/generated/common.d.ts.map +0 -1
- package/dist/generated/common.js +0 -110
- package/dist/generated/common.js.map +0 -1
- package/dist/generated/config.d.ts +0 -89
- package/dist/generated/config.d.ts.map +0 -1
- package/dist/generated/config.js +0 -85
- package/dist/generated/config.js.map +0 -1
- package/dist/generated/configuration.d.ts +0 -99
- package/dist/generated/configuration.d.ts.map +0 -1
- package/dist/generated/configuration.js +0 -50
- package/dist/generated/configuration.js.map +0 -1
- package/dist/generated/models/account-status.d.ts +0 -16
- package/dist/generated/models/account-status.d.ts.map +0 -1
- package/dist/generated/models/account-status.js +0 -22
- package/dist/generated/models/account-status.js.map +0 -1
- package/dist/generated/models/account-type.d.ts +0 -19
- package/dist/generated/models/account-type.d.ts.map +0 -1
- package/dist/generated/models/account-type.js +0 -25
- package/dist/generated/models/account-type.js.map +0 -1
- package/dist/generated/models/accountnumber.d.ts +0 -14
- package/dist/generated/models/accountnumber.d.ts.map +0 -1
- package/dist/generated/models/accountnumber.js +0 -16
- package/dist/generated/models/accountnumber.js.map +0 -1
- package/dist/generated/models/accounts.d.ts +0 -34
- package/dist/generated/models/accounts.d.ts.map +0 -1
- package/dist/generated/models/accounts.js +0 -16
- package/dist/generated/models/accounts.js.map +0 -1
- package/dist/generated/models/asset-type.d.ts +0 -18
- package/dist/generated/models/asset-type.d.ts.map +0 -1
- package/dist/generated/models/asset-type.js +0 -24
- package/dist/generated/models/asset-type.js.map +0 -1
- package/dist/generated/models/balances.d.ts +0 -28
- package/dist/generated/models/balances.d.ts.map +0 -1
- package/dist/generated/models/balances.js +0 -16
- package/dist/generated/models/balances.js.map +0 -1
- package/dist/generated/models/broker-connection-request.d.ts +0 -24
- package/dist/generated/models/broker-connection-request.d.ts.map +0 -1
- package/dist/generated/models/broker-connection-request.js +0 -16
- package/dist/generated/models/broker-connection-request.js.map +0 -1
- package/dist/generated/models/broker-connection-update-request.d.ts +0 -22
- package/dist/generated/models/broker-connection-update-request.d.ts.map +0 -1
- package/dist/generated/models/broker-connection-update-request.js +0 -16
- package/dist/generated/models/broker-connection-update-request.js.map +0 -1
- package/dist/generated/models/broker-info.d.ts +0 -29
- package/dist/generated/models/broker-info.d.ts.map +0 -1
- package/dist/generated/models/broker-info.js +0 -16
- package/dist/generated/models/broker-info.js.map +0 -1
- package/dist/generated/models/broker-permissions.d.ts +0 -25
- package/dist/generated/models/broker-permissions.d.ts.map +0 -1
- package/dist/generated/models/broker-permissions.js +0 -16
- package/dist/generated/models/broker-permissions.js.map +0 -1
- package/dist/generated/models/cancel-order-api-v1-brokers-orders-order-id-delete-request.d.ts +0 -26
- package/dist/generated/models/cancel-order-api-v1-brokers-orders-order-id-delete-request.d.ts.map +0 -1
- package/dist/generated/models/cancel-order-api-v1-brokers-orders-order-id-delete-request.js +0 -16
- package/dist/generated/models/cancel-order-api-v1-brokers-orders-order-id-delete-request.js.map +0 -1
- package/dist/generated/models/day-tif.d.ts +0 -21
- package/dist/generated/models/day-tif.d.ts.map +0 -1
- package/dist/generated/models/day-tif.js +0 -21
- package/dist/generated/models/day-tif.js.map +0 -1
- package/dist/generated/models/direct-auth-request.d.ts +0 -25
- package/dist/generated/models/direct-auth-request.d.ts.map +0 -1
- package/dist/generated/models/direct-auth-request.js +0 -16
- package/dist/generated/models/direct-auth-request.js.map +0 -1
- package/dist/generated/models/disconnect-action-result.d.ts +0 -20
- package/dist/generated/models/disconnect-action-result.d.ts.map +0 -1
- package/dist/generated/models/disconnect-action-result.js +0 -16
- package/dist/generated/models/disconnect-action-result.js.map +0 -1
- package/dist/generated/models/finatic-apiwarning.d.ts +0 -24
- package/dist/generated/models/finatic-apiwarning.d.ts.map +0 -1
- package/dist/generated/models/finatic-apiwarning.js +0 -16
- package/dist/generated/models/finatic-apiwarning.js.map +0 -1
- package/dist/generated/models/finatic-error.d.ts +0 -26
- package/dist/generated/models/finatic-error.d.ts.map +0 -1
- package/dist/generated/models/finatic-error.js +0 -16
- package/dist/generated/models/finatic-error.js.map +0 -1
- package/dist/generated/models/finatic-response-disconnect-action-result.d.ts +0 -38
- package/dist/generated/models/finatic-response-disconnect-action-result.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-disconnect-action-result.js +0 -16
- package/dist/generated/models/finatic-response-disconnect-action-result.js.map +0 -1
- package/dist/generated/models/finatic-response-list-accounts.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-accounts.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-accounts.js +0 -16
- package/dist/generated/models/finatic-response-list-accounts.js.map +0 -1
- package/dist/generated/models/finatic-response-list-balances.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-balances.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-balances.js +0 -16
- package/dist/generated/models/finatic-response-list-balances.js.map +0 -1
- package/dist/generated/models/finatic-response-list-broker-info.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-broker-info.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-broker-info.js +0 -16
- package/dist/generated/models/finatic-response-list-broker-info.js.map +0 -1
- package/dist/generated/models/finatic-response-list-dict.d.ts +0 -41
- package/dist/generated/models/finatic-response-list-dict.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-dict.js +0 -16
- package/dist/generated/models/finatic-response-list-dict.js.map +0 -1
- package/dist/generated/models/finatic-response-list-futures-historical-row.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-futures-historical-row.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-futures-historical-row.js +0 -16
- package/dist/generated/models/finatic-response-list-futures-historical-row.js.map +0 -1
- package/dist/generated/models/finatic-response-list-order-event-response.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-order-event-response.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-order-event-response.js +0 -16
- package/dist/generated/models/finatic-response-list-order-event-response.js.map +0 -1
- package/dist/generated/models/finatic-response-list-order-fill-response.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-order-fill-response.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-order-fill-response.js +0 -16
- package/dist/generated/models/finatic-response-list-order-fill-response.js.map +0 -1
- package/dist/generated/models/finatic-response-list-order-group-response.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-order-group-response.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-order-group-response.js +0 -16
- package/dist/generated/models/finatic-response-list-order-group-response.js.map +0 -1
- package/dist/generated/models/finatic-response-list-order-response.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-order-response.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-order-response.js +0 -16
- package/dist/generated/models/finatic-response-list-order-response.js.map +0 -1
- package/dist/generated/models/finatic-response-list-position-lot-fill-response.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-position-lot-fill-response.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-position-lot-fill-response.js +0 -16
- package/dist/generated/models/finatic-response-list-position-lot-fill-response.js.map +0 -1
- package/dist/generated/models/finatic-response-list-position-lot-response.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-position-lot-response.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-position-lot-response.js +0 -16
- package/dist/generated/models/finatic-response-list-position-lot-response.js.map +0 -1
- package/dist/generated/models/finatic-response-list-position-response.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-position-response.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-position-response.js +0 -16
- package/dist/generated/models/finatic-response-list-position-response.js.map +0 -1
- package/dist/generated/models/finatic-response-list-user-broker-connections.d.ts +0 -38
- package/dist/generated/models/finatic-response-list-user-broker-connections.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-list-user-broker-connections.js +0 -16
- package/dist/generated/models/finatic-response-list-user-broker-connections.js.map +0 -1
- package/dist/generated/models/finatic-response-order-action-result.d.ts +0 -38
- package/dist/generated/models/finatic-response-order-action-result.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-order-action-result.js +0 -16
- package/dist/generated/models/finatic-response-order-action-result.js.map +0 -1
- package/dist/generated/models/finatic-response-portal-url-response.d.ts +0 -18
- package/dist/generated/models/finatic-response-portal-url-response.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-portal-url-response.js +0 -16
- package/dist/generated/models/finatic-response-portal-url-response.js.map +0 -1
- package/dist/generated/models/finatic-response-session-response-data.d.ts +0 -18
- package/dist/generated/models/finatic-response-session-response-data.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-session-response-data.js +0 -16
- package/dist/generated/models/finatic-response-session-response-data.js.map +0 -1
- package/dist/generated/models/finatic-response-session-user-response.d.ts +0 -18
- package/dist/generated/models/finatic-response-session-user-response.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-session-user-response.js +0 -16
- package/dist/generated/models/finatic-response-session-user-response.js.map +0 -1
- package/dist/generated/models/finatic-response-test-webhook-response.d.ts +0 -18
- package/dist/generated/models/finatic-response-test-webhook-response.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-test-webhook-response.js +0 -16
- package/dist/generated/models/finatic-response-test-webhook-response.js.map +0 -1
- package/dist/generated/models/finatic-response-token-data.d.ts +0 -18
- package/dist/generated/models/finatic-response-token-data.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-token-data.js +0 -16
- package/dist/generated/models/finatic-response-token-data.js.map +0 -1
- package/dist/generated/models/finatic-response-token-response-data.d.ts +0 -18
- package/dist/generated/models/finatic-response-token-response-data.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-token-response-data.js +0 -16
- package/dist/generated/models/finatic-response-token-response-data.js.map +0 -1
- package/dist/generated/models/finatic-response-user-broker-connections.d.ts +0 -34
- package/dist/generated/models/finatic-response-user-broker-connections.d.ts.map +0 -1
- package/dist/generated/models/finatic-response-user-broker-connections.js +0 -16
- package/dist/generated/models/finatic-response-user-broker-connections.js.map +0 -1
- package/dist/generated/models/finaticapi-api-v1-routers-session-session-router-test-webhook-request.d.ts +0 -24
- package/dist/generated/models/finaticapi-api-v1-routers-session-session-router-test-webhook-request.d.ts.map +0 -1
- package/dist/generated/models/finaticapi-api-v1-routers-session-session-router-test-webhook-request.js +0 -16
- package/dist/generated/models/finaticapi-api-v1-routers-session-session-router-test-webhook-request.js.map +0 -1
- package/dist/generated/models/finaticapi-core-standard-models-abstract-responses-finatic-response.d.ts +0 -40
- package/dist/generated/models/finaticapi-core-standard-models-abstract-responses-finatic-response.d.ts.map +0 -1
- package/dist/generated/models/finaticapi-core-standard-models-abstract-responses-finatic-response.js +0 -16
- package/dist/generated/models/finaticapi-core-standard-models-abstract-responses-finatic-response.js.map +0 -1
- package/dist/generated/models/finaticapi-core-standard-models-finatic-response.d.ts +0 -20
- package/dist/generated/models/finaticapi-core-standard-models-finatic-response.d.ts.map +0 -1
- package/dist/generated/models/finaticapi-core-standard-models-finatic-response.js +0 -16
- package/dist/generated/models/finaticapi-core-standard-models-finatic-response.js.map +0 -1
- package/dist/generated/models/foktif.d.ts +0 -21
- package/dist/generated/models/foktif.d.ts.map +0 -1
- package/dist/generated/models/foktif.js +0 -21
- package/dist/generated/models/foktif.js.map +0 -1
- package/dist/generated/models/futures-historical-row.d.ts +0 -27
- package/dist/generated/models/futures-historical-row.d.ts.map +0 -1
- package/dist/generated/models/futures-historical-row.js +0 -16
- package/dist/generated/models/futures-historical-row.js.map +0 -1
- package/dist/generated/models/gtctif.d.ts +0 -21
- package/dist/generated/models/gtctif.d.ts.map +0 -1
- package/dist/generated/models/gtctif.js +0 -21
- package/dist/generated/models/gtctif.js.map +0 -1
- package/dist/generated/models/gtdtif.d.ts +0 -25
- package/dist/generated/models/gtdtif.d.ts.map +0 -1
- package/dist/generated/models/gtdtif.js +0 -21
- package/dist/generated/models/gtdtif.js.map +0 -1
- package/dist/generated/models/httpvalidation-error.d.ts +0 -16
- package/dist/generated/models/httpvalidation-error.d.ts.map +0 -1
- package/dist/generated/models/httpvalidation-error.js +0 -16
- package/dist/generated/models/httpvalidation-error.js.map +0 -1
- package/dist/generated/models/index.d.ts +0 -108
- package/dist/generated/models/index.d.ts.map +0 -1
- package/dist/generated/models/index.js +0 -125
- package/dist/generated/models/index.js.map +0 -1
- package/dist/generated/models/ioctif.d.ts +0 -21
- package/dist/generated/models/ioctif.d.ts.map +0 -1
- package/dist/generated/models/ioctif.js +0 -21
- package/dist/generated/models/ioctif.js.map +0 -1
- package/dist/generated/models/limit-order-modify-query-params.d.ts +0 -32
- package/dist/generated/models/limit-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/limit-order-modify-query-params.js +0 -21
- package/dist/generated/models/limit-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/market-order-modify-query-params.d.ts +0 -31
- package/dist/generated/models/market-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/market-order-modify-query-params.js +0 -21
- package/dist/generated/models/market-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/modify-order-api-v1-brokers-orders-order-id-patch-request.d.ts +0 -26
- package/dist/generated/models/modify-order-api-v1-brokers-orders-order-id-patch-request.d.ts.map +0 -1
- package/dist/generated/models/modify-order-api-v1-brokers-orders-order-id-patch-request.js +0 -16
- package/dist/generated/models/modify-order-api-v1-brokers-orders-order-id-patch-request.js.map +0 -1
- package/dist/generated/models/ninja-trader-limit-order-modify-query-params.d.ts +0 -38
- package/dist/generated/models/ninja-trader-limit-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-limit-order-modify-query-params.js +0 -21
- package/dist/generated/models/ninja-trader-limit-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/ninja-trader-limit-order-place-query-params.d.ts +0 -44
- package/dist/generated/models/ninja-trader-limit-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-limit-order-place-query-params.js +0 -30
- package/dist/generated/models/ninja-trader-limit-order-place-query-params.js.map +0 -1
- package/dist/generated/models/ninja-trader-market-order-modify-query-params.d.ts +0 -37
- package/dist/generated/models/ninja-trader-market-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-market-order-modify-query-params.js +0 -21
- package/dist/generated/models/ninja-trader-market-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/ninja-trader-market-order-place-query-params.d.ts +0 -43
- package/dist/generated/models/ninja-trader-market-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-market-order-place-query-params.js +0 -30
- package/dist/generated/models/ninja-trader-market-order-place-query-params.js.map +0 -1
- package/dist/generated/models/ninja-trader-order-cancel-query-params.d.ts +0 -26
- package/dist/generated/models/ninja-trader-order-cancel-query-params.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-order-cancel-query-params.js +0 -16
- package/dist/generated/models/ninja-trader-order-cancel-query-params.js.map +0 -1
- package/dist/generated/models/ninja-trader-order-cancel-request.d.ts +0 -21
- package/dist/generated/models/ninja-trader-order-cancel-request.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-order-cancel-request.js +0 -21
- package/dist/generated/models/ninja-trader-order-cancel-request.js.map +0 -1
- package/dist/generated/models/ninja-trader-order-modify-request.d.ts +0 -21
- package/dist/generated/models/ninja-trader-order-modify-request.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-order-modify-request.js +0 -21
- package/dist/generated/models/ninja-trader-order-modify-request.js.map +0 -1
- package/dist/generated/models/ninja-trader-order-place-request.d.ts +0 -24
- package/dist/generated/models/ninja-trader-order-place-request.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-order-place-request.js +0 -21
- package/dist/generated/models/ninja-trader-order-place-request.js.map +0 -1
- package/dist/generated/models/ninja-trader-stop-order-modify-query-params.d.ts +0 -38
- package/dist/generated/models/ninja-trader-stop-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-stop-order-modify-query-params.js +0 -21
- package/dist/generated/models/ninja-trader-stop-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/ninja-trader-stop-order-place-query-params.d.ts +0 -44
- package/dist/generated/models/ninja-trader-stop-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-stop-order-place-query-params.js +0 -30
- package/dist/generated/models/ninja-trader-stop-order-place-query-params.js.map +0 -1
- package/dist/generated/models/ninja-trader-trailing-stop-order-modify-query-params.d.ts +0 -38
- package/dist/generated/models/ninja-trader-trailing-stop-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-trailing-stop-order-modify-query-params.js +0 -21
- package/dist/generated/models/ninja-trader-trailing-stop-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/ninja-trader-trailing-stop-order-place-query-params.d.ts +0 -44
- package/dist/generated/models/ninja-trader-trailing-stop-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/ninja-trader-trailing-stop-order-place-query-params.js +0 -30
- package/dist/generated/models/ninja-trader-trailing-stop-order-place-query-params.js.map +0 -1
- package/dist/generated/models/order-action-result.d.ts +0 -21
- package/dist/generated/models/order-action-result.d.ts.map +0 -1
- package/dist/generated/models/order-action-result.js +0 -16
- package/dist/generated/models/order-action-result.js.map +0 -1
- package/dist/generated/models/order-cancel-query-params.d.ts +0 -22
- package/dist/generated/models/order-cancel-query-params.d.ts.map +0 -1
- package/dist/generated/models/order-cancel-query-params.js +0 -16
- package/dist/generated/models/order-cancel-query-params.js.map +0 -1
- package/dist/generated/models/order-event-response.d.ts +0 -25
- package/dist/generated/models/order-event-response.d.ts.map +0 -1
- package/dist/generated/models/order-event-response.js +0 -16
- package/dist/generated/models/order-event-response.js.map +0 -1
- package/dist/generated/models/order-fill-response.d.ts +0 -24
- package/dist/generated/models/order-fill-response.d.ts.map +0 -1
- package/dist/generated/models/order-fill-response.js +0 -16
- package/dist/generated/models/order-fill-response.js.map +0 -1
- package/dist/generated/models/order-group-order.d.ts +0 -24
- package/dist/generated/models/order-group-order.d.ts.map +0 -1
- package/dist/generated/models/order-group-order.js +0 -16
- package/dist/generated/models/order-group-order.js.map +0 -1
- package/dist/generated/models/order-group-response.d.ts +0 -24
- package/dist/generated/models/order-group-response.d.ts.map +0 -1
- package/dist/generated/models/order-group-response.js +0 -16
- package/dist/generated/models/order-group-response.js.map +0 -1
- package/dist/generated/models/order-leg.d.ts +0 -22
- package/dist/generated/models/order-leg.d.ts.map +0 -1
- package/dist/generated/models/order-leg.js +0 -16
- package/dist/generated/models/order-leg.js.map +0 -1
- package/dist/generated/models/order-response.d.ts +0 -27
- package/dist/generated/models/order-response.d.ts.map +0 -1
- package/dist/generated/models/order-response.js +0 -16
- package/dist/generated/models/order-response.js.map +0 -1
- package/dist/generated/models/order-side.d.ts +0 -16
- package/dist/generated/models/order-side.d.ts.map +0 -1
- package/dist/generated/models/order-side.js +0 -22
- package/dist/generated/models/order-side.js.map +0 -1
- package/dist/generated/models/order-status.d.ts +0 -23
- package/dist/generated/models/order-status.d.ts.map +0 -1
- package/dist/generated/models/order-status.js +0 -29
- package/dist/generated/models/order-status.js.map +0 -1
- package/dist/generated/models/order.d.ts +0 -28
- package/dist/generated/models/order.d.ts.map +0 -1
- package/dist/generated/models/order.js +0 -16
- package/dist/generated/models/order.js.map +0 -1
- package/dist/generated/models/order1.d.ts +0 -28
- package/dist/generated/models/order1.d.ts.map +0 -1
- package/dist/generated/models/order1.js +0 -16
- package/dist/generated/models/order1.js.map +0 -1
- package/dist/generated/models/order2.d.ts +0 -28
- package/dist/generated/models/order2.d.ts.map +0 -1
- package/dist/generated/models/order2.js +0 -16
- package/dist/generated/models/order2.js.map +0 -1
- package/dist/generated/models/order3.d.ts +0 -28
- package/dist/generated/models/order3.d.ts.map +0 -1
- package/dist/generated/models/order3.js +0 -16
- package/dist/generated/models/order3.js.map +0 -1
- package/dist/generated/models/order4.d.ts +0 -28
- package/dist/generated/models/order4.d.ts.map +0 -1
- package/dist/generated/models/order4.js +0 -16
- package/dist/generated/models/order4.js.map +0 -1
- package/dist/generated/models/order5.d.ts +0 -28
- package/dist/generated/models/order5.d.ts.map +0 -1
- package/dist/generated/models/order5.js +0 -16
- package/dist/generated/models/order5.js.map +0 -1
- package/dist/generated/models/place-order-api-v1-brokers-orders-post-request.d.ts +0 -26
- package/dist/generated/models/place-order-api-v1-brokers-orders-post-request.d.ts.map +0 -1
- package/dist/generated/models/place-order-api-v1-brokers-orders-post-request.js +0 -16
- package/dist/generated/models/place-order-api-v1-brokers-orders-post-request.js.map +0 -1
- package/dist/generated/models/portal-url-response.d.ts +0 -21
- package/dist/generated/models/portal-url-response.d.ts.map +0 -1
- package/dist/generated/models/portal-url-response.js +0 -16
- package/dist/generated/models/portal-url-response.js.map +0 -1
- package/dist/generated/models/position-lot-fill-response.d.ts +0 -23
- package/dist/generated/models/position-lot-fill-response.d.ts.map +0 -1
- package/dist/generated/models/position-lot-fill-response.js +0 -16
- package/dist/generated/models/position-lot-fill-response.js.map +0 -1
- package/dist/generated/models/position-lot-response.d.ts +0 -27
- package/dist/generated/models/position-lot-response.d.ts.map +0 -1
- package/dist/generated/models/position-lot-response.js +0 -16
- package/dist/generated/models/position-lot-response.js.map +0 -1
- package/dist/generated/models/position-response.d.ts +0 -62
- package/dist/generated/models/position-response.d.ts.map +0 -1
- package/dist/generated/models/position-response.js +0 -16
- package/dist/generated/models/position-response.js.map +0 -1
- package/dist/generated/models/position-status.d.ts +0 -16
- package/dist/generated/models/position-status.d.ts.map +0 -1
- package/dist/generated/models/position-status.js +0 -22
- package/dist/generated/models/position-status.js.map +0 -1
- package/dist/generated/models/public-account-type-enum.d.ts +0 -17
- package/dist/generated/models/public-account-type-enum.d.ts.map +0 -1
- package/dist/generated/models/public-account-type-enum.js +0 -23
- package/dist/generated/models/public-account-type-enum.js.map +0 -1
- package/dist/generated/models/public-asset-type-enum.d.ts +0 -20
- package/dist/generated/models/public-asset-type-enum.d.ts.map +0 -1
- package/dist/generated/models/public-asset-type-enum.js +0 -26
- package/dist/generated/models/public-asset-type-enum.js.map +0 -1
- package/dist/generated/models/public-connection-status-enum.d.ts +0 -20
- package/dist/generated/models/public-connection-status-enum.d.ts.map +0 -1
- package/dist/generated/models/public-connection-status-enum.js +0 -26
- package/dist/generated/models/public-connection-status-enum.js.map +0 -1
- package/dist/generated/models/public-order-side-enum.d.ts +0 -16
- package/dist/generated/models/public-order-side-enum.d.ts.map +0 -1
- package/dist/generated/models/public-order-side-enum.js +0 -22
- package/dist/generated/models/public-order-side-enum.js.map +0 -1
- package/dist/generated/models/public-order-status-enum.d.ts +0 -24
- package/dist/generated/models/public-order-status-enum.d.ts.map +0 -1
- package/dist/generated/models/public-order-status-enum.js +0 -30
- package/dist/generated/models/public-order-status-enum.js.map +0 -1
- package/dist/generated/models/public-position-status-enum.d.ts +0 -17
- package/dist/generated/models/public-position-status-enum.d.ts.map +0 -1
- package/dist/generated/models/public-position-status-enum.js +0 -23
- package/dist/generated/models/public-position-status-enum.js.map +0 -1
- package/dist/generated/models/robinhood-limit-order-place-query-params.d.ts +0 -37
- package/dist/generated/models/robinhood-limit-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/robinhood-limit-order-place-query-params.js +0 -30
- package/dist/generated/models/robinhood-limit-order-place-query-params.js.map +0 -1
- package/dist/generated/models/robinhood-market-order-place-query-params.d.ts +0 -36
- package/dist/generated/models/robinhood-market-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/robinhood-market-order-place-query-params.js +0 -30
- package/dist/generated/models/robinhood-market-order-place-query-params.js.map +0 -1
- package/dist/generated/models/robinhood-order-cancel-request.d.ts +0 -21
- package/dist/generated/models/robinhood-order-cancel-request.d.ts.map +0 -1
- package/dist/generated/models/robinhood-order-cancel-request.js +0 -21
- package/dist/generated/models/robinhood-order-cancel-request.js.map +0 -1
- package/dist/generated/models/robinhood-order-modify-request.d.ts +0 -21
- package/dist/generated/models/robinhood-order-modify-request.d.ts.map +0 -1
- package/dist/generated/models/robinhood-order-modify-request.js +0 -21
- package/dist/generated/models/robinhood-order-modify-request.js.map +0 -1
- package/dist/generated/models/robinhood-order-place-request.d.ts +0 -24
- package/dist/generated/models/robinhood-order-place-request.d.ts.map +0 -1
- package/dist/generated/models/robinhood-order-place-request.js +0 -21
- package/dist/generated/models/robinhood-order-place-request.js.map +0 -1
- package/dist/generated/models/robinhood-stop-order-place-query-params.d.ts +0 -37
- package/dist/generated/models/robinhood-stop-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/robinhood-stop-order-place-query-params.js +0 -30
- package/dist/generated/models/robinhood-stop-order-place-query-params.js.map +0 -1
- package/dist/generated/models/robinhood-trailing-stop-order-place-query-params.d.ts +0 -37
- package/dist/generated/models/robinhood-trailing-stop-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/robinhood-trailing-stop-order-place-query-params.js +0 -30
- package/dist/generated/models/robinhood-trailing-stop-order-place-query-params.js.map +0 -1
- package/dist/generated/models/session-link-request.d.ts +0 -19
- package/dist/generated/models/session-link-request.d.ts.map +0 -1
- package/dist/generated/models/session-link-request.js +0 -16
- package/dist/generated/models/session-link-request.js.map +0 -1
- package/dist/generated/models/session-response-data.d.ts +0 -39
- package/dist/generated/models/session-response-data.d.ts.map +0 -1
- package/dist/generated/models/session-response-data.js +0 -16
- package/dist/generated/models/session-response-data.js.map +0 -1
- package/dist/generated/models/session-start-request.d.ts +0 -18
- package/dist/generated/models/session-start-request.d.ts.map +0 -1
- package/dist/generated/models/session-start-request.js +0 -16
- package/dist/generated/models/session-start-request.js.map +0 -1
- package/dist/generated/models/session-status.d.ts +0 -22
- package/dist/generated/models/session-status.d.ts.map +0 -1
- package/dist/generated/models/session-status.js +0 -28
- package/dist/generated/models/session-status.js.map +0 -1
- package/dist/generated/models/session-user-response.d.ts +0 -45
- package/dist/generated/models/session-user-response.d.ts.map +0 -1
- package/dist/generated/models/session-user-response.js +0 -16
- package/dist/generated/models/session-user-response.js.map +0 -1
- package/dist/generated/models/stop-order-modify-query-params.d.ts +0 -32
- package/dist/generated/models/stop-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/stop-order-modify-query-params.js +0 -21
- package/dist/generated/models/stop-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/tasty-trade-limit-order-modify-query-params.d.ts +0 -38
- package/dist/generated/models/tasty-trade-limit-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-limit-order-modify-query-params.js +0 -21
- package/dist/generated/models/tasty-trade-limit-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/tasty-trade-limit-order-place-query-params.d.ts +0 -55
- package/dist/generated/models/tasty-trade-limit-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-limit-order-place-query-params.js +0 -40
- package/dist/generated/models/tasty-trade-limit-order-place-query-params.js.map +0 -1
- package/dist/generated/models/tasty-trade-market-order-modify-query-params.d.ts +0 -37
- package/dist/generated/models/tasty-trade-market-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-market-order-modify-query-params.js +0 -21
- package/dist/generated/models/tasty-trade-market-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/tasty-trade-market-order-place-query-params.d.ts +0 -54
- package/dist/generated/models/tasty-trade-market-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-market-order-place-query-params.js +0 -40
- package/dist/generated/models/tasty-trade-market-order-place-query-params.js.map +0 -1
- package/dist/generated/models/tasty-trade-order-cancel-query-params.d.ts +0 -26
- package/dist/generated/models/tasty-trade-order-cancel-query-params.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-order-cancel-query-params.js +0 -16
- package/dist/generated/models/tasty-trade-order-cancel-query-params.js.map +0 -1
- package/dist/generated/models/tasty-trade-order-cancel-request.d.ts +0 -21
- package/dist/generated/models/tasty-trade-order-cancel-request.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-order-cancel-request.js +0 -21
- package/dist/generated/models/tasty-trade-order-cancel-request.js.map +0 -1
- package/dist/generated/models/tasty-trade-order-modify-request.d.ts +0 -21
- package/dist/generated/models/tasty-trade-order-modify-request.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-order-modify-request.js +0 -21
- package/dist/generated/models/tasty-trade-order-modify-request.js.map +0 -1
- package/dist/generated/models/tasty-trade-order-place-request.d.ts +0 -24
- package/dist/generated/models/tasty-trade-order-place-request.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-order-place-request.js +0 -21
- package/dist/generated/models/tasty-trade-order-place-request.js.map +0 -1
- package/dist/generated/models/tasty-trade-stop-order-modify-query-params.d.ts +0 -38
- package/dist/generated/models/tasty-trade-stop-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-stop-order-modify-query-params.js +0 -21
- package/dist/generated/models/tasty-trade-stop-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/tasty-trade-stop-order-place-query-params.d.ts +0 -55
- package/dist/generated/models/tasty-trade-stop-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-stop-order-place-query-params.js +0 -40
- package/dist/generated/models/tasty-trade-stop-order-place-query-params.js.map +0 -1
- package/dist/generated/models/tasty-trade-trailing-stop-order-modify-query-params.d.ts +0 -38
- package/dist/generated/models/tasty-trade-trailing-stop-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-trailing-stop-order-modify-query-params.js +0 -21
- package/dist/generated/models/tasty-trade-trailing-stop-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/tasty-trade-trailing-stop-order-place-query-params.d.ts +0 -55
- package/dist/generated/models/tasty-trade-trailing-stop-order-place-query-params.d.ts.map +0 -1
- package/dist/generated/models/tasty-trade-trailing-stop-order-place-query-params.js +0 -40
- package/dist/generated/models/tasty-trade-trailing-stop-order-place-query-params.js.map +0 -1
- package/dist/generated/models/test-webhook-response.d.ts +0 -35
- package/dist/generated/models/test-webhook-response.d.ts.map +0 -1
- package/dist/generated/models/test-webhook-response.js +0 -16
- package/dist/generated/models/test-webhook-response.js.map +0 -1
- package/dist/generated/models/timeinforce.d.ts +0 -31
- package/dist/generated/models/timeinforce.d.ts.map +0 -1
- package/dist/generated/models/timeinforce.js +0 -16
- package/dist/generated/models/timeinforce.js.map +0 -1
- package/dist/generated/models/token-data.d.ts +0 -45
- package/dist/generated/models/token-data.d.ts.map +0 -1
- package/dist/generated/models/token-data.js +0 -16
- package/dist/generated/models/token-data.js.map +0 -1
- package/dist/generated/models/token-response-data.d.ts +0 -25
- package/dist/generated/models/token-response-data.d.ts.map +0 -1
- package/dist/generated/models/token-response-data.js +0 -16
- package/dist/generated/models/token-response-data.js.map +0 -1
- package/dist/generated/models/trailing-stop-order-modify-query-params.d.ts +0 -32
- package/dist/generated/models/trailing-stop-order-modify-query-params.d.ts.map +0 -1
- package/dist/generated/models/trailing-stop-order-modify-query-params.js +0 -21
- package/dist/generated/models/trailing-stop-order-modify-query-params.js.map +0 -1
- package/dist/generated/models/user-broker-connections.d.ts +0 -28
- package/dist/generated/models/user-broker-connections.d.ts.map +0 -1
- package/dist/generated/models/user-broker-connections.js +0 -16
- package/dist/generated/models/user-broker-connections.js.map +0 -1
- package/dist/generated/models/validation-error-loc-inner.d.ts +0 -14
- package/dist/generated/models/validation-error-loc-inner.d.ts.map +0 -1
- package/dist/generated/models/validation-error-loc-inner.js +0 -16
- package/dist/generated/models/validation-error-loc-inner.js.map +0 -1
- package/dist/generated/models/validation-error.d.ts +0 -18
- package/dist/generated/models/validation-error.d.ts.map +0 -1
- package/dist/generated/models/validation-error.js +0 -16
- package/dist/generated/models/validation-error.js.map +0 -1
- package/dist/generated/portal/PortalUI.d.ts +0 -28
- package/dist/generated/portal/PortalUI.d.ts.map +0 -1
- package/dist/generated/portal/PortalUI.js +0 -139
- package/dist/generated/portal/PortalUI.js.map +0 -1
- package/dist/generated/utils/cache.d.ts +0 -16
- package/dist/generated/utils/cache.d.ts.map +0 -1
- package/dist/generated/utils/cache.js +0 -56
- package/dist/generated/utils/cache.js.map +0 -1
- package/dist/generated/utils/enum-coercion.d.ts +0 -24
- package/dist/generated/utils/enum-coercion.d.ts.map +0 -1
- package/dist/generated/utils/enum-coercion.js +0 -49
- package/dist/generated/utils/enum-coercion.js.map +0 -1
- package/dist/generated/utils/error-handling.d.ts +0 -35
- package/dist/generated/utils/error-handling.d.ts.map +0 -1
- package/dist/generated/utils/error-handling.js +0 -75
- package/dist/generated/utils/error-handling.js.map +0 -1
- package/dist/generated/utils/events.d.ts +0 -18
- package/dist/generated/utils/events.d.ts.map +0 -1
- package/dist/generated/utils/events.js +0 -60
- package/dist/generated/utils/events.js.map +0 -1
- package/dist/generated/utils/index.d.ts +0 -17
- package/dist/generated/utils/index.d.ts.map +0 -1
- package/dist/generated/utils/index.js +0 -33
- package/dist/generated/utils/index.js.map +0 -1
- package/dist/generated/utils/interceptors.d.ts +0 -40
- package/dist/generated/utils/interceptors.d.ts.map +0 -1
- package/dist/generated/utils/interceptors.js +0 -76
- package/dist/generated/utils/interceptors.js.map +0 -1
- package/dist/generated/utils/logger.d.ts +0 -21
- package/dist/generated/utils/logger.d.ts.map +0 -1
- package/dist/generated/utils/logger.js +0 -292
- package/dist/generated/utils/logger.js.map +0 -1
- package/dist/generated/utils/plain-object.d.ts +0 -22
- package/dist/generated/utils/plain-object.d.ts.map +0 -1
- package/dist/generated/utils/plain-object.js +0 -51
- package/dist/generated/utils/plain-object.js.map +0 -1
- package/dist/generated/utils/request-id.d.ts +0 -10
- package/dist/generated/utils/request-id.d.ts.map +0 -1
- package/dist/generated/utils/request-id.js +0 -24
- package/dist/generated/utils/request-id.js.map +0 -1
- package/dist/generated/utils/retry.d.ts +0 -20
- package/dist/generated/utils/retry.d.ts.map +0 -1
- package/dist/generated/utils/retry.js +0 -83
- package/dist/generated/utils/retry.js.map +0 -1
- package/dist/generated/utils/url-utils.d.ts +0 -23
- package/dist/generated/utils/url-utils.d.ts.map +0 -1
- package/dist/generated/utils/url-utils.js +0 -64
- package/dist/generated/utils/url-utils.js.map +0 -1
- package/dist/generated/utils/validation.d.ts +0 -20
- package/dist/generated/utils/validation.d.ts.map +0 -1
- package/dist/generated/utils/validation.js +0 -103
- package/dist/generated/utils/validation.js.map +0 -1
- package/dist/generated/wrappers/brokers.d.ts +0 -1107
- package/dist/generated/wrappers/brokers.d.ts.map +0 -1
- package/dist/generated/wrappers/brokers.js +0 -3076
- package/dist/generated/wrappers/brokers.js.map +0 -1
- package/dist/generated/wrappers/index.d.ts +0 -8
- package/dist/generated/wrappers/index.d.ts.map +0 -1
- package/dist/generated/wrappers/index.js +0 -13
- package/dist/generated/wrappers/index.js.map +0 -1
- package/dist/generated/wrappers/market-data.d.ts +0 -37
- package/dist/generated/wrappers/market-data.d.ts.map +0 -1
- package/dist/generated/wrappers/market-data.js +0 -134
- package/dist/generated/wrappers/market-data.js.map +0 -1
- package/dist/generated/wrappers/session.d.ts +0 -394
- package/dist/generated/wrappers/session.d.ts.map +0 -1
- package/dist/generated/wrappers/session.js +0 -1232
- package/dist/generated/wrappers/session.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/types/core/client/ApiClient.d.ts +0 -270
- package/dist/types/core/client/FinaticConnect.d.ts +0 -332
- package/dist/types/core/portal/PortalUI.d.ts +0 -37
- package/dist/types/index.d.ts +0 -12
- package/dist/types/lib/logger/index.d.ts +0 -2
- package/dist/types/lib/logger/logger.d.ts +0 -4
- package/dist/types/lib/logger/logger.types.d.ts +0 -28
- package/dist/types/mocks/MockApiClient.d.ts +0 -171
- package/dist/types/mocks/MockDataProvider.d.ts +0 -139
- package/dist/types/mocks/MockFactory.d.ts +0 -53
- package/dist/types/mocks/utils.d.ts +0 -24
- package/dist/types/themes/portalPresets.d.ts +0 -9
- package/dist/types/types/api/auth.d.ts +0 -93
- package/dist/types/types/api/broker.d.ts +0 -421
- package/dist/types/types/api/core.d.ts +0 -46
- package/dist/types/types/api/errors.d.ts +0 -31
- package/dist/types/types/api/orders.d.ts +0 -39
- package/dist/types/types/api/portfolio.d.ts +0 -55
- package/dist/types/types/common/pagination.d.ts +0 -33
- package/dist/types/types/connect.d.ts +0 -58
- package/dist/types/types/index.d.ts +0 -13
- package/dist/types/types/portal.d.ts +0 -204
- package/dist/types/types/ui/theme.d.ts +0 -104
- package/dist/types/utils/brokerUtils.d.ts +0 -30
- package/dist/types/utils/errors.d.ts +0 -45
- package/dist/types/utils/events.d.ts +0 -12
- package/dist/types/utils/themeUtils.d.ts +0 -34
- package/src/core/client/ApiClient.ts +0 -2004
- package/src/core/client/FinaticConnect.ts +0 -1606
- package/src/core/portal/PortalUI.ts +0 -335
- package/src/index.d.ts +0 -23
- package/src/index.ts +0 -100
- package/src/lib/logger/index.ts +0 -3
- package/src/lib/logger/logger.ts +0 -332
- package/src/lib/logger/logger.types.ts +0 -34
- package/src/mocks/MockApiClient.ts +0 -1058
- package/src/mocks/MockDataProvider.ts +0 -986
- package/src/mocks/MockFactory.ts +0 -97
- package/src/mocks/utils.ts +0 -133
- package/src/themes/portalPresets.ts +0 -1307
- package/src/types/api/auth.ts +0 -112
- package/src/types/api/broker.ts +0 -461
- package/src/types/api/core.ts +0 -53
- package/src/types/api/errors.ts +0 -35
- package/src/types/api/orders.ts +0 -45
- package/src/types/api/portfolio.ts +0 -59
- package/src/types/common/pagination.ts +0 -164
- package/src/types/connect.ts +0 -56
- package/src/types/index.ts +0 -25
- package/src/types/portal.ts +0 -214
- package/src/types/ui/theme.ts +0 -105
- package/src/utils/brokerUtils.ts +0 -104
- package/src/utils/errors.ts +0 -104
- package/src/utils/events.ts +0 -66
- package/src/utils/themeUtils.ts +0 -165
|
@@ -1,1606 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from '../../utils/events';
|
|
2
|
-
import { ApiClient } from './ApiClient';
|
|
3
|
-
import { PortalUI } from '../portal/PortalUI';
|
|
4
|
-
import { SessionError, AuthenticationError, CompanyAccessError, ApiError, ValidationError } from '../../utils/errors';
|
|
5
|
-
import { MockFactory } from '../../mocks/MockFactory';
|
|
6
|
-
import { PaginatedResult } from '../../types/common/pagination';
|
|
7
|
-
import { UserToken, SessionState } from '../../types/api/auth';
|
|
8
|
-
import { Order, OrderResponse, TradingContext } from '../../types/api/orders';
|
|
9
|
-
import {
|
|
10
|
-
BrokerDataOptions,
|
|
11
|
-
BrokerAccount,
|
|
12
|
-
BrokerOrder,
|
|
13
|
-
BrokerPosition,
|
|
14
|
-
BrokerBalance,
|
|
15
|
-
BrokerInfo,
|
|
16
|
-
BrokerOrderParams,
|
|
17
|
-
BrokerConnection,
|
|
18
|
-
OrdersFilter,
|
|
19
|
-
PositionsFilter,
|
|
20
|
-
AccountsFilter,
|
|
21
|
-
BalancesFilter,
|
|
22
|
-
BrokerDataOrder,
|
|
23
|
-
BrokerDataPosition,
|
|
24
|
-
BrokerDataAccount,
|
|
25
|
-
DisconnectCompanyResponse,
|
|
26
|
-
} from '../../types/api/broker';
|
|
27
|
-
import { FinaticConnectOptions, PortalOptions } from '../../types/connect';
|
|
28
|
-
import { appendThemeToURL } from '../../utils/themeUtils';
|
|
29
|
-
import { appendBrokerFilterToURL } from '../../utils/brokerUtils';
|
|
30
|
-
import { setupLogger, buildLoggerExtra, LoggerExtra } from '../../lib/logger';
|
|
31
|
-
|
|
32
|
-
const finaticConnectLogger = setupLogger('FinaticClientSDK.FinaticConnect', undefined, {
|
|
33
|
-
codebase: 'FinaticClientSDK',
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const makeFinaticConnectExtra = (functionName: string, metadata?: Record<string, unknown>): LoggerExtra => ({
|
|
37
|
-
module: 'FinaticConnect',
|
|
38
|
-
function: functionName,
|
|
39
|
-
...(metadata ? buildLoggerExtra(metadata) : {}),
|
|
40
|
-
});
|
|
41
|
-
// Supabase import removed - SDK no longer depends on Supabase
|
|
42
|
-
|
|
43
|
-
interface DeviceInfo {
|
|
44
|
-
ip_address: string;
|
|
45
|
-
user_agent: string;
|
|
46
|
-
fingerprint: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export class FinaticConnect extends EventEmitter {
|
|
50
|
-
private static instance: FinaticConnect | null = null;
|
|
51
|
-
private apiClient: ApiClient | any; // Allow both ApiClient and MockApiClient
|
|
52
|
-
private portalUI: PortalUI;
|
|
53
|
-
private options: FinaticConnectOptions;
|
|
54
|
-
private userToken: UserToken | null = null;
|
|
55
|
-
private sessionId: string | null = null;
|
|
56
|
-
private companyId: string;
|
|
57
|
-
private baseUrl: string;
|
|
58
|
-
private readonly BROKER_LIST_CACHE_KEY = 'finatic_broker_list_cache';
|
|
59
|
-
private readonly BROKER_LIST_CACHE_VERSION = '1.0';
|
|
60
|
-
private readonly BROKER_LIST_CACHE_DURATION = 1000 * 60 * 60 * 24; // 24 hours in milliseconds
|
|
61
|
-
private readonly deviceInfo?: DeviceInfo;
|
|
62
|
-
private currentSessionState: string | null = null;
|
|
63
|
-
|
|
64
|
-
// Session keep-alive mechanism
|
|
65
|
-
private sessionKeepAliveInterval: ReturnType<typeof setInterval> | null = null;
|
|
66
|
-
private readonly SESSION_KEEP_ALIVE_INTERVAL = 1000 * 60 * 5; // 5 minutes
|
|
67
|
-
private readonly SESSION_VALIDATION_TIMEOUT = 1000 * 30; // 30 seconds
|
|
68
|
-
private readonly SESSION_REFRESH_BUFFER_HOURS = 16; // Refresh session at 16 hours
|
|
69
|
-
private sessionStartTime: number | null = null;
|
|
70
|
-
|
|
71
|
-
private readonly logger = finaticConnectLogger;
|
|
72
|
-
|
|
73
|
-
private buildLoggerExtra(functionName: string, metadata?: Record<string, unknown>): LoggerExtra {
|
|
74
|
-
return {
|
|
75
|
-
module: 'FinaticConnect',
|
|
76
|
-
function: functionName,
|
|
77
|
-
...(metadata ? buildLoggerExtra(metadata) : {}),
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
constructor(options: FinaticConnectOptions, deviceInfo?: DeviceInfo) {
|
|
82
|
-
super();
|
|
83
|
-
this.options = options;
|
|
84
|
-
this.baseUrl = options.baseUrl || 'https://api.finatic.dev';
|
|
85
|
-
this.apiClient = MockFactory.createApiClient(this.baseUrl, deviceInfo);
|
|
86
|
-
this.portalUI = new PortalUI(this.baseUrl);
|
|
87
|
-
this.deviceInfo = deviceInfo;
|
|
88
|
-
|
|
89
|
-
// Extract company ID from token
|
|
90
|
-
try {
|
|
91
|
-
// Validate token exists
|
|
92
|
-
if (!options.token) {
|
|
93
|
-
throw new Error('Token is required but not provided');
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Check if token is in JWT format (contains dots)
|
|
97
|
-
if (options.token.includes('.')) {
|
|
98
|
-
const tokenParts = options.token.split('.');
|
|
99
|
-
if (tokenParts.length === 3) {
|
|
100
|
-
const payload = JSON.parse(atob(tokenParts[1]));
|
|
101
|
-
this.companyId = payload.company_id;
|
|
102
|
-
} else {
|
|
103
|
-
throw new Error('Invalid JWT token format');
|
|
104
|
-
}
|
|
105
|
-
} else {
|
|
106
|
-
// Handle UUID format token
|
|
107
|
-
// For UUID tokens, we'll get the company_id from the session start response
|
|
108
|
-
this.companyId = ''; // Will be set after session start
|
|
109
|
-
}
|
|
110
|
-
} catch (error: unknown) {
|
|
111
|
-
if (error instanceof Error) {
|
|
112
|
-
throw new Error('Failed to parse token: ' + error.message);
|
|
113
|
-
} else {
|
|
114
|
-
throw new Error('Failed to parse token: Unknown error');
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Set up event listeners for callbacks
|
|
119
|
-
if (this.options.onSuccess) {
|
|
120
|
-
this.on('success', this.options.onSuccess);
|
|
121
|
-
}
|
|
122
|
-
if (this.options.onError) {
|
|
123
|
-
this.on('error', this.options.onError);
|
|
124
|
-
}
|
|
125
|
-
if (this.options.onClose) {
|
|
126
|
-
this.on('close', this.options.onClose);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Register automatic session cleanup
|
|
130
|
-
this.registerSessionCleanup();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
private async linkUserToSession(userId: string): Promise<boolean> {
|
|
134
|
-
try {
|
|
135
|
-
if (!this.sessionId) {
|
|
136
|
-
this.logger.error('No session ID available for user linking', this.buildLoggerExtra('linkUserToSession'));
|
|
137
|
-
return false;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Call API endpoint to authenticate user with session
|
|
141
|
-
const response = await this.apiClient.request('/session/authenticate', {
|
|
142
|
-
method: 'POST',
|
|
143
|
-
body: {
|
|
144
|
-
session_id: this.sessionId,
|
|
145
|
-
user_id: userId,
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
if (response.error) {
|
|
150
|
-
this.logger.error('Failed to link user to session', {
|
|
151
|
-
...this.buildLoggerExtra('linkUserToSession', {
|
|
152
|
-
session_id: this.sessionId,
|
|
153
|
-
user_id: userId,
|
|
154
|
-
}),
|
|
155
|
-
error: response.error,
|
|
156
|
-
});
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
this.logger.info('User linked to session successfully', this.buildLoggerExtra('linkUserToSession', { session_id: this.sessionId, user_id: userId }));
|
|
161
|
-
return true;
|
|
162
|
-
} catch (error) {
|
|
163
|
-
this.logger.exception('Error linking user to session', error, this.buildLoggerExtra('linkUserToSession', { session_id: this.sessionId, user_id: userId }));
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Store user ID for authentication state persistence
|
|
170
|
-
* @param userId - The user ID to store
|
|
171
|
-
*/
|
|
172
|
-
private storeUserId(userId: string): void {
|
|
173
|
-
// Initialize userToken if it doesn't exist
|
|
174
|
-
if (!this.userToken) {
|
|
175
|
-
this.userToken = {
|
|
176
|
-
user_id: userId,
|
|
177
|
-
};
|
|
178
|
-
} else {
|
|
179
|
-
// Update existing userToken with new userId
|
|
180
|
-
this.userToken.user_id = userId;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Set user ID in ApiClient for session context
|
|
184
|
-
this.apiClient.setSessionContext(this.sessionId || '', this.companyId, undefined);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Check if the user is fully authenticated (has userId in session context)
|
|
189
|
-
* @returns True if the user is fully authenticated and ready for API calls
|
|
190
|
-
*/
|
|
191
|
-
public async isAuthenticated(): Promise<boolean> {
|
|
192
|
-
// Check internal session context only - no localStorage dependency
|
|
193
|
-
return this.userToken?.user_id !== undefined && this.userToken?.user_id !== null;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Get user's orders with pagination and optional filtering
|
|
199
|
-
* @param params - Query parameters including page, perPage, and filters
|
|
200
|
-
* @returns Promise with paginated result that supports navigation
|
|
201
|
-
*/
|
|
202
|
-
public async getOrders(
|
|
203
|
-
page: number = 1,
|
|
204
|
-
perPage: number = 100,
|
|
205
|
-
options?: BrokerDataOptions,
|
|
206
|
-
filters?: OrdersFilter
|
|
207
|
-
): Promise<PaginatedResult<BrokerDataOrder[]>> {
|
|
208
|
-
if (!(await this.isAuthenticated())) {
|
|
209
|
-
throw new AuthenticationError('User is not authenticated');
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const result = await this.apiClient.getBrokerOrdersPage(page, perPage, filters);
|
|
213
|
-
|
|
214
|
-
// Add navigation methods to the result
|
|
215
|
-
const paginatedResult = result as any;
|
|
216
|
-
paginatedResult.next_page = async () => {
|
|
217
|
-
if (paginatedResult.hasNext) {
|
|
218
|
-
return this.apiClient.getBrokerOrdersPage(page + 1, perPage, filters);
|
|
219
|
-
}
|
|
220
|
-
throw new Error('No next page available');
|
|
221
|
-
};
|
|
222
|
-
paginatedResult.previous_page = async () => {
|
|
223
|
-
if (paginatedResult.has_previous) {
|
|
224
|
-
return this.apiClient.getBrokerOrdersPage(page - 1, perPage, filters);
|
|
225
|
-
}
|
|
226
|
-
throw new Error('No previous page available');
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
return paginatedResult;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Get user's positions with pagination and optional filtering
|
|
234
|
-
* @param params - Query parameters including page, perPage, and filters
|
|
235
|
-
* @returns Promise with paginated result that supports navigation
|
|
236
|
-
*/
|
|
237
|
-
public async getPositions(
|
|
238
|
-
page: number = 1,
|
|
239
|
-
perPage: number = 100,
|
|
240
|
-
options?: BrokerDataOptions,
|
|
241
|
-
filters?: PositionsFilter
|
|
242
|
-
): Promise<PaginatedResult<BrokerDataPosition[]>> {
|
|
243
|
-
if (!(await this.isAuthenticated())) {
|
|
244
|
-
throw new AuthenticationError('User is not authenticated');
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const result = await this.apiClient.getBrokerPositionsPage(page, perPage, filters);
|
|
248
|
-
|
|
249
|
-
// Add navigation methods to the result
|
|
250
|
-
const paginatedResult = result as any;
|
|
251
|
-
paginatedResult.next_page = async () => {
|
|
252
|
-
if (paginatedResult.hasNext) {
|
|
253
|
-
return this.apiClient.getBrokerPositionsPage(page + 1, perPage, filters);
|
|
254
|
-
}
|
|
255
|
-
throw new Error('No next page available');
|
|
256
|
-
};
|
|
257
|
-
paginatedResult.previous_page = async () => {
|
|
258
|
-
if (paginatedResult.has_previous) {
|
|
259
|
-
return this.apiClient.getBrokerPositionsPage(page - 1, perPage, filters);
|
|
260
|
-
}
|
|
261
|
-
throw new Error('No previous page available');
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
return paginatedResult;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Get user's accounts with pagination and optional filtering
|
|
269
|
-
* @param params - Query parameters including page, perPage, and filters
|
|
270
|
-
* @returns Promise with paginated result that supports navigation
|
|
271
|
-
*/
|
|
272
|
-
public async getAccounts(
|
|
273
|
-
page: number = 1,
|
|
274
|
-
perPage: number = 100,
|
|
275
|
-
options?: BrokerDataOptions,
|
|
276
|
-
filters?: AccountsFilter
|
|
277
|
-
): Promise<PaginatedResult<BrokerDataAccount[]>> {
|
|
278
|
-
if (!(await this.isAuthenticated())) {
|
|
279
|
-
throw new AuthenticationError('User is not authenticated');
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const result = await this.apiClient.getBrokerAccountsPage(page, perPage, filters);
|
|
283
|
-
|
|
284
|
-
// Add navigation methods to the result
|
|
285
|
-
const paginatedResult = result as any;
|
|
286
|
-
paginatedResult.next_page = async () => {
|
|
287
|
-
if (paginatedResult.hasNext) {
|
|
288
|
-
return this.apiClient.getBrokerAccountsPage(page + 1, perPage, filters);
|
|
289
|
-
}
|
|
290
|
-
throw new Error('No next page available');
|
|
291
|
-
};
|
|
292
|
-
paginatedResult.previous_page = async () => {
|
|
293
|
-
if (paginatedResult.has_previous) {
|
|
294
|
-
return this.apiClient.getBrokerAccountsPage(page - 1, perPage, filters);
|
|
295
|
-
}
|
|
296
|
-
throw new Error('No previous page available');
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
return paginatedResult;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Get user's balances with pagination and optional filtering
|
|
304
|
-
* @param params - Query parameters including page, perPage, and filters
|
|
305
|
-
* @returns Promise with paginated result that supports navigation
|
|
306
|
-
*/
|
|
307
|
-
public async getBalances(
|
|
308
|
-
page: number = 1,
|
|
309
|
-
perPage: number = 100,
|
|
310
|
-
options?: BrokerDataOptions,
|
|
311
|
-
filters?: BalancesFilter
|
|
312
|
-
): Promise<PaginatedResult<BrokerBalance[]>> {
|
|
313
|
-
if (!(await this.isAuthenticated())) {
|
|
314
|
-
throw new AuthenticationError('User is not authenticated');
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const result = await this.apiClient.getBrokerBalancesPage(page, perPage, filters);
|
|
318
|
-
|
|
319
|
-
// Add navigation methods to the result
|
|
320
|
-
const paginatedResult = result as any;
|
|
321
|
-
paginatedResult.next_page = async () => {
|
|
322
|
-
if (paginatedResult.hasNext) {
|
|
323
|
-
return this.apiClient.getBrokerBalancesPage(page + 1, perPage, filters);
|
|
324
|
-
}
|
|
325
|
-
throw new Error('No next page available');
|
|
326
|
-
};
|
|
327
|
-
paginatedResult.previous_page = async () => {
|
|
328
|
-
if (paginatedResult.has_previous) {
|
|
329
|
-
return this.apiClient.getBrokerBalancesPage(page - 1, perPage, filters);
|
|
330
|
-
}
|
|
331
|
-
throw new Error('No previous page available');
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
return paginatedResult;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Initialize the Finatic Connect SDK
|
|
339
|
-
* @param token - The portal token from your backend
|
|
340
|
-
* @param userId - Optional: The user ID if you have it from a previous session
|
|
341
|
-
* @param options - Optional configuration including baseUrl
|
|
342
|
-
* @returns FinaticConnect instance
|
|
343
|
-
*/
|
|
344
|
-
public static async init(
|
|
345
|
-
token: string,
|
|
346
|
-
userId?: string | null | undefined,
|
|
347
|
-
options?: { baseUrl?: string } | undefined
|
|
348
|
-
): Promise<FinaticConnect> {
|
|
349
|
-
// Safari-specific fix: Clear instance if it exists but has no valid session
|
|
350
|
-
// This prevents stale instances from interfering with new requests
|
|
351
|
-
if (FinaticConnect.instance && !FinaticConnect.instance.sessionId) {
|
|
352
|
-
finaticConnectLogger.debug('Clearing stale instance for Safari compatibility', makeFinaticConnectExtra('init'));
|
|
353
|
-
FinaticConnect.instance = null;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
if (!FinaticConnect.instance) {
|
|
357
|
-
const connectOptions: FinaticConnectOptions = {
|
|
358
|
-
token,
|
|
359
|
-
baseUrl: options?.baseUrl || 'https://api.finatic.dev',
|
|
360
|
-
onSuccess: undefined,
|
|
361
|
-
onError: undefined,
|
|
362
|
-
onClose: undefined,
|
|
363
|
-
};
|
|
364
|
-
|
|
365
|
-
// Generate device info
|
|
366
|
-
const deviceInfo: DeviceInfo = {
|
|
367
|
-
ip_address: '', // Will be set by the server
|
|
368
|
-
user_agent: navigator.userAgent,
|
|
369
|
-
fingerprint: btoa(
|
|
370
|
-
[
|
|
371
|
-
navigator.userAgent,
|
|
372
|
-
navigator.language,
|
|
373
|
-
new Date().getTimezoneOffset(),
|
|
374
|
-
screen.width,
|
|
375
|
-
screen.height,
|
|
376
|
-
navigator.hardwareConcurrency,
|
|
377
|
-
// @ts-expect-error - deviceMemory is not in the Navigator type but exists in modern browsers
|
|
378
|
-
navigator.deviceMemory || 'unknown',
|
|
379
|
-
].join('|')
|
|
380
|
-
),
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
FinaticConnect.instance = new FinaticConnect(connectOptions, deviceInfo);
|
|
384
|
-
|
|
385
|
-
// Start session and get session data
|
|
386
|
-
const normalizedUserId = userId || undefined; // Convert null to undefined
|
|
387
|
-
const startResponse = await FinaticConnect.instance.apiClient.startSession(
|
|
388
|
-
token,
|
|
389
|
-
normalizedUserId
|
|
390
|
-
);
|
|
391
|
-
FinaticConnect.instance.sessionId = startResponse.data.session_id;
|
|
392
|
-
FinaticConnect.instance.companyId = startResponse.data.company_id || '';
|
|
393
|
-
|
|
394
|
-
// Record session start time for automatic refresh
|
|
395
|
-
FinaticConnect.instance.sessionStartTime = Date.now();
|
|
396
|
-
|
|
397
|
-
// Set session context in API client
|
|
398
|
-
if (
|
|
399
|
-
FinaticConnect.instance.apiClient &&
|
|
400
|
-
typeof FinaticConnect.instance.apiClient.setSessionContext === 'function'
|
|
401
|
-
) {
|
|
402
|
-
FinaticConnect.instance.apiClient.setSessionContext(
|
|
403
|
-
FinaticConnect.instance.sessionId,
|
|
404
|
-
FinaticConnect.instance.companyId,
|
|
405
|
-
startResponse.data.csrf_token // If available in response
|
|
406
|
-
);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
// If userId is provided, try to link user to session
|
|
410
|
-
if (normalizedUserId) {
|
|
411
|
-
try {
|
|
412
|
-
// Try to link user to session via API
|
|
413
|
-
const linked = await FinaticConnect.instance.linkUserToSession(normalizedUserId);
|
|
414
|
-
if (linked) {
|
|
415
|
-
// Store user ID for authentication state
|
|
416
|
-
FinaticConnect.instance.storeUserId(normalizedUserId);
|
|
417
|
-
// Emit success event
|
|
418
|
-
FinaticConnect.instance.emit('success', normalizedUserId);
|
|
419
|
-
} else {
|
|
420
|
-
finaticConnectLogger.warn('Failed to link user to session during initialization', makeFinaticConnectExtra('init', { user_id: normalizedUserId }));
|
|
421
|
-
}
|
|
422
|
-
} catch (error) {
|
|
423
|
-
FinaticConnect.instance.emit('error', error as Error);
|
|
424
|
-
throw error;
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
return FinaticConnect.instance;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
/**
|
|
432
|
-
* Initialize the SDK with a user ID
|
|
433
|
-
* @param userId - The user ID from a previous session
|
|
434
|
-
*/
|
|
435
|
-
public async setUserId(userId: string): Promise<void> {
|
|
436
|
-
await this.initializeWithUser(userId);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* Get the user and tokens for a completed session
|
|
441
|
-
* @returns Promise with user information and tokens
|
|
442
|
-
*/
|
|
443
|
-
|
|
444
|
-
private async initializeWithUser(userId: string): Promise<void> {
|
|
445
|
-
try {
|
|
446
|
-
if (!this.sessionId) {
|
|
447
|
-
throw new SessionError('Session not initialized');
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
// Try to link user to session
|
|
451
|
-
const linked = await this.linkUserToSession(userId);
|
|
452
|
-
if (!linked) {
|
|
453
|
-
this.logger.warn('Failed to link user to session during initialization', this.buildLoggerExtra('initializeWithUser', { user_id: userId }));
|
|
454
|
-
// Don't throw error, just continue without authentication
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
// Store user ID for authentication state
|
|
459
|
-
this.storeUserId(userId);
|
|
460
|
-
|
|
461
|
-
this.emit('success', userId);
|
|
462
|
-
} catch (error) {
|
|
463
|
-
this.emit('error', error as Error);
|
|
464
|
-
throw error;
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
/**
|
|
469
|
-
* Handle company access error by opening the portal
|
|
470
|
-
* @param error The company access error
|
|
471
|
-
* @param options Optional configuration for the portal
|
|
472
|
-
*/
|
|
473
|
-
private async handleCompanyAccessError(
|
|
474
|
-
error: CompanyAccessError,
|
|
475
|
-
options?: {
|
|
476
|
-
onSuccess?: (userId: string) => void;
|
|
477
|
-
onError?: (error: Error) => void;
|
|
478
|
-
onClose?: () => void;
|
|
479
|
-
}
|
|
480
|
-
): Promise<void> {
|
|
481
|
-
// Emit a specific event for company access errors
|
|
482
|
-
this.emit('companyAccessError', error);
|
|
483
|
-
|
|
484
|
-
// Open the portal to allow the user to connect a broker
|
|
485
|
-
await this.openPortal(options);
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* Open the portal for user authentication
|
|
490
|
-
* @param options Optional configuration for the portal
|
|
491
|
-
*/
|
|
492
|
-
public async openPortal(options?: PortalOptions): Promise<void> {
|
|
493
|
-
try {
|
|
494
|
-
if (!this.sessionId) {
|
|
495
|
-
throw new SessionError('Session not initialized');
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// Ensure session is active
|
|
499
|
-
const sessionState = this.apiClient.getCurrentSessionState();
|
|
500
|
-
if (sessionState !== SessionState.ACTIVE) {
|
|
501
|
-
// If not active, try to start a new session
|
|
502
|
-
const startResponse = await this.apiClient.startSession(this.options.token);
|
|
503
|
-
this.sessionId = startResponse.data.session_id;
|
|
504
|
-
this.companyId = startResponse.data.company_id || '';
|
|
505
|
-
|
|
506
|
-
// Set session context in API client
|
|
507
|
-
if (this.apiClient && typeof this.apiClient.setSessionContext === 'function') {
|
|
508
|
-
this.apiClient.setSessionContext(
|
|
509
|
-
this.sessionId,
|
|
510
|
-
this.companyId,
|
|
511
|
-
startResponse.data.csrf_token // If available in response
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
// Session is now active
|
|
516
|
-
this.currentSessionState = SessionState.ACTIVE;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
// Get portal URL
|
|
520
|
-
const portalResponse = await this.apiClient.getPortalUrl(this.sessionId);
|
|
521
|
-
if (!portalResponse.data.portal_url) {
|
|
522
|
-
throw new Error('Failed to get portal URL');
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// Apply theme to portal URL if provided
|
|
526
|
-
let themedPortalUrl = appendThemeToURL(portalResponse.data.portal_url, options?.theme);
|
|
527
|
-
|
|
528
|
-
// Apply broker filter to portal URL if provided
|
|
529
|
-
themedPortalUrl = appendBrokerFilterToURL(themedPortalUrl, options?.brokers);
|
|
530
|
-
|
|
531
|
-
// Apply email parameter to portal URL if provided
|
|
532
|
-
if (options?.email) {
|
|
533
|
-
const url = new URL(themedPortalUrl);
|
|
534
|
-
url.searchParams.set('email', options.email);
|
|
535
|
-
themedPortalUrl = url.toString();
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
// Add session ID to portal URL so the portal can use it
|
|
539
|
-
const url = new URL(themedPortalUrl);
|
|
540
|
-
if (this.sessionId) {
|
|
541
|
-
url.searchParams.set('session_id', this.sessionId);
|
|
542
|
-
}
|
|
543
|
-
if (this.companyId) {
|
|
544
|
-
url.searchParams.set('company_id', this.companyId);
|
|
545
|
-
}
|
|
546
|
-
themedPortalUrl = url.toString();
|
|
547
|
-
|
|
548
|
-
// Create portal UI if not exists
|
|
549
|
-
if (!this.portalUI) {
|
|
550
|
-
this.portalUI = new PortalUI(this.baseUrl);
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
// Show portal
|
|
554
|
-
this.portalUI.show(themedPortalUrl, this.sessionId || '', {
|
|
555
|
-
onSuccess: async (userId: string) => {
|
|
556
|
-
try {
|
|
557
|
-
if (!this.sessionId) {
|
|
558
|
-
throw new SessionError('Session not initialized');
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// Store the userId for authentication state
|
|
562
|
-
this.storeUserId(userId);
|
|
563
|
-
|
|
564
|
-
// Try to link user to session via API
|
|
565
|
-
const linked = await this.linkUserToSession(userId);
|
|
566
|
-
if (!linked) {
|
|
567
|
-
this.logger.warn('Failed to link user to session, continuing with authentication', this.buildLoggerExtra('openPortal.onSuccess', { user_id: userId }));
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
// Emit portal success event
|
|
571
|
-
this.emit('portal:success', userId);
|
|
572
|
-
|
|
573
|
-
// Emit legacy success event
|
|
574
|
-
this.emit('success', userId);
|
|
575
|
-
options?.onSuccess?.(userId);
|
|
576
|
-
} catch (error) {
|
|
577
|
-
if (error instanceof CompanyAccessError) {
|
|
578
|
-
// Handle company access error by opening the portal
|
|
579
|
-
await this.handleCompanyAccessError(error, options);
|
|
580
|
-
} else {
|
|
581
|
-
this.emit('error', error as Error);
|
|
582
|
-
options?.onError?.(error as Error);
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
},
|
|
586
|
-
onError: (error: Error) => {
|
|
587
|
-
// Emit portal error event
|
|
588
|
-
this.emit('portal:error', error);
|
|
589
|
-
|
|
590
|
-
// Emit legacy error event
|
|
591
|
-
this.emit('error', error);
|
|
592
|
-
options?.onError?.(error);
|
|
593
|
-
},
|
|
594
|
-
onClose: () => {
|
|
595
|
-
// Emit portal close event
|
|
596
|
-
this.emit('portal:close');
|
|
597
|
-
|
|
598
|
-
// Emit legacy close event
|
|
599
|
-
this.emit('close');
|
|
600
|
-
options?.onClose?.();
|
|
601
|
-
},
|
|
602
|
-
onEvent: (type: string, data: any) => {
|
|
603
|
-
this.logger.debug('Portal event received', {
|
|
604
|
-
...this.buildLoggerExtra('openPortal.onEvent', {
|
|
605
|
-
event_type: type,
|
|
606
|
-
payload_present: Boolean(data),
|
|
607
|
-
}),
|
|
608
|
-
event: 'portal-event',
|
|
609
|
-
});
|
|
610
|
-
|
|
611
|
-
// Emit generic event
|
|
612
|
-
this.emit('event', type, data);
|
|
613
|
-
|
|
614
|
-
// Call the event callback
|
|
615
|
-
options?.onEvent?.(type, data);
|
|
616
|
-
},
|
|
617
|
-
});
|
|
618
|
-
} catch (error) {
|
|
619
|
-
if (error instanceof CompanyAccessError) {
|
|
620
|
-
// Handle company access error by opening the portal
|
|
621
|
-
await this.handleCompanyAccessError(error, options);
|
|
622
|
-
} else {
|
|
623
|
-
this.emit('error', error as Error);
|
|
624
|
-
options?.onError?.(error as Error);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
/**
|
|
630
|
-
* Close the Finatic Connect Portal
|
|
631
|
-
*/
|
|
632
|
-
public closePortal(): void {
|
|
633
|
-
this.portalUI.hide();
|
|
634
|
-
this.emit('close');
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
/**
|
|
638
|
-
* Initialize a new session
|
|
639
|
-
* @param oneTimeToken - The one-time token from initSession
|
|
640
|
-
*/
|
|
641
|
-
protected async startSession(oneTimeToken: string): Promise<void> {
|
|
642
|
-
try {
|
|
643
|
-
const response = await this.apiClient.startSession(oneTimeToken);
|
|
644
|
-
this.sessionId = response.data.session_id;
|
|
645
|
-
this.currentSessionState = response.data.state;
|
|
646
|
-
|
|
647
|
-
// Set session context in API client
|
|
648
|
-
if (this.apiClient && typeof this.apiClient.setSessionContext === 'function') {
|
|
649
|
-
this.apiClient.setSessionContext(
|
|
650
|
-
this.sessionId,
|
|
651
|
-
this.companyId,
|
|
652
|
-
response.data.csrf_token // If available in response
|
|
653
|
-
);
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// For non-direct auth, we need to wait for the session to be ACTIVE
|
|
657
|
-
if (response.data.state === SessionState.PENDING) {
|
|
658
|
-
// Session is now active
|
|
659
|
-
this.currentSessionState = SessionState.ACTIVE;
|
|
660
|
-
}
|
|
661
|
-
} catch (error) {
|
|
662
|
-
if (error instanceof SessionError) {
|
|
663
|
-
throw new AuthenticationError('Failed to start session', error.details);
|
|
664
|
-
}
|
|
665
|
-
throw error;
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
/**
|
|
670
|
-
* Place a new order using the broker order API
|
|
671
|
-
* @param order - Order details with broker context
|
|
672
|
-
*/
|
|
673
|
-
public async placeOrder(order: BrokerOrderParams, extras?: BrokerExtras): Promise<OrderResponse> {
|
|
674
|
-
if (!(await this.isAuthenticated())) {
|
|
675
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
676
|
-
}
|
|
677
|
-
if (!this.userToken?.user_id) {
|
|
678
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
try {
|
|
682
|
-
// Use the order parameter directly since it's already BrokerOrderParams
|
|
683
|
-
return await this.apiClient.placeBrokerOrder(
|
|
684
|
-
order,
|
|
685
|
-
extras || {},
|
|
686
|
-
order.connection_id
|
|
687
|
-
);
|
|
688
|
-
} catch (error) {
|
|
689
|
-
this.emit('error', error as Error);
|
|
690
|
-
throw error;
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
/**
|
|
695
|
-
* Cancel a broker order
|
|
696
|
-
* @param orderId - The order ID to cancel
|
|
697
|
-
* @param broker - Optional broker override
|
|
698
|
-
* @param connection_id - Optional connection ID for testing bypass
|
|
699
|
-
*/
|
|
700
|
-
public async cancelOrder(
|
|
701
|
-
orderId: string,
|
|
702
|
-
broker?: 'robinhood' | 'tasty_trade' | 'ninja_trader',
|
|
703
|
-
connection_id?: string
|
|
704
|
-
): Promise<OrderResponse> {
|
|
705
|
-
if (!(await this.isAuthenticated())) {
|
|
706
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
707
|
-
}
|
|
708
|
-
if (!this.userToken?.user_id) {
|
|
709
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
try {
|
|
713
|
-
return await this.apiClient.cancelBrokerOrder(orderId, broker, {}, connection_id);
|
|
714
|
-
} catch (error) {
|
|
715
|
-
this.emit('error', error as Error);
|
|
716
|
-
throw error;
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
/**
|
|
721
|
-
* Modify a broker order
|
|
722
|
-
* @param orderId - The order ID to modify
|
|
723
|
-
* @param modifications - The modifications to apply
|
|
724
|
-
* @param broker - Optional broker override
|
|
725
|
-
* @param connection_id - Optional connection ID for testing bypass
|
|
726
|
-
*/
|
|
727
|
-
public async modifyOrder(
|
|
728
|
-
orderId: string,
|
|
729
|
-
modifications: Partial<{
|
|
730
|
-
symbol?: string;
|
|
731
|
-
quantity?: number;
|
|
732
|
-
price?: number;
|
|
733
|
-
stopPrice?: number;
|
|
734
|
-
timeInForce?: 'day' | 'gtc' | 'gtd' | 'ioc' | 'fok';
|
|
735
|
-
orderType?: 'Market' | 'Limit' | 'Stop' | 'StopLimit';
|
|
736
|
-
side?: 'Buy' | 'Sell';
|
|
737
|
-
order_id?: string;
|
|
738
|
-
}>,
|
|
739
|
-
broker?: 'robinhood' | 'tasty_trade' | 'ninja_trader',
|
|
740
|
-
connection_id?: string
|
|
741
|
-
): Promise<OrderResponse> {
|
|
742
|
-
if (!(await this.isAuthenticated())) {
|
|
743
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
744
|
-
}
|
|
745
|
-
if (!this.userToken?.user_id) {
|
|
746
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
try {
|
|
750
|
-
// Convert modifications to broker format
|
|
751
|
-
const brokerModifications: Partial<BrokerOrderParams> = {};
|
|
752
|
-
if (modifications.symbol) brokerModifications.symbol = modifications.symbol;
|
|
753
|
-
if (modifications.quantity) brokerModifications.orderQty = modifications.quantity;
|
|
754
|
-
if (modifications.price) brokerModifications.price = modifications.price;
|
|
755
|
-
if (modifications.stopPrice) brokerModifications.stopPrice = modifications.stopPrice;
|
|
756
|
-
if (modifications.timeInForce)
|
|
757
|
-
brokerModifications.timeInForce = modifications.timeInForce as
|
|
758
|
-
| 'day'
|
|
759
|
-
| 'gtc'
|
|
760
|
-
| 'gtd'
|
|
761
|
-
| 'ioc'
|
|
762
|
-
| 'fok';
|
|
763
|
-
if (modifications.orderType) brokerModifications.orderType = modifications.orderType;
|
|
764
|
-
if (modifications.side) brokerModifications.action = modifications.side;
|
|
765
|
-
if (modifications.order_id) brokerModifications.order_id = modifications.order_id;
|
|
766
|
-
|
|
767
|
-
return await this.apiClient.modifyBrokerOrder(
|
|
768
|
-
orderId,
|
|
769
|
-
brokerModifications,
|
|
770
|
-
broker,
|
|
771
|
-
{},
|
|
772
|
-
connection_id
|
|
773
|
-
);
|
|
774
|
-
} catch (error) {
|
|
775
|
-
this.emit('error', error as Error);
|
|
776
|
-
throw error;
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
/**
|
|
782
|
-
* Place a stock market order (convenience method)
|
|
783
|
-
*/
|
|
784
|
-
public async placeStockMarketOrder(
|
|
785
|
-
symbol: string,
|
|
786
|
-
quantity: number,
|
|
787
|
-
side: 'buy' | 'sell',
|
|
788
|
-
broker?: 'robinhood' | 'tasty_trade' | 'ninja_trader',
|
|
789
|
-
accountNumber?: string
|
|
790
|
-
): Promise<OrderResponse> {
|
|
791
|
-
if (!(await this.isAuthenticated())) {
|
|
792
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
793
|
-
}
|
|
794
|
-
if (!this.userToken?.user_id) {
|
|
795
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
try {
|
|
799
|
-
return await this.apiClient.placeStockMarketOrder(
|
|
800
|
-
symbol,
|
|
801
|
-
quantity,
|
|
802
|
-
side === 'buy' ? 'Buy' : 'Sell',
|
|
803
|
-
broker,
|
|
804
|
-
accountNumber
|
|
805
|
-
);
|
|
806
|
-
} catch (error) {
|
|
807
|
-
this.emit('error', error as Error);
|
|
808
|
-
throw error;
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
/**
|
|
813
|
-
* Place a stock limit order (convenience method)
|
|
814
|
-
*/
|
|
815
|
-
public async placeStockLimitOrder(
|
|
816
|
-
symbol: string,
|
|
817
|
-
quantity: number,
|
|
818
|
-
side: 'buy' | 'sell',
|
|
819
|
-
price: number,
|
|
820
|
-
timeInForce: 'day' | 'gtc' = 'gtc',
|
|
821
|
-
broker?: 'robinhood' | 'tasty_trade' | 'ninja_trader',
|
|
822
|
-
accountNumber?: string
|
|
823
|
-
): Promise<OrderResponse> {
|
|
824
|
-
if (!(await this.isAuthenticated())) {
|
|
825
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
826
|
-
}
|
|
827
|
-
if (!this.userToken?.user_id) {
|
|
828
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
try {
|
|
832
|
-
return await this.apiClient.placeStockLimitOrder(
|
|
833
|
-
symbol,
|
|
834
|
-
quantity,
|
|
835
|
-
side === 'buy' ? 'Buy' : 'Sell',
|
|
836
|
-
price,
|
|
837
|
-
timeInForce,
|
|
838
|
-
broker,
|
|
839
|
-
accountNumber
|
|
840
|
-
);
|
|
841
|
-
} catch (error) {
|
|
842
|
-
this.emit('error', error as Error);
|
|
843
|
-
throw error;
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
/**
|
|
848
|
-
* Place a stock stop order (convenience method)
|
|
849
|
-
*/
|
|
850
|
-
public async placeStockStopOrder(
|
|
851
|
-
symbol: string,
|
|
852
|
-
quantity: number,
|
|
853
|
-
side: 'buy' | 'sell',
|
|
854
|
-
stopPrice: number,
|
|
855
|
-
timeInForce: 'day' | 'gtc' = 'gtc',
|
|
856
|
-
broker?: 'robinhood' | 'tasty_trade' | 'ninja_trader',
|
|
857
|
-
accountNumber?: string
|
|
858
|
-
): Promise<OrderResponse> {
|
|
859
|
-
if (!(await this.isAuthenticated())) {
|
|
860
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
861
|
-
}
|
|
862
|
-
if (!this.userToken?.user_id) {
|
|
863
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
try {
|
|
867
|
-
return await this.apiClient.placeStockStopOrder(
|
|
868
|
-
symbol,
|
|
869
|
-
quantity,
|
|
870
|
-
side === 'buy' ? 'Buy' : 'Sell',
|
|
871
|
-
stopPrice,
|
|
872
|
-
timeInForce,
|
|
873
|
-
broker,
|
|
874
|
-
accountNumber
|
|
875
|
-
);
|
|
876
|
-
} catch (error) {
|
|
877
|
-
this.emit('error', error as Error);
|
|
878
|
-
throw error;
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
/**
|
|
883
|
-
* Place a crypto market order (convenience method)
|
|
884
|
-
*/
|
|
885
|
-
public async placeCryptoMarketOrder(
|
|
886
|
-
symbol: string,
|
|
887
|
-
quantity: number,
|
|
888
|
-
side: 'buy' | 'sell',
|
|
889
|
-
broker?: 'coinbase' | 'binance' | 'kraken',
|
|
890
|
-
accountNumber?: string
|
|
891
|
-
): Promise<OrderResponse> {
|
|
892
|
-
if (!(await this.isAuthenticated())) {
|
|
893
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
894
|
-
}
|
|
895
|
-
if (!this.userToken?.user_id) {
|
|
896
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
try {
|
|
900
|
-
return await this.apiClient.placeCryptoMarketOrder(
|
|
901
|
-
symbol,
|
|
902
|
-
quantity,
|
|
903
|
-
side === 'buy' ? 'Buy' : 'Sell',
|
|
904
|
-
broker,
|
|
905
|
-
accountNumber
|
|
906
|
-
);
|
|
907
|
-
} catch (error) {
|
|
908
|
-
this.emit('error', error as Error);
|
|
909
|
-
throw error;
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
/**
|
|
914
|
-
* Place a crypto limit order (convenience method)
|
|
915
|
-
*/
|
|
916
|
-
public async placeCryptoLimitOrder(
|
|
917
|
-
symbol: string,
|
|
918
|
-
quantity: number,
|
|
919
|
-
side: 'buy' | 'sell',
|
|
920
|
-
price: number,
|
|
921
|
-
timeInForce: 'day' | 'gtc' = 'gtc',
|
|
922
|
-
broker?: 'coinbase' | 'binance' | 'kraken',
|
|
923
|
-
accountNumber?: string
|
|
924
|
-
): Promise<OrderResponse> {
|
|
925
|
-
if (!(await this.isAuthenticated())) {
|
|
926
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
927
|
-
}
|
|
928
|
-
if (!this.userToken?.user_id) {
|
|
929
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
try {
|
|
933
|
-
return await this.apiClient.placeCryptoLimitOrder(
|
|
934
|
-
symbol,
|
|
935
|
-
quantity,
|
|
936
|
-
side === 'buy' ? 'Buy' : 'Sell',
|
|
937
|
-
price,
|
|
938
|
-
timeInForce,
|
|
939
|
-
broker,
|
|
940
|
-
accountNumber
|
|
941
|
-
);
|
|
942
|
-
} catch (error) {
|
|
943
|
-
this.emit('error', error as Error);
|
|
944
|
-
throw error;
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
/**
|
|
949
|
-
* Place an options market order (convenience method)
|
|
950
|
-
*/
|
|
951
|
-
public async placeOptionsMarketOrder(
|
|
952
|
-
symbol: string,
|
|
953
|
-
quantity: number,
|
|
954
|
-
side: 'buy' | 'sell',
|
|
955
|
-
broker?: 'tasty_trade' | 'robinhood' | 'ninja_trader',
|
|
956
|
-
accountNumber?: string
|
|
957
|
-
): Promise<OrderResponse> {
|
|
958
|
-
if (!(await this.isAuthenticated())) {
|
|
959
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
960
|
-
}
|
|
961
|
-
if (!this.userToken?.user_id) {
|
|
962
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
try {
|
|
966
|
-
return await this.apiClient.placeOptionsMarketOrder(
|
|
967
|
-
symbol,
|
|
968
|
-
quantity,
|
|
969
|
-
side === 'buy' ? 'Buy' : 'Sell',
|
|
970
|
-
broker,
|
|
971
|
-
accountNumber
|
|
972
|
-
);
|
|
973
|
-
} catch (error) {
|
|
974
|
-
this.emit('error', error as Error);
|
|
975
|
-
throw error;
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
/**
|
|
980
|
-
* Place an options limit order (convenience method)
|
|
981
|
-
*/
|
|
982
|
-
public async placeOptionsLimitOrder(
|
|
983
|
-
symbol: string,
|
|
984
|
-
quantity: number,
|
|
985
|
-
side: 'buy' | 'sell',
|
|
986
|
-
price: number,
|
|
987
|
-
timeInForce: 'day' | 'gtc' = 'gtc',
|
|
988
|
-
broker?: 'tasty_trade' | 'robinhood' | 'ninja_trader',
|
|
989
|
-
accountNumber?: string
|
|
990
|
-
): Promise<OrderResponse> {
|
|
991
|
-
if (!(await this.isAuthenticated())) {
|
|
992
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
993
|
-
}
|
|
994
|
-
if (!this.userToken?.user_id) {
|
|
995
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
try {
|
|
999
|
-
return await this.apiClient.placeOptionsLimitOrder(
|
|
1000
|
-
symbol,
|
|
1001
|
-
quantity,
|
|
1002
|
-
side === 'buy' ? 'Buy' : 'Sell',
|
|
1003
|
-
price,
|
|
1004
|
-
timeInForce,
|
|
1005
|
-
broker,
|
|
1006
|
-
accountNumber
|
|
1007
|
-
);
|
|
1008
|
-
} catch (error) {
|
|
1009
|
-
this.emit('error', error as Error);
|
|
1010
|
-
throw error;
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
/**
|
|
1015
|
-
* Place a futures market order (convenience method)
|
|
1016
|
-
*/
|
|
1017
|
-
public async placeFuturesMarketOrder(
|
|
1018
|
-
symbol: string,
|
|
1019
|
-
quantity: number,
|
|
1020
|
-
side: 'buy' | 'sell',
|
|
1021
|
-
broker?: 'ninja_trader' | 'tasty_trade',
|
|
1022
|
-
accountNumber?: string
|
|
1023
|
-
): Promise<OrderResponse> {
|
|
1024
|
-
if (!(await this.isAuthenticated())) {
|
|
1025
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
1026
|
-
}
|
|
1027
|
-
if (!this.userToken?.user_id) {
|
|
1028
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
try {
|
|
1032
|
-
return await this.apiClient.placeFuturesMarketOrder(
|
|
1033
|
-
symbol,
|
|
1034
|
-
quantity,
|
|
1035
|
-
side === 'buy' ? 'Buy' : 'Sell',
|
|
1036
|
-
broker,
|
|
1037
|
-
accountNumber
|
|
1038
|
-
);
|
|
1039
|
-
} catch (error) {
|
|
1040
|
-
this.emit('error', error as Error);
|
|
1041
|
-
throw error;
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
/**
|
|
1046
|
-
* Place a futures limit order (convenience method)
|
|
1047
|
-
*/
|
|
1048
|
-
public async placeFuturesLimitOrder(
|
|
1049
|
-
symbol: string,
|
|
1050
|
-
quantity: number,
|
|
1051
|
-
side: 'buy' | 'sell',
|
|
1052
|
-
price: number,
|
|
1053
|
-
timeInForce: 'day' | 'gtc' = 'gtc',
|
|
1054
|
-
broker?: 'ninja_trader' | 'tasty_trade',
|
|
1055
|
-
accountNumber?: string
|
|
1056
|
-
): Promise<OrderResponse> {
|
|
1057
|
-
if (!(await this.isAuthenticated())) {
|
|
1058
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
1059
|
-
}
|
|
1060
|
-
if (!this.userToken?.user_id) {
|
|
1061
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
try {
|
|
1065
|
-
return await this.apiClient.placeFuturesLimitOrder(
|
|
1066
|
-
symbol,
|
|
1067
|
-
quantity,
|
|
1068
|
-
side === 'buy' ? 'Buy' : 'Sell',
|
|
1069
|
-
price,
|
|
1070
|
-
timeInForce,
|
|
1071
|
-
broker,
|
|
1072
|
-
accountNumber
|
|
1073
|
-
);
|
|
1074
|
-
} catch (error) {
|
|
1075
|
-
this.emit('error', error as Error);
|
|
1076
|
-
throw error;
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
/**
|
|
1081
|
-
* Get the current user ID
|
|
1082
|
-
* @returns The current user ID or undefined if not authenticated
|
|
1083
|
-
* @throws AuthenticationError if user is not authenticated
|
|
1084
|
-
*/
|
|
1085
|
-
public async getUserId(): Promise<string | null> {
|
|
1086
|
-
if (!(await this.isAuthenticated())) {
|
|
1087
|
-
return null;
|
|
1088
|
-
}
|
|
1089
|
-
if (!this.userToken?.user_id) {
|
|
1090
|
-
return null;
|
|
1091
|
-
}
|
|
1092
|
-
return this.userToken.user_id;
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
/**
|
|
1096
|
-
* Get list of supported brokers
|
|
1097
|
-
* @returns Promise with array of broker information
|
|
1098
|
-
*/
|
|
1099
|
-
public async getBrokerList(): Promise<BrokerInfo[]> {
|
|
1100
|
-
// if (!this.isAuthenticated()) {
|
|
1101
|
-
// throw new AuthenticationError('Not authenticated');
|
|
1102
|
-
// }
|
|
1103
|
-
|
|
1104
|
-
const response = await this.apiClient.getBrokerList();
|
|
1105
|
-
const baseUrl = this.baseUrl.replace('/api/v1', ''); // Remove /api/v1 to get the base URL
|
|
1106
|
-
|
|
1107
|
-
// Transform the broker list to include full logo URLs
|
|
1108
|
-
return response.response_data.map((broker: BrokerInfo) => ({
|
|
1109
|
-
...broker,
|
|
1110
|
-
logo_path: broker.logo_path ? `${baseUrl}${broker.logo_path}` : '',
|
|
1111
|
-
}));
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
/**
|
|
1115
|
-
* Get broker connections
|
|
1116
|
-
* @returns Promise with array of broker connections
|
|
1117
|
-
* @throws AuthenticationError if user is not authenticated
|
|
1118
|
-
*/
|
|
1119
|
-
public async getBrokerConnections(): Promise<BrokerConnection[]> {
|
|
1120
|
-
if (!(await this.isAuthenticated())) {
|
|
1121
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
1122
|
-
}
|
|
1123
|
-
if (!this.userToken?.user_id) {
|
|
1124
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
const response = await this.apiClient.getBrokerConnections();
|
|
1128
|
-
if (response.status_code !== 200) {
|
|
1129
|
-
throw new Error(response.message || 'Failed to retrieve broker connections');
|
|
1130
|
-
}
|
|
1131
|
-
return response.response_data;
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
// Abstract convenience methods
|
|
1135
|
-
/**
|
|
1136
|
-
* Get only open positions
|
|
1137
|
-
* @returns Promise with array of open positions
|
|
1138
|
-
*/
|
|
1139
|
-
public async getOpenPositions(): Promise<BrokerDataPosition[]> {
|
|
1140
|
-
return this.getAllPositions({ position_status: 'open' });
|
|
1141
|
-
}
|
|
1142
|
-
|
|
1143
|
-
/**
|
|
1144
|
-
* Get only filled orders
|
|
1145
|
-
* @returns Promise with array of filled orders
|
|
1146
|
-
*/
|
|
1147
|
-
public async getFilledOrders(): Promise<BrokerDataOrder[]> {
|
|
1148
|
-
return this.getAllOrders({ status: 'filled' });
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
|
-
/**
|
|
1152
|
-
* Get only pending orders
|
|
1153
|
-
* @returns Promise with array of pending orders
|
|
1154
|
-
*/
|
|
1155
|
-
public async getPendingOrders(): Promise<BrokerDataOrder[]> {
|
|
1156
|
-
return this.getAllOrders({ status: 'pending' });
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
/**
|
|
1160
|
-
* Get only active accounts
|
|
1161
|
-
* @returns Promise with array of active accounts
|
|
1162
|
-
*/
|
|
1163
|
-
public async getActiveAccounts(): Promise<BrokerDataAccount[]> {
|
|
1164
|
-
return this.getAllAccounts({ status: 'active' });
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
/**
|
|
1168
|
-
* Get orders for a specific symbol
|
|
1169
|
-
* @param symbol - The symbol to filter by
|
|
1170
|
-
* @returns Promise with array of orders for the symbol
|
|
1171
|
-
*/
|
|
1172
|
-
public async getOrdersBySymbol(symbol: string): Promise<BrokerDataOrder[]> {
|
|
1173
|
-
return this.getAllOrders({ symbol });
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
/**
|
|
1177
|
-
* Get positions for a specific symbol
|
|
1178
|
-
* @param symbol - The symbol to filter by
|
|
1179
|
-
* @returns Promise with array of positions for the symbol
|
|
1180
|
-
*/
|
|
1181
|
-
public async getPositionsBySymbol(symbol: string): Promise<BrokerDataPosition[]> {
|
|
1182
|
-
return this.getAllPositions({ symbol });
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
/**
|
|
1186
|
-
* Get orders for a specific broker
|
|
1187
|
-
* @param brokerId - The broker ID to filter by
|
|
1188
|
-
* @returns Promise with array of orders for the broker
|
|
1189
|
-
*/
|
|
1190
|
-
public async getOrdersByBroker(brokerId: string): Promise<BrokerDataOrder[]> {
|
|
1191
|
-
return this.getAllOrders({ broker_id: brokerId });
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
/**
|
|
1195
|
-
* Get positions for a specific broker
|
|
1196
|
-
* @param brokerId - The broker ID to filter by
|
|
1197
|
-
* @returns Promise with array of positions for the broker
|
|
1198
|
-
*/
|
|
1199
|
-
public async getPositionsByBroker(brokerId: string): Promise<BrokerDataPosition[]> {
|
|
1200
|
-
return this.getAllPositions({ broker_id: brokerId });
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
// Pagination methods
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
/**
|
|
1212
|
-
* Get all orders across all pages (convenience method)
|
|
1213
|
-
* @param filter - Optional filter parameters
|
|
1214
|
-
* @returns Promise with all orders
|
|
1215
|
-
*/
|
|
1216
|
-
public async getAllOrders(filter?: OrdersFilter): Promise<BrokerDataOrder[]> {
|
|
1217
|
-
if (!(await this.isAuthenticated())) {
|
|
1218
|
-
throw new AuthenticationError('User is not authenticated');
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
|
-
const allData: BrokerDataOrder[] = [];
|
|
1222
|
-
let currentResult = await this.apiClient.getBrokerOrdersPage(1, 100, filter);
|
|
1223
|
-
|
|
1224
|
-
while (currentResult) {
|
|
1225
|
-
allData.push(...currentResult.data);
|
|
1226
|
-
if (!currentResult.hasNext) break;
|
|
1227
|
-
const nextResult = await currentResult.nextPage();
|
|
1228
|
-
if (!nextResult) break;
|
|
1229
|
-
currentResult = nextResult;
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
return allData;
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
/**
|
|
1236
|
-
* Get all positions across all pages (convenience method)
|
|
1237
|
-
* @param filter - Optional filter parameters
|
|
1238
|
-
* @returns Promise with all positions
|
|
1239
|
-
*/
|
|
1240
|
-
public async getAllPositions(filter?: PositionsFilter): Promise<BrokerDataPosition[]> {
|
|
1241
|
-
if (!(await this.isAuthenticated())) {
|
|
1242
|
-
throw new AuthenticationError('User is not authenticated');
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
|
-
const allData: BrokerDataPosition[] = [];
|
|
1246
|
-
let currentResult = await this.apiClient.getBrokerPositionsPage(1, 100, filter);
|
|
1247
|
-
|
|
1248
|
-
while (currentResult) {
|
|
1249
|
-
allData.push(...currentResult.data);
|
|
1250
|
-
if (!currentResult.hasNext) break;
|
|
1251
|
-
const nextResult = await currentResult.nextPage();
|
|
1252
|
-
if (!nextResult) break;
|
|
1253
|
-
currentResult = nextResult;
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
return allData;
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
/**
|
|
1260
|
-
* Get all accounts across all pages (convenience method)
|
|
1261
|
-
* @param filter - Optional filter parameters
|
|
1262
|
-
* @returns Promise with all accounts
|
|
1263
|
-
*/
|
|
1264
|
-
public async getAllAccounts(filter?: AccountsFilter): Promise<BrokerDataAccount[]> {
|
|
1265
|
-
if (!(await this.isAuthenticated())) {
|
|
1266
|
-
throw new AuthenticationError('User is not authenticated');
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
const allData: BrokerDataAccount[] = [];
|
|
1270
|
-
let currentResult = await this.apiClient.getBrokerAccountsPage(1, 100, filter);
|
|
1271
|
-
|
|
1272
|
-
while (currentResult) {
|
|
1273
|
-
allData.push(...currentResult.data);
|
|
1274
|
-
if (!currentResult.hasNext) break;
|
|
1275
|
-
const nextResult = await currentResult.nextPage();
|
|
1276
|
-
if (!nextResult) break;
|
|
1277
|
-
currentResult = nextResult;
|
|
1278
|
-
}
|
|
1279
|
-
|
|
1280
|
-
return allData;
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
|
-
public async getAllBalances(filter?: BalancesFilter): Promise<BrokerBalance[]> {
|
|
1284
|
-
if (!(await this.isAuthenticated())) {
|
|
1285
|
-
throw new AuthenticationError('User is not authenticated');
|
|
1286
|
-
}
|
|
1287
|
-
|
|
1288
|
-
const allData: BrokerBalance[] = [];
|
|
1289
|
-
let currentResult = await this.apiClient.getBrokerBalancesPage(1, 100, filter);
|
|
1290
|
-
|
|
1291
|
-
while (currentResult) {
|
|
1292
|
-
allData.push(...currentResult.data);
|
|
1293
|
-
if (!currentResult.hasNext) break;
|
|
1294
|
-
const nextResult = await currentResult.nextPage();
|
|
1295
|
-
if (!nextResult) break;
|
|
1296
|
-
currentResult = nextResult;
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
|
-
return allData;
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
|
-
/**
|
|
1303
|
-
* Register session management (but don't auto-cleanup for 24-hour sessions)
|
|
1304
|
-
*/
|
|
1305
|
-
private registerSessionCleanup(): void {
|
|
1306
|
-
// Only cleanup on actual page unload (not visibility changes)
|
|
1307
|
-
// This prevents sessions from being closed when users switch tabs or apps
|
|
1308
|
-
window.addEventListener('beforeunload', this.handleSessionCleanup.bind(this));
|
|
1309
|
-
|
|
1310
|
-
// Handle visibility changes for keep-alive management (but don't complete sessions)
|
|
1311
|
-
document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this));
|
|
1312
|
-
|
|
1313
|
-
// Start session keep-alive mechanism
|
|
1314
|
-
this.startSessionKeepAlive();
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
|
-
/**
|
|
1318
|
-
* Start the session keep-alive mechanism
|
|
1319
|
-
*/
|
|
1320
|
-
private startSessionKeepAlive(): void {
|
|
1321
|
-
if (this.sessionKeepAliveInterval) {
|
|
1322
|
-
clearInterval(this.sessionKeepAliveInterval);
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
|
-
this.sessionKeepAliveInterval = setInterval(() => {
|
|
1326
|
-
this.validateSessionKeepAlive();
|
|
1327
|
-
}, this.SESSION_KEEP_ALIVE_INTERVAL);
|
|
1328
|
-
|
|
1329
|
-
this.logger.debug('Session keep-alive started', this.buildLoggerExtra('startSessionKeepAlive', { interval_ms: this.SESSION_KEEP_ALIVE_INTERVAL }));
|
|
1330
|
-
}
|
|
1331
|
-
|
|
1332
|
-
/**
|
|
1333
|
-
* Stop the session keep-alive mechanism
|
|
1334
|
-
*/
|
|
1335
|
-
private stopSessionKeepAlive(): void {
|
|
1336
|
-
if (this.sessionKeepAliveInterval) {
|
|
1337
|
-
clearInterval(this.sessionKeepAliveInterval);
|
|
1338
|
-
this.sessionKeepAliveInterval = null;
|
|
1339
|
-
this.logger.debug('Session keep-alive stopped', this.buildLoggerExtra('stopSessionKeepAlive'));
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1343
|
-
/**
|
|
1344
|
-
* Validate session for keep-alive purposes and handle automatic refresh
|
|
1345
|
-
*/
|
|
1346
|
-
private async validateSessionKeepAlive(): Promise<void> {
|
|
1347
|
-
if (!this.sessionId || !(await this.isAuthenticated())) {
|
|
1348
|
-
this.logger.debug('Session keep-alive skipped - no active session', this.buildLoggerExtra('validateSessionKeepAlive'));
|
|
1349
|
-
return;
|
|
1350
|
-
}
|
|
1351
|
-
|
|
1352
|
-
try {
|
|
1353
|
-
this.logger.debug('Validating session for keep-alive', this.buildLoggerExtra('validateSessionKeepAlive', { session_id: this.sessionId }));
|
|
1354
|
-
|
|
1355
|
-
// Check if we need to refresh the session (at 16 hours)
|
|
1356
|
-
if (this.shouldRefreshSession()) {
|
|
1357
|
-
await this.refreshSessionAutomatically();
|
|
1358
|
-
return;
|
|
1359
|
-
}
|
|
1360
|
-
|
|
1361
|
-
// Session keep-alive - assume session is active if we have a session ID
|
|
1362
|
-
this.logger.debug('Session keep-alive successful', this.buildLoggerExtra('validateSessionKeepAlive', { session_id: this.sessionId }));
|
|
1363
|
-
this.currentSessionState = 'active';
|
|
1364
|
-
} catch (error) {
|
|
1365
|
-
this.logger.exception('Session keep-alive error', error, this.buildLoggerExtra('validateSessionKeepAlive', { session_id: this.sessionId }));
|
|
1366
|
-
// Don't throw errors during keep-alive - just log them
|
|
1367
|
-
}
|
|
1368
|
-
}
|
|
1369
|
-
|
|
1370
|
-
/**
|
|
1371
|
-
* Check if the session should be refreshed (after 16 hours)
|
|
1372
|
-
*/
|
|
1373
|
-
private shouldRefreshSession(): boolean {
|
|
1374
|
-
if (!this.sessionStartTime) {
|
|
1375
|
-
return false;
|
|
1376
|
-
}
|
|
1377
|
-
|
|
1378
|
-
const sessionAgeHours = (Date.now() - this.sessionStartTime) / (1000 * 60 * 60);
|
|
1379
|
-
const hoursUntilRefresh = this.SESSION_REFRESH_BUFFER_HOURS - sessionAgeHours;
|
|
1380
|
-
|
|
1381
|
-
if (hoursUntilRefresh <= 0) {
|
|
1382
|
-
this.logger.info('Session age threshold exceeded - triggering refresh', this.buildLoggerExtra('shouldRefreshSession', {
|
|
1383
|
-
session_age_hours: Number(sessionAgeHours.toFixed(1)),
|
|
1384
|
-
}));
|
|
1385
|
-
return true;
|
|
1386
|
-
}
|
|
1387
|
-
|
|
1388
|
-
// Log when refresh will occur (every 5 minutes during keep-alive)
|
|
1389
|
-
if (hoursUntilRefresh <= 1) {
|
|
1390
|
-
this.logger.debug('Session refresh scheduled', this.buildLoggerExtra('shouldRefreshSession', {
|
|
1391
|
-
hours_until_refresh: Number(hoursUntilRefresh.toFixed(1)),
|
|
1392
|
-
}));
|
|
1393
|
-
}
|
|
1394
|
-
|
|
1395
|
-
return false;
|
|
1396
|
-
}
|
|
1397
|
-
|
|
1398
|
-
/**
|
|
1399
|
-
* Automatically refresh the session to extend its lifetime
|
|
1400
|
-
*/
|
|
1401
|
-
private async refreshSessionAutomatically(): Promise<void> {
|
|
1402
|
-
if (!this.sessionId) {
|
|
1403
|
-
this.logger.warn('Cannot refresh session - missing session ID', this.buildLoggerExtra('refreshSessionAutomatically'));
|
|
1404
|
-
return;
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
try {
|
|
1408
|
-
this.logger.info('Automatically refreshing session', this.buildLoggerExtra('refreshSessionAutomatically', {
|
|
1409
|
-
session_id: this.sessionId,
|
|
1410
|
-
}));
|
|
1411
|
-
const response = await this.apiClient.refreshSession();
|
|
1412
|
-
|
|
1413
|
-
if (response.success) {
|
|
1414
|
-
this.logger.info('Session automatically refreshed successfully', this.buildLoggerExtra('refreshSessionAutomatically', {
|
|
1415
|
-
session_id: this.sessionId,
|
|
1416
|
-
status: response.response_data.status,
|
|
1417
|
-
expires_at: response.response_data.expires_at,
|
|
1418
|
-
}));
|
|
1419
|
-
this.currentSessionState = response.response_data.status;
|
|
1420
|
-
|
|
1421
|
-
// Update session start time to prevent immediate re-refresh
|
|
1422
|
-
this.sessionStartTime = Date.now();
|
|
1423
|
-
} else {
|
|
1424
|
-
this.logger.warn('Automatic session refresh failed', this.buildLoggerExtra('refreshSessionAutomatically', {
|
|
1425
|
-
session_id: this.sessionId,
|
|
1426
|
-
}));
|
|
1427
|
-
}
|
|
1428
|
-
} catch (error) {
|
|
1429
|
-
this.logger.exception('Automatic session refresh error', error, this.buildLoggerExtra('refreshSessionAutomatically', {
|
|
1430
|
-
session_id: this.sessionId,
|
|
1431
|
-
}));
|
|
1432
|
-
// Don't throw errors during automatic refresh - just log them
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
/**
|
|
1437
|
-
* Handle session cleanup when page is unloading
|
|
1438
|
-
*/
|
|
1439
|
-
private async handleSessionCleanup(): Promise<void> {
|
|
1440
|
-
this.stopSessionKeepAlive();
|
|
1441
|
-
if (this.sessionId) {
|
|
1442
|
-
await this.completeSession(this.sessionId);
|
|
1443
|
-
}
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
/**
|
|
1447
|
-
* Handle visibility change (mobile browsers)
|
|
1448
|
-
* Note: We don't complete sessions on visibility change for 24-hour sessions
|
|
1449
|
-
*/
|
|
1450
|
-
private async handleVisibilityChange(): Promise<void> {
|
|
1451
|
-
// For 24-hour sessions, we don't want to complete sessions on visibility changes
|
|
1452
|
-
// This prevents sessions from being closed when users switch tabs or apps
|
|
1453
|
-
this.logger.debug('Page visibility changed', this.buildLoggerExtra('handleVisibilityChange', {
|
|
1454
|
-
visibility_state: document.visibilityState,
|
|
1455
|
-
}));
|
|
1456
|
-
|
|
1457
|
-
// Only pause keep-alive when hidden, but don't complete the session
|
|
1458
|
-
if (document.visibilityState === 'hidden') {
|
|
1459
|
-
this.stopSessionKeepAlive();
|
|
1460
|
-
} else if (document.visibilityState === 'visible') {
|
|
1461
|
-
// Restart keep-alive when page becomes visible again
|
|
1462
|
-
this.startSessionKeepAlive();
|
|
1463
|
-
}
|
|
1464
|
-
}
|
|
1465
|
-
|
|
1466
|
-
/**
|
|
1467
|
-
* Complete the session by calling the API
|
|
1468
|
-
* @param sessionId - The session ID to complete
|
|
1469
|
-
*/
|
|
1470
|
-
private async completeSession(sessionId: string): Promise<void> {
|
|
1471
|
-
try {
|
|
1472
|
-
// Check if we're in mock mode (check if apiClient is a mock client)
|
|
1473
|
-
const isMockMode =
|
|
1474
|
-
this.apiClient &&
|
|
1475
|
-
typeof this.apiClient.isMockClient === 'function' &&
|
|
1476
|
-
this.apiClient.isMockClient();
|
|
1477
|
-
|
|
1478
|
-
if (isMockMode) {
|
|
1479
|
-
// Mock the completion response
|
|
1480
|
-
this.logger.debug('Mock session completion', this.buildLoggerExtra('completeSession', { session_id: sessionId }));
|
|
1481
|
-
return;
|
|
1482
|
-
}
|
|
1483
|
-
|
|
1484
|
-
// Real API call
|
|
1485
|
-
const response = await fetch(`${this.baseUrl}/portal/${sessionId}/complete`, {
|
|
1486
|
-
method: 'POST',
|
|
1487
|
-
headers: {
|
|
1488
|
-
'Content-Type': 'application/json',
|
|
1489
|
-
},
|
|
1490
|
-
});
|
|
1491
|
-
|
|
1492
|
-
if (response.ok) {
|
|
1493
|
-
this.logger.info('Session completed successfully', this.buildLoggerExtra('completeSession', { session_id: sessionId }));
|
|
1494
|
-
} else {
|
|
1495
|
-
this.logger.warn('Failed to complete session', this.buildLoggerExtra('completeSession', {
|
|
1496
|
-
session_id: sessionId,
|
|
1497
|
-
response_status: response.status,
|
|
1498
|
-
}));
|
|
1499
|
-
}
|
|
1500
|
-
} catch (error) {
|
|
1501
|
-
// Silent failure - don't throw errors during cleanup
|
|
1502
|
-
this.logger.exception('Session cleanup failed', error, this.buildLoggerExtra('completeSession', { session_id: sessionId }));
|
|
1503
|
-
}
|
|
1504
|
-
}
|
|
1505
|
-
|
|
1506
|
-
/**
|
|
1507
|
-
* Disconnect a company from a broker connection
|
|
1508
|
-
* @param connectionId - The connection ID to disconnect
|
|
1509
|
-
* @returns Promise with disconnect response
|
|
1510
|
-
* @throws AuthenticationError if user is not authenticated
|
|
1511
|
-
*/
|
|
1512
|
-
public async disconnectCompany(connectionId: string): Promise<DisconnectCompanyResponse> {
|
|
1513
|
-
if (!(await this.isAuthenticated())) {
|
|
1514
|
-
throw new AuthenticationError('User is not authenticated. Please connect a broker first.');
|
|
1515
|
-
}
|
|
1516
|
-
if (!this.userToken?.user_id) {
|
|
1517
|
-
throw new AuthenticationError('No user ID available. Please connect a broker first.');
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
return this.apiClient.disconnectCompany(connectionId);
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
/**
|
|
1524
|
-
* Get order fills for a specific order
|
|
1525
|
-
* @param orderId - The order ID
|
|
1526
|
-
* @param filter - Optional filter parameters
|
|
1527
|
-
* @returns Promise with order fills response
|
|
1528
|
-
*/
|
|
1529
|
-
public async getOrderFills(
|
|
1530
|
-
orderId: string,
|
|
1531
|
-
filter?: import('../../types/api/broker').OrderFillsFilter
|
|
1532
|
-
): Promise<import('../../types/api/broker').OrderFill[]> {
|
|
1533
|
-
if (!(await this.isAuthenticated())) {
|
|
1534
|
-
throw new AuthenticationError('User is not authenticated');
|
|
1535
|
-
}
|
|
1536
|
-
const response = await this.apiClient.getOrderFills(orderId, filter);
|
|
1537
|
-
return response.response_data;
|
|
1538
|
-
}
|
|
1539
|
-
|
|
1540
|
-
/**
|
|
1541
|
-
* Get order events for a specific order
|
|
1542
|
-
* @param orderId - The order ID
|
|
1543
|
-
* @param filter - Optional filter parameters
|
|
1544
|
-
* @returns Promise with order events response
|
|
1545
|
-
*/
|
|
1546
|
-
public async getOrderEvents(
|
|
1547
|
-
orderId: string,
|
|
1548
|
-
filter?: import('../../types/api/broker').OrderEventsFilter
|
|
1549
|
-
): Promise<import('../../types/api/broker').OrderEvent[]> {
|
|
1550
|
-
if (!(await this.isAuthenticated())) {
|
|
1551
|
-
throw new AuthenticationError('User is not authenticated');
|
|
1552
|
-
}
|
|
1553
|
-
const response = await this.apiClient.getOrderEvents(orderId, filter);
|
|
1554
|
-
return response.response_data;
|
|
1555
|
-
}
|
|
1556
|
-
|
|
1557
|
-
/**
|
|
1558
|
-
* Get order groups
|
|
1559
|
-
* @param filter - Optional filter parameters
|
|
1560
|
-
* @returns Promise with order groups response
|
|
1561
|
-
*/
|
|
1562
|
-
public async getOrderGroups(
|
|
1563
|
-
filter?: import('../../types/api/broker').OrderGroupsFilter
|
|
1564
|
-
): Promise<import('../../types/api/broker').OrderGroup[]> {
|
|
1565
|
-
if (!(await this.isAuthenticated())) {
|
|
1566
|
-
throw new AuthenticationError('User is not authenticated');
|
|
1567
|
-
}
|
|
1568
|
-
const response = await this.apiClient.getOrderGroups(filter);
|
|
1569
|
-
return response.response_data;
|
|
1570
|
-
}
|
|
1571
|
-
|
|
1572
|
-
/**
|
|
1573
|
-
* Get position lots (tax lots for positions)
|
|
1574
|
-
* @param filter - Optional filter parameters
|
|
1575
|
-
* @returns Promise with position lots response
|
|
1576
|
-
*/
|
|
1577
|
-
public async getPositionLots(
|
|
1578
|
-
filter?: import('../../types/api/broker').PositionLotsFilter
|
|
1579
|
-
): Promise<import('../../types/api/broker').PositionLot[]> {
|
|
1580
|
-
if (!(await this.isAuthenticated())) {
|
|
1581
|
-
throw new AuthenticationError('User is not authenticated');
|
|
1582
|
-
}
|
|
1583
|
-
const response = await this.apiClient.getPositionLots(filter);
|
|
1584
|
-
return response.response_data;
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
/**
|
|
1588
|
-
* Get position lot fills for a specific lot
|
|
1589
|
-
* @param lotId - The position lot ID
|
|
1590
|
-
* @param filter - Optional filter parameters
|
|
1591
|
-
* @returns Promise with position lot fills response
|
|
1592
|
-
*/
|
|
1593
|
-
public async getPositionLotFills(
|
|
1594
|
-
lotId: string,
|
|
1595
|
-
filter?: import('../../types/api/broker').PositionLotFillsFilter
|
|
1596
|
-
): Promise<import('../../types/api/broker').PositionLotFill[]> {
|
|
1597
|
-
if (!(await this.isAuthenticated())) {
|
|
1598
|
-
throw new AuthenticationError('User is not authenticated');
|
|
1599
|
-
}
|
|
1600
|
-
const response = await this.apiClient.getPositionLotFills(lotId, filter);
|
|
1601
|
-
return response.response_data;
|
|
1602
|
-
}
|
|
1603
|
-
|
|
1604
|
-
// Duplicate getBalances method removed - using the paginated version above
|
|
1605
|
-
|
|
1606
|
-
}
|