@memberjunction/scheduling-actions 2.107.0

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.
@@ -0,0 +1,45 @@
1
+ import { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
2
+ import { BaseJobAction } from './BaseJobAction';
3
+ /**
4
+ * Update Scheduled Job action.
5
+ * Updates an existing scheduled job with new values for specified fields.
6
+ * Only provided fields will be updated; omitted fields remain unchanged.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * await RunAction({
11
+ * ActionName: 'Update Scheduled Job',
12
+ * Params: [
13
+ * { Name: 'JobID', Value: 'F3C4A5B6-...' },
14
+ * { Name: 'IsActive', Value: 'false' },
15
+ * { Name: 'Status', Value: 'Disabled' }
16
+ * ]
17
+ * });
18
+ * ```
19
+ */
20
+ export declare class UpdateScheduledJobAction extends BaseJobAction {
21
+ /**
22
+ * Updates an existing scheduled job
23
+ *
24
+ * @param params - The action parameters containing:
25
+ * - JobID (required): ID of the job to update
26
+ * - Name (optional): New job name
27
+ * - CronExpression (optional): New cron expression
28
+ * - IsActive (optional): New active flag
29
+ * - Status (optional): New status (Active, Disabled)
30
+ * - IntervalMinutes (optional): New interval in minutes
31
+ * - IntervalDays (optional): New interval in days
32
+ * - Description (optional): New description
33
+ *
34
+ * @returns ActionResultSimple with:
35
+ * - Success: true if job was updated successfully
36
+ * - ResultCode: SUCCESS, VALIDATION_ERROR, NOT_FOUND, NO_CHANGES, or FAILED
37
+ * - Message: Details about what was updated
38
+ */
39
+ protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
40
+ }
41
+ /**
42
+ * Loader function to prevent tree shaking
43
+ */
44
+ export declare function LoadUpdateScheduledJobAction(): void;
45
+ //# sourceMappingURL=UpdateJobAction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpdateJobAction.d.ts","sourceRoot":"","sources":["../src/UpdateJobAction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGnF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,wBAAyB,SAAQ,aAAa;IACvD;;;;;;;;;;;;;;;;;OAiBG;cACa,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAuG1F;AAED;;GAEG;AACH,wBAAgB,4BAA4B,SAE3C"}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.LoadUpdateScheduledJobAction = exports.UpdateScheduledJobAction = void 0;
10
+ const global_1 = require("@memberjunction/global");
11
+ const actions_1 = require("@memberjunction/actions");
12
+ const BaseJobAction_1 = require("./BaseJobAction");
13
+ /**
14
+ * Update Scheduled Job action.
15
+ * Updates an existing scheduled job with new values for specified fields.
16
+ * Only provided fields will be updated; omitted fields remain unchanged.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * await RunAction({
21
+ * ActionName: 'Update Scheduled Job',
22
+ * Params: [
23
+ * { Name: 'JobID', Value: 'F3C4A5B6-...' },
24
+ * { Name: 'IsActive', Value: 'false' },
25
+ * { Name: 'Status', Value: 'Disabled' }
26
+ * ]
27
+ * });
28
+ * ```
29
+ */
30
+ let UpdateScheduledJobAction = class UpdateScheduledJobAction extends BaseJobAction_1.BaseJobAction {
31
+ /**
32
+ * Updates an existing scheduled job
33
+ *
34
+ * @param params - The action parameters containing:
35
+ * - JobID (required): ID of the job to update
36
+ * - Name (optional): New job name
37
+ * - CronExpression (optional): New cron expression
38
+ * - IsActive (optional): New active flag
39
+ * - Status (optional): New status (Active, Disabled)
40
+ * - IntervalMinutes (optional): New interval in minutes
41
+ * - IntervalDays (optional): New interval in days
42
+ * - Description (optional): New description
43
+ *
44
+ * @returns ActionResultSimple with:
45
+ * - Success: true if job was updated successfully
46
+ * - ResultCode: SUCCESS, VALIDATION_ERROR, NOT_FOUND, NO_CHANGES, or FAILED
47
+ * - Message: Details about what was updated
48
+ */
49
+ async InternalRunAction(params) {
50
+ try {
51
+ const jobId = this.getParamValue(params, 'JobID');
52
+ if (!jobId) {
53
+ return {
54
+ Success: false,
55
+ ResultCode: 'VALIDATION_ERROR',
56
+ Message: 'JobID parameter is required'
57
+ };
58
+ }
59
+ // Load the existing job
60
+ const loadResult = await this.loadJob(jobId, params.ContextUser);
61
+ if (loadResult.error) {
62
+ return loadResult.error;
63
+ }
64
+ const job = loadResult.job;
65
+ // Track what changed
66
+ const updatedFields = [];
67
+ // Update Name if provided
68
+ const name = this.getParamValue(params, 'Name');
69
+ if (name && name !== job.Name) {
70
+ job.Name = name;
71
+ updatedFields.push('Name');
72
+ }
73
+ // Update CronExpression if provided
74
+ const cronExpression = this.getParamValue(params, 'CronExpression');
75
+ if (cronExpression && cronExpression !== job.CronExpression) {
76
+ // Validate cron expression
77
+ const cronValidation = this.validateCronExpression(cronExpression);
78
+ if (!cronValidation.valid) {
79
+ return {
80
+ Success: false,
81
+ ResultCode: 'VALIDATION_ERROR',
82
+ Message: cronValidation.error || 'Invalid cron expression'
83
+ };
84
+ }
85
+ job.CronExpression = cronExpression;
86
+ updatedFields.push('CronExpression');
87
+ }
88
+ // Update Status if provided
89
+ const status = this.getParamValue(params, 'Status');
90
+ if (status && status !== job.Status) {
91
+ // Validate status
92
+ const validStatuses = ['Active', 'Disabled', 'Expired', 'Paused', 'Pending'];
93
+ if (!validStatuses.includes(status)) {
94
+ return {
95
+ Success: false,
96
+ ResultCode: 'VALIDATION_ERROR',
97
+ Message: `Invalid status: ${status}. Valid values are: ${validStatuses.join(', ')}`
98
+ };
99
+ }
100
+ job.Status = status;
101
+ updatedFields.push('Status');
102
+ }
103
+ // Update Description if provided
104
+ const description = this.getParamValue(params, 'Description');
105
+ if (description !== undefined && description !== job.Description) {
106
+ job.Description = description || null;
107
+ updatedFields.push('Description');
108
+ }
109
+ // Check if any changes were made
110
+ if (updatedFields.length === 0) {
111
+ return {
112
+ Success: true,
113
+ ResultCode: 'NO_CHANGES',
114
+ Message: 'No fields were modified'
115
+ };
116
+ }
117
+ // Save changes
118
+ const saveResult = await job.Save();
119
+ if (!saveResult) {
120
+ return {
121
+ Success: false,
122
+ ResultCode: 'FAILED',
123
+ Message: `Failed to update scheduled job: ${job.LatestResult?.Message || 'Unknown error'}`
124
+ };
125
+ }
126
+ return {
127
+ Success: true,
128
+ ResultCode: 'SUCCESS',
129
+ Message: `Updated scheduled job '${job.Name}'. Changed fields: ${updatedFields.join(', ')}`
130
+ };
131
+ }
132
+ catch (error) {
133
+ return {
134
+ Success: false,
135
+ ResultCode: 'FAILED',
136
+ Message: `Error updating scheduled job: ${error instanceof Error ? error.message : String(error)}`
137
+ };
138
+ }
139
+ }
140
+ };
141
+ exports.UpdateScheduledJobAction = UpdateScheduledJobAction;
142
+ exports.UpdateScheduledJobAction = UpdateScheduledJobAction = __decorate([
143
+ (0, global_1.RegisterClass)(actions_1.BaseAction, 'Update Scheduled Job')
144
+ ], UpdateScheduledJobAction);
145
+ /**
146
+ * Loader function to prevent tree shaking
147
+ */
148
+ function LoadUpdateScheduledJobAction() {
149
+ // Stub function - ensures class is included in bundle
150
+ }
151
+ exports.LoadUpdateScheduledJobAction = LoadUpdateScheduledJobAction;
152
+ //# sourceMappingURL=UpdateJobAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpdateJobAction.js","sourceRoot":"","sources":["../src/UpdateJobAction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @memberjunction/scheduling-actions
3
+ *
4
+ * Actions for managing scheduled jobs in MemberJunction.
5
+ * These actions enable AI agents and workflows to query, create, update,
6
+ * delete, and execute scheduled jobs, as well as retrieve execution statistics.
7
+ */
8
+ export * from './BaseJobAction';
9
+ export * from './QueryJobsAction';
10
+ export * from './CreateJobAction';
11
+ export * from './UpdateJobAction';
12
+ export * from './DeleteJobAction';
13
+ export * from './ExecuteJobNowAction';
14
+ export * from './GetJobStatisticsAction';
15
+ /**
16
+ * Load all scheduling actions to prevent tree shaking.
17
+ * Call this function during application startup to ensure all action
18
+ * classes are registered and available for use.
19
+ */
20
+ export declare function LoadAllSchedulingActions(): void;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,cAAc,iBAAiB,CAAC;AAGhC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AAWzC;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAQ/C"}
package/dist/index.js ADDED
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ /**
3
+ * @memberjunction/scheduling-actions
4
+ *
5
+ * Actions for managing scheduled jobs in MemberJunction.
6
+ * These actions enable AI agents and workflows to query, create, update,
7
+ * delete, and execute scheduled jobs, as well as retrieve execution statistics.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
21
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.LoadAllSchedulingActions = void 0;
25
+ // Export base class
26
+ __exportStar(require("./BaseJobAction"), exports);
27
+ // Export all action classes
28
+ __exportStar(require("./QueryJobsAction"), exports);
29
+ __exportStar(require("./CreateJobAction"), exports);
30
+ __exportStar(require("./UpdateJobAction"), exports);
31
+ __exportStar(require("./DeleteJobAction"), exports);
32
+ __exportStar(require("./ExecuteJobNowAction"), exports);
33
+ __exportStar(require("./GetJobStatisticsAction"), exports);
34
+ // Import loader functions
35
+ const BaseJobAction_1 = require("./BaseJobAction");
36
+ const QueryJobsAction_1 = require("./QueryJobsAction");
37
+ const CreateJobAction_1 = require("./CreateJobAction");
38
+ const UpdateJobAction_1 = require("./UpdateJobAction");
39
+ const DeleteJobAction_1 = require("./DeleteJobAction");
40
+ const ExecuteJobNowAction_1 = require("./ExecuteJobNowAction");
41
+ const GetJobStatisticsAction_1 = require("./GetJobStatisticsAction");
42
+ /**
43
+ * Load all scheduling actions to prevent tree shaking.
44
+ * Call this function during application startup to ensure all action
45
+ * classes are registered and available for use.
46
+ */
47
+ function LoadAllSchedulingActions() {
48
+ (0, BaseJobAction_1.LoadBaseJobAction)();
49
+ (0, QueryJobsAction_1.LoadQueryScheduledJobsAction)();
50
+ (0, CreateJobAction_1.LoadCreateScheduledJobAction)();
51
+ (0, UpdateJobAction_1.LoadUpdateScheduledJobAction)();
52
+ (0, DeleteJobAction_1.LoadDeleteScheduledJobAction)();
53
+ (0, ExecuteJobNowAction_1.LoadExecuteScheduledJobNowAction)();
54
+ (0, GetJobStatisticsAction_1.LoadGetScheduledJobStatisticsAction)();
55
+ }
56
+ exports.LoadAllSchedulingActions = LoadAllSchedulingActions;
57
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;;AAEH,oBAAoB;AACpB,kDAAgC;AAEhC,4BAA4B;AAC5B,oDAAkC;AAClC,oDAAkC;AAClC,oDAAkC;AAClC,oDAAkC;AAClC,wDAAsC;AACtC,2DAAyC;AAEzC,0BAA0B;AAC1B,mDAAoD;AACpD,uDAAiE;AACjE,uDAAiE;AACjE,uDAAiE;AACjE,uDAAiE;AACjE,+DAAyE;AACzE,qEAA+E;AAE/E;;;;GAIG;AACH,SAAgB,wBAAwB;IACpC,IAAA,iCAAiB,GAAE,CAAC;IACpB,IAAA,8CAA4B,GAAE,CAAC;IAC/B,IAAA,8CAA4B,GAAE,CAAC;IAC/B,IAAA,8CAA4B,GAAE,CAAC;IAC/B,IAAA,8CAA4B,GAAE,CAAC;IAC/B,IAAA,sDAAgC,GAAE,CAAC;IACnC,IAAA,4DAAmC,GAAE,CAAC;AAC1C,CAAC;AARD,4DAQC"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@memberjunction/scheduling-actions",
3
+ "version": "2.107.0",
4
+ "description": "MemberJunction: Scheduling Actions - agentic tools for managing scheduled jobs",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "/dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "watch": "tsc --watch"
13
+ },
14
+ "author": "MemberJunction.com",
15
+ "license": "ISC",
16
+ "dependencies": {
17
+ "@memberjunction/global": "2.100.3",
18
+ "@memberjunction/core": "2.100.3",
19
+ "@memberjunction/core-entities": "2.107.0",
20
+ "@memberjunction/actions": "2.107.0",
21
+ "@memberjunction/actions-base": "2.107.0",
22
+ "@memberjunction/scheduling-base-types": "2.107.0",
23
+ "cron-parser": "^4.9.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "20.14.2",
27
+ "typescript": "^5.4.5"
28
+ }
29
+ }