320 lines
7.0 KiB
Markdown
320 lines
7.0 KiB
Markdown
# IronLicensing SDK for JavaScript/TypeScript
|
|
|
|
Software licensing and activation SDK for JavaScript/TypeScript applications. Validate licenses, manage activations, check features, and handle trials.
|
|
|
|
[](https://www.npmjs.com/package/@ironservices/licensing)
|
|
[](https://opensource.org/licenses/MIT)
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install @ironservices/licensing
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### Validate a License
|
|
|
|
```typescript
|
|
import { LicenseClient } from '@ironservices/licensing';
|
|
|
|
const client = new LicenseClient({
|
|
publicKey: 'pk_live_xxxxx',
|
|
productSlug: 'my-app',
|
|
});
|
|
|
|
// Validate a license key
|
|
const result = await client.validate('IRON-XXXX-XXXX-XXXX-XXXX');
|
|
|
|
if (result.valid) {
|
|
console.log('License is valid!');
|
|
console.log('Expires:', result.license?.expiresAt);
|
|
}
|
|
```
|
|
|
|
### Activate a License
|
|
|
|
```typescript
|
|
import { LicenseClient } from '@ironservices/licensing';
|
|
|
|
const client = new LicenseClient({
|
|
publicKey: 'pk_live_xxxxx',
|
|
productSlug: 'my-app',
|
|
});
|
|
|
|
// Activate on this machine
|
|
const result = await client.activate('IRON-XXXX-XXXX-XXXX-XXXX');
|
|
|
|
if (result.valid) {
|
|
console.log('License activated!');
|
|
console.log('Activations:', result.activations?.length);
|
|
}
|
|
```
|
|
|
|
### Check Features
|
|
|
|
```typescript
|
|
import { LicenseClient, LicenseRequiredError } from '@ironservices/licensing';
|
|
|
|
const client = new LicenseClient({
|
|
publicKey: 'pk_live_xxxxx',
|
|
productSlug: 'my-app',
|
|
});
|
|
|
|
await client.validate('IRON-XXXX-XXXX-XXXX-XXXX');
|
|
|
|
// Check if feature is enabled
|
|
if (client.hasFeature('premium')) {
|
|
// Enable premium features
|
|
}
|
|
|
|
// Or require a feature (throws if not available)
|
|
try {
|
|
client.requireFeature('enterprise');
|
|
// Enterprise code here
|
|
} catch (e) {
|
|
if (e instanceof LicenseRequiredError) {
|
|
console.log('Enterprise license required');
|
|
}
|
|
}
|
|
```
|
|
|
|
### Using the Global Client
|
|
|
|
```typescript
|
|
import * as licensing from '@ironservices/licensing';
|
|
|
|
// Initialize once
|
|
licensing.init({
|
|
publicKey: 'pk_live_xxxxx',
|
|
productSlug: 'my-app',
|
|
});
|
|
|
|
// Use anywhere
|
|
await licensing.validate('IRON-XXXX-XXXX-XXXX-XXXX');
|
|
|
|
if (licensing.hasFeature('premium')) {
|
|
// Premium features
|
|
}
|
|
|
|
console.log('Status:', licensing.getStatus());
|
|
console.log('Licensed:', licensing.isLicensed());
|
|
```
|
|
|
|
## Configuration
|
|
|
|
```typescript
|
|
import { LicenseClient } from '@ironservices/licensing';
|
|
|
|
const client = new LicenseClient({
|
|
publicKey: 'pk_live_xxxxx', // Required
|
|
productSlug: 'my-app', // Required
|
|
apiBaseUrl: 'https://api.ironlicensing.com',
|
|
debug: false,
|
|
enableOfflineCache: true,
|
|
cacheValidationMinutes: 60,
|
|
offlineGraceDays: 7,
|
|
storageKeyPrefix: 'ironlicensing',
|
|
});
|
|
```
|
|
|
|
### Configuration Options
|
|
|
|
| Option | Type | Default | Description |
|
|
|--------|------|---------|-------------|
|
|
| `publicKey` | string | required | Your public key (pk_live_xxx or pk_test_xxx) |
|
|
| `productSlug` | string | required | Your product slug |
|
|
| `apiBaseUrl` | string | https://api.ironlicensing.com | API base URL |
|
|
| `debug` | boolean | false | Enable debug logging |
|
|
| `enableOfflineCache` | boolean | true | Cache validation results |
|
|
| `cacheValidationMinutes` | number | 60 | Cache validity in minutes |
|
|
| `offlineGraceDays` | number | 7 | Offline grace period in days |
|
|
| `storageKeyPrefix` | string | 'ironlicensing' | Storage key prefix |
|
|
|
|
## License Status
|
|
|
|
```typescript
|
|
type LicenseStatus =
|
|
| 'valid' // License is valid
|
|
| 'expired' // License has expired
|
|
| 'suspended' // License is suspended
|
|
| 'revoked' // License is revoked
|
|
| 'invalid' // License key is invalid
|
|
| 'trial' // Trial license
|
|
| 'trial_expired' // Trial has expired
|
|
| 'not_activated' // No license activated
|
|
| 'unknown'; // Unknown status
|
|
```
|
|
|
|
## Features
|
|
|
|
### Check Features
|
|
|
|
```typescript
|
|
// Check if feature is enabled
|
|
if (client.hasFeature('premium')) {
|
|
enablePremiumFeatures();
|
|
}
|
|
|
|
// Get feature details
|
|
const feature = client.getFeature('max-users');
|
|
if (feature?.enabled) {
|
|
console.log('Max users:', feature.metadata?.limit);
|
|
}
|
|
|
|
// Get all features
|
|
const features = client.getFeatures();
|
|
features.forEach(f => {
|
|
console.log(`${f.name}: ${f.enabled ? 'enabled' : 'disabled'}`);
|
|
});
|
|
```
|
|
|
|
### Require Features
|
|
|
|
```typescript
|
|
import { LicenseRequiredError } from '@ironservices/licensing';
|
|
|
|
try {
|
|
client.requireFeature('enterprise');
|
|
// This code only runs if feature is available
|
|
} catch (e) {
|
|
if (e instanceof LicenseRequiredError) {
|
|
showUpgradeDialog();
|
|
}
|
|
}
|
|
```
|
|
|
|
## Trial Management
|
|
|
|
```typescript
|
|
// Start a trial
|
|
const result = await client.startTrial('user@example.com');
|
|
|
|
if (result.valid) {
|
|
console.log('Trial started!');
|
|
console.log('Expires:', result.license?.expiresAt);
|
|
}
|
|
|
|
// Check if trial
|
|
if (client.isTrial) {
|
|
showTrialBanner(client.expiresAt);
|
|
}
|
|
```
|
|
|
|
## Purchase Flow
|
|
|
|
```typescript
|
|
// Get available tiers
|
|
const tiers = await client.getTiers();
|
|
|
|
tiers.forEach(tier => {
|
|
console.log(`${tier.name}: ${tier.price} ${tier.currency}/${tier.billingPeriod}`);
|
|
});
|
|
|
|
// Start checkout
|
|
const checkout = await client.startPurchase('tier-pro', 'user@example.com');
|
|
|
|
if (checkout.success) {
|
|
// Redirect to checkout URL
|
|
window.location.href = checkout.checkoutUrl!;
|
|
}
|
|
```
|
|
|
|
## Deactivation
|
|
|
|
```typescript
|
|
// Deactivate on this machine
|
|
const success = await client.deactivate();
|
|
|
|
if (success) {
|
|
console.log('License deactivated');
|
|
}
|
|
```
|
|
|
|
## License Change Events
|
|
|
|
```typescript
|
|
// Listen for license changes
|
|
const unsubscribe = client.onLicenseChange((license) => {
|
|
if (license) {
|
|
console.log('License updated:', license.status);
|
|
} else {
|
|
console.log('License removed');
|
|
}
|
|
});
|
|
|
|
// Later: unsubscribe
|
|
unsubscribe();
|
|
```
|
|
|
|
## Offline Support
|
|
|
|
The SDK automatically caches validation results and supports offline usage:
|
|
|
|
```typescript
|
|
const client = new LicenseClient({
|
|
publicKey: 'pk_live_xxxxx',
|
|
productSlug: 'my-app',
|
|
enableOfflineCache: true,
|
|
cacheValidationMinutes: 60, // Use cache for 60 minutes
|
|
offlineGraceDays: 7, // Allow 7 days offline
|
|
});
|
|
|
|
// This will use cache if available
|
|
const result = await client.validate();
|
|
|
|
if (result.cached) {
|
|
console.log('Using cached validation');
|
|
}
|
|
```
|
|
|
|
## Custom Storage
|
|
|
|
```typescript
|
|
import { LicenseClient, StorageAdapter, LicenseCache } from '@ironservices/licensing';
|
|
|
|
// Implement custom storage
|
|
class MyStorage implements StorageAdapter {
|
|
get(key: string): string | null {
|
|
return myDatabase.get(key);
|
|
}
|
|
|
|
set(key: string, value: string): void {
|
|
myDatabase.set(key, value);
|
|
}
|
|
|
|
remove(key: string): void {
|
|
myDatabase.delete(key);
|
|
}
|
|
}
|
|
```
|
|
|
|
## TypeScript Support
|
|
|
|
Full TypeScript support with exported types:
|
|
|
|
```typescript
|
|
import type {
|
|
LicenseOptions,
|
|
License,
|
|
LicenseResult,
|
|
LicenseStatus,
|
|
LicenseType,
|
|
Feature,
|
|
Activation,
|
|
CheckoutResult,
|
|
ProductTier,
|
|
} from '@ironservices/licensing';
|
|
```
|
|
|
|
## Browser & Node.js
|
|
|
|
The SDK works in both browser and Node.js environments:
|
|
|
|
- **Browser**: Uses `localStorage` for caching
|
|
- **Node.js**: Uses in-memory storage by default
|
|
|
|
## License
|
|
|
|
MIT License - see [LICENSE](LICENSE) for details.
|