chai-http error Exception during run: Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No “exports” main defined

I have a problem using chai-http for testing, when I use npm test or mocha I get this error

Exception during run: Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in C:...node_moduleschai-httppackage.json
    at exportsNotFound (node:internal/modules/esm/resolve:314:10)
    at packageExportsResolve (node:internal/modules/esm/resolve:605:13)
    at resolveExports (node:internal/modules/cjs/loader:638:36)
    at Function._findPath (node:internal/modules/cjs/loader:743:31)
    at Function._resolveFilename (node:internal/modules/cjs/loader:1230:27)
    at Function._load (node:internal/modules/cjs/loader:1070:27)
    at TracingChannel.traceSync (node:diagnostics_channel:322:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1335:12)
    at require (node:internal/modules/helpers:136:16)
    at Object.
    ...

And here is the test code:

/* eslint-disable no-undef */
const chai = require('chai')
const routes = require('../src/config/enums/routes.enum')
const env = require('../src/config/environments')
const app = require('../App')
const chaiHttp = require('chai-http');

chai.use(chaiHttp)
const expect = chai.expect;

const endpoint = env.url;
const PORT = process.env.APP_PORT;

describe('POST ' + routes.USERS, () => {
    it('Debería retornar lo que se le mandó al post', async () => {
        let server;

        before(() => {
            server = app.listen(PORT, () => console.log("Running server for test"))
        });

        after(() => {
            server.close();
        });

        request(app)
            .post(endpoint + routes.USERS)
            .send({
                nickname: "osmaldym",
                name: "Osmaldy",
                password: "secret",
            })
            .end((err, res) => {
                expect(res.status).to.equal(200);
                expect(res.body).to.have.property('data');
                done();
            });
    })
})

I think this error throws cause when I look the C:...node_moduleschai-httppackage.json file points to his index.js, and uses ES Modules but it doesn’t convert to commonjs, anyway I don’t know

Encryption using .NET Framework and JavaScript with a self generated certificate

I’m trying to develop some sort of an end to end encryption using C# .NET Framework on the server side and JavaScript on the client side, this is what I need:

  1. Generating a salt in client side, and sending the salt + unique device number (I have it) to the server.

  2. On the server, Using the device number I need to create a self generated certificate with a private and public key, then encrypt the private key using the salt I sent and send the encrypted private key back to the client.

  3. In client I need to decrypt the key using the same salt and use it to encrypt a certain payload before sending to the server.

  4. Decrypt the payload using the public key (I stored it in the DB for that) and continue as regular.

No matter what I tried, I can’t get past the 3, as I’m failing at the client side decryption (Maybe the problem is with the server side encryption, I’m not sure).

Any help will be appreciated.

Just attaching one sample of what I tried (I tried many more):

Server Side:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Web.Http;

