How to find original email redirect link from landing page for firebase email link sign in option

In firebase, in order to authenticate a use after they click an email link, firebase needs the original clicked email link.
Example
This link redirects you a few times, and brings you to the page needed (currently set to localhost for dev purposes)
Firebase will only accept the email link, and only for one test per email which makes it difficult to diagnose this.
I need a way to fetch the first link clicked (the email link) from the landing page.
I apolagise if this has been answered anywhere else but I tried several combinations of keywords that did not work

export default function Home() {

  return (
    <>   
        boilerplate
        <button onClick={bigFunction}>Press me to check if the browser has the email saved</button>
    </>
  )
}
let signinwithemaillink = "https://ticketme.page.link/qbvQ"
function bigFunction()
{
  console.log(window.location.href)
  if (isSignInWithEmailLink(auth, signinwithemaillink)) {
    // Additional state parameters can also be passed via URL.
    // This can be used to continue the user's intended action before triggering
    // the sign-in operation.
    // Get the email if available. This should be available if the user completes
    // the flow on the same device where they started it.
    let email = window.localStorage.getItem('emailForSignIn');
    if (!email) {
      // User opened the link on a different device. To prevent session fixation
      // attacks, ask the user to provide the associated email again. For example:
      email = '[email protected]';
    }
    
    // The client SDK will parse the code from the link for you.
    signInWithEmailLink(auth, email, signinwithemaillink)
      .then((result) => {
        alert("all good")
        console.log(result.user)
        // Clear email from storage.
        window.localStorage.removeItem('emailForSignIn');
        // You can access the new user via result.user
        // Additional user info profile not available via:
        // result.additionalUserInfo.profile == null
        // You can check if the user is new or existing:
        // result.additionalUserInfo.isNewUser
      })
      .catch((error) => {
        console.log(error.code)
        // Some error occurred, you can inspect the code: error.code
        // Common errors could be invalid email and invalid or expired OTPs.
      });
  }  
}

As you can tell there is still an incredible amount of comments from the firebase docs, Im just trying to get this to work.

JavaScript Input File Not Storing Contents When I Add More Content to Upload

Alright so I’m looking so much to this code that I can’t figure it out anymore.

So I have a “Select Files” button that I allow users choose multiple files to upload:

<input type="file" multiple id="gallery-photo-add" name="file[]" class="form-control custom-file-input btn btn-info" value="">

Below is the JavaScript. Everything works except this behavior:

  • I click and select 1 file to send. It does everything right and send it to the preview. If I click to add more files, it resets the input value and remove the ones I added before. Just from the input, not from the previews.

    var imagesPreview = function (input) {

      if (input.files) {
    
          // remove main principal
          $('.no-image').parent().remove();
    
          // get total files sent this time
          var filesAmount = input.files.length;
    
          // get existent files in carousel
          var totalItens = $('.carousel-inner > .item').length;
    
          // sum all items
          var itensSum = (filesAmount + totalItens);
    
          // update total in title
          $('.slider-total-items > span').html('(' + itensSum + ')');
    
          var reader = new FileReader();
    
          for (i = 0; i < filesAmount; i++) {
    
              reader.onload = function (event) {
    
                  $('.carousel-inner > .item').removeClass('active');
    
                  if (input.files[0].type.substr(0, 5) == 'video') {
                      var html = '<div class="item ' + (i == 0 ? 'active' : '') + '"><video width="320" height="210" controls><source src="' + event.target.result + '"></video></div>';
                      return
                  }
    
                  if (filesAmount > 1) {
                      var html = '<div class="item text-center posts-images-edit ' + (i == filesAmount ? 'active' : '') + '"><img src="' + event.target.result + '"></div>';
                  } else {
                      var html = '<div class="item text-center posts-images-edit ' + (i == 1 ? 'active' : '') + '"><img src="' + event.target.result + '"></div>';
                  }
    
                  $(html).appendTo('.carousel-inner');
              }
    
              if (itensSum > 1) {
                  $('#galleryControls').removeClass('hide');
              }
    
              reader.readAsDataURL(input.files[i]);
          }
      }
    

    };

    $(function () {
    $(‘#gallery-photo-add’).on(‘change’, function () {
    imagesPreview(this);
    });
    });

