Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add getCronFromFrequency to manifest models #1325

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth mentioning that the function requires 2 params, the minimal start hour and the max end hour, in the [0-24] interval? Which, I think, is a bit weird as it restricts the possibility to pass a custom function, but I don't know the use-case for this

* @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