{"_rev":"45-fe488bcddabc236469833a0c939ca21c","time":{"created":"2024-04-23T20:08:21.496Z","1.0.2":"2023-04-11T21:56:56.400Z","modified":"2024-04-23T20:08:22.161Z","1.0.3":"2023-04-11T22:01:28.464Z","1.0.4":"2023-04-11T22:17:39.133Z","1.0.5":"2023-04-11T22:20:09.829Z","1.0.6":"2023-04-11T22:51:36.758Z","1.0.7":"2023-04-11T23:07:20.574Z","1.0.8":"2023-04-11T23:10:06.370Z","1.0.9":"2023-04-11T23:15:10.595Z","1.1.0":"2023-10-04T16:53:35.303Z","1.1.1":"2023-10-04T17:21:11.600Z","1.1.2":"2023-10-04T17:36:22.246Z","1.1.3":"2023-10-04T18:16:57.892Z","1.1.4":"2023-10-04T18:20:36.616Z","1.1.5":"2023-10-04T18:30:13.516Z","1.1.6":"2023-10-04T18:37:32.711Z","1.1.7":"2023-10-04T18:51:41.301Z","1.1.8":"2023-10-04T18:54:46.441Z","1.1.9":"2023-10-04T19:00:13.063Z","1.1.10":"2023-10-04T19:04:13.002Z","1.1.11":"2023-10-04T19:07:54.491Z","1.1.13":"2023-10-04T19:22:31.966Z","1.1.14":"2023-10-04T20:13:50.065Z","1.1.15":"2023-10-04T20:36:44.038Z","1.1.16":"2023-10-04T20:40:10.203Z","1.1.17":"2023-10-04T20:44:39.435Z","1.1.18":"2023-10-04T20:49:01.637Z","1.1.19":"2023-10-04T21:20:44.949Z","1.1.20":"2023-10-04T21:30:29.913Z","1.1.21":"2023-10-04T21:35:24.487Z","2.0.1":"2023-10-04T21:45:45.949Z","2.0.2":"2023-10-04T21:57:19.112Z","2.0.3":"2023-10-04T22:01:13.618Z","2.0.4":"2023-10-04T22:02:33.794Z","2.0.5":"2023-10-04T22:49:22.967Z","2.0.6":"2023-10-04T22:57:24.388Z","2.0.7":"2023-10-05T00:19:49.904Z","2.0.8":"2023-10-05T00:22:11.965Z","2.0.9":"2023-10-05T05:48:02.987Z","2.0.10":"2023-10-05T05:50:53.965Z","2.0.11":"2023-10-05T06:04:54.360Z","2.0.12":"2023-10-06T04:54:41.370Z","2.0.13":"2023-10-06T05:50:59.005Z","2.0.14":"2023-10-12T15:37:17.755Z","2.0.16":"2024-04-23T20:08:21.791Z"},"_id":"vanilla-captcha","name":"vanilla-captcha","dist-tags":{"latest":"2.0.16"},"versions":{"2.0.16":{"name":"vanilla-captcha","version":"2.0.16","description":"pure javascript captcha implementation","main":"index.js","scripts":{"clean":"rm -rf dom.d.* index.d.* utils.d.* *.js","build":"npm run clean && tsc","cp":"cp -r ./dist/* ./","git:prepublish":"git add . && git commit --amend && npm version patch","go":"npm run build &&  npm run cp && npm run git:prepublish && npm publish && npm run clean"},"exports":{".":{"types":"./index.d.ts","default":"./index.js"},"./dom":{"types":"./index.d.ts","default":"./dom.js"},"./utils":{"types":"./index.d.ts","default":"./utils.js"}},"type":"module","keywords":["anti-bot","pure js","captcha","simple","adaptable","easy to use"],"author":{"name":"Carlos Daniel Vilaseca","email":"carlosvilaseca406@avangenio.com","url":"https://github.com/carlos-err406"},"license":"MIT","repository":{"url":"git+https://github.com/Carlos-err406/vanilla-captcha.git","type":"github"},"homepage":"https://github.com/Carlos-err406/vanilla-captcha#readme","devDependencies":{"@types/node":"^20.8.2"},"dependencies":{"sharp":"^0.32.6","svg-builder":"^2.0.0"},"_id":"vanilla-captcha@2.0.16","gitHead":"c288d487df277589bc15b53661186faeb4e10149","types":"./index.d.ts","bugs":{"url":"https://github.com/Carlos-err406/vanilla-captcha/issues"},"_nodeVersion":"20.12.2","_npmVersion":"10.5.0","dist":{"integrity":"sha512-Doq9dESaFFQ6vXgrM4AIjFerxgKxa8pl2Zdf8C7Mu6RUcArCbX0RQjn36dmk3wop+T2oThgZFOpzqHVSEGZZLg==","shasum":"fa1b87ee6c0a2eea7eb7d6089df4989752356d6f","tarball":"https://registry.npmjs.org/vanilla-captcha/-/vanilla-captcha-2.0.16.tgz","fileCount":10,"unpackedSize":16579,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDO1Zm8vD16Nqr9CYSiuxbf5cFSKMWTyu2g9CwXhaYZYQIhAIfg6LuFTqaNLvuExJtlO0kOdcXM7eCGTJ1uU0pA9JZT"}]},"_npmUser":{"name":"carlos.vilaseca","email":"carlosvilaseca406@gmail.com"},"directories":{},"maintainers":[{"name":"carlos.vilaseca","email":"carlosvilaseca406@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/vanilla-captcha_2.0.16_1713902901629_0.5829965830153809"},"_hasShrinkwrap":false}},"maintainers":[{"name":"carlos.vilaseca","email":"carlosvilaseca406@gmail.com"}],"description":"pure javascript captcha implementation","homepage":"https://github.com/Carlos-err406/vanilla-captcha#readme","keywords":["anti-bot","pure js","captcha","simple","adaptable","easy to use"],"repository":{"url":"git+https://github.com/Carlos-err406/vanilla-captcha.git","type":"github"},"author":{"name":"Carlos Daniel Vilaseca","email":"carlosvilaseca406@avangenio.com","url":"https://github.com/carlos-err406"},"bugs":{"url":"https://github.com/Carlos-err406/vanilla-captcha/issues"},"license":"MIT","readme":"![License](https://img.shields.io/github/license/carlos-err406/vanilla-captcha) ![Stars](https://img.shields.io/github/stars/carlos-err406/vanilla-captcha) ![Forks](https://img.shields.io/github/forks/carlos-err406/vanilla-captcha) ![Issues](https://img.shields.io/github/issues/carlos-err406/vanilla-captcha) ![Contributors](https://img.shields.io/github/contributors/carlos-err406/vanilla-captcha)\r\n\r\n# Vanilla Captcha\r\n\r\nA highly customizable and easy to use Captcha library. Based on my [sveltekit component](https://github.com/carlos-err406/captcha-sveltekit), decided to make a more generic implementation for all frameworks in vanilla JavaScript\r\nSupports running in the **server** as well as in the **browser**\r\n`Server` usage uses sharp and svg-builder and `Browser` usage uses the canvas html element\r\n\r\n# Installation\r\n\r\n```sh\r\nnpm install vanilla-captcha #or bun, yarn, pnpm, etc\r\n```\r\n\r\n# Usage\r\n\r\nBe aware that the server usage can't be used in client side and vice versa, you'll get errors like document is not defined or some `sharp` nasty errors\r\n\r\n## Server\r\n\r\n```js\r\n//in the server\r\nimport generate from \"vanilla-captcha\";\r\nconst getCaptcha = async () => {\r\n  const charAmmount = 5;\r\n  const { answer, captcha } = await generate(charAmmount);\r\n};\r\n```\r\n\r\n`answer` is the string and `captcha` is a Buffer, so you can do whatever you want with it, like returning it in a response as is\r\n\r\n```js\r\nreturn new Response(captcha, { status: 200, headers: { \"X-answer\": answer } });\r\n```\r\n\r\nthen you can use the `response.blob()` method and `URL.createObjectURL()`\r\n\r\n```js\r\nfetch(\"/get-captcha-url\", {\r\n  method: \"GET\",\r\n})\r\n  .then((response) => response.blob())\r\n  .then((blob) => {\r\n    const img = document.createElement(\"img\");\r\n    img.src = URL.createObjectURL(blob);\r\n    document.body.appendChild(img);\r\n  });\r\n```\r\n\r\n## Browser\r\n\r\nBrowser usage is more straightforward\r\n\r\n```js\r\nimport generateSync from \"vanilla-captcha/dom\";\r\nconst charAmount = 5;\r\nconst { answer, captcha } = generateSync(charAmount);\r\nconst img = document.createElement(\"img\");\r\nimg.src = captcha; //notice that there is no need to URL.createObjectURL(), because is the canvas.toDataURL() string\r\ndocument.body.appendChild(img);\r\n```\r\n\r\nNotice the difference in the import statement, browser image generation logic is separated from the server one, be sure to import what you need where you need it.\r\nAnd yes the browser image generation version is not async since it does not use sharp, nor Buffer.\r\n\r\n## Utilities\r\n\r\nthe generate methods (`generate` and `generateSync`) can recieve a series of options to customize the image\r\n\r\n### generateSync\r\n\r\npretty self-explained options\r\n\r\n```ts\r\ninterface CaptchaSyncOptions {\r\n  width: number; // width of the generated image\r\n  height: number; // height of the generated image\r\n  backgroundColor: string;\r\n  font: string; // font of the generated image as \"Bold 30px Arial\"\r\n  fontColor: string;\r\n  lineAmount: number; //amount of strikes over the image\r\n  lineColor: string;\r\n  lineWidth: number;\r\n}\r\n```\r\n\r\ndefault values for the `options` parameter in the `generateSync` method:\r\n\r\n```ts\r\nwidth: 345,\r\nheight: 96,\r\nbackgroundColor: \"#FFF\",\r\nfont: \"Bold 30px Arial\",\r\nfontColor: \"#777\",\r\nlineColor: \"#777\",\r\nlineAmount: 10,\r\nlineWidth: 1\r\n```\r\n\r\n### generate\r\n\r\n```ts\r\nexport interface CaptchaOptions {\r\n  width: number;\r\n  height: number;\r\n  backgroundColor: string;\r\n  font: string;\r\n  fontColor: string;\r\n  fontSize: number;\r\n  fontWeight: number;\r\n  lineColor: string;\r\n  lineAmount: number;\r\n  lineWidth: number;\r\n}\r\n```\r\n\r\nnotice this one has to extra properties for `fontSize` and `fontWeight`, in this case the `font` property is only the font-family property like \"Ubuntu\" for example\r\ndefault values for the `options` parameter in the `generate` method:\r\n\r\n```ts\r\nwidth: 345,\r\nheight: 96,\r\nbackgroundColor: \"#FFF\",\r\nfont: \"Arial\",\r\nfontSize: 30,\r\nfontWeight: 600,\r\nfontColor: \"#777\",\r\nlineColor: \"#777\",\r\nlineAmount: 10,\r\nlineWidth: 1\r\n```\r\n\r\n### Other utilities\r\n\r\nyou can also use the image generation method if you want to do it with a string of your own instead of the random string generated by `vanilla-captcha` like so:\r\n\r\n```js\r\nimport { generateImage } from \"vanilla-captcha\";\r\nconst const answer = \"uRock\"\r\nconst myCaptcha = generateImage(answer)\r\nconst myCaptcha2 = generateImage(answer, { backgroundColor: \"#000\", fontColor: \"#FFF\" })\r\n//this generates the buffers for 2 images with the same answer\r\n```\r\n\r\nor in the browser\r\n\r\n```js\r\nimport { generateImageSync } from \"vanilla-captcha/dom\";\r\n```\r\n\r\nThere is also a validation method for the lazzy ones\r\n\r\n```ts\r\nimport { validate } from \"vanilla-captcha/utils\";\r\nconst userInput = \"urock\";\r\nconst answer = \"uRock\";\r\nconst valid = validate(userInput, answer, { caseSensitive: false });\r\nconsole.log(valid); //true\r\n```\r\n\r\nmethod uses caseSensitive by default so you don't need to to pass it\r\n\r\n```ts\r\nconst valid = validate(userInput, answer);\r\nconsole.log(valid); //false\r\n```\r\n\r\n# Demo\r\n\r\ndemo for tryout at: [https://vanilla-captcha-demo.vercel.app/](https://vanilla-captcha-demo.vercel.app/)\r\n\r\ndemo source code at: [https://github.com/Carlos-err406/vanilla-captcha-demo.git](https://github.com/Carlos-err406/vanilla-captcha-demo.git)\r\n\r\n# Licence\r\n\r\nMIT licensed\r\n","readmeFilename":"README.md"}