How can I keep all the files selected on the input?

Thanks

How to solve to define module error “ReferenceError: PostgresHandler is not defined”? [duplicate]

This part is part of ../utils/PostgresHandler.js


const DBString = {
    ...
        skip db information
    ...
};

const { Pool } = require('pg');

const PostgresHandler = function() {
    const self = this;
    
    this.read = function(queries, success, error, done) {
        this.ready();
        let pool = this.pool;
        
        // async/await - check out a client
        ;(async () => {
            const client = await pool.connect();
            try {
                for (let i = 0; i < queries.length; i++) {
                    const query = queries[i];
                    
                    Logger.debug("=== read query === i :: "+ i + " ===");
                    Logger.debug(query);
                    Logger.debug("=============== ");
                    
                    const result = await client.query(query);
                    success(i, result.rows);
                }
            } catch (err) {
                throw err;
            } finally {
                // Make sure to release the client before any error handling,
                // just in case the error handling itself throws an error.
                client.release();
                self.poolCount++;
                Logger.debug("client release" + self.poolCount);
            }
            
            done();
        })().catch(err => {
            Logger.error(self.TAG + " read error occurred");
            Logger.error(err.stack);
            
            error(err);
            
            done();
        });
        
    };
    
    
    this.pool = this.getPool();
    
    this.ready = function() {
        if (this.pool == null) {
            this.pool = this.getPool();
        }
    };
    
    this.finish = function() {
        this.releasePool(this.pool);
        
        this.pool = null;
    };
    
};

module.exports = new PostgresHandler();

and, this part is part of ../utils/DataHandler.js
When I run this project, “app.js” call trans function of DataHandler.js.

this.trans = function(sql, callback) {
    const postgresHandler = new PostgresHandler();
    const pool = postgresHandler.getPool();
        
    postgresHandler.read(pool, [sql], (index, result) => {
        
    }, (err) => {
        
    }, () => {
        Logger.debug("Data Transaction Done");
        postgresHandler.releasePool(pool);
    });
};

If I call “this.trans” function of DataHandler.js, it occurs error this point.
“ReferenceError: PostgresHandler is not defined”

const postgresHandler = new PostgresHandler();

Why occurred ReferenceError?
I don’t understand to occur this error.
What am I doing wrong?

Typescript throws warning when using JSON objects with types

I’m trying to get the properties of this JSON object inside a hook, using bracket notation. I’m sure this is working but Typescript keeps throwing that warning:

Property ‘github’ does not exist on type ‘PropertyValues’

useI18n.ts

import { useRouter } from 'next/router'
import i18n from 'i18n/index.json'

type JSONRaw = typeof i18n
type Name = keyof JSONRaw
type Language = keyof JSONRaw[Name]
type Selection = JSONRaw[Name]
type Property = Pick<Selection, Language>
type PropertyValues = Property[Language]

export default function useI18n (name: Name) {
  const { locale } = useRouter()

  const JSONFile: JSONRaw = i18n
  const wantedTextList = JSONFile[name]
  const localeLanguage = locale as Language
  const value = wantedTextList[localeLanguage]
  return value as PropertyValues
}

JSON

{
  "header": {
    "es-ar": {
      "text": "lorem ipsum 2."
    },
    "en-us": {
      "text": "lorem ipsum."
    }
  },
  "preferences": {
    "es-ar": {
      "text": "lorem ipsum 2"
    },
    "en-us": {
      "text": "lorem ipsum"
    }
  },
  
  "notavaible": {
    "es-ar": {
      "text": "lorem ipsum 2"
    },
    "en-us": {
      "text": "lorem ipsum"
    }
  },
  "postnav": {
    "en-us": {
      "github": "lorem ipsum 2",
      "edit": " lorem ipsum"
    },
    "es-ar": {
      "github": "lorem ipsum 2",
      "edit": "lorem ipsum"
    }
  }
}

