Modeler Plugin: How to save custom data to the filesystem?

Hello everyone,

I am using Platform 7, i believe.
I’m trying to write some data that I extract from the model into a new file in the users filesystem.
To archive this I’m trying to utilize the JS File System Access API through

window.showSaveFilePicker();

However, when im trying to write to the file I get an error:

NotAllowedError The request is not allowed by the user agent or the platform in the current context.

Is the filesystem restricted?

Somehow the Modeler seems to be able to save .bpmn files.
I tried to use app._getGlobal(“fileSystem”) to write to a file. (https://github.com/camunda/camunda-modeler/blob/develop/app/lib/file-system.js)

I can at least read some files:

var t = this.fileSystem.readFile("VERSION"); // this reads out the contents of the VERSION File.

Writing however results in an error:

"The \"data\" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined"

You can find my plugin here: GitHub - ciphersmaug/camunda_save_plugin
This is the code I wrote:

import React, { Fragment, PureComponent } from 'camunda-modeler-plugin-helpers/react';
import { Fill } from 'camunda-modeler-plugin-helpers/components';
import classNames from 'classnames';
export default class SavePlugin extends PureComponent {
  constructor(app) {
    super();
    this.app = app;
    this.fileSystem = this.app._getGlobal("fileSystem");
    this._buttonRef = React.createRef();
  }

  async saveFileThroughFilePicker(){
    try {
      const handle = await window.showSaveFilePicker({
        suggestedName:"New_save_file.json",
        types: [{
          description: '.json',
          accept: {'application/json': ['.json']},
        }],
      });
      const file = await handle.getFile();
      const contents = await file.text();
      // Write to the file.
      const writable = await handle.createWritable();
      await writable.write("Hello World");
      await writable.close();
      return;
    } catch (err) {
      if (err.name !== 'AbortError') {
        console.error(err.name, err.message);
        debugger;
        return;
      }
    }

  }

  async saveFile(){
    // Test if the fileSystem seems to work at all...
    var t = this.fileSystem.readFile("VERSION");
    t.then((value) => {
      console.log(value); // this Works, I seem to be able to read files.
    });

    var w = this.fileSystem.writeFile("./testfile.txt","MYTESTFILE"); // this seems to throw the error in question.
    w.then((value)=>{
      debugger;
    }).catch((err) => {
      console.log(err);
      debugger;
    })
  }
  // Attempt of using the FileSystem from the camunda modeler App.
  // Doesn't seem to work.
  async saveFile2(){
    var buf = Buffer.from("Test 12345","utf-8")
    this.fileSystem.writeFile("~/TextFile.txt",buf.buffer,{encoding:"utf8",filetype:".json"});
    debugger;
  }

  render() {
    return <Fragment>
      <Fill slot="status-bar__app" group="1_save">
        <button
          ref={ this._buttonRef }
          className={ classNames('btn') }
          onClick={ () =>  this.saveFile()}>
          Save as ... 
        </button>
      </Fill>
    </Fragment>;
  }
}

SavePlugin.$inject = [
  'app'
];

How can I archive writing to the filesystem of the user from within a camunda modeler plug-in?
I would appreciate any kind of help and look forward to hearing from you.

Best, ciph

Hi, even though the FileSystemApi seems to be disabled you can still trigger a file-download in the modeler.

This can work like this:

saveFile(){
    var o = {Hello: "World"}
    var json_string = JSON.stringify(o, undefined, 2);
    var link = document.createElement('a');
    link.download = 'data.json';
    var blob = new Blob([json_string], {type: 'text/plain'});
    link.href = window.URL.createObjectURL(blob);
    link.click();
  }