Flask appears to automatically add a nonce to my CSP directives. Can this be disabled?

Goal:

From a Flask server, I wish to use the url_for() function inside javascript files to calculate the proper URL.

Problem:

Flask.render_template() only touches the HTML template file, so Flask recommends you use inline <script> blocks (Flask Render Template Documenation) and call url_for() to save a script base variable which you can then access in other pure javascript modules that aren’t processed by render_template().

Unfortunately, without CSP enabled, modern browsers will completely ignore inline <script> tags. It is therefore necessary to create a Content Security Profile, which I did as follows, trying to make the most permissive policy ever:

@app.after_request
def add_csp(response):
    response.headers['Content-Security-Policy'] = ("default-src *  data: blob: filesystem: about: "
                    "ws: wss: 'unsafe-inline' 'unsafe-eval' 'unsafe-dynamic'; script-src * "
                    "'unsafe-inline' 'unsafe-eval' 'unsafe-hash'; connect-src * 'unsafe-inline'; "
                    "img-src * data: blob: "'unsafe-inline'; frame-src *; style-src * data: "
                    "blob: 'unsafe-inline';font-src * data: blob: 'unsafe-inline';")
    return response

That should work. I’ve allowed everything. (Everything I can find, anyway) Unfortunately, when running my script, I see this:

Content-Security-Policy: The page’s settings blocked an inline script (script-src-elem) from being executed because it violates the following directive: “script-src * 'unsafe-inline' 'unsafe-eval' 'unsafe-hash' 'nonce-bW96LWV4dGVuc2lvbjovL2E0ZTMxZmFjLTI5NjQtNDUxMC1iNDhjLTExOTYyODdkMWMzZC8='” index.html:14:36

This is the script it is complaining about:

    <script type="text/javascript">
      const GRAY_LIGHT = {{ url_for('static',filename='images/gray.png') }};
      const RED_LIGHT = {{ url_for('static',filename='images/red.png') }};
      console.log("RED_LIGHT = "+RED_LIGHT+", GRAY_LIGHT = "+GRAY_LIGHT);
    </script>

How can something not match * and ‘unsafe inline’? After struggling for many hours, I came upon this page: (Mozilla CSP documentation)

If a directive contains a nonce and unsafe-inline, then the browser ignores unsafe-inline.

Now, since I didn’t add the nonce value that Firefox is complaining about, it seems that Flask must have put it there. But I can find no documentation that describes this behavior, nor how to disable it.

Is anyone familiar with Flask and know how to prevent it from adding a nonce to my CSP?

Or is Flask just no longer compatible with modern browsers? All I really wanted to do was use the url_for() function, and I’ve spent over 2 days trying to make that simple thing happen.

Any advice appreciated. I’ve never dealt with CSP issues before.

Slight curve in text CSS or JS [closed]

Im currently having a hard time developing a designed text element into actual HTML.

enter image description here

I have tried, Arctext.js, Lettering.js, working with SVG paths, etc.

But i didnt even come close to the desired layout.

Does anybody have tips on how to achieve this in html/css/js?

Really appreciated.

I want to use dynamic javascript (innerhtml) in a form to send data via POST to another file

I currently working on a pizza-ordering-website. Right now I’m on the page where you can change the pizzas, change the prices or delete or add toppings. My current problem is the add toppings. I have a dropdown which when the user chooses a topping dynamically add a position for it.

HTML:

<form action="includes/edithandler.inc.php" method="POST" enctype="multipart/form-data">
[...]
<div class="edit-mode" style="display:none;">
  [...]
                                    Neue Beläge hinzufügen:
                                            <select class="belag">
                                                <option value="">-</option>
                                                <?php foreach ($belaege as $belag) { ?>
                                                    <option value="<?php echo htmlspecialchars($belag['ID']); ?>">
                                                        <?php echo htmlspecialchars($belag['Belagbezeichnung']); ?>
                                                    </option>
                                                <?php } ?>
                                            </select>

                                            <div id="selected-belaege-<?php echo $index; ?>"></div>
                                </div>
[...]
</form>

My Javascript:

document.addEventListener("DOMContentLoaded", function () {
            document.querySelectorAll(".belag").forEach(selectElement => {
                selectElement.addEventListener("change", function () {
                    const selectedValue = this.value;
                    const selectedText = this.options[this.selectedIndex].text;
                    const containerId = this.closest("td").querySelector('[id^="selected-belaege"]').id;
                    const selectedContainer = document.getElementById(containerId);


                    if (selectedValue && !selectedContainer.querySelector(`[data-id="${selectedValue}"]`)) {
                        const item = document.createElement("div");
                        item.setAttribute("data-id", selectedValue);
                        item.innerHTML = `<input type="hidden" name="belaege-gewaehlt[]" value="${selectedValue}">
                            <span class="trash-icon"><button type="button" class="remove-belag">&#128465;</button>
                            <span class="trash-icon">&#128465;</span>
                            <span class="belag-text">${selectedText}</span>`;
                        selectedContainer.appendChild(item);


                        item.querySelector(".remove-belag").addEventListener("click", function () {
                            item.remove();
                        });
                    }
                    
                    this.value = ""; // Setzt das Dropdown zurück
                });
            });
        });

