@cactus-agents/utils
Helpers framework-agnostic para uso em Workers, SSR e browser. Cobre detecção de bots, device detection, manipulação de imagens, debug mode e utilitários de player.
Instalação
pnpm add @cactus-agents/utils
Detecção de Bots
isBotUserAgent(ua)
Server-safe. Verifica se uma string de User-Agent corresponde a um bot ou crawler conhecido.
import { isBotUserAgent } from "@cactus-agents/utils";
const ua = request.headers.get("User-Agent") ?? "";
if (isBotUserAgent(ua)) {
// servir página mais leve para Lighthouse/PageSpeed/Googlebot
}
getBotName(ua)
Retorna o nome do bot detectado, ou null se nenhum padrão bateu:
import { getBotName } from "@cactus-agents/utils";
getBotName("Mozilla/5.0 (compatible; Googlebot/2.1)")
// → "googlebot"
getBotName("Mozilla/5.0 (Windows NT 10.0)")
// → null
isBot()
Client-safe. Verifica se o browser atual é um bot — lê navigator.userAgent + flag navigator.webdriver (Selenium/Puppeteer/Playwright). Retorna false no servidor.
import { isBot } from "@cactus-agents/utils";
if (isBot()) {
// não carregar scripts de terceiros pesados
}
Padrões detectados incluem: Googlebot, Chrome Lighthouse, PageSpeed, GTmetrix, Pingdom, WebPageTest, headless Chrome, PhantomJS, Puppeteer, Bingbot, Yandex, Baidu, DuckDuckBot, Twitter/Facebook crawlers, SEMrush, Ahrefs e outros.
Detecção de Device
Todas as funções de device são client-safe — retornam false no servidor.
isIOS()
import { isIOS } from "@cactus-agents/utils";
isIOS() // true em iPhone, iPad (incluindo iPadOS 13+ que reporta como Macintosh)
Detecta iPadOS 13+ verificando Macintosh no UA + navigator.maxTouchPoints > 1.
isAndroid()
import { isAndroid } from "@cactus-agents/utils";
isAndroid() // true em dispositivos Android
isIOSSafari()
import { isIOSSafari } from "@cactus-agents/utils";
isIOSSafari() // true apenas em iOS + Safari nativo (não Chrome/Firefox/Edge no iOS)
Exclui CriOS (Chrome), FxiOS (Firefox), OPiOS (Opera) e EdgiOS (Edge).
isRunningAsApp()
import { isRunningAsApp } from "@cactus-agents/utils";
isRunningAsApp() // true quando em modo standalone (PWA instalada)
Detecta navigator.standalone (iOS) e (display-mode: standalone) (Android/desktop).
isGooglePlayUrl(url)
import { isGooglePlayUrl } from "@cactus-agents/utils";
isGooglePlayUrl("https://play.google.com/store/apps/details?id=com.example")
// → true
Imagens
getImageUrl(image, options?)
Constrói a URL correta para uma imagem, detectando o tipo automaticamente:
import { getImageUrl } from "@cactus-agents/utils";
// Cloudflare Image Delivery — adiciona /w=N e params de quality/format
getImageUrl("https://imagedelivery.net/abc/image-id/public", { width: 300 })
// → "https://imagedelivery.net/abc/image-id/w=300"
// URL externa — retorna como está
getImageUrl("https://external.com/banner.jpg")
// → "https://external.com/banner.jpg"
// Path relativo — adiciona prefixo /api/storage/
getImageUrl("uploads/logo.png")
// → "/api/storage/uploads/logo.png"
// null/undefined — retorna undefined
getImageUrl(null)
// → undefined
buildImageSrcSet(image, widths, options?)
Gera srcset responsivo para imagens do projeto:
imagedelivery.net→ variantesw=...- thumbs legadas com
/mobilee/ipad - imagens sem variantes →
undefined
import { buildImageSrcSet } from "@cactus-agents/utils";
buildImageSrcSet("https://imagedelivery.net/abc/image-id/public", [320, 640]);
// → "https://imagedelivery.net/abc/image-id/w=320?quality=95&format=auto 320w, ..."
getResponsiveImageProps(image, options)
Retorna um objeto pronto para <img> com src, srcSet e sizes.
import { getResponsiveImageProps } from "@cactus-agents/utils";
const image = getResponsiveImageProps(game.image, {
widths: [200, 320, 400, 600],
fallbackWidth: 400,
sizes: "(max-width: 640px) 50vw, 200px",
});
getAssetsUrlForCDN(image, cdnBaseUrl?, options?)
Prepends CDN base URL a assets locais:
import { getAssetsUrlForCDN } from "@cactus-agents/utils";
// Path local → CDN
getAssetsUrlForCDN("/assets/icon.png", "https://cdn.example.com")
// → "https://cdn.example.com/assets/icon.png"
// URL externa → passa direto
getAssetsUrlForCDN("https://external.com/img.jpg", "https://cdn.example.com")
// → "https://external.com/img.jpg"
getImageDefaults() / setImageDefaults(defaults)
Configura padrões globais de imagem (quality, format, etc.) para o processo:
import { setImageDefaults } from "@cactus-agents/utils";
// Uma vez, na inicialização do app:
setImageDefaults({ quality: 90, format: "webp" });
Debug
activateDebugFromUrl()
Ativa o modo debug a partir do query param EnableDebug na URL. Aceita qualquer valor truthy (1, true, on, yes, ou bare ?EnableDebug) para ativar e falsy (0, false, off, no) para desativar. Persiste em sessionStorage["debug_enabled"] e limpa o param da URL.
import { activateDebugFromUrl } from "@cactus-agents/utils";
// Em um root layout effect:
useEffect(() => {
activateDebugFromUrl();
}, []);
isDebugActive()
Retorna true se o debug mode está ativo na sessão atual. Funciona da mesma forma em dev e produção.
import { isDebugActive } from "@cactus-agents/utils";
const [showDebug, setShowDebug] = useState(false);
useEffect(() => {
setShowDebug(isDebugActive());
}, []);
Player
maskPlayerName(fullName)
Mascara o nome completo de um jogador para exibição pública:
import { maskPlayerName } from "@cactus-agents/utils";
maskPlayerName("Joao Silva Santos")
// → "Joao Si**"
maskPlayerName("Maria")
// → "Ma**"
Formato: primeiro nome + 2 primeiras letras do segundo nome + **.
Tipos
interface ImageOptions {
width?: number;
height?: number;
format?: string;
quality?: number;
}
interface ResponsiveImageOptions extends Omit<ImageOptions, "width"> {
widths: number[];
sizes?: string;
fallbackWidth?: number;
}
interface ResponsiveImageProps {
src: string;
srcSet?: string;
sizes?: string;
}
interface ImageDefaults {
quality?: number;
format?: string;
}
Exports completos
| Export | Categoria | Descrição |
|---|---|---|
isBot | Bot | Detecta bot no browser (lê navigator) |
isBotUserAgent | Bot | Detecta bot a partir de string UA (server-safe) |
getBotName | Bot | Retorna nome do bot ou null |
isIOS | Device | iOS (incluindo iPadOS 13+) |
isAndroid | Device | Android |
isIOSSafari | Device | iOS + Safari nativo |
isRunningAsApp | Device | PWA standalone |
isGooglePlayUrl | Device | URL do Google Play |
getImageUrl | Image | URL de imagem com transformação |
buildImageSrcSet | Image | srcset responsivo |
getResponsiveImageProps | Image | Props prontas para <img> |
getAssetsUrlForCDN | Image | Prepend CDN para assets locais |
getImageDefaults | Image | Lê defaults globais de imagem |
setImageDefaults | Image | Define defaults globais de imagem |
activateDebugFromUrl | Debug | Ativa debug via URL token |
isDebugActive | Debug | Verifica se debug está ativo |
maskPlayerName | Player | Mascara nome para exibição pública |