173 lines
4.0 KiB
TypeScript
173 lines
4.0 KiB
TypeScript
import type { License, LicenseResult } from './types';
|
|
|
|
/**
|
|
* Storage interface for license caching.
|
|
*/
|
|
export interface StorageAdapter {
|
|
get(key: string): string | null;
|
|
set(key: string, value: string): void;
|
|
remove(key: string): void;
|
|
}
|
|
|
|
/**
|
|
* In-memory storage adapter.
|
|
*/
|
|
export class MemoryStorage implements StorageAdapter {
|
|
private data: Map<string, string> = new Map();
|
|
|
|
get(key: string): string | null {
|
|
return this.data.get(key) ?? null;
|
|
}
|
|
|
|
set(key: string, value: string): void {
|
|
this.data.set(key, value);
|
|
}
|
|
|
|
remove(key: string): void {
|
|
this.data.delete(key);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* LocalStorage adapter for browser.
|
|
*/
|
|
export class LocalStorageAdapter implements StorageAdapter {
|
|
get(key: string): string | null {
|
|
try {
|
|
return localStorage.getItem(key);
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
set(key: string, value: string): void {
|
|
try {
|
|
localStorage.setItem(key, value);
|
|
} catch {
|
|
// Ignore storage errors
|
|
}
|
|
}
|
|
|
|
remove(key: string): void {
|
|
try {
|
|
localStorage.removeItem(key);
|
|
} catch {
|
|
// Ignore storage errors
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* License cache manager.
|
|
*/
|
|
export class LicenseCache {
|
|
private storage: StorageAdapter;
|
|
private keyPrefix: string;
|
|
|
|
constructor(storage: StorageAdapter, keyPrefix: string = 'ironlicensing') {
|
|
this.storage = storage;
|
|
this.keyPrefix = keyPrefix;
|
|
}
|
|
|
|
private key(name: string): string {
|
|
return `${this.keyPrefix}:${name}`;
|
|
}
|
|
|
|
/**
|
|
* Gets the cached license.
|
|
*/
|
|
getLicense(): License | null {
|
|
const data = this.storage.get(this.key('license'));
|
|
if (!data) return null;
|
|
|
|
try {
|
|
const parsed = JSON.parse(data);
|
|
// Restore Date objects
|
|
if (parsed.expiresAt) parsed.expiresAt = new Date(parsed.expiresAt);
|
|
if (parsed.createdAt) parsed.createdAt = new Date(parsed.createdAt);
|
|
if (parsed.lastValidatedAt) parsed.lastValidatedAt = new Date(parsed.lastValidatedAt);
|
|
return parsed;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the cached license.
|
|
*/
|
|
setLicense(license: License): void {
|
|
this.storage.set(this.key('license'), JSON.stringify(license));
|
|
}
|
|
|
|
/**
|
|
* Gets the cached validation result.
|
|
*/
|
|
getValidationResult(): LicenseResult | null {
|
|
const data = this.storage.get(this.key('validation'));
|
|
if (!data) return null;
|
|
|
|
try {
|
|
const parsed = JSON.parse(data);
|
|
if (parsed.license) {
|
|
if (parsed.license.expiresAt) parsed.license.expiresAt = new Date(parsed.license.expiresAt);
|
|
if (parsed.license.createdAt) parsed.license.createdAt = new Date(parsed.license.createdAt);
|
|
if (parsed.license.lastValidatedAt) parsed.license.lastValidatedAt = new Date(parsed.license.lastValidatedAt);
|
|
}
|
|
return parsed;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the cached validation result.
|
|
*/
|
|
setValidationResult(result: LicenseResult, timestamp: Date): void {
|
|
this.storage.set(this.key('validation'), JSON.stringify(result));
|
|
this.storage.set(this.key('validation_time'), timestamp.toISOString());
|
|
}
|
|
|
|
/**
|
|
* Gets the validation timestamp.
|
|
*/
|
|
getValidationTime(): Date | null {
|
|
const data = this.storage.get(this.key('validation_time'));
|
|
if (!data) return null;
|
|
return new Date(data);
|
|
}
|
|
|
|
/**
|
|
* Gets the stored license key.
|
|
*/
|
|
getLicenseKey(): string | null {
|
|
return this.storage.get(this.key('license_key'));
|
|
}
|
|
|
|
/**
|
|
* Sets the license key.
|
|
*/
|
|
setLicenseKey(key: string): void {
|
|
this.storage.set(this.key('license_key'), key);
|
|
}
|
|
|
|
/**
|
|
* Clears all cached data.
|
|
*/
|
|
clear(): void {
|
|
this.storage.remove(this.key('license'));
|
|
this.storage.remove(this.key('validation'));
|
|
this.storage.remove(this.key('validation_time'));
|
|
this.storage.remove(this.key('license_key'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the default storage adapter based on environment.
|
|
*/
|
|
export function getDefaultStorage(): StorageAdapter {
|
|
if (typeof window !== 'undefined' && typeof localStorage !== 'undefined') {
|
|
return new LocalStorageAdapter();
|
|
}
|
|
return new MemoryStorage();
|
|
}
|