I am using SQLite3 in my Electron JS project, and I am encountering an error after building

I have integrated SQLite3 into my project, which I developed using Electron and React. Everything works perfectly in the development environment. However, when I move the project to the production environment, I encounter an error related to SQLite3. The database is installed and running on the environment where I run the project, so I don’t understand why this error occurs.

I’m sharing some code examples below. Could you help me figure this out?

sqllite.js

import sqllite3 from 'sqlite3'
const userDataPath = app.getPath('userData')
this.sql = new sqllite3.Database(`${userDataPath}/database.db`, (error, database) => { .. bla bla .. })

package.json

"sqlite3": "^5.1.7"

main/index.js

webPreferences: {
    preload: path.join(__dirname, "../preload/index.js"),
    sandbox: false,
    nodeIntegration: true,
    contextIsolation: false
 }

error

A JavaScript error occurred in the main process

Uncaught Exception:
Error: dlopen(/var/folders/g7/j3pbhgyj7gv4dhlyjsz162br0000gn/T/.com.electron.app.Mwp2Qu, 0x0001): tried: '/var/folders/g7/j3pbhgyj7gv4dhlyjsz162br0000gn/T/.com.electron.app.Mwp2Qu' (code signature in <CFB61DC4-0D6B-3B10-BE39-1944935AB942> '/private/var/folders/g7/j3pbhgyj7gv4dhlyjsz162br0000gn/T/.com.electron.app.Mwp2Qu' not valid for use in process: mapping process and mapped file (non-platform) have different Team IDs), '/System/Volumes/Preboot/Cryptexes/OS/var/folders/g7/j3pbhgyj7gv4dhlyjsz162br0000gn/T/.com.electron.app.Mwp2Qu' (no such file), '/var/folders/g7/j3pbhgyj7gv4dhlyjsz162br0000gn/T/.com.electron.app.Mwp2Qu' (code signature in <CFB61DC4-0D6B-3B10-BE39-1944935AB942> '/private/var/folders/g7/j3pbhgyj7gv4dhlyjsz162br0000gn/T/.com.electron.app.Mwp2Qu' not valid for use in process: mapping process and mapped file (non-platform) have different Team IDs), '/private/var/folders/g7/j3pbhgyj7gv4dhlyjsz162br0000gn/T/.com.electron.app.Mwp2Qu' (code signature in <CFB61DC4-0D6B-3B10-BE39-1944935AB942> '/private/var/folders/g7/j3pbhgyj7gv4dhlyjsz162br0000gn/T/.com.electron.app.Mwp2Qu' not valid for use in process: mapping process and mapped file (non-platform) have different Team IDs), '/System/Volumes/Preboot/Cryptexes/OS/private/var/folders/g7/j3pbhgyj7gv4dhlyjsz162br0000gn/T/.com.electron.app.Mwp2Qu' (no such file), '/private/var/folders/g7/j3pbhgyj7gv4dhlyjsz162br0000gn/T/.com.electron.app.Mwp2Qu' (code signature in <CFB61DC4-0D6B-3B10-BE39-1944935AB942> '/private/var/folders/g7/j3pbhgyj7gv4dhlyjsz162br0000gn/T/.com.electron.app.Mwp2Qu' not valid for use in process: mapping process and mapped file (non-platform) have different Team IDs)
at process.func [as dlopen] (node:electron/js2c/node_init:2:2559)
at Module._extensions..node (node:internal/modules/cjs/loader:1602:18)
at Object.func [as .node] (node:electron/js2c/node_init:2:2786)
at Module.load (node:internal/modules/cjs/loader:1295:32)
at Module._load (node:internal/modules/cjs/loader:1111:12)
at c._load (node:electron/js2c/node_init:2:16955)
at Module.require (node:internal/modules/cjs/loader:1318:19)
at require (node:internal/modules/helpers:179:18)
at bindings (/Users/ugurcanalyuz/Projects/kaffee-schutz-desktop/dist/mac-arm64/KFSPos.app/Contents/Resources/app.asar/node_modules/bindings/bindings.js:112:48)
at Object.<anonymous> (/Users/ugurcanalyuz/Projects/kaffee-schutz-desktop/dist/mac-arm64/KFSPos.app/Contents/Resources/app.asar/node_modules/sqlite3/lib/sqlite3-binding.js:1:37)

