@captcha-kit/core 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +674 -0
- package/README.md +169 -0
- package/dist/Factory/CaptchaFactory.d.ts +16 -0
- package/dist/Factory/CaptchaFactory.js +32 -0
- package/dist/Factory/index.d.ts +1 -0
- package/dist/Factory/index.js +1 -0
- package/dist/Function/getCaptchaFormElement.d.ts +8 -0
- package/dist/Function/getCaptchaFormElement.js +8 -0
- package/dist/Function/getCaptchaScript.d.ts +8 -0
- package/dist/Function/getCaptchaScript.js +8 -0
- package/dist/Function/index.d.ts +3 -0
- package/dist/Function/index.js +3 -0
- package/dist/Function/verifyCaptcha.d.ts +9 -0
- package/dist/Function/verifyCaptcha.js +9 -0
- package/dist/Interface/CaptchaFactoryInterface.d.ts +15 -0
- package/dist/Interface/CaptchaFactoryInterface.js +1 -0
- package/dist/Interface/CaptchaInterface.d.ts +18 -0
- package/dist/Interface/CaptchaInterface.js +1 -0
- package/dist/Interface/index.d.ts +2 -0
- package/dist/Interface/index.js +2 -0
- package/dist/Type/Types.d.ts +3 -0
- package/dist/Type/Types.js +1 -0
- package/dist/Type/index.d.ts +1 -0
- package/dist/Type/index.js +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/eslint.config.mjs +6 -0
- package/package.json +32 -0
- package/src/Factory/CaptchaFactory.ts +44 -0
- package/src/Factory/index.ts +1 -0
- package/src/Function/getCaptchaFormElement.tsx +11 -0
- package/src/Function/getCaptchaScript.tsx +11 -0
- package/src/Function/index.tsx +3 -0
- package/src/Function/verifyCaptcha.ts +12 -0
- package/src/Interface/CaptchaFactoryInterface.ts +17 -0
- package/src/Interface/CaptchaInterface.ts +21 -0
- package/src/Interface/index.ts +2 -0
- package/src/Type/Types.ts +6 -0
- package/src/Type/index.ts +1 -0
- package/src/index.tsx +4 -0
- package/tests/getCaptchaFormElement.test.tsx +25 -0
- package/tests/getCaptchaScript.test.tsx +25 -0
- package/tests/verifyCaptcha.test.ts +31 -0
- package/tsconfig.eslint.json +4 -0
- package/tsconfig.json +38 -0
- package/vitest.config.ts +9 -0
package/README.md
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
# MessageKit Core
|
2
|
+
|
3
|
+
**MessageKit Core is a TypeScript library that provides foundational classes, interfaces, and tools for handling and processing messages within domain-driven and AI applications.** This package offers a set of abstractions that make it easier to manage messaging workflows, including sending and receiving messages across different channels.
|
4
|
+
|
5
|
+
## Supported Packages
|
6
|
+
|
7
|
+
The `@messagekit/core` package supports several email service providers, including:
|
8
|
+
|
9
|
+
- **Mailgun**: Integration with the Mailgun email service for sending emails.
|
10
|
+
- **Nylas**: Integration with the Nylas email service for sending emails.
|
11
|
+
- **Resend**: Integration with the Resend email service for sending emails.
|
12
|
+
- **SendGrid**: Integration with the SendGrid email service for sending emails.
|
13
|
+
|
14
|
+
### Adding New Providers
|
15
|
+
|
16
|
+
To add a new email provider, you can implement the `EmailProviderFactoryInterface` and `EmailSenderInterface`. Here’s a brief example of how to implement a new provider:
|
17
|
+
|
18
|
+
1. **Create a New Folder**: Create a new folder for your provider (e.g., `packages/myprovider`).
|
19
|
+
2. **Implement the Factory**: Create a factory class that implements the `EmailProviderFactoryInterface`. This class should have a method to create an email sender instance.
|
20
|
+
|
21
|
+
Example:
|
22
|
+
```typescript
|
23
|
+
import { MyProviderEmailSender } from './Provider/MyProviderEmailSender';
|
24
|
+
import type { TypeMyProviderConfig } from './Type/Types';
|
25
|
+
import type { EmailProviderFactoryInterface, EmailSenderInterface } from '@messagekit/core';
|
26
|
+
|
27
|
+
export class MyProviderEmailProviderFactory implements EmailProviderFactoryInterface<TypeMyProviderConfig> {
|
28
|
+
public async createSender(config: TypeMyProviderConfig): Promise<EmailSenderInterface> {
|
29
|
+
return new MyProviderEmailSender(config);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
```
|
33
|
+
|
34
|
+
3. **Implement the Email Sender**: Create a class that implements the `EmailSenderInterface`. This class should handle the logic for sending emails.
|
35
|
+
|
36
|
+
Example:
|
37
|
+
```typescript
|
38
|
+
import type { TypeEmailMessage, TypeEmailMessageResponse, EmailSenderInterface } from '@messagekit/core';
|
39
|
+
|
40
|
+
export class MyProviderEmailSender implements EmailSenderInterface {
|
41
|
+
constructor(private config: TypeMyProviderConfig) {}
|
42
|
+
|
43
|
+
public async send(message: TypeEmailMessage): Promise<TypeEmailMessageResponse> {
|
44
|
+
// Implement the logic to send the email using your provider's API
|
45
|
+
// It is recommended to use transformers and types for consistency
|
46
|
+
}
|
47
|
+
}
|
48
|
+
```
|
49
|
+
|
50
|
+
4. **Use Transformers and Types**: It is recommended to use transformers and types to ensure consistency in the data being processed. This helps maintain the expected structure and format across different email providers.
|
51
|
+
|
52
|
+
### Folder Structure
|
53
|
+
|
54
|
+
The folder structure for each package typically includes:
|
55
|
+
|
56
|
+
- `src/`: Contains the source code for the package, including:
|
57
|
+
- `Factory/`: Contains factory classes for creating email providers.
|
58
|
+
- `Provider/`: Contains classes that implement the email sending logic.
|
59
|
+
- `Transformer/`: Contains classes for transforming email messages to the required format.
|
60
|
+
- `Type/`: Contains type definitions and interfaces.
|
61
|
+
- `tests/`: Contains unit tests for the package.
|
62
|
+
- `README.md`: Documentation for the package.
|
63
|
+
- `.env`: Environment variables for configuration.
|
64
|
+
|
65
|
+
## Installation
|
66
|
+
|
67
|
+
Install the package using pnpm:
|
68
|
+
|
69
|
+
```bash
|
70
|
+
pnpm add @messagekit/core
|
71
|
+
```
|
72
|
+
|
73
|
+
## Features
|
74
|
+
|
75
|
+
- **Unified Messaging Interfaces**: Define consistent interfaces for handling message-related actions, such as downloading attachments, sending messages, and handling webhooks.
|
76
|
+
- **AI Integration Ready**: Tools are designed to wrap actions and services, allowing them to be easily integrated into AI workflows, especially with structured validation using Zod.
|
77
|
+
- **Extensible and Reusable**: Easily extend the provided base classes and interfaces to fit your specific messaging needs.
|
78
|
+
|
79
|
+
## Usage
|
80
|
+
|
81
|
+
### Sending an Email
|
82
|
+
|
83
|
+
The `sendEmail` function is the primary method for sending emails. It can be used as follows:
|
84
|
+
|
85
|
+
```typescript
|
86
|
+
import { sendEmail } from '@messagekit/core';
|
87
|
+
|
88
|
+
const emailMessage = {
|
89
|
+
from: [{ email: 'sender@example.com', name: 'Sender Name' }],
|
90
|
+
to: [{ email: 'recipient@example.com', name: 'Recipient Name' }],
|
91
|
+
subject: 'Hello from MessageKit',
|
92
|
+
text: 'This is a test email sent using MessageKit.',
|
93
|
+
html: '<p>This is a test email sent using MessageKit.</p>',
|
94
|
+
attachments: [
|
95
|
+
{
|
96
|
+
content: 'base64-encoded-content',
|
97
|
+
filename: 'attachment.txt',
|
98
|
+
path: '/path/to/attachment.txt',
|
99
|
+
},
|
100
|
+
],
|
101
|
+
};
|
102
|
+
|
103
|
+
const config = {
|
104
|
+
PROVIDER_NAME: process.env.PROVIDER_NAME, // any supported service from @messagekit/[PROVIDER_NAME]
|
105
|
+
RESEND_API_KEY: process.env.RESEND_API_KEY,
|
106
|
+
RESEND_API_URL: process.env.RESEND_API_URL,
|
107
|
+
};
|
108
|
+
|
109
|
+
sendEmail(emailMessage, config)
|
110
|
+
.then(response => {
|
111
|
+
console.log('Email sent successfully:', response);
|
112
|
+
})
|
113
|
+
.catch(error => {
|
114
|
+
console.error('Error sending email:', error);
|
115
|
+
});
|
116
|
+
```
|
117
|
+
|
118
|
+
### Configuration
|
119
|
+
|
120
|
+
Configuration for the `sendEmail` function can be defined in a `.env` file. The naming convention for the configuration variables is as follows:
|
121
|
+
|
122
|
+
- `PROVIDER_NAME`: The email service provider (e.g., 'sendgrid', 'mailgun', 'resend').
|
123
|
+
- `RESEND_API_KEY`: The API key for authenticating with the Resend API, for Nylas it will be `NYLAS_API_KEY`, and so on...
|
124
|
+
- `RESEND_API_URL`: An optional custom API URL.
|
125
|
+
|
126
|
+
Example `.env` file:
|
127
|
+
|
128
|
+
```
|
129
|
+
RESEND_API_KEY=your_resend_api_key
|
130
|
+
RESEND_API_URL=https://api.resend.com
|
131
|
+
```
|
132
|
+
|
133
|
+
### Extensibility
|
134
|
+
|
135
|
+
The `@messagekit/core` package is designed to be extensible. You can create new email providers by implementing the `EmailProviderFactoryInterface` and `EmailSenderInterface`. This allows you to add support for additional email services in the future.
|
136
|
+
|
137
|
+
## Rationale
|
138
|
+
|
139
|
+
The `@messagekit/core` package is designed to provide a consistent and extensible foundation for managing messaging workflows in TypeScript applications. By using well-defined interfaces and tools, developers can easily integrate messaging capabilities into their domain-driven designs and AI-driven processes. The library also leverages Zod for schema validation, ensuring that the data being processed meets the expected structure.
|
140
|
+
|
141
|
+
## Serverless Focus
|
142
|
+
|
143
|
+
This package focuses on serverless (nodeless) environments, which is why it implements integrations with raw HTTP APIs.
|
144
|
+
|
145
|
+
## Installation & Setup
|
146
|
+
|
147
|
+
Install the package using pnpm:
|
148
|
+
|
149
|
+
```bash
|
150
|
+
pnpm add @messagekit/core
|
151
|
+
pnpm add @messagekit/resend
|
152
|
+
```
|
153
|
+
|
154
|
+
Ensure that your project is set up to handle TypeScript and supports ES modules, as this library is built with modern JavaScript standards.
|
155
|
+
|
156
|
+
## Contributing
|
157
|
+
|
158
|
+
Contributions are welcome! Feel free to fork this project and submit pull requests. Before submitting, please ensure your code passes all linting and unit tests.
|
159
|
+
|
160
|
+
You can format code using:
|
161
|
+
|
162
|
+
```bash
|
163
|
+
pnpm format
|
164
|
+
```
|
165
|
+
|
166
|
+
You can run unit tests using:
|
167
|
+
|
168
|
+
```bash
|
169
|
+
pnpm test
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import type { CaptchaInterface } from '../Interface/index.js';
|
2
|
+
import type { CaptchaFactoryInterface } from '../Interface/index.js';
|
3
|
+
import type { TypeBaseConfig } from '../Type/index.js';
|
4
|
+
/**
|
5
|
+
* Interface representing an captcha provider factory.
|
6
|
+
*/
|
7
|
+
export declare class CaptchaFactory implements CaptchaFactoryInterface<TypeBaseConfig> {
|
8
|
+
/**
|
9
|
+
* Creates an captcha based on the provided configuration.
|
10
|
+
*
|
11
|
+
* @param {TypeConfig} config - The configuration object for the email provider.
|
12
|
+
* @returns {Promise<CaptchaInterface>} - An captcha instance.
|
13
|
+
* @throws {Error} - Throws an error when requested provider captcha can't be created.
|
14
|
+
*/
|
15
|
+
create(config: TypeBaseConfig): Promise<CaptchaInterface>;
|
16
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
/**
|
2
|
+
* Interface representing an captcha provider factory.
|
3
|
+
*/
|
4
|
+
export class CaptchaFactory {
|
5
|
+
/**
|
6
|
+
* Creates an captcha based on the provided configuration.
|
7
|
+
*
|
8
|
+
* @param {TypeConfig} config - The configuration object for the email provider.
|
9
|
+
* @returns {Promise<CaptchaInterface>} - An captcha instance.
|
10
|
+
* @throws {Error} - Throws an error when requested provider captcha can't be created.
|
11
|
+
*/
|
12
|
+
async create(config) {
|
13
|
+
try {
|
14
|
+
const providerName = config.CAPTCHA_PROVIDER ?? 'core';
|
15
|
+
const packageName = '@captcha/' + providerName;
|
16
|
+
// Dynamically import the package and access the default export
|
17
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
18
|
+
const ProviderModule = await import(packageName);
|
19
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
20
|
+
const Factory = ProviderModule.default;
|
21
|
+
// we need to check if Factory has the create method, required by the EmailProviderFactoryInterface
|
22
|
+
if (typeof Factory !== 'function' || !('create' in Factory.prototype)) {
|
23
|
+
throw new Error('The provider module does not implement the required interface.');
|
24
|
+
}
|
25
|
+
// Instantiate the factory and create the captcha
|
26
|
+
return new Factory().create(config);
|
27
|
+
}
|
28
|
+
catch (error) {
|
29
|
+
throw new Error(`Failed to create a captcha for the provider "${config.CAPTCHA_PROVIDER}".`);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './CaptchaFactory.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './CaptchaFactory.js';
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import type { TypeBaseConfig } from '../Type/index.js';
|
2
|
+
/**
|
3
|
+
* Gets the captcha form element for the provided configuration.
|
4
|
+
*
|
5
|
+
* @param {TypeBaseConfig} config - The configuration object for the captcha provider.
|
6
|
+
* @returns {Promise<React.FC>} - The captcha form element.
|
7
|
+
*/
|
8
|
+
export declare const getCaptchaFormElement: (config: TypeBaseConfig) => Promise<React.FC>;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { CaptchaFactory } from '../Factory/index.js';
|
2
|
+
/**
|
3
|
+
* Gets the captcha form element for the provided configuration.
|
4
|
+
*
|
5
|
+
* @param {TypeBaseConfig} config - The configuration object for the captcha provider.
|
6
|
+
* @returns {Promise<React.FC>} - The captcha form element.
|
7
|
+
*/
|
8
|
+
export const getCaptchaFormElement = async (config) => (await (new CaptchaFactory()).create(config)).getCaptchaFormElement();
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import type { TypeBaseConfig } from '../Type/index.js';
|
2
|
+
/**
|
3
|
+
* Gets the captcha script for the provided configuration.
|
4
|
+
*
|
5
|
+
* @param {TypeBaseConfig} config - The configuration object for the captcha provider.
|
6
|
+
* @returns {Promise<React.FC>} - The captcha script.
|
7
|
+
*/
|
8
|
+
export declare const getCaptchaScript: (config: TypeBaseConfig) => Promise<React.FC>;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { CaptchaFactory } from '../Factory/index.js';
|
2
|
+
/**
|
3
|
+
* Gets the captcha script for the provided configuration.
|
4
|
+
*
|
5
|
+
* @param {TypeBaseConfig} config - The configuration object for the captcha provider.
|
6
|
+
* @returns {Promise<React.FC>} - The captcha script.
|
7
|
+
*/
|
8
|
+
export const getCaptchaScript = async (config) => (await (new CaptchaFactory()).create(config)).getCaptchaScript();
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import type { TypeBaseConfig } from '../Type/index.js';
|
2
|
+
/**
|
3
|
+
* Verifies the captcha response.
|
4
|
+
*
|
5
|
+
* @param {Record<string, any>} formFieldValues - The form field values to verify.
|
6
|
+
* @param {TypeBaseConfig} config - The configuration object for the captcha provider.
|
7
|
+
* @returns {Promise<boolean>} - Returns true if the captcha is verified.
|
8
|
+
*/
|
9
|
+
export declare const verifyCaptcha: (formFieldValues: Record<string, any>, config: TypeBaseConfig) => Promise<boolean>;
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { CaptchaFactory } from '../Factory/index.js';
|
2
|
+
/**
|
3
|
+
* Verifies the captcha response.
|
4
|
+
*
|
5
|
+
* @param {Record<string, any>} formFieldValues - The form field values to verify.
|
6
|
+
* @param {TypeBaseConfig} config - The configuration object for the captcha provider.
|
7
|
+
* @returns {Promise<boolean>} - Returns true if the captcha is verified.
|
8
|
+
*/
|
9
|
+
export const verifyCaptcha = async (formFieldValues, config) => (await (new CaptchaFactory()).create(config)).verifyCaptcha(formFieldValues);
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import type { TypeBaseConfig } from '../Type/Types.js';
|
2
|
+
import type { CaptchaInterface } from './CaptchaInterface.js';
|
3
|
+
/**
|
4
|
+
* Interface representing an captcha provider factory.
|
5
|
+
*/
|
6
|
+
export interface CaptchaFactoryInterface<TypeConfig extends TypeBaseConfig = TypeBaseConfig> {
|
7
|
+
/**
|
8
|
+
* Creates an captcha based on the provided configuration.
|
9
|
+
*
|
10
|
+
* @param {TypeConfig} config - The configuration object for the captcha provider.
|
11
|
+
* @returns {Promise<CaptchaInterface>} - An captcha instance.
|
12
|
+
* @throws {Error} - Throws an error when requested provider captcha can't be created.
|
13
|
+
*/
|
14
|
+
create(config: TypeConfig): Promise<CaptchaInterface>;
|
15
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,18 @@
|
|
1
|
+
export interface CaptchaInterface {
|
2
|
+
/**
|
3
|
+
* Verify captcha
|
4
|
+
* @param {Record<string, any>} formFieldValues - Form field values
|
5
|
+
* @returns {Promise<boolean>} - Returns true if captcha is verified
|
6
|
+
*/
|
7
|
+
verifyCaptcha(formFieldValues: Record<string, any>): Promise<boolean>;
|
8
|
+
/**
|
9
|
+
* Get captcha script
|
10
|
+
* @returns {React.FC} - Returns captcha script
|
11
|
+
*/
|
12
|
+
getCaptchaScript(): React.FC;
|
13
|
+
/**
|
14
|
+
* Get captcha form element
|
15
|
+
* @returns {React.FC} - Returns captcha form element
|
16
|
+
*/
|
17
|
+
getCaptchaFormElement(): React.FC;
|
18
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './Types.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './Types.js';
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/package.json
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
{
|
2
|
+
"name": "@captcha-kit/core",
|
3
|
+
"type": "module",
|
4
|
+
"version": "1.0.0",
|
5
|
+
"main": "dist/index.js",
|
6
|
+
"types": "dist/index.d.ts",
|
7
|
+
"devDependencies": {
|
8
|
+
"@dmitryrechkin/eslint-standard": "^1.0.7",
|
9
|
+
"fix-esm-import-path": "^1.0.1",
|
10
|
+
"dotenv": "^16.4.5",
|
11
|
+
"eslint": "^8.0.0",
|
12
|
+
"eslint-plugin-unused-imports": "^3.0.0",
|
13
|
+
"tsconfig-paths": "^4.2.0",
|
14
|
+
"typescript": "^5.5.3",
|
15
|
+
"vitest": "^0.24.5",
|
16
|
+
"shx": "^0.3.4",
|
17
|
+
"@types/react": "^18.0.0"
|
18
|
+
},
|
19
|
+
"dependencies": {
|
20
|
+
"react": "^18.3.1",
|
21
|
+
"react-dom": "^18.3.1"
|
22
|
+
},
|
23
|
+
"scripts": {
|
24
|
+
"lint": "eslint .",
|
25
|
+
"format": "eslint --fix .",
|
26
|
+
"test": "vitest run",
|
27
|
+
"check": "tsc --noEmit",
|
28
|
+
"build": "shx rm -rf dist && tsc && fix-esm-import-path dist",
|
29
|
+
"package:tgz": "pnpm pack",
|
30
|
+
"package:publish": "pnpm publish --access public"
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import type { CaptchaInterface } from '../Interface';
|
2
|
+
import type { CaptchaFactoryInterface } from '../Interface';
|
3
|
+
import type { TypeBaseConfig } from '../Type';
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Interface representing an captcha provider factory.
|
7
|
+
*/
|
8
|
+
export class CaptchaFactory implements CaptchaFactoryInterface<TypeBaseConfig>
|
9
|
+
{
|
10
|
+
/**
|
11
|
+
* Creates an captcha based on the provided configuration.
|
12
|
+
*
|
13
|
+
* @param {TypeConfig} config - The configuration object for the email provider.
|
14
|
+
* @returns {Promise<CaptchaInterface>} - An captcha instance.
|
15
|
+
* @throws {Error} - Throws an error when requested provider captcha can't be created.
|
16
|
+
*/
|
17
|
+
public async create(config: TypeBaseConfig): Promise<CaptchaInterface>
|
18
|
+
{
|
19
|
+
try
|
20
|
+
{
|
21
|
+
const providerName = config.CAPTCHA_PROVIDER ?? 'core';
|
22
|
+
const packageName = '@captcha/' + providerName;
|
23
|
+
|
24
|
+
// Dynamically import the package and access the default export
|
25
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
26
|
+
const ProviderModule = await import(packageName);
|
27
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
28
|
+
const Factory = ProviderModule.default;
|
29
|
+
|
30
|
+
// we need to check if Factory has the create method, required by the EmailProviderFactoryInterface
|
31
|
+
if (typeof Factory !== 'function' || !('create' in Factory.prototype))
|
32
|
+
{
|
33
|
+
throw new Error('The provider module does not implement the required interface.');
|
34
|
+
}
|
35
|
+
|
36
|
+
// Instantiate the factory and create the captcha
|
37
|
+
return new Factory().create(config as any);
|
38
|
+
}
|
39
|
+
catch (error)
|
40
|
+
{
|
41
|
+
throw new Error(`Failed to create a captcha for the provider "${config.CAPTCHA_PROVIDER}".`);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './CaptchaFactory';
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import type { TypeBaseConfig } from '../Type';
|
2
|
+
import { CaptchaFactory } from '../Factory';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Gets the captcha form element for the provided configuration.
|
6
|
+
*
|
7
|
+
* @param {TypeBaseConfig} config - The configuration object for the captcha provider.
|
8
|
+
* @returns {Promise<React.FC>} - The captcha form element.
|
9
|
+
*/
|
10
|
+
export const getCaptchaFormElement = async (config: TypeBaseConfig): Promise<React.FC> =>
|
11
|
+
(await (new CaptchaFactory()).create(config)).getCaptchaFormElement();
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import type { TypeBaseConfig } from '../Type';
|
2
|
+
import { CaptchaFactory } from '../Factory';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Gets the captcha script for the provided configuration.
|
6
|
+
*
|
7
|
+
* @param {TypeBaseConfig} config - The configuration object for the captcha provider.
|
8
|
+
* @returns {Promise<React.FC>} - The captcha script.
|
9
|
+
*/
|
10
|
+
export const getCaptchaScript = async (config: TypeBaseConfig): Promise<React.FC> =>
|
11
|
+
(await (new CaptchaFactory()).create(config)).getCaptchaScript();
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import type { TypeBaseConfig } from '../Type';
|
2
|
+
import { CaptchaFactory } from '../Factory';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Verifies the captcha response.
|
6
|
+
*
|
7
|
+
* @param {Record<string, any>} formFieldValues - The form field values to verify.
|
8
|
+
* @param {TypeBaseConfig} config - The configuration object for the captcha provider.
|
9
|
+
* @returns {Promise<boolean>} - Returns true if the captcha is verified.
|
10
|
+
*/
|
11
|
+
export const verifyCaptcha = async (formFieldValues: Record<string, any>, config: TypeBaseConfig): Promise<boolean> =>
|
12
|
+
(await (new CaptchaFactory()).create(config)).verifyCaptcha(formFieldValues);
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import type { TypeBaseConfig } from '../Type/Types';
|
2
|
+
import type { CaptchaInterface } from './CaptchaInterface';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Interface representing an captcha provider factory.
|
6
|
+
*/
|
7
|
+
export interface CaptchaFactoryInterface<TypeConfig extends TypeBaseConfig = TypeBaseConfig>
|
8
|
+
{
|
9
|
+
/**
|
10
|
+
* Creates an captcha based on the provided configuration.
|
11
|
+
*
|
12
|
+
* @param {TypeConfig} config - The configuration object for the captcha provider.
|
13
|
+
* @returns {Promise<CaptchaInterface>} - An captcha instance.
|
14
|
+
* @throws {Error} - Throws an error when requested provider captcha can't be created.
|
15
|
+
*/
|
16
|
+
create(config: TypeConfig): Promise<CaptchaInterface>;
|
17
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
export interface CaptchaInterface
|
2
|
+
{
|
3
|
+
/**
|
4
|
+
* Verify captcha
|
5
|
+
* @param {Record<string, any>} formFieldValues - Form field values
|
6
|
+
* @returns {Promise<boolean>} - Returns true if captcha is verified
|
7
|
+
*/
|
8
|
+
verifyCaptcha(formFieldValues: Record<string, any>): Promise<boolean>;
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Get captcha script
|
12
|
+
* @returns {React.FC} - Returns captcha script
|
13
|
+
*/
|
14
|
+
getCaptchaScript(): React.FC;
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Get captcha form element
|
18
|
+
* @returns {React.FC} - Returns captcha form element
|
19
|
+
*/
|
20
|
+
getCaptchaFormElement(): React.FC;
|
21
|
+
}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
// Base configuration for all configuration types, the expectation is that each provider will have its own configuration type that extends this.
|
2
|
+
export interface TypeBaseConfig
|
3
|
+
{
|
4
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
5
|
+
CAPTCHA_PROVIDER: string;
|
6
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './Types';
|
package/src/index.tsx
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
2
|
+
import { getCaptchaFormElement } from '../src/Function/getCaptchaFormElement';
|
3
|
+
import type { TypeBaseConfig } from '../src/Type/Types';
|
4
|
+
import React from 'react';
|
5
|
+
|
6
|
+
vi.mock('../src/Factory', () => {
|
7
|
+
return {
|
8
|
+
CaptchaFactory: vi.fn().mockImplementation(() => {
|
9
|
+
return {
|
10
|
+
create: vi.fn().mockResolvedValue({
|
11
|
+
getCaptchaFormElement: () => () => <form>Mocked Form</form>
|
12
|
+
})
|
13
|
+
};
|
14
|
+
})
|
15
|
+
};
|
16
|
+
});
|
17
|
+
|
18
|
+
describe('getCaptchaFormElement', () => {
|
19
|
+
it('should return a React component for the captcha form element', async () => {
|
20
|
+
const config: TypeBaseConfig = { CAPTCHA_PROVIDER: 'test-provider' };
|
21
|
+
const formElement = await getCaptchaFormElement(config);
|
22
|
+
expect(formElement).toBeDefined();
|
23
|
+
expect(typeof formElement).toBe('function'); // Check if it's a React component
|
24
|
+
});
|
25
|
+
});
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
2
|
+
import { getCaptchaScript } from '../src/Function/getCaptchaScript';
|
3
|
+
import type { TypeBaseConfig } from '../src/Type/Types';
|
4
|
+
import React from 'react';
|
5
|
+
|
6
|
+
vi.mock('../src/Factory', () => {
|
7
|
+
return {
|
8
|
+
CaptchaFactory: vi.fn().mockImplementation(() => {
|
9
|
+
return {
|
10
|
+
create: vi.fn().mockResolvedValue({
|
11
|
+
getCaptchaScript: () => () => <div>Mocked Script</div>
|
12
|
+
})
|
13
|
+
};
|
14
|
+
})
|
15
|
+
};
|
16
|
+
});
|
17
|
+
|
18
|
+
describe('getCaptchaScript', () => {
|
19
|
+
it('should return a React component for the captcha script', async () => {
|
20
|
+
const config: TypeBaseConfig = { CAPTCHA_PROVIDER: 'test-provider' };
|
21
|
+
const scriptComponent = await getCaptchaScript(config);
|
22
|
+
expect(scriptComponent).toBeDefined();
|
23
|
+
expect(typeof scriptComponent).toBe('function'); // Check if it's a React component
|
24
|
+
});
|
25
|
+
});
|