Should I explicitly write the public keyword or omit it when visibility isn’t relevant in a TypeScript/JavaScript class?

In a TypeScript project (Angular / NestJS), I’m working on a class where all methods are intended to be accessible by other parts of the app. There are no private or protected members in this file—everything is effectively public.

Some developers explicitly declare public for every method:

public funcName(): void {
  // ...
}

Others prefer to rely on the default (public) visibility and omit it:

funcName(): void {
  // ...
}

My reasoning:

  • Since there’s nothing in this file that deals with visibility, adding public creates a misleading emphasis—making others think access level matters here.
  • It can cause developers to pause and wonder: “Why is this public?” or “Is something else private?”
  • Omitting public in such cases avoids unnecessary visual noise and mental overhead.
  • It also keeps things cleaner and more consistent with the rest of the codebase, which tends to only use access modifiers when needed.

Question:

From a readability and consistency perspective, which approach is preferred in the TypeScript/JavaScript community?

  1. Explicitly write public for clarity, even when everything is already public?
  2. Omit public when visibility isn’t relevant, to keep the code simple and intention-focused?

Would love to hear how others approach this in real-world projects.

This is my first ever javascript code and its not working properly

  var dinethmaIsMine = 69;

if(dinethmaIsMine > 35){
    document.write("Dinethma is passed!");
}else if(dinethmaIsMine > 50){
    document.write("Dinethma is passed with a C grade!");
}else if(dinethmaIsMine > 60){
    document.write("Dinethma is passed with a B grade!");
}else if(dinethmaIsMine > 70){
    document.write("Dinethma is passed with a A grade!");
}else if(dinethmaIsMine > 80){
    document.write("Dinethma is passed with a A+ grade!");
}else{
    document.write("Dinethma is failed!");
}

And another thing is my VS code is showing this document.write() like this in the picture.

VS code issue

This is the error I get when its run on the chrome browser.

Error of localhost

Button with half image and half blurry gradient smoothly merge

How to develop this button, i have done some work. but i’m having issue is blur and image cut line is clearly visible which is not require. i want to merge smoothly blended image and blurry gradeint.
half image and half blurry gradient with no edge line.
see design and current button work with cut lines

.blend-button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20rem;
  height: 6rem;
  border: none;
  border-radius: 20px;
  overflow: hidden;

  /* bottom layer: your image */
  background: url("https://picsum.photos/300/300") no-repeat;
  background-size: 60% 100%;
  color: white;
  font-size: 2rem;
  font-weight: bold;
  cursor: pointer;
}

/* 1) Blur the right half  */
.blend-button::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 50%;
  height: 100%;


  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}


.blend-button::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 80%;
  height: 100%;

  background: linear-gradient(to left,
      rgba(112, 76, 52, 0.3),
      /* adjust to your “solid” color */
      rgba(112, 76, 52, 0)
      /* fully transparent */
    );
}


.blend-button span {
  position: relative;
  z-index: 1;
  text-align: center;
}
<button class="blend-button">
  <span>Testing</span>
</button>

expected design

my current button

How can I setup dynamic import path in react?

Im trying to setup dynamic import path in react. When i use hardcoded string like
import("@abc/order") it is working fine but when i use dynamic value for path, it is not working. How can i solve this issue. Here is my code snippets.

const Router = () => {
  const dynamicRoutes = routeConfig.map((route) => {
    const Components: any = Loadable({
      //@ts-ignore
      loader: () => import(`@ecommerce/order`).then(mod => mod[route.name]),
      loading: "Loading...",
    });
    return (<Route key={route.path} path={route.path} element={<Components />} />)
  });
  return (
    <Routes>
      <Route
        element={<DashboardLayout />}
      >
        {dynamicRoutes}
      </Route>
    </Routes>
  );
};