[HttpPost]
[Route("api/device/certificate")]
public IHttpActionResult GenerateDeviceCertificate([FromBody] CertificateRequestModel request)
{
    try
    {
        // Create certificate with private key
        var subjectName = $"CN={request.DeviceNumber}";
        var rsa = new RSACryptoServiceProvider(2048);
        var req = new CertificateRequest(subjectName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

        var cert = new X509Certificate2(req.CreateSelfSigned(
            DateTimeOffset.Now,
            DateTimeOffset.Now.AddYears(1)).Export(X509ContentType.Pfx),
            (string)null,
            X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

        // Get private key
        var privateKey = cert.PrivateKey as RSACryptoServiceProvider;
        if (privateKey == null)
            throw new Exception("Failed to get private key from certificate");

        var privateKeyBytes = privateKey.ExportCspBlob(true);

        // Encrypt the private key using AES with the provided salt
        byte[] saltBytes = Encoding.UTF8.GetBytes(request.Salt);
        using (Aes aes = Aes.Create())
        {
            using (var keyDerivation = new Rfc2898DeriveBytes(request.Salt, saltBytes, 10000))
            {
                aes.Key = keyDerivation.GetBytes(32);
                aes.GenerateIV();

                byte[] encryptedPrivateKey = EncryptAES(privateKeyBytes, aes.Key, aes.IV);

                return Ok(new
                {
                    success = true,
                    encryptedPrivateKey = Convert.ToBase64String(encryptedPrivateKey),
                    iv = Convert.ToBase64String(aes.IV)
                });
            }
        }
    }
    catch (Exception ex)
    {
        return Ok(new
        {
            success = false,
            error = ex.Message
        });
    }
}

// AES Encryption Helper
private byte[] EncryptAES(byte[] data, byte[] key, byte[] iv)
{
    using (Aes aes = Aes.Create())
    {
        aes.Key = key;
        aes.IV = iv;

        using (var encryptor = aes.CreateEncryptor())
        {
            return encryptor.TransformFinalBlock(data, 0, data.Length);
        }
    }
}

Client Side:

async function requestKeyFromServer() {
    // Generate a random salt for key encryption
    const salt = crypto.getRandomValues(new Uint8Array(16))
        .reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');

    // Prepare request data
    const certificateRequest = {
        deviceNumber: _userDevice,
        salt: salt
    };

    // Send to server to generate certificate
    try {
        const response = await fetch(_urlBase + 'api/device/certificate', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(certificateRequest)
        });

        const result = await response.json();
        if (result.success) {
            // Decrypt the private key using the same salt
            _privateKey = await decryptPrivateKey(result.encryptedPrivateKey, salt, result.iv);

            // Store the decrypted private key securely
            //storeKey(response.encryptedPrivateKey, salt, response.Expiry);            
        } else {
            throw new Error(result.error || 'Failed to generate certificate');
        }
    } catch (error) {
        console.error('Certificate generation failed:', error);
        throw error;
    }
}

    async function decryptPrivateKey(encryptedPrivateKey, salt, iv) {
        const aesKey = await deriveKey(salt);
        const encryptedData = Uint8Array.from(atob(encryptedPrivateKey), c => c.charCodeAt(0));
        const ivBytes = Uint8Array.from(atob(iv), c => c.charCodeAt(0));
    
        const decrypted = await crypto.subtle.decrypt(
            { name: "AES-CBC", iv: ivBytes },
            aesKey,
            encryptedData
        );
    
        return new TextDecoder().decode(decrypted);
    }
    
    async function deriveKey(salt) {
        const saltBytes = new TextEncoder().encode(salt); // Convert salt string to Uint8Array
    
        // Import key material (PBKDF2 requires a key material, which is a raw buffer from the salt)
        const keyMaterial = await crypto.subtle.importKey(
            "raw",
            saltBytes, // Corrected: Import the salt as raw key material
            { name: "PBKDF2" },
            false,
            ["deriveBits", "deriveKey"]
        );
    
        // Derive AES key from PBKDF2
        return await crypto.subtle.deriveKey(
            {
                name: "PBKDF2",
                salt: saltBytes,
                iterations: 100000, // Higher is more secure
                hash: "SHA-256"
            },
            keyMaterial,
            { name: "AES-CBC", length: 256 }, // Derive a 256-bit AES key
            true,
            ["encrypt", "decrypt"]
        );
    }

Jest mock singleton instance

service.js this file defines a Service class with a constructor that initializes a value property and a getValue method that returns this value. The file exports an instance of the Service class.

class Service {
    constructor() {
        this.value = 'A';
    }
    getValue() {
        return this.value;
    }
}

export default new Service();

main.js this file imports a service and defines a run function that logs a message with a value obtained from the service.

import service from './service';

export function run() {
    const value = service.getValue();
    console.log('Executing service with value ' + value);
}

main.test.js

import { jest } from '@jest/globals';
import { run } from './main';

jest.mock('./service', () => {
    return {
        __esModule: true,
        default: {
            getValue: jest.fn().mockReturnValue('mocked_value'),
        },
    };
});

describe('test run', () => {
    it('should log the correct message', () => {
        console.log = jest.fn();
        run();
        expect(console.log).toHaveBeenCalledWith('Executing service with value mocked_value');
    });
});

What happens?

Expected: "Executing service with value mocked_value"
Received: "Executing service with value A"

Can anyone help getting the mock work? Thanks.

Select dropdown menu not showing default value when reloading

First of all, let me mention that my knowledge of JavaScript and Vue is quite limited as I am still a student. These are not taught in my classes, so if you notice any significant mistakes in my code, please know that I consider it to be expected. I am not yet familiar with best practices or other nuances.

I’ve encountered an issue while trying to create a dependent combobox.

The first combobox is supposed to update the values in the second one. Although the values in the second combobox get updated, the default value is not “selected”, it does not render the default option text.

To provide more context: I am trying to implement a feature where a user selects a floor, which contains several classrooms. When switching from one floor to another, I would like the second combobox to display “select a classroom” as its default value.

This is the code I currently have.

<script setup>
   import { ref, onMounted } from 'vue';
   import axios from 'axios';
   import APIComboBox from './components/APIComboBox.vue';
   
   // Llamar a la función al montar el componente
   onMounted(() => {
     cargaListadoPlantas();
   });
   
   // Definir las variables reactivas
   const plantaSeleccionada = ref('');
   const listadoPlantasOpciones = ref([]);
   
   // Función para cargar los datos de la API
   const cargaListadoPlantas = async () => {
       console.log("Cargando listado plantas.");
       try {
           const response = await axios.get('http://localhost:8085/floors');
           listadoPlantasOpciones.value = response.data;
           console.log("Listado obtenido.n" + response.data);
       } catch (error) {
           console.error('Error al cargar el listado de valores', error);
       }
   };
   
   // Función para manejar la selección de plantas
   const manejarSeleccionPlantas = (nuevoValor) => {
       console.log("Cambios en selección de plantas.");
       plantaSeleccionada.value = nuevoValor;
       console.log('Valor seleccionado en combo plantas:', nuevoValor);
   
       // Resetea el aula seleccionada y carga el listado de aulas
       cargarAulasServidor(plantaSeleccionada.value);
   };
   
   const aulaSeleccionada = ref('');
   const listadoAulasPlanta = ref([]);
   
   // Función para cargar los datos de la API (Aulas)
   const cargarAulasServidor = async (plantaParam) => {
       console.log('Recuperando aulas para ' + plantaParam);
       try {
           const response = await axios.get('http://localhost:8085/classrooms', {
               params: { floor: plantaParam }
           });
   
           listadoAulasPlanta.value = response.data;
           console.log('Aulas recuperadas:n' + response.data);
           aulaSeleccionada.value = '';
   
       } catch (error) {
           console.error('Error al cargar el listado de aulas', error);
       }
   };
   
   // Función para manejar la selección de aula
   const manejarSeleccionAula = (nuevoValorAula) => {
       console.log("Cambios en selección de aulas.");
       aulaSeleccionada.value = nuevoValorAula;
       console.log('Valor seleccionado en combobox aulas:', aulaSeleccionada.value);
       cargarProyectoresAulas(aulaSeleccionada.value);
   };
   
   const listadoProyectores = ref([]);
   const selectedRow = ref(null); // Variable para almacenar la fila seleccionada
   
   // Función para cargar los proyectores de un aula específica
   const cargarProyectoresAulas = async (aulaParam) => {
       console.log('Recuperando proyectores para ' + aulaParam);
       try {
           const response = await axios.get('http://localhost:8085/classroom-projectors', {
               params: { classroom: aulaParam }
           });
   
           listadoProyectores.value = response.data;
           console.log('Proyectores recuperados:n' + response.data);
           selectedRow.value = null; // Resetea la selección cuando cambia la lista
   
       } catch (error) {
           console.error('Error al cargar el listado de proyectores.', error);
       }
   };

   const listadoComandos = ref([]);

     // Función para cargar los comandos de un proyector seleccionados
     const cargaComandosProyector = async (proyector) => {
       console.log('Recuperando comandos para ' + proyector);
       try {
           const response = await axios.get('http://localhost:8085/commands', {
               params: { modelname: proyector }
           });
   
           listadoComandos.value = response.data;
           console.log('Comandos recuperados:n' + response.data);
   
       } catch (error) {
           console.error('Error al cargar el listado de comandos.', error);
       }
   };
   
   // Función para manejar la selección de un proyector en la tabla
   const proyectorSeleccionado = (index, modelo) => {
      console.log('Modelo del proyector:', modelo); // Log para verificar el modelo seleccionado
       selectedRow.value = index; // Almacena el índice de la fila seleccionada
       cargaComandosProyector(modelo);

   };

</script>
<template>
   <div class="container mt-3" style="width: 90%; background-color: aqua;">
      <h2>Control remoto proyectores.</h2>
      <!-- Caja -->
      <div class="d-flex justify-content-between">
         <div style="width: 49%;">
            <div style="background-color: aquamarine;">
               <div class="d-flex justify-content-between">
                  <!-- Componente hijo con el listado de opciones (Plantas) -->
                  <APIComboBox class="m-2" :opciones="listadoPlantasOpciones" @selectActualizado="manejarSeleccionPlantas" />
                  <!-- Componente hijo con el listado de opciones (Aulas) -->
                  <APIComboBox class="m-2" :opciones="listadoAulasPlanta" @selectActualizado="manejarSeleccionAula" :valorSeleccionado="aulaSeleccionada" />
                  <button type="button" class="btn btn-primary m-2" @click="manejarSeleccionAula(''), manejarSeleccionPlantas()">Reset Aula</button>
               </div>
            </div>
            <!-- caja de la tabla de proyecotres -->
            <div style="background-color: azure;">
               <table class="table table-hover ml-2 mr-2" >
                  <thead>
                     <tr>
                        <th>Modelo</th>
                        <th>Aula</th>
                     </tr>
                  </thead>
                  <tbody>
                     <tr v-for="(projector, index) in listadoProyectores" 
                        :key="index" 
                        @click="proyectorSeleccionado(index, projector.model)"
                        :class="{ 'table-primary': selectedRow === index }"
                        class="cursor-pointer">
                        <td>{{ projector.model }}</td>
                        <td>{{ projector.classroom }}</td>
                     </tr>
                  </tbody>
               </table>
            </div>
         </div>
         <div style="width: 49%;">
            <div style="background-color: bisque; min-height: 100px;">
              <table class="table">
                <thead>
                  <tr>
                    <th>Accion</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="(comando, index) in listadoComandos" :key="index">
                      <td> {{ comando.action }}</td>
                  </tr>
                </tbody>
              </table>
            </div>
         </div>
      </div>
   </div>
</template>
<style scoped>
   /* Ensure cursor changes to pointer */
   .cursor-pointer {
   cursor: pointer;
   }
</style>

<script setup>


// Importa las funciones necesarias de Vue
import { defineProps, defineEmits, ref } from 'vue';

// Recibe las opciones como props
const props = defineProps({
  opciones: {
    type: Array,
    required: true,  // El listado de opciones es obligatorio
  },
});

// Declara una variable reactiva para almacenar el valor seleccionado
const valorSeleccionado = ref(''); // Valor por defecto: cadena vacía

// Define un emisor para comunicar el valor seleccionado al componente padre
const emit = defineEmits(['selectActualizado']);

// Función para emitir el valor seleccionado hacia el componente padre
const emitirSelectActualizado = () => {
  emit('selectActualizado', valorSeleccionado.value);
};

</script>

<template>
  <div>
    <!-- Dropdown para seleccionar el valor -->
    <select 
      v-model="valorSeleccionado" 
      @change="emitirSelectActualizado" 
      class="p-2 border border-gray-300 rounded-md">

      <!-- Opción predeterminada cuando no hay un valor seleccionado -->
      <option value="" selected >Seleccione un valor.</option>


      <!-- Genera las opciones dinámicamente desde las props -->
      <option 
        v-for="opcion in props.opciones" 
        :key="`${opcion}`" 
        :value="`${opcion}`">
        {{ opcion }}
      </option>

    </select>
  </div>
</template>

<style scoped>
</style>

I have tried adjusting the timing of the selected value update by moving it from one function to another. Also, I attempted to introduce a prop attribute to let the parent component specify the selected item. However, this approach did not work either so I backtracked.

I have seen other people having the same problem but their solutions did not work for me.

mongodb boolean value is not updating

I am trying to update “has_signed” value to true but its not working note that my table model structure is like this:

export interface AdminOffersInterface {
  //other fields
  seller: [{
    first_name: string,
    last_name: string,
    email: string,
    role: string,
    phone: String,
    has_signed: boolean,
    signature_id: string,
    signature_req_id: string
  }],
}

and I am using trying to update the value by using this function

async updateSellerSigningStatus(id: string): Promise<AdminOffersInterface> {
  console.log("id.....", id);
  
  try {
    let response: any = await this.adminOffersModel.findOneAndUpdate(
      { _id: id }, 
      { $set: { "seller.$[elem].has_signed": true } },
      { new: true, arrayFilters: [{ "elem.has_signed": false }] }
    );

    const code = 200
    response = {
      code,
      data: response
    }

    return response;
  }
  catch (error) {
    console.log('error', error);
  }
}

Strapi v5 overriding controller action deletes other default actions

I’ve got a weird issue here, I overrode the find() action inside of a custom controller in strapi v5 like this:

'use strict';

/**
 * team controller
 */

const {createCoreController} = require('@strapi/strapi').factories;

module.exports = createCoreController('api::team.team', ({strapi}) => ({
  async create(ctx) {
    try {
      const user = ctx.state.user;

      if (!user) {
        return ctx.unauthorized('You must be logged in to create a team');
      }

      const teamData = {
        ...ctx.request.body.data,
        user: user.id
      }

      const team = await strapi.entityService.create('api::team.team', {
        data: teamData,
      });

      return ctx.created(team);
    } catch (error) {
      throw ctx.throw(500, error);
    }
  },

  async findOne(ctx) {
    const {data, meta} = await super.findOne(ctx);
    return {data, meta};
  }
}));

Unfortunately this seems to remove all other controller actions like findOne() from the controller entirely. How can I fix this?

Thanks in advance for any useful input.

Execute swap transaction using CETUS protocol

I am trying to execute a raw SUI swap(SUI -> SUIDENG) transaction using CETUS protocol.
The problem is I don’t know how to give the movevec params as I don’t have any SUIDENG in my wallet.
Below is my current code, which would make more sense than my words.

tx.setGasBudget(1000000);  
tx.moveCall({
    target: `${packageId}::router::swap`,
    typeArguments: [suiAddr, suidengAddr],
    arguments: [
      tx.pure(process.env.CETUS_CONTRACT_ADDR), //
      tx.pure(
        "0xb785e6eed355c1f8367c06d2b0cb9303ab167f8359a129bb003891ee54c6fce0"
      ),
      // tx.pure(suiAddr),
      // tx.pure(suidengAddr),
      tx.makeMoveVec({
        objects: [
          tx.object(
            "0x278c016658478a5694ad4a7b03f367f01589d9b123f599a9bfb356613a2cd6da"
          ),
          tx.object(
            "0x221d8536273338c8d2c54470f31de83ecd559c6b69f75f3248c4b2870aa0a480"
          ),
        ],
      }),
      tx.makeMoveVec({
        objects: [],
      }),
      tx.pure.bool(true),
      tx.pure.bool(!!amount),
      tx.pure.u64(amount),
      tx.pure.u64(amount.toString()),
      tx.pure.u128("4295048016"), // use coin value always set false.
      tx.object(
        "0x0000000000000000000000000000000000000000000000000000000000000006"
      ),
    ],
  });

It says the argument can’t be an empty array.

      tx.makeMoveVec({
        objects: [],
      })

Do I need to use other module/function to handle this kind of case?

I tried with pool_script module’s swap_a2b function, which apparently doesn’t seem to require coinB argument and it fails with typemismatch error. Here’s the tx digest.
zsoFt94pvGBQVvq54k7v4Qg1Q7EN1qMyCXxTNFvNbkv

  tx.moveCall({
    target: `${publishedAt}::pool_script::swap_a2b`,
    arguments: [
      tx.pure(process.env.CETUS_CONTRACT_ADDR), //
      tx.pure(
        "0xb785e6eed355c1f8367c06d2b0cb9303ab167f8359a129bb003891ee54c6fce0"
      ),
      tx.makeMoveVec({
        objects: [
          tx.object(
            "0x278c016658478a5694ad4a7b03f367f01589d9b123f599a9bfb356613a2cd6da"
          ),
          // tx.object(
          //   "0x221d8536273338c8d2c54470f31de83ecd559c6b69f75f3248c4b2870aa0a480"
          // ),
        ],
      }),
      tx.pure.bool(true),
      tx.pure.u64(amount), // amount
      tx.pure.u64(10000000000000), // amount_limit
      tx.pure.u128(4295048016), // getDefaultSqrtPriceLimit, hardcode
      tx.pure("0x6"), // clock
    ],
    typeArguments: [suiAddr, suidengAddr],
  });

I have found correct parameters myself and I assume only this issue now remains, hopefully.

In useReducer, is it better to dispatch multiple actions separately for each state field or use a single action to update multiple fields at once?

In a React 17 useReducer setup, is it better to dispatch multiple actions separately, each updating a single state field, or to use a single action that updates multiple fields at once? For example, should I do this

const [state, dispatch] = useReducer(reducer, initialState);

if (data) {
  dispatch({ type: 'updateFieldA', payload: valueA });
  dispatch({ type: 'updateFieldB', payload: valueB });
  dispatch({ type: 'updateFieldC', payload: valueC });
}

// OR

if (data) {
  dispatch({
    type: 'updateAll',
    payload: { fieldA: valueA, fieldB: valueB, fieldC: valueC },
  });
}

I tried dispatching multiple actions separately and also using a single action to update multiple fields. I expected the single action approach to be more performant by reducing re-renders, but I want to confirm the best practice.

Open DIV/SPAN on right side (with content) on link Click

I’m displaying the results in a HTML table for right and wrong answers.
enter image description here

Each question has an “Explain Link” as the last colum of the table.
If clicked, I want a new DIV or SPAN open adjacent to it on the right side (expand as needed). It will show the detailed explanation for that particular question. It will include text which can be HTML formatted with h2, h3, p tags, and may also include images (“<img src” kind).
Clicking again on the same or different question “Explain Link” should close that open DIV or SPAN.

This is what I’ve tried:

Javascript:

<script>
    $(function () {
        $('#button-1').click(function(){
            $('#popup-1').animate({height:'500px'}, 500);
        });
    });
</script>

HTML:

<tr><td>Q.2<td>C<td>C<td>&#9989;<td><a href='#' id="button-1">Explain</a><span id='popup-1'>Explanation of answer<br>Goes<br>here<br>including images: <img src='img-explain-q2.jpg'></img></span>

CSS:

#popup-1{
    height: 0px;
    width: 100%;
    float: right;
    overflow: hidden;
    background: #efefef;
}