How to trigger Safari App Extension with a keyboard shortcut without a content script and input monitoring permissions?

I have a Safari App Extension which allows users to switch between last open tabs with a shortcut option+tab in the same way it’s possible to switch between last open apps with command+tab.

Here is how i do it:

  1. I inject a content script on all websites which has the only thing – key listener for option+tab presses.
  2. When a user presses option+tab, that keyboard listener detects it and sends a message to the Safari Handler.
  3. Then Safari Handler sends a message to the containing app and it shows a panel with last open tabs.

This approach has a problem: it shows a message to a user in settings:
“Can read sensitive info from web pages, including passwords…”

Which is bad, because in reality i don’t read passwords.

If i remove SFSafariContentScript key in the Safari App Extension target’s Info.plist, then this message about reading sensitive data disappears, but then i loose the ability to open the tabs panel.

How can I open my app window with a shortcut without frightening a user?

It’s possible to listen to global key presses, but that would require a user to grant the app permissions of input monitoring in macOS system settings, which also sounds shady.

I know an app which does not require any input monitoring permission:
https://apps.apple.com/ua/app/tabback-lite/id6469582909
and at the same time it does not tell a user about reading sensitive data in the extension settings.

Here is my app:
https://apps.apple.com/ua/app/tab-finder/id6741719894
It’s open-source:
https://github.com/kopyl/safari-tab-switcher

Save environment variable from async function in Bruno script [duplicate]

I am trying to create a pre-request script in Bruno to acquire a bearer token and save it as an environment variable before running the main request. I am using Axios to make a restful post request to get the token.

The code successfully gets the token and exposes it in the console.log statements. All console.log statements show in the logs with the correct data. The problem is that only the rootToken is saved as an environment variable. The setEnvVar statements are not working in the asynchronous axios .then blocks.

I have verified that the token is saved and does work if I save it at the root level. Any ideas?

const axios = require('axios');

const tokenEndpoint = bru.getEnvVar('RootUrl') + "/api/v1/oauth/token";
const clientId = bru.getEnvVar('ClientId');
const clientSecret = bru.getEnvVar('Secret');
const grantType = 'client_credentials';

function saveToken(token) {
  bru.setEnvVar("functionToken", token);
  console.log("functionToken set to:", token);
}

bru.setEnvVar("rootToken", "token");
console.log("rootToken set to: token");

// Make a request to get the access token
axios.post(tokenEndpoint, {
    client_id: clientId,
    client_secret: clientSecret,
    grant_type: grantType
  }, {
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  })
  .then(response => {
    console.log(response);
    const accessToken = response.data.access_token;
    console.log("Access Token:", accessToken);
    bru.setEnvVar("AccessToken", accessToken);
    console.log("AccessToken set to:", accessToken);
    saveToken(accessToken);
  })
  .catch(error => {
    console.error('Error fetching access token:', error);
  });

How to describe static method which returns a subclass constructor with given props in its prototype?

I’m trying to find a solution for typing existing JS code using d.ts declaration files. I have a Model class that uses some metaprogramming things by having a static method that initializes a new class constructor with custom props in its prototype. This works great, but I can’t figure out how to type it in order to have working autocomplete and types checking. The example bellow is as simplified as possible.

class Model {
  constructor(schema) {
    Object.assign(this, schema);
  }

  static define(prototype) {
    const Subclass = class extends this {

    }
    // in reality, I attach getters/setters here with some logic using defineProperties
    Object.assign(Subclass.prototype, prototype);

    return Subclass;
  }
}

class MyModel extends Model.define({
  foo: 'str' // initialization schema
}) {

}

// const MyModel2 = MyModel.define(...)

const schema = new MyModel({ bar: 2});
console.log(schema.foo);
console.log(schema.bar);

So I don’t see any way how return a class that extends this and assign new props to its prototype. Seems I need something like this:
(Simplified d.ts pseudocode)

type Constructor<T> = new (...args: any[]) => T;

class Model {
    static define<P extends {}, T>(this: Constructor<T>, prototypeProps: P): class extends T {[key in keyof prototypeProps]: prototypeProps[key]}
}

