@openinc/parse-server-opendash 4.0.39 → 4.0.41

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.
package/README.md CHANGED
@@ -29,5 +29,6 @@ For a full list of options see the file at [CONFIG.md](https://github.com/open-i
29
29
 
30
30
  ## Development
31
31
 
32
+
32
33
  See the file at [DEVELOPMENT.md](https://github.com/open-inc/node-parse-server-opendash/blob/master/DEVELOPMENT.md)
33
34
 
@@ -18,6 +18,7 @@
18
18
  "OD3_Config": "CORE",
19
19
  "OD3_Contact": "CORE",
20
20
  "OD3_Core_Email": "CORE",
21
+ "OD3_Core_RequestTemplate": "CORE",
21
22
  "OD3_Core_Token": "CORE",
22
23
  "OD3_Dashboard": "MONITORING",
23
24
  "OD3_Documentation_Category": "DOCUMENTATION",
@@ -0,0 +1,5 @@
1
+ import { ProxyRequestParams } from "./openinc-proxy-request.common.js";
2
+ export type ProxyRequestByIdParams = ProxyRequestParams & {
3
+ id: string;
4
+ };
5
+ export declare function init(name: string): Promise<void>;
@@ -0,0 +1,21 @@
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.init = init;
7
+ const node_1 = __importDefault(require("parse/node"));
8
+ const openinc_proxy_request_common_js_1 = require("./openinc-proxy-request.common.js");
9
+ async function init(name) {
10
+ node_1.default.Cloud.define(name, handleRequest, {
11
+ requireUser: true,
12
+ fields: ["id"],
13
+ });
14
+ }
15
+ async function handleRequest(request) {
16
+ const auth = request.master
17
+ ? { useMasterKey: true }
18
+ : { sessionToken: request.user?.getSessionToken() ?? undefined };
19
+ const template = await (0, openinc_proxy_request_common_js_1.findTemplateById)(request.params.id, auth);
20
+ return await (0, openinc_proxy_request_common_js_1.executeTemplate)(template, request.params);
21
+ }
@@ -0,0 +1,42 @@
1
+ import { Core_RequestTemplate } from "../types/index.js";
2
+ export interface ProxyRequestParams {
3
+ method?: string;
4
+ path?: string;
5
+ query?: Record<string, string>;
6
+ headers?: Record<string, string>;
7
+ body?: unknown;
8
+ placeholders?: Record<string, string>;
9
+ }
10
+ export interface ProxyRequestResult {
11
+ success: boolean;
12
+ status: number;
13
+ statusText: string;
14
+ headers: Record<string, string>;
15
+ body: unknown;
16
+ }
17
+ export interface ProxyAuthOptions {
18
+ sessionToken?: string;
19
+ useMasterKey?: boolean;
20
+ }
21
+ /**
22
+ * Finds the request template with the given identifier that is visible to the
23
+ * caller (ACL check via the caller's credentials) and has the highest
24
+ * priority. The returned object is re-fetched with the master key, so it
25
+ * includes the protected fields (secrets, headers, query, body).
26
+ */
27
+ export declare function findTemplateByIdentifier(identifier: string, auth: ProxyAuthOptions): Promise<Core_RequestTemplate>;
28
+ /**
29
+ * Finds the request template with the given objectId, if the caller's ACLs
30
+ * allow reading it. The returned object is re-fetched with the master key, so
31
+ * it includes the protected fields (secrets, headers, query, body).
32
+ */
33
+ export declare function findTemplateById(id: string, auth: ProxyAuthOptions): Promise<Core_RequestTemplate>;
34
+ /**
35
+ * Executes the request described by the template, merged with the caller
36
+ * provided request parts. Template values always win over caller values, so
37
+ * callers cannot override backend provided credentials. Placeholders
38
+ * ({{secrets.NAME}} and {{params.NAME}}) are only resolved inside template
39
+ * owned values, never inside caller input, so secrets cannot be exfiltrated
40
+ * by the caller.
41
+ */
42
+ export declare function executeTemplate(template: Core_RequestTemplate, params: ProxyRequestParams): Promise<ProxyRequestResult>;
@@ -0,0 +1,230 @@
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.findTemplateByIdentifier = findTemplateByIdentifier;
7
+ exports.findTemplateById = findTemplateById;
8
+ exports.executeTemplate = executeTemplate;
9
+ const node_1 = __importDefault(require("parse/node"));
10
+ const index_js_1 = require("../types/index.js");
11
+ const HTTP_METHODS = [
12
+ "GET",
13
+ "HEAD",
14
+ "POST",
15
+ "PUT",
16
+ "PATCH",
17
+ "DELETE",
18
+ "OPTIONS",
19
+ ];
20
+ const METHODS_WITHOUT_BODY = ["GET", "HEAD"];
21
+ const DEFAULT_TIMEOUT = 30_000;
22
+ /**
23
+ * Finds the request template with the given identifier that is visible to the
24
+ * caller (ACL check via the caller's credentials) and has the highest
25
+ * priority. The returned object is re-fetched with the master key, so it
26
+ * includes the protected fields (secrets, headers, query, body).
27
+ */
28
+ async function findTemplateByIdentifier(identifier, auth) {
29
+ const visible = await new node_1.default.Query(index_js_1.Core_RequestTemplate)
30
+ .equalTo("identifier", identifier)
31
+ .descending("priority")
32
+ .addAscending("createdAt")
33
+ .first(auth);
34
+ if (!visible) {
35
+ throw new node_1.default.Error(node_1.default.Error.OBJECT_NOT_FOUND, `No request template found for identifier "${identifier}".`);
36
+ }
37
+ return await fetchTemplateWithMasterKey(visible.id);
38
+ }
39
+ /**
40
+ * Finds the request template with the given objectId, if the caller's ACLs
41
+ * allow reading it. The returned object is re-fetched with the master key, so
42
+ * it includes the protected fields (secrets, headers, query, body).
43
+ */
44
+ async function findTemplateById(id, auth) {
45
+ const visible = await new node_1.default.Query(index_js_1.Core_RequestTemplate)
46
+ .equalTo("objectId", id)
47
+ .first(auth);
48
+ if (!visible) {
49
+ throw new node_1.default.Error(node_1.default.Error.OBJECT_NOT_FOUND, `No request template found for id "${id}".`);
50
+ }
51
+ return await fetchTemplateWithMasterKey(visible.id);
52
+ }
53
+ /**
54
+ * Executes the request described by the template, merged with the caller
55
+ * provided request parts. Template values always win over caller values, so
56
+ * callers cannot override backend provided credentials. Placeholders
57
+ * ({{secrets.NAME}} and {{params.NAME}}) are only resolved inside template
58
+ * owned values, never inside caller input, so secrets cannot be exfiltrated
59
+ * by the caller.
60
+ */
61
+ async function executeTemplate(template, params) {
62
+ const context = {
63
+ secrets: asRecord(template.get("secrets")),
64
+ params: params.placeholders ?? {},
65
+ };
66
+ const method = resolveMethod(template, params.method);
67
+ const url = buildUrl(template, params, context);
68
+ const headers = buildHeaders(template, params, context);
69
+ const body = buildBody(template, params, context, method, headers);
70
+ const timeout = template.get("timeout") ?? DEFAULT_TIMEOUT;
71
+ const response = await fetch(url, {
72
+ method,
73
+ headers,
74
+ body,
75
+ signal: AbortSignal.timeout(timeout),
76
+ });
77
+ return {
78
+ success: response.ok,
79
+ status: response.status,
80
+ statusText: response.statusText,
81
+ headers: Object.fromEntries(response.headers.entries()),
82
+ body: await parseResponseBody(response),
83
+ };
84
+ }
85
+ async function fetchTemplateWithMasterKey(id) {
86
+ return await new node_1.default.Query(index_js_1.Core_RequestTemplate).get(id, {
87
+ useMasterKey: true,
88
+ });
89
+ }
90
+ function resolveMethod(template, requested) {
91
+ const forced = template.get("method");
92
+ const method = String(forced || requested || "GET").toUpperCase();
93
+ if (!HTTP_METHODS.includes(method)) {
94
+ throw new node_1.default.Error(node_1.default.Error.VALIDATION_ERROR, `Unsupported HTTP method "${method}".`);
95
+ }
96
+ if (forced) {
97
+ return method;
98
+ }
99
+ const allowed = template.get("allowedMethods");
100
+ if (Array.isArray(allowed) && allowed.length > 0) {
101
+ const allowedUpper = allowed.map((entry) => String(entry).toUpperCase());
102
+ if (!allowedUpper.includes(method)) {
103
+ throw new node_1.default.Error(node_1.default.Error.OPERATION_FORBIDDEN, `HTTP method "${method}" is not allowed by this request template.`);
104
+ }
105
+ }
106
+ return method;
107
+ }
108
+ function buildUrl(template, params, context) {
109
+ let raw = resolvePlaceholders(template.get("url"), context);
110
+ if (params.path) {
111
+ if (template.get("allowPath") !== true) {
112
+ throw new node_1.default.Error(node_1.default.Error.OPERATION_FORBIDDEN, "This request template does not allow a custom path.");
113
+ }
114
+ raw = joinUrl(raw, params.path);
115
+ }
116
+ const url = parseUrl(raw);
117
+ for (const [key, value] of Object.entries(params.query ?? {})) {
118
+ url.searchParams.set(key, String(value));
119
+ }
120
+ const templateQuery = resolveDeep(asRecord(template.get("query")), context);
121
+ for (const [key, value] of Object.entries(templateQuery)) {
122
+ url.searchParams.set(key, String(value));
123
+ }
124
+ return url.toString();
125
+ }
126
+ function buildHeaders(template, params, context) {
127
+ const headers = new Headers();
128
+ for (const [key, value] of Object.entries(params.headers ?? {})) {
129
+ headers.set(key, String(value));
130
+ }
131
+ const templateHeaders = resolveDeep(asRecord(template.get("headers")), context);
132
+ for (const [key, value] of Object.entries(templateHeaders)) {
133
+ headers.set(key, String(value));
134
+ }
135
+ return headers;
136
+ }
137
+ function buildBody(template, params, context, method, headers) {
138
+ if (METHODS_WITHOUT_BODY.includes(method)) {
139
+ return undefined;
140
+ }
141
+ const templateBody = template.get("body")
142
+ ? resolveDeep(asRecord(template.get("body")), context)
143
+ : undefined;
144
+ const body = mergeBodies(params.body, templateBody);
145
+ if (body === undefined) {
146
+ return undefined;
147
+ }
148
+ if (typeof body === "string") {
149
+ return body;
150
+ }
151
+ if (!headers.has("content-type")) {
152
+ headers.set("content-type", "application/json");
153
+ }
154
+ return JSON.stringify(body);
155
+ }
156
+ /**
157
+ * Deep merges the template body into the caller body. On conflicts the
158
+ * template always wins; plain objects are merged recursively, everything else
159
+ * (arrays, strings, numbers, ...) is replaced.
160
+ */
161
+ function mergeBodies(callerBody, templateBody) {
162
+ if (templateBody === undefined) {
163
+ return callerBody;
164
+ }
165
+ if (!isPlainObject(callerBody) || !isPlainObject(templateBody)) {
166
+ return templateBody;
167
+ }
168
+ const result = { ...callerBody };
169
+ for (const [key, value] of Object.entries(templateBody)) {
170
+ result[key] = mergeBodies(result[key], value);
171
+ }
172
+ return result;
173
+ }
174
+ function resolvePlaceholders(input, context) {
175
+ return input.replace(/\{\{\s*(secrets|params)\.([\w.-]+)\s*\}\}/g, (match, scope, key) => {
176
+ const source = scope === "secrets" ? context.secrets : context.params;
177
+ const value = source[key];
178
+ if (value === undefined || value === null) {
179
+ throw new node_1.default.Error(node_1.default.Error.VALIDATION_ERROR, `Unresolved placeholder ${JSON.stringify(match)} in request template.`);
180
+ }
181
+ return String(value);
182
+ });
183
+ }
184
+ function resolveDeep(value, context) {
185
+ if (typeof value === "string") {
186
+ return resolvePlaceholders(value, context);
187
+ }
188
+ if (Array.isArray(value)) {
189
+ return value.map((entry) => resolveDeep(entry, context));
190
+ }
191
+ if (isPlainObject(value)) {
192
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
193
+ key,
194
+ resolveDeep(entry, context),
195
+ ]));
196
+ }
197
+ return value;
198
+ }
199
+ async function parseResponseBody(response) {
200
+ const text = await response.text();
201
+ const contentType = response.headers.get("content-type") ?? "";
202
+ if (!contentType.includes("json")) {
203
+ return text;
204
+ }
205
+ try {
206
+ return JSON.parse(text);
207
+ }
208
+ catch {
209
+ return text;
210
+ }
211
+ }
212
+ function parseUrl(raw) {
213
+ try {
214
+ return new URL(raw);
215
+ }
216
+ catch {
217
+ throw new node_1.default.Error(node_1.default.Error.VALIDATION_ERROR, `Request template contains an invalid URL.`);
218
+ }
219
+ }
220
+ function joinUrl(base, path) {
221
+ const trimmedBase = base.endsWith("/") ? base.slice(0, -1) : base;
222
+ const trimmedPath = path.startsWith("/") ? path : `/${path}`;
223
+ return trimmedBase + trimmedPath;
224
+ }
225
+ function asRecord(value) {
226
+ return isPlainObject(value) ? value : {};
227
+ }
228
+ function isPlainObject(value) {
229
+ return (typeof value === "object" && value !== null && !Array.isArray(value));
230
+ }
@@ -0,0 +1,5 @@
1
+ import { ProxyRequestParams } from "./openinc-proxy-request.common.js";
2
+ export type ProxyRequestByIdentifierParams = ProxyRequestParams & {
3
+ identifier: string;
4
+ };
5
+ export declare function init(name: string): Promise<void>;
@@ -0,0 +1,21 @@
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.init = init;
7
+ const node_1 = __importDefault(require("parse/node"));
8
+ const openinc_proxy_request_common_js_1 = require("./openinc-proxy-request.common.js");
9
+ async function init(name) {
10
+ node_1.default.Cloud.define(name, handleRequest, {
11
+ requireUser: true,
12
+ fields: ["identifier"],
13
+ });
14
+ }
15
+ async function handleRequest(request) {
16
+ const auth = request.master
17
+ ? { useMasterKey: true }
18
+ : { sessionToken: request.user?.getSessionToken() ?? undefined };
19
+ const template = await (0, openinc_proxy_request_common_js_1.findTemplateByIdentifier)(request.params.identifier, auth);
20
+ return await (0, openinc_proxy_request_common_js_1.executeTemplate)(template, request.params);
21
+ }
@@ -0,0 +1 @@
1
+ export declare function init(): Promise<void>;
@@ -0,0 +1,24 @@
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.init = init;
7
+ const node_1 = __importDefault(require("parse/node"));
8
+ const index_js_1 = require("../features/schema/index.js");
9
+ const index_js_2 = require("../types/index.js");
10
+ async function init() {
11
+ (0, index_js_1.beforeSaveHook)(index_js_2.Core_RequestTemplate, async (request) => {
12
+ const { object } = request;
13
+ await (0, index_js_1.defaultHandler)(request);
14
+ await (0, index_js_1.defaultAclHandler)(request);
15
+ const identifier = object.get("identifier");
16
+ if (typeof identifier !== "string" || identifier.trim() === "") {
17
+ throw new node_1.default.Error(node_1.default.Error.VALIDATION_ERROR, "Field 'identifier' must be a non-empty string.");
18
+ }
19
+ const url = object.get("url");
20
+ if (typeof url !== "string" || url.trim() === "") {
21
+ throw new node_1.default.Error(node_1.default.Error.VALIDATION_ERROR, "Field 'url' must be a non-empty string.");
22
+ }
23
+ });
24
+ }
@@ -0,0 +1,55 @@
1
+ import Parse from "parse/node";
2
+ import type { Tenant } from "./Tenant";
3
+ import type { _User } from "./_User";
4
+ export interface Core_RequestTemplateAttributes {
5
+ id: string;
6
+ objectId: string;
7
+ createdAt: Date;
8
+ updatedAt: Date;
9
+ identifier: string;
10
+ priority: number;
11
+ description?: string | undefined;
12
+ url: string;
13
+ method?: string | undefined;
14
+ allowedMethods?: any[] | undefined;
15
+ allowPath?: boolean | undefined;
16
+ headers?: any;
17
+ query?: any;
18
+ body?: any;
19
+ secrets?: any;
20
+ timeout?: number | undefined;
21
+ tenant?: Tenant | undefined;
22
+ user?: _User | undefined;
23
+ }
24
+ export declare class Core_RequestTemplate extends Parse.Object<Core_RequestTemplateAttributes> {
25
+ static className: string;
26
+ constructor(data?: Partial<Core_RequestTemplateAttributes>);
27
+ get identifier(): string;
28
+ set identifier(value: string);
29
+ get priority(): number;
30
+ set priority(value: number);
31
+ get description(): string | undefined;
32
+ set description(value: string | undefined);
33
+ get url(): string;
34
+ set url(value: string);
35
+ get method(): string | undefined;
36
+ set method(value: string | undefined);
37
+ get allowedMethods(): any[] | undefined;
38
+ set allowedMethods(value: any[] | undefined);
39
+ get allowPath(): boolean | undefined;
40
+ set allowPath(value: boolean | undefined);
41
+ get headers(): any;
42
+ set headers(value: any);
43
+ get query(): any;
44
+ set query(value: any);
45
+ get body(): any;
46
+ set body(value: any);
47
+ get secrets(): any;
48
+ set secrets(value: any);
49
+ get timeout(): number | undefined;
50
+ set timeout(value: number | undefined);
51
+ get tenant(): Tenant | undefined;
52
+ set tenant(value: Tenant | undefined);
53
+ get user(): _User | undefined;
54
+ set user(value: _User | undefined);
55
+ }
@@ -0,0 +1,99 @@
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.Core_RequestTemplate = void 0;
7
+ const node_1 = __importDefault(require("parse/node"));
8
+ class Core_RequestTemplate extends node_1.default.Object {
9
+ static className = "OD3_Core_RequestTemplate";
10
+ constructor(data) {
11
+ super("OD3_Core_RequestTemplate", data);
12
+ }
13
+ get identifier() {
14
+ return super.get("identifier");
15
+ }
16
+ set identifier(value) {
17
+ super.set("identifier", value);
18
+ }
19
+ get priority() {
20
+ return super.get("priority");
21
+ }
22
+ set priority(value) {
23
+ super.set("priority", value);
24
+ }
25
+ get description() {
26
+ return super.get("description");
27
+ }
28
+ set description(value) {
29
+ super.set("description", value);
30
+ }
31
+ get url() {
32
+ return super.get("url");
33
+ }
34
+ set url(value) {
35
+ super.set("url", value);
36
+ }
37
+ get method() {
38
+ return super.get("method");
39
+ }
40
+ set method(value) {
41
+ super.set("method", value);
42
+ }
43
+ get allowedMethods() {
44
+ return super.get("allowedMethods");
45
+ }
46
+ set allowedMethods(value) {
47
+ super.set("allowedMethods", value);
48
+ }
49
+ get allowPath() {
50
+ return super.get("allowPath");
51
+ }
52
+ set allowPath(value) {
53
+ super.set("allowPath", value);
54
+ }
55
+ get headers() {
56
+ return super.get("headers");
57
+ }
58
+ set headers(value) {
59
+ super.set("headers", value);
60
+ }
61
+ get query() {
62
+ return super.get("query");
63
+ }
64
+ set query(value) {
65
+ super.set("query", value);
66
+ }
67
+ get body() {
68
+ return super.get("body");
69
+ }
70
+ set body(value) {
71
+ super.set("body", value);
72
+ }
73
+ get secrets() {
74
+ return super.get("secrets");
75
+ }
76
+ set secrets(value) {
77
+ super.set("secrets", value);
78
+ }
79
+ get timeout() {
80
+ return super.get("timeout");
81
+ }
82
+ set timeout(value) {
83
+ super.set("timeout", value);
84
+ }
85
+ get tenant() {
86
+ return super.get("tenant");
87
+ }
88
+ set tenant(value) {
89
+ super.set("tenant", value);
90
+ }
91
+ get user() {
92
+ return super.get("user");
93
+ }
94
+ set user(value) {
95
+ super.set("user", value);
96
+ }
97
+ }
98
+ exports.Core_RequestTemplate = Core_RequestTemplate;
99
+ node_1.default.Object.registerSubclass("OD3_Core_RequestTemplate", Core_RequestTemplate);
@@ -36,6 +36,8 @@ export { Contact } from "./Contact";
36
36
  export type { ContactAttributes } from "./Contact";