Any inputs on what is going wrong and amends to make?

After WebGL build a websocket client doesn’t work and throws a JS exception

When I use WebGL build to build my project, websocket client doesn’t work at all.
I use WebSocketSharp library and Unity 6. I encounter a JS exception:

null function or function signature mismatch.

What does it mean and how to solve the problem?

The exception:

The JS exception

And the same error in console:

The JS exception in console

I’ve already tried to use different libraries but all the libraries I used throw the same exception. This library works correctly in Unity Editor at least.

iOS Safari prevents iframe navigation to new page while Android works fine

I have a cross-origin iframe navigation issue that only occurs on iOS Safari. The same setup works perfectly on Android devices.

Setup:

Page A contains an iframe loading Page B
Page B has a 3-second countdown, then tries to open Page C
All pages are from different domains

Current Behavior:

✅ On Android: After 3 seconds, Page C opens successfully
❌ On iOS: After 3 seconds, nothing happens – Page C doesn’t open

Code Example:

// Inside Page B
setTimeout(() => {
    // Neither method works on iOS
    window.open('https://page-c.com');
    // or
    window.location.href = 'https://page-c.com';
}, 3000);

What I’ve tried:

Both window.open() and window.location.href methods
Testing on multiple iOS devices
Testing on both iOS 15 and 18

