Typescript Here Maps for Javascript in PCF

I want to integrate Here Maps for Javascript in PowerApps Code Component which is written in typescript.

I am getting __webpack_require__is not defined error. Because PCF have their own webpack, I added a webpack script and add “bundle”: “webpack” to my package.json.

I am lost at what I should be doing to fix this.

My current output on the web

index.ts

import { IInputs, IOutputs } from "./generated/ManifestTypes";
import "@here/maps-api-for-javascript";

export class heremaps
  implements ComponentFramework.StandardControl<IInputs, IOutputs>
{
  private _container: HTMLDivElement;
  private _map: H.Map | null = null;

  // Hardcoded API key
  private readonly API_KEY: string =
    "api_key"; 

  constructor() {}

  /**
   * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to property names defined in the manifest, as well as utility functions.
   * @param notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously.
   * @param state A piece of data that persists in one session for a single user. Can be set at any point in a controls life cycle by calling 'setControlState' in the Mode interface.
   * @param container If a control is marked control-type='standard', it will receive an empty div element within which it can render its content.
   */

  public init(
    context: ComponentFramework.Context<IInputs>,
    notifyOutputChanged: () => void,
    state: ComponentFramework.Dictionary,
    container: HTMLDivElement
  ): void {
    // Create or reuse the container for the map

    if (!this._container) {
      this._container = document.createElement("div");
      this._container.id = "map";
      this._container.style.width = "100%";
      this._container.style.height = "100%";
      container.appendChild(this._container);
    } else {
      // Clear the container's content to avoid reusing the same element
      this._container.innerHTML = "";
    }

    // Dispose of any existing map instance to prevent "already in use" errors
    if (this._map) {
      this._map.dispose();
      this._map = null;
    }

    // Initialize the map
    this.initializeMap();
  }

  private initializeMap(): void {
    // Initialize communication with the platform
    const platform = new H.service.Platform({
      apikey: this.API_KEY,
    });

    // Create the map instance
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const defaultLayers: any = platform.createDefaultLayers();
    this._map = new H.Map(this._container, defaultLayers.vector.normal.map, {
      center: { lat: 52, lng: 5 },
      zoom: 5,
      pixelRatio: 2,
    });

    // Add a resize listener to ensure the map occupies the whole container
    window.addEventListener("resize", () => this._map?.getViewPort().resize());

    // Make the map interactive
    const behavior = new H.mapevents.Behavior(
      new H.mapevents.MapEvents(this._map)
    );
    const ui = H.ui.UI.createDefault(this._map, defaultLayers);

    // Add the polyline
    this.addPolylineToMap();
  }

  private addPolylineToMap(): void {
    const lineString = new H.geo.LineString();
    lineString.pushPoint({ lat: 53.3477, lng: -6.2597 }); // Dublin
    lineString.pushPoint({ lat: 51.5008, lng: -0.1224 }); // London
    lineString.pushPoint({ lat: 48.8567, lng: 2.3508 }); // Paris
    lineString.pushPoint({ lat: 52.5166, lng: 13.3833 }); // Berlin

    this._map?.addObject(new H.map.Polyline(lineString));
  }

  public updateView(context: ComponentFramework.Context<IInputs>): void {
    // Handle updates if needed, but avoid re-initializing the map
  }

  public getOutputs(): IOutputs {
    return {};
  }

  public destroy(): void {
    // Cleanup map instance
    if (this._map) {
      this._map.dispose();
      this._map = null;
    }
  }
}

webpack.config.js

import { resolve as _resolve } from "path";
import { fileURLToPath } from "url";
import { dirname } from "path";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

export const entry = "./index.ts";
export const module = {
  rules: [
    {
      test: /.tsx?$/,
      use: "ts-loader",
      exclude: /node_modules/,
    },
  ],
};
export const resolve = {
  extensions: [".tsx", ".ts", ".js"],
};
export const output = {
  filename: "index.ts",
  path: _resolve(__dirname, "dist"),
};
export const mode = "production";
export const node = {
  global: false,
};
export const performance = {
  maxEntrypointSize: 2048000,
  maxAssetSize: 2048000,
};

pcfconfig.json

