@useparagon/core 0.0.1-canary.1

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.
Files changed (84) hide show
  1. package/package.json +63 -0
  2. package/src/event/event.interface.ts +18 -0
  3. package/src/event/index.ts +1 -0
  4. package/src/execution/context.constants.ts +9 -0
  5. package/src/execution/context.interface.ts +39 -0
  6. package/src/execution/context.ts +72 -0
  7. package/src/execution/context.utils.ts +53 -0
  8. package/src/execution/index.ts +2 -0
  9. package/src/index.ts +6 -0
  10. package/src/integration/custom-integration.interface.ts +20 -0
  11. package/src/integration/index.ts +2 -0
  12. package/src/integration/integration-config.interface.ts +19 -0
  13. package/src/integration/integration.interface.ts +16 -0
  14. package/src/operator/index.ts +2 -0
  15. package/src/operator/operator.interface.ts +6 -0
  16. package/src/operator/operators/BooleanTrue.ts +20 -0
  17. package/src/operator/operators/StringContains.ts +27 -0
  18. package/src/resolvers/index.ts +2 -0
  19. package/src/resolvers/resolver.utils.ts +157 -0
  20. package/src/resolvers/resolvers.interface.ts +369 -0
  21. package/src/secret/index.ts +1 -0
  22. package/src/secret/secret.interface.ts +4 -0
  23. package/src/stateMachine/index.ts +2 -0
  24. package/src/stateMachine/stateMachine.constants.ts +12 -0
  25. package/src/stateMachine/stateMachine.interface.ts +145 -0
  26. package/src/stateMachine/stateMachine.utils.ts +733 -0
  27. package/src/steps/index.ts +3 -0
  28. package/src/steps/library/action/action.interface.ts +69 -0
  29. package/src/steps/library/action/action.step.ts +70 -0
  30. package/src/steps/library/action/index.ts +2 -0
  31. package/src/steps/library/conditional/conditional.interface.ts +82 -0
  32. package/src/steps/library/conditional/conditional.step.ts +96 -0
  33. package/src/steps/library/conditional/conditional.utils.ts +110 -0
  34. package/src/steps/library/conditional/index.ts +2 -0
  35. package/src/steps/library/delay/delay.interface.ts +71 -0
  36. package/src/steps/library/delay/delay.step.ts +51 -0
  37. package/src/steps/library/delay/index.ts +2 -0
  38. package/src/steps/library/fanout/fanout.interface.ts +46 -0
  39. package/src/steps/library/fanout/fanout.step.ts +68 -0
  40. package/src/steps/library/fanout/index.ts +2 -0
  41. package/src/steps/library/function/function.interface.ts +69 -0
  42. package/src/steps/library/function/function.step.ts +55 -0
  43. package/src/steps/library/function/index.ts +2 -0
  44. package/src/steps/library/index.ts +7 -0
  45. package/src/steps/library/integrationRequest/index.ts +2 -0
  46. package/src/steps/library/integrationRequest/integrationRequest.interface.ts +79 -0
  47. package/src/steps/library/integrationRequest/integrationRequest.step.ts +100 -0
  48. package/src/steps/library/request/index.ts +2 -0
  49. package/src/steps/library/request/request.interface.ts +159 -0
  50. package/src/steps/library/request/request.step.ts +117 -0
  51. package/src/steps/library/response/index.ts +2 -0
  52. package/src/steps/library/response/response.interface.ts +50 -0
  53. package/src/steps/library/response/response.step.ts +68 -0
  54. package/src/steps/step.constants.ts +4 -0
  55. package/src/steps/step.interface-base.ts +81 -0
  56. package/src/steps/step.interface.ts +31 -0
  57. package/src/steps/step.ts +136 -0
  58. package/src/steps/step.utils.ts +103 -0
  59. package/src/triggers/cron/cron.interface.ts +94 -0
  60. package/src/triggers/cron/cron.step.ts +52 -0
  61. package/src/triggers/cron/cron.utils.ts +117 -0
  62. package/src/triggers/cron/index.ts +3 -0
  63. package/src/triggers/endpoint/endpoint.interface.ts +66 -0
  64. package/src/triggers/endpoint/endpoint.step.ts +61 -0
  65. package/src/triggers/endpoint/index.ts +2 -0
  66. package/src/triggers/event/event.interface.ts +43 -0
  67. package/src/triggers/event/event.step.ts +41 -0
  68. package/src/triggers/event/index.ts +2 -0
  69. package/src/triggers/index.ts +4 -0
  70. package/src/triggers/integrationEnabled/index.ts +2 -0
  71. package/src/triggers/integrationEnabled/integrationEnabled.interface.ts +29 -0
  72. package/src/triggers/integrationEnabled/integrationEnabled.step.ts +33 -0
  73. package/src/triggers/trigger.interface.ts +28 -0
  74. package/src/triggers/trigger.ts +25 -0
  75. package/src/user/index.ts +2 -0
  76. package/src/user/user.interface.ts +4 -0
  77. package/src/user/user.ts +6 -0
  78. package/src/utils/index.ts +1 -0
  79. package/src/utils/utils.ts +10 -0
  80. package/src/workflow/index.ts +2 -0
  81. package/src/workflow/workflow.interface.ts +50 -0
  82. package/src/workflow/workflow.ts +132 -0
  83. package/tsconfig.json +9 -0
  84. package/tsconfig.release.json +8 -0