The screenshot from my page before submitting:

Screenshot from my browser showing the hidden input

My Output for my POST:

“Array ( [index] => 1 [pizza_name] => Margherita [price] => 11.00 [description] => Ein Klassiker der italienischen Küche! Unsere traditionelle Pizza Margherita überzeugt mit einem knusprig-dünnen Boden, fruchtiger Tomatensauce aus sonnengereiften Tomaten, zart schmelzendem Mozzarella und frischem Basilikum. Verfeinert mit einem Hauch von nativem Olivenöl extra – einfach köstlich! )”

The “belaege-gewaehlt[]” from innerHTML are completely ignored.

Is my approach completely wrong and this combination “JS with POST” simply doesn’t work?

I tried changing “belaege-gewaehlt[]” to “belaege-gewaehlt” also doesn’t show up in the POST.

How to Automatically Detect User’s Language in Botpress WebChat Before Initialization?

I am integrating Botpress WebChat on our WordPress site and want to automatically detect the user’s language based on the website’s attribute.

What I Have Tried So Far:

  1. Passed Language Directly in init()
    I attempted to detect the language using JavaScript before calling init()
let siteLang = document.documentElement.lang || "en";
siteLang = siteLang.split("-")[0];

window.botpressWebChat.init({
    "botId": "XXX",
    "clientId": "XXX",
    "host": "https://cdn.botpress.cloud/webchat",
    "config": {
        "locale": siteLang,
        "extra": { "lang": siteLang },
        "session": { "lang": siteLang }
    }
});

Expected: The chatbot should start in the detected language.

Isue: Botprss WebChat always defaults to (en), even when siteLang is “de”.

  1. Used webchat:onLoad Event (Suggested on Botpress Discord)
    To ensure WebChat was fully ready before setting the language
window.botpressWebChat.onEvent(
    function () {
        console.log("✅ Botpress WebChat Loaded! Detecting language...");

        let selectedLang = document.documentElement.lang.split("-")[0] || "en";

        window.botpressWebChat.init({
            "botId": "xxx",
            "clientId": "xxx",
            "host": "https://cdn.botpress.cloud/webchat",
            "config": {
                "locale": selectedLang,
                "extra": { "lang": selectedLang },
                "session": { "lang": selectedLang }
            }
        });

        console.log("✅ Sent to Botpress:", selectedLang);
    },
    "webchat:onLoad"
);
  1. Passed Language in session.extra Before Initialization
    I attempted to store the language before calling init():
window.botpressWebChat.init({
    "botId": "xxx",
    "clientId": "xxx",
    "host": "https://cdn.botpress.cloud/webchat",
    "config": {
        "session": { "extra": { "lang": document.documentElement.lang.split("-")[0] || "en" } },
        "locale": document.documentElement.lang.split("-")[0] || "en"
    }
});

The chatbot should recognize session.extra.lang and start in the correct language. But id doesn’t.

Questions:

  1. How does Botpress WebChat determine its default language?
  2. What is the correct way to pass the detected language to WebChat so it uses
    it correctly?
  3. Is there a way to update the language dynamically
    after initialization?
  4. Does Botpress require additional configuration
    (e.g., within the Botpress Studio) to recognize session.extra.lang?

Any help or insights would be greatly appreciated!

Check if a DOM Element is ; why can’t I use instanceof HTMLNoScriptElement?

I need to process the DOM children of a container element (to achieve some fancy layout magic) and leave non-rendered elements alone.

I was surprised to find that I can’t use an instanceof HTMLNoScriptElement check for <noscript> elements; which was my go-to solution for <style>, <script>, etc.

const shouldIgnoreElement = (element: Element) =>
  element instanceof HTMLStyleElement ||
  element instanceof HTMLScriptElement ||
  element instanceof HTMLDialogElement ||
  element instanceof HTMLTemplateElement ||
  element.tagName === 'NOSCRIPT'

const shouldProcessElement = (element: Element) => !shouldIgnoreElement(element)
[...root.children].filter(shouldProcessElement).forEach(...)

As you can see I ended up using element.tagName === 'NOSCRIPT' for the check. But I still want to get a deeper understanding of this curious situation. And wonder whether I did something wrong or harbor a misunderstanding.

My research on mdn turned up:

So it seems there simply is no class to represent <noscript> elements.

Why is there no corresponding class?

Is noscript the only HTML element type with this curious gap in the Web API?

AWS elemental media convert service audio and subtitle track missing

