@openinc/node-red-contrib-openinc-parse 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +33 -0
  3. package/dist/nodes/openinc-parse-changestream/modules/types.js +3 -0
  4. package/dist/nodes/openinc-parse-changestream/modules/types.js.map +1 -0
  5. package/dist/nodes/openinc-parse-changestream/openinc-parse-changestream.html +267 -0
  6. package/dist/nodes/openinc-parse-changestream/openinc-parse-changestream.js +147 -0
  7. package/dist/nodes/openinc-parse-changestream/openinc-parse-changestream.js.map +1 -0
  8. package/dist/nodes/openinc-parse-changestream/shared/types.js +3 -0
  9. package/dist/nodes/openinc-parse-changestream/shared/types.js.map +1 -0
  10. package/dist/nodes/openinc-parse-config/modules/types.js +3 -0
  11. package/dist/nodes/openinc-parse-config/modules/types.js.map +1 -0
  12. package/dist/nodes/openinc-parse-config/openinc-parse-config.html +416 -0
  13. package/dist/nodes/openinc-parse-config/openinc-parse-config.js +102 -0
  14. package/dist/nodes/openinc-parse-config/openinc-parse-config.js.map +1 -0
  15. package/dist/nodes/openinc-parse-config/shared/types.js +3 -0
  16. package/dist/nodes/openinc-parse-config/shared/types.js.map +1 -0
  17. package/dist/nodes/openinc-parse-delete/modules/types.js +3 -0
  18. package/dist/nodes/openinc-parse-delete/modules/types.js.map +1 -0
  19. package/dist/nodes/openinc-parse-delete/openinc-parse-delete.html +231 -0
  20. package/dist/nodes/openinc-parse-delete/openinc-parse-delete.js +60 -0
  21. package/dist/nodes/openinc-parse-delete/openinc-parse-delete.js.map +1 -0
  22. package/dist/nodes/openinc-parse-delete/shared/types.js +3 -0
  23. package/dist/nodes/openinc-parse-delete/shared/types.js.map +1 -0
  24. package/dist/nodes/openinc-parse-fetch-relation/modules/types.js +3 -0
  25. package/dist/nodes/openinc-parse-fetch-relation/modules/types.js.map +1 -0
  26. package/dist/nodes/openinc-parse-fetch-relation/openinc-parse-fetch-relation.html +306 -0
  27. package/dist/nodes/openinc-parse-fetch-relation/openinc-parse-fetch-relation.js +142 -0
  28. package/dist/nodes/openinc-parse-fetch-relation/openinc-parse-fetch-relation.js.map +1 -0
  29. package/dist/nodes/openinc-parse-fetch-relation/shared/types.js +3 -0
  30. package/dist/nodes/openinc-parse-fetch-relation/shared/types.js.map +1 -0
  31. package/dist/nodes/openinc-parse-find/modules/types.js +3 -0
  32. package/dist/nodes/openinc-parse-find/modules/types.js.map +1 -0
  33. package/dist/nodes/openinc-parse-find/openinc-parse-find.html +245 -0
  34. package/dist/nodes/openinc-parse-find/openinc-parse-find.js +63 -0
  35. package/dist/nodes/openinc-parse-find/openinc-parse-find.js.map +1 -0
  36. package/dist/nodes/openinc-parse-find/shared/types.js +3 -0
  37. package/dist/nodes/openinc-parse-find/shared/types.js.map +1 -0
  38. package/dist/nodes/openinc-parse-querybuilder/modules/types.js +3 -0
  39. package/dist/nodes/openinc-parse-querybuilder/modules/types.js.map +1 -0
  40. package/dist/nodes/openinc-parse-querybuilder/openinc-parse-querybuilder.html +440 -0
  41. package/dist/nodes/openinc-parse-querybuilder/openinc-parse-querybuilder.js +153 -0
  42. package/dist/nodes/openinc-parse-querybuilder/openinc-parse-querybuilder.js.map +1 -0
  43. package/dist/nodes/openinc-parse-querybuilder/shared/types.js +3 -0
  44. package/dist/nodes/openinc-parse-querybuilder/shared/types.js.map +1 -0
  45. package/dist/nodes/openinc-parse-save/modules/types.js +3 -0
  46. package/dist/nodes/openinc-parse-save/modules/types.js.map +1 -0
  47. package/dist/nodes/openinc-parse-save/openinc-parse-save.html +241 -0
  48. package/dist/nodes/openinc-parse-save/openinc-parse-save.js +75 -0
  49. package/dist/nodes/openinc-parse-save/openinc-parse-save.js.map +1 -0
  50. package/dist/nodes/openinc-parse-save/shared/types.js +3 -0
  51. package/dist/nodes/openinc-parse-save/shared/types.js.map +1 -0
  52. package/dist/nodes/openinc-parse-subscribe/modules/types.js +3 -0
  53. package/dist/nodes/openinc-parse-subscribe/modules/types.js.map +1 -0
  54. package/dist/nodes/openinc-parse-subscribe/openinc-parse-subscribe.html +260 -0
  55. package/dist/nodes/openinc-parse-subscribe/openinc-parse-subscribe.js +106 -0
  56. package/dist/nodes/openinc-parse-subscribe/openinc-parse-subscribe.js.map +1 -0
  57. package/dist/nodes/openinc-parse-subscribe/shared/types.js +3 -0
  58. package/dist/nodes/openinc-parse-subscribe/shared/types.js.map +1 -0
  59. package/dist/nodes/shared/helper.js +45 -0
  60. package/dist/nodes/shared/helper.js.map +1 -0
  61. package/dist/nodes/shared/livequery.js +171 -0
  62. package/dist/nodes/shared/livequery.js.map +1 -0
  63. package/dist/nodes/shared/parse-api.js +121 -0
  64. package/dist/nodes/shared/parse-api.js.map +1 -0
  65. package/dist/nodes/shared/schema-editor.js +163 -0
  66. package/dist/nodes/shared/schema-editor.js.map +1 -0
  67. package/dist/nodes/shared/types.js +3 -0
  68. package/dist/nodes/shared/types.js.map +1 -0
  69. package/package.json +61 -0
