@vario-software/vario-app-framework-backend 2026.9.2 → 2026.10.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.
@@ -0,0 +1,36 @@
1
+ function streamResponse(res, handler)
2
+ {
3
+ const streaming = res.req.headers['x-stream'] === 'true';
4
+
5
+ if (!streaming)
6
+ {
7
+ return handler().then(result => res.send(result).status(200).end());
8
+ }
9
+
10
+ res.writeHead(200, {
11
+ 'Content-Type': 'text/event-stream',
12
+ 'Cache-Control': 'no-cache',
13
+ Connection: 'keep-alive',
14
+ });
15
+
16
+ const onProgress = data =>
17
+ {
18
+ res.write(`${JSON.stringify(data)}\n`);
19
+ };
20
+
21
+ return handler(onProgress)
22
+ .then(result =>
23
+ {
24
+ res.write(`${JSON.stringify({ type: 'done', ...result })}\n`);
25
+ })
26
+ .catch(error =>
27
+ {
28
+ res.write(`${JSON.stringify({ type: 'error', message: error.message })}\n`);
29
+ })
30
+ .finally(() =>
31
+ {
32
+ res.end();
33
+ });
34
+ }
35
+
36
+ module.exports = streamResponse;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vario-software/vario-app-framework-backend",
3
- "version": "2026.09.2",
3
+ "version": "2026.10.1",
4
4
  "repository": "https://github.com/vario-software/vario-app-framework",
5
5
  "author": "VARIO Software AG",
6
6
  "homepage": "https://www.vario.ag",
package/utils/migrator.js CHANGED
@@ -330,6 +330,16 @@ const Migrator = class
330
330
  return finance;
331
331
  },
332
332
 
333
+ getMultipartImportPreset: async id =>
334
+ {
335
+ const { data: importMultipartPreset } = await this.ApiAdapter.fetch(
336
+ `/cmn/data-import/runs/multi-part/${id}`,
337
+ { method: 'GET' },
338
+ );
339
+
340
+ return importMultipartPreset;
341
+ },
342
+
333
343
  updateMultipartImportPreset: async (id, importMultipartPresetTemplate) =>
