Files
formipay/node_modules/webpack/lib/util/parseJson.js
dwindown e8fbfb14c1 fix: prevent asset conflicts between React and Grid.js versions
Add coexistence checks to all enqueue methods to prevent loading
both React and Grid.js assets simultaneously.

Changes:
- ReactAdmin.php: Only enqueue React assets when ?react=1
- Init.php: Skip Grid.js when React active on admin pages
- Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0
- Customer.php, Product.php, License.php: Add coexistence checks

Now the toggle between Classic and React versions works correctly.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 17:02:14 +07:00

113 lines
3.1 KiB
JavaScript

/*
MIT License http://www.opensource.org/licenses/mit-license.php
*/
"use strict";
/** @typedef {import("../util/fs").JsonValue} JsonValue */
// Inspired by https://github.com/npm/json-parse-even-better-errors
// Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
// because the buffer-to-string conversion in `fs.readFileSync()`
// translates it to FEFF, the UTF-16 BOM.
/**
* @param {string | Buffer} txt text
* @returns {string} text without BOM
*/
const stripBOM = (txt) => String(txt).replace(/^\uFEFF/, "");
class JSONParseError extends SyntaxError {
/**
* @param {Error} err err
* @param {EXPECTED_ANY} raw raw
* @param {string} txt text
* @param {number=} context context
* @param {EXPECTED_FUNCTION=} caller caller
*/
constructor(err, raw, txt, context = 20, caller = parseJson) {
let originalMessage = err.message;
/** @type {string} */
let message;
/** @type {number} */
let position;
if (typeof raw !== "string") {
message = `Cannot parse ${Array.isArray(raw) && raw.length === 0 ? "an empty array" : String(raw)}`;
position = 0;
} else if (!txt) {
message = `${originalMessage} while parsing empty string`;
position = 0;
} else {
// Node 20 puts single quotes around the token and a comma after it
const UNEXPECTED_TOKEN = /^Unexpected token '?(.)'?(,)? /i;
const badTokenMatch = originalMessage.match(UNEXPECTED_TOKEN);
const badIndexMatch = originalMessage.match(/ position\s+(\d+)/i);
if (badTokenMatch) {
const h = badTokenMatch[1].charCodeAt(0).toString(16).toUpperCase();
const hex = `0x${h.length % 2 ? "0" : ""}${h}`;
originalMessage = originalMessage.replace(
UNEXPECTED_TOKEN,
`Unexpected token ${JSON.stringify(badTokenMatch[1])} (${hex})$2 `
);
}
/** @type {number | undefined} */
let errIdx;
if (badIndexMatch) {
errIdx = Number(badIndexMatch[1]);
} else if (
// doesn't happen in Node 22+
/^Unexpected end of JSON.*/i.test(originalMessage)
) {
errIdx = txt.length - 1;
}
if (errIdx === undefined) {
message = `${originalMessage} while parsing '${txt.slice(0, context * 2)}'`;
position = 0;
} else {
const start = errIdx <= context ? 0 : errIdx - context;
const end =
errIdx + context >= txt.length ? txt.length : errIdx + context;
const slice = `${start ? "..." : ""}${txt.slice(start, end)}${end === txt.length ? "" : "..."}`;
message = `${originalMessage} while parsing ${txt === slice ? "" : "near "}${JSON.stringify(slice)}`;
position = errIdx;
}
}
super(message);
this.name = "JSONParseError";
this.systemError = err;
this.position = position;
Error.captureStackTrace(this, caller || this.constructor);
}
}
/**
* @template [R=JsonValue]
* @callback ParseJsonFn
* @param {string} raw text
* @param {(this: EXPECTED_ANY, key: string, value: EXPECTED_ANY) => EXPECTED_ANY=} reviver reviver
* @returns {R} parsed JSON
*/
/** @type {ParseJsonFn} */
const parseJson = (raw, reviver) => {
const txt = stripBOM(raw);
try {
return JSON.parse(txt, reviver);
} catch (err) {
throw new JSONParseError(/** @type {Error} */ (err), raw, txt);
}
};
module.exports = parseJson;