From 8932eb927bf65bd4e7d07bfe26fa0a8295618476 Mon Sep 17 00:00:00 2001 From: tiago <70700766+tiagozip@users.noreply.github.com> Date: Tue, 23 Sep 2025 17:18:31 +0100 Subject: [PATCH] widget: add proper types (0.1.29) --- docs/guide/index.md | 2 + docs/guide/widget.md | 28 +++++++- widget/src/cap.d.ts | 155 ++++++++++++++++++++++++++++++++++++++++ widget/src/package.json | 7 +- 4 files changed, 187 insertions(+), 5 deletions(-) create mode 100644 widget/src/cap.d.ts diff --git a/docs/guide/index.md b/docs/guide/index.md index 1059715..c57fd9e 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -65,6 +65,8 @@ widget.addEventListener("solve", function (e) { Alternatively, you can use `onsolve=""` directly within the widget or wrap the widget in a `
` (where Cap will automatically submit the token alongside other form data. for this, it'll create a hidden field with name set to its `data-cap-hidden-field-name` attribute or `cap-token`). +You can learn how to use the widget in more detail (such as the invisible mode) in the [widget guide](./widget.md). + ## Server-side Cap is fully self-hosted, so you'll need to start a server exposing an API for Cap's methods running at the same URL as specified in the `data-cap-api-endpoint` attribute. diff --git a/docs/guide/widget.md b/docs/guide/widget.md index 78ebcc1..880bfcc 100644 --- a/docs/guide/widget.md +++ b/docs/guide/widget.md @@ -4,7 +4,7 @@ > > **Requirements:** All modern browsers should be supported, but the build script specifically targets the last 10 versions of Chrome, Firefox, Safari and Edge. -`@cap.js/widget` is Cap's client-side library. It includes the `cap-widget` web component, the invisible mode and the Captcha solver. First, add it to your client-side code: +`@cap.js/widget` is Cap's client-side library. It includes the `cap-widget` web component, the invisible mode and the CAPTCHA solver. First, add it to your client-side code: ::: code-group @@ -24,6 +24,12 @@ ::: +You can also import it if you're using a bundler: + +```js +import Cap from '@cap.js/widget'; +``` + ::: warning We're using the latest version of the library here for simplicity, but you should optimally pin a specific version to avoid breaking changes in the future. @@ -59,6 +65,19 @@ widget.addEventListener("solve", function (e) { Alternatively, you can use `onsolve=""` directly within the widget or wrap the widget in a `` (where Cap will automatically submit the token alongside other form data. for this, it'll create a hidden field with name set to its `data-cap-hidden-field-name` attribute or `cap-token`). +## Invisible mode +You can use `new Cap({ ... })` in your client-side JavaScript to create a new Cap instance and use the `solve()` method to solve the challenge. This is helpful for situations where you don't want the Cap widget to be visible but still want security, e.g. on a social media app when posting something. + +```js +import Cap from '@cap.js/widget'; + +const cap = new Cap({ + apiEndpoint: '/api/cap' +}); + +const token = await cap.solve(); +``` + ## Supported events The following custom events are supported: @@ -94,7 +113,8 @@ You can override the default browser fetch implementation by setting `window.CAP ```js window.CAP_CUSTOM_FETCH = function (url, options) { - // Custom fetch implementation + // … add your custom fetch implementation + return fetch(url, options); }; ``` @@ -133,3 +153,7 @@ cap-widget { --cap-opacity-hover: 0.8; } ``` + +## Types + +Cap's widget is fully typed. You can find the type definitions in the `cap.d.ts` file. \ No newline at end of file diff --git a/widget/src/cap.d.ts b/widget/src/cap.d.ts new file mode 100644 index 0000000..1405306 --- /dev/null +++ b/widget/src/cap.d.ts @@ -0,0 +1,155 @@ +declare global { + interface Window { + CAP_CUSTOM_FETCH?: typeof fetch; + CAP_CUSTOM_WASM_URL?: string; + CAP_CSS_NONCE?: string; + CAP_DONT_SKIP_REDEFINE?: boolean; + Cap: typeof Cap; + } +} + +interface CapProgressEventDetail { + progress: number; +} + +interface CapSolveEventDetail { + token: string; +} + +interface CapErrorEventDetail { + isCap: boolean; + message: string; +} + +interface CapProgressEvent extends CustomEvent { + detail: CapProgressEventDetail; +} + +interface CapSolveEvent extends CustomEvent { + detail: CapSolveEventDetail; +} + +interface CapErrorEvent extends CustomEvent { + detail: CapErrorEventDetail; +} + +interface CapResetEvent extends CustomEvent { + detail: Record