@digipair/skill-web-editor 0.4.2

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,519 @@
1
+ 'use strict';
2
+
3
+ function getPinsBlockDefinition(library, methodData, pinsId) {
4
+ const blockDefinition = {
5
+ type: pinsId,
6
+ message0: library.info['x-icon'] + ' ' + methodData.summary,
7
+ args0: [],
8
+ message1: '',
9
+ args1: [],
10
+ message2: '',
11
+ args2: [],
12
+ message3: '',
13
+ args3: [],
14
+ colour: '#1e2835',
15
+ tooltip: 'library : ' + library.info.title,
16
+ inputsInline: false,
17
+ previousStatement: null,
18
+ nextStatement: null
19
+ };
20
+ const parameters = methodData.parameters;
21
+ const metadata = methodData.metadata || [];
22
+ const events = methodData['x-events'] || [];
23
+ const requiredParamInputs = parameters.filter((param)=>param.required === true);
24
+ const requiredEventInputs = [];
25
+ const requiredFields = requiredParamInputs.map((param)=>param.name);
26
+ if (methodData['x-events']) {
27
+ methodData['x-events'].forEach((event)=>{
28
+ if (event.required) {
29
+ requiredEventInputs.push(event);
30
+ requiredFields.push('__EVENT__/' + event.name);
31
+ }
32
+ });
33
+ }
34
+ requiredFields.push('');
35
+ const mutatorToolbox = parameters.map((param)=>param.name).filter((name)=>!requiredFields.includes(name));
36
+ if (methodData.tags) {
37
+ if (methodData.tags.includes('needPins') && !methodData.tags.includes('requirePins')) {
38
+ mutatorToolbox.push('pins');
39
+ } else if (methodData.tags.includes('needPins') && methodData.tags.includes('requirePins')) {
40
+ blockDefinition['message3'] += '%1 %2 %3';
41
+ blockDefinition['args3'].push({
42
+ type: 'field_label',
43
+ name: `NAME_INPUT`,
44
+ text: 'pins*'
45
+ });
46
+ blockDefinition['args3'].push({
47
+ type: 'input_dummy'
48
+ });
49
+ blockDefinition['args3'].push({
50
+ type: 'input_statement',
51
+ name: 'pins'
52
+ });
53
+ requiredFields.push('pins');
54
+ }
55
+ }
56
+ if (methodData['x-events']) {
57
+ for (const event of methodData['x-events']){
58
+ if (event.required === false || !event.required) {
59
+ mutatorToolbox.push('__EVENT__/' + event.name);
60
+ }
61
+ }
62
+ }
63
+ for(let i = 0; i < requiredParamInputs.length; i++){
64
+ var _requiredParamInputs_i_schema, _requiredParamInputs_i_schema1, _requiredParamInputs_i_schema_items_$ref, _requiredParamInputs_i_schema2;
65
+ const position = blockDefinition['args1'].length;
66
+ blockDefinition['args1'].push({
67
+ type: 'field_label',
68
+ name: `NAME_INPUT`,
69
+ text: (requiredParamInputs[i].summary || requiredParamInputs[i].name) + '*'
70
+ });
71
+ if (((_requiredParamInputs_i_schema = requiredParamInputs[i].schema) == null ? void 0 : _requiredParamInputs_i_schema.type) === 'array' && (((_requiredParamInputs_i_schema1 = requiredParamInputs[i].schema) == null ? void 0 : _requiredParamInputs_i_schema1.items.$ref) === 'https://www.pinser.world/schemas/pinsSettings' || ((_requiredParamInputs_i_schema2 = requiredParamInputs[i].schema) == null ? void 0 : (_requiredParamInputs_i_schema_items_$ref = _requiredParamInputs_i_schema2.items.$ref) == null ? void 0 : _requiredParamInputs_i_schema_items_$ref.includes('#/components/schemas/')))) {
72
+ blockDefinition['message1'] += ' %' + (position + 1) + ' %' + (position + 2) + ' %' + (position + 3);
73
+ blockDefinition['args1'].push({
74
+ type: 'input_dummy'
75
+ });
76
+ blockDefinition['args1'].push({
77
+ type: 'input_statement',
78
+ name: requiredParamInputs[i].name
79
+ });
80
+ } else {
81
+ blockDefinition['message1'] += ' %' + (position + 1) + ' %' + (position + 2);
82
+ blockDefinition['args1'].push({
83
+ type: 'input_value',
84
+ name: requiredParamInputs[i].name
85
+ });
86
+ }
87
+ }
88
+ for(let i = 0; i < requiredEventInputs.length; i++){
89
+ const position = blockDefinition['args2'].length;
90
+ blockDefinition['args2'].push({
91
+ type: 'field_label',
92
+ name: `NAME_INPUT`,
93
+ text: '@' + (requiredEventInputs[i].summary || requiredEventInputs[i].name) + '*'
94
+ });
95
+ blockDefinition['message2'] += ' %' + (position + 1) + ' %' + (position + 2) + ' %' + (position + 3);
96
+ blockDefinition['args2'].push({
97
+ type: 'input_dummy'
98
+ });
99
+ blockDefinition['args2'].push({
100
+ type: 'input_statement',
101
+ name: '__EVENT__/' + requiredEventInputs[i].name
102
+ });
103
+ }
104
+ if (mutatorToolbox.length > 0) {
105
+ blockDefinition.mutator = pinsId + '/mutator';
106
+ generateMutator(pinsId + '/mutator', mutatorToolbox, requiredFields, [
107
+ ...parameters,
108
+ ...metadata,
109
+ ...events
110
+ ]);
111
+ }
112
+ return blockDefinition;
113
+ }
114
+ function getComponentBlockDefinition(library, componentName, methodData, componentId) {
115
+ const blockDefinition = {
116
+ type: componentId,
117
+ message0: library.info['x-icon'] + ' ' + componentName,
118
+ args0: [],
119
+ message1: '',
120
+ args1: [],
121
+ colour: '#74dc04',
122
+ tooltip: 'library : ' + library.info.title,
123
+ inputsInline: false,
124
+ previousStatement: null,
125
+ nextStatement: null
126
+ };
127
+ const properties = methodData.properties;
128
+ const requiredFields = methodData.required || [];
129
+ requiredFields.push('');
130
+ const mutatorToolbox = [];
131
+ const parameters = Object.keys(properties).map((propertyName)=>({
132
+ name: propertyName,
133
+ schema: properties[propertyName]
134
+ }));
135
+ let messageIndex = 0;
136
+ parameters.forEach((parameter, _index)=>{
137
+ const propertyName = parameter.name;
138
+ if (!requiredFields.includes(propertyName)) {
139
+ mutatorToolbox.push(propertyName);
140
+ } else {
141
+ var _parameter_schema, _parameter_schema1, _parameter_schema2;
142
+ blockDefinition['args1'].push({
143
+ type: 'field_label',
144
+ name: 'NAME_INPUT',
145
+ text: propertyName + '*'
146
+ });
147
+ if (((_parameter_schema = parameter.schema) == null ? void 0 : _parameter_schema.type) === 'array' && (((_parameter_schema1 = parameter.schema) == null ? void 0 : _parameter_schema1.items.$ref) === 'https://www.pinser.world/schemas/pinsSettings' || ((_parameter_schema2 = parameter.schema) == null ? void 0 : _parameter_schema2.items.$ref.includes('#/components/schemas/')))) {
148
+ blockDefinition['message1'] += ' %' + (messageIndex * 2 + 1) + ' %' + (messageIndex * 2 + 2) + ' %' + (messageIndex * 2 + 3);
149
+ blockDefinition['args1'].push({
150
+ type: 'input_dummy'
151
+ });
152
+ blockDefinition['args1'].push({
153
+ type: 'input_statement',
154
+ name: parameter.name
155
+ });
156
+ } else {
157
+ blockDefinition['message1'] += ' %' + (messageIndex * 2 + 1) + ' %' + (messageIndex * 2 + 2);
158
+ blockDefinition['args1'].push({
159
+ type: 'input_value',
160
+ name: parameter.name
161
+ });
162
+ }
163
+ messageIndex++;
164
+ }
165
+ });
166
+ if (mutatorToolbox.length > 0) {
167
+ blockDefinition.mutator = componentId + '/mutator';
168
+ generateMutator(componentId + '/mutator', mutatorToolbox, requiredFields, parameters);
169
+ }
170
+ return blockDefinition;
171
+ }
172
+ function generateToolboxFromLibraries(libraries) {
173
+ const sortedLibraries = libraries.sort((a, b)=>{
174
+ var _a_info_summary;
175
+ const title1 = (_a_info_summary = a.info.summary) != null ? _a_info_summary : a.info.title;
176
+ var _b_info_summary;
177
+ const title2 = (_b_info_summary = b.info.summary) != null ? _b_info_summary : b.info.title;
178
+ if (title1 < title2) {
179
+ return -1;
180
+ }
181
+ if (title1 > title2) {
182
+ return 1;
183
+ }
184
+ return 0;
185
+ });
186
+ const toolbox = {
187
+ kind: 'categoryToolbox',
188
+ contents: [
189
+ {
190
+ kind: 'category',
191
+ name: '⚙️ Common',
192
+ contents: [
193
+ {
194
+ kind: 'block',
195
+ type: 'object'
196
+ },
197
+ {
198
+ kind: 'block',
199
+ type: 'member'
200
+ },
201
+ {
202
+ kind: 'block',
203
+ type: 'math_number'
204
+ },
205
+ {
206
+ kind: 'block',
207
+ type: 'text_multiline'
208
+ },
209
+ {
210
+ kind: 'block',
211
+ type: 'logic_boolean'
212
+ },
213
+ {
214
+ kind: 'block',
215
+ type: 'logic_null'
216
+ },
217
+ {
218
+ kind: 'block',
219
+ type: 'array'
220
+ },
221
+ {
222
+ kind: 'block',
223
+ type: 'array-input'
224
+ }
225
+ ]
226
+ },
227
+ ...sortedLibraries.map((library)=>{
228
+ var _library_components;
229
+ var _library_info_summary;
230
+ return {
231
+ kind: 'category',
232
+ name: library.info['x-icon'] + ' ' + ((_library_info_summary = library.info.summary) != null ? _library_info_summary : library.info.title),
233
+ contents: [
234
+ ...library.paths ? Object.entries(library.paths).sort((a, b)=>a[0].localeCompare(b[0])) // Tri alphabétique par path
235
+ .map(([path, _pins])=>({
236
+ kind: 'block',
237
+ type: library.info.title + '/__PINS__' + path
238
+ })) : [],
239
+ ...((_library_components = library.components) == null ? void 0 : _library_components.schemas) ? Object.entries(library.components.schemas).sort((a, b)=>a[0].localeCompare(b[0])) // Tri alphabétique par componentName
240
+ .map(([componentName, _componentSchema])=>({
241
+ kind: 'block',
242
+ type: library.info.title + '/__COMPONENTS__/' + componentName
243
+ })) : []
244
+ ]
245
+ };
246
+ })
247
+ ]
248
+ };
249
+ return toolbox;
250
+ }
251
+ function generateBlocklyBlockFromLibraries(pinsLibraries, blocksLegacy) {
252
+ const blocksLibrary = [
253
+ ...blocksLegacy
254
+ ];
255
+ for (const pinsLibrary of pinsLibraries){
256
+ //search for pins blocks
257
+ for(const endpoint in pinsLibrary.paths){
258
+ if (Object.hasOwnProperty.call(pinsLibrary.paths, endpoint)) {
259
+ const endpointData = pinsLibrary.paths[endpoint];
260
+ const methodData = endpointData.post;
261
+ const pinsId = pinsLibrary.info.title + '/__PINS__' + endpoint;
262
+ blocksLibrary.push(getPinsBlockDefinition(pinsLibrary, methodData, pinsId));
263
+ }
264
+ }
265
+ }
266
+ for (const pinsLibrary of pinsLibraries){
267
+ //search for components blocks
268
+ if (!pinsLibrary.components || !pinsLibrary.components.schemas) {
269
+ continue;
270
+ }
271
+ for(const endpoint in pinsLibrary.components.schemas){
272
+ if (Object.hasOwnProperty.call(pinsLibrary.components.schemas, endpoint)) {
273
+ const endpointData = pinsLibrary.components.schemas[endpoint];
274
+ if (!endpointData || !endpointData.properties) {
275
+ continue;
276
+ }
277
+ const componentId = pinsLibrary.info.title + '/__COMPONENTS__/' + endpoint;
278
+ const blockName = endpoint;
279
+ blocksLibrary.push(getComponentBlockDefinition(pinsLibrary, blockName, endpointData, componentId));
280
+ }
281
+ }
282
+ }
283
+ for (const pinsLibrary of pinsLibraries){
284
+ //search for scene blocks
285
+ for(const endpoint in pinsLibrary['x-scene-blocks']){
286
+ if (Object.hasOwnProperty.call(pinsLibrary['x-scene-blocks'], endpoint)) {
287
+ const endpointSceneblock = pinsLibrary['x-scene-blocks'][endpoint];
288
+ const sceneBlockId = pinsLibrary.info.title + '/__SCENEBLOCK__' + endpoint;
289
+ blocksLibrary.push(getSceneBlockDefinition(pinsLibrary, endpointSceneblock, sceneBlockId));
290
+ }
291
+ }
292
+ }
293
+ return blocksLibrary;
294
+ }
295
+ function initializeMutator() {
296
+ Blockly.Blocks['mutator_container'] = {
297
+ init: function() {
298
+ this.appendDummyInput().appendField('Inputs');
299
+ this.appendStatementInput('STACK');
300
+ this.setColour(230);
301
+ this.setTooltip('');
302
+ this.workspace.addChangeListener((event)=>{
303
+ if (event.type === Blockly.Events.BLOCK_MOVE) {
304
+ let currentBlock = this.workspace.getBlockById(event.newParentId);
305
+ while(currentBlock){
306
+ if (currentBlock.id === this.id) {
307
+ let firstBlock = this.getInputTargetBlock('STACK');
308
+ const seenTypes = {};
309
+ while(firstBlock){
310
+ if (seenTypes[firstBlock.type]) {
311
+ firstBlock.unplug(true);
312
+ } else {
313
+ seenTypes[firstBlock.type] = true;
314
+ }
315
+ firstBlock = firstBlock.getNextBlock();
316
+ }
317
+ break;
318
+ }
319
+ currentBlock = currentBlock.getSurroundParent();
320
+ }
321
+ }
322
+ });
323
+ }
324
+ };
325
+ }
326
+ function generateMutator(mutatorName, toolboxItem, requiredFields, parameters) {
327
+ const toolboxList = [];
328
+ for (const item of toolboxItem){
329
+ Blockly.Blocks[mutatorName + '/' + item] = {
330
+ init: function() {
331
+ this.appendDummyInput(item).appendField(item.includes('__EVENT__/') ? item.replace('__EVENT__/', '@') : item);
332
+ this.setPreviousStatement(true);
333
+ this.setNextStatement(true);
334
+ this.setColour(0);
335
+ }
336
+ };
337
+ toolboxList.push(mutatorName + '/' + item);
338
+ }
339
+ toolboxList.sort((a, b)=>a.localeCompare(b));
340
+ Blockly.Extensions.registerMutator(mutatorName, {
341
+ saveExtraState: function() {
342
+ return {
343
+ itemList: this.itemList_ || []
344
+ };
345
+ },
346
+ loadExtraState: function(state) {
347
+ this.itemList_ = state['itemList'];
348
+ this.updateShape_();
349
+ },
350
+ decompose: function(workspace) {
351
+ const containerBlock = workspace.newBlock('mutator_container');
352
+ containerBlock.initSvg();
353
+ let connection = containerBlock.getInput('STACK').connection;
354
+ for(let i = 0; i < this.inputList.length; i++){
355
+ if (requiredFields.includes(this.inputList[i].name)) {
356
+ continue;
357
+ }
358
+ const inputBlock = workspace.newBlock(mutatorName + '/' + this.inputList[i].name);
359
+ inputBlock.initSvg();
360
+ connection.connect(inputBlock.previousConnection);
361
+ connection = inputBlock.nextConnection;
362
+ }
363
+ return containerBlock;
364
+ },
365
+ compose: function(containerBlock) {
366
+ const inputConnectedArray = [];
367
+ let childBlock = containerBlock.getInputTargetBlock('STACK');
368
+ while(childBlock){
369
+ const inputName = childBlock.inputList[0].name;
370
+ let fieldName = '';
371
+ if (childBlock.inputList[0]) {
372
+ const fieldRow = childBlock.inputList[0].fieldRow;
373
+ if (fieldRow.length > 0) {
374
+ fieldName = fieldRow[0].getText();
375
+ }
376
+ }
377
+ inputConnectedArray.push({
378
+ id: inputName,
379
+ name: fieldName
380
+ });
381
+ childBlock = childBlock.nextConnection && childBlock.nextConnection.targetBlock();
382
+ }
383
+ this.itemList_ = inputConnectedArray;
384
+ this.updateShape_();
385
+ },
386
+ updateShape_: function() {
387
+ const inputToEnable = this.itemList_;
388
+ const inputLoaded = this.inputList.map((input)=>input.name);
389
+ const inputToEnableIds = inputToEnable.map((input)=>input.id);
390
+ for (const input of inputLoaded){
391
+ if (requiredFields.includes(input)) continue;
392
+ if (!inputToEnableIds.includes(input)) {
393
+ this.removeInput(input);
394
+ }
395
+ }
396
+ for (const input of inputToEnable){
397
+ if (requiredFields.includes(input)) {
398
+ continue;
399
+ }
400
+ if (!inputLoaded.includes(input.id)) {
401
+ var _parameter_schema, _parameter_schema1, _parameter_schema_items_$ref, _parameter_schema2;
402
+ const id = input.id.indexOf('/') < 0 ? input.id : input.id.split('/')[1];
403
+ var _parameters_find;
404
+ const parameter = (_parameters_find = parameters.find((param)=>param.name === id)) != null ? _parameters_find : {};
405
+ if (((_parameter_schema = parameter.schema) == null ? void 0 : _parameter_schema.type) === 'array' && (((_parameter_schema1 = parameter.schema) == null ? void 0 : _parameter_schema1.items.$ref) === 'https://www.pinser.world/schemas/pinsSettings' || ((_parameter_schema2 = parameter.schema) == null ? void 0 : (_parameter_schema_items_$ref = _parameter_schema2.items.$ref) == null ? void 0 : _parameter_schema_items_$ref.includes('#/components/schemas/')))) {
406
+ this.appendDummyInput().appendField(input.name);
407
+ this.appendStatementInput(input.id);
408
+ } else {
409
+ this.appendValueInput(input.id).appendField(input.name);
410
+ }
411
+ }
412
+ }
413
+ }
414
+ }, null, toolboxList);
415
+ }
416
+ function getSceneBlockDefinition(library, methodData, sceneBlockId) {
417
+ const blockDefinition = {
418
+ type: sceneBlockId,
419
+ message0: library.info['x-icon'] + ' ' + methodData.summary,
420
+ args0: [],
421
+ message1: '',
422
+ args1: [],
423
+ message2: '',
424
+ args2: [],
425
+ message3: '',
426
+ args3: [],
427
+ colour: 230,
428
+ tooltip: 'library : ' + library.info.title
429
+ };
430
+ const metadata = methodData.metadata || [];
431
+ const parameters = methodData.parameters || [];
432
+ if (methodData.tags && methodData.tags.includes('needPins')) {
433
+ const parameter = {
434
+ required: methodData.tags.includes('requirePins'),
435
+ name: 'EXECUTE_PINS',
436
+ summary: 'pins',
437
+ schema: {
438
+ type: 'array',
439
+ items: {
440
+ $ref: 'https://www.pinser.world/schemas/pinsSettings'
441
+ }
442
+ }
443
+ };
444
+ parameters.push(parameter);
445
+ }
446
+ const requiredParamInputs = parameters.filter((param)=>param.required === true);
447
+ const requiredFields = requiredParamInputs.map((param)=>param.name);
448
+ requiredFields.push('');
449
+ // metadata
450
+ for(let i = 0; i < (metadata == null ? void 0 : metadata.length); i++){
451
+ var _parameter_schema, _parameter_schema_items_$ref;
452
+ var _metadata_find;
453
+ const parameter = (_metadata_find = metadata.find((param)=>param.name === metadata[i].name)) != null ? _metadata_find : {};
454
+ const position = blockDefinition['args1'].length;
455
+ blockDefinition['args1'].push({
456
+ type: 'field_label',
457
+ name: `NAME_INPUT_METADATA`,
458
+ text: (parameter.summary || parameter.name) + '*'
459
+ });
460
+ if (((_parameter_schema = parameter.schema) == null ? void 0 : _parameter_schema.type) === 'array' && (parameter.schema.items.$ref === 'https://www.pinser.world/schemas/pinsSettings' || ((_parameter_schema_items_$ref = parameter.schema.items.$ref) == null ? void 0 : _parameter_schema_items_$ref.includes('#/components/schemas/')))) {
461
+ blockDefinition['message1'] += ' %' + (position + 1) + ' %' + (position + 2) + ' %' + (position + 3);
462
+ blockDefinition['args1'].push({
463
+ type: 'input_dummy'
464
+ });
465
+ blockDefinition['args1'].push({
466
+ type: 'input_statement',
467
+ name: 'metadata--' + parameter.name
468
+ });
469
+ } else {
470
+ blockDefinition['message1'] += ' %' + (position + 1) + ' %' + (position + 2);
471
+ blockDefinition['args1'].push({
472
+ type: 'input_value',
473
+ name: 'metadata--' + parameter.name
474
+ });
475
+ }
476
+ }
477
+ // mutator toolbox
478
+ const mutatorToolbox = parameters.map((param)=>param.name).filter((name)=>!requiredFields.includes(name));
479
+ // parameters
480
+ for(let i = 0; i < requiredParamInputs.length; i++){
481
+ var _parameter_schema1, _parameter_schema_items_$ref1;
482
+ var _parameters_find;
483
+ const parameter = (_parameters_find = parameters.find((param)=>param.name === requiredParamInputs[i].name)) != null ? _parameters_find : {};
484
+ const position = blockDefinition['args3'].length;
485
+ blockDefinition['args3'].push({
486
+ type: 'field_label',
487
+ name: `NAME_INPUT`,
488
+ text: (parameter.summary || parameter.name) + '*'
489
+ });
490
+ if (((_parameter_schema1 = parameter.schema) == null ? void 0 : _parameter_schema1.type) === 'array' && (parameter.schema.items.$ref === 'https://www.pinser.world/schemas/pinsSettings' || ((_parameter_schema_items_$ref1 = parameter.schema.items.$ref) == null ? void 0 : _parameter_schema_items_$ref1.includes('#/components/schemas/')))) {
491
+ blockDefinition['message3'] += ' %' + (position + 1) + ' %' + (position + 2) + ' %' + (position + 3);
492
+ blockDefinition['args3'].push({
493
+ type: 'input_dummy'
494
+ });
495
+ blockDefinition['args3'].push({
496
+ type: 'input_statement',
497
+ name: parameter.name
498
+ });
499
+ } else {
500
+ blockDefinition['message3'] += ' %' + (position + 1) + ' %' + (position + 2);
501
+ blockDefinition['args3'].push({
502
+ type: 'input_value',
503
+ name: parameter.name
504
+ });
505
+ }
506
+ }
507
+ if (mutatorToolbox.length > 0) {
508
+ blockDefinition.mutator = sceneBlockId + '/mutator';
509
+ generateMutator(sceneBlockId + '/mutator', mutatorToolbox, requiredFields, [
510
+ ...parameters,
511
+ ...metadata || []
512
+ ]);
513
+ }
514
+ return blockDefinition;
515
+ }
516
+
517
+ exports.generateBlocklyBlockFromLibraries = generateBlocklyBlockFromLibraries;
518
+ exports.generateToolboxFromLibraries = generateToolboxFromLibraries;
519
+ exports.initializeMutator = initializeMutator;