I need help understanding:

Why does this only fail on iOS?
How can I make this work on iOS devices?

Note: I don’t have access to browser dev tools on the devices, this is based purely on observed behavior.

Environment:

iOS 15 and 18
Safari browser

How can I Properly Implement a Reliable Debounce Function in JavaScript?

I need to implement a debounce function in JavaScript that ensures a function is only executed after a specified period of inactivity. This technique is commonly used to optimize performance for event listeners like scroll, resize, or input changes. My goal is to make the function efficient, reusable, and free from unexpected multiple executions.

I attempted to use setTimeout to delay function execution, but I ran into issues when the function was called repeatedly in quick succession. Here’s my implemented code:

function debounce(fn, delay) {
    let timer;
    return function() {
        clearTimeout(timer);
        timer = setTimeout(() => fn.apply(this, arguments), delay);
    };
}

const log = () => console.log(new Date(), "Function executed");
const debouncedLog = debounce(log, 1000);

console.log(new Date(), "Start");
debouncedLog();
debouncedLog(); // Should reset timer instead of executing immediately

I expected the function to reset the timer on every call and only execute after the delay period, but I noticed occasional multiple executions. How can I make this debounce function more reliable, ensuring it works consistently across different use cases?

how to know if the cookie is expired in frontend localstorage [duplicate]

