You've already forked wc-licensed-product
Implement version 0.0.9 features
- Add API client examples for PHP, Python, JavaScript, curl, and C# - Create comprehensive REST API documentation in docs/client-examples/ - All examples include rate limit handling (HTTP 429) - Examples cover validate, status, and activate endpoints Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
220
docs/client-examples/javascript-client.js
Normal file
220
docs/client-examples/javascript-client.js
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* WC Licensed Product API Client for JavaScript
|
||||
*
|
||||
* A JavaScript client for interacting with the WC Licensed Product REST API.
|
||||
* Works in both browser and Node.js environments.
|
||||
*
|
||||
* Browser usage:
|
||||
* <script src="javascript-client.js"></script>
|
||||
* const client = new WcLicensedProductClient('https://your-site.com');
|
||||
* const result = await client.validate('XXXX-XXXX-XXXX-XXXX', 'example.com');
|
||||
*
|
||||
* Node.js usage:
|
||||
* const WcLicensedProductClient = require('./javascript-client');
|
||||
* const client = new WcLicensedProductClient('https://your-site.com');
|
||||
*/
|
||||
|
||||
class WcLicensedProductError extends Error {
|
||||
constructor(message, errorCode = null, httpCode = null) {
|
||||
super(message);
|
||||
this.name = 'WcLicensedProductError';
|
||||
this.errorCode = errorCode;
|
||||
this.httpCode = httpCode;
|
||||
}
|
||||
}
|
||||
|
||||
class RateLimitError extends WcLicensedProductError {
|
||||
constructor(retryAfter) {
|
||||
super(`Rate limit exceeded. Retry after ${retryAfter} seconds.`);
|
||||
this.name = 'RateLimitError';
|
||||
this.retryAfter = retryAfter;
|
||||
}
|
||||
}
|
||||
|
||||
class WcLicensedProductClient {
|
||||
/**
|
||||
* Initialize the client
|
||||
* @param {string} siteUrl - Your WordPress site URL (e.g., 'https://example.com')
|
||||
* @param {Object} options - Optional configuration
|
||||
* @param {number} options.timeout - Request timeout in milliseconds (default: 30000)
|
||||
*/
|
||||
constructor(siteUrl, options = {}) {
|
||||
this.baseUrl = siteUrl.replace(/\/$/, '') + '/wp-json/wc-licensed-product/v1';
|
||||
this.timeout = options.timeout || 30000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a license key for a specific domain
|
||||
* @param {string} licenseKey - The license key to validate
|
||||
* @param {string} domain - The domain to validate against
|
||||
* @returns {Promise<Object>} Response data with 'valid' boolean and license info
|
||||
*/
|
||||
async validate(licenseKey, domain) {
|
||||
return this._request('/validate', {
|
||||
license_key: licenseKey,
|
||||
domain: domain,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status of a license
|
||||
* @param {string} licenseKey - The license key to check
|
||||
* @returns {Promise<Object>} License status data
|
||||
*/
|
||||
async status(licenseKey) {
|
||||
return this._request('/status', {
|
||||
license_key: licenseKey,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate a license on a domain
|
||||
* @param {string} licenseKey - The license key to activate
|
||||
* @param {string} domain - The domain to activate on
|
||||
* @returns {Promise<Object>} Response with 'success' boolean and message
|
||||
*/
|
||||
async activate(licenseKey, domain) {
|
||||
return this._request('/activate', {
|
||||
license_key: licenseKey,
|
||||
domain: domain,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an API request
|
||||
* @private
|
||||
* @param {string} endpoint - API endpoint path
|
||||
* @param {Object} data - Request data
|
||||
* @returns {Promise<Object>} Decoded response data
|
||||
*/
|
||||
async _request(endpoint, data) {
|
||||
const url = this.baseUrl + endpoint;
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
// Handle rate limiting
|
||||
if (response.status === 429) {
|
||||
const retryAfter = parseInt(response.headers.get('Retry-After') || '60', 10);
|
||||
throw new RateLimitError(retryAfter);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
// Check for API errors
|
||||
if (response.status >= 400 && result.error) {
|
||||
throw new WcLicensedProductError(
|
||||
result.message || 'Unknown error',
|
||||
result.error,
|
||||
response.status
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
if (error instanceof WcLicensedProductError) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (error.name === 'AbortError') {
|
||||
throw new WcLicensedProductError('Request timeout');
|
||||
}
|
||||
|
||||
throw new WcLicensedProductError(`Request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Usage Examples
|
||||
// =============================================================================
|
||||
|
||||
// Example usage (uncomment to run):
|
||||
|
||||
/*
|
||||
(async () => {
|
||||
const client = new WcLicensedProductClient('https://your-wordpress-site.com');
|
||||
|
||||
// Example 1: Validate a license
|
||||
console.log('=== Validate License ===');
|
||||
try {
|
||||
const result = await client.validate('XXXX-XXXX-XXXX-XXXX', 'myapp.example.com');
|
||||
|
||||
if (result.valid) {
|
||||
console.log('License is valid!');
|
||||
console.log('Status:', result.license?.status || 'active');
|
||||
console.log('Expires:', result.license?.expires_at || 'Never');
|
||||
} else {
|
||||
console.log('License is not valid:', result.message || 'Unknown error');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof RateLimitError) {
|
||||
console.log(`Rate limited. Retry after ${error.retryAfter} seconds.`);
|
||||
} else {
|
||||
console.log('Error:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
console.log();
|
||||
|
||||
// Example 2: Check license status
|
||||
console.log('=== Check License Status ===');
|
||||
try {
|
||||
const status = await client.status('XXXX-XXXX-XXXX-XXXX');
|
||||
|
||||
console.log('Valid:', status.valid ? 'Yes' : 'No');
|
||||
console.log('Status:', status.status || 'unknown');
|
||||
console.log('Domain:', status.domain || 'None');
|
||||
console.log('Expires:', status.expires_at || 'Never');
|
||||
console.log('Activations:', `${status.activations_count || 0}/${status.max_activations || 1}`);
|
||||
} catch (error) {
|
||||
if (error instanceof RateLimitError) {
|
||||
console.log(`Rate limited. Retry after ${error.retryAfter} seconds.`);
|
||||
} else {
|
||||
console.log('Error:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
console.log();
|
||||
|
||||
// Example 3: Activate license on a domain
|
||||
console.log('=== Activate License ===');
|
||||
try {
|
||||
const result = await client.activate('XXXX-XXXX-XXXX-XXXX', 'newsite.example.com');
|
||||
|
||||
if (result.success) {
|
||||
console.log('License activated successfully!');
|
||||
} else {
|
||||
console.log('Activation failed:', result.message || 'Unknown error');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof RateLimitError) {
|
||||
console.log(`Rate limited. Retry after ${error.retryAfter} seconds.`);
|
||||
} else {
|
||||
console.log(`Error (${error.errorCode}):`, error.message);
|
||||
}
|
||||
}
|
||||
})();
|
||||
*/
|
||||
|
||||
// Export for Node.js
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = WcLicensedProductClient;
|
||||
module.exports.WcLicensedProductError = WcLicensedProductError;
|
||||
module.exports.RateLimitError = RateLimitError;
|
||||
}
|
||||
Reference in New Issue
Block a user