Skip to content

Commit

Permalink
feat: Add getCronFromFrequency to manifest models
Browse files Browse the repository at this point in the history
This feature is imported from harvest and allows to get the cron string
from a given frequency like 'daily'.

This cron string will configure the trigger associated to the konnector
  • Loading branch information
doubleface committed Mar 8, 2023
1 parent b15f653 commit 36e7d16
Show file tree
Hide file tree
Showing 8 changed files with 460 additions and 8 deletions.
55 changes: 55 additions & 0 deletions docs/api/cozy-client/interfaces/manifest.FrequencyOptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[cozy-client](../README.md) / [manifest](../modules/manifest.md) / FrequencyOptions

# Interface: FrequencyOptions<>

[manifest](../modules/manifest.md).FrequencyOptions

frequency options object

## Properties

### dayOfMonth

**dayOfMonth**: `number`

day of the month

*Defined in*

[packages/cozy-client/src/models/manifest.js:329](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L329)

***

### dayOfWeek

**dayOfWeek**: `number`

day of the week

*Defined in*

[packages/cozy-client/src/models/manifest.js:330](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L330)

***

### hours

**hours**: `number`

hours

*Defined in*

[packages/cozy-client/src/models/manifest.js:331](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L331)

***

### minutes

**minutes**: `number`

minutes

*Defined in*

[packages/cozy-client/src/models/manifest.js:332](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L332)
29 changes: 29 additions & 0 deletions docs/api/cozy-client/interfaces/manifest.randomDayTimeResult.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[cozy-client](../README.md) / [manifest](../modules/manifest.md) / randomDayTimeResult

# Interface: randomDayTimeResult<>

[manifest](../modules/manifest.md).randomDayTimeResult

## Properties

### hours

**hours**: `number`

hours

*Defined in*

[packages/cozy-client/src/models/manifest.js:323](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L323)

***

### minutes

**minutes**: `number`

minutes

*Defined in*

[packages/cozy-client/src/models/manifest.js:324](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L324)
97 changes: 90 additions & 7 deletions docs/api/cozy-client/modules/manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

# Namespace: manifest

## Interfaces

* [FrequencyOptions](../interfaces/manifest.FrequencyOptions.md)
* [randomDayTimeResult](../interfaces/manifest.randomDayTimeResult.md)

## Variables

### ROLE_IDENTIFIER
Expand All @@ -22,7 +27,7 @@ Legacy login fields declared by some konnectors

*Defined in*

[packages/cozy-client/src/models/manifest.js:11](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L11)
[packages/cozy-client/src/models/manifest.js:21](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L21)

## Functions

Expand All @@ -42,7 +47,59 @@ Legacy login fields declared by some konnectors

*Defined in*

[packages/cozy-client/src/models/manifest.js:63](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L63)
[packages/cozy-client/src/models/manifest.js:73](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L73)

***

### getCronFromFrequency

**getCronFromFrequency**(`frequency`, `options?`): `string`

Build a cron string for given frequency with given options
See https://docs.cozy.io/en/cozy-stack/jobs/#cron-syntax

*Parameters*

| Name | Type | Description |
| :------ | :------ | :------ |
| `frequency` | `"hourly"` | `"daily"` | `"weekly"` | `"monthly"` | Frequency |
| `options` | [`FrequencyOptions`](../interfaces/manifest.FrequencyOptions.md) | - |

*Returns*

`string`

* The cron definition for trigger

*Defined in*

[packages/cozy-client/src/models/manifest.js:280](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L280)

***

### getCronFromKonnector

**getCronFromKonnector**(`konnector`, `startDate?`, `randomDayTimeFn?`): `string`

Build a cron string for given konnector and from a given start date

*Parameters*

| Name | Type | Default value | Description |
| :------ | :------ | :------ | :------ |
| `konnector` | `IOCozyKonnector` | `undefined` | io.cozy.konnectors object |
| `startDate` | `Date` | `undefined` | start date |
| `randomDayTimeFn` | `Function` | `randomDayTime` | - |

*Returns*

`string`

* The cron definition for trigger

*Defined in*

[packages/cozy-client/src/models/manifest.js:307](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L307)

***

Expand All @@ -66,7 +123,7 @@ The key for the identifier field, example 'login'

*Defined in*

[packages/cozy-client/src/models/manifest.js:161](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L161)
[packages/cozy-client/src/models/manifest.js:171](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L171)

***

Expand All @@ -86,7 +143,33 @@ The key for the identifier field, example 'login'

*Defined in*

[packages/cozy-client/src/models/manifest.js:67](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L67)
[packages/cozy-client/src/models/manifest.js:77](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L77)

***

### randomDayTime

**randomDayTime**(`start?`, `end?`, `randomize?`): [`randomDayTimeResult`](../interfaces/manifest.randomDayTimeResult.md)

Returns an hour of the day between two hours given in parameters

*Parameters*

| Name | Type | Default value | Description |
| :------ | :------ | :------ | :------ |
| `start` | `number` | `0` | minimal start hour |
| `end` | `number` | `1` | maximal end hour |
| `randomize` | `Function` | `undefined` | The function used to generate random values |