I am building a MERN stack project where the backend sends a cookie with an expiry time of one hour. However, when I store the token in the frontend’s local storage, it remains there even after the expiry time. After an hour, when I try to retrieve or update something, I get an “unauthorized” error.

I checked whether the cookie still exists on the frontend, and it is still there.
How can I ensure that the token is removed or invalidated properly after expiry?

How to answer question for zendesk custom objects [closed]

How will we handle deleted custom objects?

The process for handling deleted custom objects involves:
    Fetching all available objects from the system.
    Comparing the selected object with the list of available objects.
    If the selected object is not found, it will be excluded from crawling, and its data will be deleted.

Handling of Invalid Data Formats:

Invalid data formats are caught through error handling, ensuring that incorrect data is flagged and not processed.

Missing Required Fields:

Missing required fields are flagged during the validation process. If any required fields are missing, an error will be triggered to prevent incomplete data from being submitted.

Performance Considerations: Number of objects, etc.

The system is optimized to handle large volumes of objects and data efficiently by utilizing pagination and rate-limiting strategies, ensuring scalability.

How will we handle Object/Field/Record level permissions in search?

Permissions for custom objects are managed using the /api/v2/search? endpoint to retrieve roles associated with the provided email address.

How will it impact previous search permissions?

The previous search permissions functionality remains unchanged. The only update is an additional API call to manage role-based permissions.