Unfortunately, I can’t find something like this in TS to make it work.

Updating a hidden field results in original value on submit

I have this form control here. defaultValues is part of the props of the component in which the control resides.

<Controller
    name={`fees.${group.key}[${index}].included`}
    control={control}
    render={({ field }) => (
        <input
            {...field}
            {...register(`fees.${group.key}[${index}].included`)}
            type="hidden"
            value={defaultValues?.included}
          />
    )}
/>

In the parent component, onToggleGroup gets executed:

const [fees, setPayableFees] = useState([..some data]);

const onToggleGroup = (status: boolean) => {
    if (!status)
      fees?.forEach(f => (f.included = false));
      setPayableFees([...fees]); //I tought this would do the trick, but the html is updated regardless...
    }
};

fees?.map(fee => {
    return (
        <ChildComponent
          defaultValues={{included: fee.included}}
        />
    );
})}

So far, this works, I can see the hidden field’s value change using Chrome DevTools.

But when I submit the form like this:

const onSubmit: SubmitHandler<FormValues> = async data => {

};

The value has reverted to its original state.

I’ve tried a controlled, uncontrolled input, value, defaultValue, nothing seems to fix that behaviour.

Any ideas ?

GridView value when using Javascript to open page

In my GridView I have a HyperLink which takes a value from the selected row and opens it in a new page. This works fine. Howevever, I need to call a javascript to open the page instead. Once I do this though, I lose the value of the selected row and instead only get the value of the last row in the GridView. Using SelectedIndexChanged handler isn’t an option either as I have three other hyperlinks on the given row and this prevents the others from working correctly if I use that. So how can I get the value needed while also calling a JavaScript function to open the URL?

My aspx:

<head id="Head1" runat="server">
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=iso-8859-1" />  
<link href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.min.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script type = "text/javascript">
    function showComments() {
        var mydiv = $('#commentDiv');
        mydiv.dialog({
            autoOpen: false, modal: true, title: 'My Comments', width: '50%',
            position: { my: 'top', at: 'top+150' }
        });
        // Open the dialog
        mydiv.dialog('open');
    }
</script>
</head>
<body>
    <form id="form1" runat="server">
    <div class="GridContainer">
        <asp:GridView ID="GridView1" runat="server" DataKeyNames="ID"
            onrowcreated="GridView1_RowDataBound">
            <Columns>
                <asp:TemplateField ItemStyle-Wrap="False" ItemStyle-Width="10%">
                    <ItemTemplate>
                        <asp:HyperLink ID="CommentHyperLink" runat="server">
                            <img  src="images/search.png" /></asp:HyperLink>
                    </ItemTemplate>
                </asp:TemplateField>    
            </Columns>
        </asp:GridView>
        <div id="commentDiv" runat="server" style="display:none">
            <iframe id="commentPage" name="commentPage" runat="server"></iframe>
        </div>
    </div>
    </form>
</body>

This works fine, when I’m not calling my JavaScript for navigation:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        HyperLink commentHyperLink = (HyperLink)e.Row.FindControl("CommentHyperLink");

        int _id = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "ID"));
        
        commentPage.Attributes["src"] = "Page2.aspx?id=" + _id;
        //commentHyperLink.Attributes.Add("onclick", " showComments(); return false;");
        commentHyperLink.NavigateUrl = "Page2.aspx?id=" + _id;
        return;
    }
}

However, if I switch the last 4 lines as shown below, I am not getting the correct value of _id. I think I understand why, I just can’t figure out how to solve it.

commentPage.Attributes["src"] = "Page2.aspx?id=" + _id;
commentHyperLink.Attributes.Add("onclick", " showComments(); return false;");
//commentHyperLink.NavigateUrl = "Page2.aspx?id=" + _id;
return;

Create a React app that automatically compiles into Javascript

So, I am trying to integrate React into my website according to https://stackoverflow.com/a/65945804/11544951 this answer. After hours of struggling it worked, but I still face the issue that I don’t know how to execute Babel. I can execute it from the CLI but then it pastes the transpiled stuff into the command line and not into respective files. I’m a bit at a loss to how exactly to set it up. I do have a babel.config.json with the following content:

    {
        "presets": ["@babel/preset-react"]
    }

