iobroker.javascript 7.10.2 → 7.11.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.
package/README.md CHANGED
@@ -42,6 +42,21 @@ Since v5.5.0 of the JavaScript adapter the following locations (relative to the
42
42
  <!--
43
43
  ### **WORK IN PROGRESS**
44
44
  -->
45
+ ### 7.11.1 (2024-03-28)
46
+
47
+ * (klein0r) Added exec result blockly block
48
+ * (klein0r) Protect iobroker-data/files to avoid direct writes with node:fs
49
+ * (klein0r) Escape single quotes in blockly obj attributes
50
+
51
+ ### 7.11.0 (2024-03-26)
52
+
53
+ * (klein0r) Added blockly block for read and write file
54
+ * (klein0r) Allow to select other object types than state in some blocks
55
+ * (klein0r) Improved translations
56
+ * (klein0r) Removed 'type' from dropdown (is always 'state')
57
+ * (klein0r) Use highlight in search (instead of select)
58
+ * (klein0r) Added option for httpGet to receive arraybuffer (download files)
59
+
45
60
  ### 7.10.2 (2024-03-25)
46
61
 
47
62
  * (klein0r) Fixed httpGet/httpPost issue when using without options
@@ -58,16 +73,6 @@ Since v5.5.0 of the JavaScript adapter the following locations (relative to the
58
73
  * (klein0r) Copy date object in getAstroDate
59
74
  * (klein0r) Added object id as tooltip
60
75
 
61
- ### 7.9.4 (2024-03-20)
62
-
63
- * (klein0r) Fixed urlencoding for basic auth in url (user:pass)
64
- * (klein0r) Added warning icon if trigger is positioned inside of another trigger or loop
65
-
66
- ### 7.9.3 (2024-03-19)
67
-
68
- * (klein0r) Added timeout option for http blocks
69
- * (klein0r) Added option for basic auth in url (user:pass)
70
-
71
76
  ## License
72
77
  The MIT License (MIT)
73
78
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "files": {
3
- "main.js": "/static/js/main.4caef13e.js",
3
+ "main.js": "/static/js/main.f0e610b0.js",
4
4
  "static/css/184.7463f8b6.chunk.css": "/static/css/184.7463f8b6.chunk.css",
5
- "static/js/184.23703866.chunk.js": "/static/js/184.23703866.chunk.js",
5
+ "static/js/184.985be7e8.chunk.js": "/static/js/184.985be7e8.chunk.js",
6
6
  "static/js/966.088c1225.chunk.js": "/static/js/966.088c1225.chunk.js",
7
7
  "static/js/30.8bf17a3b.chunk.js": "/static/js/30.8bf17a3b.chunk.js",
8
8
  "static/js/704.4ede9892.chunk.js": "/static/js/704.4ede9892.chunk.js",
@@ -160,9 +160,9 @@
160
160
  "static/media/Garage Doors.svg": "/static/media/Garage Doors.0c2a1cfca7ad1ea59625.svg",
161
161
  "static/media/Outdoor Blinds.svg": "/static/media/Outdoor Blinds.37b85a9c060a4af48da9.svg",
162
162
  "static/media/Upstairs.svg": "/static/media/Upstairs.441813e54e0daca0882d.svg",
163
- "main.4caef13e.js.map": "/static/js/main.4caef13e.js.map",
163
+ "main.f0e610b0.js.map": "/static/js/main.f0e610b0.js.map",
164
164
  "184.7463f8b6.chunk.css.map": "/static/css/184.7463f8b6.chunk.css.map",
165
- "184.23703866.chunk.js.map": "/static/js/184.23703866.chunk.js.map",
165
+ "184.985be7e8.chunk.js.map": "/static/js/184.985be7e8.chunk.js.map",
166
166
  "966.088c1225.chunk.js.map": "/static/js/966.088c1225.chunk.js.map",
167
167
  "30.8bf17a3b.chunk.js.map": "/static/js/30.8bf17a3b.chunk.js.map",
168
168
  "704.4ede9892.chunk.js.map": "/static/js/704.4ede9892.chunk.js.map",
@@ -195,6 +195,6 @@
195
195
  "77.f4bb7c45.chunk.js.map": "/static/js/77.f4bb7c45.chunk.js.map"
196
196
  },
197
197
  "entrypoints": [
198
- "static/js/main.4caef13e.js"
198
+ "static/js/main.f0e610b0.js"
199
199
  ]
200
200
  }
@@ -20,7 +20,7 @@ Blockly.Action.blocks['exec'] =
20
20
  '<block type="exec">'
21
21
  + ' <value name="COMMAND">'
22
22
  + ' <shadow type="text">'
23
- + ' <field name="TEXT">text</field>'
23
+ + ' <field name="TEXT">pwd</field>'
24
24
  + ' </shadow>'
25
25
  + ' </value>'
26
26
  + ' <value name="LOG">'
@@ -33,7 +33,7 @@ Blockly.Action.blocks['exec'] =
33
33
  Blockly.Blocks['exec'] = {
34
34
  init: function() {
35
35
  this.appendDummyInput('TEXT')
36
- .appendField(Blockly.Translate('exec'));
36
+ .appendField('» ' + Blockly.Translate('exec'));
37
37
 
38
38
  this.appendValueInput('COMMAND')
39
39
  .appendField(Blockly.Translate('exec_command'));
@@ -96,7 +96,7 @@ Blockly.JavaScript['exec'] = function(block) {
96
96
 
97
97
  let logText;
98
98
  if (logLevel) {
99
- logText = 'console.' + logLevel + '("exec: " + ' + value_command + ');\n'
99
+ logText = `console.${logLevel}('exec: ' + ${value_command});\n`;
100
100
  } else {
101
101
  logText = '';
102
102
  }
@@ -104,18 +104,83 @@ Blockly.JavaScript['exec'] = function(block) {
104
104
  if (withStatement === 'TRUE' || withStatement === 'true' || withStatement === true) {
105
105
  const statement = Blockly.JavaScript.statementToCode(block, 'STATEMENT');
106
106
  if (statement) {
107
- return 'exec(' + value_command + ', async (error, result, stderr) => {\n' + statement + '});\n' +
108
- logText;
107
+ return `exec(${value_command}, async (error, result, stderr) => {\n` +
108
+ statement +
109
+ `});\n${logText}`;
109
110
  } else {
110
- return 'exec(' + value_command + ');\n' +
111
- logText;
111
+ return `exec(${value_command});\n${logText}`;
112
112
  }
113
113
  } else {
114
- return 'exec(' + value_command + ');\n' +
115
- logText;
114
+ return `exec(${value_command});\n${logText}`;
116
115
  }
117
116
  };
118
117
 
118
+ // --- exec_result -----------------------------------------------------------
119
+ Blockly.Action.blocks['exec_result'] =
120
+ '<block type="exec_result">'
121
+ + ' <value name="ATTR">'
122
+ + ' </value>'
123
+ + '</block>';
124
+
125
+ Blockly.Blocks['exec_result'] = {
126
+ /**
127
+ * Block for conditionally returning a value from a procedure.
128
+ * @this Blockly.Block
129
+ */
130
+ init: function() {
131
+ this.appendDummyInput()
132
+ .appendField('»');
133
+
134
+ this.appendDummyInput('ATTR')
135
+ .appendField(new Blockly.FieldDropdown([
136
+ [Blockly.Translate('exec_result_result'), 'result'],
137
+ [Blockly.Translate('exec_result_stderr'), 'stderr'],
138
+ [Blockly.Translate('exec_result_error'), 'error'],
139
+ ]), 'ATTR');
140
+
141
+ this.setInputsInline(true);
142
+ this.setOutput(true);
143
+ this.setColour(Blockly.Action.HUE);
144
+ this.setTooltip(Blockly.Translate('exec_result_tooltip'));
145
+ //this.setHelpUrl(getHelp('exec'));
146
+ },
147
+ /**
148
+ * Called whenever anything on the workspace changes.
149
+ * Add warning if this flow block is not nested inside a loop.
150
+ * @param {!Blockly.Events.Abstract} e Change event.
151
+ * @this Blockly.Block
152
+ */
153
+ onchange: function(e) {
154
+ let legal = false;
155
+ // Is the block nested in an exec?
156
+ let block = this;
157
+ do {
158
+ if (this.FUNCTION_TYPES.includes(block.type)) {
159
+ legal = true;
160
+ break;
161
+ }
162
+ block = block.getSurroundParent();
163
+ } while (block);
164
+
165
+ if (legal) {
166
+ this.setWarningText(null, this.id);
167
+ } else {
168
+ this.setWarningText(Blockly.Translate('exec_result_warning'), this.id);
169
+ }
170
+ },
171
+ /**
172
+ * List of block types that are functions and thus do not need warnings.
173
+ * To add a new function type add this to your code:
174
+ * Blockly.Blocks['procedures_ifreturn'].FUNCTION_TYPES.push('custom_func');
175
+ */
176
+ FUNCTION_TYPES: ['exec'],
177
+ };
178
+ Blockly.JavaScript['exec_result'] = function(block) {
179
+ const attr = block.getFieldValue('ATTR');
180
+
181
+ return [attr, Blockly.JavaScript.ORDER_ATOMIC];
182
+ };
183
+
119
184
  // --- action http_get --------------------------------------------------
120
185
  Blockly.Action.blocks['http_get'] =
121
186
  '<block type="http_get">'
@@ -128,6 +193,8 @@ Blockly.Action.blocks['http_get'] =
128
193
  + ' </value>'
129
194
  + ' <value name="UNIT">'
130
195
  + ' </value>'
196
+ + ' <value name="TYPE">'
197
+ + ' </value>'
131
198
  + ' <value name="STATEMENT">'
132
199
  + ' </value>'
133
200
  + '</block>';
@@ -135,16 +202,23 @@ Blockly.Action.blocks['http_get'] =
135
202
  Blockly.Blocks['http_get'] = {
136
203
  init: function() {
137
204
  this.appendValueInput('URL')
138
- .appendField(Blockly.Translate('http_get'));
205
+ .appendField('🌐 ' + Blockly.Translate('http_get'));
139
206
 
140
207
  this.appendDummyInput()
141
- .appendField(Blockly.Translate('http_get_timeout'))
208
+ .appendField(Blockly.Translate('http_timeout'))
142
209
  .appendField(new Blockly.FieldTextInput(2000), 'TIMEOUT')
143
210
  .appendField(new Blockly.FieldDropdown([
144
- [Blockly.Translate('http_get_settimeout_ms'), 'ms'],
145
- [Blockly.Translate('http_get_settimeout_sec'), 'sec']
211
+ [Blockly.Translate('http_timeout_ms'), 'ms'],
212
+ [Blockly.Translate('http_timeout_sec'), 'sec']
146
213
  ]), 'UNIT');
147
214
 
215
+ this.appendDummyInput('TYPE')
216
+ .appendField(Blockly.Translate('http_type'))
217
+ .appendField(new Blockly.FieldDropdown([
218
+ [Blockly.Translate('http_type_text'), 'text'],
219
+ [Blockly.Translate('http_type_arraybuffer'), 'arraybuffer'],
220
+ ]), 'TYPE');
221
+
148
222
  this.appendStatementInput('STATEMENT')
149
223
  .setCheck(null);
150
224
 
@@ -170,7 +244,12 @@ Blockly.JavaScript['http_get'] = function(block) {
170
244
  timeout *= 1000;
171
245
  }
172
246
 
173
- return `httpGet(${URL}, { timeout: ${timeout} }, async (err, response) => {\n` +
247
+ let responseType = block.getFieldValue('TYPE');
248
+ if (!responseType) {
249
+ responseType = 'text';
250
+ }
251
+
252
+ return `httpGet(${URL}, { timeout: ${timeout}, responseType: '${responseType}' }, async (err, response) => {\n` +
174
253
  Blockly.JavaScript.prefixLines(`if (err) {`, Blockly.JavaScript.INDENT) + '\n' +
175
254
  Blockly.JavaScript.prefixLines(`console.error(err);`, Blockly.JavaScript.INDENT + Blockly.JavaScript.INDENT) + '\n' +
176
255
  Blockly.JavaScript.prefixLines(`}`, Blockly.JavaScript.INDENT) + '\n' +
@@ -190,6 +269,8 @@ Blockly.Action.blocks['http_post'] =
190
269
  + ' </value>'
191
270
  + ' <value name="UNIT">'
192
271
  + ' </value>'
272
+ + ' <value name="TYPE">'
273
+ + ' </value>'
193
274
  + ' <value name="DATA">'
194
275
  + ' <shadow type="object_new">'
195
276
  + ' </shadow>'
@@ -201,16 +282,23 @@ Blockly.Action.blocks['http_post'] =
201
282
  Blockly.Blocks['http_post'] = {
202
283
  init: function() {
203
284
  this.appendValueInput('URL')
204
- .appendField(Blockly.Translate('http_post'));
285
+ .appendField('🌐 ' + Blockly.Translate('http_post'));
205
286
 
206
287
  this.appendDummyInput()
207
- .appendField(Blockly.Translate('http_post_timeout'))
288
+ .appendField(Blockly.Translate('http_timeout'))
208
289
  .appendField(new Blockly.FieldTextInput(2000), 'TIMEOUT')
209
290
  .appendField(new Blockly.FieldDropdown([
210
- [Blockly.Translate('http_post_settimeout_ms'), 'ms'],
211
- [Blockly.Translate('http_post_settimeout_sec'), 'sec']
291
+ [Blockly.Translate('http_timeout_ms'), 'ms'],
292
+ [Blockly.Translate('http_timeout_sec'), 'sec']
212
293
  ]), 'UNIT');
213
294
 
295
+ this.appendDummyInput('TYPE')
296
+ .appendField(Blockly.Translate('http_type'))
297
+ .appendField(new Blockly.FieldDropdown([
298
+ [Blockly.Translate('http_type_text'), 'text'],
299
+ [Blockly.Translate('http_type_arraybuffer'), 'arraybuffer'],
300
+ ]), 'TYPE');
301
+
214
302
  this.appendValueInput('DATA')
215
303
  .appendField(Blockly.Translate('http_post_data'));
216
304
 
@@ -240,11 +328,16 @@ Blockly.JavaScript['http_post'] = function(block) {
240
328
  timeout *= 1000;
241
329
  }
242
330
 
331
+ let responseType = block.getFieldValue('TYPE');
332
+ if (!responseType) {
333
+ responseType = 'text';
334
+ }
335
+
243
336
  if (!data) {
244
337
  data = 'null';
245
338
  }
246
339
 
247
- return `httpPost(${URL}, ${data}, { timeout: ${timeout} }, async (err, response) => {\n` +
340
+ return `httpPost(${URL}, ${data}, { timeout: ${timeout}, responseType: '${responseType}' }, async (err, response) => {\n` +
248
341
  Blockly.JavaScript.prefixLines(`if (err) {`, Blockly.JavaScript.INDENT) + '\n' +
249
342
  Blockly.JavaScript.prefixLines(`console.error(err);`, Blockly.JavaScript.INDENT + Blockly.JavaScript.INDENT) + '\n' +
250
343
  Blockly.JavaScript.prefixLines(`}`, Blockly.JavaScript.INDENT) + '\n' +
@@ -252,7 +345,7 @@ Blockly.JavaScript['http_post'] = function(block) {
252
345
  '});\n';
253
346
  };
254
347
 
255
- // --- get info about event -----------------------------------------------------------
348
+ // --- http_response -----------------------------------------------------------
256
349
  Blockly.Action.blocks['http_response'] =
257
350
  '<block type="http_response">'
258
351
  + ' <value name="ATTR">'
@@ -276,7 +369,7 @@ Blockly.Blocks['http_response'] = {
276
369
 
277
370
  this.setInputsInline(true);
278
371
  this.setOutput(true);
279
- this.setColour(Blockly.Trigger.HUE);
372
+ this.setColour(Blockly.Action.HUE);
280
373
  this.setTooltip(Blockly.Translate('http_response_tooltip'));
281
374
  //this.setHelpUrl(getHelp('http_response'));
282
375
  },
@@ -317,6 +410,196 @@ Blockly.JavaScript['http_response'] = function(block) {
317
410
  return [attr, Blockly.JavaScript.ORDER_ATOMIC];
318
411
  };
319
412
 
413
+ // --- action file_write --------------------------------------------------
414
+ Blockly.Action.blocks['file_write'] =
415
+ '<block type="file_write">'
416
+ + ' <value name="OID">'
417
+ + ' <shadow type="field_oid_meta">'
418
+ + ' <field name="oid">0_userdata.0</field>'
419
+ + ' </shadow>'
420
+ + ' </value>'
421
+ + ' <value name="FILE">'
422
+ + ' <shadow type="text">'
423
+ + ' <field name="TEXT">demo.json</field>'
424
+ + ' </shadow>'
425
+ + ' </value>'
426
+ + ' <value name="DATA">'
427
+ + ' </value>'
428
+ + '</block>';
429
+
430
+ Blockly.Blocks['file_write'] = {
431
+ init: function() {
432
+ this.appendValueInput('OID')
433
+ .appendField('📁 ' + Blockly.Translate('file_write'));
434
+
435
+ this.appendValueInput('FILE')
436
+ .appendField(Blockly.Translate('file_write_filename'))
437
+ .setCheck(null);
438
+
439
+ this.appendValueInput('DATA')
440
+ .appendField(Blockly.Translate('file_write_data'));
441
+
442
+ this.setInputsInline(false);
443
+ this.setPreviousStatement(true, null);
444
+ this.setNextStatement(true, null);
445
+
446
+ this.setColour(Blockly.Action.HUE);
447
+ this.setTooltip(Blockly.Translate('file_write_tooltip'));
448
+ this.setHelpUrl(getHelp('file_write_help'));
449
+ }
450
+ };
451
+
452
+ Blockly.JavaScript['file_write'] = function(block) {
453
+ const value_objectid = Blockly.JavaScript.valueToCode(block, 'OID', Blockly.JavaScript.ORDER_ATOMIC);
454
+ const file = Blockly.JavaScript.valueToCode(block, 'FILE', Blockly.JavaScript.ORDER_ATOMIC);
455
+ const data = Blockly.JavaScript.valueToCode(block, 'DATA', Blockly.JavaScript.ORDER_ATOMIC);
456
+
457
+ let objectName = '';
458
+ try {
459
+ const objId = eval(value_objectid); // Code to string
460
+ objectName = main.objects[objId] && main.objects[objId].common && main.objects[objId].common.name ? main.objects[objId].common.name : '';
461
+ if (typeof objectName === 'object') {
462
+ objectName = objectName[systemLang] || objectName.en;
463
+ }
464
+ } catch (error) {
465
+
466
+ }
467
+
468
+ return `writeFile(${value_objectid}${objectName ? ` /* ${objectName} */` : ''}, String(${file}), ${data ? data : 'null'}, (err) => {\n` +
469
+ Blockly.JavaScript.prefixLines(`if (err) {`, Blockly.JavaScript.INDENT) + '\n' +
470
+ Blockly.JavaScript.prefixLines(`console.error(err);`, Blockly.JavaScript.INDENT + Blockly.JavaScript.INDENT) + '\n' +
471
+ Blockly.JavaScript.prefixLines(`}`, Blockly.JavaScript.INDENT) + '\n' +
472
+ '});\n';
473
+ };
474
+
475
+ // --- action file_read --------------------------------------------------
476
+ Blockly.Action.blocks['file_read'] =
477
+ '<block type="file_read">'
478
+ + ' <value name="OID">'
479
+ + ' <shadow type="field_oid_meta">'
480
+ + ' <field name="oid">0_userdata.0</field>'
481
+ + ' </shadow>'
482
+ + ' </value>'
483
+ + ' <value name="FILE">'
484
+ + ' <shadow type="text">'
485
+ + ' <field name="TEXT">demo.json</field>'
486
+ + ' </shadow>'
487
+ + ' </value>'
488
+ + ' <value name="STATEMENT">'
489
+ + ' </value>'
490
+ + '</block>';
491
+
492
+ Blockly.Blocks['file_read'] = {
493
+ init: function() {
494
+ this.appendValueInput('OID')
495
+ .appendField('📁 ' + Blockly.Translate('file_read'));
496
+
497
+ this.appendValueInput('FILE')
498
+ .appendField(Blockly.Translate('file_read_filename'))
499
+ .setCheck(null);
500
+
501
+ this.appendStatementInput('STATEMENT')
502
+ .setCheck(null);
503
+
504
+ this.setInputsInline(false);
505
+ this.setPreviousStatement(true, null);
506
+ this.setNextStatement(true, null);
507
+
508
+ this.setColour(Blockly.Action.HUE);
509
+ this.setTooltip(Blockly.Translate('file_read_tooltip'));
510
+ this.setHelpUrl(getHelp('file_read_help'));
511
+ }
512
+ };
513
+
514
+ Blockly.JavaScript['file_read'] = function(block) {
515
+ const value_objectid = Blockly.JavaScript.valueToCode(block, 'OID', Blockly.JavaScript.ORDER_ATOMIC);
516
+ const file = Blockly.JavaScript.valueToCode(block, 'FILE', Blockly.JavaScript.ORDER_ATOMIC);
517
+ const statement = Blockly.JavaScript.statementToCode(block, 'STATEMENT');
518
+
519
+ let objectName = '';
520
+ try {
521
+ const objId = eval(value_objectid); // Code to string
522
+ objectName = main.objects[objId] && main.objects[objId].common && main.objects[objId].common.name ? main.objects[objId].common.name : '';
523
+ if (typeof objectName === 'object') {
524
+ objectName = objectName[systemLang] || objectName.en;
525
+ }
526
+ } catch (error) {
527
+
528
+ }
529
+
530
+ return `readFile(${value_objectid}${objectName ? ` /* ${objectName} */` : ''}, String(${file}), (err, data, mimeType) => {\n` +
531
+ Blockly.JavaScript.prefixLines(`if (err) {`, Blockly.JavaScript.INDENT) + '\n' +
532
+ Blockly.JavaScript.prefixLines(`console.error(err);`, Blockly.JavaScript.INDENT + Blockly.JavaScript.INDENT) + '\n' +
533
+ Blockly.JavaScript.prefixLines(`}`, Blockly.JavaScript.INDENT) + '\n' +
534
+ statement +
535
+ '});\n';
536
+ };
537
+
538
+ // --- file_data -----------------------------------------------------------
539
+ Blockly.Action.blocks['file_data'] =
540
+ '<block type="file_data">'
541
+ + ' <value name="ATTR">'
542
+ + ' </value>'
543
+ + '</block>';
544
+
545
+ Blockly.Blocks['file_data'] = {
546
+ /**
547
+ * Block for conditionally returning a value from a procedure.
548
+ * @this Blockly.Block
549
+ */
550
+ init: function() {
551
+ this.appendDummyInput()
552
+ .appendField('📁');
553
+
554
+ this.appendDummyInput('ATTR')
555
+ .appendField(new Blockly.FieldDropdown([
556
+ [Blockly.Translate('file_data_data'), 'data'],
557
+ [Blockly.Translate('file_data_mimeType'), 'mimeType'],
558
+ ]), 'ATTR');
559
+
560
+ this.setInputsInline(true);
561
+ this.setOutput(true);
562
+ this.setColour(Blockly.Action.HUE);
563
+ this.setTooltip(Blockly.Translate('file_data_tooltip'));
564
+ //this.setHelpUrl(getHelp('file_data'));
565
+ },
566
+ /**
567
+ * Called whenever anything on the workspace changes.
568
+ * Add warning if this flow block is not nested inside a loop.
569
+ * @param {!Blockly.Events.Abstract} e Change event.
570
+ * @this Blockly.Block
571
+ */
572
+ onchange: function(e) {
573
+ let legal = false;
574
+ // Is the block nested in a trigger?
575
+ let block = this;
576
+ do {
577
+ if (this.FUNCTION_TYPES.includes(block.type)) {
578
+ legal = true;
579
+ break;
580
+ }
581
+ block = block.getSurroundParent();
582
+ } while (block);
583
+
584
+ if (legal) {
585
+ this.setWarningText(null, this.id);
586
+ } else {
587
+ this.setWarningText(Blockly.Translate('file_data_warning'), this.id);
588
+ }
589
+ },
590
+ /**
591
+ * List of block types that are functions and thus do not need warnings.
592
+ * To add a new function type add this to your code:
593
+ * Blockly.Blocks['procedures_ifreturn'].FUNCTION_TYPES.push('custom_func');
594
+ */
595
+ FUNCTION_TYPES: ['file_read'],
596
+ };
597
+ Blockly.JavaScript['file_data'] = function(block) {
598
+ const attr = block.getFieldValue('ATTR');
599
+
600
+ return [attr, Blockly.JavaScript.ORDER_ATOMIC];
601
+ };
602
+
320
603
  // --- action request --------------------------------------------------
321
604
  Blockly.Action.blocks['request'] =
322
605
  '<block type="request">'
@@ -403,7 +686,7 @@ Blockly.JavaScript['request'] = function(block) {
403
686
  logText = '';
404
687
  }
405
688
 
406
- logText += `console.warn('request blockly block is deprecated - please use "http get" instead');\n`;
689
+ logText += `console.warn('request blockly block is deprecated - please use "http (GET)" instead');\n`;
407
690
 
408
691
  if (withStatement === 'TRUE' || withStatement === 'true' || withStatement === true) {
409
692
  const statement = Blockly.JavaScript.statementToCode(block, 'STATEMENT');
@@ -229,7 +229,7 @@ Blockly.JavaScript['object_new'] = function(block) {
229
229
  for (let n = 0; n < block.itemCount_; n++) {
230
230
  const val = Blockly.JavaScript.valueToCode(block, 'ATTR_' + n, Blockly.JavaScript.ORDER_COMMA);
231
231
  if (val) {
232
- attributes.push(`'${block.attributes_[n]}': ${val}`);
232
+ attributes.push(`'${String(block.attributes_[n]).replaceAll(`'`, `\\'`)}': ${val}`);
233
233
  }
234
234
  }
235
235
 
@@ -282,7 +282,7 @@ Blockly.JavaScript['object_set_attr'] = function(block) {
282
282
  obj = '{}';
283
283
  }
284
284
 
285
- return `(() => { const obj = ${obj}; if (typeof obj === 'object') { obj['${attr}'] = ${value}; } })();\n`;
285
+ return `((obj) => { if (typeof obj === 'object') { obj['${attr}'] = ${value}; } })(${obj});\n`;
286
286
  };
287
287
 
288
288
  // --- delete attribute --------------------------------------------------
@@ -321,7 +321,7 @@ Blockly.JavaScript['object_del_attr'] = function(block) {
321
321
  obj = '{}';
322
322
  }
323
323
 
324
- return `(() => { const obj = ${obj}; if (typeof obj === 'object') { delete obj['${attr}']; } })();\n`;
324
+ return `((obj) => { if (typeof obj === 'object') { delete obj['${attr}']; } })(${obj});\n`;
325
325
  };
326
326
 
327
327
  // --- has attribute --------------------------------------------------
@@ -102,7 +102,7 @@ Blockly.Blocks['control'] = {
102
102
  .appendField(Blockly.Translate('control'));
103
103
 
104
104
  this.appendDummyInput('OID')
105
- .appendField(new Blockly.FieldOID('Object ID'), 'OID');
105
+ .appendField(new Blockly.FieldOID(Blockly.Translate('select_id'), 'state'), 'OID');
106
106
 
107
107
  this.appendValueInput('VALUE')
108
108
  .setCheck(null)
@@ -222,7 +222,7 @@ Blockly.Blocks['toggle'] = {
222
222
  .appendField(Blockly.Translate('toggle'));
223
223
 
224
224
  this.appendDummyInput('OID')
225
- .appendField(new Blockly.FieldOID('Object ID'), 'OID');
225
+ .appendField(new Blockly.FieldOID(Blockly.Translate('select_id'), 'state'), 'OID');
226
226
 
227
227
  this.appendDummyInput('WITH_DELAY')
228
228
  .appendField(Blockly.Translate('toggle_delay'))
@@ -362,7 +362,7 @@ Blockly.Blocks['update'] = {
362
362
  .appendField(Blockly.Translate('update'));
363
363
 
364
364
  this.appendDummyInput('OID')
365
- .appendField(new Blockly.FieldOID('Object ID'), 'OID');
365
+ .appendField(new Blockly.FieldOID(Blockly.Translate('select_id'), 'state'), 'OID');
366
366
 
367
367
  this.appendValueInput('VALUE')
368
368
  .setCheck(null)
@@ -775,7 +775,6 @@ Blockly.Blocks['get_value'] = {
775
775
  [Blockly.Translate('get_common_unit'), 'common.unit'],
776
776
  [Blockly.Translate('get_common_role'), 'common.role'],
777
777
  [Blockly.Translate('get_common_state_type'), 'common.type'],
778
- [Blockly.Translate('get_common_object_type'), 'type'],
779
778
  [Blockly.Translate('get_common_read'), 'common.read'],
780
779
  [Blockly.Translate('get_common_write'), 'common.write'],
781
780
  ]), 'ATTR');
@@ -784,7 +783,7 @@ Blockly.Blocks['get_value'] = {
784
783
  .appendField(Blockly.Translate('get_value_OID'));
785
784
 
786
785
  this.appendDummyInput()
787
- .appendField(new Blockly.FieldOID(Blockly.Translate('get_value_default')), 'OID');
786
+ .appendField(new Blockly.FieldOID(Blockly.Translate('select_id'), 'state'), 'OID');
788
787
 
789
788
  this.setInputsInline(true);
790
789
  this.setOutput(true);
@@ -849,7 +848,6 @@ Blockly.Blocks['get_value_var'] = {
849
848
  [Blockly.Translate('get_common_unit'), 'common.unit'],
850
849
  [Blockly.Translate('get_common_role'), 'common.role'],
851
850
  [Blockly.Translate('get_common_state_type'), 'common.type'],
852
- [Blockly.Translate('get_common_object_type'), 'type'],
853
851
  [Blockly.Translate('get_common_read'), 'common.read'],
854
852
  [Blockly.Translate('get_common_write'), 'common.write'],
855
853
  ]), 'ATTR');
@@ -922,7 +920,6 @@ Blockly.Blocks['get_value_async'] = {
922
920
  [Blockly.Translate('get_common_unit'), 'common.unit'],
923
921
  [Blockly.Translate('get_common_role'), 'common.role'],
924
922
  [Blockly.Translate('get_common_state_type'), 'common.type'],
925
- [Blockly.Translate('get_common_object_type'), 'type'],
926
923
  [Blockly.Translate('get_common_read'), 'common.read'],
927
924
  [Blockly.Translate('get_common_write'), 'common.write'],
928
925
  ]), 'ATTR');
@@ -931,7 +928,7 @@ Blockly.Blocks['get_value_async'] = {
931
928
  .appendField(Blockly.Translate('get_value_OID'));
932
929
 
933
930
  this.appendDummyInput()
934
- .appendField(new Blockly.FieldOID(Blockly.Translate('get_value_default')), 'OID');
931
+ .appendField(new Blockly.FieldOID(Blockly.Translate('select_id'), 'state'), 'OID');
935
932
 
936
933
  this.appendStatementInput('STATEMENT')
937
934
  .setCheck(null);
@@ -978,7 +975,7 @@ Blockly.Blocks['get_object'] = {
978
975
  .appendField(Blockly.Translate('get_object'));
979
976
 
980
977
  this.appendDummyInput()
981
- .appendField(new Blockly.FieldOID(Blockly.Translate('get_object_default')), 'OID');
978
+ .appendField(new Blockly.FieldOID(Blockly.Translate('select_id'), 'all'), 'OID');
982
979
 
983
980
  this.setInputsInline(true);
984
981
  this.setOutput(true);
@@ -1024,7 +1021,7 @@ Blockly.Blocks['get_object_async'] = {
1024
1021
  .appendField(Blockly.Translate('get_object'));
1025
1022
 
1026
1023
  this.appendDummyInput()
1027
- .appendField(new Blockly.FieldOID(Blockly.Translate('get_object_default')), 'OID');
1024
+ .appendField(new Blockly.FieldOID(Blockly.Translate('select_id'), 'all'), 'OID');
1028
1025
 
1029
1026
  this.appendStatementInput('STATEMENT')
1030
1027
  .setCheck(null);
@@ -1061,7 +1058,7 @@ Blockly.Blocks['field_oid'] = {
1061
1058
  .appendField(Blockly.Translate('field_oid_OID'));
1062
1059
 
1063
1060
  this.appendDummyInput()
1064
- .appendField(new Blockly.FieldOID('default'), 'oid');
1061
+ .appendField(new Blockly.FieldOID(Blockly.Translate('select_id'), 'state'), 'oid');
1065
1062
 
1066
1063
  this.setInputsInline(true);
1067
1064
  this.setColour("%{BKY_TEXTS_HUE}");
@@ -1089,7 +1086,7 @@ Blockly.Blocks['field_oid_meta'] = {
1089
1086
  .appendField(Blockly.Translate('field_oid_OID_meta'));
1090
1087
 
1091
1088
  this.appendDummyInput()
1092
- .appendField(new Blockly.FieldOID('default', 'meta'), 'oid');
1089
+ .appendField(new Blockly.FieldOID(Blockly.Translate('select_id'), 'meta'), 'oid');
1093
1090
 
1094
1091
  this.setInputsInline(true);
1095
1092
  this.setColour("%{BKY_TEXTS_HUE}");
@@ -1117,7 +1114,7 @@ Blockly.Blocks['field_oid_script'] = {
1117
1114
  .appendField(Blockly.Translate('field_oid_OID_script'));
1118
1115
 
1119
1116
  this.appendDummyInput()
1120
- .appendField(new Blockly.FieldOID('default', 'script'), 'oid');
1117
+ .appendField(new Blockly.FieldOID(Blockly.Translate('select_id'), 'script'), 'oid');
1121
1118
 
1122
1119
  this.setInputsInline(true);
1123
1120
  this.setColour("%{BKY_TEXTS_HUE}");