Twitch API Utilization

I’m attempting to create a twitch embed on a website that either uses the latest uploaded vod when the stream is offline, or the current livestream if the channel is online.
I’m very new to using API’s and I want to know how to figure out how I can get the information from the promise into HTML where I can check the variables.
Please let me know if I’m overthinking this as well and if theres an easier solution.

I’ve gotten the “search channels” function of the API to send a promise result to the debug log using this code

 <script>
      const request = new Request("https://api.twitch.tv/helix/search/channels?query=[Channel]", {
        headers: {
          'Client-ID': '[id]',
          'Authorization': 'Bearer [id]'
        },
      })

    fetch(request)
    .then((response) => {
    console.log(response.json())
    return response.json()
  })
    </script>

Typescript Node test cannot redifine property?

So i have this test doing in my typescript project and when i do the mock tests two test have been failing all the issues are related to TypeError [Error]: Cannot redefine property: fetchAndNormalizePullRequests i looked all the way and couldn’t find a way to fix the issue. this is the

pull-request.handler.test.ts

import { test, describe, beforeEach, afterEach, mock } from 'node:test';
import assert from 'node:assert';
import type { Request, Response } from 'express';
import { getAllPullRequests } from '../../handlers/pull-requests.handler.js';

const originalEnv = process.env;
// const pullRequestsService = await import('../../services/pull-requests.service.js');

describe('Pull Requests Handler', () => {
  let mockReq: Partial<Request>;
  let mockRes: Partial<Response>;
  let statusMock: any;
  let jsonMock: any;
  let fetchMock: any;

  beforeEach(() => {
    mock.restoreAll();

    statusMock = mock.fn(() => mockRes);
    jsonMock = mock.fn();
    
    mockRes = {
      status: statusMock,
      json: jsonMock
    };

    process.env = { ...originalEnv };
  });

  afterEach(() => {
    process.env = originalEnv;
    mock.restoreAll();
  });

  test('should return 500 when GITHUB_API_TOKEN is missing', async () => {
    delete process.env.GITHUB_API_TOKEN;
    mockReq = {
      query: { owner: 'testowner', repo: 'testrepo' }
    };

    await getAllPullRequests(mockReq as Request, mockRes as Response);

    assert.strictEqual(statusMock.mock.callCount(), 1);
    assert.deepStrictEqual(statusMock.mock.calls[0].arguments, [500]);
    assert.strictEqual(jsonMock.mock.callCount(), 1);
    assert.deepStrictEqual(jsonMock.mock.calls[0].arguments, [{ error: 'Missing environment variables.' }]);
  });

  test('should return 500 when owner is missing', async () => {
    process.env.GITHUB_API_TOKEN = 'test-token';
    mockReq = {
      query: { repo: 'testrepo' }
    };

    try{
    await getAllPullRequests(mockReq as Request, mockRes as Response);
    }
    catch(e){
      console.error(e);
    }

    assert.strictEqual(statusMock.mock.callCount(), 1);
    assert.deepStrictEqual(statusMock.mock.calls[0].arguments, [500]);
    assert.strictEqual(jsonMock.mock.callCount(), 1);
    assert.deepStrictEqual(jsonMock.mock.calls[0].arguments, [{ error: 'Missing environment variables.' }]);
  });

  test('should return 500 when repo is missing', async () => {
    process.env.GITHUB_API_TOKEN = 'test-token';
    mockReq = {
      query: { owner: 'testowner' }
    };

    await getAllPullRequests(mockReq as Request, mockRes as Response);

    assert.strictEqual(statusMock.mock.callCount(), 1);
    assert.deepStrictEqual(statusMock.mock.calls[0].arguments, [500]);
    assert.strictEqual(jsonMock.mock.callCount(), 1);
    assert.deepStrictEqual(jsonMock.mock.calls[0].arguments, [{ error: 'Missing environment variables.' }]);
  });

  test('should return 200 with pull requests when all parameters are valid', async () => {
    process.env.GITHUB_API_TOKEN = 'test-token';
    mockReq = {
      query: { owner: 'testowner', repo: 'testrepo' }
    };

    const mockPullRequests = [
      {
        prNumber: 1,
        title: 'Test PR',
        creator: 'testuser',
        creationTimestamp: '2024-01-01T00:00:00Z',
        requestedReviewers: ['reviewer1'],
        lastActionType: 'open',
        lastActionTimestamp: '2024-01-01T00:00:00Z'
      }
    ];

    const fetchMock = mock.fn(() => Promise.resolve(mockPullRequests));
    mock.method(await import('../../services/pull-requests.service.js'), 'fetchAndNormalizePullRequests', fetchMock);

    await getAllPullRequests(mockReq as Request, mockRes as Response);

    assert.strictEqual(statusMock.mock.callCount(), 1);
    assert.deepStrictEqual(statusMock.mock.calls[0].arguments, [200]);
    assert.strictEqual(jsonMock.mock.callCount(), 1);
    assert.deepStrictEqual(jsonMock.mock.calls[0].arguments, [mockPullRequests]);
  });

  test('should return 500 when service throws an error', async () => {
    process.env.GITHUB_API_TOKEN = 'test-token';
    mockReq = {
      query: { owner: 'testowner', repo: 'testrepo' }
    };

    const fetchMock = mock.fn(() => Promise.reject(new Error('Service error')));
    mock.method(await import('../../services/pull-requests.service.js'), 'fetchAndNormalizePullRequests', fetchMock);

    await getAllPullRequests(mockReq as Request, mockRes as Response);

    assert.strictEqual(statusMock.mock.callCount(), 1);
    assert.deepStrictEqual(statusMock.mock.calls[0].arguments, [500]);
    assert.strictEqual(jsonMock.mock.callCount(), 1);
    assert.deepStrictEqual(jsonMock.mock.calls[0].arguments, [{ error: 'Internal server error.' }]);
  });
});