{
  "outDir": "./out/controls",
  "build": {
    "production": {
      "webpack": "./webpack.config.js"
    }
  }
}

package.json

{
  "name": "pcf-project",
  "version": "1.0.0",
  "description": "Project containing your PowerApps Component Framework (PCF) control.",
  "scripts": {
    "build": "pcf-scripts build",
    "clean": "pcf-scripts clean",
    "lint": "pcf-scripts lint",
    "lint:fix": "pcf-scripts lint fix",
    "rebuild": "pcf-scripts rebuild",
    "start": "pcf-scripts start",
    "start:watch": "pcf-scripts start watch",
    "refreshTypes": "pcf-scripts refreshTypes",
    "bundle": "webpack",
    "type": "module"
  },
  "dependencies": {
    "@here/maps-api-for-javascript": "^1.57.0",
    "@microsoft/eslint-plugin-power-apps": "^0.2.33",
    "@types/node": "^18.19.31",
    "@types/powerapps-component-framework": "^1.3.11",
    "@typescript-eslint/eslint-plugin": "^7.7.1",
    "@typescript-eslint/parser": "^7.7.1",
    "eslint": "^8.57.0",
    "eslint-plugin-import": "^2.29.1",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^6.1.1",
    "ts-loader": "^9.5.1",
    "webpack": "^5.94.0",
    "webpack-cli": "^5.1.4"
  },
  "devDependencies": {
    "@here/maps-api-for-javascript": "^1.57.0",
    "@microsoft/eslint-plugin-power-apps": "^0.2.33",
    "@types/node": "^18.19.31",
    "@types/powerapps-component-framework": "^1.3.11",
    "@typescript-eslint/eslint-plugin": "^7.7.1",
    "@typescript-eslint/parser": "^7.7.1",
    "eslint": "^8.57.0",
    "eslint-plugin-import": "^2.29.1",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^6.1.1",
    "pcf-scripts": "^1",
    "pcf-start": "^1",
    "ts-loader": "^9.5.1",
    "typescript": "^4.9.5",
    "webpack": "^5.94.0",
    "webpack-cli": "^5.1.4"
  }
}

Unable to pan a nested ReactFlow editor

I am trying to nest a ReactFlow (RF) pane within a node of a parent RF container. So far, I am able to control the inner RF as an independent editor – I can zoom, drag its nodes, and form edges. One thing I cannot seem to resolve is panning the inner RF pane with the default mouse click and drag. I have tried recommended solutions such as stopping the parent’s event propagation to switching the panning control scheme (i.e. Space+drag to pan), to no avail.
Is there something I am missing?

My codesandbox for a minimally reproducible example.

Targeting child nodes of a query selector all loop

I have a series of repeating HTML blocks on a page (over 200 times) that need to have some content tweaks made via some simple javascript. What I’ve done is use querySelectorAll to target all of the parent HTML elements and then when performing a loop of all of the HTML blocks on the page with this selector, I’ve used nested childNodes[x] to target the element of each block and to search for the letters ‘HD’ inside, before running an IF statement and subsequent content changes (in this case, adding some simple text to each block).

The problem which I face is that the same code block/function will need to be called multiple times, depending on various user functions within the page and the script breaks because after the script has run for the first time, it adds HTML into each code block and upsets the ordering of the childNodes.

Ideally, I would be able to select the child node within the loop of the parent selector by referencing the HTML tag (which would be ) or the class name that it carries. This way, I wouldn’t have to worry about childNodes ordering being disturbed.

Here is a trimmed example of the HTML block that repeats on the page:

<vm-tile-media-small class="tile">
  <div class="tile-media-small">
    <div class="tile-media-small__">
      <img src="channel_img.png" alt="channel 1 HD">
    </div>
    <h5 class="ng-star-inserted">channel 1 HD</h5>
  </div>
</vm-tile-media-small>

Here is my script which works the first time:

let small_tile = document.querySelectorAll('vm-tile-media-small.tile');
for (let i = 0; i < small_tile.length; i++) {
  small_tile[i].childNodes[1].childNodes[2].innerText;
  let hd_text = 'HD';
  if (small_tile[i].textContent.includes(hd_text)) {
    small_tile[i].classList.add('HD_channel');
    let HD_banner = document.createElement('div');
    HD_banner.className = 'HD_banner';
    HD_banner.innerHTML = '<p>HIGH DEFINITION</p>';
    small_tile[i].prepend(HD_banner);
  } // ends IF
} // ends loop