async createVideoJob(
    movieId: string,
    mainVideoPath: string,  // HLS Video Input
    audioPaths: any[] = [],
    subtitlePaths: any[] = [],
    outputFileName: string,
    resolution: any
  ): Promise<string> {
    // Verify main video file exists.
    const videoExists = await this.checkFileExists(awsDetail.bucket, mainVideoPath);
    if (!videoExists) throw new Error(`Main video file does not exist: ${mainVideoPath}`);
  
    // Verify audio files.
    for (const audioPath of audioPaths) {
      const audioExists = await this.checkFileExists(awsDetail.bucket, audioPath.file);
      if (!audioExists) throw new Error(`Audio file does not exist: ${audioPath.file}`);
    }
  
    // Verify caption files.
    for (const subtitlePath of subtitlePaths) {
      const captionExists = await this.checkFileExists(awsDetail.bucket, subtitlePath.file);
      if (!captionExists) throw new Error(`Caption file does not exist: ${subtitlePath.file}`);
    }
  
    const outputBasePath = `MOVIEZU/PROCESSED/${outputFileName}`;
    const hlsDestination = `s3://${awsDetail.bucket}/${outputBasePath}/HLS/`;
  
    const { width, height } = resolution;
    const aspectRatio = width / height;
    const presets = [
      { height: 2160, name: "4K", bitrate: 12000000 },
      { height: 1440, name: "2K", bitrate: 8000000 },
      { height: 1080, name: "1080p", bitrate: 6000000 },
      { height: 720, name: "720p", bitrate: 4000000 },
      { height: 480, name: "480p", bitrate: 2500000 },
      { height: 360, name: "360p", bitrate: 1500000 },
      { height: 240, name: "240p", bitrate: 1000000 },
      { height: 144, name: "144p", bitrate: 500000 },
    ].filter(preset => preset.height <= height);
    const resolutions = presets.map(preset => {
      let computedWidth = Math.floor(preset.height * aspectRatio);
      if (computedWidth % 2 !== 0) computedWidth--;
      return { width: computedWidth, height: preset.height, name: preset.name, bitrate: preset.bitrate };
    });
  
    // ---- Audio Setup ----
    const audioSelectors: Record<string, any> = {
      "Audio Selector 1": { DefaultSelection: "DEFAULT" },
    };
    const hlsAudioDescriptions: any[] = [
      {
        AudioSourceName: "Audio Selector 1",
        CodecSettings: {
          Codec: "AAC",
          AacSettings: { Bitrate: 96000, CodingMode: "CODING_MODE_2_0", SampleRate: 48000 },
        },
        StreamName: "Original Audio",
        AudioGroupId: "program_audio",
        LanguageCode: "ENG",
      },
    ];
    let audioInputIndex = 2;
    for (const audioPath of audioPaths) {
      const selectorName = `Audio Selector ${audioInputIndex}`;
      audioSelectors[selectorName] = {
        ExternalAudioFileInput: `s3://${awsDetail.bucket}/${audioPath.file}`,
      };
      hlsAudioDescriptions.push({
        AudioSourceName: selectorName,
        CodecSettings: {
          Codec: "AAC",
          AacSettings: { Bitrate: 96000, CodingMode: "CODING_MODE_2_0", SampleRate: 48000 },
        },
        StreamName: audioPath.name || `Audio ${audioInputIndex}`,
        AudioGroupId: "program_audio",
        LanguageCode: audioPath.language || "ENG",
      });
      audioInputIndex++;
    }
  
    // ---- Video Outputs with Embedded Captions ----
    // Each output rendition includes a CaptionDescription referencing a CaptionSelector defined in Inputs.
    const videoOutputs = resolutions.map(res => ({
      VideoDescription: {
        Width: res.width,
        Height: res.height,
        CodecSettings: {
          Codec: "H_264",
          H264Settings: {
            RateControlMode: "QVBR",
            QualityTuningLevel: "SINGLE_PASS_HQ",
            QvbrSettings: { QvbrQualityLevel: 7 },
            MaxBitrate: res.bitrate,
          },
        },
      },
      AudioDescriptions: hlsAudioDescriptions,
      CaptionDescriptions: subtitlePaths.length
        ? subtitlePaths.map((subtitle, idx) => ({
            // Must match the CaptionSelector name defined in Inputs.
            CaptionSelectorName: `Caption Selector ${idx + 1}`,
            DestinationSettings: {
              // Use EMBEDDED so that captions appear as selectable tracks.
              DestinationType: "EMBEDDED"
            },
            LanguageCode: subtitle.language || "ENG",
            LanguageDescription: subtitle.name || "English",
          }))
        : undefined,
      ContainerSettings: { Container: "M3U8" },
      NameModifier: `/${res.name}`,
    }));
  
    // ---- Job Settings ----
    // Include CaptionSelectors in Inputs so that embedded captions can be processed.
    const jobSettings: JobSettings | any = {
      Inputs: [
        {
          FileInput: `s3://${awsDetail.bucket}/${mainVideoPath}`,
          AudioSelectors: audioSelectors,
          CaptionSelectors: subtitlePaths.length
            ? Object.fromEntries(
                subtitlePaths.map((subtitle, idx) => [
                  `Caption Selector ${idx + 1}`,
                  {
                    // For selectable (embedded) captions, use a supported SourceType (EIA608).
                    SourceSettings: {
                      SourceType: "EIA608",
                      FileSourceSettings: {
                        SourceFile: `s3://${awsDetail.bucket}/${subtitle.file}`,
                      },
                    },
                  },
                ])
              )
            : {},
        },
      ],
      OutputGroups: [
        {
          Name: "HLS Output Group",
          OutputGroupSettings: {
            Type: "HLS_GROUP_SETTINGS",
            HlsGroupSettings: {
              Destination: hlsDestination,
              SegmentLength: 6,
              MinSegmentLength: 6,
              OutputSelection: "MANIFESTS_AND_SEGMENTS",
              AudioGroupId: "program_audio",
              AudioRenditionSets: "program_audio",
              // Enable insertion of closed-caption manifest tags.
              CaptionLanguageSetting: "INSERT",
              // Provide caption language mappings for each caption selector.
              CaptionLanguageMappings: subtitlePaths.length
                ? subtitlePaths.map((subtitle, idx) => ({
                    CaptionSelectorName: `Caption Selector ${idx + 1}`,
                    CustomLanguageCode: subtitle.language || "ENG",
                    LanguageDescription: subtitle.name || "English"
                  }))
                : [],
            } as any,
          },
          Outputs: videoOutputs,
        } as any,
      ],
      TimecodeConfig: { Source: "ZEROBASED" },
    };
  
    const command = new CreateJobCommand({
      Role: awsDetail.mediaConvertRoleArn,
      Settings: jobSettings,
      AccelerationSettings: { Mode: "DISABLED" },
      StatusUpdateInterval: "SECONDS_60",
    });
  
    const movieName = mainVideoPath.split("/").pop()?.replace(/.w+$/, "") || "movie";
    const path = `${outputBasePath}/HLS/${movieName}.m3u8`;
  
    try {
      const data = await this.mediaConvertClient.send(command);
      await MovieZu.findOneAndUpdate(
        { _id: movieId },
        { jobId: data.Job.Id, processedVideoUrl: path },
        { new: true }
      );
      return `${outputBasePath}/`;
    } catch (error) {
      console.error("MediaConvertService error:", error);
      throw new Error("Failed to create video job");
    }
  }