and this is my fetchAndNormalizePullRequest function

import axios from 'axios';
import type{ NormalizedPR } from '../types/types.js';

export const fetchAndNormalizePullRequests = async (owner: string, repo: string, token: string): Promise<NormalizedPR[]> => {
  const url = `https://api.github.com/repos/${owner}/${repo}/pulls?state=all`;

  try {
    const response = await axios.get(url, {
      headers: {
        Authorization: `token ${token}`,
        'Content-Type': 'application/json',
      },
    });

    return response.data.map((pr: any) => ({
      prNumber: pr.number,
      title: pr.title,
      creator: pr.user.login,
      creationTimestamp: pr.created_at,
      requestedReviewers: pr.requested_reviewers.map((reviewer: any) => reviewer.login),
      lastActionType: pr.merged_at ? 'merged' : pr.state,
      lastActionTimestamp: pr.updated_at,
    }));
  } catch (error) {
    throw new Error('Failed to fetch pull requests from GitHub API.');
  }
};

what am i doing wrong? can’t fix the issue

iPad – how to have a numeric floating keyboard with return/enter or tab key

This is what a number floating keyboard on iPad is looking like

iPad numeric keyboard

I want to have a enter/return or tab key here. There is an input field for each row in a table and I want to enter some value in it (0-9) and move to next row/cell. If I use the full screen keyboard, it suffices the requirement but the keyboard is taking 80% of the screen. So I want to use this floating keyboard but if I want to go to next cell, I need to click to that next cell and then enter value. I want to improve user experience on it. I tried input type number, numeric and tel and it did not help.

Problem with contact form HTML & JS for submit on php after required fields [closed]

I have a problem with my contact form. I have required fields that work when I click on submit, but once everything is entered, the form is not sent to the .php file. Maybe it’s only a small problem, so I add the whole code. Sorry for the length of the codes.
Where am I going wrong? I’ve been working on this for hours 🙁 I hope someone can help me.

const form = document.getElementById('userForm');
const firstNameInput = document.getElementById('name_surname');
const emailInput = document.getElementById('mail');
const firstNameError = document.getElementById('firstNameError');
const emailError = document.getElementById('emailError');
const submitBtn = document.getElementById("invia");

form.addEventListener('submit', function(event) {
  // Prevent the form from submitting normally
  event.preventDefault();

  if (validateForm()) {
    return;
    // You can now submit the form programmatically or clear it
  }

  // do animation
  submitBtn.classList.add("is-active");
  setTimeout(function() {
    submitBtn.classList.remove("is-active");

    actual_submit();
  }, 2500);

})