@@ -0,0 +1,68 @@
1
+ import { DataType, TokenizedSource } from '../../../resolvers';
2
+ import {
3
+ resolveParamsToSources,
4
+ resolveToSource,
5
+ } from '../../../resolvers/resolver.utils';
6
+ import { Step } from '../../step';
7
+ import { StepType } from '../../step.interface';
8
+ import {
9
+ IResponseStep,
10
+ IResponseStepInit,
11
+ IResponseStepParameters,
12
+ ResponseTypeEnum,
13
+ } from './response.interface';
14
+
15
+ /**
16
+ * a step used for making HTTP Responses
17
+ */
18
+ export class ResponseStep extends Step implements IResponseStep {
19
+ /**
20
+ * the step type
21
+ * @type {StepType}
22
+ * @memberof Step
23
+ */
24
+ type: StepType.RESPONSE = StepType.RESPONSE;
25
+
26
+ /**
27
+ * configuration for the response step
28
+ * @type {IResponseStepParameters}
29
+ * @memberof ResponseStep
30
+ */
31
+ parameters: IResponseStepParameters;
32
+
33
+ /**
34
+ * initialization parameters
35
+ * @type {IResponseStepInit}
36
+ * @memberof ResponseStep
37
+ */
38
+ _parameters: IResponseStepInit;
39
+
40
+ constructor(params: IResponseStepInit) {
41
+ super(params);
42
+ this._parameters = params;
43
+ this.parameters = this.serializeParameters();
44
+ }
45
+
46
+ /**
47
+ * serialize parameters for storage
48
+ */
49
+ serializeParameters(): IResponseStepParameters {
50
+ const initParams: IResponseStepInit = this._parameters;
51
+
52
+ if (initParams.responseType === ResponseTypeEnum.FILE) {
53
+ return {
54
+ statusCode: initParams.statusCode,
55
+ bodyData: [],
56
+ bodyFile: resolveToSource(
57
+ initParams.body,
58
+ DataType.FILE,
59
+ ) as TokenizedSource<DataType.FILE>,
60
+ };
61
+ }
62
+
63
+ return {
64
+ statusCode: initParams.statusCode,
65
+ bodyData: resolveParamsToSources(initParams.body),
66
+ };
67
+ }
68
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * placeholder for step ids
3
+ */
4
+ export const UNSET_STEP_ID: string = '__UNSET_STEP_ID__';
@@ -0,0 +1,81 @@
1
+ import { IStep } from './step.interface';
2
+
3
+ /**
4
+ * the supported step types
5
+ */
6
+ export enum StepType {
7
+ ACTION = 'ACTION/CUSTOM',
8
+ ACTION_TRIGGER = 'TRIGGER/ACTION',
9
+ CRON = 'TRIGGER/CRON',
10
+ CUSTOM_INTEGRATION_REQUEST = 'ACTION/CUSTOM_INTEGRATION_REQUEST',
11
+ DELAY = 'ACTION/DELAY',
12
+ ENDPOINT = 'TRIGGER/ENDPOINT',
13
+ EVENT = 'TRIGGER/EVENT',
14
+ FUNCTION = 'ACTION/FUNCTION',
15
+ IFELSE = 'TRANSITION/IFELSE',
16
+ INTEGRATION_ENABLED = 'TRIGGER/INTEGRATION_ENABLED',
17
+ MAP = 'TRANSITION/MAP',
18
+ OAUTH = 'TRIGGER/OAUTH',
19
+ REDIRECT = 'ACTION/REDIRECT',
20
+ RESPONSE = 'ACTION/RESPONSE',
21
+ REQUEST = 'ACTION/REQUEST',
22
+ UNSELECTED_TRIGGER = 'TRIGGER/NONE',
23
+ }
24
+
25
+ /**
26
+ * step types that are valid triggers
27
+ */
28
+ export const TRIGGER_TYPES = [
29
+ StepType.UNSELECTED_TRIGGER,
30
+ StepType.CRON,
31
+ StepType.ENDPOINT,
32
+ StepType.OAUTH,
33
+ StepType.ACTION_TRIGGER,
34
+ StepType.EVENT,
35
+ StepType.INTEGRATION_ENABLED,
36
+ ];
37
+
38
+ /**
39
+ * parameters used to initialize a Step
40
+ */
41
+ export interface IBaseStepParameters extends Record<string, unknown> {}
42
+
43
+ /**
44
+ * a step used in a workflow
45
+ */
46
+ export interface IBaseStep {
47
+ /**
48
+ * the id of the step
49
+ */
50
+ id: string;
51
+
52
+ /**
53
+ * the step type
54
+ */
55
+ type: StepType;
56
+
57
+ /**
58
+ * configuration for the step
59
+ */
60
+ parameters: IBaseStepParameters;
61
+
62
+ /**
63
+ * the id of the step after the current step
64
+ */
65
+ next: string | null;
66
+
67
+ /**
68
+ * description of step
69
+ */
70
+ description?: string;
71
+
72
+ /**
73
+ * used for storing data used in migrations or (de)serialization transformations
74
+ */
75
+ readonly _migrations?: Record<string, unknown>;
76
+ }
77
+
78
+ /**
79
+ * key / value map of steps where the keys are the step ids
80
+ */
81
+ export type StepMap = Record<string, IStep>;
@@ -0,0 +1,31 @@
1
+ import { ICronStep } from '../triggers/cron/cron.interface';
2
+ import { IEndpointStep } from '../triggers/endpoint/endpoint.interface';
3
+ import { IEventStep } from '../triggers/event/event.interface';
4
+ import { IIntegrationEnabledStep } from '../triggers/integrationEnabled/integrationEnabled.interface';
5
+ import { IActionStep } from './library/action/action.interface';
6
+ import { IConditionalStep } from './library/conditional/conditional.interface';
7
+ import { IDelayStep } from './library/delay/delay.interface';
8
+ import { IFanOutStep } from './library/fanout/fanout.interface';
9
+ import { IFunctionStep } from './library/function/function.interface';
10
+ import { IIntegrationRequestStep } from './library/integrationRequest/integrationRequest.interface';
11
+ import { IRequestStep } from './library/request/request.interface';
12
+ import { IResponseStep } from './library/response/response.interface';
13
+
14
+ /**
15
+ * a union type comprised of the different step types
16
+ */
17
+ export type IStep =
18
+ | IActionStep
19
+ | IConditionalStep
20
+ | ICronStep
21
+ | IDelayStep
22
+ | IEndpointStep
23
+ | IEventStep
24
+ | IFanOutStep
25
+ | IFunctionStep
26
+ | IIntegrationEnabledStep
27
+ | IIntegrationRequestStep
28
+ | IRequestStep
29
+ | IResponseStep;
30
+
31
+ export * from './step.interface-base';
@@ -0,0 +1,136 @@
1
+ import { getRandomNumberInRange } from '../utils';
2
+ import { UNSET_STEP_ID } from './step.constants';
3
+ import {
4
+ IBaseStep,
5
+ IBaseStepParameters,
6
+ IStep,
7
+ StepType,
8
+ } from './step.interface';
9
+
10
+ /**
11
+ * a step used in a workflow
12
+ */
13
+ export abstract class Step<I = any, O extends IBaseStepParameters = any>
14
+ implements IBaseStep
15
+ {
16
+ /**
17
+ * the id of the step
18
+ *
19
+ * @type {string}
20
+ * @memberof Step
21
+ */
22
+ id: string = `${UNSET_STEP_ID}${getRandomNumberInRange(10000, 99999)}`;
23
+
24
+ /**
25
+ * configuration for the step
26
+ *
27
+ * @type {IBaseStepParameters}
28
+ * @memberof Step
29
+ */
30
+ abstract parameters: IBaseStepParameters;
31
+
32
+ /**
33
+ * the step type
34
+ *
35
+ * @abstract
36
+ * @type {StepType}
37
+ * @memberof Step
38
+ */
39
+ abstract type: StepType;
40
+
41
+ /**
42
+ * the next step in the sequence
43
+ *
44
+ * @private
45
+ * @type {Step}
46
+ * @memberof Step
47
+ */
48
+ private _next?: Step;
49
+
50
+ /**
51
+ * some steps needed workflowId in param like endpoint trigger
52
+ */
53
+ protected workflowId?: string;
54
+
55
+ /**
56
+ * used for storing data used in migrations or (de)serialization transformations
57
+ *
58
+ * @private
59
+ * @type {Record<string, unknown>}
60
+ * @memberof Step
61
+ */
62
+ readonly _migrations: Record<string, unknown> = {};
63
+
64
+ /**
65
+ * returns the id of the next step in the sequence
66
+ *
67
+ * @readonly
68
+ * @type {(string | null)}
69
+ * @memberof Step
70
+ */
71
+ get next(): string | null {
72
+ return this._next?.id ?? null;
73
+ }
74
+
75
+ constructor(_params: I) {}
76
+
77
+ /**
78
+ * sets a value in the migrations
79
+ *
80
+ * @param key
81
+ * @param value
82
+ */
83
+ setMigration(key: string, value: unknown): void {
84
+ this._migrations[key] = value;
85
+ }
86
+
87
+ /**
88
+ * sets workflowid
89
+ * @param workflowId
90
+ */
91
+ setWorkflowId(workflowId: string): void {
92
+ this.workflowId = workflowId;
93
+ }
94
+
95
+ /**
96
+ * used to specify the next Step in the sequence
97
+ * @param step the next Step in the sequence
98
+ */
99
+ nextStep(step: Step): Step {
100
+ this._next = step;
101
+ return step;
102
+ }
103
+
104
+ /**
105
+ * serialize parameters for storage
106
+ */
107
+ serializeParameters(): O {
108
+ return this.parameters as unknown as O;
109
+ }
110
+
111
+ /**
112
+ * serializes (to object)
113
+ * @returns
114
+ */
115
+ toObject(): IStep {
116
+ const step: IStep = {
117
+ id: this.id,
118
+ // @ts-ignore: ignore error; TODO: fix type conflicts
119
+ type: this.type,
120
+ // @ts-ignore: ignore error; TODO: fix type conflicts
121
+ parameters: this.serializeParameters(),
122
+ next: this._next?.id ?? null,
123
+ _migrations: this._migrations,
124
+ };
125
+
126
+ return step;
127
+ }
128
+
129
+ /**
130
+ * serializes (to string)
131
+ * @returns
132
+ */
133
+ toString(): string {
134
+ return JSON.stringify(this.toObject());
135
+ }
136
+ }
@@ -0,0 +1,103 @@
1
+ import { FanOutStep } from './library/fanout/fanout.step';
2
+ import { IStep, StepMap, StepType, TRIGGER_TYPES } from './step.interface';
3
+
4
+ /**
5
+ * determines if a step is a valid trigger step
6
+ *
7
+ * @param step
8
+ * @returns
9
+ */
10
+ export function isTrigger(step: IStep): boolean {
11
+ return TRIGGER_TYPES.includes(step.type);
12
+ }
13
+
14
+ /**
15
+ * finds the first trigger step in an array of steps
16
+ *
17
+ * @param steps
18
+ * @returns
19
+ */
20
+ export function getTriggerStep(steps: IStep[]): IStep | undefined {
21
+ return steps.find(isTrigger);
22
+ }
23
+
24
+ /**
25
+ * determines if a step is a conditional
26
+ *
27
+ * @param step
28
+ * @returns
29
+ */
30
+ export function isConditional(step: IStep): boolean {
31
+ return step.type === StepType.IFELSE;
32
+ }
33
+
34
+ /**
35
+ * determines if a step is a fanout
36
+ *
37
+ * @param step
38
+ * @returns
39
+ */
40
+ export function isFanout(step: IStep): step is FanOutStep {
41
+ return step.type === StepType.MAP;
42
+ }
43
+
44
+ /**
45
+ * converts an array of steps to a map where the keys are the step ids
46
+ *
47
+ * @param steps
48
+ * @returns
49
+ */
50
+ export function stepArrayToMap(steps: IStep[]): StepMap {
51
+ const stepMap: StepMap = {};
52
+ steps.forEach((step: IStep) => (stepMap[step.id] = step));
53
+ return stepMap;
54
+ }
55
+
56
+ /**
57
+ * converts a map of steps to an array
58
+ *
59
+ * @param stepMap
60
+ * @returns
61
+ */
62
+ export function stepMapToArray(stepMap: StepMap): IStep[] {
63
+ return Object.keys(stepMap).map((stepId: string) => stepMap[stepId]);
64
+ }
65
+
66
+ /**
67
+ * given a step and an array of steps, it determines if the step is in the list
68
+ *
69
+ * @param step
70
+ * @param stepList
71
+ * @returns
72
+ */
73
+ export function isStepInStepList(
74
+ step: IStep | undefined,
75
+ stepList: IStep[],
76
+ ): boolean {
77
+ return step && stepList.filter((s: IStep) => s.id === step.id).length > 0
78
+ ? true
79
+ : false;
80
+ }
81
+
82
+ /**
83
+ * combines two arrays of steps and removes duplicates
84
+ *
85
+ * @param a
86
+ * @param b
87
+ * @param createNewArray if true, a new array is created; otherwise the first array is modified
88
+ * @returns
89
+ */
90
+ export function concatAndDedupeStepLists(
91
+ a: IStep[],
92
+ b: IStep[],
93
+ createNewArray: boolean,
94
+ ): IStep[] {
95
+ const c: IStep[] = createNewArray ? [...a] : a;
96
+ for (const step of b) {
97
+ if (c.filter((s: IStep) => s.id === step.id).length === 0) {
98
+ c.push(step);
99
+ }
100
+ }
101
+
102
+ return c;
103
+ }
@@ -0,0 +1,94 @@
1
+ import { DataType, TokenizedSource } from '../../resolvers/';
2
+ import { IBaseStep, StepType } from '../../steps/step.interface';
3
+ import { ITriggerStepParameters } from '../trigger.interface';
4
+
5
+ export enum Unit {
6
+ SECONDS = 'SECONDS',
7
+ MINUTES = 'MINUTES',
8
+ HOURLY = 'HOURLY',
9
+ DAILY = 'DAILY',
10
+ WEEKLY = 'WEEKLY',
11
+ }
12
+
13
+ export enum Weekday {
14
+ MONDAY = 'MONDAY',
15
+ TUESDAY = 'TUESDAY',
16
+ WEDNESDAY = 'WEDNESDAY',
17
+ THURSDAY = 'THURSDAY',
18
+ FRIDAY = 'FRIDAY',
19
+ SATURDAY = 'SATURDAY',
20
+ SUNDAY = 'SUNDAY',
21
+ }
22
+
23
+ export type Time = {
24
+ minutes: number;
25
+ timezone: TokenizedSource<DataType.STRING> | string;
26
+ };
27
+
28
+ export type SecondsSchedule = { unit: Unit.SECONDS; seconds: number };
29
+ export type MinutesSchedule = { unit: Unit.MINUTES; minutes: number };
30
+ export type HourlySchedule = {
31
+ unit: Unit.HOURLY;
32
+ hours: number;
33
+ offset: number;
34
+ };
35
+ export type DailySchedule<T = Time> = {
36
+ unit: Unit.DAILY;
37
+ days: number;
38
+ time: T;
39
+ };
40
+ export type WeeklySchedule<T = Time> = {
41
+ unit: Unit.WEEKLY;
42
+ weekday: Weekday;
43
+ time: T;
44
+ };
45
+
46
+ export type Schedule =
47
+ | SecondsSchedule
48
+ | MinutesSchedule
49
+ | HourlySchedule
50
+ | DailySchedule
51
+ | WeeklySchedule;
52
+
53
+ export type Timezone = {
54
+ offset: string;
55
+ label: string;
56
+ tzCode: string;
57
+ };
58
+
59
+ /**
60
+ * parameters used for initializing a CronStep
61
+ */
62
+ export interface ICronStepInitParameters extends ITriggerStepParameters {
63
+ /**
64
+ * cron expression
65
+ */
66
+ cron: string;
67
+
68
+ /**
69
+ * timzone for cron
70
+ */
71
+ timezone: string;
72
+ }
73
+
74
+ /**
75
+ * parameters used for initializing a CronStep
76
+ */
77
+ export interface ICronStepParameters extends ITriggerStepParameters {
78
+ schedule: Schedule;
79
+ }
80
+
81
+ /**
82
+ * a step used for cron trigger
83
+ */
84
+ export interface ICronStep extends IBaseStep {
85
+ /**
86
+ * the step type
87
+ */
88
+ type: StepType.CRON;
89
+
90
+ /**
91
+ * configuration for the cron step
92
+ */
93
+ parameters: ICronStepParameters;
94
+ }
@@ -0,0 +1,52 @@
1
+ import { StepType } from '../../steps/step.interface';
2
+ import { TriggerStep } from '../trigger';
3
+ import {
4
+ ICronStep,
5
+ ICronStepInitParameters,
6
+ ICronStepParameters,
7
+ } from './cron.interface';
8
+ import { getSchedule } from './cron.utils';
9
+
10
+ /**
11
+ * a step used for cron trigger
12
+ */
13
+ export class CronStep extends TriggerStep implements ICronStep {
14
+ /**
15
+ * the step type
16
+ *
17
+ * @type {StepType}
18
+ * @memberof Step
19
+ */
20
+ type: StepType.CRON = StepType.CRON;
21
+
22
+ /**
23
+ * configuraiton for the cron step
24
+ *
25
+ * @type {ICronStepInitParameters}
26
+ * @memberof CronStep
27
+ */
28
+ private _parameters: ICronStepInitParameters;
29
+
30
+ /**
31
+ * configuration for the cron step
32
+ */
33
+ parameters: ICronStepParameters;
34
+
35
+ constructor(params: ICronStepInitParameters) {
36
+ super(params);
37
+ this._parameters = params;
38
+
39
+ this.parameters = this.serializeParameters();
40
+ }
41
+
42
+ /**
43
+ * serialize parameters for storage
44
+ */
45
+ serializeParameters(): ICronStepParameters {
46
+ const cronParameters: ICronStepInitParameters = this._parameters;
47
+ return {
48
+ ...this.parameters,
49
+ schedule: getSchedule(cronParameters.cron, cronParameters.timezone),
50
+ };
51
+ }
52
+ }
@@ -0,0 +1,117 @@
1
+ import { parseExpression } from 'cron-parser';
2
+
3
+ import { Schedule, Unit, Weekday } from './cron.interface';
4
+
5
+ /**
6
+ * get cron options from schedule
7
+ * @param schedule
8
+ * @returns
9
+ */
10
+ export const getCronOptions = (
11
+ schedule: Schedule,
12
+ ): { cron: string; timeZone?: string } => {
13
+ switch (schedule.unit) {
14
+ case Unit.SECONDS:
15
+ return { cron: `*/${schedule.seconds} * * * * *` };
16
+ case Unit.MINUTES:
17
+ return {
18
+ cron: `0 */${schedule.minutes} * * * *`,
19
+ };
20
+ case Unit.HOURLY:
21
+ return {
22
+ cron: `0 ${schedule.offset} */${schedule.hours} * * *`,
23
+ };
24
+ case Unit.DAILY:
25
+ const dailyMinutes: number = schedule.time.minutes % 60;
26
+ const dailyHours: number = Math.floor(schedule.time.minutes / 60);
27
+ return {
28
+ cron: `0 ${dailyMinutes} ${dailyHours} */${schedule.days} * *`,
29
+ timeZone: 'America/Los_Angeles',
30
+ };
31
+ case Unit.WEEKLY:
32
+ const weeklyMinutes: number = schedule.time.minutes % 60;
33
+ const weeklyHours: number = Math.floor(schedule.time.minutes / 60);
34
+ const weeklyWeekday: number =
35
+ Object.keys(Weekday).indexOf(schedule.weekday) + 1;
36
+ return {
37
+ cron: `0 ${weeklyMinutes} ${weeklyHours} * * ${weeklyWeekday}`,
38
+ timeZone: 'America/Los_Angeles',
39
+ };
40
+ }
41
+ };
42
+
43
+ /**
44
+ * get schedule from cron expression
45
+ * @param cron
46
+ */
47
+ export const getSchedule = (
48
+ cron: string,
49
+ timezone: string = 'America/Los_Angeles',
50
+ ): Schedule => {
51
+ const parser = parseExpression(cron);
52
+ const firstIteration: Date = parser.next().toDate();
53
+ const secondIteration: Date = parser.next().toDate();
54
+
55
+ const diffSeconds: number = Math.floor(
56
+ (secondIteration.getTime() - firstIteration.getTime()) / 1000,
57
+ );
58
+ if (diffSeconds < 60) {
59
+ return {
60
+ unit: Unit.SECONDS,
61
+ seconds: diffSeconds,
62
+ };
63
+ }
64
+
65
+ const diffMinutes: number = Math.floor(diffSeconds / 60);
66
+ if (diffMinutes < 60) {
67
+ return {
68
+ unit: Unit.MINUTES,
69
+ minutes: diffMinutes,
70
+ };
71
+ }
72
+
73
+ const diffHours: number = Math.floor(diffMinutes / 60);
74
+ if (diffHours < 24) {
75
+ return {
76
+ unit: Unit.HOURLY,
77
+ hours: diffHours,
78
+ offset: (diffMinutes / 60) % 60,
79
+ };
80
+ }
81
+
82
+ // update this
83
+ const diffDays: number = Math.floor(diffMinutes / 24);
84
+
85
+ if (diffDays < 7) {
86
+ return {
87
+ unit: Unit.DAILY,
88
+ days: diffDays,
89
+ time: {
90
+ minutes: 2,
91
+ timezone,
92
+ },
93
+ };
94
+ }
95
+
96
+ if (diffDays > 7) {
97
+ throw new Error(`not supported crons with more than weekly interval.`);
98
+ }
99
+
100
+ const weekday: Weekday = new Intl.DateTimeFormat('en-US', {
101
+ weekday: 'long',
102
+ })
103
+ .format(firstIteration)
104
+ .toUpperCase() as Weekday;
105
+
106
+ const minutes: number =
107
+ firstIteration.getHours() * 60 + firstIteration.getMinutes();
108
+
109
+ return {
110
+ unit: Unit.WEEKLY,
111
+ weekday,
112
+ time: {
113
+ minutes,
114
+ timezone: timezone,
115
+ },
116
+ };
117
+ };
@@ -0,0 +1,3 @@
1
+ export * from './cron.interface';
2
+ export * from './cron.step';
3
+ export * from './cron.utils';