37
37
  export { Core_Email } from "./Core_Email";
38
38
  export type { Core_EmailAttributes } from "./Core_Email";
39
+ export { Core_RequestTemplate } from "./Core_RequestTemplate";
40
+ export type { Core_RequestTemplateAttributes } from "./Core_RequestTemplate";
39
41
  export { Core_Token } from "./Core_Token";
40
42
  export type { Core_TokenAttributes } from "./Core_Token";
41
43
  export { Dashboard } from "./Dashboard";
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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.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;
3
+ 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_RequestTemplate = 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.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 = exports.MES_OrderPlan = 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 = exports.Push = 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");
@@ -41,6 +41,8 @@ var Contact_1 = require("./Contact");
41
41
  Object.defineProperty(exports, "Contact", { enumerable: true, get: function () { return Contact_1.Contact; } });
42
42
  var Core_Email_1 = require("./Core_Email");
43
43
  Object.defineProperty(exports, "Core_Email", { enumerable: true, get: function () { return Core_Email_1.Core_Email; } });
44
+ var Core_RequestTemplate_1 = require("./Core_RequestTemplate");
45
+ Object.defineProperty(exports, "Core_RequestTemplate", { enumerable: true, get: function () { return Core_RequestTemplate_1.Core_RequestTemplate; } });
44
46
  var Core_Token_1 = require("./Core_Token");
