@linkforty/mobile-sdk-react-native 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +136 -0
- package/CONTRIBUTING.md +340 -0
- package/LICENSE +21 -0
- package/README.md +410 -0
- package/dist/DeepLinkHandler.d.ts +25 -0
- package/dist/DeepLinkHandler.d.ts.map +1 -0
- package/dist/DeepLinkHandler.js +81 -0
- package/dist/FingerprintCollector.d.ts +23 -0
- package/dist/FingerprintCollector.d.ts.map +1 -0
- package/dist/FingerprintCollector.js +79 -0
- package/dist/LinkFortySDK.d.ts +58 -0
- package/dist/LinkFortySDK.d.ts.map +1 -0
- package/dist/LinkFortySDK.js +258 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/types.d.ts +106 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/examples/AdvancedHooks.tsx +230 -0
- package/examples/BasicSetup.tsx +100 -0
- package/examples/EcommerceTracking.tsx +142 -0
- package/examples/README.md +318 -0
- package/examples/SelfHostedSetup.tsx +126 -0
- package/package.json +68 -0
- package/src/DeepLinkHandler.ts +96 -0
- package/src/FingerprintCollector.ts +90 -0
- package/src/LinkFortySDK.ts +320 -0
- package/src/index.ts +26 -0
- package/src/types.ts +112 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the LinkForty React Native SDK will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2024-11-22
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release of LinkForty React Native SDK
|
|
12
|
+
- **Deferred Deep Linking** - Route new users to specific content after install
|
|
13
|
+
- **Direct Deep Linking** - Handle Universal Links (iOS) and App Links (Android)
|
|
14
|
+
- **Probabilistic Attribution** - Match installs to clicks with 70%+ confidence
|
|
15
|
+
- **Event Tracking** - Track in-app events with attribution
|
|
16
|
+
- **Privacy-Focused** - No persistent device IDs required
|
|
17
|
+
- **TypeScript Support** - Full type definitions included
|
|
18
|
+
- **Works with Core & Cloud** - Compatible with self-hosted and Cloud instances
|
|
19
|
+
|
|
20
|
+
### Core Features
|
|
21
|
+
|
|
22
|
+
#### SDK Initialization
|
|
23
|
+
- `init(config)` - Initialize SDK with base URL and optional API key
|
|
24
|
+
- Support for debug logging during development
|
|
25
|
+
- Customizable attribution window (default: 7 days)
|
|
26
|
+
|
|
27
|
+
#### Deep Linking
|
|
28
|
+
- `onDeferredDeepLink(callback)` - Handle deferred deep links for new installs
|
|
29
|
+
- `onDeepLink(callback)` - Handle direct deep links for existing users
|
|
30
|
+
- Automatic Universal Links (iOS) and App Links (Android) configuration
|
|
31
|
+
- Deep link data includes UTM parameters and custom parameters
|
|
32
|
+
|
|
33
|
+
#### Event Tracking
|
|
34
|
+
- `trackEvent(name, properties)` - Track in-app events with optional properties
|
|
35
|
+
- Automatic attribution to install source
|
|
36
|
+
- Webhook triggers for conversion events
|
|
37
|
+
- Support for revenue tracking and custom event properties
|
|
38
|
+
|
|
39
|
+
#### Data Management
|
|
40
|
+
- `getInstallData()` - Retrieve cached install attribution data
|
|
41
|
+
- `getInstallId()` - Get unique install ID for this app installation
|
|
42
|
+
- `clearData()` - Clear all cached SDK data (useful for testing)
|
|
43
|
+
|
|
44
|
+
### Device Fingerprinting
|
|
45
|
+
|
|
46
|
+
Collects the following non-invasive signals for probabilistic attribution:
|
|
47
|
+
- User agent string
|
|
48
|
+
- Device timezone
|
|
49
|
+
- Device language
|
|
50
|
+
- Screen resolution
|
|
51
|
+
- Platform (iOS/Android)
|
|
52
|
+
- Device model and OS version
|
|
53
|
+
- IP address (server-side only)
|
|
54
|
+
|
|
55
|
+
### API Endpoints
|
|
56
|
+
|
|
57
|
+
Uses the following LinkForty Core API endpoints:
|
|
58
|
+
- `POST /api/sdk/v1/install` - Report app installation
|
|
59
|
+
- `POST /api/sdk/v1/event` - Track in-app events
|
|
60
|
+
- `GET /api/sdk/v1/attribution/:fingerprint` - Debug attribution data
|
|
61
|
+
- `GET /api/sdk/v1/health` - Health check
|
|
62
|
+
|
|
63
|
+
### Dependencies
|
|
64
|
+
|
|
65
|
+
**Peer Dependencies:**
|
|
66
|
+
- `react` >= 16.8.0
|
|
67
|
+
- `react-native` >= 0.60.0
|
|
68
|
+
|
|
69
|
+
**Runtime Dependencies:**
|
|
70
|
+
- `@react-native-async-storage/async-storage` ^1.21.0
|
|
71
|
+
- `react-native-device-info` ^10.12.0
|
|
72
|
+
|
|
73
|
+
### Platform Support
|
|
74
|
+
|
|
75
|
+
- ✅ iOS 12+
|
|
76
|
+
- ✅ Android 5.0+ (API level 21+)
|
|
77
|
+
- ✅ React Native 0.60+
|
|
78
|
+
- ✅ TypeScript 5.3+
|
|
79
|
+
- ✅ Expo (with custom native modules)
|
|
80
|
+
|
|
81
|
+
### Security
|
|
82
|
+
|
|
83
|
+
- No persistent device identifiers stored
|
|
84
|
+
- Privacy-focused fingerprinting
|
|
85
|
+
- Configurable attribution window
|
|
86
|
+
- Secure HTTPS-only communication
|
|
87
|
+
- No third-party tracking SDKs
|
|
88
|
+
|
|
89
|
+
### Documentation
|
|
90
|
+
|
|
91
|
+
- Comprehensive README with setup instructions
|
|
92
|
+
- TypeScript type definitions included
|
|
93
|
+
- iOS Universal Links setup guide
|
|
94
|
+
- Android App Links setup guide
|
|
95
|
+
- Troubleshooting guide
|
|
96
|
+
- API reference with examples
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## [Unreleased]
|
|
101
|
+
|
|
102
|
+
### Changed
|
|
103
|
+
- Removed unused dependencies `@onamfc/developer-log` and `@onamfc/pkg-inspect` to reduce bundle size
|
|
104
|
+
|
|
105
|
+
### Planned Features
|
|
106
|
+
- iOS SDK (Native Swift) - Q2 2025
|
|
107
|
+
- Android SDK (Native Kotlin) - Q2 2025
|
|
108
|
+
- React Native Expo compatibility mode
|
|
109
|
+
- Offline event queue for poor network conditions
|
|
110
|
+
- Advanced debugging tools
|
|
111
|
+
- Custom domain support
|
|
112
|
+
- A/B testing integration
|
|
113
|
+
- User segmentation
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Version History
|
|
118
|
+
|
|
119
|
+
- **1.0.0** - Initial release (2024-11-22)
|
|
120
|
+
|
|
121
|
+
## Migration Guides
|
|
122
|
+
|
|
123
|
+
### Upgrading to 1.0.0
|
|
124
|
+
|
|
125
|
+
This is the initial release, so no migration is necessary.
|
|
126
|
+
|
|
127
|
+
## Support
|
|
128
|
+
|
|
129
|
+
For issues, questions, or feature requests:
|
|
130
|
+
- GitHub Issues: https://github.com/linkforty/react-native-sdk/issues
|
|
131
|
+
- Documentation: https://docs.linkforty.com
|
|
132
|
+
- Discord Community: https://discord.gg/linkforty
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# Contributing to LinkForty React Native SDK
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to the LinkForty React Native SDK! We welcome contributions from the community and are grateful for your support.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Code of Conduct](#code-of-conduct)
|
|
8
|
+
- [Getting Started](#getting-started)
|
|
9
|
+
- [Development Setup](#development-setup)
|
|
10
|
+
- [How to Contribute](#how-to-contribute)
|
|
11
|
+
- [Pull Request Process](#pull-request-process)
|
|
12
|
+
- [Coding Standards](#coding-standards)
|
|
13
|
+
- [Testing Guidelines](#testing-guidelines)
|
|
14
|
+
- [Reporting Bugs](#reporting-bugs)
|
|
15
|
+
- [Feature Requests](#feature-requests)
|
|
16
|
+
|
|
17
|
+
## Code of Conduct
|
|
18
|
+
|
|
19
|
+
This project and everyone participating in it is governed by our commitment to creating a welcoming and inclusive environment. Please be respectful and constructive in your interactions.
|
|
20
|
+
|
|
21
|
+
## Getting Started
|
|
22
|
+
|
|
23
|
+
1. **Fork the repository** on GitHub
|
|
24
|
+
2. **Clone your fork** locally
|
|
25
|
+
3. **Create a branch** for your changes
|
|
26
|
+
4. **Make your changes**
|
|
27
|
+
5. **Test your changes** thoroughly
|
|
28
|
+
6. **Submit a pull request**
|
|
29
|
+
|
|
30
|
+
## Development Setup
|
|
31
|
+
|
|
32
|
+
### Prerequisites
|
|
33
|
+
|
|
34
|
+
- Node.js 20+ and npm 10+
|
|
35
|
+
- React Native development environment (iOS and/or Android)
|
|
36
|
+
- React Native 0.76+
|
|
37
|
+
- TypeScript 5.9+
|
|
38
|
+
- Git
|
|
39
|
+
|
|
40
|
+
### Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Clone your fork
|
|
44
|
+
git clone https://github.com/linkforty/react-native-sdk.git
|
|
45
|
+
cd react-native-sdk
|
|
46
|
+
|
|
47
|
+
# Install dependencies
|
|
48
|
+
npm install
|
|
49
|
+
|
|
50
|
+
# Build the TypeScript code
|
|
51
|
+
npm run build
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Project Structure
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
linkforty-react-native-sdk/
|
|
58
|
+
├── src/
|
|
59
|
+
│ ├── index.ts # Main export file
|
|
60
|
+
│ ├── LinkFortySDK.ts # Core SDK class
|
|
61
|
+
│ ├── DeepLinkHandler.ts # Deep link handling
|
|
62
|
+
│ ├── FingerprintCollector.ts # Device fingerprinting
|
|
63
|
+
│ └── types.ts # TypeScript type definitions
|
|
64
|
+
├── dist/ # Compiled JavaScript (generated)
|
|
65
|
+
├── package.json
|
|
66
|
+
├── tsconfig.json
|
|
67
|
+
├── README.md
|
|
68
|
+
├── CHANGELOG.md
|
|
69
|
+
├── CONTRIBUTING.md
|
|
70
|
+
└── LICENSE
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Building
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Build TypeScript to JavaScript
|
|
77
|
+
npm run build
|
|
78
|
+
|
|
79
|
+
# Watch mode for development
|
|
80
|
+
npm run build -- --watch
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## How to Contribute
|
|
84
|
+
|
|
85
|
+
### Types of Contributions
|
|
86
|
+
|
|
87
|
+
We welcome many types of contributions:
|
|
88
|
+
|
|
89
|
+
- **Bug fixes**
|
|
90
|
+
- **New features**
|
|
91
|
+
- **Documentation improvements**
|
|
92
|
+
- **Code quality improvements**
|
|
93
|
+
- **Test coverage additions**
|
|
94
|
+
- **Platform compatibility fixes**
|
|
95
|
+
- **Examples and tutorials**
|
|
96
|
+
|
|
97
|
+
### Before You Start
|
|
98
|
+
|
|
99
|
+
1. **Check existing issues** to see if someone is already working on it
|
|
100
|
+
2. **Open an issue** to discuss major changes before implementing
|
|
101
|
+
3. **Keep pull requests focused** - one feature/fix per PR
|
|
102
|
+
4. **Follow the coding standards** outlined below
|
|
103
|
+
|
|
104
|
+
## Pull Request Process
|
|
105
|
+
|
|
106
|
+
### 1. Create a Feature Branch
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
git checkout -b feature/my-new-feature
|
|
110
|
+
# or
|
|
111
|
+
git checkout -b fix/bug-description
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 2. Make Your Changes
|
|
115
|
+
|
|
116
|
+
- Write clear, concise commit messages
|
|
117
|
+
- Follow the existing code style
|
|
118
|
+
- Add/update tests if applicable
|
|
119
|
+
- Update documentation as needed
|
|
120
|
+
|
|
121
|
+
### 3. Test Your Changes
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Build the SDK
|
|
125
|
+
npm run build
|
|
126
|
+
|
|
127
|
+
# Test in a sample React Native app
|
|
128
|
+
cd ../sample-app
|
|
129
|
+
npm install ../linkforty-react-native-sdk
|
|
130
|
+
|
|
131
|
+
# Test on both iOS and Android if possible
|
|
132
|
+
npx react-native run-ios
|
|
133
|
+
npx react-native run-android
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
### 4. Commit Your Changes
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
git add .
|
|
141
|
+
git commit -m "feat: add custom attribution window support"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Commit Message Format:**
|
|
145
|
+
- `feat:` New feature
|
|
146
|
+
- `fix:` Bug fix
|
|
147
|
+
- `docs:` Documentation changes
|
|
148
|
+
- `style:` Code style changes (formatting, etc.)
|
|
149
|
+
- `refactor:` Code refactoring
|
|
150
|
+
- `test:` Adding or updating tests
|
|
151
|
+
- `chore:` Maintenance tasks
|
|
152
|
+
|
|
153
|
+
### 5. Push and Create PR
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
git push origin feature/my-new-feature
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Then open a Pull Request on GitHub with:
|
|
160
|
+
- Clear title describing the change
|
|
161
|
+
- Description of what changed and why
|
|
162
|
+
- Link to any related issues
|
|
163
|
+
- Screenshots/videos if UI-related
|
|
164
|
+
- Testing instructions
|
|
165
|
+
|
|
166
|
+
## Coding Standards
|
|
167
|
+
|
|
168
|
+
### TypeScript
|
|
169
|
+
|
|
170
|
+
- Use TypeScript for all new code
|
|
171
|
+
- Provide type definitions for all public APIs
|
|
172
|
+
- Avoid `any` types when possible
|
|
173
|
+
- Use interfaces for public types
|
|
174
|
+
- Export all public types from `types.ts`
|
|
175
|
+
|
|
176
|
+
### Code Style
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// ✅ Good
|
|
180
|
+
export async function trackEvent(
|
|
181
|
+
name: string,
|
|
182
|
+
properties?: Record<string, any>
|
|
183
|
+
): Promise<void> {
|
|
184
|
+
if (!this.config) {
|
|
185
|
+
throw new Error('SDK not initialized. Call init() first.');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Implementation...
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ❌ Avoid
|
|
192
|
+
export async function trackEvent(name,properties) {
|
|
193
|
+
if(!this.config) throw new Error('SDK not initialized. Call init() first.');
|
|
194
|
+
// Implementation...
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Best Practices
|
|
199
|
+
|
|
200
|
+
- **Error Handling**: Always handle errors gracefully
|
|
201
|
+
- **Logging**: Use debug mode for verbose logging
|
|
202
|
+
- **Privacy**: Never log sensitive user data
|
|
203
|
+
- **Performance**: Minimize network requests and storage operations
|
|
204
|
+
- **Compatibility**: Support React Native 0.60+
|
|
205
|
+
- **Platform-Specific**: Use Platform.select() when needed
|
|
206
|
+
|
|
207
|
+
### Documentation
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
/**
|
|
211
|
+
* Track an in-app event with optional properties
|
|
212
|
+
*
|
|
213
|
+
* @param name - Event name (e.g., 'purchase', 'signup')
|
|
214
|
+
* @param properties - Optional event properties
|
|
215
|
+
* @returns Promise that resolves when event is tracked
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```typescript
|
|
219
|
+
* await LinkForty.trackEvent('purchase', {
|
|
220
|
+
* amount: 99.99,
|
|
221
|
+
* currency: 'USD',
|
|
222
|
+
* productId: 'premium_plan'
|
|
223
|
+
* });
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
async trackEvent(
|
|
227
|
+
name: string,
|
|
228
|
+
properties?: Record<string, any>
|
|
229
|
+
): Promise<void>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Testing Guidelines
|
|
233
|
+
|
|
234
|
+
### Manual Testing Checklist
|
|
235
|
+
|
|
236
|
+
Before submitting a PR, test the following:
|
|
237
|
+
|
|
238
|
+
**iOS:**
|
|
239
|
+
- [ ] Universal Links work correctly
|
|
240
|
+
- [ ] Deferred deep links attribute on first install
|
|
241
|
+
- [ ] Direct deep links open the app
|
|
242
|
+
- [ ] Event tracking works
|
|
243
|
+
- [ ] No crashes or errors in debug mode
|
|
244
|
+
|
|
245
|
+
**Android:**
|
|
246
|
+
- [ ] App Links work correctly
|
|
247
|
+
- [ ] Deferred deep links attribute on first install
|
|
248
|
+
- [ ] Direct deep links open the app
|
|
249
|
+
- [ ] Event tracking works
|
|
250
|
+
- [ ] No crashes or errors in debug mode
|
|
251
|
+
|
|
252
|
+
**Both Platforms:**
|
|
253
|
+
- [ ] TypeScript types are correct
|
|
254
|
+
- [ ] Documentation is accurate
|
|
255
|
+
- [ ] No breaking API changes (or documented)
|
|
256
|
+
- [ ] Performance is acceptable
|
|
257
|
+
- [ ] Privacy requirements met
|
|
258
|
+
|
|
259
|
+
### Test Scenarios
|
|
260
|
+
|
|
261
|
+
1. **Fresh Install Attribution**
|
|
262
|
+
- Click a link in mobile browser
|
|
263
|
+
- Install app from store
|
|
264
|
+
- Verify `onDeferredDeepLink` receives attribution data
|
|
265
|
+
|
|
266
|
+
2. **Direct Deep Link**
|
|
267
|
+
- App is already installed
|
|
268
|
+
- Click a link in mobile browser
|
|
269
|
+
- Verify `onDeepLink` is called with correct data
|
|
270
|
+
|
|
271
|
+
3. **Event Tracking**
|
|
272
|
+
- Track various events
|
|
273
|
+
- Verify events appear in backend
|
|
274
|
+
- Verify webhooks are triggered (if configured)
|
|
275
|
+
|
|
276
|
+
4. **Edge Cases**
|
|
277
|
+
- No internet connection
|
|
278
|
+
- Invalid deep link URLs
|
|
279
|
+
- Backend server errors
|
|
280
|
+
- Concurrent SDK calls
|
|
281
|
+
|
|
282
|
+
## Reporting Bugs
|
|
283
|
+
|
|
284
|
+
### Before Reporting
|
|
285
|
+
|
|
286
|
+
1. **Check existing issues** to avoid duplicates
|
|
287
|
+
2. **Update to latest version** to see if it's already fixed
|
|
288
|
+
3. **Test in a fresh React Native project** to isolate the issue
|
|
289
|
+
|
|
290
|
+
### Bug Report Template
|
|
291
|
+
|
|
292
|
+
```markdown
|
|
293
|
+
**Describe the bug**
|
|
294
|
+
A clear description of what the bug is.
|
|
295
|
+
|
|
296
|
+
**To Reproduce**
|
|
297
|
+
Steps to reproduce the behavior:
|
|
298
|
+
1. Initialize SDK with '...'
|
|
299
|
+
2. Call method '...'
|
|
300
|
+
3. See error
|
|
301
|
+
|
|
302
|
+
**Expected behavior**
|
|
303
|
+
What you expected to happen.
|
|
304
|
+
|
|
305
|
+
**Actual behavior**
|
|
306
|
+
What actually happened.
|
|
307
|
+
|
|
308
|
+
**Environment:**
|
|
309
|
+
- OS: [e.g., iOS 17.0, Android 14]
|
|
310
|
+
- React Native version: [e.g., 0.72.0]
|
|
311
|
+
- SDK version: [e.g., 1.0.0]
|
|
312
|
+
- Device: [e.g., iPhone 14 Pro, Pixel 7]
|
|
313
|
+
|
|
314
|
+
**Logs**
|
|
315
|
+
```typescript
|
|
316
|
+
// Relevant error logs or stack traces
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Additional context**
|
|
320
|
+
Any other context about the problem.
|
|
321
|
+
|
|
322
|
+
## Feature Requests
|
|
323
|
+
|
|
324
|
+
We love feature requests! Please include:
|
|
325
|
+
|
|
326
|
+
1. **Use case** - Why do you need this feature?
|
|
327
|
+
2. **Proposed solution** - How do you think it should work?
|
|
328
|
+
3. **Alternatives** - What alternatives have you considered?
|
|
329
|
+
4. **Platform** - Is this iOS-specific, Android-specific, or both?
|
|
330
|
+
|
|
331
|
+
## Questions?
|
|
332
|
+
|
|
333
|
+
- **GitHub Issues**: For bugs and feature requests
|
|
334
|
+
|
|
335
|
+
## License
|
|
336
|
+
|
|
337
|
+
By contributing to LinkForty React Native SDK, you agree that your contributions will be licensed under the MIT License.
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
Thank you for making LinkForty better! 🎉
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 LinkForty
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|