Here is how the HTML outputs after the script is run:

<vm-tile-media-small class="tile">
  <div class="HD_banner">
    <p>HIGH DEFINITION</p>
  </div>
  <div class="tile-media-small">
    <div class="tile-media-small__">
      <img src="channel_img.png" alt="channel 1 HD">
    </div>
    <h5 class="ng-star-inserted">channel 1 HD</h5>
  </div>
</vm-tile-media-small>

For what it’s worth, I did consider performing the querySelectorAll on the , but then I’d still have to do some trickery with the script to add my new HTML mark up to the parent of this element instead.

htmx abort event not working in htmx logger

I’m coding a chat app, i’m trying to abort requesting a chat if the requested chat id is already displayed (to prevent unnecesary requests) with this code:

    htmx.logger = async function(elt, event, data) {
        // cancel the request if the requested chats is already displayed.
        if(event === 'htmx:beforeRequest' && data.pathInfo.requestPath.includes('display_chat')){
            console.log('Logger called:', event, data);
            const displayed_chat =  document.getElementById('displayed-chat-info')
            if(displayed_chat){
                const url_params = data.pathInfo.requestPath.split('/')
                const chat_id = displayed_chat.dataset.displayedChat
                // if the id of the displayed chat is the same as requested chat id
                // abort the request
                if(chat_id === url_params[url_params.length - 1]){
                    data.xhr.abort()
                    htmx.trigger(elt, 'htmx:abort')
                }
            }
        }
    }
htmx.logger()

The problem there is that I’ve debugged all the things and everything is “fine” except by the fact that htmx:abort isn’t aborting the request.
I checked if the htmx:abort event was triggered in the first place and it is, I also checked if the html element (elt) getting the abort event was the same that issued the beforeRequest and it is, I don’t know what’s happening, I’ve checked the documentation and my code should work because it’s said that “This event is triggered before an AJAX request is issued. If the event is cancelled, no request will occur.”

Remember that ‘event’ in the htmx logger is a String and not an actual event, so I can’t use event.preventDefault() here.

Child Component Not rendering in React

I’m trying to make a CV generator, and the input fields in the child component aren’t rendering.

The Parent Component:

import React, { useState } from 'react';

import WorkForm from './WorkForm';


export default function Work(){
    const [exp, setExp] = useState({
        jobArr : 
            [{company: "",
            startDate: "",
            endDate: "",
            description: "",
            id: Math.floor(Math.random() * 100)}],
        editMode: true,
})
    
      const handleSubmit = (e) => {
        e.preventDefault();
    
        setExp({ ...exp, editMode: false });
      };
      const handleEdit = (e) => {
        setExp({ ...exp, editMode: true });
      };

      const handleChange = (e) => {
        const {name, value, id} = e.target
        setExp((
            {editMode : true,
            jobArr : exp.jobArr.map(job =>{
            return job.id === id ? {...job, [name] : value} : job ;
            }) 
            }
        ))
      }

      const handleAdd = () => {
        setExp({editMode : true,
            jobArr : exp.jobArr.concat({company: "",
                startDate: "",
                endDate: "",
                description: "",
                id:Math.floor(Math.random() * 100)}),
      })
      };

      const handleDelete = (e) =>{
        const { id } = e.target
        setExp({
            editMode : true,
            jobArr: exp.jobArr.filter(job => job.id !== id )
        })
      }
    const editButton = <button onClick={handleEdit} className="edit-button">EDIT</button>;
    const submitButton = <button onClick={handleSubmit} className="submit-button">SUBMIT</button>;
    const addNewButton = <button onClick={handleAdd} className="add-new-button">ADD NEW</button>;

    const editContent = (
        <div className='edit-experience'>

            {exp.jobArr.map(job => {
                return <WorkForm 
                    handleChange = {handleChange}
                    handleDelete = {handleDelete}
                    company = {exp.company}
                    startDate = {exp.startDate}
                    endDate = {exp.startDate}
                    description = {exp.description}
                    id = {exp.id}
                    key = {exp.id}
                />
                })}
            {submitButton}
        </div>
    )

    const submittedContent = (
        <div>
            <h2>Work Experience</h2>
            {exp.jobArr.map(job => {
                return <div key = {job.id}>
                <h4>{job.company.toUpperCase()} </h4> <p> {job.startDate} to {job.endDate}</p>
                <p>{job.description}</p>
                </div>
            })}
        </div>
    )

    return(
        <>
            {!exp.editMode && editButton}
            {exp.editMode ? editContent : submittedContent}
            {exp.editMode && addNewButton}
        </>
    )
}