function actual_submit() {
  alert('Form was submitted')
  return; // for testing purposes
  $.ajax({
    type: 'post',
    url: '../../php/kontakt.php',
    data: $('form').serialize(),
    success: function() {
      alert('form was submitted');
    }
  });
}

function validateForm() {
  let isValid = true;

  // Validate First Name
  if (firstNameInput.value.trim() === '') {
    firstNameError.textContent = 'First name is required.';
    firstNameInput.classList.add('invalid'); // Add a class for styling
    isValid = false;
  } else {
    firstNameError.textContent = '';
    firstNameInput.classList.remove('invalid');
  }

  // Validate Email
  const emailValue = emailInput.value.trim();
  const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/; // Basic email regex

  if (emailValue === '') {
    emailError.textContent = 'Email is required.';
    emailInput.classList.add('invalid');
    isValid = false;
  } else if (!emailRegex.test(emailValue)) {
    emailError.textContent = 'Please enter a valid email address.';
    emailInput.classList.add('invalid');
    isValid = false;
  } else {
    emailError.textContent = '';
    emailInput.classList.remove('invalid');
  }

  return isValid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="userForm" method="post"> <!-- Do not remove this ID, it is used to identify the page so that the pagination script can work correctly -->
  <fieldset class="formContainer uk-form uk-form-stacked" id="rsform_3_page_0">
    <div class="uk-form-row rsform-block rsform-block-nome-cognome">
      <div class="formControls">
        <input type="text" value="" size="20" placeholder="Name & Nachname" name="form[name_surname]" id="name_surname" class="uk-form-large rsform-input-box" />
        <span id="firstNameError" class="error-message"></span>
      </div>
    </div>
    <div class="uk-form-row rsform-block rsform-block-mail">
      <div class="formControls">
        <input type="email" value="" size="20" placeholder="Mailadresse" name="form[mail]" id="mail" class="uk-form-large rsform-input-box" aria-required="true" />
        <span id="emailError" class="error-message"></span>
      </div>
    </div>
    <div class="uk-form-row rsform-block rsform-block-data-arrivo-3">
      <div class="formControls">
        <input type="text" value="" size="20" placeholder="Datum Anreise" name="form[arrival]" id="arrival" class="omnidatepicker-from uk-form-large rsform-input-box" aria-required="true" />
        <span class="formValidation"><span id="component61" class="formNoError"></span></span>
      </div>
    </div>
    <div class="uk-form-row rsform-block rsform-block-data-partenza-3">
      <div class="formControls">
        <input type="text" value="" size="20" placeholder="Datum Abreise" name="form[departure]" id="departure" class="omnidatepicker-to uk-form-large rsform-input-box" aria-required="true" />

      </div>
    </div>

    <div class="uk-form-row rsform-block rsform-block-messaggio">
      <div class="formControls">
        <textarea cols="50" rows="3" placeholder="Mitteilung (Bitte teilen Sie uns alle wichtigen Details mit, damit wir Ihren Aufenthalt bestens gestalten können.)" name="form[message]" id="message" class="uk-form-large rsform-text-box"></textarea>
        <span class="formValidation"><span id="component28" class="formNoError"></span></span>
      </div>
    </div>

    <div class="uk-form-row rsform-block rsform-block-accetto-privace">
      <div class="formControls">
        <div><label for="accetto_privace0"><input type="checkbox"  name="form[privacy][]" value="1" id="privacy" class="rsform-checkbox" aria-required="true" />Akzeptiere <a href="#privacy-3" data-uk-modal>Privacy</a><div id="privacy-3" class="uk-modal"><div class="uk-modal-dialog uk-modal-dialog-lightbox uk-modal-dialog-large"><a href="/" class="uk-modal-close uk-close uk-close-alt"></a><iframe src="https://www.omnigrafitalia.it/gdpr/index.php?site=https%3A%2F%2Fwww.musacomo.com%2F#googtrans(it)" width="100%" height="600px"></iframe></div></div></label> </div>
        <span class="formValidation"><span id="component31" class="formNoError"></span></span>
      </div>
    </div>


    <div id="rsform_error_3" style="display: none;">
      <p class="formRed"><i class="uk-icon-exclamation-triangle"></i> Bitte alle Felder ausfĂŒllen.</p>
    </div>
    <div class="uk-form-row rsform-block rsform-block-invia">
      <div class="formControls">
        <input type="submit" name="form[invia]" id="invia" class="uk-width-1-1 rsform-submit-button  uk-button uk-button-primary" value="Anfrage absenden" />
        <span class="formValidation"></span>
      </div>
    </div>

  </fieldset>

  <input type="hidden" name="form[language]" id="language" value="de" />
  <input type="hidden" name="form[hiddenlist_local]" id="hiddenlist_local" value="1" />

  <input type="hidden" name="form[nome_offerta_3]" id="nome_offerta_3" value="Angebot Relax BHB" />

</form>

How to automatically refresh access token when receiving 403 errors in Redux Toolkit async thunks?

I’m building a React application with Redux Toolkit and need to handle token expiration automatically. When my access token expires, the server returns a 403 error, and I want to automatically refresh the token and retry the original request.
I have favourites-related async thunks that need authentication. The server expects the access token in the Authorization header. My access token is stored in Redux memory (state.auth.accessToken). Here’s my current code:

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

const url = import.meta.env.VITE_APP_SERVER_URL;

// Thunk to add to favourites
export const addToFavouritesThunk = createAsyncThunk(
  'favourites/add',
  async (dishId, { rejectWithValue, getState }) => {
    try {
      const { auth: { accessToken } } = getState();
      const response = await axios.post(
        `${url}favourites`,
        { dishId },
        {
          headers: {
            'Authorization': `Bearer ${accessToken}`
          }
        }
      );
      return response.data;
    } catch (error) {
      return rejectWithValue(
        error.response?.data?.message || 'Failed to add to favourites'
      );
    }
  }
);

// Thunk to get all favourites
export const getFavouritesThunk = createAsyncThunk(
  'favourites/getAll',
  async (_, { rejectWithValue, getState }) => {
    try {
      const { auth: { accessToken } } = getState();
      const response = await axios.get(
        `${url}favourites`,
        {
          headers: {
            'Authorization': `Bearer ${accessToken}`
          }
        }
      );
      return response.data;
    } catch (error) {
      return rejectWithValue(
        error.response?.data?.message || 'Failed to get favourites'
      );
    }
  }
);

// Thunk to remove from favourites
export const removeFromFavouritesThunk = createAsyncThunk(
  'favourites/remove',
  async (dishId, { rejectWithValue, getState }) => {
    try {
      const { auth: { accessToken } } = getState();
      const response = await axios.delete(
        `${url}favourites/${dishId}`,
        {
          headers: {
            'Authorization': `Bearer ${accessToken}`
          }
        }
      );
      return response.data;
    } catch (error) {
      return rejectWithValue(
        error.response?.data?.message || 'Failed to remove from favourites'
      );
    }
  }
);

// Refresh token thunk (simplified version)
export const refreshTokenThunk = createAsyncThunk(
  'auth/refresh',
  async (_, { rejectWithValue, getState }) => {
    try {
      const { auth: { refreshToken } } = getState();
      const response = await axios.post(
        `${url}auth/refresh`,
        { refreshToken }
      );
      return response.data; // Contains new accessToken
    } catch (error) {
      return rejectWithValue(
        error.response?.data?.message || 'Token refresh failed'
      );
    }
  }
);

const favouritesSlice = createSlice({
  name: 'favourites',
  initialState: {
    items: [],
    loading: false,
    error: null,
    lastAction: null
  },
  reducers: {
    clearFavouritesError: (state) => {
      state.error = null;
    },
    resetLastAction: (state) => {
      state.lastAction = null;
    }
  },
  extraReducers: (builder) => {
    builder
      // Add to favourites
      .addCase(addToFavouritesThunk.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(addToFavouritesThunk.fulfilled, (state, action) => {
        state.loading = false;
        state.items = action.payload;
        state.lastAction = { type: 'add' };
      })
      .addCase(addToFavouritesThunk.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      })
      // Get all favourites
      .addCase(getFavouritesThunk.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(getFavouritesThunk.fulfilled, (state, action) => {
        state.loading = false;
        state.items = action.payload.favourites || [];
      })
      .addCase(getFavouritesThunk.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      })
      // Remove from favourites
      .addCase(removeFromFavouritesThunk.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(removeFromFavouritesThunk.fulfilled, (state, action) => {
        state.loading = false;
        state.items = action.payload;
        state.lastAction = { type: 'remove' };
      })
      .addCase(removeFromFavouritesThunk.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      });
  }
});

export const { clearFavouritesError, resetLastAction } = favouritesSlice.actions;
export default favouritesSlice.reducer;

The Problem
When the access token expires, my server returns a 403 error. I want to automatically:

Detect 403 errors in any thunk

Call refreshTokenThunk to get a new access token

Retry the original request with the new token

Handle concurrent requests (if multiple requests fail with 403 at the same time)

Fetching overridden events from Google Calendar

I have a Google Apps Script to automate the description of Google Calendar events. The script runs once a week and tries to fetch, and modify, the occurrence for the week to follow.

The code to find the next meeting looks like this:

  const now = new Date();
  const nowIso = now.toISOString();
  const oneWeekLater = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);
  const oneWeekLaterIso = oneWeekLater.toISOString();
  const instances = Calendar.Events.instances(calendarId, recurringEventId, {
    timeMin: nowIso,
    timeMax: oneWeekLaterIso,
    maxResults: 1
  });
  if (!instances.items || !instances.items.length) {
    // No upcoming occurrences found; snothing to do
    Logger.log("No upcoming instances found");
    return;
  }
  const nextInstance = instances.items[0];

