npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@codedartdev/slide-captcha-react-native

v0.1.1

Published

React Native and Expo client for Laravel Slide CAPTCHA.

Readme

@codedartdev/slide-captcha-react-native

Pacote TypeScript para usar um Laravel Slide CAPTCHA em apps React Native e Expo. Ele foi pensado para o fluxo de formulário mais comum: o desafio é pré-carregado em segundo plano, aparece somente quando o usuário toca em submit e, depois de resolvido, retorna um token para o submit real.

Instalação

npm install @codedartdev/slide-captcha-react-native

O pacote declara react e react-native como peer dependencies.

Backend Laravel

O backend deve expor:

GET  /slide-captcha/new
POST /slide-captcha/verify

GET /slide-captcha/new deve retornar:

{
  "challenge_id": "uuid",
  "background_url": "http://192.168.0.10:8000/storage/captcha/bg.png",
  "piece_url": "http://192.168.0.10:8000/storage/captcha/piece.png",
  "piece_width": 64,
  "piece_height": 64,
  "image_width": 320,
  "image_height": 180,
  "rotation_enabled": true,
  "rotation_step": 15
}

POST /slide-captcha/verify recebe challenge_id, x, y, rotation e movements, e retorna success, token, reason e message.

Uso com submit de formulário

import { useState } from 'react';
import { Pressable, Text, TextInput, View } from 'react-native';
import { SlideCaptcha } from '@codedartdev/slide-captcha-react-native';

export function LoginScreen() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [captchaVisible, setCaptchaVisible] = useState(false);
  const [submitting, setSubmitting] = useState(false);

  async function submitLogin(slideCaptchaToken: string) {
    setSubmitting(true);

    try {
      await fetch('http://192.168.0.10:8000/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json',
        },
        body: JSON.stringify({ email, password, slideCaptchaToken }),
      });
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <View>
      <TextInput value={email} onChangeText={setEmail} autoCapitalize="none" />
      <TextInput value={password} onChangeText={setPassword} secureTextEntry />

      <Pressable disabled={submitting} onPress={() => setCaptchaVisible(true)}>
        <Text>{submitting ? 'Entrando...' : 'Entrar'}</Text>
      </Pressable>

      <SlideCaptcha
        baseUrl="http://192.168.0.10:8000"
        visible={captchaVisible}
        onRequestClose={() => setCaptchaVisible(false)}
        onSuccess={(token) => {
          setCaptchaVisible(false);
          void submitLogin(token);
        }}
        onError={() => {
          setSubmitting(false);
        }}
      />
    </View>
  );
}

Client HTTP

import { createSlideCaptchaClient } from '@codedartdev/slide-captcha-react-native';

const client = createSlideCaptchaClient({
  baseUrl: 'http://192.168.0.10:8000',
  headers: {
    Accept: 'application/json',
  },
  fetcher: fetch,
});

const challenge = await client.getChallenge();
const response = await client.verifyChallenge({
  challenge_id: challenge.challenge_id,
  x: 120,
  y: 0,
  rotation: 0,
  movements: [{ x: 120, y: 0, r: 0, t: 450 }],
});

baseUrl deve ser absoluto. Em celular físico ou emulador, use o IP da sua máquina na rede, por exemplo http://192.168.0.10:8000, não localhost.

Em produção, use HTTPS para proteger credenciais, cookies, tokens de login e o token retornado pelo CAPTCHA. O uso de HTTP nos exemplos é apenas para desenvolvimento local.

Erros

Erros são normalizados como SlideCaptchaError:

import { SlideCaptchaError } from '@codedartdev/slide-captcha-react-native';

<SlideCaptcha
  baseUrl="http://192.168.0.10:8000"
  visible={captchaVisible}
  onRequestClose={() => setCaptchaVisible(false)}
  onSuccess={handleToken}
  onError={(error) => {
    if (error instanceof SlideCaptchaError) {
      console.log(error.code, error.status, error.reason);
    }
  }}
/>;

Códigos comuns: network_error, http_error, invalid_json, invalid_challenge, invalid_verify_payload, invalid_verify_response e verification_failed.

Textos e estilos

<SlideCaptcha
  baseUrl="http://192.168.0.10:8000"
  visible={captchaVisible}
  onRequestClose={() => setCaptchaVisible(false)}
  onSuccess={handleToken}
  texts={{
    title: 'Verificação',
    description: 'Arraste a peça até o local correto.',
    verify: 'Confirmar',
    refresh: 'Novo desafio',
  }}
  style={{
    maxWidth: 380,
  }}
/>

O componente mede a largura disponível, preserva a proporção da imagem e converte as coordenadas renderizadas para image_width/image_height antes de verificar. Evite colocar o modal dentro de containers que forcem larguras muito pequenas.

Exemplo Expo

Há um exemplo mínimo em example/expo.

cd example/expo
npm install
npm run start

Para testar localmente:

  1. Suba o Laravel na rede, por exemplo php artisan serve --host=0.0.0.0 --port=8000.
  2. Descubra o IP da máquina.
  3. Configure API_BASE_URL em example/expo/App.tsx.

Desenvolvimento

npm install
npm run typecheck
npm run test
npm run lint
npm run build
npm run format

Build publicado

O pacote instalado usa os arquivos compilados em dist, apontados por main, module, types e exports.

O build é gerado automaticamente antes de npm pack e npm publish pelo script prepack:

npm run build

Por segurança e compatibilidade com React Native, Expo, CI e instalações offline, este pacote não executa build em postinstall. Assim, instalar a biblioteca não roda código arbitrário no app consumidor e não exige que o projeto consumidor tenha a toolchain de build do pacote. Os arquivos em src permanecem no repositório como referência técnica; o tarball publicado contém apenas dist, README.md, LICENSE e package.json.

Publicação futura

O pacote possui um deploy automatizado:

npm login
npm run deploy

O release padrão é patch. Também é possível escolher o tipo ou uma versão exata:

npm run deploy -- patch
npm run deploy -- minor
npm run deploy -- major
npm run deploy -- 1.2.3
npm run deploy -- prerelease --preid beta

Antes de publicar pela primeira vez:

  1. Faça login no npm com uma conta que tenha acesso à organização codedartdev.
  2. Garanta que a branch tenha upstream remoto, por exemplo git push -u origin main.
  3. Valide o exemplo Expo contra o backend Laravel real.

O deploy exige uma working tree Git limpa e executa, nesta ordem:

npm run lint
npm run typecheck
npm run test
npm run build
npm version <release>
npm publish --access public
git push --follow-tags

Durante npm publish, o npm executa prepack, que roda npm run build novamente e empacota a versão compilada mais recente. O pacote é scoped público e mantém publishConfig.access como public.