@openinc/parse-server-opendash 4.0.27 → 4.0.29

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.
@@ -1,7 +1,7 @@
1
1
  import { GraphEventResponse } from "../types/Event.js";
2
2
  export type ScheduleCronTimestamp = {
3
- startData: Date;
4
- endData?: Date;
3
+ startDate: Date;
4
+ endDate?: Date;
5
5
  number: number;
6
6
  unit: "days" | "weeks" | "months";
7
7
  };
@@ -29,29 +29,26 @@ function eventToSchedule(event) {
29
29
  ? pattern.interval
30
30
  : 1;
31
31
  // Prefer explicit range.startDate, fallback to event.start.dateTime
32
- let startData;
32
+ let startDate;
33
33
  if (range?.startDate) {
34
34
  // range.startDate is YYYY-MM-DD
35
- startData = new Date(range.startDate + "T00:00:00Z");
35
+ startDate = new Date(range.startDate + "T00:00:00Z");
36
36
  }
37
37
  else if (event.start?.dateTime) {
38
- startData = new Date(event.start.dateTime);
38
+ startDate = new Date(event.start.dateTime);
39
39
  }
40
40
  // For end, prefer range.endDate. If range.type === 'noEnd' leave undefined.
41
- let endData;
41
+ let endDate;
42
42
  if (range?.type === "endDate" && range?.endDate) {
43
- endData = new Date(range.endDate + "T00:00:00Z");
43
+ endDate = new Date(range.endDate + "T00:00:00Z");
44
44
  }
45
- else if (event.end?.dateTime) {
46
- endData = new Date(event.end.dateTime);
47
- }
48
- if (!startData)
45
+ if (!startDate)
49
46
  return undefined;
50
47
  return {
51
48
  schedule_type: "timestamp",
52
49
  timestamp: {
53
- startData,
54
- endData,
50
+ startDate,
51
+ endDate,
55
52
  number: interval,
56
53
  unit,
57
54
  },
@@ -1,10 +1,16 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.scheduleToEvent = scheduleToEvent;
7
+ const dayjs_1 = __importDefault(require("dayjs"));
4
8
  async function scheduleToEvent(schedule) {
5
9
  console.log("Converting Schedule to Event...");
6
10
  try {
7
- await schedule.fetchWithInclude("template");
11
+ await schedule.fetchWithInclude(["template"], {
12
+ useMasterKey: true,
13
+ });
8
14
  }
9
15
  catch (error) {
10
16
  console.error("Error fetching template:", error);
@@ -16,19 +22,21 @@ async function scheduleToEvent(schedule) {
16
22
  const end = scheduleCron?.timestamp?.endDate ?? templateCron?.timestamp?.endDate;
17
23
  const interval = scheduleCron?.timestamp?.number ?? templateCron?.timestamp?.number;
18
24
  const unit = scheduleCron?.timestamp?.unit ?? templateCron?.timestamp?.unit;
19
- if (!start || !end || !interval || !unit) {
25
+ if (!start || !interval || !unit) {
20
26
  console.log("Insufficient data to create event from schedule.");
21
27
  return;
22
28
  }
29
+ const description = schedule.get("description");
23
30
  const event = {
24
31
  subject: schedule.get("title"),
32
+ body: { contentType: "Text", content: description ?? "" },
25
33
  start: {
26
34
  // for single-day/all-day events we use date-only; keep full ISO otherwise
27
35
  dateTime: start.toISOString().slice(0, 19),
28
36
  timeZone: "UTC",
29
37
  },
30
38
  end: {
31
- dateTime: end.toISOString().slice(0, 19),
39
+ dateTime: (0, dayjs_1.default)(start).add(1, "day").toISOString().slice(0, 19),
32
40
  timeZone: "UTC",
33
41
  },
34
42
  isAllDay: true,
@@ -65,22 +73,29 @@ async function scheduleToEvent(schedule) {
65
73
  pattern = null;
66
74
  }
67
75
  if (pattern) {
68
- event.recurrence = {
69
- pattern,
70
- range: {
76
+ const range = end
77
+ ? {
71
78
  type: "endDate",
72
79
  startDate: toDateOnly(start),
73
80
  endDate: toDateOnly(end),
74
- },
81
+ }
82
+ : {
83
+ type: "noEnd",
84
+ startDate: toDateOnly(start),
85
+ };
86
+ event.recurrence = {
87
+ pattern,
88
+ range,
75
89
  };
76
- // if event is all-day, set start/end to date-only values (Graph expects dates)
90
+ // if event is all-day, set start/end to date-only values (Graph expects dates) => always true for schedules
77
91
  if (event.isAllDay) {
78
92
  event.start.dateTime = toDateOnly(start);
79
93
  // Graph's endDate in event object is exclusive for all-day events; keep as provided for recurrence range
80
94
  // Set end to next day to represent an all-day event that begins and ends the same day
81
95
  const endForEvent = new Date(start);
82
96
  endForEvent.setUTCDate(endForEvent.getUTCDate() + 1);
83
- event.end.dateTime = toDateOnly(endForEvent);
97
+ if (event.end)
98
+ event.end.dateTime = toDateOnly(endForEvent);
84
99
  }
85
100
  }
86
101
  console.log("Schedule converted to Event:", event);
@@ -3,7 +3,11 @@ import { GraphEvent, GraphEventResponse } from "../types/Event.js";
3
3
  * Manager for calendar operations via Microsoft Graph API
4
4
  */
5
5
  export declare class CalendarManager {
6
- isValid: boolean;
6
+ tenantID: string;
7
+ clientID: string;
8
+ clientSecret: string;
9
+ userMail: string;
10
+ get isValid(): true | string;
7
11
  private getAccess;
8
12
  /**
9
13
  * Create a new event in the calendar
@@ -17,13 +21,14 @@ export declare class CalendarManager {
17
21
  * @param event The updated event data
18
22
  * @returns
19
23
  */
20
- updateEvent(eventId: string, event: Partial<GraphEvent>): Promise<unknown>;
24
+ updateEvent(eventId: string, event: Partial<GraphEvent>): Promise<GraphEventResponse | undefined>;
21
25
  /**
22
26
  * Delete an event from the calendar
23
27
  * @param eventId The ID of the event to delete
24
28
  * @returns whether the deletion was successful
25
29
  */
26
30
  deleteEvent(eventId: string): Promise<boolean | undefined>;
31
+ fetchEvent(eventId: string): Promise<GraphEventResponse | null>;
27
32
  /**
28
33
  * Fetch all events in calendar
29
34
  * @returns the list of events
@@ -31,4 +36,18 @@ export declare class CalendarManager {
31
36
  fetchEvents(): Promise<{
32
37
  value: GraphEventResponse[];
33
38
  } | undefined>;
39
+ /**
40
+ * Fetch changed events since the last delta sync.
41
+ * On the first call (no deltaLink), returns all current events and a deltaLink
42
+ * for subsequent incremental calls.
43
+ * @param deltaLink token from the previous call; omit for the initial full sync
44
+ */
45
+ fetchDelta(deltaLink?: string): Promise<{
46
+ events: (GraphEventResponse & {
47
+ "@removed"?: {
48
+ reason: string;
49
+ };
50
+ })[];
51
+ deltaLink: string;
52
+ } | null>;
34
53
  }
@@ -2,26 +2,40 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CalendarManager = void 0;
4
4
  const index_js_1 = require("../../../../config/index.js");
5
- const tenantID = index_js_1.ConfigInstance.getInstance().get("MICROSOFT_TENANT_ID");
6
- const clientID = index_js_1.ConfigInstance.getInstance().get("MICROSOFT_CLIENT_ID");
7
- const clientSecret = index_js_1.ConfigInstance.getInstance().get("MICROSOFT_CLIENT_SECRET");
8
- const userMail = index_js_1.ConfigInstance.getInstance().get("MICROSOFT_USER_EMAIL");
9
5
  /**
10
6
  * Manager for calendar operations via Microsoft Graph API
11
7
  */
12
8
  class CalendarManager {
13
- isValid = !!(tenantID && clientID && clientSecret && userMail);
9
+ tenantID = index_js_1.ConfigInstance.getInstance().get("MICROSOFT_TENANT_ID") ||
10
+ index_js_1.ConfigInstance.getInstance().get("OI_MICROSOFT_TENANT_ID");
11
+ clientID = index_js_1.ConfigInstance.getInstance().get("MICROSOFT_CLIENT_ID") ||
12
+ index_js_1.ConfigInstance.getInstance().get("OI_MICROSOFT_APP_ID");
13
+ clientSecret = index_js_1.ConfigInstance.getInstance().get("MICROSOFT_CLIENT_SECRET") ||
14
+ index_js_1.ConfigInstance.getInstance().get("OI_MICROSOFT_CLIENT_SECRET");
15
+ userMail = index_js_1.ConfigInstance.getInstance().get("MICROSOFT_USER_EMAIL") ||
16
+ index_js_1.ConfigInstance.getInstance().get("OI_MICROSOFT_USER_EMAIL");
17
+ get isValid() {
18
+ if (!this.tenantID)
19
+ return "Missing Microsoft Tenant ID";
20
+ if (!this.clientID)
21
+ return "Missing Microsoft Client ID";
22
+ if (!this.clientSecret)
23
+ return "Missing Microsoft Client Secret";
24
+ if (!this.userMail)
25
+ return "Missing Microsoft User Email";
26
+ return true;
27
+ }
14
28
  async getAccess() {
15
- if (!this.isValid)
29
+ if (this.isValid !== true)
16
30
  return null;
17
31
  console.log("Getting access token...");
18
32
  try {
19
33
  const params = new URLSearchParams();
20
- params.append("client_id", clientID);
21
- params.append("client_secret", clientSecret);
34
+ params.append("client_id", this.clientID);
35
+ params.append("client_secret", this.clientSecret);
22
36
  params.append("scope", "https://graph.microsoft.com/.default");
23
37
  params.append("grant_type", "client_credentials");
24
- const response = await fetch(`https://login.microsoftonline.com/${tenantID}/oauth2/v2.0/token`, {
38
+ const response = await fetch(`https://login.microsoftonline.com/${this.tenantID}/oauth2/v2.0/token`, {
25
39
  method: "POST",
26
40
  headers: {
27
41
  "Content-Type": "application/x-www-form-urlencoded",
@@ -43,12 +57,15 @@ class CalendarManager {
43
57
  * @returns the created event response
44
58
  */
45
59
  async createEvent(event) {
46
- if (!userMail || !tenantID || !clientID || !clientSecret)
60
+ if (!this.userMail ||
61
+ !this.tenantID ||
62
+ !this.clientID ||
63
+ !this.clientSecret)
47
64
  return;
48
65
  const accessData = await this.getAccess();
49
66
  if (!accessData?.access_token)
50
67
  return;
51
- const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(userMail)}/events`, {
68
+ const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(this.userMail)}/events`, {
52
69
  method: "POST",
53
70
  headers: {
54
71
  Authorization: `Bearer ${accessData.access_token}`,
@@ -70,7 +87,7 @@ class CalendarManager {
70
87
  const accessData = await this.getAccess();
71
88
  if (!accessData?.access_token)
72
89
  return;
73
- const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(userMail)}/events/${eventId}`, {
90
+ const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(this.userMail)}/events/${eventId}`, {
74
91
  method: "PATCH",
75
92
  headers: {
76
93
  Authorization: `Bearer ${accessData.access_token}`,
@@ -78,7 +95,7 @@ class CalendarManager {
78
95
  },
79
96
  body: JSON.stringify(event),
80
97
  });
81
- const data = await res.json();
98
+ const data = (await res.json());
82
99
  console.log("Event update response:", data);
83
100
  return data;
84
101
  }
@@ -92,7 +109,7 @@ class CalendarManager {
92
109
  if (!accessData?.access_token)
93
110
  return;
94
111
  // on successful deletion, Microsoft Graph returns 204 No Content, so no JSON to parse
95
- const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(userMail)}/events/${eventId}`, {
112
+ const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(this.userMail)}/events/${eventId}`, {
96
113
  method: "DELETE",
97
114
  headers: {
98
115
  Authorization: `Bearer ${accessData.access_token}`,
@@ -101,6 +118,15 @@ class CalendarManager {
101
118
  console.log("Event deletion response:", res);
102
119
  return res.ok;
103
120
  }
121
+ async fetchEvent(eventId) {
122
+ const accessData = await this.getAccess();
123
+ if (!accessData?.access_token)
124
+ return null;
125
+ const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(this.userMail)}/events/${eventId}`, { headers: { Authorization: `Bearer ${accessData.access_token}` } });
126
+ if (!res.ok)
127
+ return null;
128
+ return (await res.json());
129
+ }
104
130
  /**
105
131
  * Fetch all events in calendar
106
132
  * @returns the list of events
@@ -109,7 +135,7 @@ class CalendarManager {
109
135
  const accessData = await this.getAccess();
110
136
  if (!accessData?.access_token)
111
137
  return;
112
- const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(userMail)}/events`, {
138
+ const res = await fetch(`https://graph.microsoft.com/v1.0/users/${encodeURIComponent(this.userMail)}/events`, {
113
139
  method: "GET",
114
140
  headers: {
115
141
  Authorization: `Bearer ${accessData.access_token}`,
@@ -119,5 +145,38 @@ class CalendarManager {
119
145
  console.log("Calendar events:", data);
120
146
  return data;
121
147
  }
148
+ /**
149
+ * Fetch changed events since the last delta sync.
150
+ * On the first call (no deltaLink), returns all current events and a deltaLink
151
+ * for subsequent incremental calls.
152
+ * @param deltaLink token from the previous call; omit for the initial full sync
153
+ */
154
+ async fetchDelta(deltaLink) {
155
+ const accessData = await this.getAccess();
156
+ if (!accessData?.access_token)
157
+ return null;
158
+ const events = [];
159
+ let nextUrl = deltaLink || // treat empty string same as missing
160
+ `https://graph.microsoft.com/v1.0/users/${encodeURIComponent(this.userMail)}/events/delta`;
161
+ let newDeltaLink = "";
162
+ while (nextUrl) {
163
+ const res = await fetch(nextUrl, {
164
+ headers: { Authorization: `Bearer ${accessData.access_token}` },
165
+ });
166
+ if (!res.ok) {
167
+ console.error(`[CalendarManager] fetchDelta HTTP ${res.status}:`, await res.text());
168
+ return null;
169
+ }
170
+ const data = (await res.json());
171
+ events.push(...(data.value ?? []));
172
+ nextUrl = data["@odata.nextLink"];
173
+ if (data["@odata.deltaLink"])
174
+ newDeltaLink = data["@odata.deltaLink"];
175
+ }
176
+ console.log("Delta fetch result:", { events, newDeltaLink });
177
+ if (!newDeltaLink)
178
+ return null;
179
+ return { events, deltaLink: newDeltaLink };
180
+ }
122
181
  }
123
182
  exports.CalendarManager = CalendarManager;
@@ -0,0 +1,17 @@
1
+ export declare class CalendarSyncPoller {
2
+ private manager;
3
+ private timer;
4
+ /**
5
+ * Start polling the Microsoft Calendar delta feed.
6
+ * @param intervalMs polling interval in milliseconds (default: 5 minutes)
7
+ */
8
+ start(intervalMs?: number): void;
9
+ stop(): void;
10
+ private poll;
11
+ private processEvent;
12
+ private updateScheduleFromEvent;
13
+ private createScheduleFromEvent;
14
+ private handleDeleted;
15
+ private loadDeltaLink;
16
+ private saveDeltaLink;
17
+ }
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CalendarSyncPoller = void 0;
7
+ const node_1 = __importDefault(require("parse/node"));
8
+ const eventToSchedule_js_1 = require("../functions/eventToSchedule.js");
9
+ const calendarMetaHelper_js_1 = require("./calendarMetaHelper.js");
10
+ const CalendarManager_js_1 = require("./CalendarManager.js");
11
+ const index_js_1 = require("../../../../../types/index.js");
12
+ const DELTA_LINK_CONFIG_KEY = "microsoftCalendarDeltaLink";
13
+ class CalendarSyncPoller {
14
+ manager = new CalendarManager_js_1.CalendarManager();
15
+ timer = null;
16
+ /**
17
+ * Start polling the Microsoft Calendar delta feed.
18
+ * @param intervalMs polling interval in milliseconds (default: 5 minutes)
19
+ */
20
+ start(intervalMs = 5 * 60 * 1000) {
21
+ if (this.manager.isValid !== true) {
22
+ console.log("[CalendarSyncPoller] Not started — missing Microsoft credentials.", this.manager.isValid);
23
+ return;
24
+ }
25
+ this.poll().catch(console.error);
26
+ this.timer = setInterval(() => this.poll().catch(console.error), intervalMs);
27
+ }
28
+ stop() {
29
+ if (this.timer)
30
+ clearInterval(this.timer);
31
+ }
32
+ async poll() {
33
+ console.log("[CalendarSyncPoller] Polling calendar delta...");
34
+ const deltaLink = await this.loadDeltaLink();
35
+ const result = await this.manager.fetchDelta(deltaLink ?? undefined);
36
+ if (!result) {
37
+ console.log("[CalendarSyncPoller] Failed to fetch calendar delta.");
38
+ return;
39
+ }
40
+ for (const event of result.events) {
41
+ try {
42
+ await this.processEvent(event);
43
+ }
44
+ catch (err) {
45
+ console.error("[CalendarSyncPoller] Error processing event:", event.id, err);
46
+ }
47
+ }
48
+ await this.saveDeltaLink(result.deltaLink);
49
+ }
50
+ async processEvent(event) {
51
+ if (event["@removed"]) {
52
+ await this.handleDeleted(event.id);
53
+ return;
54
+ }
55
+ const metaEntry = await (0, calendarMetaHelper_js_1.findCalendarMetaByEventId)(event.id);
56
+ if (metaEntry) {
57
+ const storedChangeKey = metaEntry.get("values")?.microsoftCalendarChangeKey;
58
+ // Skip if we caused this change (our write already stored this changeKey)
59
+ if (event.changeKey && storedChangeKey === event.changeKey)
60
+ return;
61
+ await this.updateScheduleFromEvent(metaEntry, event);
62
+ }
63
+ else {
64
+ // Delta responses omit most properties; fetch the full event before creating a schedule
65
+ const fullEvent = await this.manager.fetchEvent(event.id);
66
+ if (!fullEvent)
67
+ return;
68
+ await this.createScheduleFromEvent(fullEvent);
69
+ }
70
+ }
71
+ async updateScheduleFromEvent(metaEntry, event) {
72
+ const scheduleId = metaEntry.get("entryObjectId");
73
+ if (!scheduleId)
74
+ return;
75
+ // Delta responses omit most fields; fetch the full event for title/body/cron
76
+ const fullEvent = await this.manager.fetchEvent(event.id) ?? event;
77
+ const schedule = await new node_1.default.Query(index_js_1.Maintenance_Schedule).get(scheduleId, { useMasterKey: true });
78
+ if (fullEvent.subject)
79
+ schedule.set("title", fullEvent.subject);
80
+ if (fullEvent.bodyPreview)
81
+ schedule.set("description", fullEvent.bodyPreview);
82
+ const cronData = (0, eventToSchedule_js_1.eventToSchedule)(fullEvent);
83
+ if (cronData)
84
+ schedule.set("cron", cronData);
85
+ // useMasterKey prevents afterSaveHook from re-syncing back to calendar
86
+ await schedule.save(null, { useMasterKey: true });
87
+ if (event.changeKey) {
88
+ await (0, calendarMetaHelper_js_1.updateCalendarChangeKey)(metaEntry, event.changeKey, fullEvent);
89
+ }
90
+ }
91
+ async createScheduleFromEvent(event) {
92
+ const parsed = parseEventSubject(event.subject);
93
+ if (!parsed) {
94
+ console.log(`[CalendarSyncPoller] Skipping event "${event.subject}" (${event.id}) — subject does not match expected format: '"<source>" - <title>'.`);
95
+ return;
96
+ }
97
+ const source = await new node_1.default.Query(index_js_1.Source)
98
+ .equalTo("name", parsed.sourceName)
99
+ .first({ useMasterKey: true });
100
+ if (!source) {
101
+ console.log(`[CalendarSyncPoller] Skipping event "${event.subject}" (${event.id}) — no Source found with name "${parsed.sourceName}".`);
102
+ return;
103
+ }
104
+ const schedule = new index_js_1.Maintenance_Schedule();
105
+ schedule.set("title", event.subject);
106
+ schedule.set("source", source);
107
+ schedule.set("enabled", true);
108
+ schedule.set("tenant", source.get("tenant"));
109
+ if (event.bodyPreview)
110
+ schedule.set("description", event.bodyPreview);
111
+ const cronData = (0, eventToSchedule_js_1.eventToSchedule)(event);
112
+ if (cronData)
113
+ schedule.set("cron", cronData);
114
+ // useMasterKey prevents afterSaveHook from syncing back to calendar
115
+ await schedule.save(null, { useMasterKey: true });
116
+ await (0, calendarMetaHelper_js_1.saveCalendarMeta)(schedule.id, event.id, event.changeKey, source.get("tenant"), event);
117
+ console.log(`[CalendarSyncPoller] Created schedule "${event.subject}" for source "${parsed.sourceName}" from calendar event ${event.id}.`);
118
+ }
119
+ async handleDeleted(eventId) {
120
+ const metaEntry = await (0, calendarMetaHelper_js_1.findCalendarMetaByEventId)(eventId);
121
+ if (!metaEntry)
122
+ return;
123
+ const scheduleId = metaEntry.get("entryObjectId");
124
+ if (scheduleId) {
125
+ try {
126
+ const schedule = await new node_1.default.Query(index_js_1.Maintenance_Schedule).get(scheduleId, { useMasterKey: true });
127
+ // Disable rather than delete to preserve execution history
128
+ schedule.set("enabled", false);
129
+ await schedule.save(null, { useMasterKey: true });
130
+ }
131
+ catch (err) {
132
+ console.error("[CalendarSyncPoller] Could not disable schedule for deleted event:", scheduleId, err);
133
+ }
134
+ }
135
+ await metaEntry.destroy({ useMasterKey: true });
136
+ }
137
+ async loadDeltaLink() {
138
+ try {
139
+ const config = await node_1.default.Config.get({ useMasterKey: true });
140
+ return config.get(DELTA_LINK_CONFIG_KEY) || null;
141
+ }
142
+ catch {
143
+ return null;
144
+ }
145
+ }
146
+ async saveDeltaLink(link) {
147
+ await node_1.default.Config.save({ [DELTA_LINK_CONFIG_KEY]: link }, { useMasterKey: true });
148
+ }
149
+ }
150
+ exports.CalendarSyncPoller = CalendarSyncPoller;
151
+ // Parses the source name out of an Outlook-originated event subject.
152
+ // Expected format for externally-created events: "<source.name>" - <anything>
153
+ // Quotes around the source name are optional.
154
+ function parseEventSubject(subject) {
155
+ if (!subject)
156
+ return null;
157
+ const separatorIdx = subject.indexOf(" - ");
158
+ if (separatorIdx === -1)
159
+ return null;
160
+ const rawSource = subject.slice(0, separatorIdx).trim();
161
+ if (!rawSource)
162
+ return null;
163
+ const sourceName = rawSource.replace(/^"(.*)"$/, "$1");
164
+ return { sourceName };
165
+ }
@@ -0,0 +1,36 @@
1
+ import { Meta_Entry, Tenant } from "../../../../../types/index.js";
2
+ import { MetaConfig } from "../../../../../types/custom/MetaField.js";
3
+ import { GraphEventResponse } from "../types/Event.js";
4
+ export declare const CALENDAR_SYNC_CONTEXT: string;
5
+ export interface CalendarEventSnapshot {
6
+ id: string;
7
+ subject?: string;
8
+ start: {
9
+ dateTime: string;
10
+ timeZone: string;
11
+ };
12
+ end: {
13
+ dateTime: string;
14
+ timeZone: string;
15
+ };
16
+ isAllDay?: boolean;
17
+ isCancelled?: boolean;
18
+ body?: {
19
+ contentType?: string;
20
+ content?: string;
21
+ };
22
+ recurrence?: GraphEventResponse["recurrence"];
23
+ location?: {
24
+ displayName?: string;
25
+ };
26
+ }
27
+ export interface CalendarMetaValues {
28
+ microsoftCalendarEventId: string;
29
+ microsoftCalendarChangeKey?: string;
30
+ microsoftCalendarEvent?: CalendarEventSnapshot;
31
+ }
32
+ export declare const CalendarMetaConfig: MetaConfig;
33
+ export declare function findCalendarMetaForSchedule(scheduleId: string): Promise<Meta_Entry | null>;
34
+ export declare function findCalendarMetaByEventId(eventId: string): Promise<Meta_Entry | null>;
35
+ export declare function saveCalendarMeta(scheduleId: string, eventId: string, changeKey?: string, tenant?: Tenant, event?: GraphEventResponse): Promise<Meta_Entry>;
36
+ export declare function updateCalendarChangeKey(entry: Meta_Entry, changeKey: string, event?: GraphEventResponse): Promise<void>;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CalendarMetaConfig = exports.CALENDAR_SYNC_CONTEXT = void 0;
7
+ exports.findCalendarMetaForSchedule = findCalendarMetaForSchedule;
8
+ exports.findCalendarMetaByEventId = findCalendarMetaByEventId;
9
+ exports.saveCalendarMeta = saveCalendarMeta;
10
+ exports.updateCalendarChangeKey = updateCalendarChangeKey;
11
+ const node_1 = __importDefault(require("parse/node"));
12
+ const index_js_1 = require("../../../../../types/index.js");
13
+ exports.CALENDAR_SYNC_CONTEXT = JSON.stringify([
14
+ "schedule",
15
+ "sync",
16
+ "microsoft",
17
+ ]);
18
+ function toEventSnapshot(event) {
19
+ return {
20
+ id: event.id,
21
+ subject: event.subject,
22
+ start: event.start,
23
+ end: event.end,
24
+ isAllDay: event.isAllDay,
25
+ isCancelled: event.isCancelled,
26
+ body: event.body
27
+ ? { contentType: event.body.contentType, content: event.body.content }
28
+ : undefined,
29
+ recurrence: event.recurrence ?? undefined,
30
+ location: event.location?.displayName
31
+ ? { displayName: event.location.displayName }
32
+ : undefined,
33
+ };
34
+ }
35
+ exports.CalendarMetaConfig = {
36
+ fields: [
37
+ {
38
+ name: "microsoftCalendarEventId",
39
+ type: "string",
40
+ label: "Microsoft Calendar Event ID",
41
+ },
42
+ {
43
+ name: "microsoftCalendarChangeKey",
44
+ type: "string",
45
+ label: "Microsoft Calendar Change Key",
46
+ },
47
+ ],
48
+ };
49
+ async function findCalendarMetaForSchedule(scheduleId) {
50
+ return ((await new node_1.default.Query(index_js_1.Meta_Entry)
51
+ .equalTo("context", exports.CALENDAR_SYNC_CONTEXT)
52
+ .equalTo("entryClassName", index_js_1.Maintenance_Schedule.className)
53
+ .equalTo("entryObjectId", scheduleId)
54
+ .first({ useMasterKey: true })) ?? null);
55
+ }
56
+ async function findCalendarMetaByEventId(eventId) {
57
+ return ((await new node_1.default.Query(index_js_1.Meta_Entry)
58
+ .equalTo("context", exports.CALENDAR_SYNC_CONTEXT)
59
+ .equalTo("entryClassName", index_js_1.Maintenance_Schedule.className)
60
+ // @ts-expect-error
61
+ .equalTo("values.microsoftCalendarEventId", eventId)
62
+ .first({ useMasterKey: true })) ?? null);
63
+ }
64
+ async function saveCalendarMeta(scheduleId, eventId, changeKey, tenant, event) {
65
+ let entry = await findCalendarMetaForSchedule(scheduleId);
66
+ if (!entry) {
67
+ entry = new index_js_1.Meta_Entry();
68
+ entry.set("context", exports.CALENDAR_SYNC_CONTEXT);
69
+ entry.set("entryClassName", index_js_1.Maintenance_Schedule.className);
70
+ entry.set("entryObjectId", scheduleId);
71
+ entry.set("tenant", tenant);
72
+ entry.set("config", {});
73
+ }
74
+ const values = { microsoftCalendarEventId: eventId };
75
+ if (changeKey)
76
+ values.microsoftCalendarChangeKey = changeKey;
77
+ if (event)
78
+ values.microsoftCalendarEvent = toEventSnapshot(event);
79
+ entry.set("values", values);
80
+ return entry.save(null, { useMasterKey: true });
81
+ }
82
+ async function updateCalendarChangeKey(entry, changeKey, event) {
83
+ entry.set("values", {
84
+ ...entry.get("values"),
85
+ microsoftCalendarChangeKey: changeKey,
86
+ ...(event ? { microsoftCalendarEvent: toEventSnapshot(event) } : {}),
87
+ });
88
+ await entry.save(null, { useMasterKey: true });
89
+ }
@@ -60,7 +60,7 @@ export type GraphEvent = {
60
60
  subject?: string;
61
61
  body?: ItemBody;
62
62
  start: DateTimeTimeZone;
63
- end: DateTimeTimeZone;
63
+ end?: DateTimeTimeZone;
64
64
  location?: Location;
65
65
  attendees?: Attendee[];
66
66
  isAllDay?: boolean;
@@ -6,8 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.initSchedulesFeature = initSchedulesFeature;
7
7
  const node_1 = __importDefault(require("parse/node"));
8
8
  const index_js_1 = require("../../../types/index.js");
9
+ const CalendarSyncPoller_js_1 = require("./calendarSync/service/CalendarSyncPoller.js");
9
10
  async function initSchedulesFeature() {
10
11
  updateFiinishedSchedules();
12
+ new CalendarSyncPoller_js_1.CalendarSyncPoller().start(1000 * 60);
11
13
  }
12
14
  async function updateFiinishedSchedules() {
13
15
  const executionsToUpdate = await new node_1.default.Query(index_js_1.Maintenance_Schedule_Execution)
@@ -80,8 +80,6 @@ async function init() {
80
80
  scheduleOrderStartedStatusCheck("0 * * * * *");
81
81
  (0, index_js_2.beforeSaveHook)(index_js_3.MES_Order, async (request) => {
82
82
  const { object, original, user } = request;
83
- console.log("===".repeat(10) + " BEFORE SAVE HOOK " + "===".repeat(10));
84
- console.log("[MES] - beforeSaveHook: Received order \n" + JSON.stringify(object.toJSON(), null, 2) + "\n with original \n" + JSON.stringify(original?.toJSON(), null, 2) + "\n by user " + user?.getEmail());
85
83
  await (0, index_js_2.defaultHandler)(request);
86
84
  await (0, index_js_2.defaultAclHandler)(request, {
87
85
  allowCustomACL: true,
@@ -152,13 +150,9 @@ async function init() {
152
150
  }
153
151
  }
154
152
  }
155
- console.log("[MES] - beforeSaveHook: Finished processing order " + object.id + " with final status " + object.get("status"));
156
- console.log("===".repeat(10) + " END BEFORE SAVE HOOK " + "===".repeat(10));
157
153
  });
158
154
  (0, index_js_2.afterSaveHook)(index_js_3.MES_Order, async (request) => {
159
155
  const { object, original, user } = request;
160
- console.log("===".repeat(10) + " AFTER SAVE HOOK " + "===".repeat(10));
161
- console.log("[MES] - afterSaveHook: Received order \n" + JSON.stringify(object.toJSON(), null, 2) + " with original \n" + JSON.stringify(original?.toJSON(), null, 2) + " by user \n" + user?.getEmail());
162
156
  try {
163
157
  if (original) {
164
158
  // If the order is canceled, publish it as canceled
@@ -193,7 +187,6 @@ async function init() {
193
187
  runningData.name = "Order_Running";
194
188
  console.log("-".repeat(20));
195
189
  console.log("Publishing running order " + object.id);
196
- console.log("Data:", JSON.stringify(runningData));
197
190
  console.log("-".repeat(20));
198
191
  await (0, index_js_1.publishDataItem)(runningData, user?.getEmail() || undefined, true);
199
192
  }
@@ -202,12 +195,9 @@ async function init() {
202
195
  console.error(e);
203
196
  console.log("Order Data not published:" + e.message, e);
204
197
  }
205
- console.log("[MES] - afterSaveHook: Finished processing order " + object.id);
206
- console.log("===".repeat(10) + " END AFTER SAVE HOOK " + "===".repeat(10));
207
198
  });
208
199
  }
209
200
  async function object2OWItem(object) {
210
- console.log("[MES] - object2OWItem: Converting order " + JSON.stringify(object.toJSON(), null, 2) + " to DataItemInterface");
211
201
  const tag = object.get("tag");
212
202
  const configString = await new node_1.default.Query("OD3_Config")
213
203
  .equalTo("key", "ow.mes.unitInfo")
@@ -280,7 +270,6 @@ function createCustomValueTypes(object, fields, fieldInfos) {
280
270
  });
281
271
  }
282
272
  async function createValueArrayForObject(object, extraValues, fields) {
283
- console.log("[MES] - createValueArrayForObject: Creating values object " + JSON.stringify(object.toJSON(), null, 2) + " with extraValues " + JSON.stringify(extraValues));
284
273
  const values = [];
285
274
  const status = object.get("status");
286
275
  const ordernr = object.get("ordernr");
@@ -319,7 +308,6 @@ async function createValueArrayForObject(object, extraValues, fields) {
319
308
  }
320
309
  values.push(value);
321
310
  }
322
- console.log("[MES] - createValueArrayForObject: Created values object for order " + object.id + ": ", values);
323
311
  return [{ date: object.get("start").getTime(), value: values }];
324
312
  }
325
313
  function scheduleOrderStartedStatusCheck(cronInterval) {
@@ -6,12 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.init = init;
7
7
  const node_1 = __importDefault(require("parse/node"));
8
8
  const scheduleToEvent_1 = require("../features/openservice/schedules/calendarSync/functions/scheduleToEvent");
9
+ const calendarMetaHelper_1 = require("../features/openservice/schedules/calendarSync/service/calendarMetaHelper");
9
10
  const CalendarManager_1 = require("../features/openservice/schedules/calendarSync/service/CalendarManager");
10
11
  const schema_1 = require("../features/schema");
11
12
  const types_1 = require("../types");
12
13
  async function init() {
13
14
  (0, schema_1.beforeSaveHook)(types_1.Maintenance_Schedule, async (request) => {
14
- const { object, original, user } = request;
15
15
  await (0, schema_1.defaultHandler)(request);
16
16
  // await defaultAclHandler(request, { allowCustomACL: true });
17
17
  });
@@ -51,7 +51,7 @@ async function init() {
51
51
  }
52
52
  });
53
53
  (0, schema_1.beforeDeleteHook)(types_1.Maintenance_Schedule, async (request) => {
54
- const { object, original, user, master } = request;
54
+ const { object } = request;
55
55
  const scheduleFetched = await object?.fetchWithInclude(["template", "source"], {
56
56
  useMasterKey: true,
57
57
  });
@@ -60,9 +60,13 @@ async function init() {
60
60
  if (source)
61
61
  template?.relation("sources").remove(source);
62
62
  await template?.save(null, { useMasterKey: true });
63
- // Delete associated calendar event
64
- if (object.get("meta")?.microsoftCalendarEventId) {
65
- await new CalendarManager_1.CalendarManager().deleteEvent(object.get("meta")?.microsoftCalendarEventId);
63
+ const metaEntry = await (0, calendarMetaHelper_1.findCalendarMetaForSchedule)(object.id);
64
+ if (metaEntry) {
65
+ const eventId = metaEntry.get("values")?.microsoftCalendarEventId;
66
+ if (eventId) {
67
+ await new CalendarManager_1.CalendarManager().deleteEvent(eventId);
68
+ }
69
+ await metaEntry.destroy({ useMasterKey: true });
66
70
  }
67
71
  });
68
72
  }
@@ -89,11 +93,14 @@ async function updateCalendarEvent(schedule) {
89
93
  if (!event)
90
94
  return;
91
95
  const calendarManager = new CalendarManager_1.CalendarManager();
92
- const meta = schedule.get("meta") || {};
93
- const microsoftCalendarEventId = meta.microsoftCalendarEventId;
94
- if (microsoftCalendarEventId) {
96
+ const metaEntry = await (0, calendarMetaHelper_1.findCalendarMetaForSchedule)(schedule.id);
97
+ const eventId = metaEntry?.get("values")?.microsoftCalendarEventId;
98
+ if (eventId) {
95
99
  console.log("Updating schedule in calendar...");
96
- await calendarManager.updateEvent(microsoftCalendarEventId, event);
100
+ const updatedEvent = await calendarManager.updateEvent(eventId, event);
101
+ if (updatedEvent?.changeKey && metaEntry) {
102
+ await (0, calendarMetaHelper_1.updateCalendarChangeKey)(metaEntry, updatedEvent.changeKey, updatedEvent);
103
+ }
97
104
  }
98
105
  else {
99
106
  await addToCalendar(schedule);
@@ -110,12 +117,7 @@ async function addToCalendar(schedule) {
110
117
  return;
111
118
  const calendarManager = new CalendarManager_1.CalendarManager();
112
119
  const createdEvent = await calendarManager.createEvent(event);
113
- if (createdEvent && createdEvent.id) {
114
- const existingMeta = schedule.get("meta") || {};
115
- schedule.set("meta", {
116
- ...existingMeta,
117
- microsoftCalendarEventId: createdEvent.id,
118
- });
119
- await schedule.save(null, { useMasterKey: true });
120
+ if (createdEvent?.id) {
121
+ await (0, calendarMetaHelper_1.saveCalendarMeta)(schedule.id, createdEvent.id, createdEvent.changeKey, schedule.get("tenant"), createdEvent);
120
122
  }
121
123
  }
@@ -1,19 +1,20 @@
1
1
  import Parse from "parse/node";
2
2
  import type { Tenant } from "./Tenant";
3
+ import { MetaConfig } from "./custom/MetaField";
3
4
  export interface Meta_ConfigAttributes {
4
5
  id: string;
5
6
  objectId: string;
6
7
  createdAt: Date;
7
8
  updatedAt: Date;
8
- config: any;
9
+ config: MetaConfig;
9
10
  context?: string | undefined;
10
11
  tenant?: Tenant | undefined;
11
12
  }
12
13
  export declare class Meta_Config extends Parse.Object<Meta_ConfigAttributes> {
13
14
  static className: string;
14
15
  constructor(data?: Partial<Meta_ConfigAttributes>);
15
- get config(): any;
16
- set config(value: any);
16
+ get config(): MetaConfig;
17
+ set config(value: MetaConfig);
17
18
  get context(): string | undefined;
18
19
  set context(value: string | undefined);
19
20
  get tenant(): Tenant | undefined;
@@ -1,12 +1,13 @@
1
1
  import Parse from "parse/node";
2
2
  import type { Meta_Config } from "./Meta_Config";
3
3
  import type { Tenant } from "./Tenant";
4
+ import { MetaConfig } from "./custom/MetaField";
4
5
  export interface Meta_EntryAttributes {
5
6
  id: string;
6
7
  objectId: string;
7
8
  createdAt: Date;
8
9
  updatedAt: Date;
9
- config?: any | undefined;
10
+ config?: MetaConfig | undefined;
10
11
  context?: string | undefined;
11
12
  entryClassName?: string | undefined;
12
13
  entryObjectId?: string | undefined;
@@ -17,8 +18,8 @@ export interface Meta_EntryAttributes {
17
18
  export declare class Meta_Entry extends Parse.Object<Meta_EntryAttributes> {
18
19
  static className: string;
19
20
  constructor(data?: Partial<Meta_EntryAttributes>);
20
- get config(): any | undefined;
21
- set config(value: any | undefined);
21
+ get config(): MetaConfig | undefined;
22
+ set config(value: MetaConfig | undefined);
22
23
  get context(): string | undefined;
23
24
  set context(value: string | undefined);
24
25
  get entryClassName(): string | undefined;
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Base properties shared by all meta field types
3
+ */
4
+ export type MetaFieldBaseConfig = {
5
+ name: string;
6
+ label: string;
7
+ placeholder?: string;
8
+ help?: string;
9
+ required?: boolean;
10
+ /** Default value for the field */
11
+ defaultValue?: any;
12
+ };
13
+ /**
14
+ * String field type with optional validation
15
+ */
16
+ export type MetaFieldString = MetaFieldBaseConfig & {
17
+ type: "string";
18
+ minLength?: number;
19
+ maxLength?: number;
20
+ pattern?: string;
21
+ multiline?: boolean;
22
+ };
23
+ /**
24
+ * Number field type with min/max constraints
25
+ */
26
+ export type MetaFieldNumber = MetaFieldBaseConfig & {
27
+ type: "number";
28
+ min?: number;
29
+ max?: number;
30
+ step?: number;
31
+ unit?: string;
32
+ };
33
+ /**
34
+ * Boolean field type (checkbox/switch)
35
+ */
36
+ export type MetaFieldBoolean = MetaFieldBaseConfig & {
37
+ type: "boolean";
38
+ defaultValue?: boolean;
39
+ };
40
+ /**
41
+ * Date field type with optional date range constraints
42
+ */
43
+ export type MetaFieldDate = MetaFieldBaseConfig & {
44
+ type: "date";
45
+ minDate?: Date;
46
+ maxDate?: Date;
47
+ includeTime?: boolean;
48
+ };
49
+ /**
50
+ * Select field type with predefined options
51
+ */
52
+ export type MetaFieldSelect = MetaFieldBaseConfig & {
53
+ type: "select";
54
+ options: Array<{
55
+ label: string;
56
+ value: string;
57
+ disabled?: boolean;
58
+ }>;
59
+ /** Optional grouping for select options */
60
+ groups?: Array<{
61
+ label: string;
62
+ options: Array<{
63
+ label: string;
64
+ value: string;
65
+ disabled?: boolean;
66
+ }>;
67
+ }>;
68
+ multiple?: boolean;
69
+ defaultValue?: string | string[];
70
+ };
71
+ /**
72
+ * Parse select field type for selecting Parse objects
73
+ */
74
+ export type MetaFieldSelectParse = MetaFieldBaseConfig & {
75
+ type: "select_parse";
76
+ className: string;
77
+ display?: string;
78
+ multiple?: boolean;
79
+ defaultValue?: string | string[];
80
+ };
81
+ /**
82
+ * Array of all available field types
83
+ */
84
+ export declare const META_FIELD_TYPES: readonly ["string", "number", "boolean", "date", "select", "select_parse"];
85
+ /**
86
+ * Literal type for field types derived from the array
87
+ */
88
+ export type MetaFieldTypes = (typeof META_FIELD_TYPES)[number];
89
+ /**
90
+ * Mapped type for accessing MetaField types by their string literal
91
+ * @example MetaFieldMap["string"] => MetaFieldString
92
+ */
93
+ export type MetaFieldMap = {
94
+ string: MetaFieldString;
95
+ number: MetaFieldNumber;
96
+ boolean: MetaFieldBoolean;
97
+ date: MetaFieldDate;
98
+ select: MetaFieldSelect;
99
+ select_parse: MetaFieldSelectParse;
100
+ };
101
+ /**
102
+ * Union type of all specific meta field types
103
+ */
104
+ export type MetaFieldConfig = MetaFieldString | MetaFieldNumber | MetaFieldBoolean | MetaFieldDate | MetaFieldSelect | MetaFieldSelectParse;
105
+ /**
106
+ * Helper type to extract specific field type from MetaField union
107
+ */
108
+ export type MetaFieldOfType<T extends MetaFieldTypes> = Extract<MetaFieldConfig, {
109
+ type: T;
110
+ }>;
111
+ /**
112
+ * Type guard to check if a field is of a specific type
113
+ */
114
+ export declare function isMetaFieldType<T extends MetaFieldTypes>(field: MetaFieldConfig, type: T): field is MetaFieldOfType<T>;
115
+ export type MetaConfig = {
116
+ fields: MetaFieldConfig[];
117
+ };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.META_FIELD_TYPES = void 0;
4
+ exports.isMetaFieldType = isMetaFieldType;
5
+ /**
6
+ * Array of all available field types
7
+ */
8
+ exports.META_FIELD_TYPES = [
9
+ "string",
10
+ "number",
11
+ "boolean",
12
+ "date",
13
+ "select",
14
+ "select_parse",
15
+ ];
16
+ /**
17
+ * Type guard to check if a field is of a specific type
18
+ */
19
+ function isMetaFieldType(field, type) {
20
+ return field.type === type;
21
+ }
@@ -140,6 +140,8 @@ export { Maintenance_Schedule_Step } from "./Maintenance_Schedule_Step";
140
140
  export type { Maintenance_Schedule_StepAttributes } from "./Maintenance_Schedule_Step";
141
141
  export { Maintenance_Schedule_Template } from "./Maintenance_Schedule_Template";
142
142
  export type { Maintenance_Schedule_TemplateAttributes } from "./Maintenance_Schedule_Template";
143
+ export { Maintenance_SourceMeta } from "./Maintenance_SourceMeta";
144
+ export type { Maintenance_SourceMetaAttributes } from "./Maintenance_SourceMeta";
143
145
  export { Maintenance_Source_File } from "./Maintenance_Source_File";
144
146
  export type { Maintenance_Source_FileAttributes } from "./Maintenance_Source_File";
145
147
  export { Maintenance_Ticket } from "./Maintenance_Ticket";
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MES_OrderPlan = exports.MES_Order = exports.MES_Article = exports.Log = exports.Language = exports.Knowledge_Video = exports.Knowledge_DocumentPage = exports.Knowledge_Document = exports.Knowledge_ChatMessage = exports.Knowledge_Chat = exports.Knowledge_Category = exports.Knowledge_Article = exports.GTFS_Wheelchair_Boarding = exports.GTFS_Wheelchair_Accessible = exports.GTFS_Trip = exports.GTFS_Stop_Times = exports.GTFS_Stop = exports.GTFS_Route_Type = exports.GTFS_Route = exports.GTFS_Location_Type = exports.GTFS_Level = exports.GTFS_Direction = exports.GTFS_Calendar = exports.GTFS_Bikes_Allowed = exports.GTFS_Agency = exports.EMS_ChargePoint = exports.Documentation_Document = exports.Documentation_Config = exports.Documentation_Category = exports.Dashboard = exports.Core_Token = exports.Core_Email = exports.Contact = exports.Config = exports.Company = exports.Changelog = exports.BDE_WorkTime = exports.BDE_WorkOrder = exports.BDE_Unit = exports.BDE_Result = exports.BDE_Page = exports.BDE_ListEntry = exports.BDE_List = exports.BDE_Form = exports.BDE_Article = exports.Attachment = exports.Assets = exports.AlarmWebhook = exports.AlarmAction = exports.Alarm = void 0;
4
- exports.RAG_Data = exports.Push = exports.Permission = exports.OWPlcItem = exports.OWPlcDevice = exports.Notification_Setting = exports.Notification = exports.NavigationItem = exports.NavigationGroup = exports.Monitoring_Slideshow = exports.Monitoring_ReportImage = exports.Monitoring_ParseTableSensor = exports.Monitoring_Jobs = exports.Monitoring_DataHierachies = exports.Meta_Entry = exports.Meta_Config = exports.Maintenance_Ticket_Title = exports.Maintenance_Ticket_Source = exports.Maintenance_Ticket_QR_Code = exports.Maintenance_Ticket_Project = exports.Maintenance_Ticket_Material = exports.Maintenance_Ticket_Kanban_State_Current = exports.Maintenance_Ticket_Kanban_State = exports.Maintenance_Ticket_Issuecategory = exports.Maintenance_Ticket_FormConfig = exports.Maintenance_Ticket_Data = exports.Maintenance_Ticket_Assignment = exports.Maintenance_Ticket = exports.Maintenance_Source_File = exports.Maintenance_Schedule_Template = exports.Maintenance_Schedule_Step = exports.Maintenance_Schedule_Execution_Step = exports.Maintenance_Schedule_Execution = exports.Maintenance_Schedule = exports.Maintenance_Restriction = exports.Maintenance_Project = exports.Maintenance_Priority = exports.Maintenance_Order = exports.Maintenance_Message = exports.Maintenance_Media = exports.Maintenance_Kanban_State = exports.Maintenance_Item = exports.Maintenance_Issuecategory = exports.Maintenance_Frequency = exports.Maintenance_Duedate = exports.Maintenance_Downtime = exports.Mail_Groups = exports.MailTemplate = exports.ML_DataSelection = exports.MIAAS_MDSEndpoint = void 0;
5
- exports.WidgetPreset = exports.Widget = exports.WebPush = exports.VirtualKPI = exports.User_Setting = exports.UserData = exports.TenantTrustedDomain = exports.TenantMeta = exports.Tenant = exports.Spreadsheet_Workbook = exports.SourceMeta = exports.Source = exports.Share = exports.Report = exports.RAG_Request = exports.RAG_Questions = exports.RAG_Prompts = exports.RAG_Meta = exports.RAG_Interview = void 0;
4
+ exports.Push = exports.Permission = exports.OWPlcItem = exports.OWPlcDevice = exports.Notification_Setting = exports.Notification = exports.NavigationItem = exports.NavigationGroup = exports.Monitoring_Slideshow = exports.Monitoring_ReportImage = exports.Monitoring_ParseTableSensor = exports.Monitoring_Jobs = exports.Monitoring_DataHierachies = exports.Meta_Entry = exports.Meta_Config = exports.Maintenance_Ticket_Title = exports.Maintenance_Ticket_Source = exports.Maintenance_Ticket_QR_Code = exports.Maintenance_Ticket_Project = exports.Maintenance_Ticket_Material = exports.Maintenance_Ticket_Kanban_State_Current = exports.Maintenance_Ticket_Kanban_State = exports.Maintenance_Ticket_Issuecategory = exports.Maintenance_Ticket_FormConfig = exports.Maintenance_Ticket_Data = exports.Maintenance_Ticket_Assignment = exports.Maintenance_Ticket = exports.Maintenance_Source_File = exports.Maintenance_SourceMeta = exports.Maintenance_Schedule_Template = exports.Maintenance_Schedule_Step = exports.Maintenance_Schedule_Execution_Step = exports.Maintenance_Schedule_Execution = exports.Maintenance_Schedule = exports.Maintenance_Restriction = exports.Maintenance_Project = exports.Maintenance_Priority = exports.Maintenance_Order = exports.Maintenance_Message = exports.Maintenance_Media = exports.Maintenance_Kanban_State = exports.Maintenance_Item = exports.Maintenance_Issuecategory = exports.Maintenance_Frequency = exports.Maintenance_Duedate = exports.Maintenance_Downtime = exports.Mail_Groups = exports.MailTemplate = exports.ML_DataSelection = exports.MIAAS_MDSEndpoint = void 0;
5
+ exports.WidgetPreset = exports.Widget = exports.WebPush = exports.VirtualKPI = exports.User_Setting = exports.UserData = exports.TenantTrustedDomain = exports.TenantMeta = exports.Tenant = exports.Spreadsheet_Workbook = exports.SourceMeta = exports.Source = exports.Share = exports.Report = exports.RAG_Request = exports.RAG_Questions = exports.RAG_Prompts = exports.RAG_Meta = exports.RAG_Interview = exports.RAG_Data = void 0;
6
6
  var Alarm_1 = require("./Alarm");
7
7
  Object.defineProperty(exports, "Alarm", { enumerable: true, get: function () { return Alarm_1.Alarm; } });
8
8
  var AlarmAction_1 = require("./AlarmAction");
@@ -145,6 +145,8 @@ var Maintenance_Schedule_Step_1 = require("./Maintenance_Schedule_Step");
145
145
  Object.defineProperty(exports, "Maintenance_Schedule_Step", { enumerable: true, get: function () { return Maintenance_Schedule_Step_1.Maintenance_Schedule_Step; } });
146
146
  var Maintenance_Schedule_Template_1 = require("./Maintenance_Schedule_Template");
147
147
  Object.defineProperty(exports, "Maintenance_Schedule_Template", { enumerable: true, get: function () { return Maintenance_Schedule_Template_1.Maintenance_Schedule_Template; } });
148
+ var Maintenance_SourceMeta_1 = require("./Maintenance_SourceMeta");
149
+ Object.defineProperty(exports, "Maintenance_SourceMeta", { enumerable: true, get: function () { return Maintenance_SourceMeta_1.Maintenance_SourceMeta; } });
148
150
  var Maintenance_Source_File_1 = require("./Maintenance_Source_File");
149
151
  Object.defineProperty(exports, "Maintenance_Source_File", { enumerable: true, get: function () { return Maintenance_Source_File_1.Maintenance_Source_File; } });
150
152
  var Maintenance_Ticket_1 = require("./Maintenance_Ticket");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openinc/parse-server-opendash",
3
- "version": "4.0.27",
3
+ "version": "4.0.29",
4
4
  "description": "Parse Server Cloud Code for open.INC Stack.",
5
5
  "packageManager": "pnpm@10.33.0",
6
6
  "keywords": [