diff --git a/src/components/ContentComponents/Konnector/KonnectorLaunch.tsx b/src/components/ContentComponents/Konnector/KonnectorLaunch.tsx index 180f20990668f49eaedcba650bea425cb4cea78a..e54fc2e6c83adb7b36f0bc640d10bc22d1d5b634 100644 --- a/src/components/ContentComponents/Konnector/KonnectorLaunch.tsx +++ b/src/components/ContentComponents/Konnector/KonnectorLaunch.tsx @@ -2,13 +2,13 @@ import React, { useEffect, useState } from 'react' import { withClient, Client } from 'cozy-client' import { translate } from 'cozy-ui/react/I18n' +import { Konnector, Trigger } from 'models' import { isKonnectorRunning } from 'cozy-harvest-lib/dist/helpers/triggers' import ConnectionFlow, { ERROR_EVENT, LOGIN_SUCCESS_EVENT, SUCCESS_EVENT, } from 'cozy-harvest-lib/dist/models/ConnectionFlow' -import { Trigger, Konnector } from 'doctypes' import Lottie from 'react-lottie' import * as loadingData from 'assets/anims/bounceloading.json' diff --git a/src/components/ContentComponents/Konnector/KonnectorLoginForm.tsx b/src/components/ContentComponents/Konnector/KonnectorLoginForm.tsx index 2731c89ebac345b696fcf9ac04eee3eccd8ce215..6d4532ca3c783b9815c7cb969a94b78515ca53c2 100644 --- a/src/components/ContentComponents/Konnector/KonnectorLoginForm.tsx +++ b/src/components/ContentComponents/Konnector/KonnectorLoginForm.tsx @@ -2,15 +2,14 @@ import React, { useState, useEffect } from 'react' import { withClient, Client } from 'cozy-client' import { translate } from 'cozy-ui/react/I18n' +import { Account, AccountAuthData, Trigger } from 'models' +import AccountService from 'services/account.service' +import ConnectionService from 'services/connection.service' import IFluidConfig from 'services/fluidConfigService' import StyledIconButton from 'components/CommonKit/IconButton/StyledIconButton' import StyledButton from 'components/CommonKit/Button/StyledButton' import TrailingIcon from 'assets/icons/ico/trailing-icon.svg' -import { ConnectionService } from 'services/connectionService' -import { Account, AccountAuthData } from 'models/account.model' -import { AccountService } from 'services/account.service' -import { Trigger } from 'doctypes' import iconGRDFLogo from 'assets/icons/visu/grdf-logo.svg' import iconEGLLogo from 'assets/icons/visu/egl-logo.svg' @@ -78,13 +77,12 @@ const KonnectorLoginForm: React.FC<KonnectorLoginFormProps> = ({ } const connect = async () => { - const connectionService = new ConnectionService( - client, + const connectionService = new ConnectionService(client) + const { account, trigger } = await connectionService.connectNewUser( fluidConfig.konnectorConfig.slug, login, password ) - const { account, trigger } = await connectionService.connectNewUser() if (!trigger) { setError(t('KONNECTORCONFIG.ERROR_ACCOUNT_CREATION')) setLoading(false) diff --git a/src/components/ContentComponents/Konnector/KonnectorOAuthForm.tsx b/src/components/ContentComponents/Konnector/KonnectorOAuthForm.tsx index 1955d01a4b73e12b4c9cd0eef2d53752cec3c5eb..055118ef6f92f4b7ed5aa9284e6ecab7646ff76e 100644 --- a/src/components/ContentComponents/Konnector/KonnectorOAuthForm.tsx +++ b/src/components/ContentComponents/Konnector/KonnectorOAuthForm.tsx @@ -2,11 +2,11 @@ import React from 'react' import { Client, withClient } from 'cozy-client' import { translate } from 'cozy-ui/react/I18n' -import { Konnector, Trigger } from 'doctypes' +import { Konnector, Trigger } from 'models' import OAuthForm from 'components/ContentComponents/OAuth/OAuthForm' import StyledButton from 'components/CommonKit/Button/StyledButton' -import { AccountService } from 'services/account.service' -import { TriggerService } from 'services/triggersService' +import AccountService from 'services/account.service' +import TriggerService from 'services/triggers.service' interface KonnectorOAuthFormProps { konnector: Konnector diff --git a/src/components/ContentComponents/Konnector/KonnectorResult.tsx b/src/components/ContentComponents/Konnector/KonnectorResult.tsx index fa257b02ef8597cee61d6f1d320d0b9f9bdb7ad2..ba93735d82051602a5aaaa6749aa4082135c4c0c 100644 --- a/src/components/ContentComponents/Konnector/KonnectorResult.tsx +++ b/src/components/ContentComponents/Konnector/KonnectorResult.tsx @@ -7,9 +7,9 @@ import { AppContext } from 'components/Contexts/AppContextProvider' import StyledButton from 'components/CommonKit/Button/StyledButton' import StyledBlackSpinner from 'components/CommonKit/Spinner/StyledBlackSpinner' -import { Account, Trigger, Konnector } from 'doctypes' -import { TriggerService } from 'services/triggersService' -import { AccountService } from 'services/account.service' +import { Account, Konnector, Trigger } from 'models' +import TriggerService from 'services/triggers.service' +import AccountService from 'services/account.service' import warningWhite from 'assets/icons/ico/warning-white.svg' import { isKonnectorRunning } from 'cozy-harvest-lib/dist/helpers/triggers' @@ -43,12 +43,11 @@ const KonnectorResult: React.FC<KonnectorResultProps> = ({ const context = useContext(AppContext) const updateState = async (_trigger: Trigger) => { - const triggerState = await TriggerService.fetchTriggerState( - client, - _trigger - ) + const triggerService = new TriggerService(client) + const triggerState = await triggerService.fetchTriggerState(_trigger) if (triggerState) { + console.log('TO CHECK - last sucess', triggerState) if (triggerState.last_success) { setLastExecutionDate( new Date(triggerState.last_success).toLocaleString() @@ -106,10 +105,8 @@ const KonnectorResult: React.FC<KonnectorResultProps> = ({ useEffect(() => { let subscribed = true async function getData() { - const _trigger = await TriggerService.fetchTriggerFromAccount( - client, - account - ) + const triggerService = new TriggerService(client) + const _trigger = await triggerService.getTrigger(account, konnector) if (subscribed && _trigger) { setTrigger(_trigger) await updateState(_trigger) diff --git a/src/components/ContentComponents/KonnectorViewer/KonnectorViewer.tsx b/src/components/ContentComponents/KonnectorViewer/KonnectorViewer.tsx index ddbdb3bd569071b42f9ef97e855acbd520d92cc0..ddd95f683a2293c7b5e874093aafddaf64fef882 100644 --- a/src/components/ContentComponents/KonnectorViewer/KonnectorViewer.tsx +++ b/src/components/ContentComponents/KonnectorViewer/KonnectorViewer.tsx @@ -23,12 +23,11 @@ const KonnectorViewer: React.FC<KonnectorViewerProps> = ({ useEffect(() => { let subscribed = true - const konnectorService = new KonnectorService( - client, - fluidConfig.konnectorConfig.slug - ) + const konnectorService = new KonnectorService(client) async function getData() { - const _konnector: Konnector = await konnectorService.fetchKonnector() + const _konnector: Konnector = await konnectorService.getKonnector( + fluidConfig.konnectorConfig.slug + ) if (subscribed && _konnector) { setKonnector(_konnector) } diff --git a/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx b/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx index cb32c937f5ae087d60d5dc2cb1eaf1914e03121b..98e5e6c6f756f3e46c072f05b71f6c114237a178 100644 --- a/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx +++ b/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx @@ -1,5 +1,4 @@ import React, { useState, useEffect, useRef } from 'react' -import { AccountService } from 'services/account.service' import { FluidType } from 'enum/fluid.enum' @@ -22,9 +21,10 @@ import KonnectorForm from 'components/ContentComponents/Konnector/KonnectorForm' import KonnectorResult from 'components/ContentComponents/Konnector/KonnectorResult' import KonnectorLaunch from 'components/ContentComponents/Konnector/KonnectorLaunch' -import { Konnector, Trigger, TriggerState } from 'doctypes' +import { Konnector, Trigger, TriggerState } from 'models' +import AccountService from 'services/account.service' +import TriggerService from 'services/triggers.service' import { JobState } from 'enum/jobState.enum' -import { TriggerService } from 'services/triggersService' interface KonnectorViewerCardProps { fluidConfig: IFluidConfig @@ -86,10 +86,11 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ ) } - const updateState = async (trigger: Trigger) => { - const triggerState = await TriggerService.fetchTriggerState(client, trigger) - if (triggerState) { - setTriggerState(triggerState) + const updateState = async (_trigger: Trigger) => { + const triggerService = new TriggerService(client) + const _triggerState = await triggerService.fetchTriggerState(_trigger) + if (_triggerState) { + setTriggerState(_triggerState) } } @@ -119,10 +120,8 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ const _account = await accountService.getAccountByType(konnector.slug) if (subscribed && _account) { setAccount(_account) - const _trigger = await TriggerService.fetchTriggerFromAccount( - client, - _account - ) + const triggerService = new TriggerService(client) + const _trigger = await triggerService.getTrigger(_account, konnector) if (subscribed && _trigger) { setTrigger(_trigger) await updateState(_trigger) diff --git a/src/doctypes/io-cozy-konnectors.ts b/src/doctypes/io-cozy-konnectors.ts index b8e9378bd68b1dcc9c0d7b3d5fbcfe339379e47a..1401e16525bf7644b02d994854a633a826d6cdd1 100644 --- a/src/doctypes/io-cozy-konnectors.ts +++ b/src/doctypes/io-cozy-konnectors.ts @@ -1,18 +1 @@ export const KONNECTORS_DOCTYPE = 'io.cozy.konnectors' - -export type Konnector = { - _id: string - name: string - slug: string - state: string -} - -export function isKonnector(konnector: any): konnector is Konnector { - return ( - konnector && - '_id' in konnector && - 'name' in konnector && - 'slug' in konnector && - 'state' in konnector - ) -} diff --git a/src/doctypes/io-cozy-triggers.ts b/src/doctypes/io-cozy-triggers.ts index 60e696f4ac1906bd6518670c2e709f1dffac04d1..6ebfc50d198c8c9bdca40a4427d3d98bef1caadd 100644 --- a/src/doctypes/io-cozy-triggers.ts +++ b/src/doctypes/io-cozy-triggers.ts @@ -1,35 +1 @@ export const TRIGGERS_DOCTYPE = 'io.cozy.triggers' - -export type Trigger = { - _id: string - type: string - worker: string - arguments: string - message: { - account: string - konnector: string - } -} - -export type TriggerState = { - trigger_id: string - status: string - last_error?: string - last_executed_job_id: string - last_execution: string - last_failed_job_id: string - last_failure: string - last_manual_execution: string - last_manual_job_id: string -} - -export function isTrigger(trigger: any): trigger is Trigger { - return ( - trigger && - '_id' in trigger && - 'type' in trigger && - 'worker' in trigger && - 'arguments' in trigger && - 'message' in trigger - ) -} diff --git a/src/models/account.model.ts b/src/models/account.model.ts index 7f9ad023f1d7d92fe1145e146dcde078cd00253e..c48c8f2e187820a861b4c780c8ffd68cb07bc1c9 100644 --- a/src/models/account.model.ts +++ b/src/models/account.model.ts @@ -1,5 +1,8 @@ -export interface Account { +export interface Account extends AccountAttributes { _id: string +} + +export interface AccountAttributes { account_type: string auth: AccountAuthData | AccountOAuthData identifier: string diff --git a/src/models/index.ts b/src/models/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..5b8c1a7e102c7c0aeacd0bb4fc7d457fc3dc5b3b --- /dev/null +++ b/src/models/index.ts @@ -0,0 +1,3 @@ +export * from './account.model' +export * from './konnector.model' +export * from './trigger.model' diff --git a/src/models/konnector.model.ts b/src/models/konnector.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..11bf9229b32fcb5a4d1734580813efdebf7d6ca0 --- /dev/null +++ b/src/models/konnector.model.ts @@ -0,0 +1,6 @@ +export interface Konnector { + _id: string + name: string + slug: string + state: string +} diff --git a/src/models/trigger.model.ts b/src/models/trigger.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..f72a874291b518bb427c1dce4b513446e9b581e5 --- /dev/null +++ b/src/models/trigger.model.ts @@ -0,0 +1,25 @@ +export interface Trigger extends TriggerAttributes { + _id: string +} + +export interface TriggerAttributes { + type: string + arguments: string + worker: string + message: { + account: string + konnector: string + } +} + +export interface TriggerState { + trigger_id: string + status: string + last_error?: string + last_executed_job_id: string + last_execution: string + last_failed_job_id: string + last_failure: string + last_manual_execution: string + last_manual_job_id: string +} diff --git a/src/services/account.service.ts b/src/services/account.service.ts index 6b50d0e69133d9f0fba29d6f758daaf98ef90efa..35067a831c24eaa27aa3a960cd20f11fbb2c3689 100644 --- a/src/services/account.service.ts +++ b/src/services/account.service.ts @@ -1,6 +1,5 @@ import { Client } from 'cozy-client' -import { Account, AccountAuthData } from 'models/account.model' -import { Konnector } from 'doctypes' +import { Account, AccountAttributes, AccountAuthData, Konnector } from 'models' import { build } from 'cozy-harvest-lib/dist/helpers/accounts' import { createAccount, @@ -9,24 +8,24 @@ import { updateAccount, } from 'cozy-harvest-lib/dist/connections/accounts' -export class AccountService { +export default class AccountService { private _client: Client constructor(_client: Client) { this._client = _client } - private buildAccountAttributes = ( + private buildAccountAttributes( konnector: Konnector, authData: AccountAuthData - ) => { + ): AccountAttributes { return build(konnector, authData) } - public createAccount = async ( + public async createAccount( konnector: Konnector, accountAuthData: AccountAuthData - ) => { + ): Promise<Account> { const accountAttributes = this.buildAccountAttributes( konnector, accountAuthData @@ -39,12 +38,12 @@ export class AccountService { return account } - public getAccount = async (id: string) => { + public async getAccount(id: string): Promise<Account> { const account: Account = await findAccount(this._client, id) return account } - public getAccountByType = async (type: string) => { + public async getAccountByType(type: string): Promise<Account> { const query = this._client .find('io.cozy.accounts') // eslint-disable-next-line @typescript-eslint/camelcase @@ -54,17 +53,17 @@ export class AccountService { return result.data[0] ? result.data[0] : null } - public updateAccount = async (account: Account) => { + public async updateAccount(account: Account): Promise<Account> { const updatedAccount: Account = await updateAccount(this._client, account) return updatedAccount } - public deleteAccount = async (account: Account) => { - const del = await deleteAccount(this._client, account) - return del + public async deleteAccount(account: Account): Promise<any> { + await deleteAccount(this._client, account) + return true } - public createIndexAccount = async () => { + public async createIndexAccount(): Promise<any> { const query = this._client .find('io.cozy.accounts') // eslint-disable-next-line @typescript-eslint/camelcase diff --git a/src/services/connection.service.ts b/src/services/connection.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..ade5f4f212d1147cb39244170329f8e79b832f8d --- /dev/null +++ b/src/services/connection.service.ts @@ -0,0 +1,54 @@ +import { Client } from 'cozy-client' +import { Account, AccountAuthData, Konnector, Trigger } from 'models' +import AccountService from 'services/account.service' +import TriggerService from 'services/triggers.service' +import KonnectorService from 'services/konnectorService' + +export default class ConnectionService { + private _client: Client + + constructor(_client: Client) { + this._client = _client + } + + public async connectNewUser( + konnectorId: string, + login: string, + password: string + ) { + // Retrieve konnector + const konnectorService = new KonnectorService(this._client) + const konnector: Konnector = await konnectorService.getKonnector( + konnectorId + ) + if (!konnector || !konnector.slug) { + throw new Error(`Could not find konnector for ${konnectorId}`) + } + // Creation of the account linked to the konnector retrieved + const accountAuthData: AccountAuthData = { + login: login, + password: password, + } + const accountService = new AccountService(this._client) + const account: Account = await accountService.createAccount( + konnector, + accountAuthData + ) + if (!account || !account._id) { + throw new Error(`Error during account creation`) + } + // creation of the trigger for the konnector retrieve and the created account + const triggersServices = new TriggerService(this._client) + const trigger: Trigger = await triggersServices.createTrigger( + account, + konnector + ) + if (!trigger) { + throw new Error(`Error during trigger creation`) + } + return { + account: account, + trigger: trigger, + } + } +} diff --git a/src/services/connectionService.ts b/src/services/connectionService.ts deleted file mode 100644 index a23c4a4d0a7d0d4703636e87814592b77714ae77..0000000000000000000000000000000000000000 --- a/src/services/connectionService.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Client } from 'cozy-client' -import { Account, AccountAuthData } from 'models/account.model' -import { Konnector, Trigger } from 'doctypes' -import { AccountService } from './account.service' -import { TriggerService } from './triggersService' -import KonnectorService from './konnectorService' - -export class ConnectionService { - constructor( - private _client: Client, - private _konnectorId: string, - private _login: string, - private _password: string - ) { - this._client = _client - this._konnectorId = _konnectorId - this._login = _login - this._password = _password - } - - connectNewUser = async () => { - // Retrieve konnector - const konnectorService = new KonnectorService( - this._client, - this._konnectorId - ) - const konnector: Konnector = await konnectorService.fetchKonnector() - if (!konnector || !konnector.slug) { - throw new Error(`Could not find konnector for ${this._konnectorId}`) - } - // Creation of the account linked to the konnector retrieved - const accountAuthData: AccountAuthData = { - login: this._login, - password: this._password, - } - const accountService = new AccountService(this._client) - const account: Account = await accountService.createAccount( - konnector, - accountAuthData - ) - if (!account || !account._id) { - throw new Error(`Error during account creation`) - } - // creation of the trigger for the konnector retrieve and the created account - const triggersServices = new TriggerService( - this._client, - account, - konnector - ) - const trigger: Trigger = await triggersServices.createTrigger() - if (!trigger) { - throw new Error(`Error during trigger creation`) - } - return { - account: account, - trigger: trigger, - } - } -} diff --git a/src/services/fluidService.ts b/src/services/fluidService.ts index fda691c98d676d0bb5df11b8d2e902ed54f81763..48565ca0da5ee9cc4f458805f410d7ca8532bcde 100644 --- a/src/services/fluidService.ts +++ b/src/services/fluidService.ts @@ -4,7 +4,8 @@ import { DateTime } from 'luxon' import FluidConfigService from 'services/fluidConfigService' import KonnectorService from 'services/konnectorService' import ConsumptionDataManager from 'services/consumptionDataManagerService' -import { AccountService } from 'services/account.service' +import AccountService from 'services/account.service' +import TriggerService from 'services/triggers.service' // eslint-disable-next-line @typescript-eslint/interface-name-prefix export interface IFluidStatus { @@ -34,30 +35,39 @@ export class FluidService { fluidConfig[FluidType.WATER].konnectorConfig.slug ), ]) + const konnectorService = new KonnectorService(this._client) + const [elecKonnector, gasKonnector, waterKonnector] = await Promise.all([ + konnectorService.getKonnector( + fluidConfig[FluidType.ELECTRICITY].konnectorConfig.slug + ), + konnectorService.getKonnector( + fluidConfig[FluidType.GAS].konnectorConfig.slug + ), + konnectorService.getKonnector( + fluidConfig[FluidType.WATER].konnectorConfig.slug + ), + ]) + const triggerService = new TriggerService(this._client) + const [elecTrigger, waterTrigger, gasTrigger] = await Promise.all([ + elecAccount && elecKonnector + ? triggerService.getTrigger(elecAccount, elecKonnector) + : null, + waterAccount && waterKonnector + ? triggerService.getTrigger(waterAccount, waterKonnector) + : null, + gasAccount && gasKonnector + ? triggerService.getTrigger(gasAccount, gasKonnector) + : null, + ]) const [ elecStatus, waterStatus, gasStatus, lastDataDates, ] = await Promise.all([ - elecAccount - ? new KonnectorService( - this._client, - fluidConfig[FluidType.ELECTRICITY].konnectorConfig.slug - ).getKonnectorLastState(elecAccount) - : null, - waterAccount - ? new KonnectorService( - this._client, - fluidConfig[FluidType.WATER].konnectorConfig.slug - ).getKonnectorLastState(waterAccount) - : null, - gasAccount - ? new KonnectorService( - this._client, - fluidConfig[FluidType.GAS].konnectorConfig.slug - ).getKonnectorLastState(gasAccount) - : null, + elecTrigger ? triggerService.fetchTriggerState(elecTrigger) : null, + waterTrigger ? triggerService.fetchTriggerState(waterTrigger) : null, + gasTrigger ? triggerService.fetchTriggerState(gasTrigger) : null, new ConsumptionDataManager(this._client).fetchAllLastDateData([ FluidType.ELECTRICITY, FluidType.WATER, diff --git a/src/services/initDataManagerService.ts b/src/services/initDataManagerService.ts index 1355a231e813ce07c4bc6d66eff6893ea85c70b0..ac20ee4cf5dc40e5c884dd6d7eef7f93a67198bb 100644 --- a/src/services/initDataManagerService.ts +++ b/src/services/initDataManagerService.ts @@ -26,7 +26,7 @@ import UserProfileDataManager from 'services/userProfileDataManagerService' import userProfileData from 'db/userProfileData.json' import KonnectorStatusService from 'services/konnectorStatusService' import KonnectorService from 'services/konnectorService' -import { AccountService } from 'services/account.service' +import AccountService from 'services/account.service' import { hashFile } from 'utils/hash' import { @@ -400,6 +400,7 @@ export default class InitDataManager { public async initIndex(): Promise<boolean | null> { try { const accountService = new AccountService(this._client) + const konnectorService = new KonnectorService(this._client) await Promise.all([ this.createIndex(EGL_DAY_DOCTYPE), this.createIndex(EGL_MONTH_DOCTYPE), @@ -412,7 +413,7 @@ export default class InitDataManager { this.createIndex(GRDF_HOUR_DOCTYPE), this.createIndex(GRDF_MONTH_DOCTYPE), this.createIndex(GRDF_YEAR_DOCTYPE), - KonnectorService.createIndexKonnector(this._client), + konnectorService.createIndexKonnector(), accountService.createIndexAccount(), ]) return true diff --git a/src/services/konnectorService.ts b/src/services/konnectorService.ts index 4443af4a1408df5b4afbfdab75e51dabfb591d46..f0fdea3034b7c16ba115bddb3217bb48ba8f87a6 100644 --- a/src/services/konnectorService.ts +++ b/src/services/konnectorService.ts @@ -1,83 +1,44 @@ import { Client } from 'cozy-client' -import { KONNECTORS_DOCTYPE, Konnector } from 'doctypes' -import { TriggerService, ITriggerState } from 'services/triggersService' +import { KONNECTORS_DOCTYPE } from 'doctypes' +import { Account, Konnector, TriggerState } from 'models' +import TriggerService from 'services/triggers.service' export default class KonnectorService { - private _konnector: Konnector | null + private _client: Client - constructor(private _client: Client, private _konnectorId: string) { - this._konnector = null + constructor(_client: Client) { this._client = _client - this._konnectorId = _konnectorId } - get konnector(): Konnector | null { - return this._konnector - } - - fetchKonnector = async () => { - if (!(this._client && this._konnectorId)) { - throw new Error( - 'KonnectorService : fetchKonnector - client or konnector id not found' - ) - } - try { - const { data } = await this._client.query( - this._client.find(KONNECTORS_DOCTYPE).where({ - _id: KONNECTORS_DOCTYPE + '/' + this._konnectorId, - }) - ) - const konnector: Konnector = data && data[0] - this._konnector = konnector - return konnector - } catch (error) { - throw error - } - } - - async getKonnectorLastTrigger(slug: string, accountId: string) { + public async getKonnector(id: string) { const { data } = await this._client.query( - this._client - .find('io.cozy.triggers') - .where({ 'message.konnector': slug, 'message.account': accountId }) - .sortBy([{ 'cozyMetadata.updatedAt': 'desc' }]) - .limitBy(1) + this._client.find(KONNECTORS_DOCTYPE).where({ + _id: KONNECTORS_DOCTYPE + '/' + id, + }) ) - const trigger = (data && data[0]) || null - return trigger + const konnector: Konnector = data && data[0] + return konnector } - async getKonnectorLastJob(slug: string) { - const query = this._client - .find('io.cozy.jobs') - .where({ 'message.konnector': slug }) - // eslint-disable-next-line @typescript-eslint/camelcase - .sortBy([{ finished_at: 'desc' }]) - .limitBy(1) - return await this._client.query(query) - } - - async getKonnectorLastState(account: Account): Promise<ITriggerState | null> { - const trigger = await this.getKonnectorLastTrigger( - this._konnectorId, - account.id - ) + public async getKonnectorLastState( + konnector: Konnector, + account: Account + ): Promise<TriggerState | null> { + const triggerService = new TriggerService(this._client) + const trigger = await triggerService.getTrigger(account, konnector) if (trigger) { - const triggerState = await TriggerService.fetchTriggerState( - this._client, - trigger - ) + const triggerState = await triggerService.fetchTriggerState(trigger) return triggerState } return null } - static createIndexKonnector = async (client: Client) => { - const query = client + public async createIndexKonnector() { + const query = this._client .find('io.cozy.konnectors') // eslint-disable-next-line @typescript-eslint/camelcase .where({ _id: 'index' }) .limitBy(1) - return await client.query(query) + return await this._client.query(query) } } diff --git a/src/services/konnectorStatusService.ts b/src/services/konnectorStatusService.ts index a796ac6254ada31c4569c6ba3eb77ba2720a994d..197ec6d23235bbaa926cc684deae77e126dd910b 100644 --- a/src/services/konnectorStatusService.ts +++ b/src/services/konnectorStatusService.ts @@ -1,8 +1,8 @@ import { Client } from 'cozy-client' -import { Konnector } from 'doctypes' +import { Konnector } from 'models' import triggersMutations from 'cozy-harvest-lib/dist/connections/triggers' import FluidConfigService from 'services/fluidConfigService' -import { AccountService } from 'services/account.service' +import AccountService from 'services/account.service' import { FluidType } from 'enum/fluid.enum' export default class KonnectorStatusService { diff --git a/src/services/triggers.service.ts b/src/services/triggers.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..40ced82db86737f6c95c5fe0eaa8a092c5374c69 --- /dev/null +++ b/src/services/triggers.service.ts @@ -0,0 +1,101 @@ +import { Client } from 'cozy-client' +import { + Account, + Konnector, + Trigger, + TriggerAttributes, + TriggerState, +} from 'models' +import { buildAttributes } from 'cozy-harvest-lib/dist/helpers/triggers' +import triggersMutations from 'cozy-harvest-lib/dist/connections/triggers' +import FluidConfig from 'services/fluidConfigService' + +export default class TriggerService { + private _client: Client + + constructor(_client: Client) { + this._client = _client + } + + private createTriggerAttributes(account: Account, konnector: Konnector) { + const fluidConfigService = new FluidConfig() + const cronArgs = fluidConfigService.getCronArgs() + const triggerAttributes: TriggerAttributes = buildAttributes( + account, + cronArgs, + null, + konnector + ) + return triggerAttributes + } + + public async createTrigger( + account: Account, + konnector: Konnector + ): Promise<Trigger> { + const triggerAttributes = this.createTriggerAttributes(account, konnector) + if (!triggerAttributes) { + throw new Error( + 'TriggersServices : createTrigger - _triggerAttributes not found' + ) + } + const trigger = await triggersMutations(this._client).createTrigger( + triggerAttributes + ) + return trigger + } + + public async getTrigger( + account: Account, + konnector: Konnector + ): Promise<Trigger> { + const query = this._client + .find('io.cozy.triggers') + .where({ + 'message.account': account._id, + 'message.konnector': konnector.slug, + }) + .sortBy([{ 'cozyMetadata.updatedAt': 'desc' }]) + .limitBy(1) + const result = await this._client.query(query) + return result.data[0] ? result.data[0] : null + } + + public static async fetchTriggerFromAccount( + client: Client, + account: Account + ) { + if (account == null) return null + const query = client + .find('io.cozy.triggers') + .where({ 'message.account': account._id }) + .sortBy([{ 'cozyMetadata.updatedAt': 'desc' }]) + .limitBy(1) + const result = await client.query(query) + return result.data[0] ? result.data[0] : null + } + + public async launchTrigger(trigger: Trigger): Promise<any> { + if (!trigger) { + throw new Error('TriggersServices : createTrigger - trigger not found') + } + console.log( + '%c Launched Trigger is : ' + trigger._id, + 'background: #222; color: white' + ) + const job = await triggersMutations(this._client).launchTrigger(trigger) + return job + } + + public async fetchTriggerState( + trigger: Trigger + ): Promise<TriggerState | null> { + if (trigger == null) return null + const triggerState = await this._client + .getStackClient() + .fetchJSON('GET', `/jobs/triggers/${trigger._id}`) + return triggerState.data.attributes.current_state + ? triggerState.data.attributes.current_state + : null + } +} diff --git a/src/services/triggersService.ts b/src/services/triggersService.ts deleted file mode 100644 index b675bd3e6a6b7a1ec073e22bc1c5c920238267df..0000000000000000000000000000000000000000 --- a/src/services/triggersService.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { Client } from 'cozy-client' -import { Account, Konnector, Trigger } from 'doctypes' -import triggersMutations from 'cozy-harvest-lib/dist/connections/triggers' -import FluidConfig from 'services/fluidConfigService' -import { DateTime } from 'luxon' - -// eslint-disable-next-line @typescript-eslint/interface-name-prefix -export interface ITriggerState { - last_error: string - last_executed_job_id: string - last_execution: string - last_failed_job_id: string - last_failure: string - last_manual_execution: string - last_manual_job_id: string - status: string - trigger_id: string -} - -export interface TriggerAttributes { - type: string - arguments: string - worker: string - message: { - account: string - konnector: string - } -} -export class TriggerService { - private _trigger: Trigger - private _triggerAttributes?: TriggerAttributes - - constructor( - private _client: Client, - private _account: Account, - private _konnector: Konnector - ) { - this._trigger = { - _id: '', - type: '', - worker: '', - arguments: '', - message: { - account: '', - konnector: '', - }, - } - this._client = _client - this._account = _account - this._konnector = _konnector - } - - get trigger(): Trigger { - return this._trigger - } - - private createTriggerAttributes = () => { - if (!(this._account._id && this._konnector.slug)) { - throw new Error( - 'TriggersServices : createTriggerAttribute - account _id or konnector slug not found' - ) - } - const fluidConfigService = new FluidConfig() - const cronArgs = fluidConfigService.getCronArgs() - const triggerAttributes: TriggerAttributes = { - type: '@cron', - arguments: cronArgs, - worker: 'konnector', - message: { - account: this._account._id, - konnector: this._konnector.slug, - }, - } - return triggerAttributes - } - - public createTrigger = async () => { - this._triggerAttributes = this.createTriggerAttributes() - if (!(this._triggerAttributes && this._client)) { - throw new Error( - 'TriggersServices : createTrigger - _triggerAttributes or _client not found' - ) - } - this._trigger = await triggersMutations(this._client).createTrigger( - this._triggerAttributes - ) - return this._trigger - } - - public setTrigger = (trigger: Trigger) => { - this._trigger = trigger - } - - public launchTrigger = async () => { - if (!this._trigger) { - throw new Error('TriggersServices : createTrigger - trigger not found') - } - console.log( - '%c Launched Trigger is : ' + this._trigger._id, - 'background: #222; color: white' - ) - const job = await triggersMutations(this._client).launchTrigger( - this._trigger - ) - return job - } - - public static fetchKonnectorAccountFromTrigger(trigger: any) { - if (trigger == null || trigger.message.account == null) return '' - return trigger.message - } - - public static fetchStateFromTrigger(trigger: any) { - if (trigger == null || trigger.current_state == null) return '' - const { current_state: state } = trigger - return state - } - - public static fetchDateFromTrigger(trigger: any) { - if (trigger == null || trigger.current_state == null) return '' - return DateTime.fromISO( - trigger.current_state.last_execution - ).toLocaleString(DateTime.DATETIME_MED) - } - - public static async fetchTriggerFromAccount( - client: Client, - account: Account - ) { - if (account == null) return null - const query = client - .find('io.cozy.triggers') - .where({ 'message.account': account._id }) - .sortBy([{ 'cozyMetadata.updatedAt': 'desc' }]) - .limitBy(1) - const result = await client.query(query) - return result.data[0] ? result.data[0] : null - } - - public static async fetchTriggerState(client: Client, trigger: Trigger) { - if (trigger == null) return null - const triggerState = await client - .getStackClient() - .fetchJSON('GET', `/jobs/triggers/${trigger._id}`) - return triggerState.data.attributes.current_state - ? triggerState.data.attributes.current_state - : null - } -}