ubon
Version:
Security scanner for AI-generated apps (Cursor, Lovable, Windsurf, v0). Catches hardcoded secrets, prompt injection, hallucinated imports, Server Actions / Edge runtime mistakes, and the vibe-coded vulnerabilities traditional linters miss.
87 lines • 2.79 kB
JavaScript
;
/**
* Tiny chalk-compatible color shim built on picocolors.
*
* Supports the chainable subset Ubon actually uses:
* - basic colors: red, green, yellow, blue, cyan, gray, white, black
* - basic backgrounds: bgRed, bgYellow, bgBlue
* - modifiers: bold, dim, italic, underline
* - hex/bgHex truecolor (24-bit ANSI) for branded UI
*
* Honors NO_COLOR, FORCE_COLOR, and process.stdout.isTTY via picocolors' own
* detection. If colors are disabled the styler is a pass-through identity.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const picocolors_1 = __importDefault(require("picocolors"));
const isColorEnabled = () => {
if (process.env.NO_COLOR)
return false;
return Boolean(picocolors_1.default.isColorSupported);
};
function hexToRgb(hex) {
const v = hex.replace(/^#/, '');
const full = v.length === 3 ? v.split('').map((c) => c + c).join('') : v;
const num = Number.parseInt(full, 16);
if (Number.isNaN(num))
return [255, 255, 255];
return [(num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff];
}
const RESET = '\u001b[0m';
const ansi = (code) => ({ open: `\u001b[${code}m`, close: RESET });
const ansiTrue = (r, g, b, bg = false) => ({ open: `\u001b[${bg ? 48 : 38};2;${r};${g};${b}m`, close: RESET });
const STYLES = {
red: ansi(31),
green: ansi(32),
yellow: ansi(33),
blue: ansi(34),
magenta: ansi(35),
cyan: ansi(36),
white: ansi(37),
gray: ansi(90),
black: ansi(30),
bgRed: ansi(41),
bgGreen: ansi(42),
bgYellow: ansi(43),
bgBlue: ansi(44),
bold: ansi(1),
dim: ansi(2),
italic: ansi(3),
underline: ansi(4),
};
function build(codes) {
const fn = ((input) => {
if (!isColorEnabled() || codes.length === 0)
return input;
let opens = '';
let closes = '';
for (const c of codes) {
opens += c.open;
closes = c.close + closes;
}
return opens + input + closes;
});
for (const [name, code] of Object.entries(STYLES)) {
Object.defineProperty(fn, name, {
get() {
return build([...codes, code]);
},
enumerable: false,
configurable: true,
});
}
fn.hex = (color) => {
const [r, g, b] = hexToRgb(color);
return build([...codes, ansiTrue(r, g, b, false)]);
};
fn.bgHex = (color) => {
const [r, g, b] = hexToRgb(color);
return build([...codes, ansiTrue(r, g, b, true)]);
};
return fn;
}
const chalk = build([]);
exports.default = chalk;
//# sourceMappingURL=colors.js.map