Here’s the hook usage:

const { github, edit } = useI18n('postnav')

I expect to get the right types and scale it easy

add zoom and scroll buttons in pdf.js

According to this example: https://jsfiddle.net/pdfjs/wagvs9Lf/

What would be required to add zoomIn and zoomOut buttons(+ and -), and then add scroll buttons (left, right, up, down) or scroll bar so the user can access content that goes outside the borders after zooming.

The code below works for zooming in, however, there is no way to view content outside the edges after zooming

pdfDoc.getPage(pageNum).then(function(page){
   var viewport = page.getViewport({scale: 2});
   canvas.width = viewport.width;
   canvas.height = viewport.height;
   page.render({ canvasContext:ctx, 
                 viewport: viewport })
 })

Any help is greatly appreciated.

How do you grab an element and dynamically add or remove styles from it in react native

I’m coming from the world of React and trying to translate a component into React Native. In react we can easily grab an element with useRef and then add or remove classes.

Is there a way to easily translate this to react native as I see when I inspect the current property of the <Text> element it looks nothing like an html element.

Here is the file I’m trying to convert:

import React, {useState, useEffect, useRef} from 'react';

// styles
import styles from './whiteTextReveal.module.css';

export const WhiteTextReveal = props => {
    // props
    const {text, duration, callback} = props;
    // local
    const leftMask = useRef(null);
    const rightMask = useRef(null);
    const textRef = useRef(null);
    const animationTimeouts = useRef([]);

    useEffect(() => {
        reveal();
        return () => {
            animationTimeouts.current.map(val => clearTimeout(val));
        }
    }, [text]);

    function reveal() {
        let time = 0;
        // reveal first white masks
        const timeout1 = setTimeout(() => {
            // cleanup if called successively
            textRef.current.classList.remove(styles.shrink);
            leftMask.current.classList.remove(styles.moveRight);
            rightMask.current.classList.remove(styles.moveLeft);

            leftMask.current.classList.add(styles.moveLeft);
            rightMask.current.classList.add(styles.moveRight);
        }, 1000*time);
        animationTimeouts.current = [...animationTimeouts.current, timeout1];

        // reveal text behind first white mask
        time = time + .8; // come from the css file .mask.left.moveLeft
        const timeout2 = setTimeout(() => {
            textRef.current.classList.remove(styles.hide);
            leftMask.current.classList.remove(styles.moveLeft);
            rightMask.current.classList.remove(styles.moveRight);

            leftMask.current.classList.add(styles.moveRight);
            rightMask.current.classList.add(styles.moveLeft);
        }, 1000*time);
        animationTimeouts.current = [...animationTimeouts.current, timeout2];

        // move mask to cover text again
        time = time + .5 + duration; // come from the css file .mask.left.moveRight
        const timeout3 = setTimeout(() => {
            textRef.current.classList.add(styles.shrink);
            const timeout4 = setTimeout(() => {
                textRef.current.classList.add(styles.hide);
                callback()
            }, .7*1000);
            animationTimeouts.current = [...animationTimeouts.current, timeout4];
        }, time*1000);
        animationTimeouts.current = [...animationTimeouts.current, timeout3];

    }
    return (
        <div className={styles.container}>
            <span ref={textRef} className={`${styles.text} ${styles.hide}`}>{text}</span>
            <div ref={leftMask} className={`${styles.mask} ${styles.left}`}/>
            <div ref={rightMask} className={`${styles.mask} ${styles.right}`}/>
        </div>
    )
};

This is a text animation reveal that paints a white strip over text, slides back, and the scales the text to 0 before telling the parent component it finished.

As you can see from these lines:

textRef.current.classList.remove(styles.shrink);
leftMask.current.classList.remove(styles.moveRight);
rightMask.current.classList.remove(styles.moveLeft);

I am grabbing the ref and then removing classes. And the lines that follow after add those classes back in specific ways.