Any Webhook Required?

No webhook is required for handling custom objects in this setup.

Note on Missing Required Fields and Invalid Data Formats:

The questions regarding "Missing Required Fields" and "Invalid Data Formats" weren’t fully clear. However, these scenarios are managed during validation, where missing fields or incorrect formats are flagged. If further clarification is needed, feel free to provide additional context.

This version consolidates the answers for questions where the solution is already present in the standard code and provides a clearer, more streamlined response. Let me know if you’d like any further changes!

In english simple answers

Fixing Sticky Table Header with Horizontal Scroll in a Scrollable Container

Problem Description:
I have a layout where a fixed menu occupies the left side of the viewport, taking up the full height. On the right side, I have a table that dynamically loads data as you scroll. The table includes both a header and a footer.

The issue arises with the table header:

The header stays sticky at the top when scrolling vertically.
However, when I set overflow-x: auto; on the .content container to allow horizontal scrolling, the sticky behavior of the header breaks, and it no longer remains fixed at the top.
What I Tried:
I applied position: sticky; top: 0; to the to keep it fixed.
I wrapped the table inside a div with overflow-x: auto;, but this causes the sticky behavior to stop working.
I also tried setting position: sticky; directly on the th elements, but that didn’t help.
I attempted to use display: block; on the table header, but it affected column alignment.
What I Expected:
I want the table header to remain sticky at the top of the viewport when scrolling vertically, while also allowing horizontal scrolling within the .content div.

