Javascript “arraybytes” format in Delphi

I’m receiving a JSON response from an API with the following format:

{
  "type": "Buffer",
  "data": [23, 23, 23, 23, 23]
}

In NodeJS, decoding this is simple. Here’s the code:

const response = await Api.get("endpoint", {
  params: {
    param1: value,
    param2: value,
  },
  responseType: "arraybuffer",
  headers: {
    Authorization: bearer,
  },
});

The response will have the decoded content I need.

In Delphi, I am using the native RESTClient to extract data from the API. The raw binary data didn’t fit my expectations. Here’s an example of the code I tried to extract the ByteArray from the JSON:

for i := 0 to DataArray.Count - 1 do
begin
  JSONValue := DataArray.Items[i];
  if JSONValue is TJSONNumber then
  begin
    ByteValue := StrToIntDef(TJSONNumber(JSONValue).ToString, 0) and $FF;
    ByteArray[i] := ByteValue;
  end;
end;

I tried converting the ByteArray in different encodings, but none of them worked as expected:

    //UTF-8:
    TEncoding.UTF8.GetString(ByteArray)//This raised an exception.
   
    //ISO-8859-1:
    TEncoding.GetEncoding(28591).GetString(ByteArray)//This resulted in incorrect content.
    
    //Windows-1252:
    TEncoding.GetEncoding(1252).GetString(ByteArray)//This also resulted in incorrect content.  

What I Want:

The content I am trying to extract is ZPL (Zebra Programming Language).

If you need more code or details to reproduce the issue, feel free to let me know, and I can share it.

Javascript onfocusout Uncaught TypeError

I have page where I want to force user to input certain pre defined values in a text box and if he does not inout those chosen values, focus is shifted back to that text box till user chooses one of the values. My code looks like this

function onloadfunction() {
  alert("On Load!");
  var sourcDealerId = document.getElementById("dsatext");
  sourcDealerId.focus();
}

function getFocusBack() {
  alert("Welcome Back Focus!");
  var sourcDealerId = document.getElementById("dsatext");
  if ((sourcDealerId.value != "DEALER") || (sourcDealerId.value != "MARKET")) {
    alert("Text Box Values::" + sourcDealerId.value)
    alert("Valid Values are DEALER OR MARKET only")
    sourcDealerId = "";
    sourcDealerId.focus();
  }
}
<input type="text" id="dsatext" onfocusout="getFocusBack()" />
<input type="text" id="othertext" />

However when i run this code I encounter following errors

  1. Even when I input values like DEALER or MARKET, it still alerts the message Valid Values are DEALER OR MARKET only
  2. Fcous is not shifted to first text box when i input wrong values
  3. I get the message Uncaught TypeError: sourcDealerId.focus is not a function in console . It pertains to line of code inside getFocusBack() function

Safari extension doesn’t load js files

I built extension but safari seems to have problem to load js files. html is loaded correctly. Same extension in chrome doesn’t seem to have any problem to find all the files.

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>TEST extension</title>
</head>

<body>

   <h3>TEST</h3>
    <script src="axios.min.js"></script>
    <script src="popup.js"></script>
</body>

</html>

popup.js has only

alert('works')

All these files are in Resources inside Shared (Extension) directory

My manifest:

{
  "manifest_version": 3,
  "default_locale": "en",
  "name": "test title",
  "description": "test description",
  "version": "1.0",

  "icons": {
    "48": "images/icon-48.png",
    "96": "images/icon-96.png",
    "128": "images/icon-128.png",
    "256": "images/icon-256.png",
    "512": "images/icon-512.png"
  },

  "background": {
    "scripts": ["background.js"],
    "type": "module"
  },

  "content_scripts": [
    {
      "js": ["content.js"],
      "matches": ["*://example.com/*"]
    }
  ],

  "action": {
    "default_popup": "popup.html",
    "default_icon": "images/toolbar-icon.svg"
  },

  "host_permissions": ["http://localhost:3000/*"],

  "permissions": []
}

Failed to load resource

enter image description here

enter image description here

Html code is not working in similar environment

I’m building an html-based branching interaction in Moodle. For the same code, it behaves differently in different Moodle environments.