audio and subtitle track are missing on master.m3u8, only HLS video quality track.
Track missing

m3u8 response data

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-STREAM-INF:BANDWIDTH=6908373,AVERAGE-BANDWIDTH=2249342,CODECS="avc1.640028",RESOLUTION=1920x1080,FRAME-RATE=24.000
Fateh.2025.1080p.JHS.WEB.DL.Hindi.DDPA5.1.ESub.x264-Vegamovies.is/1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=4868448,AVERAGE-BANDWIDTH=1105432,CODECS="avc1.64001f",RESOLUTION=1280x720,FRAME-RATE=24.000
Fateh.2025.1080p.JHS.WEB.DL.Hindi.DDPA5.1.ESub.x264-Vegamovies.is/720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=3016272,AVERAGE-BANDWIDTH=665885,CODECS="avc1.64001e",RESOLUTION=852x480,FRAME-RATE=24.000
Fateh.2025.1080p.JHS.WEB.DL.Hindi.DDPA5.1.ESub.x264-Vegamovies.is/480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1825354,AVERAGE-BANDWIDTH=415826,CODECS="avc1.64001e",RESOLUTION=640x360,FRAME-RATE=24.000
Fateh.2025.1080p.JHS.WEB.DL.Hindi.DDPA5.1.ESub.x264-Vegamovies.is/360p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1116720,AVERAGE-BANDWIDTH=254112,CODECS="avc1.640015",RESOLUTION=426x240,FRAME-RATE=24.000
Fateh.2025.1080p.JHS.WEB.DL.Hindi.DDPA5.1.ESub.x264-Vegamovies.is/240p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=506848,AVERAGE-BANDWIDTH=130283,CODECS="avc1.64000c",RESOLUTION=256x144,FRAME-RATE=24.000
Fateh.2025.1080p.JHS.WEB.DL.Hindi.DDPA5.1.ESub.x264-Vegamovies.is/144p.m3u8

When working with AWS Elemental MediaConvert to transcode media files using Node.js, a common issue developers face is that audio tracks or subtitle tracks are missing in the output files. This note aims to explain why this happens and how to properly configure your Node.js MediaConvert job to include audio and subtitle tracks.

When in development mode, unable to GET bundle.js file, fails with 404 Not Found

While trying to run the application locally, browser is not able to load bundle.js
enter image description here

This is the setup to load up bundle.js inside index.html

<script type="text/javascript" src="/static/js/bundle.js"></script>

But when hitting directly to this request URL: http://localhost:3000/static/js/bundle.js, bundled js code is visible
enter image description here

If webpack failed to generate the bundle.js file then this should also fail I assume. I can also see this assets report
enter image description here

Below is my output config inside webpack.config

 output: {
    pathinfo: true,
    filename: 'static/js/bundle.js',
    chunkFilename: 'static/js/[name].chunk.js',
    publicPath: "/",
    devtoolModuleFilenameTemplate: (info) => path.resolve(info.absoluteResourcePath).replace(/\/g, '/'),
  },

This is how I server static files using Express

  app.use(favicon(path.join(__dirname, '../build', 'favicon.ico')));
  app.use('/static', express.static(path.join(__dirname, '../build/static/'), { maxAge: '30d' }));

My build folder structure is:

-build
--static
---css
----main.123sf.css
---js
----main.123124.js
----main.123124.js.LICENSE.txt
---media
----mygif.gif
--favicon.ico
--index.html
--login.html

