Files
formipay/node_modules/stylelint/lib/formatters/stringFormatter.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

272 lines
6.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
const path = require('path');
const stringWidth = require('string-width');
const table = require('table');
const { yellow, dim, underline, blue, red, green } = require('picocolors');
const calcSeverityCounts = require('./calcSeverityCounts');
const pluralize = require('../utils/pluralize');
const { assertNumber } = require('../utils/validateTypes');
const preprocessWarnings = require('./preprocessWarnings');
const terminalLink = require('./terminalLink');
const MARGIN_WIDTHS = 9;
/**
* @param {string} s
* @returns {string}
*/
function nope(s) {
return s;
}
const levelColors = {
info: blue,
warning: yellow,
error: red,
success: nope,
};
const symbols = {
info: blue(''),
warning: yellow('⚠'),
error: red('✖'),
success: green('✔'),
};
/**
* @param {import('stylelint').LintResult[]} results
* @returns {string}
*/
function deprecationsFormatter(results) {
const allDeprecationWarnings = results.flatMap((result) => result.deprecations || []);
if (allDeprecationWarnings.length === 0) {
return '';
}
const seenText = new Set();
return allDeprecationWarnings.reduce((output, warning) => {
if (seenText.has(warning.text)) return output;
seenText.add(warning.text);
output += yellow('Deprecation Warning: ');
output += warning.text;
if (warning.reference) {
output += dim(' See: ');
output += dim(underline(warning.reference));
}
return `${output}\n`;
}, '\n');
}
/**
* @param {import('stylelint').LintResult[]} results
* @return {string}
*/
function invalidOptionsFormatter(results) {
const allInvalidOptionWarnings = results.flatMap((result) =>
(result.invalidOptionWarnings || []).map((warning) => warning.text),
);
const uniqueInvalidOptionWarnings = [...new Set(allInvalidOptionWarnings)];
return uniqueInvalidOptionWarnings.reduce((output, warning) => {
output += red('Invalid Option: ');
output += warning;
return `${output}\n`;
}, '\n');
}
/**
* @param {string} fromValue
* @param {string} cwd
* @return {string}
*/
function logFrom(fromValue, cwd) {
if (fromValue.startsWith('<')) {
return underline(fromValue);
}
const filePath = path.relative(cwd, fromValue).split(path.sep).join('/');
return terminalLink(filePath, `file://${fromValue}`);
}
/**
* @param {{[k: number]: number}} columnWidths
* @return {number}
*/
function getMessageWidth(columnWidths) {
const width = columnWidths[3];
assertNumber(width);
if (!process.stdout.isTTY) {
return width;
}
const availableWidth = process.stdout.columns < 80 ? 80 : process.stdout.columns;
const fullWidth = Object.values(columnWidths).reduce((a, b) => a + b);
// If there is no reason to wrap the text, we won't align the last column to the right
if (availableWidth > fullWidth + MARGIN_WIDTHS) {
return width;
}
return availableWidth - (fullWidth - width + MARGIN_WIDTHS);
}
/**
* @param {import('stylelint').Warning[]} messages
* @param {string} source
* @param {string} cwd
* @return {string}
*/
function formatter(messages, source, cwd) {
if (messages.length === 0) return '';
/**
* Create a list of column widths, needed to calculate
* the size of the message column and if needed wrap it.
* @type {{[k: string]: number}}
*/
const columnWidths = { 0: 1, 1: 1, 2: 1, 3: 1, 4: 1 };
/**
* @param {[string, string, string, string, string]} columns
* @return {[string, string, string, string, string]}
*/
function calculateWidths(columns) {
for (const [key, value] of Object.entries(columns)) {
const normalisedValue = value ? value.toString() : value;
const width = columnWidths[key];
assertNumber(width);
columnWidths[key] = Math.max(width, stringWidth(normalisedValue));
}
return columns;
}
let output = '\n';
if (source) {
output += `${logFrom(source, cwd)}\n`;
}
/**
* @param {import('stylelint').Warning} message
* @return {string}
*/
function formatMessageText(message) {
let result = message.text;
result = result
// Remove all control characters (newline, tab and etc)
.replace(/[\u0001-\u001A]+/g, ' ') // eslint-disable-line no-control-regex
.replace(/\.$/, '');
const ruleString = ` (${message.rule})`;
if (result.endsWith(ruleString)) {
result = result.slice(0, result.lastIndexOf(ruleString));
}
return result;
}
const cleanedMessages = messages.map((message) => {
const { line, column, severity } = message;
/**
* @type {[string, string, string, string, string]}
*/
const row = [
line ? line.toString() : '',
column ? column.toString() : '',
symbols[severity] ? levelColors[severity](symbols[severity]) : severity,
formatMessageText(message),
dim(message.rule || ''),
];
calculateWidths(row);
return row;
});
output += table
.table(cleanedMessages, {
border: table.getBorderCharacters('void'),
columns: {
0: { alignment: 'right', width: columnWidths[0], paddingRight: 0 },
1: { alignment: 'left', width: columnWidths[1] },
2: { alignment: 'center', width: columnWidths[2] },
3: {
alignment: 'left',
width: getMessageWidth(columnWidths),
wrapWord: getMessageWidth(columnWidths) > 1,
},
4: { alignment: 'left', width: columnWidths[4], paddingRight: 0 },
},
drawHorizontalLine: () => false,
})
.split('\n')
.map((el) => el.replace(/(\d+)\s+(\d+)/, (_m, p1, p2) => dim(`${p1}:${p2}`)).trimEnd())
.join('\n');
return output;
}
/**
* @type {import('stylelint').Formatter}
*/
module.exports = function stringFormatter(results, returnValue) {
let output = invalidOptionsFormatter(results);
output += deprecationsFormatter(results);
const counts = { error: 0, warning: 0 };
output = results.reduce((accum, result) => {
preprocessWarnings(result);
accum += formatter(
result.warnings,
result.source || '',
(returnValue && returnValue.cwd) || process.cwd(),
);
for (const warning of result.warnings) {
calcSeverityCounts(warning.severity, counts);
}
return accum;
}, output);
// Ensure consistent padding
output = output.trim();
if (output !== '') {
output = `\n${output}\n\n`;
const errorCount = counts.error;
const warningCount = counts.warning;
const total = errorCount + warningCount;
if (total > 0) {
const error = red(`${errorCount} ${pluralize('error', errorCount)}`);
const warning = yellow(`${warningCount} ${pluralize('warning', warningCount)}`);
const tally = `${total} ${pluralize('problem', total)} (${error}, ${warning})`;
output += `${tally}\n\n`;
}
}
return output;
};