334
344
  {
335
345
  const { data: importMultipartPreset } = await this.app.erp.fetch(
@@ -344,17 +354,8 @@ const Migrator = class
344
354
  return importMultipartPreset;
345
355
  },
346
356
 
347
- addAppScriptingTrigger: async (triggerId, script) =>
357
+ getOrCreateScriptModuleGroup: async () =>
348
358
  {
349
- const existingProxyId = await this.methods.getAppScriptingTriggerId(triggerId);
350
-
351
- if (existingProxyId)
352
- {
353
- await this.methods.updateAppScriptingTrigger(triggerId, script, existingProxyId);
354
-
355
- return;
356
- }
357
-
358
359
  const { data: existingGroups } = await this.ApiAdapter.fetch(
359
360
  '/cmn/computed-queries/scripting/script-module-groups',
360
361
  {
@@ -376,24 +377,172 @@ const Migrator = class
376
377
  },
377
378
  );
378
379
 
379
- let scriptGroup;
380
+ if (existingGroups?.data?.length > 0)
381
+ {
382
+ return existingGroups.data[0];
383
+ }
380
384
 
381
- if (existingGroups?.data && existingGroups.data.length > 0)
385
+ const { data: newGroup } = await this.ApiAdapter.fetch(
386
+ '/cmn/scripting/module-groups',
387
+ {
388
+ method: 'POST',
389
+ body: { name: this.app.client.appIdentifier },
390
+ },
391
+ );
392
+
393
+ await this.methods.log(`Script-Module-Group "${this.app.client.appIdentifier}" created (ID: ${newGroup.id})\n`);
394
+
395
+ return newGroup;
396
+ },
397
+
398
+ getOrCreateImportScriptPresetting: async (name, script, existingInlineScript) =>
399
+ {
400
+ const scriptGroup = await this.methods.getOrCreateScriptModuleGroup();
401
+
402
+ const { data: existingModules } = await this.ApiAdapter.fetch(
403
+ '/cmn/computed-queries/scripting/script-modules',
404
+ {
405
+ method: 'POST',
406
+ body: {
407
+ adhocPreset: {
408
+ queryPredicate: {
409
+ type: 'JUNCTION',
410
+ operator: 'AND',
411
+ children: [
412
+ {
413
+ type: 'FILTER',
414
+ operator: 'EQUALS',
415
+ property: 'name',
416
+ values: [name],
417
+ },
418
+ {
419
+ type: 'FILTER',
420
+ operator: 'EQUALS',
421
+ property: 'group.id',
422
+ values: [scriptGroup.id],
423
+ },
424
+ ],
425
+ },
426
+ results: [
427
+ { property: 'id' },
428
+ { property: 'name' },
429
+ ],
430
+ },
431
+ },
432
+ },
433
+ );
434
+
435
+ const scriptContent = typeof script === 'string' ? script : JSON.stringify(script);
436
+ let scriptModuleRef;
437
+
438
+ if (existingModules?.data?.length > 0)
382
439
  {
383
- scriptGroup = existingGroups.data[0];
440
+ const moduleId = existingModules.data[0].id;
441
+
442
+ const { data: existingPresetting } = await this.ApiAdapter.fetch(
443
+ `/cmn/scripting/modules/${moduleId}/presettings`,
444
+ { method: 'GET' },
445
+ );
446
+
447
+ await this.ApiAdapter.fetch(
448
+ `/cmn/scripting/modules/${moduleId}/presettings`,
449
+ {
450
+ method: 'PUT',
451
+ body: {
452
+ ...existingPresetting,
453
+ script: scriptContent,
454
+ },
455
+ },
456
+ );
457
+
458
+ await this.methods.log(`Script-Module-Presetting "${name}" updated (ID: ${moduleId})\n`);
459
+
460
+ scriptModuleRef = { id: moduleId };
384
461
  }
385
462
  else
386
463
  {
387
- const { data: newGroup } = await this.ApiAdapter.fetch(
388
- '/cmn/scripting/module-groups',
464
+ const { data: scriptModule } = await this.ApiAdapter.fetch(
465
+ '/cmn/scripting/modules/presettings',
466
+ {
467
+ method: 'POST',
468
+ body: {
469
+ name,
470
+ script: scriptContent,
471
+ domain: 'IMPORT_BATCH_PROCESSING',
472
+ groupRef: { id: scriptGroup.id },
473
+ permissionAggregation: {
474
+ operationForAllUsers: 'READ_AND_EDIT',
475
+ },
476
+ },
477
+ },
478
+ );
479
+
480
+ await this.methods.log(`Script-Module-Presetting "${name}" created (ID: ${scriptModule.id})\n`);
481
+
482
+ scriptModuleRef = { id: scriptModule.id };
483
+
484
+ // Migrate existing inline script as user script on the new module
485
+ if (existingInlineScript)
486
+ {
487
+ const inlineScriptContent = typeof existingInlineScript === 'string'
488
+ ? existingInlineScript
489
+ : JSON.stringify(existingInlineScript);
490
+
491
+ const { data: createdModule } = await this.ApiAdapter.fetch(
492
+ `/cmn/scripting/modules/${scriptModule.id}`,
493
+ { method: 'GET' },
494
+ );
495
+
496
+ await this.ApiAdapter.fetch(
497
+ `/cmn/scripting/modules/${scriptModule.id}`,
498
+ {
499
+ method: 'PUT',
500
+ body: {
501
+ ...createdModule,
502
+ script: inlineScriptContent,
503
+ },
504
+ },
505
+ );
506
+
507
+ await this.methods.log(`Migrated existing inline script for "${name}" to script module\n`);
508
+ }
509
+ }
510
+
511
+ const existingProxyId = await this.methods.getAppScriptingTriggerId(name);
512
+
513
+ if (!existingProxyId)
514
+ {
515
+ await this.ApiAdapter.fetch(
516
+ `/community/${this.app.version}/cmn/system/app-scripting-proxy`,
389
517
  {
390
518
  method: 'POST',
391
- body: { name: this.app.client.appIdentifier },
519
+ body: {
520
+ appIdentifier: this.app.client.appIdentifier,
521
+ triggerId: name,
522
+ scriptModuleRef,
523
+ },
392
524
  },
393
525
  );
394
- scriptGroup = newGroup;
526
+
527
+ await this.methods.log(`App-Script-Proxy for "${name}" successfully created\n`);
528
+ }
529
+
530
+ return scriptModuleRef;
531
+ },
532
+
533
+ addAppScriptingTrigger: async (triggerId, script) =>
534
+ {
535
+ const existingProxyId = await this.methods.getAppScriptingTriggerId(triggerId);
536
+
537
+ if (existingProxyId)
538
+ {
539
+ await this.methods.updateAppScriptingTrigger(triggerId, script, existingProxyId);
540
+
541
+ return;
395
542
  }
396
543
 
544
+ const scriptGroup = await this.methods.getOrCreateScriptModuleGroup();
545
+
397
546
  const { data: scriptModule } = await this.ApiAdapter.fetch(
398
547
  '/cmn/scripting/modules/presettings',
399
548
  {