A tsconfig like this:

{
  "compilerOptions": {
    "target": "ESNext",
    "lib": [ "dom", "dom.iterable", "esnext" ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "ESNext",
    "moduleResolution": "nodenext",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "react-jsx",
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ],
    "paths": {
      "@/*": [ "./src/*" ]
    }
  },
  "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts" ],
  "exclude": [ "node_modules" ],
  "compileOnSave":  true
}

And that’s my (shortened) package.json:

{
  "name": "lindy-hop-classification",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "babel_compile": "babel --presets @babel/preset-react ./src/*"
  },
  "dependencies": {
    "@babel/cli": "^7.26.4",
    "@babel/core": "^7.26.9",
    "@babel/plugin-transform-react-jsx": "^7.25.9",
    "@babel/preset-react": "^7.26.3",
    ...
  },
  "devDependencies": {
    ...
  }
}

I can imagine it having something to do with the fact that I use tsx and not jsx, but I am honestly at a loss how to set up and trigger the compilation into files.

How to follow a specific flow on a questionnaire?

I have this questionnaire and I have 3 flows/rules based on what the user selects for answer. I’m displaying the questionnaire using an object called apiData and inside of it I have 2 properties “questions” and “flows“. I currently have the first flow working just fine but it seems like the other 2 flows are not working properly.

Here’s a working DEMO Thank you in advance!

Let me explain the flows:

  1. if user answers question with id ‘travel’ with the answer that has id “france” and clicks “next” => display question with id “state”, then user picks any answer and clicks “next” => display question with id “tolerance”, then user picks any answer and clicks “next” display selectedAnswers object.

and if you look at flow array it’s also self-explanatory

flows: [
      [
        { question: 'travel', answer: 'france' },
        { question: 'state', answer: null },
        { question: 'tolerance', answer: null },
      ],
]

Currently, I’m able to get the First flow working but having an issue with the second and third flow. I also believe the problem is happening here but can’t seem to figure it out:

 if (step.answer && answered[step.question] !== step.answer) {
     match = false;
     break;
 }

Basically, for some reason as soon as I select “Spain” and click on next it prints the selectedAnswer object without following the flow. That’s my issue.

Angular fields not retaining disabled on switching tab

I have angular modal which is made of several tabs. On a single tab, when unchecking on a checkbox, some other fields are disabled. However, when I switch tab again, the fields are becoming enabled. I have used json form config to dynamically build my html so cant use viewchild.

My html tab is ngbNav. Help pls 🙁