Above code is working fine, but when i replace @ecommerce/order with route.path it didn`t render components.

I try to solve this problem by creating functions but still it didnot work.

Browser doesn’t maintain history if JavaScript redirects without user action

I’m having trouble identifying whether this is a well-known issue:

Navigating the browser to a new page using any of the various methods which push the new URL onto the history stack, e.g. window.location = '...' or window.location.assign('...') or pushState({},"",...) or <a href="...", etc., will subsequently allow the user to return to the previous website / state with the back button — but only if the user “interacted” with the browser while that state was rendered on screen. In simpler terms, any navigation followed by an auto-navigation (where no user input was registered) prevents the initially-navigated-to state from being retained and revisited, whether the user may want to (back button) or not (history.go(-1)). It’s like that page never existed.

I set up a test page on w3schools’s code spaces to demo this:
https://anon2.w3spaces.com/saved-from-Tryit-2025-04-18.html

Mouseover events are not considered a user action. Neither are scroll events. You have to click, tap, or press a key. Note that the interaction doesn’t necessarily have to be with the page itself — it can also be with a bookmarketlet that runs some JavaScript in the page context, or it can be an interaction with the DevTools window attached to the page.

Without some interaction, the browser does not retain the page in its history. This seems to hold true regardless of how long the page remains on-screen. If you visit a webpage that has a scrolling news feed which you were reading for hours, and then a JS event caused a new page to load, without you having ever interacted with the browser (aside from whichever action initially loaded the page, and the user events previously mentioned) then you cannot use the back button to return to that page, and there is nothing the page’s developer can do to let you, even if they wanted to. As best I can tell, all modern browsers based on Chromium behave this way.

Where is this behavior documented?

Is it true that appending and submitting a hidden form is a valid workaround? (the linked question does not address the lack of user interaction with the page, but I assume that’s implied)

Elaboration on my use case:

I don’t have a good example of this causing real issues “in the wild” but I do have extensive experience with this issue appearing with my Tampermonkey user scripts. Let’s try a short thought experiment: Say you are searching for something on Amazon, and the query returns 50 pages of results. Say you wanted to create a simple user script that called click() on the “next page” nav button using setTimeout() with a delay of 6 seconds. Say you wanted to occasionally scroll down the items list as your script automatically runs through each page of the results. Say you eventually found something interesting — but right before you can click it (or interact), the script triggers a navigation to the next page. If you then press the back button, you are returned all the way back to the beginning — that is, the last page you had clicked on (interacted with), which is likely the first page of the results. Pressing the forward button takes you back to the page that is subsequent to the page with the item you were interested in. There is no history state for any page in between. Now admittedly, in this example you could disable your script and use the on-page navigation buttons to go back one page in the results, then re-scroll to the spot where the interesting item was. But if instead you were storing a list of URLs in localStorage that you cycled through with a stored index value that incremented each execution. In such case, there is no on-page navigation that will bring you back.

Browser doesn’t maintain history if JavaScript redirects prior to user interaction

I’m having trouble identifying whether this is a well-known issue:

Navigating the browser to a new page using any of the various methods which push the new URL onto the history stack, e.g. window.location = '...' or window.location.assign('...') or pushState({},"",...) or <a href="...", etc., will subsequently allow the user to return to the previous website / state with the back button — but only if the user “interacted” with the browser while that state was rendered on screen. In simpler terms, any navigation followed by an auto-navigation (where no user input was registered) prevents the initially-navigated-to state from being retained and revisited, whether the user may want to (back button) or not (history.go(-1)). It’s like that page never existed.

I set up a test page on w3schools’s code spaces to demo this:
https://anon2.w3spaces.com/saved-from-Tryit-2025-04-18.html

Mouseover events are not considered a user action. Neither are scroll events. You have to click, tap, or press a key. Note that the interaction doesn’t necessarily have to be with the page itself — it can also be with a bookmarketlet that runs some JavaScript in the page context, or it can be an interaction with the DevTools window attached to the page.

Without some interaction, the browser does not retain the page in its history. This seems to hold true regardless of how long the page remains on-screen. If you visit a webpage that has a scrolling news feed which you were reading for hours, and then a JS event caused a new page to load, without you having ever interacted with the browser (aside from whichever action initially loaded the page, and the user events previously mentioned) then you cannot use the back button to return to that page, and there is nothing the page’s developer can do to let you, even if they wanted to. As best I can tell, all modern browsers based on Chromium behave this way.

Where is this behavior documented?

Is it true that appending and submitting a hidden form is a valid workaround? (the linked question does not address the lack of user interaction with the page, but I assume that’s implied)

Elaboration on my use case:

I don’t have a good example of this causing real issues “in the wild” but I do have extensive experience with this issue appearing with my Tampermonkey user scripts. Let’s try a short thought experiment: Say you are searching for something on Amazon, and the query returns 50 pages of results. Say you wanted to create a simple user script that called click() on the “next page” nav button using setTimeout() with a delay of 6 seconds. Say you wanted to occasionally scroll down the items list as your script automatically runs through each page of the results. Say you eventually found something interesting — but right before you can click it (or interact), the script triggers a navigation to the next page. If you then press the back button, you are returned all the way back to the beginning — that is, the last page you had clicked on (interacted with), which is likely the first page of the results. Pressing the forward button takes you back to the page that is subsequent to the page with the item you were interested in. There is no history state for any page in between. Now admittedly, in this example you could disable your script and use the on-page navigation buttons to go back one page in the results, then re-scroll to the spot where the interesting item was. But if instead you were storing a list of URLs in localStorage that you cycled through with a stored index value that incremented each execution. In such case, there is no on-page navigation that will bring you back.

Issue with custom Capacitor Java plugin to work with Javascript app on Android

We are developping a custom Android app.
The app is coded on Javascript and we coded a plugin in Java who’s role is to read the USB port on the Android tablet.

Capacitor is used to bridge between the plug-in & the android javascript app.

Unfortunately, we’re unable to make the plug-in visible for the javascript app. Capacitor is not able to recognize it as a plugin and hence we cannot call it as a function.

Is there a good tutorial online I could check ?

Project structure

enter image description here

Bash commands to initialize the project

mkdir mon-plugin-capacitor
cd mon-plugin-capacitor
npm init
npm install @capacitor/core @capacitor/android
npm install --save-dev @capacitor/cli
npm install --save-dev vite
npx cap init MonPluginCapacitor com.example.plugin
npx cap add android
npm run build

Project structure

React/Next.js: Efficiently Determining Arcane Status for Characters with Multiple Vocations in a D&D Web App

I’m developing a D&D-inspired web application where characters can have multiple vocations (classes). I need to correctly determine if a character is “arcane” (can use magic) based on their vocations. A character is considered arcane if at least one of their vocations has arcaneWielding=true in the database.

I recently updated my database schema to support multiple vocations per character:

// In schema.prisma
model Character {
  // ...other fields
  vocations                 String[]            @default([])
  // ...more fields
}

I’m having issues with the mana calculation in my BodyAndBurden component, which needs to know if the character is arcane to calculate the correct mana value.

Here’s my current implementation:

// In BodyAndBurden.tsx
// Use the direct vocation arcane status hook
const { isArcane, loading: arcaneStatusLoading } = useVocationArcaneStatus(character.vocations);

// Memoize character mana calculation
const characterMana = useMemo(() => {
  // Determine if the character is arcane based solely on the hook value
  const isCharacterArcane = isArcane === true;
  
  // Calculate mana based on whether the character is arcane
  const calculatedMana = calculateCharacterMana(
    character.abilityCON, 
    character.abilityINT, 
    isCharacterArcane
  );
  
  return calculatedMana;
}, [
  character.abilityCON, 
  character.abilityINT,
  isArcane,
  arcaneStatusLoading,
  vocation
]);

The hook that checks arcane status:

// In useVocationArcaneStatus.ts
export function useVocationArcaneStatus(vocations: string | string[] | null) {
  const [isArcane, setIsArcane] = useState<boolean | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  
  useEffect(() => {
    if (!vocations) {
      setIsArcane(false);
      setLoading(false);
      return;
    }

    // Handle both string and array inputs
    let vocationNames: string[] = [];
    let vocationNameForApi: string;
    
    if (Array.isArray(vocations)) {
      // If vocations is already an array, use it directly
      vocationNames = vocations.filter(Boolean).map(v => v.toLowerCase());
      vocationNameForApi = vocations.join(',');
    } else {
      // If vocations is a string, split it (for backward compatibility)
      vocationNames = vocations.split(/[,;]/).map(v => v.trim().toLowerCase());
      vocationNameForApi = vocations;
    }

    const fetchArcaneStatus = async () => {
      try {
        // Fetch from API
        const response = await dataFetcher.fetch<{ isArcane: boolean }>(
          `/api/player-sheet/vocation-arcane-status?name=${encodeURIComponent(vocationNameForApi)}`
        );
        
        setIsArcane(response.isArcane);
        setError(null);
      } catch (err) {
        // Error handling...
      } finally {
        setLoading(false);
      }
    };

    fetchArcaneStatus();
  }, [vocations]);

  return { isArcane, loading, error };
}

The API endpoint:

// In vocation-arcane-status/route.ts
export async function GET(request: NextRequest) {
  // ...
  // Handle multiple vocations (comma or semicolon separated)
  const vocationNames = vocationName.split(/[,;]/).map(v => v.trim()).filter(Boolean);
  
  // If there are multiple vocations, check each one
  if (vocationNames.length > 1) {
    const vocations = await db.vocation.findMany({
      where: {
        name: {
          in: vocationNames
        }
      },
      select: {
        name: true,
        arcaneWielding: true
      }
    });
    
    // If any vocation is arcane, return true
    const isArcane = vocations.some(v => v.arcaneWielding);
    return { isArcane };
  }
  // ...
}

The mana calculation function:

export const calculateCharacterMana = (
  constitutionScore: number,
  intelligenceScore: number,
  isArcane: boolean
): number => {
  const constitutionModifier = calculateModifier(constitutionScore);
  const intelligenceModifier = calculateModifier(intelligenceScore);
  
  if (isArcane) {
    return 10 + constitutionModifier + intelligenceModifier;
  } else {
    return 5 + constitutionModifier;
  }
};

My Question
I’ve fixed a previous issue where we were hardcoding “arcanist” as an arcane vocation instead of properly querying the database. Now I want to ensure my implementation correctly handles multiple vocations.

What’s the most efficient and reliable way to determine if a character with multiple vocations is arcane (has at least one vocation with arcaneWielding=true)? I’m concerned about:

  • Race conditions in the hook
  • Proper handling of the loading state
  • Ensuring the mana calculation is correct when vocations change
  • Optimizing database queries for this common operation

Any suggestions for improving this implementation? I’m particularly interested in best practices for handling derived state that depends on multiple asynchronous data sources.

How do I make it so I have multiple audios on one page?

I’m working on a music page for my website, and I’m trying to put songs on it, but when I press them, it only plays one song.
I’ve tried to use , rename the id, and I’ve tried it without any separation, but it just doesn’t play the right song.
This is the code I currently have down. You can see i have Asong and Bsong, I just don’t understand why it still merges together??? If someone could redo my code, I’d be very thankful.
Thanks!

<div>
<button id="ASong" onClick="playandpause()">
  <audio
    src="https://archive.org/download/1998-01-suite-pee/04%20-%20Asking%20for%20It.mp3"

  ></audio>
  <img src="https://images-na.ssl-images-amazon.com/images/I/71uuPnDUZkL._SL1050_.jpg" height=200 />
  <p>
    Asking For It - Hole
  </p><script>
  var aud = document.getElementById("ASong").children[0];
  var isPlaying = false;
  aud.pause();

  function playandpause() {
    if (isPlaying) {
      aud.pause();
    } else {
      aud.play();
    }
    isPlaying = !isPlaying;
  }
</script>
</button>


</div>
<div>
<button id="BSong" onClick="playandpause()">
  <audio
    src="https://archive.org/download/1998-01-suite-pee/%281998%29%2001%20Suite-Pee.mp3"

  ></audio>
  <img src="https://th.bing.com/th/id/OIP.PkMiOQ02e2P13wIY7mYIKwAAAA?rs=1&pid=ImgDetMain" height=200 />
  <p>
    Suite-Pee - System Of A Down
  </p>
</button>


<script>
  var aud = document.getElementById("BSong").children[0];
  var isPlaying = false;
  aud.pause();

  function playandpause() {
    if (isPlaying) {
      aud.pause();
    } else {
      aud.play();
    }
    isPlaying = !isPlaying;
  }
</script>
</div>

Javascript toggle CSS Property to make an element sticky/not sticky

i have made a JS code to open and close an “accordion” though i want to have a toggle option to make the accordion sticky / not sticky (normal), the CSS snippet below will make the active accordion sticky when the user goes down in page:

.accordion.active {
                    position: sticky;
                    top: 2%;
            }

I want to have a toggle to switch if the users wants the accordion to be sticky or not. full code inserted below, please help.

            // the code snippet below allows for one accordion to be opened and closes the rest   
            const accordionEls = document.querySelectorAll('.accordion')
            const panelEls = document.querySelectorAll('.panel')

            accordionEls.forEach((acc) => {
                acc.addEventListener('click', ({ target }) => {
                    target.classList.toggle('active')
                    accordionEls.forEach(accordionEl => {
                        if (accordionEl !== target) {
                            accordionEl.classList.remove('active')
                        }
                    })
                    const { nextElementSibling } = target
                    panelEls.forEach(panelEl => {
                        if (panelEl !== nextElementSibling) {
                            panelEl.classList.remove('open')
                        } else {
                            panelEl.classList.toggle('open')
                        }
                    })
                }) 
            })
        body {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            background-color: White;
            font-family: Sakkal Majalla;
            direction: rtl;
            position: relative;
            text-align: center;
        }
      
        button{
            margin-top: 4rem;
            
        }

        .main{    
            display: grid;
            grid-template-columns: 1fr;
            justify-items: center;
            margin-top: 2rem;
            margin-bottom: 1rem;
        }

        table {
            border: 1px solid #dededf;  
            table-layout: fixed;
            border-collapse: collapse;
            border-spacing: 1px;
            text-align: center;
        }

        th {
            border: 1px solid #dededf;
            background-color: #eceff1;
            color: #000000;
            padding: 5px;
        }

        td {
            border: 1px solid #dededf;
            background-color: #ffffff;
            color: #000000;
            padding: 5px;  
        }
        th:nth-child(1) {  
            width: 30.9rem;
        }

        th:nth-child(2) {  
            width: 10rem;
        }
        th:nth-child(3) {  
            width: 7rem;
        }

        .accordion {
            background-color: #ffffff;
            color: black;
            font-weight: bold;
            cursor: pointer;
            margin-top: 20px;
            padding: 18px;
            border: none;
            text-align: right;
            outline: none;
            font-size: 20px;
            transition: 0.4s;
            width: 50rem;
            border: 1px solid rgb(219, 219, 219);
            border-radius: 8px;
            box-shadow: rgba(100, 100, 111, 0.123) 0px 7px 29px 0px;
        }

        .active, .accordion:hover {
            border-color:  rgb(0, 128, 255);
        }

        .accordion span{
            float: left;
            font-size: 15px;
            color: #116ce4;
        }
        
        /* this code makes the accordion become sticky if it's clicked "becomes active" */
        .accordion.active {
                position: sticky;
                top: 2%;
        }

        
        .panel {
            max-height: 0;
            overflow: hidden;
            transition: max-height 0.5s ease, padding 0.5s ease;
            padding: 0px;
        }

        .panel.open {
            max-height: 1000px;
            padding: 18px;
        }
        <button onclick="changeCSS()">TOGGLE STICKY ACCORDION / NOT STICKY ACCORDION</button>

        <div class="main">

            <button class="accordion">John Doe<span>7</span></button><div class="panel"><table><th>company</th><th>department</th><th>?</th><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td>company</td><td>HR</td><td>&#9989;</td></tr><tr><td>company</td><td>HR</td><td>&#10060;</td></tr><tr><td> company</td><td>HR</td><td>&#10060;</td></tr><tr><td> company</td><td>HR</td><td>&#10060;</td></tr><tr><td> company</td><td>HR</td><td>&#10060;</td></tr></table></div><button class="accordion">Smith Taylor<span>5</span></button><div class="panel"><table><th>company</th><th>department</th><th>?</th><tr><td> company</td><td>HR</td><td>&#9989;</td></tr><tr><td> company</td><td>HR</td><td>&#10060;</td></tr><tr><td> company</td><td>HR</td><td>&#10060;</td></tr><tr><td> company</td><td>HR</td><td>&#10060;</td></tr><tr><td>  company</td><td>HR</td><td>&#10060;</td></tr></table></div>
    </div>

Detect Last Iteration of For Each Loop

I am trying to write some code to insert my “finalNTE” XML only after the last OBX occurrence. What I have below is inserting it after each OBX.

Is there a way to know when you are on the last iteration of a for each loop?

for each(var obx in getSegmentsAfter(msg,msg.OBR[i],'OBX')){
    msg.insertChildAfter(obx, finalNTE) 
}

How to Solve Node mailer error while using godaddy’s email

So I was creating an otp authenticator component I had GoDaddy’s email and when I try to send any email. It returns this error

Error sending OTP: Error: connect ETIMEDOUT 92.204.80.1:25
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1634:16) {
  errno: -4039,
  code: 'ESOCKET',
  syscall: 'connect',
  address: '92.204.80.1',
  port: 25,
  command: 'CONN'
}
Error: Failed to send OTP. Please try again later.
    at sendOtpEmail
    throw new ERR_HTTP_INVALID_STATUS_CODE(originalStatusCode);
          ^

RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: {
  success: false,
  message: 'Your ID has been deleted or rejected, Create a new accout'
}

I tried adding and changing the ports to 587 but that too did not work.
Here is how my OTP Component looks so far


export const sendOtpEmail = async (email, otp) => {
  const transporter = nodemailer.createTransport({
    service: 'Godaddy',
    host: 'smtp.secureserver.net',
    secure: true,
    secureConnection: false,
    tls: {
      ciphers:'SSLv3',
    },
    requireTLS:true,
    port: 465,
    debug: true,
    auth: {
      user: process.env.EMAIL_USER,
      pass: process.env.EMAIL_PASS,
    },
  });

  const mailOptions = {
    from: process.env.EMAIL_USER,
    to: [email protected],
    subject: 'Your OTP Code',
    html: `
        <h1>Your OTP Code</h1>
    `,
  };

Thank You so much.
If anyone Could help that would be appreciated.

Adding Node to Python Firebase Function

I am trying to deploy a firebase function in python. In the main.py file I define a basic Flask server, this main.py imports fetch.py (another file -same directory- with my source code). The fetch.py file uses the python javascript package. I added javascript to requirements.txt too. This package needs Node.js installed in the environment. Is there any simple way I can add Node.js?

I saw these Docs but I feel like its not what I need because I am not calling any Node/JS code, rather Node just needs to be setup in the same environment. Calling this deploy command

gcloud functions deploy fetchPython                       
  --gen2 
  --runtime=python311 
  --region=us-central1 
  --entry-point=app 
  --trigger-http 
  --allow-unauthenticated

results in this

ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Could not create or update Cloud Run service fetchpython, Container Healthcheck failed. Revision ‘fetchpython-00003-muh’ is not ready and cannot serve traffic. The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable within the allocated timeout. This can happen when the container port is misconfigured or if the timeout is too short. The health check timeout can be extended. Logs for this revision might contain more information.

running gcloud functions logs read fetchPython --region=us-central1 I get:

LEVEL    NAME         EXECUTION_ID  TIME_UTC                 LOG
E        fetchpython                2025-04-17 21:54:58.739  Default STARTUP TCP probe failed 1 time consecutively for container "worker" on port 8080. The instance was not started.
                                                             Connection failed with status CANCELLED.
         fetchpython                2025-04-17 21:54:58.649  Exception: Timed out accessing 'console'
WARNING  fetchpython                2025-04-17 21:54:58.649  Container called exit(1).
         fetchpython                2025-04-17 21:54:58.345      raise Exception(f"Timed out accessing '{attr}'")
         fetchpython                2025-04-17 21:54:58.345    File "/layers/google.python.pip/pip/lib/python3.11/site-packages/javascript/proxy.py", line 43, in ipc
         fetchpython                2025-04-17 21:54:58.345             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         fetchpython                2025-04-17 21:54:58.345      resp = self.ipc("get", ffid, method)
         fetchpython                2025-04-17 21:54:58.345    File "/layers/google.python.pip/pip/lib/python3.11/site-packages/javascript/proxy.py", line 150, in getProp
         fetchpython                2025-04-17 21:54:58.345                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         fetchpython                2025-04-17 21:54:58.345      methodType, val = self._exe.getProp(self._pffid, attr)
         fetchpython                2025-04-17 21:54:58.343    File "/layers/google.python.pip/pip/lib/python3.11/site-packages/javascript/proxy.py", line 230, in __getattr__
         fetchpython                2025-04-17 21:54:58.343                ^^^^^^^^^^^^^^^^^^^^^^^^^
         fetchpython                2025-04-17 21:54:58.343      console = config.global_jsi.console  # TODO: Remove this in 1.0
         fetchpython                2025-04-17 21:54:58.343    File "/layers/google.python.pip/pip/lib/python3.11/site-packages/javascript/__init__.py", line 18, in init
         fetchpython                2025-04-17 21:54:58.343      init()
         fetchpython                2025-04-17 21:54:58.341    File "/layers/google.python.pip/pip/lib/python3.11/site-packages/javascript/__init__.py", line 27, in <module>
         fetchpython                2025-04-17 21:54:58.341      from javascript import require
         fetchpython                2025-04-17 21:54:58.341    File "/workspace/fetch.py", line 2, in <module>
         fetchpython                2025-04-17 21:54:58.341      from fetch import KeyFetcher
         fetchpython                2025-04-17 21:54:58.341    File "/workspace/main.py", line 3, in <module>

main.py

from flask import Flask, request, jsonify
from google.cloud import firestore
from fetch import KeyFetcher
import os

app = Flask(__name__)
db = firestore.Client()

@app.route('/keys', methods=['POST'])
def call_fetch():
    data = request.json
    version = data.get("version")

    if not version:
        return jsonify({"error": "Version is required"}), 401

    try:
        result = KeyFetcher(version).fetch_keys()
    except Exception as e:
        return jsonify({"parse error": e}), 401

    return jsonify({"result": result}), 200

if __name__ == '__main__':
    port = int(os.environ.get('PORT', 8080))
    app.run(host='0.0.0.0', port=port)

fetch.py

import base64, os, re, tempfile, threading, esprima
from javascript import require
from functools import wraps
from logger import Logger
from wasm import Wasm
import jsbeautifier
import requests
import binascii
import sys, os
import base64
import re

# My code here

Requirments.txt

firebase_functions~=0.1.0
flask
google-cloud-firestore
jsbeautifier
requests
esprima
javascript
colorama

Converting Terraform tfvars to JSON using javascript

I am currently trying to convert a terraform tfvar file as a string into a list of key value pairs for each attribute in the file. I have tried to use a few packages, such as js-hcl-parser and hcl2-json-parser, but it seems those convert the defined attributes vs an actual tfvar file. Do I need to create custom logic to parse the string that I give, or is there a package I can utilize that would save me the headache. The problem with creating my own parsing is that I need to be able to handle complex nested objects and arrays. Here’s an example of the file string I can have:

name=""
environment="deve"
subnet_name="app-compute-db"
create_new_resource_group=false
ant={
"test"="test",
"test2"={"TEST"=["test"]}
}