45
47
  Object.defineProperty(exports, "Core_Token", { enumerable: true, get: function () { return Core_Token_1.Core_Token; } });
46
48
  var Dashboard_1 = require("./Dashboard");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openinc/parse-server-opendash",
3
- "version": "4.0.39",
3
+ "version": "4.0.41",
4
4
  "description": "Parse Server Cloud Code for open.INC Stack.",
5
5
  "packageManager": "pnpm@11.9.0",
6
6
  "keywords": [
@@ -0,0 +1,89 @@
1
+ {
2
+ "fields": {
3
+ "identifier": {
4
+ "type": "String",
5
+ "required": true
6
+ },
7
+ "priority": {
8
+ "type": "Number",
9
+ "required": true,
10
+ "defaultValue": 0
11
+ },
12
+ "description": {
13
+ "type": "String",
14
+ "required": false
15
+ },
16
+ "url": {
17
+ "type": "String",
18
+ "required": true
19
+ },
20
+ "method": {
21
+ "type": "String",
22
+ "required": false
23
+ },
24
+ "allowedMethods": {
25
+ "type": "Array",
26
+ "required": false
27
+ },
28
+ "allowPath": {
29
+ "type": "Boolean",
30
+ "required": false,
31
+ "defaultValue": false
32
+ },
33
+ "headers": {
34
+ "type": "Object",
35
+ "required": false
36
+ },
37
+ "query": {
38
+ "type": "Object",
39
+ "required": false
40
+ },
41
+ "body": {
42
+ "type": "Object",
43
+ "required": false
44
+ },
45
+ "secrets": {
46
+ "type": "Object",
47
+ "required": false
48
+ },
49
+ "timeout": {
50
+ "type": "Number",
51
+ "required": false
52
+ },
53
+ "tenant": {
54
+ "type": "Pointer",
55
+ "targetClass": "{{PREFIX}}Tenant",
56
+ "required": false
57
+ },
58
+ "user": {
59
+ "type": "Pointer",
60
+ "targetClass": "_User",
61
+ "required": false
62
+ }
63
+ },
64
+ "classLevelPermissions": {
65
+ "find": {
66
+ "requiresAuthentication": true
67
+ },
68
+ "count": {
69
+ "requiresAuthentication": true
70
+ },
71
+ "get": {
72
+ "requiresAuthentication": true
73
+ },
74
+ "create": {
75
+ "requiresAuthentication": true
76
+ },
77
+ "update": {
78
+ "requiresAuthentication": true
79
+ },
80
+ "delete": {
81
+ "requiresAuthentication": true
82
+ },
83
+ "addField": {},
84
+ "protectedFields": {
85
+ "*": ["secrets", "headers", "query", "body"],
86
+ "role:od-admin": []
87
+ }
88
+ }
89
+ }