@ledgerhq/device-management-kit 0.0.0-z-intent-queue-7-20251204111630 → 0.0.0-zzz-solana-20251204140055
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/lib/cjs/package.json +1 -1
- package/lib/cjs/src/api/DeviceManagementKit.js +1 -1
- package/lib/cjs/src/api/DeviceManagementKit.js.map +2 -2
- package/lib/cjs/src/api/device-action/DeviceAction.js +1 -1
- package/lib/cjs/src/api/device-action/DeviceAction.js.map +1 -1
- package/lib/cjs/src/api/device-action/__test-utils__/makeInternalApi.js +1 -1
- package/lib/cjs/src/api/device-action/__test-utils__/makeInternalApi.js.map +3 -3
- package/lib/cjs/src/api/logger-subscriber/service/WebLogsExporterLogger.test.js +1 -1
- package/lib/cjs/src/api/logger-subscriber/service/WebLogsExporterLogger.test.js.map +2 -2
- package/lib/cjs/src/api/secure-channel/task/ConnectToSecureChannelTask.js +1 -1
- package/lib/cjs/src/api/secure-channel/task/ConnectToSecureChannelTask.js.map +3 -3
- package/lib/cjs/src/api/transport/model/Errors.js +1 -1
- package/lib/cjs/src/api/transport/model/Errors.js.map +3 -3
- package/lib/cjs/src/internal/device-session/di/deviceSessionModule.js +1 -1
- package/lib/cjs/src/internal/device-session/di/deviceSessionModule.js.map +3 -3
- package/lib/cjs/src/internal/device-session/di/deviceSessionTypes.js +1 -1
- package/lib/cjs/src/internal/device-session/di/deviceSessionTypes.js.map +2 -2
- package/lib/cjs/src/internal/device-session/model/DeviceSession.js +1 -1
- package/lib/cjs/src/internal/device-session/model/DeviceSession.js.map +3 -3
- package/lib/cjs/src/internal/device-session/model/DeviceSessionEventDispatcher.js +1 -1
- package/lib/cjs/src/internal/device-session/model/DeviceSessionEventDispatcher.js.map +2 -2
- package/lib/cjs/src/internal/device-session/model/DeviceSessionRefresher.js +1 -1
- package/lib/cjs/src/internal/device-session/model/DeviceSessionRefresher.js.map +3 -3
- package/lib/cjs/src/internal/device-session/model/DeviceSessionRefresher.test.js +1 -1
- package/lib/cjs/src/internal/device-session/model/DeviceSessionRefresher.test.js.map +2 -2
- package/lib/cjs/src/internal/device-session/model/DeviceSessionStateHandler.js +1 -1
- package/lib/cjs/src/internal/device-session/model/DeviceSessionStateHandler.js.map +3 -3
- package/lib/cjs/src/internal/device-session/model/DeviceSessionStateHandler.test.js +1 -1
- package/lib/cjs/src/internal/device-session/model/DeviceSessionStateHandler.test.js.map +2 -2
- package/lib/cjs/src/internal/device-session/service/MutexService.js +2 -0
- package/lib/cjs/src/internal/device-session/service/MutexService.js.map +7 -0
- package/lib/cjs/src/internal/device-session/service/MutexService.test.js +2 -0
- package/lib/cjs/src/internal/device-session/service/MutexService.test.js.map +7 -0
- package/lib/cjs/src/internal/discovery/use-case/ConnectUseCase.test.js +1 -1
- package/lib/cjs/src/internal/discovery/use-case/ConnectUseCase.test.js.map +3 -3
- package/lib/cjs/src/internal/send/use-case/SendApduUseCase.test.js +1 -1
- package/lib/cjs/src/internal/send/use-case/SendApduUseCase.test.js.map +3 -3
- package/lib/esm/package.json +1 -1
- package/lib/esm/src/api/DeviceManagementKit.js +1 -1
- package/lib/esm/src/api/DeviceManagementKit.js.map +2 -2
- package/lib/esm/src/api/device-action/__test-utils__/makeInternalApi.js +1 -1
- package/lib/esm/src/api/device-action/__test-utils__/makeInternalApi.js.map +3 -3
- package/lib/esm/src/api/logger-subscriber/service/WebLogsExporterLogger.test.js +1 -1
- package/lib/esm/src/api/logger-subscriber/service/WebLogsExporterLogger.test.js.map +3 -3
- package/lib/esm/src/api/secure-channel/task/ConnectToSecureChannelTask.js +1 -1
- package/lib/esm/src/api/secure-channel/task/ConnectToSecureChannelTask.js.map +3 -3
- package/lib/esm/src/api/transport/model/Errors.js +1 -1
- package/lib/esm/src/api/transport/model/Errors.js.map +3 -3
- package/lib/esm/src/internal/device-session/di/deviceSessionModule.js +1 -1
- package/lib/esm/src/internal/device-session/di/deviceSessionModule.js.map +3 -3
- package/lib/esm/src/internal/device-session/di/deviceSessionTypes.js +1 -1
- package/lib/esm/src/internal/device-session/di/deviceSessionTypes.js.map +2 -2
- package/lib/esm/src/internal/device-session/model/DeviceSession.js +1 -1
- package/lib/esm/src/internal/device-session/model/DeviceSession.js.map +3 -3
- package/lib/esm/src/internal/device-session/model/DeviceSessionEventDispatcher.js +1 -1
- package/lib/esm/src/internal/device-session/model/DeviceSessionEventDispatcher.js.map +2 -2
- package/lib/esm/src/internal/device-session/model/DeviceSessionRefresher.js +1 -1
- package/lib/esm/src/internal/device-session/model/DeviceSessionRefresher.js.map +3 -3
- package/lib/esm/src/internal/device-session/model/DeviceSessionRefresher.test.js +1 -1
- package/lib/esm/src/internal/device-session/model/DeviceSessionRefresher.test.js.map +2 -2
- package/lib/esm/src/internal/device-session/model/DeviceSessionStateHandler.js +1 -1
- package/lib/esm/src/internal/device-session/model/DeviceSessionStateHandler.js.map +3 -3
- package/lib/esm/src/internal/device-session/model/DeviceSessionStateHandler.test.js +1 -1
- package/lib/esm/src/internal/device-session/model/DeviceSessionStateHandler.test.js.map +2 -2
- package/lib/esm/src/internal/device-session/service/MutexService.js +2 -0
- package/lib/esm/src/internal/device-session/service/MutexService.js.map +7 -0
- package/lib/esm/src/internal/device-session/service/MutexService.test.js +2 -0
- package/lib/esm/src/internal/device-session/service/MutexService.test.js.map +7 -0
- package/lib/esm/src/internal/discovery/use-case/ConnectUseCase.test.js +1 -1
- package/lib/esm/src/internal/discovery/use-case/ConnectUseCase.test.js.map +3 -3
- package/lib/esm/src/internal/send/use-case/SendApduUseCase.test.js +1 -1
- package/lib/esm/src/internal/send/use-case/SendApduUseCase.test.js.map +3 -3
- package/lib/types/src/api/DeviceManagementKit.d.ts +0 -10
- package/lib/types/src/api/DeviceManagementKit.d.ts.map +1 -1
- package/lib/types/src/api/device-action/DeviceAction.d.ts +1 -0
- package/lib/types/src/api/device-action/DeviceAction.d.ts.map +1 -1
- package/lib/types/src/api/device-action/__test-utils__/makeInternalApi.d.ts.map +1 -1
- package/lib/types/src/api/secure-channel/task/ConnectToSecureChannelTask.d.ts.map +1 -1
- package/lib/types/src/api/transport/model/Errors.d.ts +0 -5
- package/lib/types/src/api/transport/model/Errors.d.ts.map +1 -1
- package/lib/types/src/internal/device-session/di/deviceSessionModule.d.ts.map +1 -1
- package/lib/types/src/internal/device-session/di/deviceSessionTypes.d.ts +0 -1
- package/lib/types/src/internal/device-session/di/deviceSessionTypes.d.ts.map +1 -1
- package/lib/types/src/internal/device-session/model/DeviceSession.d.ts +2 -12
- package/lib/types/src/internal/device-session/model/DeviceSession.d.ts.map +1 -1
- package/lib/types/src/internal/device-session/model/DeviceSessionEventDispatcher.d.ts +1 -3
- package/lib/types/src/internal/device-session/model/DeviceSessionEventDispatcher.d.ts.map +1 -1
- package/lib/types/src/internal/device-session/model/DeviceSessionRefresher.d.ts +1 -0
- package/lib/types/src/internal/device-session/model/DeviceSessionRefresher.d.ts.map +1 -1
- package/lib/types/src/internal/device-session/model/DeviceSessionStateHandler.d.ts +0 -1
- package/lib/types/src/internal/device-session/model/DeviceSessionStateHandler.d.ts.map +1 -1
- package/lib/types/src/internal/device-session/service/MutexService.d.ts +6 -0
- package/lib/types/src/internal/device-session/service/MutexService.d.ts.map +1 -0
- package/lib/types/src/internal/device-session/service/MutexService.test.d.ts +2 -0
- package/lib/types/src/internal/device-session/service/MutexService.test.d.ts.map +1 -0
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/lib/cjs/src/internal/device-session/model/DeviceSession.test.js +0 -2
- package/lib/cjs/src/internal/device-session/model/DeviceSession.test.js.map +0 -7
- package/lib/cjs/src/internal/device-session/service/IntentQueueService.js +0 -2
- package/lib/cjs/src/internal/device-session/service/IntentQueueService.js.map +0 -7
- package/lib/cjs/src/internal/device-session/service/IntentQueueService.test.js +0 -2
- package/lib/cjs/src/internal/device-session/service/IntentQueueService.test.js.map +0 -7
- package/lib/cjs/src/internal/device-session/use-case/UnsafeBypassIntentQueueUseCase.js +0 -2
- package/lib/cjs/src/internal/device-session/use-case/UnsafeBypassIntentQueueUseCase.js.map +0 -7
- package/lib/esm/src/internal/device-session/model/DeviceSession.test.js +0 -2
- package/lib/esm/src/internal/device-session/model/DeviceSession.test.js.map +0 -7
- package/lib/esm/src/internal/device-session/service/IntentQueueService.js +0 -2
- package/lib/esm/src/internal/device-session/service/IntentQueueService.js.map +0 -7
- package/lib/esm/src/internal/device-session/service/IntentQueueService.test.js +0 -2
- package/lib/esm/src/internal/device-session/service/IntentQueueService.test.js.map +0 -7
- package/lib/esm/src/internal/device-session/use-case/UnsafeBypassIntentQueueUseCase.js +0 -2
- package/lib/esm/src/internal/device-session/use-case/UnsafeBypassIntentQueueUseCase.js.map +0 -7
- package/lib/types/src/internal/device-session/model/DeviceSession.test.d.ts +0 -2
- package/lib/types/src/internal/device-session/model/DeviceSession.test.d.ts.map +0 -1
- package/lib/types/src/internal/device-session/service/IntentQueueService.d.ts +0 -101
- package/lib/types/src/internal/device-session/service/IntentQueueService.d.ts.map +0 -1
- package/lib/types/src/internal/device-session/service/IntentQueueService.test.d.ts +0 -2
- package/lib/types/src/internal/device-session/service/IntentQueueService.test.d.ts.map +0 -1
- package/lib/types/src/internal/device-session/use-case/UnsafeBypassIntentQueueUseCase.d.ts +0 -19
- package/lib/types/src/internal/device-session/use-case/UnsafeBypassIntentQueueUseCase.d.ts.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/device-session/model/DeviceSession.ts"],
|
|
4
|
-
"sourcesContent": ["import { type Either } from \"purify-ts\";\nimport {\n BehaviorSubject,\n from,\n lastValueFrom,\n type Observable,\n timeout,\n} from \"rxjs\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nimport { type Command } from \"@api/command/Command\";\nimport { type CommandResult } from \"@api/command/model/CommandResult\";\nimport { CommandUtils } from \"@api/command/utils/CommandUtils\";\nimport { DeviceStatus } from \"@api/device/DeviceStatus\";\nimport {\n type DeviceAction,\n type DeviceActionIntermediateValue,\n type ExecuteDeviceActionReturnType,\n} from \"@api/device-action/DeviceAction\";\nimport { type ApduResponse } from \"@api/device-session/ApduResponse\";\nimport {\n type DeviceSessionState,\n DeviceSessionStateType,\n} from \"@api/device-session/DeviceSessionState\";\nimport { type DeviceSessionId } from \"@api/device-session/types\";\nimport { type DmkError } from \"@api/Error\";\nimport { type LoggerPublisherService } from \"@api/logger-publisher/service/LoggerPublisherService\";\nimport {\n SendApduTimeoutError,\n SendCommandTimeoutError,\n} from \"@api/transport/model/Errors\";\nimport { type TransportConnectedDevice } from \"@api/transport/model/TransportConnectedDevice\";\nimport { bufferToHexaString } from \"@api/utils/HexaString\";\nimport { DEVICE_SESSION_REFRESHER_DEFAULT_OPTIONS } from \"@internal/device-session/data/DeviceSessionRefresherConst\";\nimport { IntentQueueService } from \"@internal/device-session/service/IntentQueueService\";\nimport { RefresherService } from \"@internal/device-session/service/RefresherService\";\nimport { type ManagerApiService } from \"@internal/manager-api/service/ManagerApiService\";\nimport { type SecureChannelService } from \"@internal/secure-channel/service/SecureChannelService\";\n\nimport { DevicePinger } from \"./DevicePinger\";\nimport {\n DeviceSessionEventDispatcher,\n SessionEvents,\n} from \"./DeviceSessionEventDispatcher\";\nimport { DeviceSessionRefresher } from \"./DeviceSessionRefresher\";\nimport { DeviceSessionStateHandler } from \"./DeviceSessionStateHandler\";\n\nexport type SessionConstructorArgs = {\n connectedDevice: TransportConnectedDevice;\n id?: DeviceSessionId;\n};\n\nexport type DeviceSessionRefresherOptions = {\n isRefresherDisabled: boolean;\n pollingInterval?: number;\n};\n\ntype SendApduOptions = {\n isPolling?: boolean;\n triggersDisconnection?: boolean;\n abortTimeout?: number;\n};\n\n/**\n * Represents a session with a device.\n */\nexport class DeviceSession {\n private readonly _id: DeviceSessionId;\n private readonly _connectedDevice: TransportConnectedDevice;\n private readonly _deviceState: BehaviorSubject<DeviceSessionState>;\n private readonly _managerApiService: ManagerApiService;\n private readonly _secureChannelService: SecureChannelService;\n private readonly _logger: LoggerPublisherService;\n private readonly _refresherOptions: DeviceSessionRefresherOptions;\n private _pinger: DevicePinger;\n private _deviceSessionRefresher: DeviceSessionRefresher;\n private readonly _refresherService: RefresherService;\n private readonly _intentQueueService: IntentQueueService;\n private _sessionEventDispatcher = new DeviceSessionEventDispatcher();\n private _bypassIntentQueue: boolean = false;\n\n constructor(\n { connectedDevice, id = uuidv4() }: SessionConstructorArgs,\n loggerModuleFactory: (tag: string) => LoggerPublisherService,\n managerApiService: ManagerApiService,\n secureChannelService: SecureChannelService,\n deviceSessionRefresherOptions: DeviceSessionRefresherOptions | undefined,\n intentQueueServiceFactory: (\n sessionEventDispatcher: DeviceSessionEventDispatcher,\n ) => IntentQueueService = (sessionEventDispatcher) =>\n new IntentQueueService(loggerModuleFactory, sessionEventDispatcher),\n ) {\n this._id = id;\n this._connectedDevice = connectedDevice;\n this._logger = loggerModuleFactory(\"device-session\");\n this._managerApiService = managerApiService;\n this._intentQueueService = intentQueueServiceFactory(\n this._sessionEventDispatcher,\n );\n this._secureChannelService = secureChannelService;\n this._refresherOptions = {\n ...DEVICE_SESSION_REFRESHER_DEFAULT_OPTIONS,\n ...deviceSessionRefresherOptions,\n };\n this._deviceState = new BehaviorSubject<DeviceSessionState>({\n sessionStateType: DeviceSessionStateType.Connected,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: this._connectedDevice.deviceModel.id,\n });\n\n this._pinger = new DevicePinger(\n loggerModuleFactory,\n connectedDevice,\n this._sessionEventDispatcher,\n (command, abortTimeout) => this.sendCommand(command, abortTimeout),\n );\n this._deviceSessionRefresher = new DeviceSessionRefresher(\n loggerModuleFactory,\n this._refresherOptions,\n this._sessionEventDispatcher,\n this._connectedDevice,\n );\n new DeviceSessionStateHandler(\n loggerModuleFactory,\n this._sessionEventDispatcher,\n this._connectedDevice,\n this._deviceState,\n (state) => this.setDeviceSessionState(state),\n );\n\n this._refresherService = new RefresherService(loggerModuleFactory, {\n start: () => this._deviceSessionRefresher.restartRefresher(),\n stop: () => this._deviceSessionRefresher.stopRefresher(),\n });\n }\n\n public async initialiseSession(): Promise<void> {\n try {\n if (this._refresherOptions.isRefresherDisabled) await this._pinger.ping();\n else this._deviceSessionRefresher.startRefresher();\n } catch (error) {\n this._logger.error(\"Error while initialising session\", {\n data: { error },\n });\n throw error;\n }\n }\n\n public get id(): DeviceSessionId {\n return this._id;\n }\n\n public get connectedDevice(): TransportConnectedDevice {\n return this._connectedDevice;\n }\n\n public get state(): Observable<DeviceSessionState> {\n return this._deviceState.asObservable();\n }\n\n public getDeviceSessionState(): DeviceSessionState {\n return this._deviceState.getValue();\n }\n\n public setDeviceSessionState(state: DeviceSessionState): void {\n this._deviceState.next(state);\n }\n\n public sendApdu(\n rawApdu: Uint8Array,\n options: SendApduOptions = {\n isPolling: false,\n triggersDisconnection: false,\n abortTimeout: undefined,\n },\n ): Promise<Either<DmkError, ApduResponse>> {\n // Bypass intent queue if flag is set\n if (this._bypassIntentQueue) {\n return this._unsafeInternalSendApdu(rawApdu, options);\n }\n return this._internalSendApdu(rawApdu, options);\n }\n\n private _internalSendApdu(\n rawApdu: Uint8Array,\n options: SendApduOptions,\n ): Promise<Either<DmkError, ApduResponse>> {\n const abortTimeout = options.abortTimeout;\n const beforeQueuedTimestamp = Date.now();\n const { observable, cancel } = this._intentQueueService.enqueue({\n type: \"send-apdu\",\n execute: () =>\n from(\n (async () => {\n const elapsedTime = Date.now() - beforeQueuedTimestamp;\n const result = await this._unsafeInternalSendApdu(rawApdu, {\n isPolling: options.isPolling,\n triggersDisconnection: options.triggersDisconnection,\n // Subtract the elapsed time to account for the time spent in the queue\n // to sync both observable and transport timeout\n abortTimeout: abortTimeout\n ? abortTimeout - elapsedTime\n : undefined,\n });\n return result;\n })(),\n ),\n });\n\n const timeoutObservable = abortTimeout\n ? observable.pipe(\n timeout({\n each: abortTimeout,\n with: () => {\n cancel();\n throw new SendApduTimeoutError();\n },\n }),\n )\n : observable;\n\n return lastValueFrom(timeoutObservable);\n }\n\n private async _unsafeInternalSendApdu(\n rawApdu: Uint8Array,\n options: SendApduOptions = {\n isPolling: false,\n triggersDisconnection: false,\n abortTimeout: undefined,\n },\n ): Promise<Either<DmkError, ApduResponse>> {\n this._logger.debug(`[exchange] => ${bufferToHexaString(rawApdu, false)}`);\n const result = await this._connectedDevice.sendApdu(\n rawApdu,\n options.triggersDisconnection,\n options.abortTimeout,\n );\n\n return result\n .ifRight((response: ApduResponse) => {\n this._logger.debug(\n `[exchange] <= ${bufferToHexaString(response.data, false)}${bufferToHexaString(response.statusCode, false)}`,\n );\n if (CommandUtils.isLockedDeviceResponse(response)) {\n this._sessionEventDispatcher.dispatch({\n eventName: SessionEvents.DEVICE_STATE_UPDATE_LOCKED,\n });\n } else {\n this._sessionEventDispatcher.dispatch({\n eventName: SessionEvents.DEVICE_STATE_UPDATE_CONNECTED,\n });\n }\n })\n .ifLeft(() => {\n this._sessionEventDispatcher.dispatch({\n eventName: SessionEvents.DEVICE_STATE_UPDATE_UNKNOWN,\n });\n });\n }\n\n public sendCommand<Response, Args, ErrorStatusCodes>(\n command: Command<Response, Args, ErrorStatusCodes>,\n abortTimeout?: number,\n ): Promise<CommandResult<Response, ErrorStatusCodes>> {\n this._logger.debug(`[sendCommand] ${command.name}`);\n\n // Bypass intent queue if flag is set\n if (this._bypassIntentQueue) {\n return this._unsafeInternalSendCommand(command, abortTimeout);\n }\n return this._internalSendCommand(command, abortTimeout);\n }\n\n private _internalSendCommand<Response, Args, ErrorStatusCodes>(\n command: Command<Response, Args, ErrorStatusCodes>,\n abortTimeout?: number,\n ): Promise<CommandResult<Response, ErrorStatusCodes>> {\n const beforeQueuedTimestamp = Date.now();\n const { observable, cancel } = this._intentQueueService.enqueue({\n type: \"send-command\",\n execute: () =>\n from(\n (async () => {\n const elapsedTime = Date.now() - beforeQueuedTimestamp;\n const result = await this._unsafeInternalSendCommand(\n command,\n // Subtract the elapsed time to account for the time spent in the queue\n // to sync both observable and transport timeout\n abortTimeout ? abortTimeout - elapsedTime : undefined,\n );\n return result;\n })(),\n ),\n });\n\n const timeoutObservable = abortTimeout\n ? observable.pipe(\n timeout({\n each: abortTimeout,\n with: () => {\n cancel();\n throw new SendCommandTimeoutError();\n },\n }),\n )\n : observable;\n\n return lastValueFrom(timeoutObservable);\n }\n\n private async _unsafeInternalSendCommand<Response, Args, ErrorStatusCodes>(\n command: Command<Response, Args, ErrorStatusCodes>,\n abortTimeout?: number,\n ): Promise<CommandResult<Response, ErrorStatusCodes>> {\n const apdu = command.getApdu();\n\n const response = await this._unsafeInternalSendApdu(apdu.getRawApdu(), {\n isPolling: false,\n triggersDisconnection: command.triggersDisconnection ?? false,\n abortTimeout,\n });\n\n return response.caseOf({\n Left: (err) => {\n this._logger.error(\"[sendCommand] error\", { data: { err } });\n throw err;\n },\n Right: (r) => {\n const result = command.parseResponse(\n r,\n this._connectedDevice.deviceModel.id,\n );\n this._logger.debug(\"[sendCommand] result\", { data: { result } });\n return result;\n },\n });\n }\n\n public executeDeviceAction<\n Output,\n Input,\n E extends DmkError,\n IntermediateValue extends DeviceActionIntermediateValue,\n >(\n deviceAction: DeviceAction<Output, Input, E, IntermediateValue>,\n ): ExecuteDeviceActionReturnType<Output, E, IntermediateValue> {\n // Bypass intent queue if flag is set\n if (this._bypassIntentQueue) {\n return this._unsafeInternalExecuteDeviceAction(deviceAction);\n }\n return this._internalExecuteDeviceAction(deviceAction);\n }\n\n private _internalExecuteDeviceAction<\n Output,\n Input,\n E extends DmkError,\n IntermediateValue extends DeviceActionIntermediateValue,\n >(\n deviceAction: DeviceAction<Output, Input, E, IntermediateValue>,\n ): ExecuteDeviceActionReturnType<Output, E, IntermediateValue> {\n let deviceActionCancel: (() => void) | undefined;\n\n const { observable: o, cancel: queueCancel } =\n this._intentQueueService.enqueue({\n type: \"device-action\",\n execute: () => {\n const { observable, cancel } =\n this._unsafeInternalExecuteDeviceAction(deviceAction);\n deviceActionCancel = cancel;\n return observable;\n },\n });\n\n return {\n observable: o,\n cancel: () => {\n deviceActionCancel?.();\n queueCancel();\n },\n };\n }\n\n private _unsafeInternalExecuteDeviceAction<\n Output,\n Input,\n E extends DmkError,\n IntermediateValue extends DeviceActionIntermediateValue,\n >(\n deviceAction: DeviceAction<Output, Input, E, IntermediateValue>,\n ): ExecuteDeviceActionReturnType<Output, E, IntermediateValue> {\n const { observable, cancel } = deviceAction._execute({\n sendApdu: async (apdu: Uint8Array) => this._unsafeInternalSendApdu(apdu), // note: there is no timeout handled at this stage\n sendCommand: async <Response, ErrorStatusCodes, Args>(\n command: Command<Response, ErrorStatusCodes, Args>,\n ) => this._unsafeInternalSendCommand(command), // note: there is no timeout handled at this stage\n getDeviceModel: () => this._connectedDevice.deviceModel,\n getDeviceSessionState: () => this._deviceState.getValue(),\n getDeviceSessionStateObservable: () => this.state,\n setDeviceSessionState: (state: DeviceSessionState) => {\n this.setDeviceSessionState(state);\n return this._deviceState.getValue();\n },\n getManagerApiService: () => this._managerApiService,\n getSecureChannelService: () => this._secureChannelService,\n });\n\n return {\n observable,\n cancel,\n };\n }\n\n public close(): void {\n this._updateDeviceStatus(DeviceStatus.NOT_CONNECTED);\n this._deviceState.complete();\n this._deviceSessionRefresher.stopRefresher();\n this._pinger.unsubscribe();\n }\n\n public disableRefresher(id: string): () => void {\n return this._refresherService.disableRefresher(id);\n }\n\n public _unsafeBypassIntentQueue(bypass: boolean): void {\n this._bypassIntentQueue = bypass;\n }\n\n private _updateDeviceStatus(deviceStatus: DeviceStatus): void {\n const state = this._deviceState.getValue();\n this._deviceState.next({ ...state, deviceStatus });\n }\n}\n"],
|
|
5
|
-
"mappings": "AACA,
|
|
6
|
-
"names": ["BehaviorSubject", "
|
|
4
|
+
"sourcesContent": ["import { type Either } from \"purify-ts\";\nimport { BehaviorSubject, type Observable } from \"rxjs\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nimport { type Command } from \"@api/command/Command\";\nimport { type CommandResult } from \"@api/command/model/CommandResult\";\nimport { CommandUtils } from \"@api/command/utils/CommandUtils\";\nimport { DeviceStatus } from \"@api/device/DeviceStatus\";\nimport {\n type DeviceAction,\n type DeviceActionIntermediateValue,\n type ExecuteDeviceActionReturnType,\n} from \"@api/device-action/DeviceAction\";\nimport { type ApduResponse } from \"@api/device-session/ApduResponse\";\nimport {\n type DeviceSessionState,\n DeviceSessionStateType,\n} from \"@api/device-session/DeviceSessionState\";\nimport { type DeviceSessionId } from \"@api/device-session/types\";\nimport { type DmkError } from \"@api/Error\";\nimport { bufferToHexaString } from \"@api/index\";\nimport { type LoggerPublisherService } from \"@api/logger-publisher/service/LoggerPublisherService\";\nimport { type TransportConnectedDevice } from \"@api/transport/model/TransportConnectedDevice\";\nimport { DEVICE_SESSION_REFRESHER_DEFAULT_OPTIONS } from \"@internal/device-session/data/DeviceSessionRefresherConst\";\nimport { MutexService } from \"@internal/device-session/service/MutexService\";\nimport { RefresherService } from \"@internal/device-session/service/RefresherService\";\nimport { type ManagerApiService } from \"@internal/manager-api/service/ManagerApiService\";\nimport { type SecureChannelService } from \"@internal/secure-channel/service/SecureChannelService\";\n\nimport { DevicePinger } from \"./DevicePinger\";\nimport {\n DeviceSessionEventDispatcher,\n SessionEvents,\n} from \"./DeviceSessionEventDispatcher\";\nimport { DeviceSessionRefresher } from \"./DeviceSessionRefresher\";\nimport { DeviceSessionStateHandler } from \"./DeviceSessionStateHandler\";\n\nexport type SessionConstructorArgs = {\n connectedDevice: TransportConnectedDevice;\n id?: DeviceSessionId;\n};\n\nexport type DeviceSessionRefresherOptions = {\n isRefresherDisabled: boolean;\n pollingInterval?: number;\n};\n\ntype SendApduOptions = {\n isPolling?: boolean;\n triggersDisconnection?: boolean;\n abortTimeout?: number;\n};\n\n/**\n * Represents a session with a device.\n */\nexport class DeviceSession {\n private readonly _id: DeviceSessionId;\n private readonly _connectedDevice: TransportConnectedDevice;\n private readonly _deviceState: BehaviorSubject<DeviceSessionState>;\n private readonly _managerApiService: ManagerApiService;\n private readonly _secureChannelService: SecureChannelService;\n private readonly _logger: LoggerPublisherService;\n private readonly _refresherOptions: DeviceSessionRefresherOptions;\n private _pinger: DevicePinger;\n private _deviceSessionRefresher: DeviceSessionRefresher;\n private readonly _refresherService: RefresherService;\n private _commandMutex = new MutexService();\n private _sessionEventDispatcher = new DeviceSessionEventDispatcher();\n\n constructor(\n { connectedDevice, id = uuidv4() }: SessionConstructorArgs,\n loggerModuleFactory: (tag: string) => LoggerPublisherService,\n managerApiService: ManagerApiService,\n secureChannelService: SecureChannelService,\n deviceSessionRefresherOptions: DeviceSessionRefresherOptions | undefined,\n ) {\n this._id = id;\n this._connectedDevice = connectedDevice;\n this._logger = loggerModuleFactory(\"device-session\");\n this._managerApiService = managerApiService;\n this._secureChannelService = secureChannelService;\n this._refresherOptions = {\n ...DEVICE_SESSION_REFRESHER_DEFAULT_OPTIONS,\n ...deviceSessionRefresherOptions,\n };\n this._deviceState = new BehaviorSubject<DeviceSessionState>({\n sessionStateType: DeviceSessionStateType.Connected,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: this._connectedDevice.deviceModel.id,\n });\n\n this._pinger = new DevicePinger(\n loggerModuleFactory,\n connectedDevice,\n this._sessionEventDispatcher,\n (command, abortTimeout) => this.sendCommand(command, abortTimeout),\n );\n this._deviceSessionRefresher = new DeviceSessionRefresher(\n loggerModuleFactory,\n this._refresherOptions,\n this._sessionEventDispatcher,\n this._connectedDevice,\n );\n new DeviceSessionStateHandler(\n loggerModuleFactory,\n this._sessionEventDispatcher,\n this._connectedDevice,\n this._deviceState,\n (state) => this.setDeviceSessionState(state),\n );\n\n this._refresherService = new RefresherService(loggerModuleFactory, {\n start: () => this._deviceSessionRefresher.restartRefresher(),\n stop: () => this._deviceSessionRefresher.stopRefresher(),\n });\n }\n\n public async initialiseSession(): Promise<void> {\n try {\n await this._pinger.ping();\n } catch (error) {\n this._logger.error(\"Error while initialising session\", {\n data: { error },\n });\n throw error;\n } finally {\n if (!this._refresherOptions.isRefresherDisabled) {\n this._deviceSessionRefresher.startRefresher();\n }\n }\n }\n\n public get id(): DeviceSessionId {\n return this._id;\n }\n\n public get connectedDevice(): TransportConnectedDevice {\n return this._connectedDevice;\n }\n\n public get state(): Observable<DeviceSessionState> {\n return this._deviceState.asObservable();\n }\n\n public getDeviceSessionState(): DeviceSessionState {\n return this._deviceState.getValue();\n }\n\n public setDeviceSessionState(state: DeviceSessionState): void {\n this._deviceState.next(state);\n }\n\n public async sendApdu(\n rawApdu: Uint8Array,\n options: SendApduOptions = {\n isPolling: false,\n triggersDisconnection: false,\n abortTimeout: undefined,\n },\n ): Promise<Either<DmkError, ApduResponse>> {\n const release = await this._commandMutex.lock();\n\n try {\n this._sessionEventDispatcher.dispatch({\n eventName: SessionEvents.DEVICE_STATE_UPDATE_BUSY,\n });\n\n this._logger.debug(`[exchange] => ${bufferToHexaString(rawApdu, false)}`);\n const result = await this._connectedDevice.sendApdu(\n rawApdu,\n options.triggersDisconnection,\n options.abortTimeout,\n );\n\n result\n .ifRight((response: ApduResponse) => {\n this._logger.debug(\n `[exchange] <= ${bufferToHexaString(response.data, false)}${bufferToHexaString(response.statusCode, false)}`,\n );\n if (CommandUtils.isLockedDeviceResponse(response)) {\n this._sessionEventDispatcher.dispatch({\n eventName: SessionEvents.DEVICE_STATE_UPDATE_LOCKED,\n });\n } else {\n this._sessionEventDispatcher.dispatch({\n eventName: SessionEvents.DEVICE_STATE_UPDATE_CONNECTED,\n });\n }\n })\n .ifLeft(() => {\n this._sessionEventDispatcher.dispatch({\n eventName: SessionEvents.DEVICE_STATE_UPDATE_CONNECTED,\n });\n });\n return result;\n } finally {\n release();\n }\n }\n\n public async sendCommand<Response, Args, ErrorStatusCodes>(\n command: Command<Response, Args, ErrorStatusCodes>,\n abortTimeout?: number,\n ): Promise<CommandResult<Response, ErrorStatusCodes>> {\n this._logger.debug(`[sendCommand] ${command.name}`);\n const apdu = command.getApdu();\n\n const response = await this.sendApdu(apdu.getRawApdu(), {\n isPolling: false,\n triggersDisconnection: command.triggersDisconnection ?? false,\n abortTimeout,\n });\n\n return response.caseOf({\n Left: (err) => {\n this._logger.error(\"[sendCommand] error\", { data: { err } });\n throw err;\n },\n Right: (r) => {\n const result = command.parseResponse(\n r,\n this._connectedDevice.deviceModel.id,\n );\n this._logger.debug(\"[sendCommand] result\", { data: { result } });\n return result;\n },\n });\n }\n\n public executeDeviceAction<\n Output,\n Input,\n E extends DmkError,\n IntermediateValue extends DeviceActionIntermediateValue,\n >(\n deviceAction: DeviceAction<Output, Input, E, IntermediateValue>,\n ): ExecuteDeviceActionReturnType<Output, E, IntermediateValue> {\n const { observable, cancel } = deviceAction._execute({\n sendApdu: async (apdu: Uint8Array) => this.sendApdu(apdu),\n sendCommand: async <Response, ErrorStatusCodes, Args>(\n command: Command<Response, ErrorStatusCodes, Args>,\n abortTimeout?: number,\n ) => this.sendCommand(command, abortTimeout),\n getDeviceModel: () => this._connectedDevice.deviceModel,\n getDeviceSessionState: () => this._deviceState.getValue(),\n getDeviceSessionStateObservable: () => this.state,\n setDeviceSessionState: (state: DeviceSessionState) => {\n this.setDeviceSessionState(state);\n return this._deviceState.getValue();\n },\n disableRefresher: (blockerId: string) =>\n this._refresherService.disableRefresher(blockerId),\n getManagerApiService: () => this._managerApiService,\n getSecureChannelService: () => this._secureChannelService,\n });\n return { observable, cancel };\n }\n\n public close(): void {\n this._updateDeviceStatus(DeviceStatus.NOT_CONNECTED);\n this._deviceState.complete();\n this._deviceSessionRefresher.stopRefresher();\n }\n\n public disableRefresher(id: string): () => void {\n return this._refresherService.disableRefresher(id);\n }\n\n private _updateDeviceStatus(deviceStatus: DeviceStatus): void {\n const state = this._deviceState.getValue();\n this._deviceState.next({ ...state, deviceStatus });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["BehaviorSubject", "uuidv4", "CommandUtils", "DeviceStatus", "DeviceSessionStateType", "bufferToHexaString", "DEVICE_SESSION_REFRESHER_DEFAULT_OPTIONS", "MutexService", "RefresherService", "DevicePinger", "DeviceSessionEventDispatcher", "SessionEvents", "DeviceSessionRefresher", "DeviceSessionStateHandler", "DeviceSession", "connectedDevice", "id", "loggerModuleFactory", "managerApiService", "secureChannelService", "deviceSessionRefresherOptions", "command", "abortTimeout", "state", "error", "rawApdu", "options", "release", "result", "response", "apdu", "err", "r", "deviceAction", "observable", "cancel", "blockerId", "deviceStatus"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Subject as n}from"rxjs";var t=(
|
|
1
|
+
import{Subject as n}from"rxjs";var t=(e=>(e.NEW_STATE="NEW_STATE",e.REFRESH_NEEDED="REFRESH_NEEDED",e.COMMAND_SUCCEEDED="COMMAND_SUCCEEDED",e.DEVICE_STATE_UPDATE_BUSY="DEVICE_STATE_UPDATE_BUSY",e.DEVICE_STATE_UPDATE_LOCKED="DEVICE_STATE_UPDATE_LOCKED",e.DEVICE_STATE_UPDATE_CONNECTED="DEVICE_STATE_UPDATE_CONNECTED",e))(t||{});class s{_eventEmitter=new n;listen(){return this._eventEmitter.asObservable()}dispatch(E){this._eventEmitter.next(E)}}export{s as DeviceSessionEventDispatcher,t as SessionEvents};
|
|
2
2
|
//# sourceMappingURL=DeviceSessionEventDispatcher.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/device-session/model/DeviceSessionEventDispatcher.ts"],
|
|
4
|
-
"sourcesContent": ["import { type Observable, Subject } from \"rxjs\";\n\nimport { type GetAppAndVersionResponse } from \"@api/index\";\nimport { type CommandResult } from \"@api/types\";\n\nexport enum SessionEvents {\n NEW_STATE = \"NEW_STATE\",\n REFRESH_NEEDED = \"REFRESH_NEEDED\",\n COMMAND_SUCCEEDED = \"COMMAND_SUCCEEDED\",\n DEVICE_STATE_UPDATE_BUSY = \"DEVICE_STATE_UPDATE_BUSY\",\n DEVICE_STATE_UPDATE_LOCKED = \"DEVICE_STATE_UPDATE_LOCKED\",\n DEVICE_STATE_UPDATE_CONNECTED = \"DEVICE_STATE_UPDATE_CONNECTED\",\n
|
|
5
|
-
"mappings": "AAAA,OAA0B,WAAAA,MAAe,OAKlC,IAAKC,OACVA,EAAA,UAAY,YACZA,EAAA,eAAiB,iBACjBA,EAAA,kBAAoB,oBACpBA,EAAA,yBAA2B,2BAC3BA,EAAA,2BAA6B,6BAC7BA,EAAA,8BAAgC,
|
|
4
|
+
"sourcesContent": ["import { type Observable, Subject } from \"rxjs\";\n\nimport { type GetAppAndVersionResponse } from \"@api/index\";\nimport { type CommandResult } from \"@api/types\";\n\nexport enum SessionEvents {\n NEW_STATE = \"NEW_STATE\",\n REFRESH_NEEDED = \"REFRESH_NEEDED\",\n COMMAND_SUCCEEDED = \"COMMAND_SUCCEEDED\",\n DEVICE_STATE_UPDATE_BUSY = \"DEVICE_STATE_UPDATE_BUSY\",\n DEVICE_STATE_UPDATE_LOCKED = \"DEVICE_STATE_UPDATE_LOCKED\",\n DEVICE_STATE_UPDATE_CONNECTED = \"DEVICE_STATE_UPDATE_CONNECTED\",\n}\n\ninterface SessionEventPayloads {\n [SessionEvents.NEW_STATE]: undefined;\n [SessionEvents.REFRESH_NEEDED]: undefined;\n [SessionEvents.DEVICE_STATE_UPDATE_BUSY]: undefined;\n [SessionEvents.DEVICE_STATE_UPDATE_LOCKED]: undefined;\n [SessionEvents.DEVICE_STATE_UPDATE_CONNECTED]: undefined;\n [SessionEvents.COMMAND_SUCCEEDED]: CommandResult<GetAppAndVersionResponse>;\n}\n\nexport type NewEvent = {\n [K in SessionEvents]: SessionEventPayloads[K] extends undefined\n ? { eventName: K; eventData?: undefined }\n : { eventName: K; eventData: SessionEventPayloads[K] };\n}[SessionEvents];\n\nexport class DeviceSessionEventDispatcher {\n private _eventEmitter: Subject<NewEvent> = new Subject();\n\n public listen(): Observable<NewEvent> {\n return this._eventEmitter.asObservable();\n }\n\n public dispatch(event: NewEvent): void {\n this._eventEmitter.next(event);\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAA0B,WAAAA,MAAe,OAKlC,IAAKC,OACVA,EAAA,UAAY,YACZA,EAAA,eAAiB,iBACjBA,EAAA,kBAAoB,oBACpBA,EAAA,yBAA2B,2BAC3BA,EAAA,2BAA6B,6BAC7BA,EAAA,8BAAgC,gCANtBA,OAAA,IAwBL,MAAMC,CAA6B,CAChC,cAAmC,IAAIF,EAExC,QAA+B,CACpC,OAAO,KAAK,cAAc,aAAa,CACzC,CAEO,SAASG,EAAuB,CACrC,KAAK,cAAc,KAAKA,CAAK,CAC/B,CACF",
|
|
6
6
|
"names": ["Subject", "SessionEvents", "DeviceSessionEventDispatcher", "event"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{timer as n}from"rxjs";import{DeviceModelId as c}from"../../../api/device/DeviceModel";import{DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL as t,DEVICE_SESSION_REFRESHER_POLLING_INTERVAL as o}from"../../device-session/data/DeviceSessionRefresherConst";import{SessionEvents as h}from"../../device-session/model/DeviceSessionEventDispatcher";class d{constructor(i,s,e,r){this._sessionEventDispatcher=e;this._refresherOptions=s,this._logger=i("device-session-refresher"),this._connectedDeviceID=r.deviceModel.id}_refresherSubscription;_refresherOptions;_logger;_connectedDeviceID;startRefresher(){if(this._refresherOptions.isRefresherDisabled)return;const i=this.getValidPollingInterval(this._refresherOptions,this._logger)*2;this._refresherSubscription=n(0,i).subscribe(()=>{this._sessionEventDispatcher.dispatch({eventName:h.REFRESH_NEEDED})})}stopRefresher(){this._refresherSubscription&&(this._refresherSubscription.unsubscribe(),this._refresherSubscription=void 0,this._logger.info("Refresher stopped."))}restartRefresher(){this.stopRefresher(),this.startRefresher(),this._logger.info("Refresher restarted.")}destroy(){this.stopRefresher()}getValidPollingInterval=(i,s)=>{const{pollingInterval:e}=i;switch(this._connectedDeviceID){case c.NANO_S:{const r=o*2;return e!==void 0&&e<r?(s.warn(`Polling interval of ${e} is too low, setting to minimum as ${r}`),r):e??r}default:return e!==void 0&&e<t?(s.warn(`Polling interval of ${e} is too low, setting to minimum as ${t}`),t):e??o}}}export{d as DeviceSessionRefresher};
|
|
2
2
|
//# sourceMappingURL=DeviceSessionRefresher.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/device-session/model/DeviceSessionRefresher.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "AAAA,
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["import { type Subscription, timer } from \"rxjs\";\n\nimport { DeviceModelId } from \"@api/device/DeviceModel\";\nimport { type TransportConnectedDevice } from \"@api/transport/model/TransportConnectedDevice\";\nimport { type LoggerPublisherService } from \"@api/types\";\nimport {\n DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL,\n DEVICE_SESSION_REFRESHER_POLLING_INTERVAL,\n} from \"@internal/device-session/data/DeviceSessionRefresherConst\";\nimport {\n type DeviceSessionEventDispatcher,\n SessionEvents,\n} from \"@internal/device-session/model/DeviceSessionEventDispatcher\";\n\nexport interface DeviceSessionRefresherOptions {\n isRefresherDisabled: boolean;\n pollingInterval?: number;\n}\n\nexport class DeviceSessionRefresher {\n private _refresherSubscription!: Subscription | undefined;\n private _refresherOptions: DeviceSessionRefresherOptions;\n private readonly _logger: LoggerPublisherService;\n private _connectedDeviceID: DeviceModelId;\n\n constructor(\n loggerModuleFactory: (tag: string) => LoggerPublisherService,\n refresherOptions: DeviceSessionRefresherOptions,\n private _sessionEventDispatcher: DeviceSessionEventDispatcher,\n connectedDevice: TransportConnectedDevice,\n ) {\n this._refresherOptions = refresherOptions;\n this._logger = loggerModuleFactory(\"device-session-refresher\");\n this._connectedDeviceID = connectedDevice.deviceModel.id;\n }\n\n public startRefresher(): void {\n if (this._refresherOptions.isRefresherDisabled) return;\n\n const pollingInterval =\n this.getValidPollingInterval(this._refresherOptions, this._logger) * 2;\n\n this._refresherSubscription = timer(0, pollingInterval).subscribe(() => {\n this._sessionEventDispatcher.dispatch({\n eventName: SessionEvents.REFRESH_NEEDED,\n });\n });\n }\n\n public stopRefresher(): void {\n if (this._refresherSubscription) {\n this._refresherSubscription.unsubscribe();\n this._refresherSubscription = undefined;\n this._logger.info(\"Refresher stopped.\");\n }\n }\n\n public restartRefresher(): void {\n this.stopRefresher();\n this.startRefresher();\n this._logger.info(\"Refresher restarted.\");\n }\n\n public destroy(): void {\n this.stopRefresher();\n }\n\n private getValidPollingInterval = (\n refresherOptions: DeviceSessionRefresherOptions,\n logger: LoggerPublisherService,\n ): number => {\n const { pollingInterval } = refresherOptions;\n switch (this._connectedDeviceID) {\n case DeviceModelId.NANO_S: {\n const defaultNanoPollingInterval =\n DEVICE_SESSION_REFRESHER_POLLING_INTERVAL * 2;\n if (\n pollingInterval !== undefined &&\n pollingInterval < defaultNanoPollingInterval\n ) {\n logger.warn(\n `Polling interval of ${pollingInterval} is too low, setting to minimum as ${defaultNanoPollingInterval}`,\n );\n return defaultNanoPollingInterval;\n }\n return pollingInterval ?? defaultNanoPollingInterval;\n }\n default:\n if (\n pollingInterval !== undefined &&\n pollingInterval < DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL\n ) {\n logger.warn(\n `Polling interval of ${pollingInterval} is too low, setting to minimum as ${DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL}`,\n );\n return DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL;\n }\n\n return pollingInterval ?? DEVICE_SESSION_REFRESHER_POLLING_INTERVAL;\n }\n };\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAA4B,SAAAA,MAAa,OAEzC,OAAS,iBAAAC,MAAqB,0BAG9B,OACE,qDAAAC,EACA,6CAAAC,MACK,4DACP,OAEE,iBAAAC,MACK,8DAOA,MAAMC,CAAuB,CAMlC,YACEC,EACAC,EACQC,EACRC,EACA,CAFQ,6BAAAD,EAGR,KAAK,kBAAoBD,EACzB,KAAK,QAAUD,EAAoB,0BAA0B,EAC7D,KAAK,mBAAqBG,EAAgB,YAAY,EACxD,CAdQ,uBACA,kBACS,QACT,mBAaD,gBAAuB,CAC5B,GAAI,KAAK,kBAAkB,oBAAqB,OAEhD,MAAMC,EACJ,KAAK,wBAAwB,KAAK,kBAAmB,KAAK,OAAO,EAAI,EAEvE,KAAK,uBAAyBV,EAAM,EAAGU,CAAe,EAAE,UAAU,IAAM,CACtE,KAAK,wBAAwB,SAAS,CACpC,UAAWN,EAAc,cAC3B,CAAC,CACH,CAAC,CACH,CAEO,eAAsB,CACvB,KAAK,yBACP,KAAK,uBAAuB,YAAY,EACxC,KAAK,uBAAyB,OAC9B,KAAK,QAAQ,KAAK,oBAAoB,EAE1C,CAEO,kBAAyB,CAC9B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,QAAQ,KAAK,sBAAsB,CAC1C,CAEO,SAAgB,CACrB,KAAK,cAAc,CACrB,CAEQ,wBAA0B,CAChCG,EACAI,IACW,CACX,KAAM,CAAE,gBAAAD,CAAgB,EAAIH,EAC5B,OAAQ,KAAK,mBAAoB,CAC/B,KAAKN,EAAc,OAAQ,CACzB,MAAMW,EACJT,EAA4C,EAC9C,OACEO,IAAoB,QACpBA,EAAkBE,GAElBD,EAAO,KACL,uBAAuBD,CAAe,sCAAsCE,CAA0B,EACxG,EACOA,GAEFF,GAAmBE,CAC5B,CACA,QACE,OACEF,IAAoB,QACpBA,EAAkBR,GAElBS,EAAO,KACL,uBAAuBD,CAAe,sCAAsCR,CAAiD,EAC/H,EACOA,GAGFQ,GAAmBP,CAC9B,CACF,CACF",
|
|
6
|
+
"names": ["timer", "DeviceModelId", "DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL", "DEVICE_SESSION_REFRESHER_POLLING_INTERVAL", "SessionEvents", "DeviceSessionRefresher", "loggerModuleFactory", "refresherOptions", "_sessionEventDispatcher", "connectedDevice", "pollingInterval", "logger", "defaultNanoPollingInterval"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Subject as
|
|
1
|
+
import{Subject as u}from"rxjs";import{afterEach as D,beforeEach as S,describe as y,expect as n,it as l,vi as t}from"vitest";import{DeviceModelId as h}from"../../../api/device/DeviceModel";import{DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL as p,DEVICE_SESSION_REFRESHER_POLLING_INTERVAL as E}from"../../device-session/data/DeviceSessionRefresherConst";import{SessionEvents as w}from"../../device-session/model/DeviceSessionEventDispatcher";import{DeviceSessionRefresher as c}from"./DeviceSessionRefresher";y("DeviceSessionRefresher",()=>{let d,s,o;const f={deviceModel:{id:h.FLEX}},m={deviceModel:{id:h.NANO_S}},i=t.fn(()=>o);let e;S(()=>{t.useFakeTimers(),d=new u,s={listen:()=>d.asObservable(),dispatch:t.fn()},o={info:t.fn(),warn:t.fn(),error:t.fn(),debug:t.fn(),subscribers:[]}}),D(()=>{e?.destroy(),t.useRealTimers(),t.restoreAllMocks()}),l("should not start refresher if disabled",()=>{const r={isRefresherDisabled:!0,pollingInterval:1e3};e=new c(i,r,s,f),e.startRefresher(),t.advanceTimersByTime(2e3),n(s.dispatch).not.toHaveBeenCalled()}),l("should warn and use minimum polling interval for default device when provided interval is too low",()=>{const r=p-100,a={isRefresherDisabled:!1,pollingInterval:r};e=new c(i,a,s,f),e.startRefresher();const v=`Polling interval of ${r} is too low, setting to minimum as ${p}`;n(o.warn).toHaveBeenCalledWith(v)}),l("should warn and use minimum polling interval for NANO_S device when provided interval is too low",()=>{const r=E*2,a=r-100,v={isRefresherDisabled:!1,pollingInterval:a};e=new c(i,v,s,m),e.startRefresher();const R=`Polling interval of ${a} is too low, setting to minimum as ${r}`;n(o.warn).toHaveBeenCalledWith(R)}),l("should not warn when provided polling interval is valid for default device",()=>{const a={isRefresherDisabled:!1,pollingInterval:p+100};e=new c(i,a,s,f),e.startRefresher(),n(o.warn).not.toHaveBeenCalled()}),l("should dispatch refresh event on timer ticks",()=>{const r=p+100,a={isRefresherDisabled:!1,pollingInterval:r};e=new c(i,a,s,f),e.startRefresher();const v=r*2;t.advanceTimersByTime(v*3),n(s.dispatch.mock.calls.length).toBe(4),n(s.dispatch.mock.calls[0][0]).toEqual({eventName:w.REFRESH_NEEDED})}),l("should stop refresher",()=>{const r={isRefresherDisabled:!1,pollingInterval:1e3};e=new c(i,r,s,f),e.startRefresher(),s.dispatch.mockClear(),e.stopRefresher(),t.advanceTimersByTime(2e3),n(s.dispatch).not.toHaveBeenCalled(),n(o.info).toHaveBeenCalledWith("Refresher stopped.")}),l("should restart refresher",()=>{const r={isRefresherDisabled:!1,pollingInterval:1e3};e=new c(i,r,s,f),e.startRefresher(),s.dispatch.mockClear(),t.clearAllTimers(),e.restartRefresher(),n(o.info).toHaveBeenCalledWith("Refresher stopped."),n(o.info).toHaveBeenCalledWith("Refresher restarted."),t.advanceTimersByTime(2e3),n(s.dispatch.mock.calls.length).toBeGreaterThan(0)}),l("should destroy refresher",()=>{const r={isRefresherDisabled:!1,pollingInterval:1e3};e=new c(i,r,s,f),e.startRefresher(),e.destroy(),t.advanceTimersByTime(2e3),n(s.dispatch).not.toHaveBeenCalled()})});
|
|
2
2
|
//# sourceMappingURL=DeviceSessionRefresher.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/device-session/model/DeviceSessionRefresher.test.ts"],
|
|
4
|
-
"sourcesContent": ["import { Subject } from \"rxjs\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { DeviceModelId } from \"@api/device/DeviceModel\";\nimport { type TransportConnectedDevice } from \"@api/transport/model/TransportConnectedDevice\";\nimport type { LoggerPublisherService } from \"@api/types\";\nimport {\n DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL,\n DEVICE_SESSION_REFRESHER_POLLING_INTERVAL,\n} from \"@internal/device-session/data/DeviceSessionRefresherConst\";\nimport type {\n DeviceSessionEventDispatcher,\n NewEvent,\n} from \"@internal/device-session/model/DeviceSessionEventDispatcher\";\nimport { SessionEvents } from \"@internal/device-session/model/DeviceSessionEventDispatcher\";\n\nimport {\n DeviceSessionRefresher,\n type DeviceSessionRefresherOptions,\n} from \"./DeviceSessionRefresher\";\n\ndescribe(\"DeviceSessionRefresher\", () => {\n let subject: Subject<NewEvent>;\n let mockSessionEventDispatcher: DeviceSessionEventDispatcher;\n let mockLogger: LoggerPublisherService & {\n info: ReturnType<typeof vi.fn>;\n warn: ReturnType<typeof vi.fn>;\n error: ReturnType<typeof vi.fn>;\n debug: ReturnType<typeof vi.fn>;\n subscribers?: unknown[];\n };\n\n const stubDefaultDevice = {\n deviceModel: {\n id: DeviceModelId.FLEX,\n },\n } as TransportConnectedDevice;\n\n const stubNanoSDevice = {\n deviceModel: {\n id: DeviceModelId.NANO_S,\n },\n } as TransportConnectedDevice;\n\n const mockedLoggerModuleFactory = vi.fn(() => mockLogger);\n let refresher: DeviceSessionRefresher;\n\n beforeEach(() => {\n vi.useFakeTimers();\n subject = new Subject<NewEvent>();\n mockSessionEventDispatcher = {\n listen: () => subject.asObservable(),\n dispatch: vi.fn(),\n } as unknown as DeviceSessionEventDispatcher;\n mockLogger = {\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n debug: vi.fn(),\n subscribers: [],\n };\n });\n\n afterEach(() => {\n refresher?.
|
|
5
|
-
"mappings": "AAAA,OAAS,WAAAA,MAAe,OACxB,OAAS,aAAAC,EAAW,cAAAC,EAAY,YAAAC,EAAU,UAAAC,EAAQ,MAAAC,EAAI,MAAAC,MAAU,SAEhE,OAAS,iBAAAC,MAAqB,0BAG9B,OACE,qDAAAC,EACA,6CAAAC,MACK,4DAKP,OAAS,iBAAAC,MAAqB,8DAE9B,OACE,0BAAAC,MAEK,2BAEPR,EAAS,yBAA0B,IAAM,CACvC,IAAIS,EACAC,EACAC,EAQJ,MAAMC,EAAoB,CACxB,YAAa,CACX,GAAIR,EAAc,IACpB,CACF,EAEMS,EAAkB,CACtB,YAAa,CACX,GAAIT,EAAc,MACpB,CACF,EAEMU,EAA4BX,EAAG,GAAG,IAAMQ,CAAU,EACxD,IAAII,EAEJhB,EAAW,IAAM,CACfI,EAAG,cAAc,EACjBM,EAAU,IAAIZ,EACda,EAA6B,CAC3B,OAAQ,IAAMD,EAAQ,aAAa,EACnC,SAAUN,EAAG,GAAG,CAClB,EACAQ,EAAa,CACX,KAAMR,EAAG,GAAG,EACZ,KAAMA,EAAG,GAAG,EACZ,MAAOA,EAAG,GAAG,EACb,MAAOA,EAAG,GAAG,EACb,YAAa,CAAC,CAChB,CACF,CAAC,EAEDL,EAAU,IAAM,CACdiB,GAAW,
|
|
4
|
+
"sourcesContent": ["import { Subject } from \"rxjs\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { DeviceModelId } from \"@api/device/DeviceModel\";\nimport { type TransportConnectedDevice } from \"@api/transport/model/TransportConnectedDevice\";\nimport type { LoggerPublisherService } from \"@api/types\";\nimport {\n DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL,\n DEVICE_SESSION_REFRESHER_POLLING_INTERVAL,\n} from \"@internal/device-session/data/DeviceSessionRefresherConst\";\nimport type {\n DeviceSessionEventDispatcher,\n NewEvent,\n} from \"@internal/device-session/model/DeviceSessionEventDispatcher\";\nimport { SessionEvents } from \"@internal/device-session/model/DeviceSessionEventDispatcher\";\n\nimport {\n DeviceSessionRefresher,\n type DeviceSessionRefresherOptions,\n} from \"./DeviceSessionRefresher\";\n\ndescribe(\"DeviceSessionRefresher\", () => {\n let subject: Subject<NewEvent>;\n let mockSessionEventDispatcher: DeviceSessionEventDispatcher;\n let mockLogger: LoggerPublisherService & {\n info: ReturnType<typeof vi.fn>;\n warn: ReturnType<typeof vi.fn>;\n error: ReturnType<typeof vi.fn>;\n debug: ReturnType<typeof vi.fn>;\n subscribers?: unknown[];\n };\n\n const stubDefaultDevice = {\n deviceModel: {\n id: DeviceModelId.FLEX,\n },\n } as TransportConnectedDevice;\n\n const stubNanoSDevice = {\n deviceModel: {\n id: DeviceModelId.NANO_S,\n },\n } as TransportConnectedDevice;\n\n const mockedLoggerModuleFactory = vi.fn(() => mockLogger);\n let refresher: DeviceSessionRefresher;\n\n beforeEach(() => {\n vi.useFakeTimers();\n subject = new Subject<NewEvent>();\n mockSessionEventDispatcher = {\n listen: () => subject.asObservable(),\n dispatch: vi.fn(),\n } as unknown as DeviceSessionEventDispatcher;\n mockLogger = {\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n debug: vi.fn(),\n subscribers: [],\n };\n });\n\n afterEach(() => {\n refresher?.destroy();\n vi.useRealTimers();\n vi.restoreAllMocks();\n });\n\n it(\"should not start refresher if disabled\", () => {\n const options: DeviceSessionRefresherOptions = {\n isRefresherDisabled: true,\n pollingInterval: 1000,\n };\n\n refresher = new DeviceSessionRefresher(\n mockedLoggerModuleFactory,\n options,\n mockSessionEventDispatcher,\n stubDefaultDevice,\n );\n refresher.startRefresher();\n vi.advanceTimersByTime(2000);\n\n expect(mockSessionEventDispatcher.dispatch).not.toHaveBeenCalled();\n });\n\n it(\"should warn and use minimum polling interval for default device when provided interval is too low\", () => {\n const lowInterval = DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL - 100;\n const options: DeviceSessionRefresherOptions = {\n isRefresherDisabled: false,\n pollingInterval: lowInterval,\n };\n\n refresher = new DeviceSessionRefresher(\n mockedLoggerModuleFactory,\n options,\n mockSessionEventDispatcher,\n stubDefaultDevice,\n );\n refresher.startRefresher();\n\n const expectedMessage = `Polling interval of ${lowInterval} is too low, setting to minimum as ${DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL}`;\n expect(mockLogger.warn).toHaveBeenCalledWith(expectedMessage);\n });\n\n it(\"should warn and use minimum polling interval for NANO_S device when provided interval is too low\", () => {\n const defaultNanoPollingInterval =\n DEVICE_SESSION_REFRESHER_POLLING_INTERVAL * 2;\n const lowInterval = defaultNanoPollingInterval - 100;\n const options: DeviceSessionRefresherOptions = {\n isRefresherDisabled: false,\n pollingInterval: lowInterval,\n };\n\n refresher = new DeviceSessionRefresher(\n mockedLoggerModuleFactory,\n options,\n mockSessionEventDispatcher,\n stubNanoSDevice,\n );\n refresher.startRefresher();\n\n const expectedMessage = `Polling interval of ${lowInterval} is too low, setting to minimum as ${defaultNanoPollingInterval}`;\n expect(mockLogger.warn).toHaveBeenCalledWith(expectedMessage);\n });\n\n it(\"should not warn when provided polling interval is valid for default device\", () => {\n const validInterval =\n DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL + 100;\n const options: DeviceSessionRefresherOptions = {\n isRefresherDisabled: false,\n pollingInterval: validInterval,\n };\n\n refresher = new DeviceSessionRefresher(\n mockedLoggerModuleFactory,\n options,\n mockSessionEventDispatcher,\n stubDefaultDevice,\n );\n refresher.startRefresher();\n\n expect(mockLogger.warn).not.toHaveBeenCalled();\n });\n\n it(\"should dispatch refresh event on timer ticks\", () => {\n const validInterval =\n DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL + 100;\n const options: DeviceSessionRefresherOptions = {\n isRefresherDisabled: false,\n pollingInterval: validInterval,\n };\n\n refresher = new DeviceSessionRefresher(\n mockedLoggerModuleFactory,\n options,\n mockSessionEventDispatcher,\n stubDefaultDevice,\n );\n refresher.startRefresher();\n\n const timerInterval = validInterval * 2;\n\n vi.advanceTimersByTime(timerInterval * 3);\n\n expect(\n (mockSessionEventDispatcher.dispatch as ReturnType<typeof vi.fn>).mock\n .calls.length,\n ).toBe(4);\n expect(\n (mockSessionEventDispatcher.dispatch as ReturnType<typeof vi.fn>).mock\n .calls[0]![0],\n ).toEqual({\n eventName: SessionEvents.REFRESH_NEEDED,\n });\n });\n\n it(\"should stop refresher\", () => {\n const options: DeviceSessionRefresherOptions = {\n isRefresherDisabled: false,\n pollingInterval: 1000,\n };\n refresher = new DeviceSessionRefresher(\n mockedLoggerModuleFactory,\n options,\n mockSessionEventDispatcher,\n stubDefaultDevice,\n );\n refresher.startRefresher();\n (\n mockSessionEventDispatcher.dispatch as ReturnType<typeof vi.fn>\n ).mockClear();\n\n refresher.stopRefresher();\n vi.advanceTimersByTime(2000);\n\n expect(mockSessionEventDispatcher.dispatch).not.toHaveBeenCalled();\n expect(mockLogger.info).toHaveBeenCalledWith(\"Refresher stopped.\");\n });\n\n it(\"should restart refresher\", () => {\n const options: DeviceSessionRefresherOptions = {\n isRefresherDisabled: false,\n pollingInterval: 1000,\n };\n refresher = new DeviceSessionRefresher(\n mockedLoggerModuleFactory,\n options,\n mockSessionEventDispatcher,\n stubDefaultDevice,\n );\n refresher.startRefresher();\n (\n mockSessionEventDispatcher.dispatch as ReturnType<typeof vi.fn>\n ).mockClear();\n vi.clearAllTimers();\n\n refresher.restartRefresher();\n expect(mockLogger.info).toHaveBeenCalledWith(\"Refresher stopped.\");\n expect(mockLogger.info).toHaveBeenCalledWith(\"Refresher restarted.\");\n\n vi.advanceTimersByTime(2000);\n expect(\n (mockSessionEventDispatcher.dispatch as ReturnType<typeof vi.fn>).mock\n .calls.length,\n ).toBeGreaterThan(0);\n });\n\n it(\"should destroy refresher\", () => {\n const options: DeviceSessionRefresherOptions = {\n isRefresherDisabled: false,\n pollingInterval: 1000,\n };\n refresher = new DeviceSessionRefresher(\n mockedLoggerModuleFactory,\n options,\n mockSessionEventDispatcher,\n stubDefaultDevice,\n );\n refresher.startRefresher();\n\n refresher.destroy();\n vi.advanceTimersByTime(2000);\n\n expect(mockSessionEventDispatcher.dispatch).not.toHaveBeenCalled();\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["Subject", "afterEach", "beforeEach", "describe", "expect", "it", "vi", "DeviceModelId", "DEVICE_SESSION_REFRESHER_MINIMUM_POLLING_INTERVAL", "DEVICE_SESSION_REFRESHER_POLLING_INTERVAL", "SessionEvents", "DeviceSessionRefresher", "subject", "mockSessionEventDispatcher", "mockLogger", "stubDefaultDevice", "stubNanoSDevice", "mockedLoggerModuleFactory", "refresher", "options", "lowInterval", "expectedMessage", "defaultNanoPollingInterval", "validInterval", "timerInterval"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{DeviceSessionStateType as o,DeviceStatus as i,isSuccessCommandResult as v}from"../../../api/index";import{SessionEvents as s}from"../../device-session/model/DeviceSessionEventDispatcher";class
|
|
1
|
+
import{DeviceSessionStateType as o,DeviceStatus as i,isSuccessCommandResult as v}from"../../../api/index";import{SessionEvents as s}from"../../device-session/model/DeviceSessionEventDispatcher";class d{constructor(e,n,a,c,r){this._sessionEventDispatcher=n;this._connectedDevice=a;this._deviceState=c;this.setDeviceSessionState=r;this._subscription=this._sessionEventDispatcher.listen().subscribe(t=>this.mapEventAction(t)),this._logger=e("device-session-state-handler")}_subscription;_logger;_updateDeviceState(e){const n=this._parseDeviceStatus(e);if(n){const{sessionStateType:a,deviceStatus:c,currentApp:r}=n,t=this._deviceState.getValue();t.sessionStateType===o.Connected?this.setDeviceSessionState({sessionStateType:a,deviceStatus:c,deviceModelId:this._connectedDevice.deviceModel.id,currentApp:r,installedApps:[],isSecureConnectionAllowed:!1}):this.setDeviceSessionState({...t,sessionStateType:a,deviceStatus:c,deviceModelId:this._connectedDevice.deviceModel.id,currentApp:r})}}mapEventAction=e=>{switch(e.eventName){case s.COMMAND_SUCCEEDED:return this._updateDeviceState(e.eventData);case s.DEVICE_STATE_UPDATE_BUSY:return this.setDeviceSessionState({...this._deviceState.getValue(),deviceStatus:i.BUSY});case s.DEVICE_STATE_UPDATE_LOCKED:return this.setDeviceSessionState({...this._deviceState.getValue(),deviceStatus:i.LOCKED});case s.DEVICE_STATE_UPDATE_CONNECTED:return this.setDeviceSessionState({...this._deviceState.getValue(),deviceStatus:i.CONNECTED});default:return null}};_parseDeviceStatus(e){return v(e)?{sessionStateType:o.ReadyWithoutSecureChannel,deviceStatus:i.CONNECTED,currentApp:{name:e.data.name,version:e.data.version}}:(this._logger.debug("Error while parsing APDU response",{data:{parsedResponse:e}}),null)}unsubscribe(){this._subscription.unsubscribe()}}export{d as DeviceSessionStateHandler};
|
|
2
2
|
//# sourceMappingURL=DeviceSessionStateHandler.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/device-session/model/DeviceSessionStateHandler.ts"],
|
|
4
|
-
"sourcesContent": ["import { type BehaviorSubject, type Subscription } from \"rxjs\";\n\nimport { type DeviceSessionState } from \"@api/device-session/DeviceSessionState\";\nimport {\n DeviceSessionStateType,\n DeviceStatus,\n type GetAppAndVersionResponse,\n isSuccessCommandResult,\n type TransportConnectedDevice,\n} from \"@api/index\";\nimport { type CommandResult, type LoggerPublisherService } from \"@api/types\";\nimport {\n type DeviceSessionEventDispatcher,\n type NewEvent,\n SessionEvents,\n} from \"@internal/device-session/model/DeviceSessionEventDispatcher\";\n\nexport type SetDeviceSessionStateFn = (state: DeviceSessionState) => void;\n\ntype NewDeviceStatus = {\n sessionStateType: DeviceSessionStateType;\n deviceStatus: DeviceStatus;\n currentApp: {\n name: string;\n version: string;\n };\n};\n\nexport class DeviceSessionStateHandler {\n private _subscription: Subscription;\n private readonly _logger: LoggerPublisherService;\n
|
|
5
|
-
"mappings": "AAGA,OACE,0BAAAA,EACA,gBAAAC,EAEA,0BAAAC,MAEK,aAEP,OAGE,iBAAAC,MACK,8DAaA,MAAMC,CAA0B,
|
|
6
|
-
"names": ["DeviceSessionStateType", "DeviceStatus", "isSuccessCommandResult", "SessionEvents", "DeviceSessionStateHandler", "loggerModuleFactory", "_sessionEventDispatcher", "_connectedDevice", "_deviceState", "setDeviceSessionState", "event", "parsedResponse", "newDeviceStatus", "sessionStateType", "deviceStatus", "currentApp", "state"
|
|
4
|
+
"sourcesContent": ["import { type BehaviorSubject, type Subscription } from \"rxjs\";\n\nimport { type DeviceSessionState } from \"@api/device-session/DeviceSessionState\";\nimport {\n DeviceSessionStateType,\n DeviceStatus,\n type GetAppAndVersionResponse,\n isSuccessCommandResult,\n type TransportConnectedDevice,\n} from \"@api/index\";\nimport { type CommandResult, type LoggerPublisherService } from \"@api/types\";\nimport {\n type DeviceSessionEventDispatcher,\n type NewEvent,\n SessionEvents,\n} from \"@internal/device-session/model/DeviceSessionEventDispatcher\";\n\nexport type SetDeviceSessionStateFn = (state: DeviceSessionState) => void;\n\ntype NewDeviceStatus = {\n sessionStateType: DeviceSessionStateType;\n deviceStatus: DeviceStatus;\n currentApp: {\n name: string;\n version: string;\n };\n};\n\nexport class DeviceSessionStateHandler {\n private _subscription: Subscription;\n private readonly _logger: LoggerPublisherService;\n\n constructor(\n loggerModuleFactory: (tag: string) => LoggerPublisherService,\n private _sessionEventDispatcher: DeviceSessionEventDispatcher,\n private _connectedDevice: TransportConnectedDevice,\n private _deviceState: BehaviorSubject<DeviceSessionState>,\n private setDeviceSessionState: SetDeviceSessionStateFn,\n ) {\n this._subscription = this._sessionEventDispatcher\n .listen()\n .subscribe((event) => this.mapEventAction(event));\n this._logger = loggerModuleFactory(\"device-session-state-handler\");\n }\n\n private _updateDeviceState(\n parsedResponse: CommandResult<GetAppAndVersionResponse>,\n ): void {\n const newDeviceStatus = this._parseDeviceStatus(parsedResponse);\n\n if (newDeviceStatus) {\n const { sessionStateType, deviceStatus, currentApp } = newDeviceStatus;\n const state = this._deviceState.getValue();\n if (state.sessionStateType === DeviceSessionStateType.Connected) {\n // When device is connected, initialize fields to default values\n this.setDeviceSessionState({\n sessionStateType,\n deviceStatus,\n deviceModelId: this._connectedDevice.deviceModel.id,\n currentApp,\n installedApps: [],\n isSecureConnectionAllowed: false,\n });\n } else {\n // When device is ready, keep un-modified state fields\n this.setDeviceSessionState({\n ...state,\n sessionStateType,\n deviceStatus,\n deviceModelId: this._connectedDevice.deviceModel.id,\n currentApp,\n });\n }\n }\n }\n\n private mapEventAction = (event: NewEvent) => {\n switch (event.eventName) {\n case SessionEvents.COMMAND_SUCCEEDED:\n return this._updateDeviceState(event.eventData);\n case SessionEvents.DEVICE_STATE_UPDATE_BUSY:\n return this.setDeviceSessionState({\n ...this._deviceState.getValue(),\n deviceStatus: DeviceStatus.BUSY,\n });\n case SessionEvents.DEVICE_STATE_UPDATE_LOCKED:\n return this.setDeviceSessionState({\n ...this._deviceState.getValue(),\n deviceStatus: DeviceStatus.LOCKED,\n });\n case SessionEvents.DEVICE_STATE_UPDATE_CONNECTED:\n return this.setDeviceSessionState({\n ...this._deviceState.getValue(),\n deviceStatus: DeviceStatus.CONNECTED,\n });\n default:\n return null;\n }\n };\n\n private _parseDeviceStatus(\n parsedResponse: CommandResult<GetAppAndVersionResponse>,\n ): NewDeviceStatus | null {\n if (isSuccessCommandResult(parsedResponse)) {\n return {\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n currentApp: {\n name: parsedResponse.data.name,\n version: parsedResponse.data.version,\n },\n };\n } else {\n this._logger.debug(\"Error while parsing APDU response\", {\n data: { parsedResponse },\n });\n return null;\n }\n }\n\n public unsubscribe(): void {\n this._subscription.unsubscribe();\n }\n}\n"],
|
|
5
|
+
"mappings": "AAGA,OACE,0BAAAA,EACA,gBAAAC,EAEA,0BAAAC,MAEK,aAEP,OAGE,iBAAAC,MACK,8DAaA,MAAMC,CAA0B,CAIrC,YACEC,EACQC,EACAC,EACAC,EACAC,EACR,CAJQ,6BAAAH,EACA,sBAAAC,EACA,kBAAAC,EACA,2BAAAC,EAER,KAAK,cAAgB,KAAK,wBACvB,OAAO,EACP,UAAWC,GAAU,KAAK,eAAeA,CAAK,CAAC,EAClD,KAAK,QAAUL,EAAoB,8BAA8B,CACnE,CAdQ,cACS,QAeT,mBACNM,EACM,CACN,MAAMC,EAAkB,KAAK,mBAAmBD,CAAc,EAE9D,GAAIC,EAAiB,CACnB,KAAM,CAAE,iBAAAC,EAAkB,aAAAC,EAAc,WAAAC,CAAW,EAAIH,EACjDI,EAAQ,KAAK,aAAa,SAAS,EACrCA,EAAM,mBAAqBhB,EAAuB,UAEpD,KAAK,sBAAsB,CACzB,iBAAAa,EACA,aAAAC,EACA,cAAe,KAAK,iBAAiB,YAAY,GACjD,WAAAC,EACA,cAAe,CAAC,EAChB,0BAA2B,EAC7B,CAAC,EAGD,KAAK,sBAAsB,CACzB,GAAGC,EACH,iBAAAH,EACA,aAAAC,EACA,cAAe,KAAK,iBAAiB,YAAY,GACjD,WAAAC,CACF,CAAC,CAEL,CACF,CAEQ,eAAkBL,GAAoB,CAC5C,OAAQA,EAAM,UAAW,CACvB,KAAKP,EAAc,kBACjB,OAAO,KAAK,mBAAmBO,EAAM,SAAS,EAChD,KAAKP,EAAc,yBACjB,OAAO,KAAK,sBAAsB,CAChC,GAAG,KAAK,aAAa,SAAS,EAC9B,aAAcF,EAAa,IAC7B,CAAC,EACH,KAAKE,EAAc,2BACjB,OAAO,KAAK,sBAAsB,CAChC,GAAG,KAAK,aAAa,SAAS,EAC9B,aAAcF,EAAa,MAC7B,CAAC,EACH,KAAKE,EAAc,8BACjB,OAAO,KAAK,sBAAsB,CAChC,GAAG,KAAK,aAAa,SAAS,EAC9B,aAAcF,EAAa,SAC7B,CAAC,EACH,QACE,OAAO,IACX,CACF,EAEQ,mBACNU,EACwB,CACxB,OAAIT,EAAuBS,CAAc,EAChC,CACL,iBAAkBX,EAAuB,0BACzC,aAAcC,EAAa,UAC3B,WAAY,CACV,KAAMU,EAAe,KAAK,KAC1B,QAASA,EAAe,KAAK,OAC/B,CACF,GAEA,KAAK,QAAQ,MAAM,oCAAqC,CACtD,KAAM,CAAE,eAAAA,CAAe,CACzB,CAAC,EACM,KAEX,CAEO,aAAoB,CACzB,KAAK,cAAc,YAAY,CACjC,CACF",
|
|
6
|
+
"names": ["DeviceSessionStateType", "DeviceStatus", "isSuccessCommandResult", "SessionEvents", "DeviceSessionStateHandler", "loggerModuleFactory", "_sessionEventDispatcher", "_connectedDevice", "_deviceState", "setDeviceSessionState", "event", "parsedResponse", "newDeviceStatus", "sessionStateType", "deviceStatus", "currentApp", "state"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{BehaviorSubject as p,Subject as C}from"rxjs";import{expect as
|
|
1
|
+
import{BehaviorSubject as p,Subject as C}from"rxjs";import{expect as e}from"vitest";import{CommandResultStatus as u,DeviceModelId as S,DeviceSessionStateType as r,DeviceStatus as a}from"../../../api/index";import{SessionEvents as i}from"../../device-session/model/DeviceSessionEventDispatcher";import{DeviceSessionStateHandler as D}from"./DeviceSessionStateHandler";describe("DeviceSessionStateHandler",()=>{let t,v,c;const E=vi.fn(()=>c);let l,d,n,o;beforeEach(()=>{t=new C,v={listen:()=>t,dispatch:vi.fn()},c={error:vi.fn(),debug:vi.fn()},l={deviceModel:{id:"device-model-1"}},d=new p({sessionStateType:r.Connected,deviceStatus:a.CONNECTED,deviceModelId:S.NANO_X}),n=vi.fn(),o=new D(E,v,l,d,n)}),afterEach(()=>{o&&typeof o.unsubscribe=="function"&&o.unsubscribe()}),it("updates device state on COMMAND_SUCCEEDED event with a successful response",()=>{const s={data:{name:"TestApp",version:"1.0.0"},status:u.Success};t.next({eventName:i.COMMAND_SUCCEEDED,eventData:s}),e(n).toHaveBeenCalledWith({sessionStateType:r.ReadyWithoutSecureChannel,deviceStatus:a.CONNECTED,deviceModelId:"device-model-1",currentApp:{name:"TestApp",version:"1.0.0"},installedApps:[],isSecureConnectionAllowed:!1})}),it("updates device state on COMMAND_SUCCEEDED event when device is ready",()=>{d.next({sessionStateType:r.ReadyWithoutSecureChannel,deviceStatus:a.CONNECTED,deviceModelId:S.NANO_X,currentApp:{name:"",version:""},installedApps:["Bitcoin","Ethereum"],isSecureConnectionAllowed:!0});const s={data:{name:"TestApp",version:"1.0.0"},status:u.Success};t.next({eventName:i.COMMAND_SUCCEEDED,eventData:s}),e(n).toHaveBeenCalledWith({sessionStateType:r.ReadyWithoutSecureChannel,deviceStatus:a.CONNECTED,deviceModelId:"device-model-1",currentApp:{name:"TestApp",version:"1.0.0"},installedApps:["Bitcoin","Ethereum"],isSecureConnectionAllowed:!0})}),it("updates device state on DEVICE_STATE_UPDATE_BUSY event",()=>{t.next({eventName:i.DEVICE_STATE_UPDATE_BUSY}),e(n).toHaveBeenCalledWith(e.objectContaining({deviceStatus:a.BUSY}))}),it("updates device state on DEVICE_STATE_UPDATE_CONNECTED event",()=>{t.next({eventName:i.DEVICE_STATE_UPDATE_CONNECTED}),e(n).toHaveBeenCalledWith(e.objectContaining({deviceStatus:a.CONNECTED}))}),it("logs error and does not update state if command result is unsuccessful",()=>{const s={data:null,error:{_tag:"SomeOtherError"}};t.next({eventName:i.COMMAND_SUCCEEDED,eventData:s}),e(c.debug).toHaveBeenCalledWith("Error while parsing APDU response",{data:{parsedResponse:s}}),e(n).not.toHaveBeenCalled()}),it("does not update state if command result is not a success",()=>{const s={data:null,error:{_tag:"SomeOtherError"}};t.next({eventName:i.COMMAND_SUCCEEDED,eventData:s}),e(n).not.toHaveBeenCalled()})});
|
|
2
2
|
//# sourceMappingURL=DeviceSessionStateHandler.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/device-session/model/DeviceSessionStateHandler.test.ts"],
|
|
4
|
-
"sourcesContent": ["import { BehaviorSubject, Subject } from \"rxjs\";\nimport { expect, type Mock } from \"vitest\";\n\nimport { type DeviceSessionState } from \"@api/device-session/DeviceSessionState\";\nimport {\n CommandResultStatus,\n DeviceModelId,\n DeviceSessionStateType,\n DeviceStatus,\n} from \"@api/index\";\nimport {\n type DeviceSessionEventDispatcher,\n type NewEvent,\n SessionEvents,\n} from \"@internal/device-session/model/DeviceSessionEventDispatcher\";\nimport { type Application } from \"@internal/manager-api/model/Application\";\n\nimport {\n DeviceSessionStateHandler,\n type SetDeviceSessionStateFn,\n} from \"./DeviceSessionStateHandler\";\n\ndescribe(\"DeviceSessionStateHandler\", () => {\n let fakeEventSubject: Subject<NewEvent>;\n let fakeSessionEventDispatcher: DeviceSessionEventDispatcher;\n let mockLogger: {\n error: (message: string, meta?: Record<string, unknown>) => void;\n debug: (message: string, meta?: Record<string, unknown>) => void;\n };\n const mockLoggerModuleFactory = vi.fn(() => mockLogger);\n let fakeConnectedDevice: { deviceModel: { id: string } };\n let deviceState: BehaviorSubject<DeviceSessionState>;\n let setDeviceSessionState: Mock<SetDeviceSessionStateFn>;\n let handler: DeviceSessionStateHandler;\n\n beforeEach(() => {\n fakeEventSubject = new Subject<NewEvent>();\n //@ts-expect-error mock\n fakeSessionEventDispatcher = {\n listen: () => fakeEventSubject,\n dispatch: vi.fn(),\n };\n\n mockLogger = {\n error: vi.fn(),\n debug: vi.fn(),\n };\n\n fakeConnectedDevice = {\n deviceModel: {\n id: \"device-model-1\",\n },\n };\n\n deviceState = new BehaviorSubject<DeviceSessionState>({\n sessionStateType: DeviceSessionStateType.Connected,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: DeviceModelId.NANO_X,\n });\n\n setDeviceSessionState = vi.fn();\n\n handler = new DeviceSessionStateHandler(\n //@ts-expect-error mock\n mockLoggerModuleFactory,\n fakeSessionEventDispatcher,\n fakeConnectedDevice,\n deviceState,\n setDeviceSessionState,\n );\n });\n\n afterEach(() => {\n if (handler && typeof handler.unsubscribe === \"function\") {\n handler.unsubscribe();\n }\n });\n\n it(\"updates device state on COMMAND_SUCCEEDED event with a successful response\", () => {\n // Given\n const fakeCommandResult = {\n data: {\n name: \"TestApp\",\n version: \"1.0.0\",\n },\n status: CommandResultStatus.Success,\n };\n\n // When\n fakeEventSubject.next({\n eventName: SessionEvents.COMMAND_SUCCEEDED,\n //@ts-expect-error mock\n eventData: fakeCommandResult,\n });\n\n // Then\n expect(setDeviceSessionState).toHaveBeenCalledWith({\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: \"device-model-1\",\n currentApp: { name: \"TestApp\", version: \"1.0.0\" },\n installedApps: [],\n isSecureConnectionAllowed: false,\n });\n });\n\n it(\"updates device state on COMMAND_SUCCEEDED event when device is ready\", () => {\n // Given\n deviceState.next({\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: DeviceModelId.NANO_X,\n currentApp: { name: \"\", version: \"\" },\n installedApps: [\"Bitcoin\", \"Ethereum\"] as unknown as Application[],\n isSecureConnectionAllowed: true,\n });\n const fakeCommandResult = {\n data: {\n name: \"TestApp\",\n version: \"1.0.0\",\n },\n status: CommandResultStatus.Success,\n };\n\n // When\n fakeEventSubject.next({\n eventName: SessionEvents.COMMAND_SUCCEEDED,\n //@ts-expect-error mock\n eventData: fakeCommandResult,\n });\n\n // Then\n expect(setDeviceSessionState).toHaveBeenCalledWith({\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: \"device-model-1\",\n currentApp: { name: \"TestApp\", version: \"1.0.0\" },\n installedApps: [\"Bitcoin\", \"Ethereum\"] as unknown as Application[],\n isSecureConnectionAllowed: true,\n });\n });\n\n it(\"updates device state on DEVICE_STATE_UPDATE_BUSY event\", () => {\n // When\n fakeEventSubject.next({\n eventName: SessionEvents.DEVICE_STATE_UPDATE_BUSY,\n });\n\n // Then\n expect(setDeviceSessionState).toHaveBeenCalledWith(\n expect.objectContaining({ deviceStatus: DeviceStatus.BUSY }),\n );\n });\n\n it(\"updates device state on DEVICE_STATE_UPDATE_CONNECTED event\", () => {\n // When\n fakeEventSubject.next({\n eventName: SessionEvents.DEVICE_STATE_UPDATE_CONNECTED,\n });\n\n //
|
|
5
|
-
"mappings": "AAAA,OAAS,mBAAAA,EAAiB,WAAAC,MAAe,OACzC,OAAS,UAAAC,MAAyB,SAGlC,OACE,uBAAAC,EACA,iBAAAC,EACA,0BAAAC,EACA,gBAAAC,MACK,aACP,OAGE,iBAAAC,MACK,8DAGP,OACE,6BAAAC,MAEK,8BAEP,SAAS,4BAA6B,IAAM,CAC1C,IAAIC,EACAC,EACAC,EAIJ,MAAMC,EAA0B,GAAG,GAAG,IAAMD,CAAU,EACtD,IAAIE,EACAC,EACAC,EACAC,EAEJ,WAAW,IAAM,CACfP,EAAmB,IAAIR,EAEvBS,EAA6B,CAC3B,OAAQ,IAAMD,EACd,SAAU,GAAG,GAAG,CAClB,EAEAE,EAAa,CACX,MAAO,GAAG,GAAG,EACb,MAAO,GAAG,GAAG,CACf,EAEAE,EAAsB,CACpB,YAAa,CACX,GAAI,gBACN,CACF,EAEAC,EAAc,IAAId,EAAoC,CACpD,iBAAkBK,EAAuB,UACzC,aAAcC,EAAa,UAC3B,cAAeF,EAAc,MAC/B,CAAC,EAEDW,EAAwB,GAAG,GAAG,EAE9BC,EAAU,IAAIR,EAEZI,EACAF,EACAG,EACAC,EACAC,CACF,CACF,CAAC,EAED,UAAU,IAAM,CACVC,GAAW,OAAOA,EAAQ,aAAgB,YAC5CA,EAAQ,YAAY,CAExB,CAAC,EAED,GAAG,6EAA8E,IAAM,CAErF,MAAMC,EAAoB,CACxB,KAAM,CACJ,KAAM,UACN,QAAS,OACX,EACA,OAAQd,EAAoB,OAC9B,EAGAM,EAAiB,KAAK,CACpB,UAAWF,EAAc,kBAEzB,UAAWU,CACb,CAAC,EAGDf,EAAOa,CAAqB,EAAE,qBAAqB,CACjD,iBAAkBV,EAAuB,0BACzC,aAAcC,EAAa,UAC3B,cAAe,iBACf,WAAY,CAAE,KAAM,UAAW,QAAS,OAAQ,EAChD,cAAe,CAAC,EAChB,0BAA2B,EAC7B,CAAC,CACH,CAAC,EAED,GAAG,uEAAwE,IAAM,CAE/EQ,EAAY,KAAK,CACf,iBAAkBT,EAAuB,0BACzC,aAAcC,EAAa,UAC3B,cAAeF,EAAc,OAC7B,WAAY,CAAE,KAAM,GAAI,QAAS,EAAG,EACpC,cAAe,CAAC,UAAW,UAAU,EACrC,0BAA2B,EAC7B,CAAC,EACD,MAAMa,EAAoB,CACxB,KAAM,CACJ,KAAM,UACN,QAAS,OACX,EACA,OAAQd,EAAoB,OAC9B,EAGAM,EAAiB,KAAK,CACpB,UAAWF,EAAc,kBAEzB,UAAWU,CACb,CAAC,EAGDf,EAAOa,CAAqB,EAAE,qBAAqB,CACjD,iBAAkBV,EAAuB,0BACzC,aAAcC,EAAa,UAC3B,cAAe,iBACf,WAAY,CAAE,KAAM,UAAW,QAAS,OAAQ,EAChD,cAAe,CAAC,UAAW,UAAU,EACrC,0BAA2B,EAC7B,CAAC,CACH,CAAC,EAED,GAAG,yDAA0D,IAAM,CAEjEG,EAAiB,KAAK,CACpB,UAAWF,EAAc,wBAC3B,CAAC,EAGDL,EAAOa,CAAqB,EAAE,qBAC5Bb,EAAO,iBAAiB,CAAE,aAAcI,EAAa,IAAK,CAAC,CAC7D,CACF,CAAC,EAED,GAAG,8DAA+D,IAAM,CAEtEG,EAAiB,KAAK,CACpB,UAAWF,EAAc,6BAC3B,CAAC,
|
|
4
|
+
"sourcesContent": ["import { BehaviorSubject, Subject } from \"rxjs\";\nimport { expect, type Mock } from \"vitest\";\n\nimport { type DeviceSessionState } from \"@api/device-session/DeviceSessionState\";\nimport {\n CommandResultStatus,\n DeviceModelId,\n DeviceSessionStateType,\n DeviceStatus,\n} from \"@api/index\";\nimport {\n type DeviceSessionEventDispatcher,\n type NewEvent,\n SessionEvents,\n} from \"@internal/device-session/model/DeviceSessionEventDispatcher\";\nimport { type Application } from \"@internal/manager-api/model/Application\";\n\nimport {\n DeviceSessionStateHandler,\n type SetDeviceSessionStateFn,\n} from \"./DeviceSessionStateHandler\";\n\ndescribe(\"DeviceSessionStateHandler\", () => {\n let fakeEventSubject: Subject<NewEvent>;\n let fakeSessionEventDispatcher: DeviceSessionEventDispatcher;\n let mockLogger: {\n error: (message: string, meta?: Record<string, unknown>) => void;\n debug: (message: string, meta?: Record<string, unknown>) => void;\n };\n const mockLoggerModuleFactory = vi.fn(() => mockLogger);\n let fakeConnectedDevice: { deviceModel: { id: string } };\n let deviceState: BehaviorSubject<DeviceSessionState>;\n let setDeviceSessionState: Mock<SetDeviceSessionStateFn>;\n let handler: DeviceSessionStateHandler;\n\n beforeEach(() => {\n fakeEventSubject = new Subject<NewEvent>();\n //@ts-expect-error mock\n fakeSessionEventDispatcher = {\n listen: () => fakeEventSubject,\n dispatch: vi.fn(),\n };\n\n mockLogger = {\n error: vi.fn(),\n debug: vi.fn(),\n };\n\n fakeConnectedDevice = {\n deviceModel: {\n id: \"device-model-1\",\n },\n };\n\n deviceState = new BehaviorSubject<DeviceSessionState>({\n sessionStateType: DeviceSessionStateType.Connected,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: DeviceModelId.NANO_X,\n });\n\n setDeviceSessionState = vi.fn();\n\n handler = new DeviceSessionStateHandler(\n //@ts-expect-error mock\n mockLoggerModuleFactory,\n fakeSessionEventDispatcher,\n fakeConnectedDevice,\n deviceState,\n setDeviceSessionState,\n );\n });\n\n afterEach(() => {\n if (handler && typeof handler.unsubscribe === \"function\") {\n handler.unsubscribe();\n }\n });\n\n it(\"updates device state on COMMAND_SUCCEEDED event with a successful response\", () => {\n // Given\n const fakeCommandResult = {\n data: {\n name: \"TestApp\",\n version: \"1.0.0\",\n },\n status: CommandResultStatus.Success,\n };\n\n // When\n fakeEventSubject.next({\n eventName: SessionEvents.COMMAND_SUCCEEDED,\n //@ts-expect-error mock\n eventData: fakeCommandResult,\n });\n\n // Then\n expect(setDeviceSessionState).toHaveBeenCalledWith({\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: \"device-model-1\",\n currentApp: { name: \"TestApp\", version: \"1.0.0\" },\n installedApps: [],\n isSecureConnectionAllowed: false,\n });\n });\n\n it(\"updates device state on COMMAND_SUCCEEDED event when device is ready\", () => {\n // Given\n deviceState.next({\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: DeviceModelId.NANO_X,\n currentApp: { name: \"\", version: \"\" },\n installedApps: [\"Bitcoin\", \"Ethereum\"] as unknown as Application[],\n isSecureConnectionAllowed: true,\n });\n const fakeCommandResult = {\n data: {\n name: \"TestApp\",\n version: \"1.0.0\",\n },\n status: CommandResultStatus.Success,\n };\n\n // When\n fakeEventSubject.next({\n eventName: SessionEvents.COMMAND_SUCCEEDED,\n //@ts-expect-error mock\n eventData: fakeCommandResult,\n });\n\n // Then\n expect(setDeviceSessionState).toHaveBeenCalledWith({\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: \"device-model-1\",\n currentApp: { name: \"TestApp\", version: \"1.0.0\" },\n installedApps: [\"Bitcoin\", \"Ethereum\"] as unknown as Application[],\n isSecureConnectionAllowed: true,\n });\n });\n\n it(\"updates device state on DEVICE_STATE_UPDATE_BUSY event\", () => {\n // When\n fakeEventSubject.next({\n eventName: SessionEvents.DEVICE_STATE_UPDATE_BUSY,\n });\n\n // Then\n expect(setDeviceSessionState).toHaveBeenCalledWith(\n expect.objectContaining({ deviceStatus: DeviceStatus.BUSY }),\n );\n });\n\n it(\"updates device state on DEVICE_STATE_UPDATE_CONNECTED event\", () => {\n // When\n fakeEventSubject.next({\n eventName: SessionEvents.DEVICE_STATE_UPDATE_CONNECTED,\n });\n\n // Then\n expect(setDeviceSessionState).toHaveBeenCalledWith(\n expect.objectContaining({ deviceStatus: DeviceStatus.CONNECTED }),\n );\n });\n\n it(\"logs error and does not update state if command result is unsuccessful\", () => {\n // Given\n const fakeErrorCommandResult = {\n data: null,\n error: { _tag: \"SomeOtherError\" },\n };\n\n // When\n fakeEventSubject.next({\n eventName: SessionEvents.COMMAND_SUCCEEDED,\n //@ts-expect-error mock\n eventData: fakeErrorCommandResult,\n });\n\n // Then\n expect(mockLogger.debug).toHaveBeenCalledWith(\n \"Error while parsing APDU response\",\n { data: { parsedResponse: fakeErrorCommandResult } },\n );\n expect(setDeviceSessionState).not.toHaveBeenCalled();\n });\n\n it(\"does not update state if command result is not a success\", () => {\n // Given\n const fakeErrorCommandResult = {\n data: null,\n error: { _tag: \"SomeOtherError\" },\n };\n\n // When\n fakeEventSubject.next({\n eventName: SessionEvents.COMMAND_SUCCEEDED,\n //@ts-expect-error mock\n eventData: fakeErrorCommandResult,\n });\n\n // Then\n expect(setDeviceSessionState).not.toHaveBeenCalled();\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["BehaviorSubject", "Subject", "expect", "CommandResultStatus", "DeviceModelId", "DeviceSessionStateType", "DeviceStatus", "SessionEvents", "DeviceSessionStateHandler", "fakeEventSubject", "fakeSessionEventDispatcher", "mockLogger", "mockLoggerModuleFactory", "fakeConnectedDevice", "deviceState", "setDeviceSessionState", "handler", "fakeCommandResult", "fakeErrorCommandResult"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
class u{_queue=[];_locked=!1;async lock(){return new Promise(e=>{const s=()=>{if(this._locked=!1,this._queue.length>0){const t=this._queue.shift();this._locked=!0,t()}};this._locked?this._queue.push(()=>e(s)):(this._locked=!0,e(s))})}}export{u as MutexService};
|
|
2
|
+
//# sourceMappingURL=MutexService.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/device-session/service/MutexService.ts"],
|
|
4
|
+
"sourcesContent": ["export class MutexService {\n private _queue: Array<() => void> = [];\n private _locked = false;\n\n async lock(): Promise<() => void> {\n return new Promise((resolve) => {\n const release = () => {\n this._locked = false;\n if (this._queue.length > 0) {\n const next = this._queue.shift();\n this._locked = true;\n next!();\n }\n };\n\n if (!this._locked) {\n this._locked = true;\n resolve(release);\n } else {\n this._queue.push(() => resolve(release));\n }\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAO,MAAMA,CAAa,CAChB,OAA4B,CAAC,EAC7B,QAAU,GAElB,MAAM,MAA4B,CAChC,OAAO,IAAI,QAASC,GAAY,CAC9B,MAAMC,EAAU,IAAM,CAEpB,GADA,KAAK,QAAU,GACX,KAAK,OAAO,OAAS,EAAG,CAC1B,MAAMC,EAAO,KAAK,OAAO,MAAM,EAC/B,KAAK,QAAU,GACfA,EAAM,CACR,CACF,EAEK,KAAK,QAIR,KAAK,OAAO,KAAK,IAAMF,EAAQC,CAAO,CAAC,GAHvC,KAAK,QAAU,GACfD,EAAQC,CAAO,EAInB,CAAC,CACH,CACF",
|
|
6
|
+
"names": ["MutexService", "resolve", "release", "next"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{describe as i,expect as s,it as r}from"vitest";import{MutexService as u}from"./MutexService";i("MutexService",()=>{r("should immediately return a release function when not locked",async()=>{const e=await new u().lock();s(typeof e).toBe("function"),e()}),r("should queue subsequent lock calls until the lock is released",async()=>{const t=new u,e=await t.lock();let o=!1;const c=t.lock().then(l=>{o=!0,l()});s(o).toBe(!1),e(),await c,s(o).toBe(!0)}),r("should queue multiple locks in FIFO order",async()=>{const t=new u,e=[],o=await t.lock();e.push("first");const c=t.lock().then(n=>{e.push("second"),n()}),l=t.lock().then(n=>{e.push("third"),n()});e.push("afterqueue"),o(),await Promise.all([c,l]),s(e).toEqual(["first","afterqueue","second","third"])})});
|
|
2
|
+
//# sourceMappingURL=MutexService.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/device-session/service/MutexService.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { describe, expect, it } from \"vitest\";\n\nimport { MutexService } from \"./MutexService\";\n\ndescribe(\"MutexService\", () => {\n it(\"should immediately return a release function when not locked\", async () => {\n // given\n const mutex = new MutexService();\n\n // when\n const release = await mutex.lock();\n\n // then\n expect(typeof release).toBe(\"function\");\n release();\n });\n\n it(\"should queue subsequent lock calls until the lock is released\", async () => {\n // given\n const mutex = new MutexService();\n const release1 = await mutex.lock();\n\n // when\n let lock2Resolved = false;\n const lock2Promise = mutex.lock().then((release2) => {\n lock2Resolved = true;\n release2();\n });\n\n // then\n expect(lock2Resolved).toBe(false);\n\n // when\n release1();\n await lock2Promise;\n\n // then\n expect(lock2Resolved).toBe(true);\n });\n\n it(\"should queue multiple locks in FIFO order\", async () => {\n // given\n const mutex = new MutexService();\n const order: string[] = [];\n\n // when\n const release1 = await mutex.lock();\n order.push(\"first\");\n const lock2Promise = mutex.lock().then((release2) => {\n order.push(\"second\");\n release2();\n });\n const lock3Promise = mutex.lock().then((release3) => {\n order.push(\"third\");\n release3();\n });\n\n // then\n order.push(\"afterqueue\");\n\n // when\n release1();\n await Promise.all([lock2Promise, lock3Promise]);\n\n // then\n expect(order).toEqual([\"first\", \"afterqueue\", \"second\", \"third\"]);\n });\n});\n"],
|
|
5
|
+
"mappings": "AAAA,OAAS,YAAAA,EAAU,UAAAC,EAAQ,MAAAC,MAAU,SAErC,OAAS,gBAAAC,MAAoB,iBAE7BH,EAAS,eAAgB,IAAM,CAC7BE,EAAG,+DAAgE,SAAY,CAK7E,MAAME,EAAU,MAHF,IAAID,EAAa,EAGH,KAAK,EAGjCF,EAAO,OAAOG,CAAO,EAAE,KAAK,UAAU,EACtCA,EAAQ,CACV,CAAC,EAEDF,EAAG,gEAAiE,SAAY,CAE9E,MAAMG,EAAQ,IAAIF,EACZG,EAAW,MAAMD,EAAM,KAAK,EAGlC,IAAIE,EAAgB,GACpB,MAAMC,EAAeH,EAAM,KAAK,EAAE,KAAMI,GAAa,CACnDF,EAAgB,GAChBE,EAAS,CACX,CAAC,EAGDR,EAAOM,CAAa,EAAE,KAAK,EAAK,EAGhCD,EAAS,EACT,MAAME,EAGNP,EAAOM,CAAa,EAAE,KAAK,EAAI,CACjC,CAAC,EAEDL,EAAG,4CAA6C,SAAY,CAE1D,MAAMG,EAAQ,IAAIF,EACZO,EAAkB,CAAC,EAGnBJ,EAAW,MAAMD,EAAM,KAAK,EAClCK,EAAM,KAAK,OAAO,EAClB,MAAMF,EAAeH,EAAM,KAAK,EAAE,KAAMI,GAAa,CACnDC,EAAM,KAAK,QAAQ,EACnBD,EAAS,CACX,CAAC,EACKE,EAAeN,EAAM,KAAK,EAAE,KAAMO,GAAa,CACnDF,EAAM,KAAK,OAAO,EAClBE,EAAS,CACX,CAAC,EAGDF,EAAM,KAAK,YAAY,EAGvBJ,EAAS,EACT,MAAM,QAAQ,IAAI,CAACE,EAAcG,CAAY,CAAC,EAG9CV,EAAOS,CAAK,EAAE,QAAQ,CAAC,QAAS,aAAc,SAAU,OAAO,CAAC,CAClE,CAAC,CACH,CAAC",
|
|
6
|
+
"names": ["describe", "expect", "it", "MutexService", "release", "mutex", "release1", "lock2Resolved", "lock2Promise", "release2", "order", "lock3Promise", "release3"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Left as k,Maybe as
|
|
1
|
+
import{Left as k,Maybe as m,Right as S}from"purify-ts";import{TransportMock as C}from"../../../api/transport/model/__mocks__/TransportMock";import{UnknownDeviceError as f}from"../../../api/transport/model/Errors";import{connectedDeviceStubBuilder as w}from"../../../api/transport/model/TransportConnectedDevice.stub";import{DefaultDeviceSessionService as I}from"../../device-session/service/DefaultDeviceSessionService";import{DefaultLoggerPublisherService as M}from"../../logger-publisher/service/DefaultLoggerPublisherService";import{AxiosManagerApiDataSource as T}from"../../manager-api/data/AxiosManagerApiDataSource";import{DefaultManagerApiService as h}from"../../manager-api/service/DefaultManagerApiService";import{DefaultSecureChannelDataSource as A}from"../../secure-channel/data/DefaultSecureChannelDataSource";import{DefaultSecureChannelService as b}from"../../secure-channel/service/DefaultSecureChannelService";import{DefaultTransportService as O}from"../../transport/service/DefaultTransportService";import{ConnectUseCase as p}from"./ConnectUseCase";vi.mock("uuid",()=>({v4:vi.fn().mockReturnValue("fakeSessionId")}));vi.mock("@internal/manager-api/data/AxiosManagerApiDataSource");vi.mock("@internal/transport/service/DefaultTransportService");let o,n,i,e,s,l,d,c;const x="fakeSessionId",D="fakeSessionIdConnectedDevice";describe("ConnectUseCase",()=>{const v={id:"",deviceModel:{},transport:"USB",name:"TEST"},u=w({id:"1"}),g={id:"1",sessionId:D,modelId:"model-id",name:"device-name",type:"MOCK",transport:"USB"},y="logger-tag";beforeAll(()=>{i=new M([],y),o=new C,e=new I(()=>i),l=new T({}),s=new h(l),d=new A({}),c=new b(d),n=new O}),afterEach(()=>{for(const t of e.getDeviceSessions())e.removeDeviceSession(t.id)}),afterAll(()=>{vi.restoreAllMocks()}),test("If connect use case encounter an error, return it",async()=>{vi.spyOn(o,"connect").mockResolvedValue(k(new f)),vi.spyOn(n,"getTransport").mockReturnValue(m.of(o));const t=new p(n,e,()=>i,s,c);await expect(t.execute({device:v})).rejects.toBeInstanceOf(f)}),test("If connect is in success, return a deviceSession id",async()=>{vi.spyOn(o,"connect").mockResolvedValue(S(u)),vi.spyOn(n,"getTransport").mockReturnValue(m.of(o)),vi.spyOn(e,"addDeviceSession").mockImplementation(a=>(a.setDeviceSessionState({}),e));const r=await new p(n,e,()=>i,s,c).execute({device:v});expect(r).toBe(x),e.removeDeviceSession(r)}),test("If connect is in success after a reconnect, return the same deviceSession id",async()=>{vi.spyOn(o,"connect").mockResolvedValue(S(u)),vi.spyOn(n,"getTransport").mockReturnValue(m.of(o)),vi.spyOn(e,"addDeviceSession").mockImplementation(a=>(a.setDeviceSessionState({}),e));const r=await new p(n,e,()=>i,s,c).execute({device:g});expect(r).toBe(D),e.removeDeviceSession(r)})});
|
|
2
2
|
//# sourceMappingURL=ConnectUseCase.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/discovery/use-case/ConnectUseCase.test.ts"],
|
|
4
|
-
"sourcesContent": ["import { Left, Maybe, Right } from \"purify-ts\";\n\nimport { type DeviceModel, type DeviceModelId } from \"@api/device/DeviceModel\";\nimport { type ConnectionType } from \"@api/discovery/ConnectionType\";\nimport { type LoggerPublisherService } from \"@api/logger-publisher/service/LoggerPublisherService\";\nimport { type ConnectedDevice } from \"@api/transport/model/ConnectedDevice\";\nimport { type DiscoveredDevice } from \"@api/transport/model/DiscoveredDevice\";\nimport {
|
|
5
|
-
"mappings": "AAAA,OAAS,QAAAA,EAAM,SAAAC,EAAO,SAAAC,MAAa,YAOnC,
|
|
6
|
-
"names": ["Left", "Maybe", "Right", "
|
|
4
|
+
"sourcesContent": ["import { Left, Maybe, Right } from \"purify-ts\";\n\nimport { type DeviceModel, type DeviceModelId } from \"@api/device/DeviceModel\";\nimport { type DeviceSessionState } from \"@api/device-session/DeviceSessionState\";\nimport { type ConnectionType } from \"@api/discovery/ConnectionType\";\nimport { type DmkConfig } from \"@api/DmkConfig\";\nimport { type LoggerPublisherService } from \"@api/logger-publisher/service/LoggerPublisherService\";\nimport { TransportMock } from \"@api/transport/model/__mocks__/TransportMock\";\nimport { type ConnectedDevice } from \"@api/transport/model/ConnectedDevice\";\nimport { type DiscoveredDevice } from \"@api/transport/model/DiscoveredDevice\";\nimport { UnknownDeviceError } from \"@api/transport/model/Errors\";\nimport { type Transport } from \"@api/transport/model/Transport\";\nimport { connectedDeviceStubBuilder } from \"@api/transport/model/TransportConnectedDevice.stub\";\nimport { DefaultDeviceSessionService } from \"@internal/device-session/service/DefaultDeviceSessionService\";\nimport { type DeviceSessionService } from \"@internal/device-session/service/DeviceSessionService\";\nimport { DefaultLoggerPublisherService } from \"@internal/logger-publisher/service/DefaultLoggerPublisherService\";\nimport { AxiosManagerApiDataSource } from \"@internal/manager-api/data/AxiosManagerApiDataSource\";\nimport { type ManagerApiDataSource } from \"@internal/manager-api/data/ManagerApiDataSource\";\nimport { DefaultManagerApiService } from \"@internal/manager-api/service/DefaultManagerApiService\";\nimport { type ManagerApiService } from \"@internal/manager-api/service/ManagerApiService\";\nimport { DefaultSecureChannelDataSource } from \"@internal/secure-channel/data/DefaultSecureChannelDataSource\";\nimport { type SecureChannelDataSource } from \"@internal/secure-channel/data/SecureChannelDataSource\";\nimport { DefaultSecureChannelService } from \"@internal/secure-channel/service/DefaultSecureChannelService\";\nimport { type SecureChannelService } from \"@internal/secure-channel/service/SecureChannelService\";\nimport { DefaultTransportService } from \"@internal/transport/service/DefaultTransportService\";\nimport { type TransportService } from \"@internal/transport/service/TransportService\";\n\nimport { ConnectUseCase } from \"./ConnectUseCase\";\n\nvi.mock(\"uuid\", () => ({\n v4: vi.fn().mockReturnValue(\"fakeSessionId\"),\n}));\n\nvi.mock(\"@internal/manager-api/data/AxiosManagerApiDataSource\");\nvi.mock(\"@internal/transport/service/DefaultTransportService\");\n\n// TODO test several transports\n// let transports: WebUsbHidTransport[];\nlet transport: Transport;\nlet transportService: TransportService;\nlet logger: LoggerPublisherService;\nlet sessionService: DeviceSessionService;\nlet managerApi: ManagerApiService;\nlet managerApiDataSource: ManagerApiDataSource;\nlet secureChannelDataSource: SecureChannelDataSource;\nlet secureChannel: SecureChannelService;\nconst fakeSessionId = \"fakeSessionId\";\nconst fakeSessionIdConnectedDevice = \"fakeSessionIdConnectedDevice\";\n\ndescribe(\"ConnectUseCase\", () => {\n const stubDiscoveredDevice: DiscoveredDevice = {\n id: \"\",\n deviceModel: {} as DeviceModel,\n transport: \"USB\",\n name: \"TEST\",\n };\n const stubTransportConnectedDevice = connectedDeviceStubBuilder({ id: \"1\" });\n const stubConnectedDevice = {\n id: \"1\",\n sessionId: fakeSessionIdConnectedDevice,\n modelId: \"model-id\" as unknown as DeviceModelId,\n name: \"device-name\",\n type: \"MOCK\" as unknown as ConnectionType,\n transport: \"USB\",\n } as unknown as ConnectedDevice;\n const tag = \"logger-tag\";\n\n beforeAll(() => {\n logger = new DefaultLoggerPublisherService([], tag);\n transport = new TransportMock();\n sessionService = new DefaultDeviceSessionService(() => logger);\n managerApiDataSource = new AxiosManagerApiDataSource({} as DmkConfig);\n managerApi = new DefaultManagerApiService(managerApiDataSource);\n secureChannelDataSource = new DefaultSecureChannelDataSource(\n {} as DmkConfig,\n );\n secureChannel = new DefaultSecureChannelService(secureChannelDataSource);\n // @ts-expect-error mock\n transportService = new DefaultTransportService();\n });\n\n afterEach(() => {\n for (const session of sessionService.getDeviceSessions()) {\n sessionService.removeDeviceSession(session.id);\n }\n });\n\n afterAll(() => {\n vi.restoreAllMocks();\n });\n\n test(\"If connect use case encounter an error, return it\", async () => {\n vi.spyOn(transport, \"connect\").mockResolvedValue(\n Left(new UnknownDeviceError()),\n );\n\n vi.spyOn(transportService, \"getTransport\").mockReturnValue(\n Maybe.of(transport),\n );\n\n const usecase = new ConnectUseCase(\n transportService,\n sessionService,\n () => logger,\n managerApi,\n secureChannel,\n );\n\n await expect(\n usecase.execute({ device: stubDiscoveredDevice }),\n ).rejects.toBeInstanceOf(UnknownDeviceError);\n });\n\n test(\"If connect is in success, return a deviceSession id\", async () => {\n vi.spyOn(transport, \"connect\").mockResolvedValue(\n Right(stubTransportConnectedDevice),\n );\n vi.spyOn(transportService, \"getTransport\").mockReturnValue(\n Maybe.of(transport),\n );\n vi.spyOn(sessionService, \"addDeviceSession\").mockImplementation(\n (deviceSession) => {\n deviceSession.setDeviceSessionState({} as DeviceSessionState);\n return sessionService;\n },\n );\n\n const usecase = new ConnectUseCase(\n transportService,\n sessionService,\n () => logger,\n managerApi,\n secureChannel,\n );\n\n const sessionId = await usecase.execute({\n device: stubDiscoveredDevice,\n });\n expect(sessionId).toBe(fakeSessionId);\n sessionService.removeDeviceSession(sessionId);\n });\n\n test(\"If connect is in success after a reconnect, return the same deviceSession id\", async () => {\n vi.spyOn(transport, \"connect\").mockResolvedValue(\n Right(stubTransportConnectedDevice),\n );\n vi.spyOn(transportService, \"getTransport\").mockReturnValue(\n Maybe.of(transport),\n );\n vi.spyOn(sessionService, \"addDeviceSession\").mockImplementation(\n (deviceSession) => {\n deviceSession.setDeviceSessionState({} as DeviceSessionState);\n return sessionService;\n },\n );\n\n const usecase = new ConnectUseCase(\n transportService,\n sessionService,\n () => logger,\n managerApi,\n secureChannel,\n );\n\n const sessionId = await usecase.execute({\n device: stubConnectedDevice,\n });\n expect(sessionId).toBe(fakeSessionIdConnectedDevice); // same session id as the connected device\n sessionService.removeDeviceSession(sessionId);\n });\n});\n"],
|
|
5
|
+
"mappings": "AAAA,OAAS,QAAAA,EAAM,SAAAC,EAAO,SAAAC,MAAa,YAOnC,OAAS,iBAAAC,MAAqB,+CAG9B,OAAS,sBAAAC,MAA0B,8BAEnC,OAAS,8BAAAC,MAAkC,qDAC3C,OAAS,+BAAAC,MAAmC,+DAE5C,OAAS,iCAAAC,MAAqC,mEAC9C,OAAS,6BAAAC,MAAiC,uDAE1C,OAAS,4BAAAC,MAAgC,yDAEzC,OAAS,kCAAAC,MAAsC,+DAE/C,OAAS,+BAAAC,MAAmC,+DAE5C,OAAS,2BAAAC,MAA+B,sDAGxC,OAAS,kBAAAC,MAAsB,mBAE/B,GAAG,KAAK,OAAQ,KAAO,CACrB,GAAI,GAAG,GAAG,EAAE,gBAAgB,eAAe,CAC7C,EAAE,EAEF,GAAG,KAAK,sDAAsD,EAC9D,GAAG,KAAK,qDAAqD,EAI7D,IAAIC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACJ,MAAMC,EAAgB,gBAChBC,EAA+B,+BAErC,SAAS,iBAAkB,IAAM,CAC/B,MAAMC,EAAyC,CAC7C,GAAI,GACJ,YAAa,CAAC,EACd,UAAW,MACX,KAAM,MACR,EACMC,EAA+BpB,EAA2B,CAAE,GAAI,GAAI,CAAC,EACrEqB,EAAsB,CAC1B,GAAI,IACJ,UAAWH,EACX,QAAS,WACT,KAAM,cACN,KAAM,OACN,UAAW,KACb,EACMI,EAAM,aAEZ,UAAU,IAAM,CACdX,EAAS,IAAIT,EAA8B,CAAC,EAAGoB,CAAG,EAClDb,EAAY,IAAIX,EAChBc,EAAiB,IAAIX,EAA4B,IAAMU,CAAM,EAC7DG,EAAuB,IAAIX,EAA0B,CAAC,CAAc,EACpEU,EAAa,IAAIT,EAAyBU,CAAoB,EAC9DC,EAA0B,IAAIV,EAC5B,CAAC,CACH,EACAW,EAAgB,IAAIV,EAA4BS,CAAuB,EAEvEL,EAAmB,IAAIH,CACzB,CAAC,EAED,UAAU,IAAM,CACd,UAAWgB,KAAWX,EAAe,kBAAkB,EACrDA,EAAe,oBAAoBW,EAAQ,EAAE,CAEjD,CAAC,EAED,SAAS,IAAM,CACb,GAAG,gBAAgB,CACrB,CAAC,EAED,KAAK,oDAAqD,SAAY,CACpE,GAAG,MAAMd,EAAW,SAAS,EAAE,kBAC7Bd,EAAK,IAAII,CAAoB,CAC/B,EAEA,GAAG,MAAMW,EAAkB,cAAc,EAAE,gBACzCd,EAAM,GAAGa,CAAS,CACpB,EAEA,MAAMe,EAAU,IAAIhB,EAClBE,EACAE,EACA,IAAMD,EACNE,EACAG,CACF,EAEA,MAAM,OACJQ,EAAQ,QAAQ,CAAE,OAAQL,CAAqB,CAAC,CAClD,EAAE,QAAQ,eAAepB,CAAkB,CAC7C,CAAC,EAED,KAAK,sDAAuD,SAAY,CACtE,GAAG,MAAMU,EAAW,SAAS,EAAE,kBAC7BZ,EAAMuB,CAA4B,CACpC,EACA,GAAG,MAAMV,EAAkB,cAAc,EAAE,gBACzCd,EAAM,GAAGa,CAAS,CACpB,EACA,GAAG,MAAMG,EAAgB,kBAAkB,EAAE,mBAC1Ca,IACCA,EAAc,sBAAsB,CAAC,CAAuB,EACrDb,EAEX,EAUA,MAAMc,EAAY,MARF,IAAIlB,EAClBE,EACAE,EACA,IAAMD,EACNE,EACAG,CACF,EAEgC,QAAQ,CACtC,OAAQG,CACV,CAAC,EACD,OAAOO,CAAS,EAAE,KAAKT,CAAa,EACpCL,EAAe,oBAAoBc,CAAS,CAC9C,CAAC,EAED,KAAK,+EAAgF,SAAY,CAC/F,GAAG,MAAMjB,EAAW,SAAS,EAAE,kBAC7BZ,EAAMuB,CAA4B,CACpC,EACA,GAAG,MAAMV,EAAkB,cAAc,EAAE,gBACzCd,EAAM,GAAGa,CAAS,CACpB,EACA,GAAG,MAAMG,EAAgB,kBAAkB,EAAE,mBAC1Ca,IACCA,EAAc,sBAAsB,CAAC,CAAuB,EACrDb,EAEX,EAUA,MAAMc,EAAY,MARF,IAAIlB,EAClBE,EACAE,EACA,IAAMD,EACNE,EACAG,CACF,EAEgC,QAAQ,CACtC,OAAQK,CACV,CAAC,EACD,OAAOK,CAAS,EAAE,KAAKR,CAA4B,EACnDN,EAAe,oBAAoBc,CAAS,CAC9C,CAAC,CACH,CAAC",
|
|
6
|
+
"names": ["Left", "Maybe", "Right", "TransportMock", "UnknownDeviceError", "connectedDeviceStubBuilder", "DefaultDeviceSessionService", "DefaultLoggerPublisherService", "AxiosManagerApiDataSource", "DefaultManagerApiService", "DefaultSecureChannelDataSource", "DefaultSecureChannelService", "DefaultTransportService", "ConnectUseCase", "transport", "transportService", "logger", "sessionService", "managerApi", "managerApiDataSource", "secureChannelDataSource", "secureChannel", "fakeSessionId", "fakeSessionIdConnectedDevice", "stubDiscoveredDevice", "stubTransportConnectedDevice", "stubConnectedDevice", "tag", "session", "usecase", "deviceSession", "sessionId"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Left as
|
|
1
|
+
import{Left as l}from"purify-ts";import{connectedDeviceStubBuilder as v}from"../../../api/transport/model/TransportConnectedDevice.stub";import{DEVICE_SESSION_REFRESHER_DEFAULT_OPTIONS as u}from"../../device-session/data/DeviceSessionRefresherConst";import{deviceSessionStubBuilder as p}from"../../device-session/model/DeviceSession.stub";import{DeviceSessionNotFound as D,ReceiverApduError as S}from"../../device-session/model/Errors";import{DefaultDeviceSessionService as g}from"../../device-session/service/DefaultDeviceSessionService";import{DefaultLoggerPublisherService as x}from"../../logger-publisher/service/DefaultLoggerPublisherService";import{AxiosManagerApiDataSource as A}from"../../manager-api/data/AxiosManagerApiDataSource";import{DefaultManagerApiService as C}from"../../manager-api/service/DefaultManagerApiService";import{DefaultSecureChannelDataSource as h}from"../../secure-channel/data/DefaultSecureChannelDataSource";import{DefaultSecureChannelService as w}from"../../secure-channel/service/DefaultSecureChannelService";import{SendApduUseCase as i}from"../../send/use-case/SendApduUseCase";vi.mock("@internal/manager-api/data/AxiosManagerApiDataSource");let e,o,m,s,d,a;const t="fakeSessionId";describe("SendApduUseCase",()=>{beforeEach(()=>{e=new x([],"send-apdu-use-case"),o=new g(()=>e),m=new A({}),s=new C(m),d=new h({}),a=new w(d)}),it("should send an APDU to a connected device",async()=>{const r=p({},()=>e,s,a,u);o.addDeviceSession(r);const c=await new i(o,()=>e).execute({sessionId:t,apdu:new Uint8Array([0,1,2,3])});r.close(),expect(r.connectedDevice.sendApdu).toHaveBeenCalledTimes(1),expect(c).toBeDefined()}),it("should throw an error if the deviceSession is not found",async()=>{const n=new i(o,()=>e).execute({sessionId:t,apdu:new Uint8Array([0,1,2,3])});await expect(n).rejects.toBeInstanceOf(D)}),it("should throw an error if the apdu receiver failed",async()=>{const r=v({sendApdu:vi.fn(async()=>Promise.resolve(l(new S)))}),n=p({connectedDevice:r},()=>e,s,a,u);o.addDeviceSession(n);const f=new i(o,()=>e).execute({sessionId:t,apdu:new Uint8Array([0,1,2,3])});n.close(),await expect(f).rejects.toBeInstanceOf(S)})});
|
|
2
2
|
//# sourceMappingURL=SendApduUseCase.test.js.map
|