Skip to content

Commit

Permalink
CP-2596 Contacts data transfer (#1846)
Browse files Browse the repository at this point in the history
  • Loading branch information
lkowalczyk87 authored and dkarski committed May 23, 2024
1 parent 8787da1 commit bd83355
Show file tree
Hide file tree
Showing 36 changed files with 1,070 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,26 @@ export interface GoogleContactResourceItem {
displayName?: string
familyName?: string
givenName?: string
middleName?: string
honorificPrefix?: string
honorificSuffix?: string
}[]
addresses?: {
metadata: GoogleContactMetadata
extendedAddress: string
streetAddress: string
postalCode: string
city: string
type?: string
poBox?: string
country?: string
countryCode?: string
region?: string
}[]
emailAddresses?: {
metadata: GoogleContactMetadata
value: string
type?: string
}[]
phoneNumbers?: {
metadata: GoogleContactMetadata
Expand All @@ -64,6 +73,21 @@ export interface GoogleContactResourceItem {
value: string
contentType: string
}[]
urls?: {
metadata: GoogleContactMetadata
value: string
type?: string
}[]
organizations?: {
metadata: GoogleContactMetadata
name?: string
department?: string
title?: string
}[]
nicknames?: {
metadata: GoogleContactMetadata
value: string
}[]
}

export interface GoogleContacts {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ test("contacts are received properly", async () => {
axiosMock
.onGet(`${googleEndpoints.people}/people/me/connections`, {
params: {
personFields: "names,addresses,phoneNumbers,emailAddresses,biographies",
personFields:
"names,addresses,phoneNumbers,emailAddresses,biographies,organizations,urls,nicknames",
pageSize: 1000,
},
})
Expand Down Expand Up @@ -165,7 +166,8 @@ test("empty list is returned when no contacts", async () => {
axiosMock
.onGet(`${googleEndpoints.people}/people/me/connections`, {
params: {
personFields: "names,addresses,phoneNumbers,emailAddresses,biographies",
personFields:
"names,addresses,phoneNumbers,emailAddresses,biographies,organizations,urls,nicknames",
pageSize: 1000,
},
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ const google = createModel<ExternalProvidersModels>({
url: `${googleEndpoints.people}/people/me/connections`,
params: {
personFields:
"names,addresses,phoneNumbers,emailAddresses,biographies",
"names,addresses,phoneNumbers,emailAddresses,biographies,organizations,urls,nicknames",
pageSize: 1000,
...(nextPageToken && {
pageToken: String(nextPageToken),
Expand Down
1 change: 1 addition & 0 deletions libs/device/feature/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from "./lib/file-transfer"
export * from "./lib/file-manager"
export * from "./lib/backup"
export * from "./lib/restore"
export * from "./lib/data-transfer"
4 changes: 4 additions & 0 deletions libs/device/feature/src/lib/api-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { SystemUtilsModule } from "system-utils/feature"
import { createSettingsService } from "Core/settings/containers/settings.container"
import { APIRestoreService } from "./restore"
import { DeviceSystemActionsService } from "./device-system-actions/device-system-actions.service"
import { APIDataTransferService } from "./data-transfer"

export class APIModule {
private apiConfigService: APIConfigService
Expand All @@ -30,6 +31,7 @@ export class APIModule {
private fileManager: FileManager
private deviceSystemActionsService: DeviceSystemActionsService
private serviceBridge: ServiceBridge
private apiDataTransferService: APIDataTransferService

constructor(
deviceManager: DeviceManager,
Expand All @@ -42,6 +44,7 @@ export class APIModule {
this.apiMenuService = new APIMenuService(deviceManager)
this.serverService = new ServerService()
this.backupService = new APIBackupService(deviceManager)
this.apiDataTransferService = new APIDataTransferService(deviceManager)
this.restoreService = new APIRestoreService(
deviceManager,
this.serviceBridge
Expand Down Expand Up @@ -73,6 +76,7 @@ export class APIModule {
this.fileTransferService,
this.fileManager,
this.deviceSystemActionsService,
this.apiDataTransferService,
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/

import { ResultObject } from "Core/core/builder"
import { ipcRenderer } from "electron-better-ipc"
import { APIDataTransferServiceEvents, DataTransfer } from "device/models"
import { DeviceId } from "Core/device/constants/device-id"

export const cancelDataTransferRequest = (
dataTransferId: number,
deviceId?: DeviceId
): Promise<ResultObject<DataTransfer>> => {
return ipcRenderer.callMain(APIDataTransferServiceEvents.CancelDataTransfer, {
dataTransferId,
deviceId,
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/

import { ResultObject } from "Core/core/builder"
import { ipcRenderer } from "electron-better-ipc"
import { APIDataTransferServiceEvents, DataTransfer } from "device/models"
import { DeviceId } from "Core/device/constants/device-id"

export const checkDataTransferRequest = (
dataTransferId: number,
deviceId?: DeviceId
): Promise<ResultObject<DataTransfer>> => {
return ipcRenderer.callMain(APIDataTransferServiceEvents.CheckDataTransfer, {
dataTransferId,
deviceId,
})
}
177 changes: 177 additions & 0 deletions libs/device/feature/src/lib/data-transfer/data-transfer.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/

import { Result, ResultObject } from "Core/core/builder"
import { IpcEvent } from "Core/core/decorators"
import { AppError } from "Core/core/errors"
import { DeviceManager } from "Core/device-manager/services"
import { DeviceId } from "Core/device/constants/device-id"
import { ApiResponse } from "Core/device/types/mudita-os"
import {
APIDataTransferServiceEvents,
DataTransferDomain,
DataTransferValidator200,
DataTransferValidator202,
GeneralError,
PreDataTransfer,
PreDataTransferValidator,
DataTransfer,
} from "device/models"
import random from "lodash/random"

export class APIDataTransferService {
constructor(private deviceManager: DeviceManager) {}

@IpcEvent(APIDataTransferServiceEvents.StartPreDataTransfer)
public async startPreDataTransfer({
domains,
deviceId,
}: {
domains: DataTransferDomain[]
deviceId?: DeviceId
}): Promise<ResultObject<PreDataTransfer>> {
const device = deviceId
? this.deviceManager.getAPIDeviceById(deviceId)
: this.deviceManager.apiDevice

if (!device) {
return Result.failed(new AppError(GeneralError.NoDevice, ""))
}

const dataTransferId = random(1, 100000)

const response = await device.request({
endpoint: "PRE_DATA_TRANSFER",
method: "POST",
body: {
dataTransferId,
domains,
},
})

if (response.ok) {
const startDataTransferResponse = PreDataTransferValidator(
domains
).safeParse(response.data.body)

return startDataTransferResponse.success
? Result.success(startDataTransferResponse.data)
: Result.failed(new AppError(GeneralError.IncorrectResponse, ""))
}

return Result.failed(new AppError(GeneralError.IncorrectResponse))
}

@IpcEvent(APIDataTransferServiceEvents.CheckDataTransfer)
public async checkDataTransfer({
dataTransferId,
deviceId,
}: {
dataTransferId: number
deviceId?: DeviceId
}): Promise<ResultObject<DataTransfer>> {
const device = deviceId
? this.deviceManager.getAPIDeviceById(deviceId)
: this.deviceManager.apiDevice

if (!device) {
return Result.failed(new AppError(GeneralError.NoDevice, ""))
}

const response = await device.request({
endpoint: "DATA_TRANSFER",
method: "GET",
body: {
dataTransferId,
},
})

return this.parseDataTransferResponse(response)
}

@IpcEvent(APIDataTransferServiceEvents.StartDataTransfer)
public async startDataTransfer({
dataTransferId,
deviceId,
}: {
dataTransferId: number
deviceId?: DeviceId
}): Promise<ResultObject<DataTransfer>> {
const device = deviceId
? this.deviceManager.getAPIDeviceById(deviceId)
: this.deviceManager.apiDevice

if (!device) {
return Result.failed(new AppError(GeneralError.NoDevice, ""))
}

const response = await device.request({
endpoint: "DATA_TRANSFER",
method: "POST",
body: {
dataTransferId,
},
})

return this.parseDataTransferResponse(response)
}

@IpcEvent(APIDataTransferServiceEvents.CancelDataTransfer)
public async cancelDataTransfer({
dataTransferId,
deviceId,
}: {
dataTransferId: number
deviceId?: DeviceId
}): Promise<ResultObject<undefined>> {
const device = deviceId
? this.deviceManager.getAPIDeviceById(deviceId)
: this.deviceManager.apiDevice

if (!device) {
return Result.failed(new AppError(GeneralError.NoDevice, ""))
}

const response = await device.request({
endpoint: "DATA_TRANSFER",
method: "DELETE",
body: {
dataTransferId,
},
})

if (response.ok) {
return Result.success(undefined)
}

return Result.failed(new AppError(GeneralError.IncorrectResponse))
}

private parseDataTransferResponse(
response: ResultObject<ApiResponse<unknown>, string | number, unknown>
) {
if (!response.ok) {
return Result.failed(response.error)
}

if (response.data.status === 200) {
const response200 = DataTransferValidator200.safeParse(response.data.body)
if (response200.success) {
return Result.success(response200.data)
}
return Result.success(response.data.body as DataTransfer)
}
if (response.data.status === 202) {
const response202 = DataTransferValidator202.safeParse(response.data.body)

if (response202.success) {
return Result.success(response202.data)
}
return Result.success(response.data.body as DataTransfer)
}

return Result.failed(new AppError(GeneralError.IncorrectResponse, ""))
}
}
10 changes: 10 additions & 0 deletions libs/device/feature/src/lib/data-transfer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/

export * from "./data-transfer.service"
export * from "./cancel-data-transfer.request"
export * from "./check-data-transfer.request"
export * from "./start-data-transfer.request"
export * from "./start-pre-data-transfer.request"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/

import { ResultObject } from "Core/core/builder"
import { ipcRenderer } from "electron-better-ipc"
import { APIDataTransferServiceEvents, DataTransfer } from "device/models"
import { DeviceId } from "Core/device/constants/device-id"

export const startDataTransferRequest = (
dataTransferId: number,
deviceId?: DeviceId
): Promise<ResultObject<DataTransfer>> => {
return ipcRenderer.callMain(APIDataTransferServiceEvents.StartDataTransfer, {
dataTransferId,
deviceId,
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/

import { ResultObject } from "Core/core/builder"
import { ipcRenderer } from "electron-better-ipc"
import {
APIDataTransferServiceEvents,
DataTransferDomain,
PreDataTransfer,
} from "device/models"
import { DeviceId } from "Core/device/constants/device-id"

export const startPreDataTransferRequest = (
domains: DataTransferDomain[],
deviceId?: DeviceId
): Promise<ResultObject<PreDataTransfer>> => {
return ipcRenderer.callMain(
APIDataTransferServiceEvents.StartPreDataTransfer,
{
domains,
deviceId,
}
)
}
Loading

0 comments on commit bd83355

Please sign in to comment.