Link: https://codepen.io/Amit-Soni-the-vuer/pen/mydeqVE

<div class="container">
  <div class="d-flex align-items-start gap-30">
    <div class="menu-main-wrapper">
    </div>
    <div class="page-main-wrapper">
      <div class="header">header</div>
      <div class="content">
        <div class="table-wrapper">
          <table id="dataTable">
            <thead>
              <tr>
                <th>Fixed Column</th>
                <th>Column 2</th>
                <th>Column 3</th>
                <th>Column 4</th>
                <th>Column 5</th>
                <th>Column 6</th>
                <th>Column 7</th>
                <th>Column 8</th>
                <th>Column 9</th>
                <th>Column 10</th>
              </tr>
            </thead>
            <tbody>
            </tbody>
          </table>
        </div>
      </div>
      <div class="footer">
      </div>
    </div>
  </div>
.container {
  max-width: 1350px;
  padding: 0;
  @media (max-width: 1350px) {
    padding: 0 15px;
  }
  @media (max-width: 991.98px) {
    padding: 0 15px;
  }
}
.d-flex {
  display: flex !important;
}
.align-items-start {
  align-items: flex-start !important;
}
.gap-30 {
  gap: 30px;
}

.menu-main-wrapper {
    background: linear-gradient(93.39deg, rgba(113, 113, 113, 0.62) 0.08%, rgba(113, 113, 113, 0) 79.29%);
    padding: 0 1px;
    height: 100svh;
    width: 25.25%;
    position: -webkit-sticky;
    position: sticky;
    z-index: 10;
    top: 0;
}
@media screen and (max-width: 1133.98px) {
  .menu-main-wrapper {
    display: none;
  }
}