When in development mode, I believe if everything goes well bundle.js can be located at below structure inside Sources.

-top
--localhost:3000
---static/js
----bundle.js

this are the package versions I am using currently using

"express": "^4.21.2",
"webpack": "^5.96.1",
"webpack-dev-server": "^4.15.2",

what am I doing wrong here? Any help is appreciated, thanks in advance.

How to implemet slide search with Ivory Search in WordPress?

I am using the Ivory Search plugin on my WordPress site, and I would like to implement a “slide search” feature.

Currently, the whole search form is showing (search bar and search icon). I want the search icon to be visible only at first. When the user clicks the search icon, I want the search bar to appear by sliding out to the left (as the search icon is placed to the right). I also want to make sure that when the user first clicks the search icon, it shows the search bar and doesn’t toggle the search functionality (I want it to search a term on second click).

I haven’t written any custom code yet, but I am open to using JavaScript, CSS, or PHP if necessary. Could someone guide me on how to achieve this?

<div class="ast-search-menu-icon slide-search">
        <form class="is-search-form is-form-style is-form-style-3 is-form-id-9231 " action="https://embroidla.com/" method="get" role="search"><label for="is-search-input-9231"><span class="is-screen-reader-text">Search for:</span><input type="search" id="is-search-input-9231" name="s" value="" class="is-search-input" placeholder="Search..." autocomplete="off"></label><button type="submit" class="is-search-submit"><span class="is-screen-reader-text">Search Button</span><span class="is-search-icon"><svg focusable="false" aria-label="Search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24px"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></svg></span></button></form>         <div class="ast-search-icon">
                <a class="slide-search astra-search-icon" aria-label="Search icon link" href="#">
                    <span class="screen-reader-text">Search</span>
                    <span class="ast-icon icon-search"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="-893 477 142 142" enable-background="new -888 480 142 142" xml:space="preserve">
                          <path d="M-787.4,568.7h-6.3l-2.4-2.4c7.9-8.7,12.6-20.5,12.6-33.1c0-28.4-22.9-51.3-51.3-51.3  c-28.4,0-51.3,22.9-51.3,51.3c0,28.4,22.9,51.3,51.3,51.3c12.6,0,24.4-4.7,33.1-12.6l2.4,2.4v6.3l39.4,39.4l11.8-11.8L-787.4,568.7  L-787.4,568.7z M-834.7,568.7c-19.7,0-35.5-15.8-35.5-35.5c0-19.7,15.8-35.5,35.5-35.5c19.7,0,35.5,15.8,35.5,35.5  C-799.3,553-815,568.7-834.7,568.7L-834.7,568.7z"></path>
                          </svg></span>             </a>
            </div>
        </div>

Rollup Package Error: TypeError: Unable to determine current node version

I have built an npm package using Rollup, but after publishing and installing it in another project, I get the following error when running the project:

TypeError: Unable to determine current node version

My Rollup Configuration:
Here is my rollup.config.js:

import babel from "@rollup/plugin-babel";
import commonjs from "@rollup/plugin-commonjs";
import json from "@rollup/plugin-json";
import resolve from "@rollup/plugin-node-resolve";
import typescript from "@rollup/plugin-typescript";
import url from "@rollup/plugin-url";
import svgr from "@svgr/rollup";
import jsx from "acorn-jsx";
import dts from "rollup-plugin-dts";
import peerDepsExternal from "rollup-plugin-peer-deps-external";
import postcss from "rollup-plugin-postcss";
import { terser } from "rollup-plugin-terser";
import { visualizer } from "rollup-plugin-visualizer";

const packageJson = require("./package.json");

export default [
  {
    input: packageJson.source,
    output: [
      {
        file: packageJson.main,
        format: "cjs",
        exports: "named",
        inlineDynamicImports: true,
      },
      {
        file: packageJson.module,
        format: "esm",
        inlineDynamicImports: true,
      },
    ],
    acornInjectPlugins: [jsx()],
    plugins: [
      peerDepsExternal(),
      json(),
      url({
        include: ["**/*.svg", "**/*.png"],
        limit: 8192,
        emitFiles: true,
        fileName: "[dirname][hash][extname]",
      }),
      svgr(),
      resolve({
        extensions: [".js", ".jsx", ".ts", ".tsx"],
        mainFields: ["module", "main"],
        preferBuiltins: false,
        browser: true,
      }),
      babel({
        exclude: "node_modules/**",
        babelHelpers: "runtime",
        extensions: [".js", ".ts", ".jsx", ".tsx"],
        presets: ["@babel/preset-react", "@babel/preset-typescript"],
        plugins: ["@babel/plugin-transform-runtime"],
      }),
      commonjs({
        include: "node_modules/**",
        exclude: [
          "node_modules/process-es6/**",
          "node_modules/@mui/**",
          "node_modules/three/**",
        ],
      }),
      typescript({
        tsconfig: "./tsconfig.json",
        exclude: ["**/*.stories.tsx", "**/*.test.tsx"],
      }),
      postcss({
        extract: true,
        minimize: true,
        modules: true,
        plugins: [require("cssnano")], // Add CSS minification
      }),
      terser({
        format: {
          comments: false,
        },
        compress: {
          drop_console: true,
          ecma: 2015,
        },
      }),
      visualizer({
        filename: "bundle-analysis.html",
        open: true,
      }),
    ],
    external: [
      /^react($|/)/,
      /^react-dom($|/)/,
      /^three($|/)/,
      /^@mui/.*/,
      /^@react-three/.*/,
      "axios",
      "jszip",
      "i18next",
      "react-i18next",
      "lucide-react",
      "moment",
      "process",
    ],
  },
  {
    input: "build/types/index.d.ts",
    output: [{ file: "build/index.d.ts", format: "esm" }],
    plugins: [dts.default()],
    external: [/.css$/, /.scss$/],
  },
];