Hey guys I’m having trouble starting my react application, anyone know how what my problem is?

`{
  "name": "google-clone",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "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"
    ]
  }
}`{

Hey guys I’m trying to start my react app and every here is the package.json File and I have no clue what I’m doing wrong…I have looked online and they tell people to add the “scripts” and the “start” but I already have those, I litterally have no idea why my npm start won’t work. Anyone have some advice?

npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path C:UserspeytoOneDriveDesktopgoogle-clone/package.json
npm ERR! errno -4058
npm ERR! enoent ENOENT: no such file or directory, open ‘C:UserspeytoOneDriveDesktopgoogle-clonepackage.json’
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

npm ERR! A complete log of this run can be found in:
npm ERR! C:UserspeytoAppDataLocalnpm-cache_logs2023-02-08T01_50_32_942Z-debug-0.log

It is throwing me this error when I try and npm start the application any advice would be appriciated.

How to get element on click in Chart Js?

I’m adding Chart Js in my react app to display data as bar chart. The code works and I can display data correctly, the only issue I’m facing is that if one of the data values is too high, bar chart will only display it

enter image description here

As you can see on this image, if data for January is 100,000 and for other months it’s less than 10,000, we can only see data for January. When I click on element for data (January) I get index 0, I need to get index for all elements for other months, for example when I click on white space for February I should get index 1 etc.

Code Sandbox – link

My code:

import React, { useRef } from "react";
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend
} from "chart.js";
import { Bar, getElementAtEvent } from "react-chartjs-2";

ChartJS.register(
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend
);

export const options = {
  responsive: true,
  plugins: {
    legend: {
      position: "top"
    },
    title: {
      display: true,
      text: "Chart.js Bar Chart"
    }
  }
};

const labels = ["January", "February", "March", "April", "May", "June", "July"];

export const data = {
  labels,
  datasets: [
    {
      label: "Dataset 1",
      data: [100000, 500, 40],
      backgroundColor: "rgba(255, 99, 132, 0.5)"
    }
  ]
};

export default function App() {
  const barRef = useRef();

  const handleGetData = (event) => {
    console.log(getElementAtEvent(barRef.current, event)[0]?.index);
  };

  return (
    <Bar ref={barRef} options={options} data={data} onClick={handleGetData} />
  );
}

How can I get the index for February in this case? If I click on white space, getElementAtEvent(barRef.current, event)[0]?.index returns undefined.

I am not able to import a code from another file

I’m trying to import my code functions from one file to another, however, it’s not working.

Look at the file I’m exporting from:

const uri = "mongodb+srv://<User>:<PassWord>@cluster0.ubhacr9.mongodb.net/?retryWrites=true&w=majority"



const client = new MongoClient(uri);


async function run(){
    //code
}

async function inserirDatabase(tipo, descricao, valor, id){
   //code
}

async function readDatabase (){
    //code
}

async function deleteOneOnDatabase(id){
   //code
}

module.exports = run, inserirDatabase, readDatabase, deleteOneOnDatabase 

Look how I’m importing the file:
import {run, inserirDatabase, readDatabase, deleteOneOnDatabase} from '../database/database.js';

Combined error “Error : ValidationError: Expected a boolean primitive” and ” ValidationError: Expected undefined or null”

Hello ! I am a newbie to code and i needed help for this … After ive done the slash commands part ,everytime i try to run my code i get these errors .. May someone help me ? Thanks in advance !