This normally works. However, if an event has been modified (either manually or by my own code), it is not found by this. It seems Calendar.Events.instances only lists unaltered events. How do I get around this? I want to find the next occurrence (modified or not, but not deleted) of a recurring event.

How can I add structured data (JSON-LD) for multiple products on a single blog page?

I’m trying to improve the SEO of a blog page that also highlights a few of our products. For example, here’s one of the pages I’m working with:

Famous Places to visit in Salem

The page is mostly a travel article, but in between the content, we mention some of our products (different varieties of Salem mangoes).

I know how to add JSON-LD schema for a single Product, but in this case, I’m not sure:

Should I add multiple “@type”: “Product” blocks inside one tag, or use multiple tags?

Since the page is primarily a blog post and not a product listing, is it still valid to use Product schema here, or should I only use Article schema and skip products?

What’s the best practice so Google doesn’t treat this as “spammy” structured data?

Here’s an example of what I tried with two products:

<script type="application/ld+json">
{
  "@context": "https://schema.org/",
  "@type": "Product",
  "name": "Alphonso Mango",
  "image": "https://www.salemmango.com/images/alphonso-mango.jpg",
  "description": "Premium Alphonso Mangoes from Salem",
  "offers": {
    "@type": "Offer",
    "priceCurrency": "INR",
    "price": "999",
    "availability": "https://schema.org/InStock"
  }
},
{
  "@context": "https://schema.org/",
  "@type": "Product",
  "name": "Imam Pasand Mango",
  "image": "https://www.salemmango.com/images/imam-pasand-mango.jpg",
  "description": "Rare Salem Imam Pasand Mango",
  "offers": {
    "@type": "Offer",
    "priceCurrency": "INR",
    "price": "899",
    "availability": "https://schema.org/InStock"
  }
}
</script>

