@5minds/node-red-contrib-processcube-tools 1.1.0-develop-083e62-mfz95lr2 → 1.1.0-feature-975857-mg4vqpai

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,959 @@
1
+ <!--
2
+ Copyright 2015 IBM Corp.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ -->
16
+
17
+ <script type="text/x-red" data-template-name="swagger-doc">
18
+ <div class="form-row">
19
+ <label><span data-i18n="swagger.label.path"></span></label>
20
+ <span id="node-config-input-method"></span>
21
+ <span id="node-config-input-path"></span>
22
+ </div>
23
+
24
+ <div class="form-row">
25
+ <ul style="background: #fff; min-width: 600px; margin-bottom: 20px;" id="node-config-swagger-tabs"></ul>
26
+ </div>
27
+
28
+ <div id="node-config-swagger-tabs-content" style="min-height: 350px">
29
+ <div id="swagger-tab-info">
30
+ <div class="form-row">
31
+ <label id="node-config-input-summary-label" for="node-config-input-summary" class="popover-right" data-i18n="[data-content]swagger.data-content.summary"><span data-i18n="swagger.label.summary"></span></label>
32
+ <input type="text" id="node-config-input-summary">
33
+ </div>
34
+ <div class="form-row">
35
+ <label id="node-config-input-description-label" for="node-config-input-description" class="popover-right" data-i18n="[data-content]swagger.data-content.description"><span data-i18n="swagger.label.description"></span></label>
36
+ <input type="text" id="node-config-input-description">
37
+ </div>
38
+ <div class="form-row">
39
+ <label id="node-config-input-tags-label" for="node-config-input-tags" class="popover-right" data-i18n="[data-content]swagger.data-content.tags"><span data-i18n="swagger.label.tags"></span></label>
40
+ <input type="text" id="node-config-input-tags" data-i18n="[placeholder]swagger.placeholder.tags">
41
+ </div>
42
+ <div class="form-row">
43
+ <input type="checkbox" id="node-config-input-deprecated" style="width: auto; vertical-align: top;"> <label id="node-config-input-deprecated-label" for="node-config-input-deprecated" class="popover-right" data-i18n="[data-content]swagger.data-content.deprecated"><span data-i18n="swagger.label.deprecated"></span></label>
44
+ </div>
45
+ </div>
46
+ <div id="swagger-tab-parameters">
47
+ <div class="form-row" style="box-sizing: border-box; border-radius: 5px; height: 310px; padding: 5px; border: 1px solid #ccc; overflow-y:scroll;">
48
+ <ul id="node-config-parameter-list" style="padding: 0; margin:0;"></ul>
49
+ </div>
50
+ <div class="form-row">
51
+ <a href="#" class="red-ui-button red-ui-button-small" id="node-config-input-add-parameter"><i class="fa fa-plus"></i> <span data-i18n="swagger.label.parameter"></span></a>
52
+ <a href="#" id="node-config-input-parameter-info" class="popover-closable" style="font-size: 10px; text-decoration: underline; float: right"><span data-i18n="swagger.label.parameters-help"></span></a>
53
+ </div>
54
+ </div>
55
+ <div id="swagger-tab-responses">
56
+ <div class="form-row" style="box-sizing: border-box; border-radius: 5px; height: 310px; padding: 5px; border: 1px solid #ccc; overflow-y:scroll;">
57
+ <ul id="node-config-response-list" style="padding: 0; margin:0;"></ul>
58
+ </div>
59
+ <div class="form-row">
60
+ <a href="#" class="red-ui-button red-ui-button-small" id="node-config-input-add-response"><i class="fa fa-plus"></i> <span data-i18n="swagger.label.response"></span></a>
61
+ <a href="#" id="node-config-input-response-info" class="popover-closable" style="font-size: 10px; text-decoration: underline; float: right"><span data-i18n="swagger.label.responses-help"></span></a>
62
+ </div>
63
+ </div>
64
+ <div id="swagger-tab-requestBody">
65
+ <div class="form-row">
66
+ <label for="node-config-input-requestBody-contentType"><span>Content Type</span></label>
67
+ <input type="text" id="node-config-input-requestBody-contentType" value="application/json" style="width: 100%;">
68
+ </div>
69
+ <div class="form-row">
70
+ <label for="node-config-input-requestBody-json"><span>Schema/Example</span></label>
71
+ <div style="margin-bottom: 5px;">
72
+ <small>For JSON: provide JSON schema. For other types: provide example content.</small>
73
+ </div>
74
+ <textarea id="node-config-input-requestBody-json" style="width:100%; height: 200px;" placeholder='For JSON schema: {"type": "object", "properties": {...}}&#10;For XML example: &lt;root&gt;&lt;element&gt;value&lt;/element&gt;&lt;/root&gt;'></textarea>
75
+ </div>
76
+ </div>
77
+ </div>
78
+
79
+ </div>
80
+ </script>
81
+
82
+ <script type="text/x-red" data-help-name="swagger-doc">
83
+ <p>Describes an HTTP API using Swagger.</p>
84
+ </script>
85
+
86
+ <script type="text/javascript">
87
+ var swaggerDocUrl;
88
+ (function () {
89
+ function decodeHtmlEntities(str) {
90
+ if (typeof str !== 'string') return str;
91
+ return str
92
+ .replace(/&quot;/g, '"')
93
+ .replace(/&#39;/g, "'")
94
+ .replace(/&lt;/g, '<')
95
+ .replace(/&gt;/g, '>')
96
+ .replace(/&amp;/g, '&');
97
+ }
98
+
99
+ function createPropertyRow(opts) {
100
+ var row = $('<div/>', {
101
+ class: 'node-swagger-property-name-row',
102
+ style: 'margin-top: 3px; margin-left: 10px;',
103
+ });
104
+ $('<label/>', {
105
+ class: 'node-swagger-prop-name-label',
106
+ style: 'width: auto; margin-right: 10px;',
107
+ })
108
+ .text('Name')
109
+ .appendTo(row);
110
+ $('<input/>', {
111
+ class: 'node-swagger-type-name',
112
+ style: 'width: 150px;',
113
+ type: 'text',
114
+ })
115
+ .val(opts.name)
116
+ .appendTo(row);
117
+ var remove = $('<a/>', {
118
+ href: '#',
119
+ class: 'red-ui-button red-ui-button-small',
120
+ style: 'float: right; margin-right: 5px; margin-top: 3px;',
121
+ }).appendTo(row);
122
+ $('<i/>', { class: 'fa fa-remove' }).appendTo(remove);
123
+ remove.click(function (e) {
124
+ row.slideUp(100, function () {
125
+ row.remove();
126
+ });
127
+ e.preventDefault();
128
+ });
129
+ var propList = $('<div/>', {
130
+ class: 'node-swagger-property-row',
131
+ style: 'margin-top: 3px; margin-left: 10px;',
132
+ });
133
+ propList.appendTo(row);
134
+ opts.propertyRow = true;
135
+ createTypeRow(opts, true).appendTo(propList);
136
+ return row;
137
+ }
138
+
139
+ function createTypeRow(opts, top) {
140
+ var row = $('<div/>');
141
+ row.addClass('node-swagger-type-row');
142
+ row.css('margin-top', '3px');
143
+ if (top) {
144
+ row.addClass('node-swagger-type-top-row');
145
+ } else {
146
+ row.css('margin-left', '10px');
147
+ }
148
+
149
+ var typeLabel = $('<label/>').text('Type').appendTo(row);
150
+ var typeSelect = $('<select/>', {
151
+ class: 'node-swagger-type-select',
152
+ style: 'max-width: 150px',
153
+ }).appendTo(row);
154
+
155
+ var typeOptions = ['string', 'number', 'integer', 'boolean', 'array'];
156
+ typeOptions.forEach(function (opt) {
157
+ typeSelect.append($('<option/>').val(opt).text(opt));
158
+ });
159
+ typeSelect.val(opts.type);
160
+
161
+ $('<label/>', {
162
+ class: 'node-swagger-type-format-label',
163
+ style: 'width: auto; margin-left:20px; margin-right: 10px;',
164
+ })
165
+ .text('Format')
166
+ .appendTo(row);
167
+ $('<input/>', {
168
+ class: 'node-swagger-type-format',
169
+ style: 'width: 150px;',
170
+ type: 'text',
171
+ })
172
+ .val(opts.format)
173
+ .appendTo(row);
174
+
175
+ if (!opts.propertyRow) {
176
+ var collFormatSelect = $('<select/>', {
177
+ class: 'node-swagger-type-collection-format',
178
+ style: 'width: 150px;',
179
+ type: 'text',
180
+ }).appendTo(row);
181
+ ['csv', 'ssv', 'tsv', 'pipes', 'multi'].forEach(function (opt) {
182
+ collFormatSelect.append($('<option/>').val(opt).text(opt));
183
+ });
184
+ collFormatSelect.val(opts.collectionFormat || 'csv');
185
+ }
186
+
187
+ typeSelect.change(function () {
188
+ var t = $(this).val();
189
+ if (t != 'array') {
190
+ $(this).parent().find('.node-swagger-type-row').remove();
191
+ $(this).parent().find('.node-swagger-type-format').show();
192
+ $(this).parent().find('.node-swagger-type-format-label').text('Format');
193
+ $(this).parent().find('.node-swagger-type-collection-format').hide();
194
+ } else {
195
+ $(this).parent().find('.node-swagger-type-format').hide();
196
+ $(this).parent().find('.node-swagger-type-collection-format').show();
197
+ if (opts.propertyRow) {
198
+ $(this).parent().find('.node-swagger-type-format-label').text('');
199
+ if (!opts.items) {
200
+ opts.items = {};
201
+ }
202
+ opts.items.propertyRow = true;
203
+ }
204
+ createTypeRow(opts.items || {}, false).appendTo($(this).parent());
205
+ }
206
+ });
207
+ typeSelect.change();
208
+
209
+ return row;
210
+ }
211
+
212
+ function createParameterLine(opts, expand) {
213
+ var li = $('<li/>', {
214
+ style: 'background: #fff; margin:4px 0; border: 1px solid #ccc;',
215
+ }).appendTo('#node-config-parameter-list');
216
+
217
+ var row1 = $('<div/>', {
218
+ style: 'background:#f3f3f3; padding: 5px;',
219
+ }).appendTo(li);
220
+ var remove = $('<a/>', {
221
+ href: '#',
222
+ class: 'red-ui-button red-ui-button-small',
223
+ style: 'float: right; margin-right: 5px; margin-top: 3px;',
224
+ }).appendTo(row1);
225
+ $('<i/>', { class: 'fa fa-remove' }).appendTo(remove);
226
+ remove.click(function (e) {
227
+ li.slideUp(100, function () {
228
+ li.remove();
229
+ });
230
+ e.preventDefault();
231
+ });
232
+
233
+ var expanderSpan = $('<span/>', {
234
+ style: 'display:inline-block; width: 20px; margin-right:10px;',
235
+ }).appendTo(row1);
236
+ var expander = $('<a/>', {
237
+ href: '#',
238
+ style: 'text-align: center; display: inline-block; 5px; width: 20px; height: 30px; line-height: 30px;',
239
+ }).appendTo(expanderSpan);
240
+ var expanderIcon = $('<i/>', {
241
+ class: 'fa fa-chevron-right',
242
+ style: 'width: 15px; text-align:centre;',
243
+ }).appendTo(expander);
244
+
245
+ var showDetails = function () {
246
+ expanderIcon.removeClass('fa-chevron-right');
247
+ expanderIcon.addClass('fa-chevron-down');
248
+ nameRows.slideDown(200);
249
+ };
250
+ var hideDetails = function () {
251
+ expanderIcon.removeClass('fa-chevron-down');
252
+ expanderIcon.addClass('fa-chevron-right');
253
+ nameRows.slideUp(200);
254
+ };
255
+
256
+ expander.click(function (e) {
257
+ var icn = $(this).children('.fa');
258
+ if (icn.hasClass('fa-chevron-right')) {
259
+ showDetails();
260
+ } else {
261
+ hideDetails();
262
+ }
263
+ e.preventDefault();
264
+ });
265
+
266
+ var parameterSelect = $('<select/>', {
267
+ class: 'node-swagger-name-select',
268
+ style: 'max-width: 90px; margin-right: 10px;',
269
+ }).appendTo(row1);
270
+ parameterSelect.append($('<option/>').val('name').text('Name'));
271
+
272
+ parameterSelect.change(function () {
273
+ var p = $(this).val();
274
+ if (p == 'name') {
275
+ expander.show();
276
+ $(this).parent().children('.node-swagger-in-form').show();
277
+ $(this).parent().find('.node-swagger-name').css({ maxWidth: '150px' });
278
+ showDetails();
279
+ } else {
280
+ expander.hide();
281
+ $(this).parent().children('.node-swagger-in-form').hide();
282
+ $(this).parent().find('.node-swagger-name').css({ maxWidth: '300px' });
283
+ hideDetails();
284
+ }
285
+ });
286
+
287
+ var parameterName = $('<input/>', {
288
+ style: 'max-width: 150px',
289
+ type: 'text',
290
+ class: 'node-swagger-name',
291
+ }).appendTo(row1);
292
+
293
+ parameterSelect.val('name');
294
+ parameterName.val(opts.name);
295
+
296
+ var inSpan = $('<span/>', {
297
+ class: 'node-swagger-in-form',
298
+ }).appendTo(row1);
299
+ $('<label/>', {
300
+ style: 'width: auto; margin-left:10px; margin-right: 10px;',
301
+ })
302
+ .text('In')
303
+ .appendTo(inSpan);
304
+ var inSelect = $('<select/>', {
305
+ class: 'node-swagger-in-select',
306
+ style: 'max-width: 150px',
307
+ }).appendTo(inSpan);
308
+ ['query', 'header'].forEach(function (opt) {
309
+ inSelect.append($('<option></option>').val(opt).text(opt));
310
+ });
311
+ inSelect.val(opts.in);
312
+
313
+ var nameRows = $('<div/>', {
314
+ class: 'node-swagger-name-row',
315
+ style: 'padding: 15px;',
316
+ })
317
+ .appendTo(li)
318
+ .hide();
319
+
320
+ var row2 = $('<div/>', {
321
+ class: 'form-row node-swagger-name-row',
322
+ }).appendTo(nameRows);
323
+ $('<label/>').text('Description').appendTo(row2);
324
+ $('<input/>', {
325
+ type: 'text',
326
+ class: 'node-swagger-description',
327
+ style: 'max-width: 300px',
328
+ })
329
+ .val(opts.description)
330
+ .appendTo(row2);
331
+ var required = $('<input/>', {
332
+ type: 'checkbox',
333
+ class: 'node-swagger-required',
334
+ style: 'width: auto; float: right; margin-left: 10px; vertical-align: middle',
335
+ }).appendTo(row2);
336
+ $('<label/>', {
337
+ style: 'width: auto; float: right; margin-left:20px; vertical-align: middle',
338
+ })
339
+ .text('Required')
340
+ .appendTo(row2);
341
+ required.prop('checked', opts.required);
342
+
343
+ var row3 = createTypeRow(opts, true).appendTo(nameRows);
344
+
345
+ var rowPropHeader = $('<div/>', {
346
+ class: 'form-row node-swagger-propHeader-row',
347
+ }).appendTo(nameRows);
348
+ $('<label/>', {
349
+ class: 'node-swagger-propHeader-label',
350
+ style: 'width: auto; font-weight: bold; margin-right: 10px',
351
+ })
352
+ .text('Properties')
353
+ .appendTo(rowPropHeader);
354
+ var addPropButton = $(
355
+ '<a href=#" class="red-ui-button red-ui-button-small" id="node-config-input-add-property"><i class="fa fa-plus"></i> Property</a>',
356
+ ).appendTo(rowPropHeader);
357
+
358
+ var rowPropList = $('<div/>', {
359
+ class: 'form-row node-swagger-prop-list',
360
+ style: 'margin-left:10px',
361
+ }).appendTo(rowPropHeader);
362
+
363
+ addPropButton.click(function (e) {
364
+ createPropertyRow({}).appendTo(rowPropList);
365
+ var scrollContainer = $('#node-config-parameter-list').parent();
366
+ scrollContainer.scrollTop(scrollContainer.prop('scrollHeight'));
367
+ e.preventDefault();
368
+ });
369
+ if (opts.schema && opts.schema.properties) {
370
+ var props = opts.schema.properties;
371
+ for (var prop in props) {
372
+ var propOpt = opts.schema.properties[prop];
373
+ propOpt.name = prop;
374
+ createPropertyRow(propOpt).appendTo(rowPropList);
375
+ }
376
+ }
377
+
378
+ inSelect.change(function () {
379
+ var i = $(this).val();
380
+ var schemaRow = $(this)
381
+ .parent()
382
+ .parent()
383
+ .parent()
384
+ .children('.node-swagger-name-row')
385
+ .children('.node-swagger-propHeader-row');
386
+ var typeRow = $(this)
387
+ .parent()
388
+ .parent()
389
+ .parent()
390
+ .children('.node-swagger-name-row')
391
+ .children('.node-swagger-type-row');
392
+ if (i == 'body') {
393
+ schemaRow.show();
394
+ typeRow.hide();
395
+ } else {
396
+ if (i == 'formData') {
397
+ if (
398
+ typeRow.children('.node-swagger-type-select').children("option[value='file']").length == 0
399
+ ) {
400
+ $('<option/>')
401
+ .val('file')
402
+ .text('file')
403
+ .appendTo(typeRow.children('.node-swagger-type-select'));
404
+ }
405
+ } else {
406
+ typeRow.children('.node-swagger-type-select').children("option[value='file']").remove();
407
+ }
408
+ schemaRow.hide();
409
+ typeRow.show();
410
+ }
411
+ });
412
+
413
+ inSelect.change();
414
+ parameterSelect.change();
415
+ if (!expand) {
416
+ hideDetails();
417
+ }
418
+ }
419
+
420
+ function createResponseLine(opts, expand) {
421
+ var li = $('<li/>', {
422
+ style: 'background: #fff; margin:4px 0; border: 1px solid #ccc;',
423
+ }).appendTo('#node-config-response-list');
424
+
425
+ var row1 = $('<div/>', {
426
+ style: 'background:#f3f3f3; padding: 5px;',
427
+ }).appendTo(li);
428
+ var remove = $('<a/>', {
429
+ href: '#',
430
+ class: 'red-ui-button red-ui-button-small',
431
+ style: 'float: right; margin-right: 5px; margin-top: 3px;',
432
+ }).appendTo(row1);
433
+ $('<i/>', { class: 'fa fa-remove' }).appendTo(remove);
434
+ remove.click(function (e) {
435
+ li.slideUp(100, function () {
436
+ li.remove();
437
+ });
438
+ e.preventDefault();
439
+ });
440
+
441
+ var expanderSpan = $('<span/>', {
442
+ style: 'display:inline-block; width: 20px; margin-right:10px;',
443
+ }).appendTo(row1);
444
+ var expander = $('<a/>', {
445
+ href: '#',
446
+ style: 'text-align: center; display: inline-block; 5px; width: 20px; height: 30px; line-height: 30px;',
447
+ }).appendTo(expanderSpan);
448
+ var expanderIcon = $('<i/>', {
449
+ class: 'fa fa-chevron-right',
450
+ style: 'width: 15px; text-align:centre;',
451
+ }).appendTo(expander);
452
+
453
+ var showDetails = function () {
454
+ expanderIcon.removeClass('fa-chevron-right');
455
+ expanderIcon.addClass('fa-chevron-down');
456
+ nameRows.slideDown(200);
457
+ };
458
+ var hideDetails = function () {
459
+ expanderIcon.removeClass('fa-chevron-down');
460
+ expanderIcon.addClass('fa-chevron-right');
461
+ nameRows.slideUp(200);
462
+ };
463
+
464
+ expander.click(function (e) {
465
+ var icn = $(this).children('.fa');
466
+ if (icn.hasClass('fa-chevron-right')) {
467
+ showDetails();
468
+ } else {
469
+ hideDetails();
470
+ }
471
+ e.preventDefault();
472
+ });
473
+
474
+ var responseSelect = $('<select/>', {
475
+ class: 'node-swagger-name-select',
476
+ style: 'max-width: 90px; margin-right: 10px;',
477
+ }).appendTo(row1);
478
+ responseSelect.append($('<option/>').val('code').text('Code'));
479
+ responseSelect.append($('<option/>').val('default').text('Default'));
480
+ responseSelect.change(function () {
481
+ var p = $(this).val();
482
+ if (p == 'code') {
483
+ expander.show();
484
+ $(this).parent().children('.node-swagger-respCode').show();
485
+ showDetails();
486
+ } else {
487
+ expander.show();
488
+ $(this).parent().children('.node-swagger-respCode').hide();
489
+ showDetails();
490
+ }
491
+ });
492
+
493
+ var responseRespCode = $('<input/>', {
494
+ style: 'max-width: 150px',
495
+ type: 'text',
496
+ class: 'node-swagger-respCode',
497
+ }).appendTo(row1);
498
+
499
+ if (opts.code == 'default') {
500
+ responseSelect.val('default');
501
+ } else {
502
+ responseSelect.val('code');
503
+ responseRespCode.val(opts.code);
504
+ }
505
+
506
+ var nameRows = $('<div/>', {
507
+ class: 'node-swagger-name-row',
508
+ style: 'padding: 15px;',
509
+ })
510
+ .appendTo(li)
511
+ .hide();
512
+
513
+ var row2 = $('<div/>', {
514
+ class: 'form-row node-swagger-description-row',
515
+ }).appendTo(nameRows);
516
+ $('<label/>').text('Description').appendTo(row2);
517
+ $('<input/>', {
518
+ type: 'text',
519
+ class: 'node-swagger-description',
520
+ })
521
+ .val(opts.description)
522
+ .appendTo(row2);
523
+
524
+ var rowPropHeader = $('<div/>', {
525
+ class: 'form-row node-swagger-propHeader-row',
526
+ }).appendTo(nameRows);
527
+ $('<label/>', {
528
+ class: 'node-swagger-propHeader-label',
529
+ style: 'width: auto; font-weight: bold; margin-right: 10px',
530
+ })
531
+ .text('Properties')
532
+ .appendTo(rowPropHeader);
533
+ var addPropButton = $(
534
+ '<a href=#" class="red-ui-button red-ui-button-small" id="node-config-input-add-property"><i class="fa fa-plus"></i> Property</a>',
535
+ ).appendTo(rowPropHeader);
536
+
537
+ var rowPropList = $('<div/>', {
538
+ class: 'form-row node-swagger-prop-list',
539
+ style: 'margin-left:10px',
540
+ }).appendTo(rowPropHeader);
541
+
542
+ if (opts.schema && opts.schema.properties) {
543
+ var props = opts.schema.properties;
544
+ for (var prop in props) {
545
+ var propOpt = opts.schema.properties[prop];
546
+ propOpt.name = prop;
547
+ createPropertyRow(propOpt).appendTo(rowPropList);
548
+ }
549
+ }
550
+
551
+ addPropButton.click(function (e) {
552
+ createPropertyRow({}).appendTo(rowPropList);
553
+ var scrollContainer = $('#node-config-parameter-list').parent();
554
+ scrollContainer.scrollTop(scrollContainer.prop('scrollHeight'));
555
+ e.preventDefault();
556
+ });
557
+
558
+ responseSelect.change();
559
+ if (!expand) {
560
+ hideDetails();
561
+ }
562
+ }
563
+
564
+ function initializeUI(node) {
565
+ var tabs = RED.tabs.create({
566
+ id: 'node-config-swagger-tabs',
567
+ onchange: function (tab) {
568
+ $('#node-config-swagger-tabs-content').children().hide();
569
+ $('#' + tab.id).show();
570
+ },
571
+ });
572
+
573
+ tabs.addTab({ id: 'swagger-tab-info', label: 'Info' });
574
+ tabs.addTab({ id: 'swagger-tab-parameters', label: 'Parameters' });
575
+ tabs.addTab({ id: 'swagger-tab-responses', label: 'Responses' });
576
+ tabs.addTab({ id: 'swagger-tab-requestBody', label: 'Request Body' });
577
+
578
+ setTimeout(function () {
579
+ tabs.resize();
580
+ }, 10);
581
+ }
582
+
583
+ function getArrayItems(row) {
584
+ var items = {};
585
+ var ctype = row.children('.node-swagger-type-select').val();
586
+ if (ctype) {
587
+ if (ctype != 'ref') {
588
+ items.type = ctype;
589
+ if (items.type == 'array') {
590
+ var collFormat = row.children('.node-swagger-type-collection-format').val();
591
+ if (collFormat) items.collectionFormat = collFormat;
592
+ var nextRow = row.children('.node-swagger-type-row');
593
+ items.items = getArrayItems(nextRow);
594
+ } else {
595
+ var format = row.children('.node-swagger-type-format').val();
596
+ if (format) items.format = format;
597
+ }
598
+ } else {
599
+ items['$ref'] = row.children('.node-swagger-type-format').val();
600
+ }
601
+ }
602
+ return items;
603
+ }
604
+
605
+ RED.nodes.registerType('swagger-doc', {
606
+ category: 'config',
607
+ exclusive: true,
608
+ defaults: {
609
+ summary: { value: '' },
610
+ description: { value: '' },
611
+ tags: { value: '' },
612
+ parameters: { value: [] },
613
+ responses: { value: null },
614
+ requestBody: { value: null },
615
+ deprecated: { value: false },
616
+ },
617
+ label: function () {
618
+ return this.summary || 'swagger doc';
619
+ },
620
+ onpaletteadd: function () {
621
+ var content = $('<div/>', {
622
+ id: 'tab-swagger-ui',
623
+ style: 'position: relative; padding: 20px; height: 100%; overflow: hidden; text-align: center;'
624
+ });
625
+
626
+ var openButton = $('<button/>', {
627
+ id: 'open-swagger-button',
628
+ class: 'red-ui-button',
629
+ style: 'padding: 12px 24px; font-size: 16px; margin-top: 50px; text-align: center; display: inline-block; line-height: 1;',
630
+ text: 'Open Swagger UI'
631
+ });
632
+
633
+ openButton.click(function() {
634
+ var swaggerUrl = window.location.protocol + '//' +
635
+ window.location.hostname + ':' +
636
+ window.location.port +
637
+ RED.settings.httpNodeRoot +
638
+ 'swagger-ui/swagger-ui.html';
639
+ window.open(swaggerUrl, '_blank');
640
+ });
641
+
642
+ openButton.appendTo(content);
643
+
644
+ RED.sidebar.addTab({
645
+ id: 'swagger-ui',
646
+ label: this._('swagger.sidebar.label'),
647
+ name: this._('swagger.sidebar.name'),
648
+ content: content,
649
+ iconClass: 'fa fa-scribd'
650
+ });
651
+ },
652
+ oneditprepare: function () {
653
+ var node = this;
654
+
655
+ if ($('#node-input-method').length) {
656
+ $('#node-config-input-method').text($('#node-input-method').val().toUpperCase());
657
+ $('#node-config-input-path').html($('#node-input-url').val());
658
+ } else {
659
+ var httpNodes = RED.nodes.filterNodes({ type: 'http in' });
660
+ for (var i = 0; i < httpNodes.length; i++) {
661
+ if (httpNodes[i].swaggerDoc === node.id) {
662
+ $('#node-config-input-method').text(httpNodes[i].method.toUpperCase());
663
+ $('#node-config-input-path').html(httpNodes[i].url);
664
+ break;
665
+ }
666
+ }
667
+ }
668
+
669
+ initializeUI(node);
670
+
671
+ $('#node-config-input-add-parameter').click(function (e) {
672
+ createParameterLine({}, true);
673
+ var scrollContainer = $('#node-config-parameter-list').parent();
674
+ scrollContainer.scrollTop(scrollContainer.prop('scrollHeight'));
675
+ e.preventDefault();
676
+ });
677
+
678
+ $('#node-config-input-add-response').click(function (e) {
679
+ createResponseLine({}, true);
680
+ var scrollContainer = $('#node-config-response-list').parent();
681
+ scrollContainer.scrollTop(scrollContainer.prop('scrollHeight'));
682
+ e.preventDefault();
683
+ });
684
+
685
+ if (node.parameters && node.parameters.length > 0) {
686
+ node.parameters.forEach(function (p) {
687
+ createParameterLine(p, false);
688
+ });
689
+ }
690
+
691
+ if (node.responses) {
692
+ for (var code in node.responses) {
693
+ var response = node.responses[code];
694
+ response.code = code;
695
+ createResponseLine(response, false);
696
+ }
697
+ }
698
+
699
+ if (node.requestBody) {
700
+ var contentType = Object.keys(node.requestBody.content)[0];
701
+ if (contentType) {
702
+ $('#node-config-input-requestBody-contentType').val(contentType);
703
+
704
+ var contentObj = node.requestBody.content[contentType];
705
+
706
+ var isXmlContentType =
707
+ contentType === 'application/xml' ||
708
+ contentType === 'text/xml' ||
709
+ contentType.includes('xml');
710
+
711
+ if (contentObj.example) {
712
+ var exampleContent = contentObj.example;
713
+
714
+ if (isXmlContentType) {
715
+ exampleContent = decodeHtmlEntities(exampleContent);
716
+ }
717
+
718
+ $('#node-config-input-requestBody-json').val(exampleContent);
719
+ } else if (contentObj.schema) {
720
+ if (isXmlContentType) {
721
+ if (typeof contentObj.schema === 'object') {
722
+ $('#node-config-input-requestBody-json').val(
723
+ JSON.stringify(contentObj.schema, null, 2),
724
+ );
725
+ } else {
726
+ $('#node-config-input-requestBody-json').val(decodeHtmlEntities(contentObj.schema));
727
+ }
728
+ } else {
729
+ if (typeof contentObj.schema === 'object') {
730
+ $('#node-config-input-requestBody-json').val(
731
+ JSON.stringify(contentObj.schema, null, 2),
732
+ );
733
+ } else {
734
+ $('#node-config-input-requestBody-json').val(contentObj.schema);
735
+ }
736
+ }
737
+ }
738
+ }
739
+ }
740
+ },
741
+
742
+ oneditsave: function () {
743
+ var node = this;
744
+
745
+ var params = [];
746
+ $('#node-config-parameter-list li').each(function () {
747
+ var param = {};
748
+ var nameType = $(this).find('.node-swagger-name-select').val();
749
+ var name = $(this).find('.node-swagger-name').val();
750
+ if (nameType == 'ref') {
751
+ param['$ref'] = name;
752
+ } else {
753
+ param.name = name;
754
+ param.in = $(this).find('.node-swagger-in-select').val();
755
+ var desc = $(this).find('.node-swagger-description').val();
756
+ if (desc) {
757
+ param.description = desc;
758
+ }
759
+ param.required = $(this).find('.node-swagger-required').is(':checked');
760
+ if (param.in == 'body') {
761
+ var properties = {};
762
+ $(this)
763
+ .find('.node-swagger-prop-list')
764
+ .children('.node-swagger-property-name-row')
765
+ .each(function () {
766
+ var property = {};
767
+ var name = $(this).find('.node-swagger-type-name').val();
768
+
769
+ var row = $(this).find('.node-swagger-type-top-row');
770
+
771
+ var current = property;
772
+ var ctype = row.children('.node-swagger-type-select').val();
773
+
774
+ if (ctype) {
775
+ if (ctype != 'ref') {
776
+ current.type = ctype;
777
+ if (current.type == 'array') {
778
+ var collFormat = row
779
+ .children('.node-swagger-type-collection-format')
780
+ .val();
781
+ if (collFormat) current.collectionFormat = collFormat;
782
+ var nextRow = row.children('.node-swagger-type-row');
783
+ current.items = getArrayItems(nextRow);
784
+ } else {
785
+ var format = row.children('.node-swagger-type-format').val();
786
+ if (format) current.format = format;
787
+ }
788
+ } else {
789
+ current['$ref'] = row.children('.node-swagger-type-format').val();
790
+ }
791
+ }
792
+
793
+ properties[name] = property;
794
+ });
795
+ param.schema = {};
796
+ param.schema.type = 'object';
797
+ if (Object.keys(properties).length > 0) {
798
+ param.schema.properties = properties;
799
+ }
800
+ } else {
801
+ var row = $(this).find('.node-swagger-type-top-row');
802
+ var current = param;
803
+ var ctype = row.children('.node-swagger-type-select').val();
804
+ if (ctype) {
805
+ if (ctype != 'ref') {
806
+ current.type = ctype;
807
+ if (current.type == 'array') {
808
+ var collFormat = row.children('.node-swagger-type-collection-format').val();
809
+ current.collectionFormat = collFormat;
810
+ var nextRow = row.children('.node-swagger-type-row');
811
+ current.items = getArrayItems(nextRow);
812
+ } else {
813
+ var format = row.children('.node-swagger-type-format').val();
814
+ if (format) {
815
+ current.format = format;
816
+ }
817
+ }
818
+ } else {
819
+ current['$ref'] = row.children('.node-swagger-type-format').val();
820
+ }
821
+ }
822
+ }
823
+ }
824
+ params.push(param);
825
+ });
826
+ node.parameters = params;
827
+
828
+ var requestBodyDescription = $('#node-config-input-requestBody-description').val();
829
+ var requestBodyRequired = $('#node-config-input-requestBody-required').is(':checked');
830
+ var contentType = $('#node-config-input-requestBody-contentType').val();
831
+ var schemaContent = $('#node-config-input-requestBody-json').val();
832
+
833
+ if (requestBodyDescription || schemaContent) {
834
+ var requestBody = {
835
+ description: requestBodyDescription || 'Request body',
836
+ required: requestBodyRequired,
837
+ content: {},
838
+ };
839
+
840
+ if (contentType && schemaContent) {
841
+ var isXmlContentType =
842
+ contentType === 'application/xml' ||
843
+ contentType === 'text/xml' ||
844
+ contentType.includes('xml');
845
+
846
+ if (contentType === 'application/json') {
847
+ try {
848
+ var schema = JSON.parse(schemaContent);
849
+ requestBody.content[contentType] = {
850
+ schema: schema,
851
+ };
852
+ } catch (e) {
853
+ requestBody.content[contentType] = {
854
+ schema: {
855
+ type: 'string',
856
+ },
857
+ example: schemaContent,
858
+ };
859
+ }
860
+ } else if (isXmlContentType) {
861
+ console.log('Raw schemaContent:', JSON.stringify(schemaContent));
862
+
863
+ var processedContent = schemaContent.replace(/\\n/g, '\n');
864
+
865
+ console.log('Processed content:', JSON.stringify(processedContent));
866
+
867
+ requestBody.content['text/plain'] = {
868
+ schema: {
869
+ type: 'string'
870
+ },
871
+ example: processedContent
872
+ };
873
+ }
874
+ else {
875
+ try {
876
+ var schema = JSON.parse(schemaContent);
877
+ requestBody.content[contentType] = {
878
+ schema: schema,
879
+ };
880
+ } catch (e) {
881
+ requestBody.content[contentType] = {
882
+ schema: {
883
+ type: 'string',
884
+ },
885
+ example: schemaContent,
886
+ };
887
+ }
888
+ }
889
+ }
890
+
891
+ if (Object.keys(requestBody.content).length > 0) {
892
+ node.requestBody = requestBody;
893
+ } else {
894
+ delete node.requestBody;
895
+ }
896
+ } else {
897
+ delete node.requestBody;
898
+ }
899
+
900
+ var responses = {};
901
+ $('#node-config-response-list li').each(function () {
902
+ var response = {};
903
+ var respCode;
904
+ var nameType = $(this).find('.node-swagger-name-select').val();
905
+ if (nameType === 'default') {
906
+ respCode = 'default';
907
+ } else {
908
+ respCode = $(this).find('.node-swagger-respCode').val();
909
+ }
910
+ var desc = $(this).find('.node-swagger-description').val();
911
+ response.description = desc || '';
912
+ var properties = {};
913
+ $(this)
914
+ .find('.node-swagger-prop-list')
915
+ .children('.node-swagger-property-name-row')
916
+ .each(function () {
917
+ var property = {};
918
+ var name = $(this).find('.node-swagger-type-name').val();
919
+
920
+ var row = $(this).find('.node-swagger-type-top-row');
921
+
922
+ var current = property;
923
+ var ctype = row.children('.node-swagger-type-select').val();
924
+
925
+ if (ctype) {
926
+ if (ctype != 'ref') {
927
+ current.type = ctype;
928
+ if (current.type == 'array') {
929
+ var collFormat = row.children('.node-swagger-type-collection-format').val();
930
+ if (collFormat) current.collectionFormat = collFormat;
931
+ var nextRow = row.children('.node-swagger-type-row');
932
+ current.items = getArrayItems(nextRow);
933
+ } else {
934
+ var format = row.children('.node-swagger-type-format').val();
935
+ if (format) {
936
+ current.format = format;
937
+ }
938
+ }
939
+ } else {
940
+ current['$ref'] = row.children('.node-swagger-type-format').val();
941
+ }
942
+ }
943
+
944
+ properties[name] = property;
945
+ });
946
+
947
+ if (Object.keys(properties).length > 0) {
948
+ response.schema = {
949
+ properties: properties,
950
+ };
951
+ }
952
+
953
+ responses[respCode] = response;
954
+ });
955
+ node.responses = responses;
956
+ },
957
+ });
958
+ })();
959
+ </script>