The Child Component :

import React, { useState } from 'react';


export default function WorkForm(props){
    <div>
            <form onSubmit={props.handleSubmit}>
                <input 
                    name = "company"
                    type = "text"
                    value = {props.company}
                    placeholder = "Enter Company Name"
                    onChange={props.handleChange}
                    id = {props.id} 
                />
                <br/>
                <input 
                    name = "startDate"
                    type = "month"
                    value = {props.startDate}
                    placeholder = "Enter Starting Date"
                    onChange={props.handleChange}
                    id = {props.id}
                />
                <input 
                    name = "endDate"
                    type = "month"
                    value = {props.endDate}
                    placeholder = "Enter Ending Date"
                    onChange={props.handleChange}
                    id = {props.id}
                />
                <br/>
                <textarea 
                    name="description" 
                    rows="4" 
                    cols="50"
                    value = {props.description}
                    placeholder= 'Describe your work experience'
                    onChange={props.handleChange}
                    id = {props.id}
                >
                </textarea>
                <br/><br/>
                <button onClick = {props.handle} className="delete-button">DELETE</button>
            </form>
        </div>
}

I’m not sure where I’m going wrong. I’m using Math.random to generate ID and using that as the keys for the list of children components, is that where I’m going wrong?

Wierd javascript behaviour about connecting string [closed]

I am a starter javascript hobbyist and I am confused about connecting strings.

I tried

const html = `<p>Hello World!</p>`;
console.log( "response.end(`" + html + "`);");

and expected response.end(`<p>Hello World!</p>`)
but received response.end(`<p>Hello World!</p>`;}.
I am really confused. I thought this might be to do with escaping characters.

Edit:
Full code
var staffcontent = fs.readFileSync(path.join(__dirname, "/assets/staff.html"), 'utf8'); console.log("response.end(`" + staffcontent + "`);"); eval("response.end(`" + staffcontent + "`);");

The first time a div slides down the child elements it contains appear first JQuery

I am making a website with JQuery, and I want a signup bar to slide down when I click a button. For some reason, when I first click it, the signup form appears before the div containing it slides down. The div contains the background color, so it is a very noticeable difference. I am using the following code to make the form slide up first and down last.

            if (signupBarDown) {
                $signup.slideUp();
                $login.slideUp();
            }

            $signupOrLoginDiv.slideToggle(400);

            if (!signupBarDown) {
                $signup.slideDown();
                $login.slideDown();
            }

            signupBarDown = !signupBarDown;

As I said before this works perfectly if its not the first time sliding down/up
I have no idea why this happens.

The forms are absolutely positioned which forced me to right this code to begin with, but I don’t know why that would stop it from working the first time. signupBarDown also starts as false.

I tried changing the positioning to fixed, because positioning it absolutely changed the effects of the script before, but it is still the same.

React How to get all free available plugins and tools for CKEditor, similar to Django

In my Django backend, I have all available CKEditor tools and plugins, but in React, I have very few plugins available. See the two screenshots

django screenshot
enter image description here

react screenshot
enter image description here

Why am I not getting all the tools and plugins like I have in Django in my React app?

my react config:

import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
function CreateBlog() {
   
      upload() {
        return this.loader.file.then((file) =>
          new Promise((resolve, reject) => {
            const formData = new FormData();
            formData.append('upload', file);
    
            handleAxois(`${domain}/ckeditor/upload/`, 'post', formData, {
              headers: {
                'Content-Type': 'multipart/form-data'
              }
            })
              .then((res) => {
                console.log(res.data); // Debugging: Check the response to ensure the full URL
                resolve({
                  default: `${domain}${res.data.url}`  // Use the full URL returned from the server
                });
              })
              .catch((err) => {
                reject(err);
              });
          })
        );
      }
    
      abort() {}
    }



  return (
    <> <CKEditor
                          editor={ClassicEditor}
                          data={subtitle.description}
                          onChange={(event, editor) => {
                            const data = editor.getData();
                            handleSubtitleChange(index, subtitleIndex, 'description', data);
                          }}
                          config={{
                            extraPlugins: [CustomUploadAdapterPlugin],
                            mediaEmbed: {
                              previewsInData: true
                            },
                            filebrowserUploadUrl: '/ckeditor/upload/',
                            filebrowserImageUploadUrl: '/ckeditor/upload/',
                            height: 500,
                          }}
                        />
</>
}

Keyboard-Shortcut to Open Safari Web Extension Popup

Is it possible to open a Safari WEB Extension popup through a command or keyboard shortcut?

I have a Safari Web Extension whose popup I want to access quickly through a Command or Keyboard Shortcut. I don’t care if the configuration for this is inside or outside the extension’s code.

The main problem I have is that, since this is a Safari WEB Extension (not App), it’s more difficult to interact with Safari functionalities.

From what I could find, there’s no built-in way to do it, but a workaround could be to add an event listener in content.js and then send a message to SafariWebExtensionHandler through browser.runtime.sendNativeMessage inside background.js to open the popup. I couldn’t find anything on how to do the latter.

content.js

document.addEventListener('keydown', function(event) {
    // Check if the Control key is pressed
    if (event.ctrlKey) {
        console.log('Control key pressed!');
        browser.runtime.sendMessage("open").then((response) => {
            console.log("Received response: ", response);
        });
    }
});

background.js

browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
    browser.runtime.sendNativeMessage(
      "com.owner.MyExtension",
      "open"
      )
    .then((response) => {
        sendResponse(response.echo);
    });
});

SafariWebExtensionHandler.swift

class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {

    func beginRequest(with context: NSExtensionContext) {
        ...
        // YOUR CODE
        ...
    }    
}

What I’ve tried:

WooCommerce Swiper in AJAX Mini-Cart

I’m trying to create a slider inside the mini cart containing product’s cross sales. For example, product A has cross sale items 1, 2 and 3. Product B has cross sale items 4, 5 and 6, so when you add product A to the cart, inside your mini cart you should see a slider containing products 1, 2 and 3. When you also add product B, you should see a slider containing products 1 to 6. And if you remove product A, the slider should display only products 4, 5 and 6. Now the problem I’m facing is that I can’t init the Swiper.. In my app.js I have the basic swiper init:

const miniCartSwiper = new Swiper('.mini-cart-slider', {
  direction: 'horizontal',
  loop: true,
  slidesPerView: 1,
  spaceBetween: 0,
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  }
});

In my PHP I have a basic foreach with the products. The problem is that when I try to console log my .mini-cart-slider, the length is always 0 and JS doesn’t find that element, even though is there. I suspect that is because is added after a product is added to the cart. So how should I init my Swiper? And how should I handle the changes in the slides? I should reInit it on every change on the mini cart..

Clicking a button to populate a div with value, and then use this value for an onclick function – Javascript

I have a text box here which when I click into it and press a letter, it populates with that letter. Then I click a button (Go) which takes the letter I have entered and runs a JavaScript function that works. This is the code:

<div id="enterlettertext">
  Enter the letter:&nbsp;
  <input type="text" id="myletterInput" name="myletterInput" />
</div>
<input type="button" id="wadgo" value="Go" 
   onclick="QuizAnswer(document.getElementById('myletterInput').value)">

Rather than clicking into the text box to enter a letter, I want to build an onscreen keyboard where the user presses the button representing the letter and this letter populates the text box. The user would then click ‘Go’ to run the function.

I built the following as the keyboard:

<button class="fiveninebutton" onclick="setLetter('q');">Q</button>
<button class="fiveninebutton" onclick="setLetter('w');">W</button>
<button class="fiveninebutton" onclick="setLetter('e');">E</button>
<button class="fiveninebutton" onclick="setLetter('r');">R</button>