Package.json
My package.json includes:

{
  "name": "@solarhub-3d-viewer",
  "version": "0.0.10",
  "main": "build/index.js",
  "module": "build/index.es.js",
  "types": "dist/index.d.ts",
  "source": "index.ts",
  "dependencies": {
    "@babel/preset-flow": "^7.25.9",
    "@cometchat-pro/chat": "^3.0.6",
    "@emotion/react": "^11.10.0",
    "@emotion/styled": "^11.10.0",
    "@mui/icons-material": "^5.5.1",
    "@mui/material": "^5.14.17",
    "@mui/styles": "^5.5.3",
    "@mui/types": "^7.1.3",
    "@react-google-maps/api": "^2.19.2",
    "@react-oauth/google": "^0.10.0",
    "@react-pdf/renderer": "^3.4.4",
    "@react-three/drei": "^9.109.5",
    "@react-three/fiber": "^8.17.5",
    "@rollup/plugin-babel": "^6.0.4",
    "@sentry/react": "^7.27.0",
    "@sentry/tracing": "^7.27.0",
    "@stripe/react-stripe-js": "^1.7.0",
    "@stripe/stripe-js": "^1.24.0",
    "@testing-library/jest-dom": "^5.16.2",
    "@testing-library/react": "^12.1.4",
    "@testing-library/user-event": "^13.5.0",
    "@turf/turf": "^6.5.0",
    "@types/antd": "^1.0.0",
    "@types/axios": "^0.14.0",
    "@types/jest": "^27.4.1",
    "@types/mapbox__mapbox-gl-geocoder": "^4.7.2",
    "@types/mixpanel-browser": "^2.38.0",
    "@types/node": "^16.11.26",
    "@types/react-dom": "^17.0.13",
    "@types/react-dropzone": "^5.1.0",
    "@types/react-share": "^4.0.0",
    "@types/styled-components": "^5.1.24",
    "@types/uuid": "^8.3.4",
    "antd": "^4.19.2",
    "apexcharts": "^3.36.0",
    "axios": "^0.26.1",
    "buffer": "^6.0.3",
    "chart.js": "^3.9.1",
    "dateformat": "^4.6.3",
    "earcut": "^2.2.4",
    "emoji-mart": "^3.0.1",
    "env-cmd": "^10.1.0",
    "firebase": "^8.4.2",
    "firebase-admin": "^10.0.0",
    "geofire-common": "^5.2.0",
    "geotiff": "^2.1.3",
    "geotiff-geokeys-to-proj4": "^2024.4.13",
    "html-react-parser": "^1.4.5",
    "html-to-image": "^1.11.11",
    "html2canvas": "^1.4.1",
    "http": "0.0.1-security",
    "https": "^1.0.0",
    "https-browserify": "^1.0.0",
    "i": "^0.3.7",
    "i18next": "^21.8.16",
    "install": "^0.13.0",
    "jodit-react": "^4.1.2",
    "jszip": "^3.10.1",
    "jwt-decode": "^4.0.0",
    "load-bmfont": "^1.4.1",
    "lodash": "^4.17.21",
    "lucide-react": "^0.469.0",
    "mapbox-gl": "^2.7.1",
    "mixpanel-browser": "^2.45.0",
    "ndarray": "^1.0.19",
    "ndarray-gemm": "^1.0.0",
    "npm": "^8.7.0",
    "pdf-lib": "^1.17.1",
    "plotty": "^0.4.9",
    "proj4": "^2.11.0",
    "prop-types": "^15.8.1",
    "querystring": "^0.2.1",
    "react": "^18.3.1",
    "react-3d-viewer": "^1.0.12",
    "react-apexcharts": "^1.4.0",
    "react-app-rewired": "^2.2.1",
    "react-calendly": "^2.2.2",
    "react-chartjs-2": "^4.3.1",
    "react-colorful": "^5.6.1",
    "react-dom": "^18.3.1",
    "react-draggable": "^4.4.6",
    "react-dropzone": "^14.2.2",
    "react-full-screen": "^1.1.1",
    "react-html-parser": "^2.0.2",
    "react-i18next": "^11.18.6",
    "react-image-gallery": "^1.2.7",
    "react-map-gl": "^6.1.16",
    "react-map-gl-geocoder": "^2.1.7",
    "react-mapbox-gl-geocoder": "^1.1.0",
    "react-multi-date-picker": "^3.3.0",
    "react-pdf": "^9.1.0",
    "react-query": "^3.34.16",
    "react-quick-pinch-zoom": "^4.9.0",
    "react-redux": "^7.2.6",
    "react-router": "^6.18.0",
    "react-router-dom": "^6.2.2",
    "react-scripts": "^5.0.0",
    "react-share": "^4.4.0",
    "react-signature-canvas": "^1.0.6",
    "react-slick": "^0.28.1",
    "react-spinners": "^0.11.0",
    "react-timezone-select": "^1.2.0",
    "react-to-print": "^2.15.1",
    "react-toastify": "^8.2.0",
    "redux": "^4.1.2",
    "redux-saga": "^1.1.3",
    "redux-thunk": "^2.4.1",
    "reselect": "^4.1.8",
    "rollup-plugin-copy": "^3.5.0",
    "rollup-plugin-dts": "^6.1.1",
    "slick-carousel": "^1.8.1",
    "stream-http": "^3.2.0",
    "suncalc": "^1.9.0",
    "swiper": "^6.8.4",
    "three": "^0.167.1",
    "three-bmfont-text": "^3.0.1",
    "twemoji": "^13.1.0",
    "url": "^0.11.0",
    "uuid": "^8.3.2",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "env-cmd -f .env.stage react-app-rewired start",
    "prebuild": "tsc --noEmit",
    "build": "env-cmd -f .env.stage react-app-rewired build",
    "deploy": "firebase deploy --only hosting:solarhub-redesign",
    "start:prod": "env-cmd -f .env.prod react-app-rewired start",
    "prebuild:prod": "tsc --noEmit",
    "build:prod": "env-cmd -f .env.prod react-app-rewired build",
    "predeploy:prod": "npm run build:prod",
    "deploy:prod": "firebase deploy --only hosting:solarhub-44450",
    "lint": "eslint src/**/*.{js,jsx,ts,tsx,json}",
    "lint:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx,json}'",
    "format": "prettier --write 'src/**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc",
    "rollup": "rollup -c --bundleConfigAsCjs"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@babel/plugin-transform-runtime": "^7.26.9",
    "@babel/preset-react": "^7.26.3",
    "@babel/runtime": "^7.26.9",
    "@rollup/plugin-commonjs": "^28.0.2",
    "@rollup/plugin-json": "^6.1.0",
    "@rollup/plugin-node-resolve": "^16.0.0",
    "@rollup/plugin-typescript": "^12.1.2",
    "@rollup/plugin-url": "^8.0.2",
    "@svgr/rollup": "^8.1.0",
    "@types/earcut": "^2.1.4",
    "@types/lodash": "^4.14.182",
    "@types/mapbox-gl": "^2.6.3",
    "@types/ndarray": "^1.0.11",
    "@types/proj4": "^2.5.5",
    "@types/react": "^17.0.19",
    "@types/react-html-parser": "^2.0.2",
    "@types/react-signature-canvas": "^1.0.5",
    "@types/react-slick": "^0.23.8",
    "@types/suncalc": "^1.9.2",
    "@types/three": "^0.158.3",
    "@typescript-eslint/eslint-plugin": "^5.47.1",
    "ajv": "^7.2.4",
    "autoprefixer": "^10.4.2",
    "cssnano": "^7.0.6",
    "eslint": "^8.31.0",
    "eslint-config-prettier": "^8.5.0",
    "eslint-config-standard-with-typescript": "^24.0.0",
    "eslint-import-resolver-alias": "^1.1.2",
    "eslint-import-resolver-typescript": "^3.5.2",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-n": "^15.6.0",
    "eslint-plugin-only-warn": "^1.1.0",
    "eslint-plugin-prettier": "^4.2.1",
    "eslint-plugin-promise": "^6.1.1",
    "eslint-plugin-react": "^7.31.11",
    "eslint-plugin-react-hooks": "^4.6.0",
    "i18next-scanner": "^4.3.0",
    "postcss": "^8.4.8",
    "prettier": "^2.8.1",
    "process": "^0.11.10",
    "readline-sync": "^1.4.10",
    "rollup": "^4.34.9",
    "rollup-plugin-peer-deps-external": "^2.2.4",
    "rollup-plugin-postcss": "^4.0.2",
    "rollup-plugin-terser": "^7.0.2",
    "rollup-plugin-visualizer": "^5.14.0",
    "styled-components": "^5.3.3",
    "tailwindcss": "^3.0.23",
    "ts-node": "^10.9.2",
    "typescript": "^5.8.2"
  }
}