ngAfterViewInit(): void {
this.dishCategories = this.menuService.getDishCategoryFromToken();

if (!Array.isArray(this.dishCategories)) {
    this.dishCategories = this.dishCategories ? [this.dishCategories] : [];
}

if (this.dishCategories.includes('SpicySpecials')) {
    this.prepareSauce();
    this.disableSides();
    this.toggleSpicyLevel();
    this.cdr.detectChanges();
 }
}

 private disableSides() {
const isExtraSpicy = this.dynamicOrderForm.get('extraSpicy');
const spicyLevelInput = this.dynamicOrderForm.get('spicyLevel');
const sideDishesAcc = this.dynamicOrderForm.get('sideDishes');
const drinkSelection = this.dynamicOrderForm.get('drinkSelection');
const dessertOption = this.dynamicOrderForm.get('dessertOption');

if (isExtraSpicy?.value == false) {
    drinkSelection?.enable();
    spicyLevelInput?.disable();
    sideDishesAcc?.disable();

if (drinkSelection?.value == false) 
{
        dessertOption?.disable();
    }
} else {
    drinkSelection?.reset(false);
    drinkSelection?.disable();
    dessertOption?.disable();
}

if (isExtraSpicy) {
    isExtraSpicy.valueChanges.subscribe((newValue) => {
        if (newValue === true) { // extra spicy selected
            spicyLevelInput?.enable();
            drinkSelection?.patchValue(false);
            drinkSelection?.disable();

            const dessertElement = document.querySelector(`.dessertSelect select`) as HTMLSelectElement;
            dessertOption?.patchValue(null);
            dessertElement.selectedIndex = 0;
            dessertElement.disabled = true;

            sideDishesAcc?.enable();
        } else { // no extra spice
            const spicyLevelElement = document.querySelector(`.spicyLevel input`) as HTMLInputElement;
            console.log('element:', spicyLevelElement

Make a plain HTML Submit button active again through javascript of jquery

So I run a test website and have come across a unique issue. I have tests that will reload with a event.preventDefault(); so the page they are on does not reload, but the test question does. Everything has been going great, but recently I have found that I need to move the submit button (that up until this point has been reloaded with the question).

The submit button now needs to be listening for the form to be submitted even after a question is submitted, the questions and answers section is reloaded, and replaced with a new question. Now here is the issue, the submit button will now be part of the page that doesn’t reload, while the form and the questions/answers will be reloaded every time the submit button is pressed.

Here is the current form handler:

$(document).ready(function () {
  $(document).on("submit", "#quiz", function (event) {

    console.log("Custom submit")

    event.preventDefault(); //prevent default action
    var post_url = $(this).attr("action"); //get form action url
    var form_data = $(this).serialize(); //Encode form elements for submission
    $.post(post_url, form_data, function (response) {

      console.log(response)
      $("#prntqst").html(response);
    });
  });
});

Here is an example of the form:

<form id="quiz" action="someform.php" method="post" onsubmit="event.preventDefault();">
          <input type="hidden" id="next_question" name="next_question" value="2">
          <input type="hidden" id="quiz_type" name="quiz_type" value="learning">
          <input type="hidden" id="quiz_name" name="quiz_name" value="test">

<label class="container" for="a">Ans A.
  <input type="radio" name="answers[1]" id="a" value="a">
  <span class="checkmark"></span>
</label>

<label class="container" for="b">Ans B.
  <input type="radio" name="answers[1]" id="b" value="b">
  <span class="checkmark"></span>
</label>
            

<label class="container" for="c">Ans C.
  <input type="radio" name="answers[1]" id="c" value="c">
  <span class="checkmark"></span>
</label>

The submit button is fairly plain:

    <div class="subbtn_contain">
        <div class="submitbtn">
              <input id="submit" type="submit" class="button" value="Next Question">
        </div>
     </div>
  </form>

Is it even possible to have the reloaded section submitted off of a button that has already fired and was not reloaded? I have tried to unbind it, set the default to false even after a timer it won’t submit the second question. I figure it is no longer listening for the second plus sumbit, and has to be reset to accept the click.

I am sure I am missing something.

Thanks for your time.

Here is the full return of the ajax call right now:

<font class="prntqst-text">Question?</font>

<form id="quiz" action="someform.php" method="post" onsubmit="event.preventDefault();">

<input type="hidden" id="next_question" name="next_question" value="2">
<input type="hidden" id="quiz_type" name="quiz_type" value="learning">
<input type="hidden" id="quiz_name" name="quiz_name" value="test">

<label class="container" for="a">Ans A.
  <input type="radio" name="answers[1]" id="a" value="a">
  <span class="checkmark"></span>
</label>

<label class="container" for="b">Ans B.
  <input type="radio" name="answers[1]" id="b" value="b">
  <span class="checkmark"></span>
</label>
            

<label class="container" for="c">Ans C.
  <input type="radio" name="answers[1]" id="c" value="c">
  <span class="checkmark"></span>
</label>

<div class="subbtn_contain">
<div class="submitbtn">
  <input id="submit" type="submit" class="button" value="Next Question">
</div>
</div>

<script>
$(document).ready(function () {
  $(document).on("submit", "#quiz", function (event) {

    console.log("Custom submit")

    event.preventDefault(); //prevent default action
    var post_url = $(this).attr("action"); //get form action url
    var form_data = $(this).serialize(); //Encode form elements for submission
    $.post(post_url, form_data, function (response) {

      console.log(response)
      $("#prntqst").html(response);
    });
  });
});
</script>

</form>

Problem with interstitial in admob-plus-cordova 2.0.0-alpha.19

I have some issue and I have been struggling with this problem for a long time…

My code:

<button class="sem-show-ad">Show ad</button>
<script src="cordova.js"></script>
<script>

    document.addEventListener('deviceready', () => {
        window.admob.start();
    });

    let interstitial
    document.addEventListener('deviceready', () => {
        alert(window.admob);
        document.querySelector(".sem-show-ad").addEventListener("click", async () => {
            console.log("window.admob:", window.admob);

            interstitial = new window.admob.InterstitialAd({
                adUnitId: 'ca-app-pub-3940256099942544/1033173712', // test
            });

            interstitial.on('load', (evt) => {
                console.log("c: ", evt.ad);
            });

            console.log("interstitial: ",interstitial);

            await interstitial.load();
            await interstitial.show();

            interstitial.on('loadFail', (err) => {
                console.error("Failed to load ad:", err);
            });

            interstitial.on('showFail', (err) => {
                console.error("Failed to show ad:", err);
            });
        });
    }, false);

    document.addEventListener('admob.ad.dismiss', async () => {
        // Once a interstitial ad is shown, it cannot be shown again.
        // Starts loading the next interstitial ad as soon as it is dismissed.
        await interstitial.load()
    })
</script>

I can’t show interstitial ad, I have no Idea why, I asked chat GPT but it didn’t help me… I was based on documentation: https://admob-plus.github.io/docs/cordova/ads/interstitial

I have tried to debug in many ways, for example connecting my mobile device to my computer and debugging through the chrome console, but I do not get any errors

Before I used admob-plus-cordova 1.28.0 and everything worked, but I got a message from google play console that I have to update my plugins:

com.google.android.gms:play-services-ads-lite:20.6.0
The creator of the Google Mobile Ads (GMA) SDK package (com.google.android.gms:play-services-ads-lite) added this notice to version 20.6.0:

As of June 30th 2024, this version is sunset. For more information, please visit https://developers.google.com/admob/android/deprecation.

From May 20, 2025, at 00:00 (UTC), it will no longer be possible to publish new versions of applications containing this version of the SDK package on the production track or the open testing track.

A-FRAME can’t get extras data from gltf JSON object

Is it possible in A-FRAME framework to pass some extra user data through JSON gltf object?

For example, I have this JSON and can get extras with Three.js as new THREE.GLTFLoader() and mesh.userData[0] is that “extras”:

{
   "accessors" : [
      {
         "bufferView" : 0,
         "componentType" : 5123,
         "count" : 1854,
         "max" : [ 1853 ],
         "min" : [ 0 ],
         "name" : "buffer-0-accessor-indices-buffer-0-mesh-0",
         "type" : "SCALAR"
      },...
   ...
,
"extras": [{
    "dimensions": {
        "x": 5, 
        "y": 6, 
        "z": 7},
    "name": "Some Name",
    "project": "Some project",
    "customData": {
      "someKey": "someValue"
    }
}]

But using A-FRAME as element.setAttribute(‘gltf-model’, strURL); this extras is not available, userData under mesh is empty.

ClientAuthError: network_error: Network request failed – ConfigurationBotFrameworkAuthentication

I am creating a chatbot using Azure Bot resources with a node JS application.

I use the botbuilder package to create an adapter.

credentialsFactory = new MsalServiceClientCredentialsFactory(
  'APP_ID',
  new ConfidentialClientApplication({
    auth: {
      clientId: 'APP_ID',
      clientSecret: 'APP_PASSWORD',
      authority: 'https://login.microsoftonline.com/botframework.com',
    },
  }),
);

const httpsProxyAgent = getHttpsProxyAgent();

const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(
  undefined,
  credentialsFactory,
  undefined,
  undefined,
  {
    proxySettings: httpsProxyAgent
      ? {
          host: httpsProxyAgent.proxy.hostname,
          port: +httpsProxyAgent.proxy.port,
        }
      : undefined,
  },
);
const adapter = new CloudAdapter(botFrameworkAuthentication);

await adapter.process(req, res, async (context) => {
       // Do something
  await context.sendActivity(await response.component.GetMessage({
                userSession,
                userMessage,
                template,
                responseMessageOverride: null,
              }));
});

At first, we got ENOTFOUND login.botframework.com when receiving a request from Bot framework because of our corporate proxy. We fixed this by adding proxySettings as shown above.
We used the following sample to configure the proxy : https://github.com/microsoft/BotBuilder-Samples/blob/main/samples/javascript_nodejs/49.echo-proxy-bot/index.js

Now, we get the following error:

err: {
"type": "ClientAuthError",
"message": "network_error: Network request failed",
"stack":
ClientAuthError: network_error: Network request failed
at createClientAuthError (file:///opt/app-root/src/node_modules/.pnpm/@[email protected]/node_modules/@azure/msal-common/dist/error/ClientAuthError.mjs:255:12)
at ClientCredentialClient.sendPostRequest (file:///opt/app-root/src/node_modules/.pnpm/@[email protected]/node_modules/@azure/msal-common/dist/client/BaseClient.mjs:131:23)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async ClientCredentialClient.executePostToTokenEndpoint (file:///opt/app-root/src/node_modules/.pnpm/@[email protected]/node_modules/@azure/msal-common/dist/client/BaseClient.mjs:82:26)
at async ClientCredentialClient.executeTokenRequest (file:///opt/app-root/src/node_modules/.pnpm/@[email protected]/node_modules/@azure/msal-node/dist/client/ClientCredentialClient.mjs:155:30)
at async ConfidentialClientApplication.acquireTokenByClientCredential (file:///opt/app-root/src/node_modules/.pnpm/@[email protected]/node_modules/@azure/msal-node/dist/client/ConfidentialClientApplication.mjs:112:20)
"errorCode": "network_error",
"errorMessage": "Network request failed",
"subError": "",
"name": "ClientAuthError",
"correlationId": "REDACTED"
}

I tried the run my app on my personal computer and it works. I suppose there is a missing proxy config somewhere, but I cannot figure out. Is there another configuration necessary for botframework to use the proxy settings when connecting to Azure ?

“excludeMatches” array in scripting.registerContentScripts() API is totally ignored in Safari web extensions

In a project to create a web extension for Safari, using scripting.registerContentScript() API to inject a bunch of scripts into web pages, I needed to manage a dynamic whitelist (i.e., web pages where the scripts should not be injected).

Fortunately, scripting.registerContentScripts() gives you the option of defining a list of web pages to be considered as a whitelist, using the excludeMatches parameter in the directive, to represent an array of pages where the script should not be injected.

Here just a sample of what I mean:

const matches = ['*://*/*'];
const excludeMatches = ['*://*.example.com/*'];
const directive = {
  id: 'injected-jstest',
  js: ['injectedscript.js'],
  matches: matches,
  excludeMatches: excludeMatches,
  persistAcrossSessions: false,
  runAt: 'document_start'
};
await chrome.scripting.registerContentScripts([directive])
.catch(reason => { console.log("[SW] >>> inject script error:",reason); });

Of course, the whitelist is not static, but varies over time according to the needs of the moment.

Everything works perfectly in Chromium browsers (Chrome, Edge, …) and Firefox, but fails miserably in Safari. In fact, Safari seems to completely ignore the excludeMatches parameter and injects the script even where it should not.

Has anyone had the same problem and solved it somehow?

NOTE: To test the correctness and capabilities of the API in each browser, I created a simple repository on Github with the extension code for Chromium, Firefox and Safari (XCode project).

When does Promise resolve/reject actually add a micro task?

When does Promise resolve/reject actually add a micro task?

I read the Promise/A+ implementation code from here, and understood that task adding action is triggered after resolve() (the mentioned implementation do it by timer callback, but from GPT’s info, it seems to be micro task in real Promise implementation, then the onFulfilleds queue on the chain will be executed one by one).

However, when I run the code below, I get the result I didn’t expect:

function a() {
  return new Promise((resolve) => {
      resolve();

      new Promise((r) => {
          r();
      }).then(() => {
          console.log("1")
      });

  })
}

await a();
console.log("2");

or

new Promise((resolve) => {
      resolve();

      new Promise((r) => {
          r();
      }).then(() => {
          console.log("1")
      });

  }).then(() => {
     console.log("2")   
})

I expected both the code pieces will log 2 then 1, but they both log 1 then 2, why I expect so:

  1. the outer Promise’s resolve() add a micro task (provided by then) to queue which logs 2
  2. the inner Promise’s r() add a micro task to queue which logs 1
  3. According to FIFO principle, 2 then 1.

but the result is 1 then 2, what did I mis-understand, I want to know it so bad.