@openinc/parse-server-opendash 3.24.6 → 3.25.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,11 @@
1
+ import { GraphEventResponse } from "../types/Event";
2
+ export type ScheduleCronTimestamp = {
3
+ startData: Date;
4
+ endData?: Date;
5
+ number: number;
6
+ unit: "days" | "weeks" | "months";
7
+ };
8
+ export declare function eventToSchedule(event: GraphEventResponse): {
9
+ timestamp: ScheduleCronTimestamp;
10
+ schedule_type: "timestamp";
11
+ } | undefined;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.eventToSchedule = eventToSchedule;
4
+ function eventToSchedule(event) {
5
+ const recurrence = event?.recurrence;
6
+ if (!recurrence)
7
+ return undefined;
8
+ const pattern = recurrence.pattern;
9
+ const range = recurrence.range;
10
+ if (!pattern || !range || !pattern.type)
11
+ return undefined;
12
+ let unit;
13
+ switch (pattern.type) {
14
+ case "daily":
15
+ unit = "days";
16
+ break;
17
+ case "weekly":
18
+ unit = "weeks";
19
+ break;
20
+ case "absoluteMonthly":
21
+ case "relativeMonthly":
22
+ unit = "months";
23
+ break;
24
+ default:
25
+ // unsupported recurrence type
26
+ return undefined;
27
+ }
28
+ const interval = typeof pattern.interval === "number" && pattern.interval > 0
29
+ ? pattern.interval
30
+ : 1;
31
+ // Prefer explicit range.startDate, fallback to event.start.dateTime
32
+ let startData;
33
+ if (range?.startDate) {
34
+ // range.startDate is YYYY-MM-DD
35
+ startData = new Date(range.startDate + "T00:00:00Z");
36
+ }
37
+ else if (event.start?.dateTime) {
38
+ startData = new Date(event.start.dateTime);
39
+ }
40
+ // For end, prefer range.endDate. If range.type === 'noEnd' leave undefined.
41
+ let endData;
42
+ if (range?.type === "endDate" && range?.endDate) {
43
+ endData = new Date(range.endDate + "T00:00:00Z");
44
+ }
45
+ else if (event.end?.dateTime) {
46
+ endData = new Date(event.end.dateTime);
47
+ }
48
+ if (!startData)
49
+ return undefined;
50
+ return {
51
+ schedule_type: "timestamp",
52
+ timestamp: {
53
+ startData,
54
+ endData,
55
+ number: interval,
56
+ unit,
57
+ },
58
+ };
59
+ }
@@ -0,0 +1,3 @@
1
+ import { Maintenance_Schedule } from "../../../../../types";
2
+ import { GraphEvent } from "../types/Event";
3
+ export declare function scheduleToEvent(schedule: Maintenance_Schedule): Promise<GraphEvent | undefined>;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scheduleToEvent = scheduleToEvent;
4
+ async function scheduleToEvent(schedule) {
5
+ console.log("Converting Schedule to Event...");
6
+ try {
7
+ await schedule.fetchWithInclude("template");
8
+ }
9
+ catch (error) {
10
+ console.error("Error fetching template:", error);
11
+ }
12
+ const template = schedule.get("template");
13
+ const templateCron = template?.get("cron");
14
+ const scheduleCron = schedule.get("cron");
15
+ const start = scheduleCron?.timestamp?.startDate ?? templateCron?.timestamp?.startDate;
16
+ const end = scheduleCron?.timestamp?.endDate ?? templateCron?.timestamp?.endDate;
17
+ const interval = scheduleCron?.timestamp?.number ?? templateCron?.timestamp?.number;
18
+ const unit = scheduleCron?.timestamp?.unit ?? templateCron?.timestamp?.unit;
19
+ if (!start || !end || !interval || !unit) {
20
+ console.log("Insufficient data to create event from schedule.");
21
+ return;
22
+ }
23
+ const event = {
24
+ subject: schedule.get("title"),
25
+ start: {
26
+ // for single-day/all-day events we use date-only; keep full ISO otherwise
27
+ dateTime: start.toISOString().slice(0, 19),
28
+ timeZone: "UTC",
29
+ },
30
+ end: {
31
+ dateTime: end.toISOString().slice(0, 19),
32
+ timeZone: "UTC",
33
+ },
34
+ isAllDay: true,
35
+ };
36
+ // Helper to format date as YYYY-MM-DD for recurrence range
37
+ const toDateOnly = (d) => d.toISOString().slice(0, 10);
38
+ // determine pattern type and additional fields
39
+ let pattern = { interval };
40
+ if (unit === "days") {
41
+ pattern.type = "daily";
42
+ }
43
+ else if (unit === "weeks") {
44
+ pattern.type = "weekly";
45
+ // include the weekday of the start date so weekly recurrences occur on that weekday
46
+ const dayNames = [
47
+ "Sunday",
48
+ "Monday",
49
+ "Tuesday",
50
+ "Wednesday",
51
+ "Thursday",
52
+ "Friday",
53
+ "Saturday",
54
+ ];
55
+ pattern.daysOfWeek = [dayNames[start.getUTCDay()]];
56
+ pattern.firstDayOfWeek = "Monday";
57
+ }
58
+ else if (unit === "months") {
59
+ pattern.type = "absoluteMonthly";
60
+ // Graph uses dayOfMonth for absoluteMonthly
61
+ pattern.dayOfMonth = start.getUTCDate();
62
+ }
63
+ else {
64
+ // unsupported unit -> skip recurrence
65
+ pattern = null;
66
+ }
67
+ if (pattern) {
68
+ event.recurrence = {
69
+ pattern,
70
+ range: {
71
+ type: "endDate",
72
+ startDate: toDateOnly(start),
73
+ endDate: toDateOnly(end),
74
+ },
75
+ };
76
+ // if event is all-day, set start/end to date-only values (Graph expects dates)
77
+ if (event.isAllDay) {
78
+ event.start.dateTime = toDateOnly(start);
79
+ // Graph's endDate in event object is exclusive for all-day events; keep as provided for recurrence range
80
+ // Set end to next day to represent an all-day event that begins and ends the same day
81
+ const endForEvent = new Date(start);
82
+ endForEvent.setUTCDate(endForEvent.getUTCDate() + 1);
83
+ event.end.dateTime = toDateOnly(endForEvent);
84
+ }
85
+ }
86
+ console.log("Schedule converted to Event:", event);
87
+ return event;
88
+ }
@@ -0,0 +1,34 @@
1
+ import { GraphEvent, GraphEventResponse } from "../types/Event";
2
+ /**
3
+ * Manager for calendar operations via Microsoft Graph API
4
+ */
5
+ export declare class CalendarManager {
6
+ isValid: boolean;
7
+ private getAccess;
8
+ /**
9
+ * Create a new event in the calendar
10
+ * @param event The event data to create
11
+ * @returns the created event response
12
+ */
13
+ createEvent(event: GraphEvent): Promise<GraphEventResponse | undefined>;
14
+ /**
15
+ * Update an event in the calendar
16
+ * @param eventId The ID of the event to update
17
+ * @param event The updated event data
18
+ * @returns
19
+ */
20
+ updateEvent(eventId: string, event: Partial<GraphEvent>): Promise<unknown>;
21
+ /**
22
+ * Delete an event from the calendar
23
+ * @param eventId The ID of the event to delete
24
+ * @returns whether the deletion was successful
25
+ */
26
+ deleteEvent(eventId: string): Promise<boolean | undefined>;
27
+ /**
28
+ * Fetch all events in calendar
29
+ * @returns the list of events
30
+ */
31
+ fetchEvents(): Promise<{
32
+ value: GraphEventResponse[];
33
+ } | undefined>;
34
+ }
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CalendarManager = void 0;
4
+ const tenantID = process.env.MICROSOFT_TENANT_ID;
5
+ const clientID = process.env.MICROSOFT_CLIENT_ID;
6
+ const clientSecret = process.env.MICROSOFT_CLIENT_SECRET;
7
+ const userMail = process.env.MICROSOFT_USER_EMAIL;
8
+ /**
9
+ * Manager for calendar operations via Microsoft Graph API
10
+ */
11
+ class CalendarManager {
12
+ constructor() {
13
+ this.isValid = !!(tenantID && clientID && clientSecret && userMail);
14
+ }
15
+ async getAccess() {
16
+ if (!this.isValid)
17
+ return null;
18
+ console.log("Getting access token...");
19
+ try {
20
+ const params = new URLSearchParams();
21
+ params.append("client_id", clientID);
22
+ params.append("client_secret", clientSecret);
23
+ params.append("scope", "https://graph.microsoft.com/.default");
24
+ params.append("grant_type", "client_credentials");
25
+ const response = await fetch(`https://login.microsoftonline.com/${tenantID}/oauth2/v2.0/token`, {
26
+ method: "POST",
27
+ headers: {
28
+ "Content-Type": "application/x-www-form-urlencoded",
29
+ },
30
+ body: params.toString(),
31
+ });
32
+ const data = await response.json();
33
+ console.log("Access token fetched successfully:", data);
34
+ return data;
35
+ }
36
+ catch (error) {
37
+ console.error("Error fetching access token:", error);
38
+ return null;
39
+ }
40
+ }
41
+ /**
42
+ * Create a new event in the calendar
43
+ * @param event The event data to create
44
+ * @returns the created event response
45
+ */
46
+ async createEvent(event) {
47
+ if (!userMail || !tenantID || !clientID || !clientSecret)
48
+ return;
49
+ const accessData = await this.getAccess();
50
+ if (!accessData?.access_token)
51
+ return;
52
+ const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(userMail)}/events`, {
53
+ method: "POST",
54
+ headers: {
55
+ Authorization: `Bearer ${accessData.access_token}`,
56
+ "Content-Type": "application/json",
57
+ },
58
+ body: JSON.stringify(event),
59
+ });
60
+ const data = (await res.json());
61
+ console.log("Event creation response:", data);
62
+ return data;
63
+ }
64
+ /**
65
+ * Update an event in the calendar
66
+ * @param eventId The ID of the event to update
67
+ * @param event The updated event data
68
+ * @returns
69
+ */
70
+ async updateEvent(eventId, event) {
71
+ const accessData = await this.getAccess();
72
+ if (!accessData?.access_token)
73
+ return;
74
+ const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(userMail)}/events/${eventId}`, {
75
+ method: "PATCH",
76
+ headers: {
77
+ Authorization: `Bearer ${accessData.access_token}`,
78
+ "Content-Type": "application/json",
79
+ },
80
+ body: JSON.stringify(event),
81
+ });
82
+ const data = await res.json();
83
+ console.log("Event update response:", data);
84
+ return data;
85
+ }
86
+ /**
87
+ * Delete an event from the calendar
88
+ * @param eventId The ID of the event to delete
89
+ * @returns whether the deletion was successful
90
+ */
91
+ async deleteEvent(eventId) {
92
+ const accessData = await this.getAccess();
93
+ if (!accessData?.access_token)
94
+ return;
95
+ // on successful deletion, Microsoft Graph returns 204 No Content, so no JSON to parse
96
+ const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(userMail)}/events/${eventId}`, {
97
+ method: "DELETE",
98
+ headers: {
99
+ Authorization: `Bearer ${accessData.access_token}`,
100
+ },
101
+ });
102
+ console.log("Event deletion response:", res);
103
+ return res.ok;
104
+ }
105
+ /**
106
+ * Fetch all events in calendar
107
+ * @returns the list of events
108
+ */
109
+ async fetchEvents() {
110
+ const accessData = await this.getAccess();
111
+ if (!accessData?.access_token)
112
+ return;
113
+ const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(userMail)}/events`, {
114
+ method: "GET",
115
+ headers: {
116
+ Authorization: `Bearer ${accessData.access_token}`,
117
+ },
118
+ });
119
+ const data = await res.json();
120
+ console.log("Calendar events:", data);
121
+ return data;
122
+ }
123
+ }
124
+ exports.CalendarManager = CalendarManager;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The Return-Type of Microsoft
3
+ */
4
+ export type Access = {
5
+ token_type: "Bearer";
6
+ expires_in: number;
7
+ ext_expires_in: number;
8
+ access_token: string;
9
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,150 @@
1
+ export type DateTimeTimeZone = {
2
+ dateTime: string;
3
+ timeZone: string;
4
+ };
5
+ export type EmailAddress = {
6
+ name?: string;
7
+ address: string;
8
+ };
9
+ export type Attendee = {
10
+ type?: "required" | "optional" | "resource";
11
+ emailAddress: EmailAddress;
12
+ };
13
+ export type ItemBody = {
14
+ contentType?: "Text" | "HTML";
15
+ content?: string;
16
+ };
17
+ export type LocationAddress = {
18
+ street?: string;
19
+ city?: string;
20
+ state?: string;
21
+ countryOrRegion?: string;
22
+ postalCode?: string;
23
+ };
24
+ export type Location = {
25
+ displayName?: string;
26
+ locationEmailAddress?: string;
27
+ locationUri?: string;
28
+ address?: LocationAddress;
29
+ locationType?: string;
30
+ uniqueId?: string;
31
+ };
32
+ export type RecurrencePattern = {
33
+ type: "daily" | "weekly" | "absoluteMonthly" | "relativeMonthly" | "absoluteYearly" | "relativeYearly";
34
+ interval?: number;
35
+ daysOfWeek?: Array<"Sunday" | "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday">;
36
+ firstDayOfWeek?: "Sunday" | "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday";
37
+ month?: number;
38
+ index?: "first" | "second" | "third" | "fourth" | "last";
39
+ };
40
+ export type RecurrenceRange = {
41
+ type: "noEnd";
42
+ startDate: string;
43
+ } | {
44
+ type: "endDate";
45
+ startDate: string;
46
+ endDate: string;
47
+ } | {
48
+ type: "numbered";
49
+ startDate: string;
50
+ numberOfOccurrences: number;
51
+ };
52
+ export type Recurrence = {
53
+ pattern: RecurrencePattern;
54
+ range: RecurrenceRange;
55
+ };
56
+ /**
57
+ * Graph Event type for creating/updating events
58
+ */
59
+ export type GraphEvent = {
60
+ subject?: string;
61
+ body?: ItemBody;
62
+ start: DateTimeTimeZone;
63
+ end: DateTimeTimeZone;
64
+ location?: Location;
65
+ attendees?: Attendee[];
66
+ isAllDay?: boolean;
67
+ recurrence?: Recurrence;
68
+ sensitivity?: "normal" | "personal" | "private" | "confidential";
69
+ showAs?: "free" | "tentative" | "busy" | "oof" | "workingElsewhere" | "unknown";
70
+ importance?: "low" | "normal" | "high";
71
+ allowNewTimeProposals?: boolean;
72
+ reminderMinutesBeforeStart?: number;
73
+ isReminderOn?: boolean;
74
+ categories?: string[];
75
+ transactionId?: string;
76
+ onlineMeetingProvider?: "unknown" | "skypeForBusiness" | "skypeForConsumer" | "teamsForBusiness";
77
+ onlineMeeting?: {
78
+ joinUrl?: string;
79
+ };
80
+ };
81
+ export type GraphEventResponse = {
82
+ "@odata.context"?: string;
83
+ "@odata.etag"?: string;
84
+ id: string;
85
+ createdDateTime?: string;
86
+ lastModifiedDateTime?: string;
87
+ changeKey?: string;
88
+ categories?: string[];
89
+ transactionId?: string | null;
90
+ originalStartTimeZone?: string;
91
+ originalEndTimeZone?: string;
92
+ iCalUId?: string;
93
+ uid?: string;
94
+ reminderMinutesBeforeStart?: number;
95
+ isReminderOn?: boolean;
96
+ hasAttachments?: boolean;
97
+ subject?: string;
98
+ bodyPreview?: string;
99
+ importance?: "low" | "normal" | "high";
100
+ sensitivity?: "normal" | "personal" | "private" | "confidential";
101
+ isAllDay?: boolean;
102
+ isCancelled?: boolean;
103
+ isOrganizer?: boolean;
104
+ responseRequested?: boolean;
105
+ seriesMasterId?: string | null;
106
+ showAs?: "free" | "tentative" | "busy" | "oof" | "workingElsewhere" | "unknown";
107
+ type?: string;
108
+ webLink?: string;
109
+ onlineMeetingUrl?: string | null;
110
+ isOnlineMeeting?: boolean;
111
+ onlineMeetingProvider?: "unknown" | "skypeForBusiness" | "skypeForConsumer" | "teamsForBusiness" | string;
112
+ allowNewTimeProposals?: boolean;
113
+ occurrenceId?: string | null;
114
+ isDraft?: boolean;
115
+ hideAttendees?: boolean;
116
+ responseStatus?: {
117
+ response?: string;
118
+ time?: string;
119
+ };
120
+ body?: {
121
+ contentType?: string;
122
+ content?: string;
123
+ };
124
+ start: DateTimeTimeZone;
125
+ end: DateTimeTimeZone;
126
+ location?: {
127
+ displayName?: string;
128
+ locationType?: string;
129
+ uniqueId?: string;
130
+ uniqueIdType?: string;
131
+ locationEmailAddress?: string;
132
+ address?: LocationAddress;
133
+ } | null;
134
+ locations?: Array<{
135
+ displayName?: string;
136
+ locationType?: string;
137
+ uniqueId?: string;
138
+ uniqueIdType?: string;
139
+ locationEmailAddress?: string;
140
+ address?: LocationAddress;
141
+ }>;
142
+ recurrence?: Recurrence | null;
143
+ attendees?: Attendee[];
144
+ organizer?: {
145
+ emailAddress: EmailAddress;
146
+ };
147
+ onlineMeeting?: {
148
+ joinUrl?: string;
149
+ } | null;
150
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.init = init;
4
4
  const __1 = require("..");
5
+ const scheduleToEvent_1 = require("../features/openservice/schedules/calendarSync/functions/scheduleToEvent");
6
+ const CalendarManager_1 = require("../features/openservice/schedules/calendarSync/service/CalendarManager");
5
7
  const types_1 = require("../types");
6
8
  async function init() {
7
9
  (0, __1.beforeSaveHook)(types_1.Maintenance_Schedule, async (request) => {
@@ -10,12 +12,19 @@ async function init() {
10
12
  await (0, __1.defaultAclHandler)(request);
11
13
  });
12
14
  (0, __1.afterSaveHook)(types_1.Maintenance_Schedule, async (request) => {
13
- const { object, original, user } = request;
14
- if (!original)
15
+ const { object, original, user, master } = request;
16
+ if (!original) {
15
17
  await addToTemplateSources(object);
18
+ if (!master) {
19
+ await addToCalendar(object);
20
+ }
21
+ }
22
+ if (original && !master) {
23
+ await updateCalendarEvent(object);
24
+ }
16
25
  });
17
26
  (0, __1.beforeDeleteHook)(types_1.Maintenance_Schedule, async (request) => {
18
- const { object, original, user } = request;
27
+ const { object, original, user, master } = request;
19
28
  const scheduleFetched = await object?.fetchWithInclude(["template", "source"], {
20
29
  useMasterKey: true,
21
30
  });
@@ -24,6 +33,10 @@ async function init() {
24
33
  if (source)
25
34
  template?.relation("sources").remove(source);
26
35
  await template?.save(null, { useMasterKey: true });
36
+ // Delete associated calendar event
37
+ if (object.get("meta")?.calendarEventId) {
38
+ await new CalendarManager_1.CalendarManager().deleteEvent(object.get("meta")?.calendarEventId);
39
+ }
27
40
  });
28
41
  }
29
42
  async function addToTemplateSources(schedule) {
@@ -39,3 +52,38 @@ async function addToTemplateSources(schedule) {
39
52
  template.relation("sources").add(schedule.source);
40
53
  await template.save(null, { useMasterKey: true });
41
54
  }
55
+ async function updateCalendarEvent(schedule) {
56
+ const event = await (0, scheduleToEvent_1.scheduleToEvent)(schedule);
57
+ if (!event)
58
+ return;
59
+ const calendarManager = new CalendarManager_1.CalendarManager();
60
+ const meta = schedule.get("meta") || {};
61
+ const calendarEventId = meta.calendarEventId;
62
+ if (calendarEventId) {
63
+ console.log("Updating schedule in calendar...");
64
+ await calendarManager.updateEvent(calendarEventId, event);
65
+ }
66
+ else {
67
+ await addToCalendar(schedule);
68
+ }
69
+ }
70
+ /**
71
+ * Add schedule as event to calendar when first created
72
+ * @param schedule
73
+ */
74
+ async function addToCalendar(schedule) {
75
+ console.log("Creating new calendar event for schedule...");
76
+ const event = await (0, scheduleToEvent_1.scheduleToEvent)(schedule);
77
+ if (!event)
78
+ return;
79
+ const calendarManager = new CalendarManager_1.CalendarManager();
80
+ const createdEvent = await calendarManager.createEvent(event);
81
+ if (createdEvent && createdEvent.id) {
82
+ const existingMeta = schedule.get("meta") || {};
83
+ schedule.set("meta", {
84
+ ...existingMeta,
85
+ calendarEventId: createdEvent.id,
86
+ });
87
+ await schedule.save(null, { useMasterKey: true });
88
+ }
89
+ }
@@ -1,33 +1,31 @@
1
- import type { Contact } from "./Contact";
2
1
  import type { Maintenance_Schedule_Execution } from "./Maintenance_Schedule_Execution";
3
- import type { Source } from "./Source";
4
2
  import type { Maintenance_Schedule_Step } from "./Maintenance_Schedule_Step";
5
3
  import type { Maintenance_Schedule_Template } from "./Maintenance_Schedule_Template";
4
+ import type { Source } from "./Source";
6
5
  import type { Tenant } from "./Tenant";
7
6
  export interface Maintenance_ScheduleAttributes {
8
7
  id: string;
9
8
  objectId: string;
10
9
  createdAt: Date;
11
10
  updatedAt: Date;
12
- color?: string | undefined;
13
- contacts: Parse.Relation<Maintenance_Schedule, Contact>;
14
- cron?: any | undefined;
15
- description?: string | undefined;
11
+ color?: string;
12
+ cron?: any;
13
+ description?: string;
16
14
  enabled: boolean;
17
- lastExecution?: Maintenance_Schedule_Execution | undefined;
18
- notifyBeforeDue?: any | undefined;
15
+ lastExecution?: Maintenance_Schedule_Execution;
16
+ meta?: any;
17
+ notifyBeforeDue?: any;
19
18
  source: Source;
20
19
  steps: Parse.Relation<Maintenance_Schedule, Maintenance_Schedule_Step>;
21
- template?: Maintenance_Schedule_Template | undefined;
22
- tenant?: Tenant | undefined;
23
- title?: string | undefined;
20
+ template?: Maintenance_Schedule_Template;
21
+ tenant?: Tenant;
22
+ title?: string;
24
23
  }
25
24
  export declare class Maintenance_Schedule extends Parse.Object<Maintenance_ScheduleAttributes> {
26
25
  static className: string;
27
26
  constructor(data?: Partial<Maintenance_ScheduleAttributes>);
28
27
  get color(): string | undefined;
29
28
  set color(value: string | undefined);
30
- get contacts(): Parse.Relation<Maintenance_Schedule, Contact>;
31
29
  get cron(): any | undefined;
32
30
  set cron(value: any | undefined);
33
31
  get description(): string | undefined;
@@ -36,6 +34,8 @@ export declare class Maintenance_Schedule extends Parse.Object<Maintenance_Sched
36
34
  set enabled(value: boolean);
37
35
  get lastExecution(): Maintenance_Schedule_Execution | undefined;
38
36
  set lastExecution(value: Maintenance_Schedule_Execution | undefined);
37
+ get meta(): any | undefined;
38
+ set meta(value: any | undefined);
39
39
  get notifyBeforeDue(): any | undefined;
40
40
  set notifyBeforeDue(value: any | undefined);
41
41
  get source(): Source;
@@ -11,9 +11,6 @@ class Maintenance_Schedule extends Parse.Object {
11
11
  set color(value) {
12
12
  super.set("color", value);
13
13
  }
14
- get contacts() {
15
- return super.relation("contacts");
16
- }
17
14
  get cron() {
18
15
  return super.get("cron");
19
16
  }
@@ -38,6 +35,12 @@ class Maintenance_Schedule extends Parse.Object {
38
35
  set lastExecution(value) {
39
36
  super.set("lastExecution", value);
40
37
  }
38
+ get meta() {
39
+ return super.get("meta");
40
+ }
41
+ set meta(value) {
42
+ super.set("meta", value);
43
+ }
41
44
  get notifyBeforeDue() {
42
45
  return super.get("notifyBeforeDue");
43
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openinc/parse-server-opendash",
3
- "version": "3.24.6",
3
+ "version": "3.25.0",
4
4
  "description": "Parse Server Cloud Code for open.INC Stack.",
5
5
  "packageManager": "pnpm@10.19.0",
6
6
  "keywords": [
@@ -22,6 +22,10 @@
22
22
  "targetClass": "{{PREFIX}}Maintenance_Schedule_Execution",
23
23
  "required": false
24
24
  },
25
+ "meta": {
26
+ "type": "Object",
27
+ "required": false
28
+ },
25
29
  "notifyBeforeDue": {
26
30
  "type": "Object",
27
31
  "required": false