But this throws validation errors in Google’s Rich Results Test.

What’s the correct way to structure multiple product schemas on the same blog page?

Using browser’s native pdfViewer from JavaScript?

Browser’s navigator.pdfViewerEnabled property indicates whether the browser supports inline display of PDF files when navigating to them.

If we think of going further – is it possible to use browser’s built-in (native) capability of processing PDF files from JavaScript code? One particular thing I need is to get page size and page count of a selected local PDF file.

In other words, is there any API exposed by a browser to use its native PDF-processing capabilities without importing any JS/npm library or implementing it from scratch?

How to intercept all HTTP requests from page

I am trying to learn how to use JavaScript to block all outgoing HTTP requests from an HTML file. The problem is when you click the link to www.example.com it doesn’t seem to catch it as a fetch event.

test.html:

<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">


if ("serviceWorker" in navigator) {
  navigator.serviceWorker.register("./sw.js", { scope: "/" }).then(
    (registration) => {
      console.log("Service worker registration succeeded:", registration);
    },
    (error) => {
      console.error(`Service worker registration failed: ${error}`);
    },
  );
} else {
  console.error("Service workers are not supported.");
}

  
</script>
<div>
<a href="https://www.example.com">Visit Example</a>
</div>
</body>
</html>

sw.js:

console.log('loaded')
self.addEventListener('fetch', function (event) {
    console.log('fetch', event.request.url);
});