The code makes sense and it did work perfectly in the staging environment. When I use the exact same code in the product environment, none of the buttons is responsive.

The code is as follows:

<div id="question1">
    <p>Have you only completed task A?</p>
</div>

<div id="question2" hidden>
    <p>Have you only completed task A and B?</p>
</div>

<div id="question3" hidden>
    <p>Have you only completed task A, B and C?</p>
</div>

<div id="result" hidden></div>

<div class="controls">
    <button id="yesBtn" onclick="handleYes()">Yes</button>
    <button id="noBtn" onclick="handleNo()">No</button>
    <button id="resetBtn" hidden onclick="handleReset()">Reset</button>
</div>

<script>
    let currentQuestionId = 'question1';
    let resetStack = [];

    const questions = {
        question1: {
            next: 'question2',
            verificationLinks: ['someURL'],
            verificationTexts: ['Task A'],
            nextTaskLinks: ['someURL', 'someURL', 'someURL'],
            nextTaskTexts: ['Task B', 'Task C', 'Task D']
        },
        question2: {
            next: 'question3',
            verificationLinks: ['someURL', 'someURL'],
            verificationTexts: ['Task A', 'Task B'],
            nextTaskLinks: ['someURL', 'someURL'],
            nextTaskTexts: ['Task C', 'Task D']
        },
        question3: {
            next: null,
            verificationLinks: ['someURL', 'someURL', 'someURL'],
            verificationTexts: ['Task A', 'Task B', 'Task C'],
            nextTaskLinks: ['someURL'],
            nextTaskTexts: ['Task D']
        }
    };

    function handleYes() {
        resetStack.push(currentQuestionId);
        const question = questions[currentQuestionId];

        if (question.verificationLinks) {
            showVerification(question.verificationLinks, question.verificationTexts, question.nextTaskLinks, question.nextTaskTexts);
        }

        toggleElement('noBtn', false);
        toggleElement('resetBtn', true);
    }

    function handleNo() {
        const question = questions[currentQuestionId];
        if (!question.next) return;

        resetStack.push(currentQuestionId);
        toggleElement(currentQuestionId, false);
        currentQuestionId = question.next;
        toggleElement(currentQuestionId, true);

        toggleElement('resetBtn', true);
        if (!questions[currentQuestionId].next) {
            toggleElement('noBtn', false);
        }
    }

    function handleReset() {
        if (resetStack.length === 0) return;

        toggleElement(currentQuestionId, false);
        toggleElement('result', false);

        currentQuestionId = resetStack.pop();
        toggleElement(currentQuestionId, true);

        toggleElement('noBtn', true);
        toggleElement('yesBtn', true);

        if (resetStack.length === 0) {
            toggleElement('resetBtn', false);
        }
    }

    function showVerification(verificationLinks, verificationTexts, nextTaskLinks, nextTaskTexts) {
        const resultBox = document.getElementById('result');
        resultBox.innerHTML = '<p>Please verify the following tasks:</p>';
        verificationLinks.forEach((link, index) => {
            resultBox.innerHTML += `<p><a href="${link}" target="_blank">${verificationTexts[index]}</a></p>`;
        });

        resultBox.innerHTML += '<p>The next Task you should complete:</p>';
        nextTaskLinks.forEach((link, index) => {
            resultBox.innerHTML += `<p><a href="${link}" target="_blank">${nextTaskTexts[index]}</a></p>`;
        });

        toggleElement('result', true);
        toggleElement('yesBtn', false);
    }

    function toggleElement(id, show) {
        const element = document.getElementById(id);
        if (show) {
            element.hidden = false;
        } else {
            element.hidden = true;
        }
    }
</script>

What could be the reason for this problem. The only difference as I know between the staging and product environments is the CSS setting.

Here are the things I’ve tried so far:

  • different browsers (Chrome, MS Edge, Firefox): not working
  • the code
  • force CSS overwriting: CSS code disappears in the editor after editing, not working
  • use inline onclick handlers: not working
  • use jQuery library: not working
  • I also tried simplified code to test button responsiveness in the product environment, although the code behaviour was not as expected, at least the buttons were somehow responsive. Here’s the simplified code I tried:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