And have this code:

function setLetter(letter) {
  document.getElementById('myletterInput').innerHTML =    
  document.getElementById('myletterInput').innerHTML + letter;
}

When I click the letter button, nothing happens. However, if I change:

<input type="text" id="myletterInput" name="myletterInput" /> 

to:

<div id="myletterInput" name="myletterInput"></div>

the letter is populated in the div just as I want it to – but the ‘go’ button function no longer works.

How do I get the letter to populate the div and then the other function which uses this button to work?

How to simply send an mp3 from current directory to user? JavaScript/Flask

I have this flask backend, which in the future will generate mp3 files dynamically upon user request but for now it’s just a way to route functions.

The problem I am facing is that when the user goes to the frontend there is a button they click for download, this works and it does correctly download the file. But when it downloads it converts the file for some reason to mp4 format and the audio quality is terrible (like low and compressed sounding). I am wondering if this is some browser issue or something else. Id like to know why the frontend converts it to mp4 and why the audio quality is bad.

Here is my flask backend code

from flask import Flask, send_file, render_template
import os

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/run-python', methods=['GET'])
def run_python():
    # Define the file path
    file_path = os.path.join('static', 'test_file.mp3')
    
    # Check if the file exists
    if os.path.exists(file_path):
        # Send the file
        return send_file(file_path, as_attachment=True, mimetype='audio/mpeg', download_name='test_file.mp3')
    else:
        return "File not found", 404

if __name__ == '__main__':
    app.run(debug=True)

And here is my index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Run Python Example</title>
    </head>
    <body>
        <h1>Run Python Code</h1>
        <button id="runPythonButton">Download File</button>

        <script>
            document.getElementById('runPythonButton').addEventListener('click', function() {
                // Open the file in a new tab or prompt the download
                window.location.href = '/run-python';
            });
        </script>
    </body>
    </html>

And I have the mp3 in static/test_file.mp3

When I play the song here it sounds perfect, but once it gets downloaded through the frontend it that files sound quality is poor.

Thanks

Tried multiple files and same error

Error setting an response: ERR_HTTP_HEADERS_SENT

I’m new programming in node.js. I’m doing an app to pull code from Github, etc.
I just check if some variable is set in query param (URL), like localhost:3000/gitservices/gitpull?development.

I’m in a piece of code where i’m doing the git pull. If the path passed by URL exists, then redirect to the success page. If the query param passed by url does not exists, It will “throw” an error, handled by a middleware.

But even passing a res.render, for example, the code continues and my line of code responsable to redirect to the error page (handled by the middleware) throws this error:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

    environments = require('../config/paths').env;
    const { exec } = require("child_process");

    //Controller to do git pull
    exports.gitPull = (req, res, next) => {
        //query param (example: localhost/gitservices/gitpull?development
        const env = req.query.env;
        //checking if the query param matches with an array defined in config file. 
        //Ex. ([{name: development, path: '/var/www/development'}])
        environments.map(e => {
            if (e.name == env) {
                //doing the command
                let command = "cd " + e.path + " && git pull origin main";
                exec(command, (err, stdout, stderr) => {
                //redirecting to the success page
                    res.status(200).render('success', {
                        pageTitle: 'Success',
                        result: stdout
                    });
                });            
            }
        });
    //if none path is equal to query param, return an error.
        next(new Error('Ambiente ' + env + ' errado'));
    };

AWS Role Assume Role Temporary Access with JavaScript for backend

In the past I open an minio client inside my JavaScript app with a technical user to access S3. This was working very good. Now I want ot make the app more secure. My app is running inside a ECS Cluster on a Fargate service/task.

I have a task role with “S3 Full Access” that was given to the Bucket with s3Bucket.grantReadWrite(props.role);

I assume that the task role with S3 Full Access can access the bucket without accesskey and secretkey from technical user.
I try to use the function “AsumeRoleProvider”. But iam confused how to get the webidentityToken and why the function also request an accesskey and secretkey?

My task role has the sts:AssumeRole in Trusted entities

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ecs-tasks.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

The attached image to try to use currently.Function I use currently

I think the appoach to access S3 from ECS task is wrong. Anybody has an hint ot a weblink where I can see how this have to work?