.page-main-wrapper {
  width: 74.75%;
}
@media screen and (max-width: 1133px) {
  .page-main-wrapper {
    width: 100%;
  }
}

.content {
  width: 100%;
}

.table-wrapper {
  width: 100%;
}


/* Table styling */
table {
  border-collapse: separate;
  border-spacing: 0; 
  width: 100%;
  min-width: 100px;
  margin-bottom: 20px;
}
th,
td {
  padding: 10px;
  white-space: nowrap;
  border-bottom: 1px solid green;
}
thead th {
  position: sticky;
  top: 0;
  background: #686161;
  z-index: 2;
}
th:first-child,
td:first-child {
  position: sticky;
  left: 0;
  background: #7e4545;
  z-index: 1;
  border-right: 1px solid blue;
}
thead th:first-child {
  z-index: 3;
  border-top-left-radius: 10px;
  border-top: 1px solid red;
} 

.header, .footer{
  height:100px;
  background:blue;
  text-align:center;
  margin:30px 0;
}
let rowCount = 20;
const tbody = document.querySelector('#dataTable tbody');

// Function to generate a table row (simulate fetched data)
function generateRow(index) {
  return `
    <tr>
      <td>Row ${index} - Fixed</td>
      <td>Row ${index} - Col2</td>
      <td>Row ${index} - Col3</td>
      <td>Row ${index} - Col4</td>
      <td>Row ${index} - Col5</td>
      <td>Row ${index} - Col6</td>
      <td>Row ${index} - Col7</td>
      <td>Row ${index} - Col8</td>
      <td>Row ${index} - Col9</td>
      <td>Row ${index} - Col10</td>
    </tr>
  `;
}

// Insert initial rows
for (let i = 1; i <= rowCount; i++) {
  tbody.insertAdjacentHTML('beforeend', generateRow(i));
}

// Auto-load more rows when scrolling near the bottom of the page
let loading = false;
window.addEventListener('scroll', function() {
  if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 100 && !loading) {
    loading = true;
    // Simulate API call delay (replace with your actual API call)
    setTimeout(() => {
      for (let i = rowCount + 1; i <= rowCount + 10; i++) {
        tbody.insertAdjacentHTML('beforeend', generateRow(i));
      }
      rowCount += 10;
      loading = false;
    }, 300);
  }
});