My config.overrides.js:

const webpack = require("webpack");

module.exports = function override(config, env) {
  config.resolve.fallback = {
    ...config.resolve.fallback,
    http: require.resolve("stream-http"),
    https: require.resolve("https-browserify"),
    buffer: require.resolve("buffer"),
    assert: require.resolve("assert/"),
    tty: require.resolve("tty-browserify"),
    util: require.resolve("util/"),
    os: require.resolve("os-browserify/browser"),
    path: require.resolve("path-browserify"),
    "process": require.resolve("process/browser"),
    fs: false, // fs is not available in browsers
    module: false, // module should not be included
  };
  config.resolve.extensions = [...config.resolve.extensions, ".ts", ".js"];
  config.plugins = [
    ...config.plugins,
    new webpack.ProvidePlugin({
      process: "process/browser",
      Buffer: ["buffer", "Buffer"],
    }),
  ];
  config.module.rules.push({
    test: /.(js|mjs|jsx)$/,
    enforce: "pre",
    loader: require.resolve("source-map-loader"),
    resolve: {
      fullySpecified: false,
    },
  });

  return config;
};

What I Have Tried:

  • Ensured the package.json correctly specifies source, main, and
    module.
  • Checked if babelHelpers: “runtime” is correctly configured.
  • Added preferBuiltins: false in @rollup/plugin-node-resolve.
  • Verified that external dependencies are properly marked in external.