@@ -0,0 +1,416 @@
1
+ <script type="text/javascript">
2
+ (function () {
3
+ 'use strict';
4
+
5
+ /******************************************************************************
6
+ Copyright (c) Microsoft Corporation.
7
+
8
+ Permission to use, copy, modify, and/or distribute this software for any
9
+ purpose with or without fee is hereby granted.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ ***************************************************************************** */
19
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
20
+
21
+
22
+ var __assign = function() {
23
+ __assign = Object.assign || function __assign(t) {
24
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
25
+ s = arguments[i];
26
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
27
+ }
28
+ return t;
29
+ };
30
+ return __assign.apply(this, arguments);
31
+ };
32
+
33
+ function __awaiter(thisArg, _arguments, P, generator) {
34
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
35
+ return new (P || (P = Promise))(function (resolve, reject) {
36
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
37
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
38
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
39
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
40
+ });
41
+ }
42
+
43
+ function __generator(thisArg, body) {
44
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
45
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
46
+ function verb(n) { return function (v) { return step([n, v]); }; }
47
+ function step(op) {
48
+ if (f) throw new TypeError("Generator is already executing.");
49
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
50
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
51
+ if (y = 0, t) op = [op[0] & 2, t.value];
52
+ switch (op[0]) {
53
+ case 0: case 1: t = op; break;
54
+ case 4: _.label++; return { value: op[1], done: false };
55
+ case 5: _.label++; y = op[1]; op = [0]; continue;
56
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
57
+ default:
58
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
59
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
60
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
61
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
62
+ if (t[2]) _.ops.pop();
63
+ _.trys.pop(); continue;
64
+ }
65
+ op = body.call(thisArg, _);
66
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
67
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
68
+ }
69
+ }
70
+
71
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
72
+ var e = new Error(message);
73
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
74
+ };
75
+
76
+ // Editor-only helpers (run in the Node-RED editor, not the runtime). They parse
77
+ // a Parse schema — as exported from the dashboard or fetched from /schemas — and
78
+ // wire jQuery-UI autocomplete onto class-name / field-name inputs. Other node
79
+ // editors read the schema straight off the referenced config node, so no server
80
+ // round-trip is needed while editing.
81
+ var EMPTY = {
82
+ classNames: [],
83
+ fieldsByClass: {},
84
+ relationsByClass: {},
85
+ };
86
+ /**
87
+ * Parses a schema JSON string. Accepts the shapes the Parse dashboard / REST
88
+ * API produce: an array of class schemas, `{ results: [...] }`, or a single
89
+ * class object.
90
+ */
91
+ function parseSchema(raw) {
92
+ if (!raw || typeof raw !== "string" || raw.trim() === "")
93
+ return EMPTY;
94
+ var data;
95
+ try {
96
+ data = JSON.parse(raw);
97
+ }
98
+ catch (_a) {
99
+ return EMPTY;
100
+ }
101
+ var classes = [];
102
+ if (Array.isArray(data)) {
103
+ classes = data;
104
+ }
105
+ else if (data && Array.isArray(data.results)) {
106
+ classes = data.results;
107
+ }
108
+ else if (data && typeof data.className === "string") {
109
+ classes = [data];
110
+ }
111
+ else if (data && typeof data === "object") {
112
+ // Object keyed by class name -> schema.
113
+ classes = Object.keys(data).map(function (key) {
114
+ return data[key] && data[key].className ? data[key] : __assign({ className: key }, data[key]);
115
+ });
116
+ }
117
+ var result = {
118
+ classNames: [],
119
+ fieldsByClass: {},
120
+ relationsByClass: {},
121
+ };
122
+ var _loop_1 = function (cls) {
123
+ if (!cls || typeof cls !== "object")
124
+ return "continue";
125
+ var name_1 = cls.className;
126
+ if (typeof name_1 !== "string" || name_1 === "")
127
+ return "continue";
128
+ if (result.classNames.indexOf(name_1) === -1)
129
+ result.classNames.push(name_1);
130
+ var fields = cls.fields && typeof cls.fields === "object" ? cls.fields : {};
131
+ var fieldNames = Object.keys(fields);
132
+ result.fieldsByClass[name_1] = fieldNames;
133
+ result.relationsByClass[name_1] = fieldNames.filter(function (field) { return fields[field] && fields[field].type === "Relation"; });
134
+ };
135
+ for (var _i = 0, classes_1 = classes; _i < classes_1.length; _i++) {
136
+ var cls = classes_1[_i];
137
+ _loop_1(cls);
138
+ }
139
+ result.classNames.sort();
140
+ return result;
141
+ }
142
+ /** Short human summary, e.g. "12 classes, 84 fields". */
143
+ function schemaSummary(raw) {
144
+ var schema = parseSchema(raw);
145
+ if (schema.classNames.length === 0)
146
+ return "";
147
+ var fieldCount = Object.keys(schema.fieldsByClass).reduce(function (sum, cls) { return sum + schema.fieldsByClass[cls].length; }, 0);
148
+ return "".concat(schema.classNames.length, " classes, ").concat(fieldCount, " fields");
149
+ }
150
+
151
+ RED.nodes.registerType("openinc-parse-config", {
152
+ category: "config",
153
+ defaults: {
154
+ serverUrl: { value: "http://localhost:1337/parse", required: true },
155
+ liveQueryUrl: { value: "", required: false },
156
+ appId: { value: "", required: true },
157
+ useMasterKey: { value: false, required: false },
158
+ schema: { value: "" },
159
+ },
160
+ //@ts-expect-error credentials are not part of the editor typings
161
+ credentials: {
162
+ restApiKey: { type: "password" },
163
+ javascriptKey: { type: "password" },
164
+ masterKey: { type: "password" },
165
+ sessionToken: { type: "password" },
166
+ },
167
+ label: function () {
168
+ return this.appId
169
+ ? "".concat(this.appId, " @ ").concat(this.serverUrl)
170
+ : this.serverUrl || "parse server";
171
+ },
172
+ oneditprepare: function () {
173
+ var _this = this;
174
+ var testButton = document.getElementById("openinc-parse-config-test");
175
+ var resultSpan = document.getElementById("openinc-parse-config-test-result");
176
+ testButton === null || testButton === void 0 ? void 0 : testButton.addEventListener("click", function () { return __awaiter(_this, void 0, void 0, function () {
177
+ var serverUrl, appId, data, error_1, jqXHR, detail;
178
+ return __generator(this, function (_a) {
179
+ switch (_a.label) {
180
+ case 0:
181
+ if (!resultSpan)
182
+ return [2 /*return*/];
183
+ serverUrl = String($("#node-config-input-serverUrl").val() || "");
184
+ appId = String($("#node-config-input-appId").val() || "");
185
+ resultSpan.textContent = "testing...";
186
+ resultSpan.style.color = "#888";
187
+ _a.label = 1;
188
+ case 1:
189
+ _a.trys.push([1, 3, , 4]);
190
+ return [4 /*yield*/, $.ajax({
191
+ url: "openinc-parse/test-connection?serverUrl=" +
192
+ encodeURIComponent(serverUrl) +
193
+ "&appId=" +
194
+ encodeURIComponent(appId),
195
+ dataType: "json",
196
+ })];
197
+ case 2:
198
+ data = _a.sent();
199
+ if (data.ok) {
200
+ resultSpan.textContent = "OK - server is healthy";
201
+ resultSpan.style.color = "#5cb85c";
202
+ }
203
+ else {
204
+ resultSpan.textContent =
205
+ "Failed: " + (data.error || "HTTP ".concat(data.status));
206
+ resultSpan.style.color = "#d9534f";
207
+ }
208
+ return [3 /*break*/, 4];
209
+ case 3:
210
+ error_1 = _a.sent();
211
+ jqXHR = error_1;
212
+ detail = jqXHR && typeof jqXHR.status === "number"
213
+ ? "HTTP ".concat(jqXHR.status, " ").concat(jqXHR.statusText || "").trim()
214
+ : String(error_1);
215
+ resultSpan.textContent = "Failed: " + detail;
216
+ resultSpan.style.color = "#d9534f";
217
+ return [3 /*break*/, 4];
218
+ case 4: return [2 /*return*/];
219
+ }
220
+ });
221
+ }); });
222
+ // --- Schema: paste, fetch from server, live summary -------------------
223
+ var nodeId = this.id;
224
+ var schemaResult = document.getElementById("openinc-parse-config-schema-result");
225
+ var fetchButton = document.getElementById("openinc-parse-config-fetch-schema");
226
+ var updateSummary = function () {
227
+ if (!schemaResult)
228
+ return;
229
+ var raw = String($("#node-config-input-schema").val() || "");
230
+ if (raw.trim() === "") {
231
+ schemaResult.textContent = "";
232
+ return;
233
+ }
234
+ var summary = schemaSummary(raw);
235
+ if (summary) {
236
+ schemaResult.textContent = summary;
237
+ schemaResult.style.color = "#888";
238
+ }
239
+ else {
240
+ schemaResult.textContent = "Invalid schema JSON";
241
+ schemaResult.style.color = "#d9534f";
242
+ }
243
+ };
244
+ var fetchSchema = function (auto) { return __awaiter(_this, void 0, void 0, function () {
245
+ var serverUrl, appId, masterKey, query, headers, data, error_2, jqXHR;
246
+ return __generator(this, function (_a) {
247
+ switch (_a.label) {
248
+ case 0:
249
+ serverUrl = String($("#node-config-input-serverUrl").val() || "");
250
+ appId = String($("#node-config-input-appId").val() || "");
251
+ masterKey = String($("#node-config-input-masterKey").val() || "");
252
+ if (!serverUrl) {
253
+ if (schemaResult && !auto) {
254
+ schemaResult.textContent = "Set a Server URL first";
255
+ schemaResult.style.color = "#d9534f";
256
+ }
257
+ return [2 /*return*/];
258
+ }
259
+ query = "openinc-parse/schema?serverUrl=" +
260
+ encodeURIComponent(serverUrl) +
261
+ "&appId=" +
262
+ encodeURIComponent(appId);
263
+ headers = {};
264
+ // A freshly-typed master key is available here; a previously-saved one
265
+ // is masked as "__PWRD__", so fall back to the stored credential via id.
266
+ if (masterKey && masterKey !== "__PWRD__") {
267
+ headers["x-parse-master-key"] = masterKey;
268
+ }
269
+ else if (nodeId) {
270
+ query += "&id=" + encodeURIComponent(nodeId);
271
+ }
272
+ if (schemaResult) {
273
+ schemaResult.textContent = "fetching schema...";
274
+ schemaResult.style.color = "#888";
275
+ }
276
+ _a.label = 1;
277
+ case 1:
278
+ _a.trys.push([1, 3, , 4]);
279
+ return [4 /*yield*/, $.ajax({ url: query, headers: headers, dataType: "json" })];
280
+ case 2:
281
+ data = _a.sent();
282
+ if (data.ok) {
283
+ $("#node-config-input-schema").val(JSON.stringify(data.schema, null, 2));
284
+ updateSummary();
285
+ }
286
+ else if (schemaResult) {
287
+ schemaResult.textContent =
288
+ "Failed: " + (data.error || "HTTP ".concat(data.status));
289
+ schemaResult.style.color = "#d9534f";
290
+ }
291
+ return [3 /*break*/, 4];
292
+ case 3:
293
+ error_2 = _a.sent();
294
+ if (schemaResult) {
295
+ jqXHR = error_2;
296
+ schemaResult.textContent =
297
+ "Failed: " +
298
+ (jqXHR && typeof jqXHR.status === "number"
299
+ ? "HTTP ".concat(jqXHR.status, " ").concat(jqXHR.statusText || "").trim()
300
+ : String(error_2));
301
+ schemaResult.style.color = "#d9534f";
302
+ }
303
+ return [3 /*break*/, 4];
304
+ case 4: return [2 /*return*/];
305
+ }
306
+ });
307
+ }); };
308
+ fetchButton === null || fetchButton === void 0 ? void 0 : fetchButton.addEventListener("click", function () { return fetchSchema(false); });
309
+ $("#node-config-input-schema").on("change keyup paste", updateSummary);
310
+ updateSummary();
311
+ // Auto-fetch on open when a master key is present and no schema is set yet.
312
+ var hasMasterKey = String($("#node-config-input-masterKey").val() || "") !== "";
313
+ var hasSchema = String($("#node-config-input-schema").val() || "").trim() !== "";
314
+ if (hasMasterKey && !hasSchema) {
315
+ fetchSchema(true);
316
+ }
317
+ },
318
+ });
319
+
320
+ })();
321
+ </script>
322
+ <script type="text/html" data-help-name="openinc-parse-config">
323
+ <p>
324
+ Configuration node holding the connection settings for a Parse Server.
325
+ All Parse nodes of this package reference such a configuration.
326
+ </p>
327
+
328
+ <h2>Configuration</h2>
329
+
330
+ <ul>
331
+ <li>
332
+ <strong>Server URL:</strong> Full URL of the Parse Server REST endpoint
333
+ including the mount path, e.g. <code>https://example.com/parse</code>.
334
+ </li>
335
+ <li>
336
+ <strong>LiveQuery URL:</strong> Optional websocket URL of the LiveQuery
337
+ server (e.g. <code>wss://example.com/parse</code>). If empty, the Server
338
+ URL is used with the protocol switched to <code>ws://</code> /
339
+ <code>wss://</code>.
340
+ </li>
341
+ <li><strong>App ID:</strong> The Parse application id.</li>
342
+ <li>
343
+ <strong>REST API Key / JavaScript Key / Master Key:</strong> Optional
344
+ keys sent as the corresponding <code>X-Parse-*</code> headers.
345
+ </li>
346
+ <li>
347
+ <strong>Use Master Key:</strong> If checked (and a master key is set),
348
+ all requests are performed with the master key.
349
+ </li>
350
+ <li>
351
+ <strong>Session Token:</strong> Optional session token of a Parse user,
352
+ sent as <code>X-Parse-Session-Token</code>.
353
+ </li>
354
+ </ul>
355
+
356
+ <p>
357
+ The <strong>Test connection</strong> button calls the
358
+ <code>/health</code> endpoint of the configured server through the
359
+ Node-RED runtime.
360
+ </p>
361
+ </script>
362
+
363
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.17.0/cdn/themes/light.css" />
364
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.17.0/cdn/shoelace-autoloader.js"></script>
365
+
366
+ <script type="text/html" data-template-name="openinc-parse-config">
367
+ <div class="form-row">
368
+ <label for="node-config-input-serverUrl"><i class="fa fa-server"></i> Server URL</label>
369
+ <input type="text" id="node-config-input-serverUrl" placeholder="http://localhost:1337/parse">
370
+ </div>
371
+ <div class="form-row">
372
+ <label for="node-config-input-liveQueryUrl"><i class="fa fa-bolt"></i> LiveQuery URL</label>
373
+ <input type="text" id="node-config-input-liveQueryUrl" placeholder="(optional, e.g. ws://localhost:1337/parse)">
374
+ </div>
375
+ <div class="form-row">
376
+ <label for="node-config-input-appId"><i class="fa fa-id-card-o"></i> App ID</label>
377
+ <input type="text" id="node-config-input-appId">
378
+ </div>
379
+ <div class="form-row">
380
+ <label for="node-config-input-restApiKey"><i class="fa fa-key"></i> REST API Key</label>
381
+ <input type="password" id="node-config-input-restApiKey" placeholder="(optional)">
382
+ </div>
383
+ <div class="form-row">
384
+ <label for="node-config-input-javascriptKey"><i class="fa fa-key"></i> JavaScript Key</label>
385
+ <input type="password" id="node-config-input-javascriptKey" placeholder="(optional)">
386
+ </div>
387
+ <div class="form-row">
388
+ <label for="node-config-input-masterKey"><i class="fa fa-key"></i> Master Key</label>
389
+ <input type="password" id="node-config-input-masterKey" placeholder="(optional)">
390
+ </div>
391
+ <div class="form-row">
392
+ <label for="node-config-input-useMasterKey"><i class="fa fa-unlock-alt"></i> Use Master Key</label>
393
+ <input type="checkbox" id="node-config-input-useMasterKey" style="display:inline-block;width:auto;vertical-align:top;">
394
+ </div>
395
+ <div class="form-row">
396
+ <label for="node-config-input-sessionToken"><i class="fa fa-user-secret"></i> Session Token</label>
397
+ <input type="password" id="node-config-input-sessionToken" placeholder="(optional)">
398
+ </div>
399
+ <div class="form-row">
400
+ <label><i class="fa fa-plug"></i> Connection</label>
401
+ <sl-button id="openinc-parse-config-test" size="small">Test connection</sl-button>
402
+ <span id="openinc-parse-config-test-result" style="margin-left:8px;font-size:13px;color:#888;"></span>
403
+ </div>
404
+
405
+ <div class="form-row" style="margin-bottom:0;">
406
+ <label for="node-config-input-schema" style="vertical-align:top;"><i class="fa fa-sitemap"></i> Schema</label>
407
+ <div style="display:inline-block;width:70%;vertical-align:top;">
408
+ <sl-button id="openinc-parse-config-fetch-schema" size="small">Fetch from server</sl-button>
409
+ <span id="openinc-parse-config-schema-result" style="margin-left:8px;font-size:13px;color:#888;"></span>
410
+ </div>
411
+ </div>
412
+ <div class="form-row">
413
+ <label></label>
414
+ <textarea id="node-config-input-schema" rows="6" placeholder='Paste the schema exported from the Parse dashboard, or click "Fetch from server" (requires a Master Key).' style="width:70%;font-family:monospace;"></textarea>
415
+ </div>
416
+ </script>
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ const parse_api_1 = require("../shared/parse-api");
3
+ const nodeInit = (RED) => {
4
+ function OpenincParseConfigNodeConstructor(config) {
5
+ RED.nodes.createNode(this, config);
6
+ this.serverUrl = config.serverUrl;
7
+ this.liveQueryUrl = config.liveQueryUrl;
8
+ this.appId = config.appId;
9
+ this.useMasterKey = config.useMasterKey;
10
+ this.schema = config.schema;
11
+ (0, parse_api_1.initParseApi)(this);
12
+ }
13
+ RED.nodes.registerType("openinc-parse-config", OpenincParseConfigNodeConstructor, {
14
+ credentials: {
15
+ restApiKey: { type: "password" },
16
+ javascriptKey: { type: "password" },
17
+ masterKey: { type: "password" },
18
+ sessionToken: { type: "password" },
19
+ },
20
+ });
21
+ // Lets the editor test a connection through the runtime (avoids CORS
22
+ // restrictions of a direct browser request against the Parse server).
23
+ RED.httpAdmin.get("/openinc-parse/test-connection", RED.auth.needsPermission("flows.read"), async (req, res) => {
24
+ const serverUrl = String(req.query.serverUrl || "").replace(/\/+$/, "");
25
+ const appId = String(req.query.appId || "");
26
+ if (!serverUrl) {
27
+ res.status(400).send({ ok: false, error: "Missing serverUrl" });
28
+ return;
29
+ }
30
+ const url = (/^https?:\/\//i.test(serverUrl) ? serverUrl : "http://" + serverUrl) +
31
+ "/health";
32
+ try {
33
+ const response = await fetch(url, {
34
+ headers: appId ? { "X-Parse-Application-Id": appId } : {},
35
+ });
36
+ const text = await response.text();
37
+ res.send({ ok: response.ok, status: response.status, body: text });
38
+ }
39
+ catch (error) {
40
+ res.send({ ok: false, error: String(error) });
41
+ }
42
+ });
43
+ // Fetches the full schema from the Parse server using the Master Key, for the
44
+ // editor's "Fetch from server" button / master-key auto-fetch. The master key
45
+ // comes either from a freshly-typed value (x-parse-master-key header) or, for
46
+ // an already-saved config node, from its stored credentials (via ?id=).
47
+ RED.httpAdmin.get("/openinc-parse/schema", RED.auth.needsPermission("flows.read"), async (req, res) => {
48
+ var _a;
49
+ const serverUrl = String(req.query.serverUrl || "").replace(/\/+$/, "");
50
+ const appId = String(req.query.appId || "");
51
+ const id = req.query.id ? String(req.query.id) : "";
52
+ let masterKey = String(req.get("x-parse-master-key") || "");
53
+ if (!masterKey && id) {
54
+ const creds = RED.nodes.getCredentials(id);
55
+ masterKey = (creds === null || creds === void 0 ? void 0 : creds.masterKey) || "";
56
+ }
57
+ if (!serverUrl) {
58
+ res.status(400).send({ ok: false, error: "Missing serverUrl" });
59
+ return;
60
+ }
61
+ if (!masterKey) {
62
+ res
63
+ .status(400)
64
+ .send({ ok: false, error: "Master Key required to fetch schema" });
65
+ return;
66
+ }
67
+ const base = (/^https?:\/\//i.test(serverUrl) ? serverUrl : "http://" + serverUrl) +
68
+ "/schemas";
69
+ try {
70
+ const response = await fetch(base, {
71
+ headers: {
72
+ "X-Parse-Application-Id": appId,
73
+ "X-Parse-Master-Key": masterKey,
74
+ },
75
+ });
76
+ const text = await response.text();
77
+ let body;
78
+ try {
79
+ body = JSON.parse(text);
80
+ }
81
+ catch (_b) {
82
+ body = { raw: text };
83
+ }
84
+ if (!response.ok) {
85
+ res.send({
86
+ ok: false,
87
+ status: response.status,
88
+ error: (_a = body === null || body === void 0 ? void 0 : body.error) !== null && _a !== void 0 ? _a : response.statusText,
89
+ });
90
+ return;
91
+ }
92
+ // /schemas returns { results: [ {className, fields, ...}, ... ] }.
93
+ const schema = Array.isArray(body === null || body === void 0 ? void 0 : body.results) ? body.results : body;
94
+ res.send({ ok: true, schema });
95
+ }
96
+ catch (error) {
97
+ res.send({ ok: false, error: String(error) });
98
+ }
99
+ });
100
+ };
101
+ module.exports = nodeInit;
102
+ //# sourceMappingURL=openinc-parse-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openinc-parse-config.js","sourceRoot":"","sources":["../../../src/nodes/openinc-parse-config/openinc-parse-config.ts"],"names":[],"mappings":";AAKA,mDAAmD;AAEnD,MAAM,QAAQ,GAAoB,CAAC,GAAG,EAAQ,EAAE;IAC9C,SAAS,iCAAiC,CAExC,MAAiC;QAEjC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAA,wBAAY,EAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,GAAG,CAAC,KAAK,CAAC,YAAY,CACpB,sBAAsB,EACtB,iCAAiC,EACjC;QACE,WAAW,EAAE;YACX,UAAU,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;YAChC,aAAa,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;YACnC,SAAS,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;YAC/B,YAAY,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;SACnC;KACF,CACF,CAAC;IAEF,qEAAqE;IACrE,sEAAsE;IACtE,GAAG,CAAC,SAAS,CAAC,GAAG,CACf,gCAAgC,EAChC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,EACtC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACjB,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACxE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QACD,MAAM,GAAG,GACP,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC;YACrE,SAAS,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,wBAAwB,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE;aAC1D,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,8EAA8E;IAC9E,8EAA8E;IAC9E,8EAA8E;IAC9E,wEAAwE;IACxE,GAAG,CAAC,SAAS,CAAC,GAAG,CACf,uBAAuB,EACvB,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,EACtC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;;QACjB,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACxE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5C,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,IAAI,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAE5B,CAAC;YACd,SAAS,GAAG,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,KAAI,EAAE,CAAC;QACrC,CAAC;QACD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QACD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,GAAG;iBACA,MAAM,CAAC,GAAG,CAAC;iBACX,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GACR,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC;YACrE,UAAU,CAAC;QACb,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE;gBACjC,OAAO,EAAE;oBACP,wBAAwB,EAAE,KAAK;oBAC/B,oBAAoB,EAAE,SAAS;iBAChC;aACF,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,IAAS,CAAC;YACd,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;YAAC,WAAM,CAAC;gBACP,IAAI,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;YACvB,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,GAAG,CAAC,IAAI,CAAC;oBACP,EAAE,EAAE,KAAK;oBACT,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,KAAK,EAAE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,mCAAI,QAAQ,CAAC,UAAU;iBAC1C,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,mEAAmE;YACnE,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;YAClE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AAEF,iBAAS,QAAQ,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/nodes/openinc-parse-config/shared/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/nodes/openinc-parse-delete/modules/types.ts"],"names":[],"mappings":""}