ValidationError: Expected undefined or null
at NullishValidator.handle (C:UsersBryanDesktopVegetable [email protected]:748:79)
at NullishValidator.run (C:UsersBryanDesktopVegetable [email protected]:187:23)
at UnionValidator.handle (C:UsersBryanDesktopVegetable [email protected]:1083:32)
at UnionValidator.parse (C:UsersBryanDesktopVegetable [email protected]:201:88)
at validateDMPermission (C:UsersBryanDesktopVegetable [email protected]:952:25)
at MixedClass.setDMPermission (C:UsersBryanDesktopVegetable [email protected]:1434:5)
at C:UsersBryanDesktopVegetable v1.2LoadersloadSlashCommands.js:14:10
at Collection.forEach ()
at module.exports (C:UsersBryanDesktopVegetable v1.2LoadersloadSlashCommands.js:9:18)
at module.exports (C:UsersBryanDesktopVegetable v1.2Eventsready.js:6:11) {
validator: ‘s.nullish’,
given: ‘true’
},
ValidationError: Expected a boolean primitive
at BooleanValidator.handle (C:UsersBryanDesktopVegetable [email protected]:582:71)
at BooleanValidator.run (C:UsersBryanDesktopVegetable [email protected]:187:23)
at UnionValidator.handle (C:UsersBryanDesktopVegetable [email protected]:1083:32)
at UnionValidator.parse (C:UsersBryanDesktopVegetable [email protected]:201:88)
at validateDMPermission (C:UsersBryanDesktopVegetable [email protected]:952:25)
at MixedClass.setDMPermission (C:UsersBryanDesktopVegetable [email protected]:1434:5)
at C:UsersBryanDesktopVegetable v1.2LoadersloadSlashCommands.js:14:10
at Collection.forEach ()
at module.exports (C:UsersBryanDesktopVegetable v1.2LoadersloadSlashCommands.js:9:18)
at module.exports (C:UsersBryanDesktopVegetable v1.2Eventsready.js:6:11) {
validator: ‘s.boolean’,
given: ‘true’
}
]
}

Node.js v18.14.0

Here is my loadSlashCommands file :

const Discord = require('discord.js')
const { REST } = require('@discordjs/rest')
const { Routes } = require('discord.js')

module.exports = async bot => {

    let commands = [];

    bot.commands.forEach(async command => {

        let slashcommand = new Discord.SlashCommandBuilder()
        .setName(command.name)
        .setDescription(command.description)
        .setDMPermission(command.dm) 
        .setDefaultMemberPermissions(command.permission === "Aucune" ? null : command.permission)

        if(command.options?.length >= 1) {
            for(let i = 0; i < command.options.length; i++) {
                slashcommand[`add${command.options[i].type.slice(0, 1).toUpperCase() + command.options[i].type.slice(1, command.options[i].type.length)}Option`](option => option.setName(command.options[i].name).setDescription(command.options[i].description).setRequired(command.options[i].required))
            }
        }

        await commands.push(slashcommand)
    })

    const rest = new REST({version: '10'}).setToken(bot.token)

    await rest.put(Routes.applicationCommands(bot.user.id), {body: commands})
    
    console.log("Les slash commandes sont crées avec succès !")
}

Here is my ready file :

const Discord = require("discord.js")
const loadSlashCommands = require("../Loaders/loadSlashCommands")

module.exports = async bot => {

    await loadSlashCommands(bot)

    console.log(`${bot.user.tag} est bien en ligne !`)
} 

I have tried to search the reasons of these errors like changing values etc.. But as i said , im new to coding and i dont understand very well ..

How to change the icon of NWJS APP on taskbar?

Ive tried 64, 32px, 24px, 16px FAVICON.png in the same DIR as the manifest file. No luck. I also tried and ICO with ever 32bit size.

package.json

{

    "main": "INDEX.html",
    "name": "cacluclator",
    "description": "NWJS SMART CALCULATOR",
    "version": "00.00.00",
    "keywords": [ "SMART CALCULATOR", "INSECURITY" ],

    "window": {

        "title": "SMART CALCULATOR",
        "icon": "FAVICON 32.png",

        "frame": false,
        "toolbar": true,
        "transparent": true,
        "position": "center",

        "height": 500,
        "min_height": 500,
        "max_height": 500,

        "width": 400,
        "min_width": 400,
        "max_width": 400

    },

    "webkit": {

      "plugin": true

    }

  }

Using `cy.request()` command how to get `meta` tag and `script` tag contents

Using cy.request() command how to get meta tag and script tag content. Example given below:

<meta data-n-head="ssr" data-hid="og-title" property="og:title" content="Blue zone booking area">