<div id="question1">
    <p>Have you only completed Task A?</p>
</div>

<div id="question2" hidden="">
    <p>Have you only completed Task A and Task B?</p>
</div>

<div id="question3" hidden="">
    <p>Have you only completed Task A, Task B and Task C?</p>
</div>

<div id="result" hidden="">
    <p>Your result will appear here.</p>
</div>

<div class="controls">
    <button id="yesBtn" onclick="handleYes()">Yes</button>
    <button id="noBtn" onclick="handleNo()">No</button>
    <button id="resetBtn" class="hidden" onclick="handleReset()">Reset</button>
</div>

<script>
    $(document).ready(function() {
        console.log('DOM is fully loaded');
    });

    let currentQuestionId = 'question1';

    function handleYes() {
        console.log('Yes clicked');
        hideElement(currentQuestionId);
        showElement('result');
    }

    function handleNo() {
        console.log('No clicked');
        if (currentQuestionId === 'question1') {
            hideElement('question1');
            showElement('question2');
            currentQuestionId = 'question2';
        } else if (currentQuestionId === 'question2') {
            hideElement('question2');
            showElement('question3');
            currentQuestionId = 'question3';
        }
    }

    function handleReset() {
        console.log('Reset clicked');
        hideElement('result');
        showElement('question1');
        currentQuestionId = 'question1';
    }

    function showElement(id) {
        document.getElementById(id).hidden = false;
    }

    function hideElement(id) {
        document.getElementById(id).hidden = true;
    }
</script>

Would be great if someone could hint possible solutions to the issue!

Why does express router get blocked by CORS but router routes do not?

I have this function that I am using to protect my routes.

export function authUser(req, res, next) {
    let token = req.cookies?.token;
    if (token) {
        jwt.verify(token, process.env.jwt_secret, (err, data) => {
            if (err) {
                res.sendStatus(403);
            } else {
                req.username = data;
                next();
            }
        });
    } else {
        res.sendStatus(403);
    }
}

This works completely fine

const authRoutes = express.Router();

authRoutes.get('/content', authUser, (req, res) => {
    res.send(`This is the content in Content.vue for ${req.username}`);
});

app.use('/a', authRoutes);

But it would be annoying to add authUser to every route under authRoutes manually. I would like to do this so that every route in authRoutes goes through authUser

const authRoutes = express.Router();

authRoutes.use(authUser);

authRoutes.get('/content', (req, res) => {
    res.send(`This is the content in Content.vue for ${req.username}`);
});

app.use('/a', authRoutes);

But the problem is when I do this, I get this error on the frontend

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8182/a/content. (Reason: CORS preflight response did not succeed). Status code: 403.

I am puzzled on why the first approach works but the second doesn’t.

Aren’t the two requests flowing the same way? Does authRoutes.use send data back to the user before reaching a route?

Is there a way to dynamically get all WebAPI dom events and related types?

I want to get a list of all events like MouseEvent and related types, for example MouseEvent -> click, dblclick, mousedown, mouseenter, mouseleave, mousemove, mouseout, mouseover, or mouseup

And what about the constructor? When I try to create a new BeforeUnloadEvent event, I get the error “Illegal constructor”, How to check which values are correct?

I’ve seen code trying to do the same using regex mapping types to constructors, but it’s not dynamic and browser dependent

Scientific calculator using js