Looking at my console:

loaded
fetch test.html
test.html:31 Service worker registration succeeded
fetch favicon.ico
favicon.ico:1   GET favicon.ico 404 (Not Found)

So you can see above that it even blocks an attempt to load favicon.ico (host provider icon) but it doesn’t block me if I click the link – I just go to example.com.

non-standard query in wp pattern file

so i love the patterns and the templates in the editor
im trying to create my own patterns
im sure this is a basic question but ive been googling
and am getting really confused as to the order of operations

in a standard query type of last-3-posts.php

    <!-- wp:query {"queryId":1,"query":{"perPage":"3","pages":0,"offset":"0","postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false},"align":"wide","layout":{"type":"default"}} -->

ok but what if i wanted to do a join query or a query on a non-standard table
ie ive created a new table called mission_meta
where mission_meta has a foreign key to posts
and i want to return that data as well

do i do it in php first and then fill out the pattern template
(how to then populate the pattern?)
or can i call a wp:query with a join?

any pointers would be greatly apprec
thanks!

Why Doesn’t FrankenPHP Feel Faster on Laravel 12 with SQL Server? It’s Almost the Same as Apache [closed]

I’m trying out FrankenPHP for my Laravel 12 application because many people say it’s a super-fast PHP runtime compared to PHP-FPM or Apache. However, after testing it, I found that the speed is almost the same as the standard Apache setup I was using before. In fact, for some API endpoints, the response time is still around 1.2 seconds, and for exporting large data sets (around 90,000 rows to Excel via PhpSpreadsheet), it often timeouts even after increasing the max_execution_time to 60 seconds or more.

For simple API endpoints (e.g. fetch data from DB with a simple join query), response time in Apache is around 600-1200ms, in FrankenPHP it is about the same (it doesn’t drop to <200ms as I expected).

What’s wrong? Is FrankenPHP less than optimal for SQL Server? Or is there a specific tuning for Laravel + SQL Server? Perhaps a bottleneck in the SQLSRV driver?

If anyone has had similar experiences, please share any tips or configurations that make FrankenPHP truly superior. Thank you!

ExtJS – changing css class in another cell based on value and renderer

I have a requirement to change the class of the nominal_currency_id cell based on information from the ch_nominal_currency_id_flag column. I simply want to assign a background color to it.

I could use a renderer in the nominal_currency_id cell, but this is impossible because I have a resolveView that handles changing the ID to one retrieved from the dictionary. The renderer overrides this, and I still see the ID instead of the code value.

Therefore, I would like to add a renderer to the column with the ch_nominal_currency_id_flag flag, but I don’t know how to add to the nominal_currency_id column to assign a class to it. metadata, of course, only works for the column containing the renderer.

In short, I want to apply a red background color to the nominal_currency_id cell based on the value from the true/false ch_nominal_currency_id_flag cell

How should I approach this?

        {
            name: 'nominal_currency_id',
            title: 'Nominal Currency',
            editable: true,
            type: 'string',
            maxLength: 3,
            formSortOrder: 13,
            resolveView: {
                dataProviderId: 'PROVIDER_ID',
                childrenTable: 'pd_currency',
                remote: false,
                valueField: 'currency_id',
                displayField: 'currency_code',
                addBlank: true
            }
        },
        {
            name: 'ch_nominal_currency_id_flag',
            title: 'Ch Nominal Currency Flag',
            editable: true,
            type: 'boolean',
            hidden: true,
            hiddenInForm: true,
            formSortOrder: 45
        },

I also add the code that adds my resolveView, maybe it will help in solving

if (column.resolveView !== undefined) {
        ;(() => {
          const resolveView = column.resolveView
          const columnName = column.name
          let dropDownTemplate
          let dropDownTemplateList

          tempColumnType.filter = {
            type: 'resolver',
            addBlank: false,
            underlyingField: columnName,
            ...resolveView,
            control,
          }

          tempColumnType.renderer = function (value, _metaData, record) {
            if (!_.isNil(value)) {
              const retrivedValue = app.nameResolver.resolve(
                {
                  value,
                  underlyingField: columnName,
                  ...resolveView,
                },
                record?.data,
              )

              return _.isString(retrivedValue)
                ? _.unescape(retrivedValue)
                : retrivedValue
            }
          }

          if (column.editable !== false) {
            tempColumnType.field = {
              xtype: 'resolvercombo',
              underlyingField: columnName,
              ...resolveView,
            }
          }

          if (dropDownTemplate) {
            tempColumnType.field.tpl = dropDownTemplateList
            tempColumnType.field.displayTpl = dropDownTemplate
            tempColumnType.filter.tpl = dropDownTemplateList
            tempColumnType.filter.displayTpl = dropDownTemplate
          }
        })()
      }

Setting up Codeigniter 4 project’s Base URL (Config/App.php) and .htaccess because i can’t set the document root of the domain to the public folder

This is my base URL on Config/App: https://pantradeglobal.com/raymond_new_pantradeglobal/public

This is my htaccess on root folder:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^(.*)$ raymond_new_pantradeglobal/public/$1 [L]
</IfModule>

<FilesMatch "^.">
    Require all denied
    Satisfy All
</FilesMatch>

This is my hataccess on public folder:

# Disable directory browsing
Options -Indexes


<IfModule mod_rewrite.c>
    Options +FollowSymlinks
    RewriteEngine On

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([sS]*)$ /index.php/$1 [L,NC,QSA]

    # Ensure Authorization header is passed along
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>


<IfModule !mod_rewrite.c>
    # If we don't have mod_rewrite installed, all 404's
    # can be sent to index.php, and everything works as normal.
    ErrorDocument 404 index.php
</IfModule>

# Disable server signature start
ServerSignature Off
# Disable server signature end

It works but the URL becomes very ugly: enter image description here

I set it up like this because i use a web hosting that can’t set the document root for the main domain, (it can only set document root for the subdomains). Is there a way i can make so the base URL in Config/App as https://pantradeglobal.com/ ? so the URL becomes https://pantradeglobal.com/web/gogogyes_new_new instead of https://pantradeglobal.com/raymond_new_pantradeglobal/public/web/gogogyes_new_new. Documentation on Codeigniter: https://codeigniter.com/user_guide/installation/deployment.html#deployment-to-shared-hosting-services enter image description here

The server use LiteSpeed, not Apache.

This is my project structure: enter image description here

Block all outgoing HTTP requests from page (javascript) [closed]

I am trying to make a very basic proxy just for learning purposes. The PHP file accesses a URL and displays it. I’m trying to block all outgoing HTTP requests from any links in the page displayed. I tried using a service worker but it does nothing – all requests go through.

proxy.php:

<script type="text/javascript">
function sendm(){
  navigator.serviceWorker.controller.postMessage('test');
}

if ('serviceWorker' in navigator) { 
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('sw.js').then(function(registration) {
      console.log('Service worker registered with scope: ', registration.scope);
    }, function(err) {
      console.log('ServiceWorker registration failed: ', err);
    });
  });
}

  
</script>


<!DOCTYPE html>
<html>

<body>

<div class="content">

<?php


    $url = "www.ft.com";
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);

    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    $response = curl_exec($curl);
    echo $response;

?>
</div>
</body>
</html>

service worker:

self.addEventListener('fetch', function(event) {
  event.respondWith(
    //fetch(event.request)
  );
});

What am I doing wrong? The service worker is registered successfully, but just doesn’t block any requests.