Additional Info:

  • Node.js Version: v16.14.0
  • Project Type: React + TypeScript
  • Error Appears When: Running the installed package inside another project

Question:

What could be causing this error, and how can I fix it? Any help would be greatly appreciated! Let me know if you have any questions!

amCharts4 – How to stretch the visible data range to see last value of a DateAxisRangeSelector?

I have an XYChart developed with amCharts4 in Javascript. I have a DateAxis on the x-axis and a ValueAxis on the y-axis. To control the visible data range, I use a DateAxisRangeSelector and an XYChartScrollbar. When I select two dates, my chart displays data from the first date at 00:00:00 to the second date at 00:00:00. As a result, I can’t see the data corresponding to the last date.

Is there any way of stretching the visible data range to see the last date, without modifying the dates in the selector?

Cypress Studio Does Not Handle Multiple Matching Elements – How to Fix?

I’m using Cypress Studio to generate test scripts, and I noticed an issue with how it selects elements. Consider the following line generated by Cypress Studio:

cy.get('[data-cy="kam.customer.basic-details.customer-name-input"] input').clear().type('test_1');

The problem is that there are multiple elements matching this selector, but Cypress Studio does not add any indexing. So, when I run the test again, it sometimes fails because it selects the wrong element (or multiple elements).

For example, if I manually add indexing like this:

`cy.get('[data-cy="kam.customer.basic-details.customer-name-input"]').find('input').eq(0).clear().type('test_1');

It works, but I want to know:
Why doesn’t Cypress Studio automatically handle multiple matching elements?
Is there a way to configure Cypress Studio to generate more reliable selectors?
What are the best practices to avoid this issue when using Cypress Studio for test recording?

How can I get a ACS ID for initiating a 1:1 voice all using Azure Communication Service?

I am using the sample code from Azure to trying the JS SDK of the Azure Communication Service. Now I am trying to initiate an outgoing call. But the API needs the ACS ID for the outgoing call and I am unable to find this ID.

I have already created a resource in azure portal and got the Connection String. A user token with VOIP is also generated. The SDK initialisation has worked with the connection string. But I could only initiate a voice call to the azure echo bot using 8:echo123 successfully.

Hide a highchart sankey diagram node on double click

I have created a Sankey diagram from Highcharts.

I want to hide all the nodes which start from a particular node when i double click it.

So far, i am able to remove the path from clicked node to target node, but could not remove target node itself.

Here is the example, if you double click on “Shopping” node ( and remove the mouse from the chart ) it hides the path, but i want to remove both “Online” and “Offline” node also.

Highcharts.chart("container", {
  title: {
    text: "Cash flow"
  },
  chart: {
    events: {
      load: function() {
        let chart = this;

        chart.series[0].points.forEach((point) => {
          point.graphic.element.addEventListener("dblclick", function() {
            point.toNode.linksFrom.forEach((node) => {
              node.update({color: 'transparent', weight: 0 }, false);
            });
          });
        });
      }
    }
  },

  accessibility: {
    point: {
      valueDescriptionFormat: "{index}. {point.from} to {point.to}, " + "{point.weight}."
    }
  },
  tooltip: {
    headerFormat: null,
    pointFormat: "{point.fromNode.name} u2192 {point.toNode.name}: {point.weight:.2f} ",
    nodeFormat: "{point.name}: {point.sum:.2f}"
  },
  series: [{
    keys: ["from", "to", "weight"],
    data: [
      ["Salary", "Income", 5],
      ["Dividend", "Income", 2],
      ["Bonus", "Income", 3],

      ["Income", "Tax", 1],
      ["Income", "Shopping", 3],
      ["Income", "Invest", 6],

      ["Shopping", "Online", 1],
      ["Shopping", "Offline", 2]
    ],
    type: "sankey",
    name: "Sankey demo series"
  }]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/sankey.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>

<figure class="highcharts-figure">
  <div id="container"></div>
</figure>

Issue when yarn install inside docker, but works outside docker

I get this error

Yarn - There appears to be trouble with your network connection. Retrying

and then timeout as error An unexpected error occurred: 'https://registry.yarnpkg.com/<package name>.tgz: ESOCKETTIMEDOUT’.

I have tried adding network timeout via yarn install --network-timeout 240000 , still same issue

if have any suggestions for this then please let me know. Thankyou