<script data-n-head="ssr" data-hid="nuxt-jsonld-6378ffa8" type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","headline":"Parcel area for Blue Zone one","url":"https://staging.booking.com/au/booking-area/zone/blue/"}</script>

I have tried cy.wrap($meta) and iterate but it doesn’t work ?. Can anyone suggest how can we grab content=”Blue zone booking area” attribute from meta tag and headline attribute content from the script tag ?

note : This is not a front end test, here I am using cy.request() to make sure that the SEO/SSR are looking good in our website

 cy.request(apiHelper.makeGeneralRequestObject("au/booking-area/zone/blue/")).then(
        (response) => {
          const htmlString = response.body;
          const parser = new DOMParser();
          const parseHtml = parser.parseFromString(htmlString, 'text/html');
         const $meta = parseHtml.getElementsByTagName('meta');
        $meta.each(($elem)=>{
        // how to get at here             
      })
    });

How to loop slides in custom javascript?

I’m a beginner in javascript. I downloaded a custom javacsript slide from this website:

https://www.cssscript.com/swiper-thumbnail-paginator/

Slide demo here: https://www.cssscript.com/demo/swiper-thumbnail-paginator/

I’ve also created a demo on jsfiddle: https://jsfiddle.net/t4c1nb3g/

The file consists of 5 files, namely: index.html, style.css, debounce.js, script.js, slide.js

And it has 6 images.

Currently, there is no slide loop in the demo, I want to change it to play the slides continuously (looping).

How can I make it loop for the slide?

Below is the index.html file:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Slider</title>
  <link rel="stylesheet" href="css/style.css">
</head>

<body>
  <div class="slide-wrapper">
    <ul class="slide">
      <li><img src="https://i.stack.imgur.com/2fkLR.jpg" alt=""></li>
      <li><img src="https://i.stack.imgur.com/gN1Ri.jpg" alt=""></li>
      <li><img src="https://i.stack.imgur.com/FgqYP.jpg" alt=""></li>
      <li><img src="https://i.stack.imgur.com/su1na.jpg" alt=""></li>
      <li><img src="https://i.stack.imgur.com/vZYry.jpg" alt=""></li>
      <li><img src="https://i.stack.imgur.com/5dXtQ.jpg" alt=""></li>
    </ul>
  </div>
  <div class="wrap-controls">
    <div class="arrow-nav">
      <button class="prev"></button>
    </div>
    <ul class="custom-controls">
      <li><img src="https://i.stack.imgur.com/2fkLR.jpg" alt=""></li>
      <li><img src="https://i.stack.imgur.com/gN1Ri.jpg" alt=""></li>
      <li><img src="https://i.stack.imgur.com/FgqYP.jpg" alt=""></li>
      <li><img src="https://i.stack.imgur.com/su1na.jpg" alt=""></li>
      <li><img src="https://i.stack.imgur.com/vZYry.jpg" alt=""></li>
      <li><img src="https://i.stack.imgur.com/5dXtQ.jpg" alt=""></li>
    </ul>
    <div class="arrow-nav">
      <button class="next"></button>
    </div>
  </div>
  <script type="module" src="js/script.js"></script>
</body>

</html>

Below is the style.css file:

body {
  margin: 0px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

ul {
  padding: 0px;
  margin: 0px;
  list-style: none;
}

img {
  display: block;
  max-width: 100%;
}

.slide-wrapper {
  overflow: hidden;
}

.slide {
  display: flex;
}

.slide:hover {
  will-change: transform;
}

.slide li {
  flex-shrink: 0;
  max-width: 600px;
  margin: 0 20px;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 2px 4px rgba(0,0,0,.4);
  opacity: .8;
  transform: scale(.8);
  transition: .4s;
}

.slide li.active {
  opacity: 1;
  transform: scale(1);
}

[data-control="slide"] {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

[data-control="slide"] li a {
  display: block;
  width: 12px;
  height: 12px;
  background: #FB5;
  border-radius: 50%;
  overflow: hidden;
  text-indent: -999px;
  margin: 5px;
}

[data-control="slide"] li.active a, [data-control="slide"] li a:hover {
  background: #E54;
}

.custom-controls {
  display: flex;
  justify-content: center;
  margin-top: 40px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.custom-controls li {
  opacity: .8;
  transform: scale(.8);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  overflow: hidden;
  margin: 2px;
  box-shadow: 0 2px 2px rgba(0,0,0,.5);
  transition: .3s;
  cursor: pointer;
}

.custom-controls li.active {
  opacity: 1;
  transform: scale(1);
}

.arrow-nav {
  display: flex;
  justify-content: space-around;
  margin: 20px 10px 0 10px;
}

.arrow-nav button {
  cursor: pointer;
  border: none;
  border-radius: 50%;
  color: white;
  width: 30px;
  height: 30px;
  background: #999 url('../img/arrow.svg') center center no-repeat;
  outline: none;
}

.arrow-nav button:hover {
  background: #333 url('../img/arrow.svg') center center no-repeat;
  transition: ease-in-out .3s;
}

.arrow-nav button.prev {
  transform: rotate(-180deg);
}

.wrap-controls {
  display: flex;
  justify-content: center;
  align-items: center;
}

Below is the debounce.js file:

export default function debounce(callback, delay) {
  let timer;
  return (...args) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      callback(...args);
      timer = null;
    }, delay);
  };
}

Below is the script.js file:

import SlideNav from './slide.js';

const slide = new SlideNav('.slide', '.slide-wrapper');
slide.init();
slide.addArrow('.prev', '.next');
slide.addControl('.custom-controls');

Below is the slide.js file:

import debounce from './debounce.js';

export class Slide {
  constructor(slide, wrapper) {
    this.slide = document.querySelector(slide)
    this.wrapper = document.querySelector(wrapper);
    this.dist = { finalPosition: 0, startX: 0, movement: 0 }
    this.activeClass = 'active';
    this.changeEvent = new Event('changeEvent');
  }

  transition(active) {
    this.slide.style.transition = active ? 'transform .3s' : '';
  }

  moveSlide(distX) {
    this.dist.movePosition = distX;
    this.slide.style.transform = `translate3d(${distX}px, 0, 0)`;
  }

  updatePosition(clientX) {
    this.dist.movement = (this.dist.startX - clientX) * 1.6;
    return this.dist.finalPosition - this.dist.movement;
  }

  onStart(event) {
    let movetype;
    if (event.type === 'mousedown') {
      event.preventDefault();
      this.dist.startX = event.clientX;
      movetype = 'mousemove';
    } else {
      this.dist.startX = event.changedTouches[0].clientX;
      movetype = 'touchmove';
    }
    this.wrapper.addEventListener(movetype, this.onMove);
    this.transition(false);
  }

  onMove(event) {
    const pointerPosition = (event.type === 'mousemove') ? event.clientX : event.changedTouches[0].clientX;
    const finalPosition = this.updatePosition(pointerPosition);
    this.moveSlide(finalPosition);
  }

  onEnd(event) {
    const movetype = (event.type === 'mouseup') ? 'mousemove' : 'touchmove';
    this.wrapper.removeEventListener(movetype, this.onMove);
    this.dist.finalPosition = this.dist.movePosition;
    this.transition(true);
    this.changeSlideOnEnd();
  }

  changeSlideOnEnd() {
    if (this.dist.movement > 120 && this.index.next !== undefined) {
      this.activeNextSlide();
    } else if (this.dist.movement < -120 && this.index.prev !== undefined) {
      this.activePrevSlide();
    } else {
      this.changeSlide(this.index.active);
    }
  }

  addSlideEvents() {
    this.wrapper.addEventListener('mousedown', this.onStart);
    this.wrapper.addEventListener('touchstart', this.onStart);
    this.wrapper.addEventListener('mouseup', this.onEnd);
    this.wrapper.addEventListener('touchend', this.onEnd);
  }

  // Slides config