*Returns*

[`randomDayTimeResult`](../interfaces/manifest.randomDayTimeResult.md)

Object containing two atributes : hours and minutes

*Defined in*

[packages/cozy-client/src/models/manifest.js:248](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L248)

***

Expand All @@ -108,7 +191,7 @@ Normalize app manifest, retro-compatibility for old manifests

*Defined in*

[packages/cozy-client/src/models/manifest.js:77](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L77)
[packages/cozy-client/src/models/manifest.js:87](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L87)

***

Expand All @@ -132,7 +215,7 @@ sanitized categories

*Defined in*

[packages/cozy-client/src/models/manifest.js:56](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L56)
[packages/cozy-client/src/models/manifest.js:66](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L66)

***

Expand All @@ -156,4 +239,4 @@ Ensures that fields has at least one field with the role 'identifier'

*Defined in*

[packages/cozy-client/src/models/manifest.js:130](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L130)
[packages/cozy-client/src/models/manifest.js:140](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/manifest.js#L140)
105 changes: 105 additions & 0 deletions packages/cozy-client/src/models/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ import findKey from 'lodash/findKey'

export const ROLE_IDENTIFIER = 'identifier'

const DAILY = 'daily'
const HOURLY = 'hourly'
const WEEKLY = 'weekly'
const MONTHLY = 'monthly'
const VALID_FREQUENCIES = [DAILY, HOURLY, WEEKLY, MONTHLY]

const DEFAULT_FREQUENCY = WEEKLY
// By default konnectors are run at random hour between 12:00PM and 05:00AM.
const DEFAULT_TIME_INTERVAL = [0, 5]

/**
* Legacy login fields declared by some konnectors
*/
Expand Down Expand Up @@ -226,3 +236,98 @@ const sanitizeFields = _flow([
sanitizeRequired,
sanitizeEncrypted
])

/**
* Returns an hour of the day between two hours given in parameters
*
* @param {number} start minimal start hour
* @param {number} end maximal end hour
* @param {function} randomize The function used to generate random values
* @returns {randomDayTimeResult} Object containing two atributes : hours and minutes
*/
export const randomDayTime = (
start = 0,
end = 1,
randomize = (min, max) => Math.random() * (max - min) + min
) => {
if (typeof start !== 'number')
throw new Error('Parameter start must be a number')
if (typeof end !== 'number') throw new Error('Parameter end must be a number')

if (typeof randomize !== 'function')
throw new Error('Parameter randomize must be a function')

if (start < 0 || end > 24) throw new Error('interval must be inside [0, 24]')

const r = randomize(start, end)
const hours = Math.floor(r)
const minutes = Math.floor((r - hours) * 60)

if (hours < 0 || hours > 23)
throw new Error('randomize function returns invalid hour value')

return { hours, minutes }
}

/**
* Build a cron string for given frequency with given options
* See https://docs.cozy.io/en/cozy-stack/jobs/#cron-syntax
*
* @param {'hourly'|'daily'|'weekly'|'monthly'} frequency Frequency
* @param {FrequencyOptions} [options] - FrequencyOptions object
* @returns {String} - The cron definition for trigger
*/
export const getCronFromFrequency = (frequency, options = {}) => {
const { dayOfMonth = 1, dayOfWeek = 1, hours = 0, minutes = 0 } = options
const sanitizedFrequency = VALID_FREQUENCIES.includes(frequency)
? frequency
: DEFAULT_FREQUENCY

switch (sanitizedFrequency) {
case DAILY:
return `0 ${minutes} ${hours} * * *`
case HOURLY:
return `0 ${minutes} * * * *`
case MONTHLY:
return `0 ${minutes} ${hours} ${dayOfMonth} * *`
default:
// also WEEKLY
return `0 ${minutes} ${hours} * * ${dayOfWeek}`
}
}

/**
* Build a cron string for given konnector and from a given start date
*
* @param {import('../types').IOCozyKonnector} konnector - io.cozy.konnectors object
* @param {Date} startDate - start date
* @param {function} [randomDayTimeFn] - function generating random hours and minutes
* @returns {String} - The cron definition for trigger
*/
export const getCronFromKonnector = (
konnector,
startDate = new Date(),
randomDayTimeFn = randomDayTime
) =>
getCronFromFrequency(konnector.frequency, {
...randomDayTimeFn.apply(
null,
konnector.time_interval || DEFAULT_TIME_INTERVAL
),
dayOfWeek: startDate.getDay(),
dayOfMonth: startDate.getDate()
})

/**
* @typedef {object} randomDayTimeResult
* @property {number} hours - hours
* @property {number} minutes - minutes
*/

/**
* @typedef {object} FrequencyOptions - frequency options object
* @property {Number} [dayOfMonth] - day of the month
* @property {Number} [dayOfWeek] - day of the week
* @property {Number} [hours] - hours
* @property {Number} [minutes] - minutes
*/
Loading

0 comments on commit 36e7d16

Please sign in to comment.