I am buildinng a scientific calculator using js. The normal calculator part is working but my scientific calculator is not working. Earlier I was using `eval( function for calculation but due to security issues, I have used tokenization method to build it.

The issue is the while using the trignometric calculation it is not working.
Here is the screenshot of it

enter image description here

const userInput = document.getElementById('input');
const userOutput = document.getElementById('output');
const clearbtn = document.getElementById('clear');
const calBtn = document.getElementById('calcBtn');
const btns = document.querySelectorAll('input[type="button"]');

function calc() {
  btns.forEach(button => {
    button.addEventListener('click', () => {
      const btnDataType = button.dataset.type;

      if (btnDataType === 'number' || btnDataType === 'operator') {
        userInput.value += button.value;
      } else if (btnDataType === 'Soperator') {
        userInput.value += `${button.value}(`;
      }

      calBtn.addEventListener("click", () => {
        let tokens = userInput.value.match(/(d+(.d+)?)|[+-*/%()]|sin|cos|tan/g);
        if (!tokens) {
          console.log("Error: Invalid input");
          return;
        }

        console.log("Tokens:", tokens);

        for (let i = 0; i < tokens.length; i++) {
          if (['sin', 'cos', 'tan'].includes(tokens[i]) && tokens[i + 1] === '(') {
            let argStart = i + 2;
            let argEnd = tokens.indexOf(')', argStart);
            if (argEnd === -1) {
              console.log("Error: Missing closing parenthesis");
              return;
            }

            let angle = parseFloat(tokens.slice(argStart, argEnd).join(''));
            let result;

            if (tokens[i] === 'sin') {
              result = Math.sin(angle * (Math.PI / 180));
            } else if (tokens[i] === 'cos') {
              result = Math.cos(angle * (Math.PI / 180));
            } else if (tokens[i] === 'tan') {
              result = Math.tan(angle * (Math.PI / 180));
            }

            tokens.splice(i, argEnd - i + 1, result.toString());
            i--;
          }
        }

        for (let i = 0; i < tokens.length; i++) {
          if (['*', '/', '%'].includes(tokens[i])) {
            let left = parseFloat(tokens[i - 1]);
            let right = parseFloat(tokens[i + 1]);
            let result = tokens[i] === '*' ? left * right : tokens[i] === '/' ? left / right : left % right;
            tokens.splice(i - 1, 3, result.toString());
            i--;
          }
        }

        for (let i = 0; i < tokens.length; i++) {
          if (['+', '-'].includes(tokens[i])) {
            let left = parseFloat(tokens[i - 1]);
            let right = parseFloat(tokens[i + 1]);
            let result = tokens[i] === '+' ? left + right : left - right;
            tokens.splice(i - 1, 3, result.toString());
            i--;
          }
        }

        userOutput.value = tokens[0];
      });
    });
  });

  document.getElementById("cut").addEventListener('click', () => {
    userInput.value = userInput.value.slice(0, -1);
  });

  clearbtn.addEventListener('click', () => {
    userInput.value = '';
    userOutput.value = '';
  });
}

calc();
<!-- header section -->
<header>
  <nav>
    <a href="">Logo</a>
    <button>contribute here</button>
  </nav>
</header>

<!-- main -->
<main>
  <section>
    <!-- calculator wrapper div -->
    <div>
      <!-- input and output screens -->
      <div>
        <input type="text" placeholder="Type to Calculate" id="input">
        <input type="text" placeholder="Output" readonly id="output">
        <button id="clear">Clear</button>
      </div>

      <!-- wrapper that contains number btns , operators -->
      <div>

        <!-- numbers -->
        <div>
          <input type="button" value="0" id="0" data-type="number">
          <input type="button" value="1" id="1" data-type="number">
          <input type="button" value="2" id="2" data-type="number">
          <input type="button" value="3" id="3" data-type="number">
          <input type="button" value="4" id="4" data-type="number">
          <input type="button" value="5" id="5" data-type="number">
          <input type="button" value="6" id="6" data-type="number">
          <input type="button" value="7" id="7" data-type="number">
          <input type="button" value="8" id="8" data-type="number">
          <input type="button" value="9" id="9" data-type="number">
        </div>

        <!-- operators btns -->

        <div>
          <input type="button" value="+" id="+" data-type="operator">
          <input type="button" value="-" id="-" data-type="operator">
          <input type="button" value="*" id="*" data-type="operator">
          <input type="button" value="/" id="/" data-type="operator">
          <input type="button" value="%" id="%" data-type="operator">
          <button id="calcBtn">Calculate</button>
          <button id="cut">X</button>
        </div>

      </div>
    </div>


    <!-- scientific calculator -->

    <div>
      <input type="button" value="Sin" id="sin" data-type="Soperator">
      <input type="button" value="Cos" id="cos" data-type="Soperator">
      <input type="button" value="Tan" id="tan" data-type="Soperator">
      <input type="button" value="sin⁻¹" id="sin-in" data-type="Soperator">
      <input type="button" value="cos⁻¹" id="cos-in" data-type="Soperator">
      <input type="button" value="tan⁻¹" id="tan-in" data-type="Soperator">
    </div>
  </section>
  <section>
  </section>
</main>
<script src="cal.js"></script>

Running Cucumber/Playwright tests in Microsoft Edge with Single Sign on

Need some help as I’m new to Cucumber and Playwright.

System has a single sign on option, which is currently signed on through my instance of Edge.

I need to run my tests through the single sign on, so using the inbuilt Chromium instance doesn’t work as it goes in via Incognito mode.

I’ve got my code to successfully open Edge and run the initial part of the test.

What I’m unable to do is change the test to open Edge in ‘not incognito’ mode and actually click the link and go through to the application.

My research on this has led me to believe that ‘launchPersistentContext’ should help, but I can’t get my code to work with that.

The code I’m currently using is:

const { Given, When, Then, Before, After, setDefaultTimeout } = require("@cucumber/cucumber");

const { chromium, expect, test } = require("@playwright/test");

const { Page } = require("playwright");

setDefaultTimeout(10 * 1000);

let page, browser;

Before(async function () {
    browser = await chromium.launch({ channel: 'msedge', headless: false });
    const context = await browser.newContext();
    page = await context.newPage();
});

Given("User navigates to the Staging Environment Login", async () => {
    await page.goto("<website>");
    await page.waitForTimeout(5000); //5 secs
    expect(page).toHaveTitle('Sign in to Website');
    const pageTitle = await page.title();
    console.log("Page title is: " + pageTitle);
});

When("using the SSO log in", async function(){
    await page.waitForLoadState();
    await page.getByTitle('saml').click();
    await page.waitForTimeout(5000); //2 secs
  
  });


After(async function () {
    await browser.close();
});

I’m getting the Edge browser instance from the Playwright.config.js

SVG interchangable

I want to animate circle along the path, once in front of object (big circle), and after in the back of the big circle. I’ve separate the path, and make 2 circle to animate along separated path. But what I want is, after the “front circle” reach the end of its path, it will disappear, and the “back circle” appear and start to animate, then it repeats. I tried “begin”, but while waiting to begin, the circle are staying at (0,0) coordinate, and it’s not repeating. I’m okay if the solution are using javascript

svg {
 width:300px;
 height:300px;
 border:1px solid black;
}
<svg viewBox="0 0 300 300">
  <defs>
    <style>
      .cls-1 {
        fill: #00930e;
      }
      .cls-2 {
        fill: #141414;
      }
      .cls-3 {
        stroke: red;
      }
      .cls-3, .cls-4 {
        fill: none;
        stroke-miterlimit: 10;
      }
      .cls-5 {
        fill: blue;
      }
      .cls-6 {
        fill: green;
      }
      .cls-4 {
        stroke: #ffe600;
      }
    </style>
  </defs>
  <!--  CIRCLE 2 BACK -->
    <circle class="cls-5" r="9.73">
      <animateMotion
        dur="5s"
        repeatCount="indefinite"
        path="M283.37,129.63c-9.64-26.65-77.18-26.64-150.85.01C58.85,156.3,6.95,199.52,16.6,226.17" />
    </circle>
  <path 
      stroke="yellow"
        fill="none"
        d="M283.37,129.63c-9.64-26.65-77.18-26.64-150.85.01C58.85,156.3,6.95,199.52,16.6,226.17"
        stroke-width="3"
        />
  <!--  CIRCLE 1 BACK  -->
  <circle class="cls-6" r="9.73" >
    <animateMotion
      dur="5s"
      repeatCount="indefinite"
      path="M34.78,59.23c18.61-21.38,81.6,3,140.68,54.44,59.08,51.44,91.89,110.48,73.28,131.85" />
  </circle>
  <path 
      stroke="yellow"
        fill="none"
        d="M34.78,59.23c18.61-21.38,81.6,3,140.68,54.44,59.08,51.44,91.89,110.48,73.28,131.85"
        stroke-width="3"
        />
  
  <!--  BIG CIRCLE  -->
  <circle cx="50%" cy="50%" r="110" fill="hotpink"/>
  
  <!--  CIRCLE 1 FRONT -->
  <circle class="cls-6" r="9.73" >
    <animateMotion
      dur="5s"
      repeatCount="indefinite"
      path="M248.74,245.53c-18.61,21.38-81.6-3-140.68-54.44C48.97,139.64,16.17,80.61,34.78,59.23" />
  </circle>
  <path 
      stroke="red"
        fill="none"
        d="M248.74,245.53c-18.61,21.38-81.6-3-140.68-54.44C48.97,139.64,16.17,80.61,34.78,59.23"
        stroke-width="3"
        />
  
    <!--  CIRCLE 2 FRONT -->
    <circle class="cls-5" r="9.73">
      <animateMotion
        dur="5s"
        repeatCount="indefinite"
        path="M16.6,226.17c9.64,26.65,77.18,26.64,150.85-.01,73.67-26.66,125.57-69.87,115.92-96.52" />
    </circle>
  <path 
      stroke="red"
        fill="none"
        d="M16.6,226.17c9.64,26.65,77.18,26.64,150.85-.01,73.67-26.66,125.57-69.87,115.92-96.52"
        stroke-width="3"
        />

</svg>

jQuery – see if the same text appear on both lists and add class to list item if match

I try to check if text on list_1 is present on list_2 and add class “show” to the each list item if text is found.

On below example class “show” should be assigned to item lists “This is text c” & “This is text e” as the same text exist on the list_1

However in my case class “show” only appear for last item list “This is text e”

HTML:

<ul class="list_1">
  <li>This is text c</li>
  <li>This is text e</li>
</ul>


<ul class="list_2">
  <li>This is text a</li>
  <li>This is text b</li>
  <li>This is text c</li>
  <li>This is text d</li>
  <li>This is text e</li>
</ul>

Script:

$(function(){

var showTag;

$('.list_1 li').each(function(){
      showTag = $(this).text();
});

$('.list_2 li').each(function(){
   if($(this).text()==showTag)
       $(this).closest('li').addClass('show');
});

});

How to filter product categories based on selected variants (e.g. Size “P”) without excluding categories that have other variants?

I’m creating a product page where users can filter items based on various variants like “Size”, “Color” etc. However, I am facing an issue when trying to filter product categories based on selected variants.

Here’s what I want to achieve:

If the user selects size “P”, they should continue to see other size variants (M, L, XL), but categories that do not have products with size “P” should be removed from the filter list.
If the user selects another category, for example “Pants”, filtering logic must be applied so that the other categories are adjusted to show only those that have products with size “P” or another selected size.
The behavior is the same for other variants, such as “Color” or “Gender” — the idea is that selecting a variant influences which categories appear, without removing categories with other variants still available.
Here is the code I have already implemented to search for available products and filters:

Route.js:

const filters = {};

  if (genders.length) {
    filters.variants = { some: { gender: { in: genders } } };
  }
  if (colors.length) {
    if (!filters.variants) filters.variants = {};
    filters.variants.some = { ...filters.variants.some, color: { in: colors } };
  }
  if (sizes.length) {
    if (!filters.variants) filters.variants = {};
    filters.variants.some = { ...filters.variants.some, size: { in: sizes } };
  }
  if (category.length) {
    filters.categories = { some: { Category: { name: { in: category } } } };
  }

const availableFilters = {
      genders: await prisma.productVariant.findMany({
        select: { gender: true },
        distinct: ["gender"],
        where: {
          product: { AND: filters }, 
        },
      }),
      sizes: await prisma.productVariant.findMany({
        select: { size: true },
        distinct: ["size"],
        where: {
          product: { AND: filters },
        },
      }),
      colors: await prisma.productVariant.findMany({
        select: { color: true },
        distinct: ["color"],
        where: {
          product: { AND: filters },
        },
      }),
      categories: await prisma.category.findMany({
        where: {
          products: {
            some: {
              product: { AND: filters },
            },
          },
        },
        select: { name: true },
      }),
    };

ProductsPage:

"use client";

import Filtro from "@/components/Produtos/Filtro";
import BotãoOrdenar from "./BotãoOrdenar";
import { useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
import ProdutoCard from "./ProdutoCard";
import BotãoFiltro from "./BotãoFiltro";

export default function PaginaProdutos({ titulo }) {
  const searchParams = useSearchParams();
  const [isLoading, setIsLoading] = useState(true);
  const [produtos, setProdutos] = useState([]);
  const [availableFilters, setAvailableFilters] = useState({
    genders: [],
    sizes: [],
    colors: [],
    categories: [],
  });

  const tamanhoOrdem = ["PP", "P", "M", "G", "GG"];

  function ordenarTamanhos(tamanhos) {
    return tamanhos.sort((a, b) => {
      const indexA = tamanhoOrdem.indexOf(a.size);
      const indexB = tamanhoOrdem.indexOf(b.size);
      return indexA - indexB;
    });
  }

  useEffect(() => {
    async function fetchProducts() {
      setIsLoading(true);
      try {
        const params = new URLSearchParams(searchParams.toString());
        params.append("pathname", window.location.pathname);

        const response = await fetch(`/api/produtos?${params}`);

        if (response.ok) {
          const { produtos, availableFilters } = await response.json();
          setProdutos(produtos);
          setAvailableFilters({
            ...availableFilters,
            sizes: ordenarTamanhos(availableFilters.sizes),
          });
        } else {
          console.error("Error ao buscar produtos");
        }
      } catch (err) {
        console.error("Erro na requisição", err);
      } finally {
        setIsLoading(false);
      }
    }

    fetchProducts();
  }, [searchParams]);

  return (
    <div className="font-raleway text-text">
      <div className="flex items-center text-center min-[1001px]:mb-[40px] mt-[20px] px-5">
        <h1 className="flex-1 font-bold text-[32px] max-[1340px]:text-[30px] max-[1000px]:text-[28px] max-[550px]:text-[25px]">
          {titulo}
        </h1>
        <BotãoFiltro filters={availableFilters} />
      </div>
      <div className="max-[850px]:px-[15px] px-[50px]">
        <BotãoOrdenar />
        {isLoading ? (
          <div className="h-[40vh] w-full text-center flex justify-center items-center flex-col gap-2">
            <span className="w-[48px] h-[48px] border-[5px] border-icon border-b-transparent rounded-[50%] animate-spin flex" />
            <span className="text-icon font-semibold text-[18px]">
              CARREGANDO
            </span>
          </div>
        ) : (
          <div className="flex gap-[30px] pt-5 mb-5 max-[1000px]:pt-10">
            <Filtro filters={availableFilters} />

            <ul className="flex flex-wrap max-[800px]:gap-y-2.5 max-[800px]:gap-x-2.5 gap-x-5 gap-y-5 list-none max-[1000px]:w-full w-[calc(100%-320px)]">
              {produtos.map((p) => (
                <ProdutoCard
                  key={p.id}
                  nome={p.name}
                  slug={p.slug}
                  images={p.images}
                />
              ))}
            </ul>
          </div>
        )}
      </div>
    </div>
  );
}

Database:
The data structure of my database is as follows (with the main related tables: Product, ProductVariant, Category):

model Product {
    id          Int               @id @default(autoincrement())
    name        String
    variants    ProductVariant[]
    categories  ProductCategory[]
}

model ProductVariant {
    id        Int     @id @default(autoincrement())
    color     String
    gender    String
    size      Size
    productId Int
    product   Product @relation(fields: [productId], references: [id])
}

model Category {
    id       Int               @id @default(autoincrement())
    name     String            @unique
    products ProductCategory[]
}

What I’m trying to do:

  1. I want to apply category filtering based on selected variants such as Size, Color and Gender dynamically. That is, if the user selects a specific size, for example “P”, only categories that have that size should be shown.
  2. Categories should not be removed if there are still products with other variants (such as different sizes, for example “M” or “L”).
  3. The problem is that the category filtering is excluding categories with products in other variants, which is not what I want.

Doubts:

  1. How can I adjust my query in route.js so that categories are not removed if there are still products in other variants?
  2. Is there an efficient way to ensure that only categories with the selected variants are shown, without removing the other options?

Bokeh: OpenDialog triggered from Dropdown

Bokeh 3.6.0

Working with Bokeh server, I try to open a bokeh.models.Dialog model. Usually, this is done via my_button.js_on_click(OpenDialog(Dialog=dialog))

Now, I’m struggling to open a given dialog depending on Dropdown model. Here is a minimal example:

from bokeh.models import (
    Div,
    CustomJS,
    Dropdown,
    Dialog,
    OpenDialog,
    CloseDialog,
)
from bokeh.plotting import curdoc

d1 = Dialog(title="Dialog 1", content=Div(text="<h1>Dialog 1</h1>"))
d2 = Dialog(title="Dialog 2", content=Div(text="<h1>Dialog 2</h1>"))

menu = Dropdown(label="Test", menu=["option1", "option2"])

# This works, but always open the same Dialog...
# menu.js_on_click(OpenDialog(dialog=d1))

# This is what I would like...
menu.js_on_click(
    {menu.menu[0]: OpenDialog(dialog=d1), menu.menu[1]: OpenDialog(dialog=d2)}
)

curdoc().add_root(menu)

Next.js API Route Works Locally but Returns 404 in Production

I have a Next.js application with the following setup:

  • Next.js Version: 14.2.8
  • Node.js Version: 20.9.0
  • Couchbase SDK: 4.4.1

My API route is located at:

src/app/api/translations/route.ts

The API works perfectly in the local development environment. For example:

  • http://localhost:8082/api/translations?lang=en returns the expected result.
  • Even on the production server (via SSH), accessing http://localhost:3000/api/translations?lang=en works as expected.

However, when I try to access the API via the public URL in production (e.g., http://example.com/api/translations?lang=en), I get the following error response:

{
  "error": "ERR001",
  "id": "b3b632e0349fa8fd3b5ca9fa4e578fd624617fb2ffbcef5aa6c6a029ac0e0d6f",
  "message": "No handler found for GET /api/translations",
  "source": "No handler found for GET /api/translations"
}

Code for the Route

Here’s the implementation of the GET and PUT handlers in route.ts:

import { connectToDatabase } from '../../../utils/couchbase';

export async function GET(req: Request) {
  const { translationsCollection } = await connectToDatabase();
  const { searchParams } = new URL(req.url);
  const lang = searchParams.get('lang');

  if (!lang) {
    return new Response(JSON.stringify({ message: "Language parameter 'lang' is required" }), {
      status: 400,
    });
  }

  try {
    const result = await translationsCollection.get(lang);
    return new Response(JSON.stringify(result.content), { status: 200 });
  } catch (error: any) {
    console.error('Error fetching translation:', error);
    return new Response(JSON.stringify({ message: `Translation Not Found: ${error.message}` }), {
      status: 500,
    });
  }
}

export async function PUT(req: Request) {
  const { translationsCollection } = await connectToDatabase();
  const { searchParams } = new URL(req.url);
  const lang = searchParams.get('lang');
  const body = await req.json();

  if (!lang || !body) {
    return new Response(JSON.stringify({ message: "Missing 'lang' parameter or request body" }), {
      status: 400,
    });
  }

  try {
    await translationsCollection.upsert(lang, body);
    const updatedDoc = await translationsCollection.get(lang);
    return new Response(JSON.stringify(updatedDoc.content), { status: 200 });
  } catch (error: any) {
    console.error('Error updating translation:', error);
    return new Response(
      JSON.stringify({ message: `Translation Update Failed: ${error.message}` }),
      { status: 500 }
    );
  }
}

Steps I’ve Tried

  • Verified that the server is running and accessible.
  • Tested the API locally on the production server (localhost:3000), and it works.
  • Checked the file location: src/app/api/translations/route.ts.
  • Confirmed the build and deployment process completed without errors.
  • Tested removing node_modules and .next folders, then rebuilding and restarting the app.

Environment Details

  • Reverse proxy: Possible Nginx configuration, but I’m not sure if this could interfere.

  • SSL: The public URL uses HTTPS.

Question

What could cause the API route to work locally (on both development and production servers) but return a 404 error when accessed via the public URL? Are there any known issues with routing, proxy setups, or deployment configurations in this case?