  slidePosition(slide) {
    const margin = (this.wrapper.offsetWidth - slide.offsetWidth) / 2;
    return -(slide.offsetLeft - margin);
  }

  slidesConfig() {
    this.slideArray = [...this.slide.children].map((element) => {
      const position = this.slidePosition(element);
      return { position, element };
    });
  }

  slidesIndexNav(index) {
    const last = this.slideArray.length - 1;
    this.index = {
      prev: index ? index - 1 : undefined,
      active: index,
      next: index === last ? undefined : index + 1,
    }
  }

  changeSlide(index) {
    const activeSlide = this.slideArray[index];
    this.moveSlide(activeSlide.position);
    this.slidesIndexNav(index);
    this.dist.finalPosition = activeSlide.position;
    this.changeActiveClass();
    this.wrapper.dispatchEvent(this.changeEvent);
  }

  changeActiveClass() {
    this.slideArray.forEach(item => item.element.classList.remove(this.activeClass));
    this.slideArray[this.index.active].element.classList.add(this.activeClass);
  }

  activePrevSlide() {
    if (this.index.prev !== undefined) this.changeSlide(this.index.prev);
  }

  activeNextSlide() {
    if (this.index.next !== undefined) this.changeSlide(this.index.next);
  }

  onResize() {
    setTimeout(() => {
      this.slidesConfig();
      this.changeSlide(this.index.active);
    }, 1000);
  }

  addResizeEvent() {
    window.addEventListener('resize', this.onResize);
  }

  bindEvents() {
    this.onStart = this.onStart.bind(this);
    this.onMove = this.onMove.bind(this);
    this.onEnd = this.onEnd.bind(this);

    this.activePrevSlide = this.activePrevSlide.bind(this);
    this.activeNextSlide = this.activeNextSlide.bind(this);

    this.onResize = debounce(this.onResize.bind(this), 200);
  }

  init() {
    this.bindEvents();
    this.transition(true);
    this.addSlideEvents();
    this.slidesConfig();
    this.addResizeEvent();
    this.changeSlide(0);
    return this;
  }
}

export default class SlideNav extends Slide {
  constructor(slide, wrapper) {
    super(slide, wrapper);
    this.bindControlEvents();
  }

  addArrow(prev, next) {
    this.prevElement = document.querySelector(prev);
    this.nextElement = document.querySelector(next);
    this.addArrowEvent();
  }

  addArrowEvent() {
    this.prevElement.addEventListener('click', this.activePrevSlide);
    this.nextElement.addEventListener('click', this.activeNextSlide);
  }

  createControl() {
    const control = document.createElement('ul');
    control.dataset.control = 'slide';
    this.slideArray.forEach((item, index) => {
      control.innerHTML += `<li><a href="#slide${index + 1}">${index + 1}</a></li>`;
    });
    this.wrapper.appendChild(control);
    return control;
  }

  eventControl(item, index) {
    item.addEventListener('click', (event) => {
      event.preventDefault();
      this.changeSlide(index);
    });
    this.wrapper.addEventListener('changeEvent', this.activeControlItem);
  }

  activeControlItem() {
    this.controlArray.forEach(item => item.classList.remove(this.activeClass));
    this.controlArray[this.index.active].classList.add(this.activeClass);
  }

  addControl(customControl) {
    this.control = document.querySelector(customControl) || this.createControl();
    this.controlArray = [...this.control.children];

    this.activeControlItem();
    this.controlArray.forEach(this.eventControl);
  }

  bindControlEvents() {
    this.eventControl = this.eventControl.bind(this);
    this.activeControlItem = this.activeControlItem.bind(this);
  }
}

Thank you very much,

best regards.

Franks.

Optimizing Node.js API Performance

What are some of the best practices and strategies for optimizing the performance of Node.js APIs?

Considerations might include efficient database queries, reducing the number of API calls, caching, and using efficient data structures.

Are there any tools or libraries that are particularly useful for this goal? Any real-world examples of successfully optimized Node.js APIs would be appreciated.