@nice2dev/licensing 1.0.10
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/README.md +123 -0
- package/dist/FeatureGate-Cs1zphXs.cjs +1405 -0
- package/dist/FeatureGate-Cs1zphXs.cjs.map +1 -0
- package/dist/FeatureGate-Da7fCJA5.js +1406 -0
- package/dist/FeatureGate-Da7fCJA5.js.map +1 -0
- package/dist/__vite-browser-external-2Ng8QIWW.js +5 -0
- package/dist/__vite-browser-external-2Ng8QIWW.js.map +1 -0
- package/dist/__vite-browser-external-DES75WN9.cjs +5 -0
- package/dist/__vite-browser-external-DES75WN9.cjs.map +1 -0
- package/dist/index.cjs +4352 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2285 -0
- package/dist/index.mjs +4353 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react.cjs +1039 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.ts +327 -0
- package/dist/react.mjs +1039 -0
- package/dist/react.mjs.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeatureGate-Cs1zphXs.cjs","sources":["../src/LicenseKeyGenerator.ts","../src/HardwareFingerprint.ts","../src/LicenseValidator.ts","../src/FeatureGate.ts"],"sourcesContent":["/* ────────────────────────────────────────────────────────────────\r\n License Key Generator — RSA-signed license keys\r\n──────────────────────────────────────────────────────────────── */\r\n\r\nimport type { LicenseKey, LicenseKeyOptions, LicenseInfo, LicenseTier, FeatureId } from './types';\r\n\r\n/** Key segment length */\r\nconst SEGMENT_LENGTH = 4;\r\n/** Number of segments */\r\nconst NUM_SEGMENTS = 5;\r\n/** Characters used in license keys (no ambiguous chars) */\r\nconst KEY_CHARS = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';\r\n\r\n/** Tier numeric codes for embedding in key */\r\nconst TIER_CODES: Record<LicenseTier, number> = {\r\n trial: 1,\r\n personal: 2,\r\n team: 3,\r\n enterprise: 4,\r\n site: 5,\r\n oem: 6,\r\n};\r\n\r\n/** Reverse lookup */\r\nconst CODE_TO_TIER: Record<number, LicenseTier> = Object.entries(TIER_CODES).reduce(\r\n (acc, [tier, code]) => ({ ...acc, [code]: tier as LicenseTier }),\r\n {} as Record<number, LicenseTier>,\r\n);\r\n\r\n/**\r\n * Generate a cryptographically secure random string\r\n */\r\nfunction secureRandom(length: number): string {\r\n const array = new Uint8Array(length);\r\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\r\n crypto.getRandomValues(array);\r\n } else {\r\n // Fallback for Node.js\r\n for (let i = 0; i < length; i++) {\r\n array[i] = Math.floor(Math.random() * 256);\r\n }\r\n }\r\n return Array.from(array)\r\n .map((b) => KEY_CHARS[b % KEY_CHARS.length])\r\n .join('');\r\n}\r\n\r\n/**\r\n * Calculate checksum for license key validation\r\n */\r\nfunction calculateChecksum(data: string): string {\r\n let hash = 0;\r\n for (let i = 0; i < data.length; i++) {\r\n const char = data.charCodeAt(i);\r\n hash = ((hash << 5) - hash + char) | 0;\r\n }\r\n // Convert to 4-character checksum\r\n const positive = Math.abs(hash);\r\n let checksum = '';\r\n let remaining = positive;\r\n for (let i = 0; i < SEGMENT_LENGTH; i++) {\r\n checksum += KEY_CHARS[remaining % KEY_CHARS.length];\r\n remaining = Math.floor(remaining / KEY_CHARS.length);\r\n }\r\n return checksum;\r\n}\r\n\r\n/**\r\n * Encode metadata into key segment\r\n */\r\nfunction encodeMetadata(tier: LicenseTier, year: number, month: number): string {\r\n const tierCode = TIER_CODES[tier];\r\n const yearOffset = year - 2024; // Base year\r\n const encoded = tierCode * 1000 + yearOffset * 12 + month;\r\n\r\n let segment = '';\r\n let remaining = encoded;\r\n for (let i = 0; i < SEGMENT_LENGTH; i++) {\r\n segment += KEY_CHARS[remaining % KEY_CHARS.length];\r\n remaining = Math.floor(remaining / KEY_CHARS.length);\r\n }\r\n return segment;\r\n}\r\n\r\n/**\r\n * Decode metadata from key segment\r\n */\r\nfunction decodeMetadata(\r\n segment: string,\r\n): { tier: LicenseTier; year: number; month: number } | null {\r\n let decoded = 0;\r\n for (let i = segment.length - 1; i >= 0; i--) {\r\n const idx = KEY_CHARS.indexOf(segment[i]);\r\n if (idx === -1) {\r\n return null;\r\n }\r\n decoded = decoded * KEY_CHARS.length + idx;\r\n }\r\n\r\n const tierCode = Math.floor(decoded / 1000);\r\n const remainder = decoded % 1000;\r\n const yearOffset = Math.floor(remainder / 12);\r\n const month = remainder % 12;\r\n\r\n const tier = CODE_TO_TIER[tierCode];\r\n if (!tier) {\r\n return null;\r\n }\r\n\r\n return {\r\n tier,\r\n year: 2024 + yearOffset,\r\n month,\r\n };\r\n}\r\n\r\n/**\r\n * Generate a new license key\r\n * Format: XXXX-XXXX-XXXX-XXXX-XXXX\r\n * - Segment 1: Encoded metadata (tier, date)\r\n * - Segment 2-4: Random unique identifier\r\n * - Segment 5: Checksum\r\n */\r\nexport function generateLicenseKey(tier: LicenseTier = 'personal'): LicenseKey {\r\n const now = new Date();\r\n const metadataSegment = encodeMetadata(tier, now.getFullYear(), now.getMonth());\r\n const randomSegments = [\r\n secureRandom(SEGMENT_LENGTH),\r\n secureRandom(SEGMENT_LENGTH),\r\n secureRandom(SEGMENT_LENGTH),\r\n ];\r\n\r\n const dataWithoutChecksum = [metadataSegment, ...randomSegments].join('-');\r\n const checksumSegment = calculateChecksum(dataWithoutChecksum);\r\n\r\n return `${dataWithoutChecksum}-${checksumSegment}`;\r\n}\r\n\r\n/**\r\n * Validate license key format and checksum\r\n */\r\nexport function validateKeyFormat(key: LicenseKey): boolean {\r\n // Check format\r\n const pattern = new RegExp(\r\n `^[${KEY_CHARS}]{${SEGMENT_LENGTH}}(-[${KEY_CHARS}]{${SEGMENT_LENGTH}}){${NUM_SEGMENTS - 1}}$`,\r\n );\r\n if (!pattern.test(key)) {\r\n return false;\r\n }\r\n\r\n // Verify checksum\r\n const segments = key.split('-');\r\n const dataSegments = segments.slice(0, -1).join('-');\r\n const providedChecksum = segments[segments.length - 1];\r\n const calculatedChecksum = calculateChecksum(dataSegments);\r\n\r\n return providedChecksum === calculatedChecksum;\r\n}\r\n\r\n/**\r\n * Extract metadata from license key\r\n */\r\nexport function extractKeyMetadata(key: LicenseKey): {\r\n tier: LicenseTier;\r\n year: number;\r\n month: number;\r\n} | null {\r\n if (!validateKeyFormat(key)) {\r\n return null;\r\n }\r\n\r\n const segments = key.split('-');\r\n return decodeMetadata(segments[0]);\r\n}\r\n\r\n/**\r\n * Generate license info from key options\r\n */\r\nexport function generateLicenseInfo(options: LicenseKeyOptions): LicenseInfo {\r\n const key = generateLicenseKey(options.tier);\r\n const now = new Date();\r\n const issuedAt = now.toISOString();\r\n\r\n let expiresAt: string | null = null;\r\n let graceUntil: string | undefined;\r\n\r\n if (options.durationDays !== null) {\r\n const expiry = new Date(now);\r\n expiry.setDate(expiry.getDate() + options.durationDays);\r\n expiresAt = expiry.toISOString();\r\n\r\n if (options.graceDays) {\r\n const grace = new Date(expiry);\r\n grace.setDate(grace.getDate() + options.graceDays);\r\n graceUntil = grace.toISOString();\r\n }\r\n }\r\n\r\n return {\r\n key,\r\n tier: options.tier,\r\n status: 'valid',\r\n licensee: options.licensee,\r\n email: options.email,\r\n issuedAt,\r\n expiresAt,\r\n graceUntil,\r\n features: options.features ?? getDefaultFeatures(options.tier),\r\n maxSeats: options.maxSeats ?? getDefaultSeats(options.tier),\r\n activeSeats: 0,\r\n boundMachines: [],\r\n maxMachines: options.maxMachines ?? getDefaultMachines(options.tier),\r\n floatingSeats: options.floatingSeats,\r\n metadata: options.metadata,\r\n };\r\n}\r\n\r\n/**\r\n * Get default features for tier\r\n */\r\nexport function getDefaultFeatures(tier: LicenseTier): FeatureId[] {\r\n const features: FeatureId[] = ['core', 'basic-components'];\r\n\r\n if (tier === 'trial') {\r\n features.push('trial-watermark');\r\n }\r\n\r\n if (['personal', 'team', 'enterprise', 'site', 'oem'].includes(tier)) {\r\n features.push('advanced-components', 'theming', 'i18n');\r\n }\r\n\r\n if (['team', 'enterprise', 'site', 'oem'].includes(tier)) {\r\n features.push('collaboration', 'analytics', 'priority-support');\r\n }\r\n\r\n if (['enterprise', 'site', 'oem'].includes(tier)) {\r\n features.push('white-label', 'sso', 'audit-log', 'custom-branding', 'api-access');\r\n }\r\n\r\n if (['site', 'oem'].includes(tier)) {\r\n features.push('unlimited-seats', 'source-code-access', 'dedicated-support');\r\n }\r\n\r\n if (tier === 'oem') {\r\n features.push('redistribution', 'custom-licensing');\r\n }\r\n\r\n return features;\r\n}\r\n\r\n/**\r\n * Get default max seats for tier\r\n */\r\nexport function getDefaultSeats(tier: LicenseTier): number | null {\r\n switch (tier) {\r\n case 'trial':\r\n return 1;\r\n case 'personal':\r\n return 1;\r\n case 'team':\r\n return 10;\r\n case 'enterprise':\r\n return 50;\r\n case 'site':\r\n return null; // unlimited\r\n case 'oem':\r\n return null;\r\n default:\r\n return 1;\r\n }\r\n}\r\n\r\n/**\r\n * Get default max machines for tier\r\n */\r\nexport function getDefaultMachines(tier: LicenseTier): number {\r\n switch (tier) {\r\n case 'trial':\r\n return 1;\r\n case 'personal':\r\n return 2;\r\n case 'team':\r\n return 20;\r\n case 'enterprise':\r\n return 100;\r\n case 'site':\r\n return 1000;\r\n case 'oem':\r\n return 10000;\r\n default:\r\n return 1;\r\n }\r\n}\r\n\r\n/**\r\n * Compare two tiers, returns positive if a > b\r\n */\r\nexport function compareTiers(a: LicenseTier, b: LicenseTier): number {\r\n return TIER_CODES[a] - TIER_CODES[b];\r\n}\r\n\r\n/**\r\n * Check if tier meets minimum requirement\r\n */\r\nexport function tierMeetsRequirement(userTier: LicenseTier, requiredTier: LicenseTier): boolean {\r\n return compareTiers(userTier, requiredTier) >= 0;\r\n}\r\n\r\n/**\r\n * Mask license key for display (show first and last segments)\r\n */\r\nexport function maskLicenseKey(key: LicenseKey): string {\r\n const segments = key.split('-');\r\n if (segments.length !== NUM_SEGMENTS) {\r\n return '****-****-****-****-****';\r\n }\r\n return `${segments[0]}-****-****-****-${segments[segments.length - 1]}`;\r\n}\r\n\r\n/**\r\n * Parse license key from various formats (with or without dashes)\r\n */\r\nexport function normalizeLicenseKey(input: string): LicenseKey | null {\r\n // Remove whitespace and convert to uppercase\r\n const cleaned = input.replace(/\\s/g, '').toUpperCase();\r\n\r\n // If already has dashes, validate format\r\n if (cleaned.includes('-')) {\r\n return validateKeyFormat(cleaned) ? cleaned : null;\r\n }\r\n\r\n // Add dashes if plain string\r\n if (cleaned.length === SEGMENT_LENGTH * NUM_SEGMENTS) {\r\n const segments: string[] = [];\r\n for (let i = 0; i < NUM_SEGMENTS; i++) {\r\n segments.push(cleaned.substring(i * SEGMENT_LENGTH, (i + 1) * SEGMENT_LENGTH));\r\n }\r\n const formatted = segments.join('-');\r\n return validateKeyFormat(formatted) ? formatted : null;\r\n }\r\n\r\n return null;\r\n}\r\n","/* ────────────────────────────────────────────────────────────────\r\n Hardware Fingerprint — Machine binding for license protection\r\n──────────────────────────────────────────────────────────────── */\r\n\r\nimport type { HardwareFingerprint, HardwareFingerprintData, MachineId } from './types';\r\n\r\n/**\r\n * Simple hash function (FNV-1a)\r\n */\r\nfunction fnv1aHash(str: string): number {\r\n let hash = 2166136261;\r\n for (let i = 0; i < str.length; i++) {\r\n hash ^= str.charCodeAt(i);\r\n hash = Math.imul(hash, 16777619);\r\n }\r\n return hash >>> 0;\r\n}\r\n\r\n/**\r\n * Convert hash to hex string\r\n */\r\nfunction hashToHex(hash: number): string {\r\n return hash.toString(16).padStart(8, '0');\r\n}\r\n\r\n/**\r\n * Hash a string using multiple passes for stronger fingerprint\r\n */\r\nfunction strongHash(input: string): string {\r\n const h1 = fnv1aHash(input);\r\n const h2 = fnv1aHash(input + h1.toString());\r\n const h3 = fnv1aHash(h2.toString() + input);\r\n return hashToHex(h1) + hashToHex(h2) + hashToHex(h3);\r\n}\r\n\r\n/**\r\n * Get WebGL renderer info (GPU fingerprint)\r\n */\r\nfunction getWebGLFingerprint(): string | undefined {\r\n if (typeof document === 'undefined') {\r\n return undefined;\r\n }\r\n\r\n try {\r\n const canvas = document.createElement('canvas');\r\n const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');\r\n if (!gl) {\r\n return undefined;\r\n }\r\n\r\n const glAny = gl as WebGLRenderingContext;\r\n const debugInfo = glAny.getExtension('WEBGL_debug_renderer_info');\r\n if (!debugInfo) {\r\n return undefined;\r\n }\r\n\r\n const vendor = glAny.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);\r\n const renderer = glAny.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);\r\n\r\n return strongHash(`${vendor}|${renderer}`);\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\n/**\r\n * Get canvas fingerprint\r\n */\r\nfunction getCanvasFingerprint(): string | undefined {\r\n if (typeof document === 'undefined') {\r\n return undefined;\r\n }\r\n\r\n try {\r\n const canvas = document.createElement('canvas');\r\n canvas.width = 200;\r\n canvas.height = 50;\r\n\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) {\r\n return undefined;\r\n }\r\n\r\n // Draw text with specific styles\r\n ctx.textBaseline = 'top';\r\n ctx.font = '14px Arial';\r\n ctx.fillStyle = '#f60';\r\n ctx.fillRect(125, 1, 62, 20);\r\n ctx.fillStyle = '#069';\r\n ctx.fillText('Nice2Dev Licensing', 2, 15);\r\n ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';\r\n ctx.fillText('Nice2Dev Licensing', 4, 17);\r\n\r\n return strongHash(canvas.toDataURL());\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\n/**\r\n * Get audio context fingerprint\r\n */\r\nfunction getAudioFingerprint(): Promise<string | undefined> {\r\n if (typeof window === 'undefined' || !window.AudioContext) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return new Promise((resolve) => {\r\n try {\r\n const audioContext = new AudioContext();\r\n const oscillator = audioContext.createOscillator();\r\n const analyser = audioContext.createAnalyser();\r\n const gainNode = audioContext.createGain();\r\n const scriptProcessor = audioContext.createScriptProcessor(4096, 1, 1);\r\n\r\n gainNode.gain.value = 0; // Mute\r\n oscillator.type = 'triangle';\r\n oscillator.frequency.value = 10000;\r\n\r\n oscillator.connect(analyser);\r\n analyser.connect(scriptProcessor);\r\n scriptProcessor.connect(gainNode);\r\n gainNode.connect(audioContext.destination);\r\n\r\n let fingerprint = '';\r\n scriptProcessor.onaudioprocess = (e) => {\r\n const buffer = e.inputBuffer.getChannelData(0);\r\n fingerprint = strongHash(buffer.slice(0, 100).join(','));\r\n\r\n scriptProcessor.disconnect();\r\n oscillator.disconnect();\r\n analyser.disconnect();\r\n gainNode.disconnect();\r\n audioContext.close();\r\n\r\n resolve(fingerprint);\r\n };\r\n\r\n oscillator.start(0);\r\n\r\n // Timeout fallback\r\n setTimeout(() => {\r\n if (!fingerprint) {\r\n resolve(undefined);\r\n }\r\n }, 1000);\r\n } catch {\r\n resolve(undefined);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Get user agent hash\r\n */\r\nfunction getUserAgentHash(): string | undefined {\r\n if (typeof navigator === 'undefined') {\r\n return undefined;\r\n }\r\n return strongHash(navigator.userAgent);\r\n}\r\n\r\n/**\r\n * Get timezone info\r\n */\r\nfunction getTimezoneInfo(): string {\r\n try {\r\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\r\n } catch {\r\n return 'unknown';\r\n }\r\n}\r\n\r\n/**\r\n * Get screen info\r\n */\r\nfunction getScreenInfo(): string | undefined {\r\n if (typeof screen === 'undefined') {\r\n return undefined;\r\n }\r\n return `${screen.width}x${screen.height}x${screen.colorDepth}`;\r\n}\r\n\r\n/**\r\n * Get language info\r\n */\r\nfunction getLanguageInfo(): string | undefined {\r\n if (typeof navigator === 'undefined') {\r\n return undefined;\r\n }\r\n return navigator.language || (navigator as { userLanguage?: string }).userLanguage || 'unknown';\r\n}\r\n\r\n/**\r\n * Get platform info\r\n */\r\nfunction getPlatformInfo(): string | undefined {\r\n if (typeof navigator === 'undefined') {\r\n return undefined;\r\n }\r\n return navigator.platform;\r\n}\r\n\r\n/**\r\n * Get hardware concurrency\r\n */\r\nfunction getHardwareConcurrency(): number | undefined {\r\n if (typeof navigator === 'undefined') {\r\n return undefined;\r\n }\r\n return navigator.hardwareConcurrency;\r\n}\r\n\r\n/**\r\n * Get device memory (if available)\r\n */\r\nfunction getDeviceMemory(): number | undefined {\r\n if (typeof navigator === 'undefined') {\r\n return undefined;\r\n }\r\n return (navigator as { deviceMemory?: number }).deviceMemory;\r\n}\r\n\r\n/**\r\n * Collect all fingerprint components\r\n */\r\nexport async function collectFingerprintData(): Promise<HardwareFingerprintData> {\r\n const audioFingerprint = await getAudioFingerprint();\r\n\r\n return {\r\n webglHash: getWebGLFingerprint(),\r\n canvasFingerprint: getCanvasFingerprint(),\r\n audioFingerprint,\r\n userAgentHash: getUserAgentHash(),\r\n browserFingerprint: strongHash(\r\n [\r\n getTimezoneInfo(),\r\n getScreenInfo(),\r\n getLanguageInfo(),\r\n getPlatformInfo(),\r\n getHardwareConcurrency()?.toString(),\r\n getDeviceMemory()?.toString(),\r\n ]\r\n .filter(Boolean)\r\n .join('|'),\r\n ),\r\n };\r\n}\r\n\r\n/**\r\n * Generate hardware fingerprint\r\n */\r\nexport async function generateFingerprint(): Promise<HardwareFingerprint> {\r\n const data = await collectFingerprintData();\r\n\r\n // Combine all components\r\n const components = [\r\n data.webglHash,\r\n data.canvasFingerprint,\r\n data.audioFingerprint,\r\n data.userAgentHash,\r\n data.browserFingerprint,\r\n ].filter(Boolean);\r\n\r\n if (components.length === 0) {\r\n // Fallback: use timestamp + random for environments without fingerprint support\r\n const fallback = Date.now().toString() + Math.random().toString(36);\r\n return strongHash(fallback);\r\n }\r\n\r\n return strongHash(components.join(':'));\r\n}\r\n\r\n/**\r\n * Generate machine ID (stable identifier for this machine)\r\n */\r\nexport async function generateMachineId(): Promise<MachineId> {\r\n const fingerprint = await generateFingerprint();\r\n // Machine ID is the first 16 characters of the fingerprint\r\n return fingerprint.substring(0, 16).toUpperCase();\r\n}\r\n\r\n/**\r\n * Compare two fingerprints with tolerance (fuzzy match)\r\n * Returns similarity score 0-1\r\n */\r\nexport function compareFingerprintsData(\r\n fp1: HardwareFingerprintData,\r\n fp2: HardwareFingerprintData,\r\n): number {\r\n const fields: (keyof HardwareFingerprintData)[] = [\r\n 'webglHash',\r\n 'canvasFingerprint',\r\n 'audioFingerprint',\r\n 'userAgentHash',\r\n 'browserFingerprint',\r\n ];\r\n\r\n let matches = 0;\r\n let total = 0;\r\n\r\n for (const field of fields) {\r\n const v1 = fp1[field];\r\n const v2 = fp2[field];\r\n\r\n if (v1 !== undefined || v2 !== undefined) {\r\n total++;\r\n if (v1 === v2) {\r\n matches++;\r\n }\r\n }\r\n }\r\n\r\n return total > 0 ? matches / total : 0;\r\n}\r\n\r\n/**\r\n * Store fingerprint in local storage\r\n */\r\nexport function storeFingerprint(fingerprint: HardwareFingerprint): void {\r\n if (typeof localStorage === 'undefined') {\r\n return;\r\n }\r\n try {\r\n localStorage.setItem('nice2dev_fp', fingerprint);\r\n } catch {\r\n // Storage not available\r\n }\r\n}\r\n\r\n/**\r\n * Retrieve stored fingerprint\r\n */\r\nexport function getStoredFingerprint(): HardwareFingerprint | null {\r\n if (typeof localStorage === 'undefined') {\r\n return null;\r\n }\r\n try {\r\n return localStorage.getItem('nice2dev_fp');\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Get or generate fingerprint (uses cached value if available)\r\n */\r\nexport async function getOrGenerateFingerprint(): Promise<HardwareFingerprint> {\r\n const stored = getStoredFingerprint();\r\n if (stored) {\r\n return stored;\r\n }\r\n\r\n const fingerprint = await generateFingerprint();\r\n storeFingerprint(fingerprint);\r\n return fingerprint;\r\n}\r\n","/* ────────────────────────────────────────────────────────────────\r\n License Validator — Online/Offline license validation\r\n──────────────────────────────────────────────────────────────── */\r\n\r\nimport { generateMachineId } from './HardwareFingerprint';\r\nimport { validateKeyFormat, extractKeyMetadata } from './LicenseKeyGenerator';\r\nimport type {\r\n LicenseKey,\r\n LicenseInfo,\r\n LicenseValidationResult,\r\n LicenseServerConfig,\r\n LicenseErrorCode,\r\n FeatureId,\r\n HardwareFingerprint,\r\n OfflineChallenge,\r\n OfflineResponse,\r\n} from './types';\r\n\r\n/** Default server config */\r\nconst DEFAULT_CONFIG: LicenseServerConfig = {\r\n serverUrl: 'https://license.nice2dev.com/api/v1',\r\n timeout: 10000,\r\n retries: 3,\r\n cacheTtl: 3600, // 1 hour\r\n offlineMode: false,\r\n telemetryEnabled: false,\r\n};\r\n\r\n/** Cache key prefix */\r\nconst CACHE_PREFIX = 'nice2dev_license_';\r\n\r\n/** Validation result cache */\r\ninterface CachedValidation {\r\n result: LicenseValidationResult;\r\n cachedAt: number;\r\n expiresAt: number;\r\n}\r\n\r\n/**\r\n * License Validator Service\r\n */\r\nexport class LicenseValidator {\r\n private config: LicenseServerConfig;\r\n private cache: Map<string, CachedValidation> = new Map();\r\n\r\n constructor(config: Partial<LicenseServerConfig> = {}) {\r\n this.config = { ...DEFAULT_CONFIG, ...config };\r\n this.loadCacheFromStorage();\r\n }\r\n\r\n /**\r\n * Validate a license key\r\n */\r\n async validate(\r\n key: LicenseKey,\r\n fingerprint?: HardwareFingerprint,\r\n ): Promise<LicenseValidationResult> {\r\n const now = new Date().toISOString();\r\n\r\n // First, validate format locally\r\n if (!validateKeyFormat(key)) {\r\n return {\r\n valid: false,\r\n errorCode: 'INVALID_KEY',\r\n errorMessage: 'Invalid license key format',\r\n validatedAt: now,\r\n };\r\n }\r\n\r\n // Check cache\r\n const cached = this.getFromCache(key);\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n // Get machine fingerprint if not provided\r\n const machineFingerprint = fingerprint || (await generateMachineId());\r\n\r\n // Try online validation first\r\n if (!this.config.offlineMode) {\r\n try {\r\n const result = await this.validateOnline(key, machineFingerprint);\r\n this.setCache(key, result);\r\n return result;\r\n } catch (error) {\r\n // Fall back to offline validation\r\n console.warn('Online validation failed, trying offline:', error);\r\n }\r\n }\r\n\r\n // Offline validation\r\n return this.validateOffline(key, machineFingerprint);\r\n }\r\n\r\n /**\r\n * Online license validation\r\n */\r\n private async validateOnline(\r\n key: LicenseKey,\r\n fingerprint: HardwareFingerprint,\r\n ): Promise<LicenseValidationResult> {\r\n const url = `${this.config.serverUrl}/validate`;\r\n const now = new Date().toISOString();\r\n\r\n let lastError: Error | null = null;\r\n\r\n for (let attempt = 0; attempt < (this.config.retries || 1); attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...(this.config.apiKey ? { 'X-API-Key': this.config.apiKey } : {}),\r\n },\r\n body: JSON.stringify({\r\n licenseKey: key,\r\n machineFingerprint: fingerprint,\r\n timestamp: now,\r\n }),\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n if (response.status === 404) {\r\n return {\r\n valid: false,\r\n errorCode: 'INVALID_KEY',\r\n errorMessage: 'License key not found',\r\n validatedAt: now,\r\n };\r\n }\r\n throw new Error(`Server error: ${response.status}`);\r\n }\r\n\r\n const data = await response.json();\r\n return this.parseServerResponse(data, now);\r\n } catch (error) {\r\n lastError = error as Error;\r\n // Wait before retry (exponential backoff)\r\n if (attempt < (this.config.retries || 1) - 1) {\r\n await new Promise((r) => setTimeout(r, Math.pow(2, attempt) * 1000));\r\n }\r\n }\r\n }\r\n\r\n throw lastError || new Error('Validation failed');\r\n }\r\n\r\n /**\r\n * Parse server validation response\r\n */\r\n private parseServerResponse(\r\n data: Record<string, unknown>,\r\n validatedAt: string,\r\n ): LicenseValidationResult {\r\n // Handle server response format\r\n if (data.valid === false) {\r\n return {\r\n valid: false,\r\n errorCode: data.errorCode as LicenseErrorCode,\r\n errorMessage: data.errorMessage as string,\r\n validatedAt,\r\n };\r\n }\r\n\r\n const license = data.license as LicenseInfo;\r\n const now = new Date();\r\n\r\n // Check expiration\r\n let daysRemaining: number | undefined;\r\n let inGracePeriod = false;\r\n\r\n if (license.expiresAt) {\r\n const expiry = new Date(license.expiresAt);\r\n const diffMs = expiry.getTime() - now.getTime();\r\n daysRemaining = Math.ceil(diffMs / (1000 * 60 * 60 * 24));\r\n\r\n if (daysRemaining < 0 && license.graceUntil) {\r\n const graceEnd = new Date(license.graceUntil);\r\n if (now < graceEnd) {\r\n inGracePeriod = true;\r\n }\r\n }\r\n }\r\n\r\n return {\r\n valid: true,\r\n license,\r\n daysRemaining,\r\n inGracePeriod,\r\n availableFeatures: license.features,\r\n validatedAt,\r\n };\r\n }\r\n\r\n /**\r\n * Offline license validation\r\n */\r\n private validateOffline(\r\n key: LicenseKey,\r\n fingerprint: HardwareFingerprint,\r\n ): LicenseValidationResult {\r\n const now = new Date().toISOString();\r\n\r\n // Extract metadata from key\r\n const metadata = extractKeyMetadata(key);\r\n if (!metadata) {\r\n return {\r\n valid: false,\r\n errorCode: 'INVALID_KEY',\r\n errorMessage: 'Cannot decode license key',\r\n validatedAt: now,\r\n };\r\n }\r\n\r\n // Check for locally stored license data\r\n const storedLicense = this.getStoredLicense(key);\r\n if (storedLicense) {\r\n // Verify fingerprint matches\r\n if (!storedLicense.boundMachines.some((m) => m.startsWith(fingerprint.substring(0, 8)))) {\r\n return {\r\n valid: false,\r\n errorCode: 'MACHINE_LIMIT',\r\n errorMessage: 'This machine is not authorized for this license',\r\n validatedAt: now,\r\n };\r\n }\r\n\r\n // Check expiration\r\n if (storedLicense.expiresAt) {\r\n const expiry = new Date(storedLicense.expiresAt);\r\n const nowDate = new Date();\r\n\r\n if (nowDate > expiry) {\r\n // Check grace period\r\n if (storedLicense.graceUntil) {\r\n const graceEnd = new Date(storedLicense.graceUntil);\r\n if (nowDate > graceEnd) {\r\n return {\r\n valid: false,\r\n errorCode: 'EXPIRED',\r\n errorMessage: 'License has expired',\r\n validatedAt: now,\r\n };\r\n }\r\n // In grace period\r\n return {\r\n valid: true,\r\n license: storedLicense,\r\n inGracePeriod: true,\r\n daysRemaining: 0,\r\n availableFeatures: storedLicense.features,\r\n validatedAt: now,\r\n };\r\n }\r\n\r\n return {\r\n valid: false,\r\n errorCode: 'EXPIRED',\r\n errorMessage: 'License has expired',\r\n validatedAt: now,\r\n };\r\n }\r\n\r\n const diffMs = expiry.getTime() - nowDate.getTime();\r\n const daysRemaining = Math.ceil(diffMs / (1000 * 60 * 60 * 24));\r\n\r\n return {\r\n valid: true,\r\n license: storedLicense,\r\n daysRemaining,\r\n inGracePeriod: false,\r\n availableFeatures: storedLicense.features,\r\n validatedAt: now,\r\n };\r\n }\r\n\r\n // Perpetual license\r\n return {\r\n valid: true,\r\n license: storedLicense,\r\n availableFeatures: storedLicense.features,\r\n validatedAt: now,\r\n };\r\n }\r\n\r\n // No stored license data - limited offline validation\r\n // Only validate format and metadata\r\n return {\r\n valid: true, // Trust the key format\r\n license: {\r\n key,\r\n tier: metadata.tier,\r\n status: 'pending', // Needs online verification\r\n licensee: 'Unknown (offline)',\r\n email: '',\r\n issuedAt: `${metadata.year}-${String(metadata.month + 1).padStart(2, '0')}-01T00:00:00Z`,\r\n expiresAt: null,\r\n features: [], // Limited features offline\r\n maxSeats: null,\r\n activeSeats: 0,\r\n boundMachines: [fingerprint],\r\n maxMachines: 1,\r\n },\r\n availableFeatures: ['core'], // Only core features offline\r\n validatedAt: now,\r\n };\r\n }\r\n\r\n /**\r\n * Generate offline activation challenge\r\n */\r\n async generateChallenge(key: LicenseKey): Promise<OfflineChallenge> {\r\n const fingerprint = await generateMachineId();\r\n const challengeId = crypto.randomUUID\r\n ? crypto.randomUUID()\r\n : Math.random().toString(36).substring(2) + Date.now().toString(36);\r\n\r\n const challengeData = JSON.stringify({\r\n key,\r\n fingerprint,\r\n timestamp: Date.now(),\r\n });\r\n\r\n // Base64 encode (simple encoding for challenge)\r\n const challengeCode =\r\n typeof btoa !== 'undefined'\r\n ? btoa(challengeData)\r\n : Buffer.from(challengeData).toString('base64');\r\n\r\n const expiresAt = new Date();\r\n expiresAt.setHours(expiresAt.getHours() + 24); // 24 hour validity\r\n\r\n return {\r\n challengeId,\r\n challengeCode,\r\n fingerprint,\r\n expiresAt: expiresAt.toISOString(),\r\n };\r\n }\r\n\r\n /**\r\n * Apply offline activation response\r\n */\r\n applyOfflineResponse(response: OfflineResponse): LicenseValidationResult {\r\n const now = new Date().toISOString();\r\n\r\n try {\r\n // Decode license data\r\n const licenseDataJson =\r\n typeof atob !== 'undefined'\r\n ? atob(response.licenseData)\r\n : Buffer.from(response.licenseData, 'base64').toString('utf-8');\r\n\r\n const license = JSON.parse(licenseDataJson) as LicenseInfo;\r\n\r\n // Store license locally\r\n this.storeLicense(license);\r\n\r\n return {\r\n valid: true,\r\n license,\r\n availableFeatures: license.features,\r\n validatedAt: now,\r\n };\r\n } catch {\r\n return {\r\n valid: false,\r\n errorCode: 'TAMPERED',\r\n errorMessage: 'Invalid offline activation response',\r\n validatedAt: now,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Check if feature is available\r\n */\r\n async hasFeature(key: LicenseKey, feature: FeatureId): Promise<boolean> {\r\n const result = await this.validate(key);\r\n if (!result.valid) {\r\n return false;\r\n }\r\n return result.availableFeatures?.includes(feature) ?? false;\r\n }\r\n\r\n /**\r\n * Activate machine for license\r\n */\r\n async activateMachine(key: LicenseKey): Promise<LicenseValidationResult> {\r\n const fingerprint = await generateMachineId();\r\n const url = `${this.config.serverUrl}/activate`;\r\n const now = new Date().toISOString();\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...(this.config.apiKey ? { 'X-API-Key': this.config.apiKey } : {}),\r\n },\r\n body: JSON.stringify({\r\n licenseKey: key,\r\n machineFingerprint: fingerprint,\r\n machineName: this.getMachineName(),\r\n timestamp: now,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const data = await response.json();\r\n return {\r\n valid: false,\r\n errorCode: data.errorCode || 'SERVER_ERROR',\r\n errorMessage: data.errorMessage || 'Activation failed',\r\n validatedAt: now,\r\n };\r\n }\r\n\r\n const data = await response.json();\r\n const license = data.license as LicenseInfo;\r\n\r\n // Store license locally\r\n this.storeLicense(license);\r\n this.clearCache(key);\r\n\r\n return {\r\n valid: true,\r\n license,\r\n availableFeatures: license.features,\r\n validatedAt: now,\r\n };\r\n } catch (error) {\r\n return {\r\n valid: false,\r\n errorCode: 'NETWORK_ERROR',\r\n errorMessage: 'Cannot connect to license server',\r\n validatedAt: now,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Deactivate machine from license\r\n */\r\n async deactivateMachine(key: LicenseKey): Promise<boolean> {\r\n const fingerprint = await generateMachineId();\r\n const url = `${this.config.serverUrl}/deactivate`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...(this.config.apiKey ? { 'X-API-Key': this.config.apiKey } : {}),\r\n },\r\n body: JSON.stringify({\r\n licenseKey: key,\r\n machineFingerprint: fingerprint,\r\n }),\r\n });\r\n\r\n if (response.ok) {\r\n this.clearStoredLicense(key);\r\n this.clearCache(key);\r\n return true;\r\n }\r\n\r\n return false;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n // ─── Cache Management ─────────────────────────────────────────\r\n\r\n private getFromCache(key: LicenseKey): LicenseValidationResult | null {\r\n const cached = this.cache.get(key);\r\n if (!cached) {\r\n return null;\r\n }\r\n\r\n if (Date.now() > cached.expiresAt) {\r\n this.cache.delete(key);\r\n return null;\r\n }\r\n\r\n return cached.result;\r\n }\r\n\r\n private setCache(key: LicenseKey, result: LicenseValidationResult): void {\r\n const now = Date.now();\r\n const ttl = (this.config.cacheTtl || 3600) * 1000;\r\n\r\n this.cache.set(key, {\r\n result,\r\n cachedAt: now,\r\n expiresAt: now + ttl,\r\n });\r\n\r\n this.saveCacheToStorage();\r\n }\r\n\r\n private clearCache(key: LicenseKey): void {\r\n this.cache.delete(key);\r\n this.saveCacheToStorage();\r\n }\r\n\r\n // ─── Storage Management ───────────────────────────────────────\r\n\r\n private getStoredLicense(key: LicenseKey): LicenseInfo | null {\r\n if (typeof localStorage === 'undefined') {\r\n return null;\r\n }\r\n\r\n try {\r\n const data = localStorage.getItem(`${CACHE_PREFIX}info_${key}`);\r\n return data ? JSON.parse(data) : null;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n private storeLicense(license: LicenseInfo): void {\r\n if (typeof localStorage === 'undefined') {\r\n return;\r\n }\r\n\r\n try {\r\n localStorage.setItem(`${CACHE_PREFIX}info_${license.key}`, JSON.stringify(license));\r\n } catch {\r\n // Storage not available\r\n }\r\n }\r\n\r\n private clearStoredLicense(key: LicenseKey): void {\r\n if (typeof localStorage === 'undefined') {\r\n return;\r\n }\r\n\r\n try {\r\n localStorage.removeItem(`${CACHE_PREFIX}info_${key}`);\r\n } catch {\r\n // Ignore\r\n }\r\n }\r\n\r\n private loadCacheFromStorage(): void {\r\n if (typeof localStorage === 'undefined') {\r\n return;\r\n }\r\n\r\n try {\r\n const data = localStorage.getItem(`${CACHE_PREFIX}cache`);\r\n if (data) {\r\n const parsed = JSON.parse(data);\r\n for (const [key, value] of Object.entries(parsed)) {\r\n this.cache.set(key, value as CachedValidation);\r\n }\r\n }\r\n } catch {\r\n // Ignore\r\n }\r\n }\r\n\r\n private saveCacheToStorage(): void {\r\n if (typeof localStorage === 'undefined') {\r\n return;\r\n }\r\n\r\n try {\r\n const obj: Record<string, CachedValidation> = {};\r\n for (const [key, value] of this.cache.entries()) {\r\n obj[key] = value;\r\n }\r\n localStorage.setItem(`${CACHE_PREFIX}cache`, JSON.stringify(obj));\r\n } catch {\r\n // Ignore\r\n }\r\n }\r\n\r\n private getMachineName(): string {\r\n if (typeof navigator !== 'undefined') {\r\n return navigator.userAgent.split(/[()]/)[1] || 'Unknown Device';\r\n }\r\n return 'Server';\r\n }\r\n}\r\n\r\n/** Global validator instance */\r\nlet globalValidator: LicenseValidator | null = null;\r\n\r\n/**\r\n * Get or create global validator instance\r\n */\r\nexport function getValidator(config?: Partial<LicenseServerConfig>): LicenseValidator {\r\n if (!globalValidator || config) {\r\n globalValidator = new LicenseValidator(config);\r\n }\r\n return globalValidator;\r\n}\r\n\r\n/**\r\n * Validate license key (convenience function)\r\n */\r\nexport async function validateLicense(key: LicenseKey): Promise<LicenseValidationResult> {\r\n return getValidator().validate(key);\r\n}\r\n\r\n/**\r\n * Check if feature is licensed (convenience function)\r\n */\r\nexport async function isFeatureLicensed(key: LicenseKey, feature: FeatureId): Promise<boolean> {\r\n return getValidator().hasFeature(key, feature);\r\n}\r\n","/* ────────────────────────────────────────────────────────────────\r\n Feature Gate — Component gating based on license tier/features\r\n──────────────────────────────────────────────────────────────── */\r\n\r\nimport { tierMeetsRequirement, getDefaultFeatures } from './LicenseKeyGenerator';\r\nimport type { LicenseInfo, LicenseTier, FeatureId, FeatureDefinition, LicensePlan } from './types';\r\n\r\n/** Feature registry */\r\nconst featureRegistry = new Map<FeatureId, FeatureDefinition>();\r\n\r\n/** Plan registry */\r\nconst planRegistry = new Map<LicenseTier, LicensePlan>();\r\n\r\n/**\r\n * Register a feature definition\r\n */\r\nexport function registerFeature(feature: FeatureDefinition): void {\r\n featureRegistry.set(feature.id, feature);\r\n}\r\n\r\n/**\r\n * Register multiple features\r\n */\r\nexport function registerFeatures(features: FeatureDefinition[]): void {\r\n features.forEach(registerFeature);\r\n}\r\n\r\n/**\r\n * Get feature definition\r\n */\r\nexport function getFeature(id: FeatureId): FeatureDefinition | undefined {\r\n return featureRegistry.get(id);\r\n}\r\n\r\n/**\r\n * Get all registered features\r\n */\r\nexport function getAllFeatures(): FeatureDefinition[] {\r\n return Array.from(featureRegistry.values());\r\n}\r\n\r\n/**\r\n * Get features by category\r\n */\r\nexport function getFeaturesByCategory(category: string): FeatureDefinition[] {\r\n return getAllFeatures().filter((f) => f.category === category);\r\n}\r\n\r\n/**\r\n * Register a license plan\r\n */\r\nexport function registerPlan(plan: LicensePlan): void {\r\n planRegistry.set(plan.id, plan);\r\n}\r\n\r\n/**\r\n * Register multiple plans\r\n */\r\nexport function registerPlans(plans: LicensePlan[]): void {\r\n plans.forEach(registerPlan);\r\n}\r\n\r\n/**\r\n * Get plan by tier\r\n */\r\nexport function getPlan(tier: LicenseTier): LicensePlan | undefined {\r\n return planRegistry.get(tier);\r\n}\r\n\r\n/**\r\n * Get all plans\r\n */\r\nexport function getAllPlans(): LicensePlan[] {\r\n return Array.from(planRegistry.values());\r\n}\r\n\r\n/**\r\n * Check if license has specific feature\r\n */\r\nexport function hasFeature(license: LicenseInfo | null, featureId: FeatureId): boolean {\r\n if (!license) {\r\n return false;\r\n }\r\n\r\n // Check explicit features list\r\n if (license.features.includes(featureId)) {\r\n return true;\r\n }\r\n\r\n // Check tier-based access\r\n const feature = getFeature(featureId);\r\n if (feature) {\r\n return tierMeetsRequirement(license.tier, feature.requiredTier);\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if license meets tier requirement\r\n */\r\nexport function hasTier(license: LicenseInfo | null, requiredTier: LicenseTier): boolean {\r\n if (!license) {\r\n return false;\r\n }\r\n return tierMeetsRequirement(license.tier, requiredTier);\r\n}\r\n\r\n/**\r\n * Get all available features for a license\r\n */\r\nexport function getAvailableFeatures(license: LicenseInfo | null): FeatureId[] {\r\n if (!license) {\r\n return [];\r\n }\r\n\r\n const available = new Set<FeatureId>(license.features);\r\n\r\n // Add tier-based features\r\n for (const feature of getAllFeatures()) {\r\n if (tierMeetsRequirement(license.tier, feature.requiredTier)) {\r\n available.add(feature.id);\r\n }\r\n }\r\n\r\n return Array.from(available);\r\n}\r\n\r\n/**\r\n * Get missing features for upgrade promotion\r\n */\r\nexport function getMissingFeatures(\r\n license: LicenseInfo | null,\r\n targetTier: LicenseTier,\r\n): FeatureDefinition[] {\r\n const currentFeatures = new Set(license ? getAvailableFeatures(license) : []);\r\n const targetFeatures = getDefaultFeatures(targetTier);\r\n\r\n return getAllFeatures().filter(\r\n (f) => targetFeatures.includes(f.id) && !currentFeatures.has(f.id),\r\n );\r\n}\r\n\r\n/**\r\n * Feature check result\r\n */\r\nexport interface FeatureCheckResult {\r\n allowed: boolean;\r\n reason?: 'no-license' | 'tier-insufficient' | 'feature-not-included' | 'expired';\r\n requiredTier?: LicenseTier;\r\n upgradeTarget?: LicenseTier;\r\n}\r\n\r\n/**\r\n * Check feature access with detailed result\r\n */\r\nexport function checkFeatureAccess(\r\n license: LicenseInfo | null,\r\n featureId: FeatureId,\r\n): FeatureCheckResult {\r\n if (!license) {\r\n return {\r\n allowed: false,\r\n reason: 'no-license',\r\n requiredTier: 'personal',\r\n };\r\n }\r\n\r\n if (license.status === 'expired') {\r\n return {\r\n allowed: false,\r\n reason: 'expired',\r\n };\r\n }\r\n\r\n const feature = getFeature(featureId);\r\n if (!feature) {\r\n // Unknown feature - check explicit list\r\n return {\r\n allowed: license.features.includes(featureId),\r\n reason: license.features.includes(featureId) ? undefined : 'feature-not-included',\r\n };\r\n }\r\n\r\n if (!tierMeetsRequirement(license.tier, feature.requiredTier)) {\r\n return {\r\n allowed: false,\r\n reason: 'tier-insufficient',\r\n requiredTier: feature.requiredTier,\r\n upgradeTarget: feature.requiredTier,\r\n };\r\n }\r\n\r\n // Check dependencies\r\n if (feature.dependencies) {\r\n for (const dep of feature.dependencies) {\r\n const depResult = checkFeatureAccess(license, dep);\r\n if (!depResult.allowed) {\r\n return depResult;\r\n }\r\n }\r\n }\r\n\r\n return { allowed: true };\r\n}\r\n\r\n// ─── Default Feature Definitions ────────────────────────────────\r\n\r\nconst DEFAULT_FEATURES: FeatureDefinition[] = [\r\n // Core features\r\n {\r\n id: 'core',\r\n name: 'Core Components',\r\n description: 'Basic UI components',\r\n requiredTier: 'trial',\r\n category: 'core',\r\n },\r\n {\r\n id: 'basic-components',\r\n name: 'Basic Components',\r\n description: 'Buttons, inputs, cards',\r\n requiredTier: 'trial',\r\n category: 'core',\r\n },\r\n\r\n // Personal tier\r\n {\r\n id: 'advanced-components',\r\n name: 'Advanced Components',\r\n description: 'Data grids, charts, editors',\r\n requiredTier: 'personal',\r\n category: 'components',\r\n },\r\n {\r\n id: 'theming',\r\n name: 'Custom Theming',\r\n description: 'Theme customization',\r\n requiredTier: 'personal',\r\n category: 'customization',\r\n },\r\n {\r\n id: 'i18n',\r\n name: 'Internationalization',\r\n description: 'Multi-language support',\r\n requiredTier: 'personal',\r\n category: 'customization',\r\n },\r\n\r\n // Team tier\r\n {\r\n id: 'collaboration',\r\n name: 'Collaboration',\r\n description: 'Real-time collaboration features',\r\n requiredTier: 'team',\r\n category: 'team',\r\n },\r\n {\r\n id: 'analytics',\r\n name: 'Analytics',\r\n description: 'Usage analytics dashboard',\r\n requiredTier: 'team',\r\n category: 'team',\r\n },\r\n {\r\n id: 'priority-support',\r\n name: 'Priority Support',\r\n description: '24-hour response time',\r\n requiredTier: 'team',\r\n category: 'support',\r\n },\r\n\r\n // Enterprise tier\r\n {\r\n id: 'white-label',\r\n name: 'White Labeling',\r\n description: 'Remove Nice2Dev branding',\r\n requiredTier: 'enterprise',\r\n category: 'enterprise',\r\n },\r\n {\r\n id: 'sso',\r\n name: 'Single Sign-On',\r\n description: 'SAML/OIDC integration',\r\n requiredTier: 'enterprise',\r\n category: 'enterprise',\r\n },\r\n {\r\n id: 'audit-log',\r\n name: 'Audit Log',\r\n description: 'Detailed activity logging',\r\n requiredTier: 'enterprise',\r\n category: 'enterprise',\r\n },\r\n {\r\n id: 'custom-branding',\r\n name: 'Custom Branding',\r\n description: 'Full brand customization',\r\n requiredTier: 'enterprise',\r\n category: 'enterprise',\r\n },\r\n {\r\n id: 'api-access',\r\n name: 'API Access',\r\n description: 'Full REST API access',\r\n requiredTier: 'enterprise',\r\n category: 'enterprise',\r\n },\r\n\r\n // Site tier\r\n {\r\n id: 'unlimited-seats',\r\n name: 'Unlimited Seats',\r\n description: 'No user limits',\r\n requiredTier: 'site',\r\n category: 'site',\r\n },\r\n {\r\n id: 'source-code-access',\r\n name: 'Source Code Access',\r\n description: 'Access to source code',\r\n requiredTier: 'site',\r\n category: 'site',\r\n },\r\n {\r\n id: 'dedicated-support',\r\n name: 'Dedicated Support',\r\n description: 'Dedicated support engineer',\r\n requiredTier: 'site',\r\n category: 'support',\r\n },\r\n\r\n // OEM tier\r\n {\r\n id: 'redistribution',\r\n name: 'Redistribution Rights',\r\n description: 'Include in your products',\r\n requiredTier: 'oem',\r\n category: 'oem',\r\n },\r\n {\r\n id: 'custom-licensing',\r\n name: 'Custom Licensing',\r\n description: 'Your own license terms',\r\n requiredTier: 'oem',\r\n category: 'oem',\r\n },\r\n\r\n // Trial marker\r\n {\r\n id: 'trial-watermark',\r\n name: 'Trial Watermark',\r\n description: 'Watermark for trial versions',\r\n requiredTier: 'trial',\r\n category: 'trial',\r\n },\r\n\r\n // Game Engine features\r\n {\r\n id: 'game-editor',\r\n name: 'Game Editor',\r\n description: 'Visual game editor',\r\n requiredTier: 'personal',\r\n category: 'game-engine',\r\n },\r\n {\r\n id: 'game-export',\r\n name: 'Game Export',\r\n description: 'Export to various platforms',\r\n requiredTier: 'team',\r\n category: 'game-engine',\r\n },\r\n {\r\n id: 'game-multiplayer',\r\n name: 'Multiplayer',\r\n description: 'Online multiplayer support',\r\n requiredTier: 'team',\r\n category: 'game-engine',\r\n },\r\n {\r\n id: 'game-build-cloud',\r\n name: 'Build Cloud',\r\n description: 'Cloud compilation for games',\r\n requiredTier: 'enterprise',\r\n category: 'game-engine',\r\n },\r\n\r\n // Spatial features\r\n {\r\n id: 'spatial-editor',\r\n name: 'Spatial Editor',\r\n description: 'Floor plan editor',\r\n requiredTier: 'personal',\r\n category: 'spatial',\r\n },\r\n {\r\n id: 'spatial-3d',\r\n name: '3D Visualization',\r\n description: '3D building visualization',\r\n requiredTier: 'team',\r\n category: 'spatial',\r\n },\r\n {\r\n id: 'spatial-bim',\r\n name: 'BIM Integration',\r\n description: 'IFC/BIM file support',\r\n requiredTier: 'enterprise',\r\n category: 'spatial',\r\n },\r\n];\r\n\r\nconst DEFAULT_PLANS: LicensePlan[] = [\r\n {\r\n id: 'trial',\r\n name: 'Trial',\r\n description: '14-day free trial with all features',\r\n priceMonthly: 0,\r\n priceYearly: 0,\r\n features: ['core', 'basic-components', 'trial-watermark'],\r\n maxSeats: 1,\r\n maxMachines: 1,\r\n highlights: ['All features for 14 days', 'No credit card required'],\r\n },\r\n {\r\n id: 'personal',\r\n name: 'Personal',\r\n description: 'For individual developers',\r\n priceMonthly: 1900, // $19\r\n priceYearly: 15900, // $159 (2 months free)\r\n features: ['core', 'basic-components', 'advanced-components', 'theming', 'i18n'],\r\n maxSeats: 1,\r\n maxMachines: 2,\r\n highlights: ['All UI components', 'Custom theming', 'Email support'],\r\n },\r\n {\r\n id: 'team',\r\n name: 'Team',\r\n description: 'For small to medium teams',\r\n priceMonthly: 4900, // $49/seat\r\n priceYearly: 41900, // $419/seat\r\n features: [\r\n 'core',\r\n 'basic-components',\r\n 'advanced-components',\r\n 'theming',\r\n 'i18n',\r\n 'collaboration',\r\n 'analytics',\r\n 'priority-support',\r\n ],\r\n maxSeats: 10,\r\n maxMachines: 20,\r\n highlights: ['Up to 10 seats', 'Collaboration tools', 'Priority support'],\r\n recommended: true,\r\n },\r\n {\r\n id: 'enterprise',\r\n name: 'Enterprise',\r\n description: 'For large organizations',\r\n priceMonthly: 19900, // $199/month base\r\n priceYearly: 199900, // $1999/year\r\n features: [\r\n 'core',\r\n 'basic-components',\r\n 'advanced-components',\r\n 'theming',\r\n 'i18n',\r\n 'collaboration',\r\n 'analytics',\r\n 'priority-support',\r\n 'white-label',\r\n 'sso',\r\n 'audit-log',\r\n 'custom-branding',\r\n 'api-access',\r\n ],\r\n maxSeats: 50,\r\n maxMachines: 100,\r\n highlights: ['Up to 50 seats', 'SSO & SAML', 'White labeling', 'API access'],\r\n },\r\n {\r\n id: 'site',\r\n name: 'Site License',\r\n description: 'Unlimited usage for your organization',\r\n priceMonthly: 0, // Contact sales\r\n priceYearly: 0,\r\n features: [\r\n 'core',\r\n 'basic-components',\r\n 'advanced-components',\r\n 'theming',\r\n 'i18n',\r\n 'collaboration',\r\n 'analytics',\r\n 'priority-support',\r\n 'white-label',\r\n 'sso',\r\n 'audit-log',\r\n 'custom-branding',\r\n 'api-access',\r\n 'unlimited-seats',\r\n 'source-code-access',\r\n 'dedicated-support',\r\n ],\r\n maxSeats: null,\r\n maxMachines: 1000,\r\n highlights: ['Unlimited seats', 'Source code access', 'Dedicated support engineer'],\r\n },\r\n {\r\n id: 'oem',\r\n name: 'OEM',\r\n description: 'Embed in your products',\r\n priceMonthly: 0, // Contact sales\r\n priceYearly: 0,\r\n features: [\r\n 'core',\r\n 'basic-components',\r\n 'advanced-components',\r\n 'theming',\r\n 'i18n',\r\n 'collaboration',\r\n 'analytics',\r\n 'priority-support',\r\n 'white-label',\r\n 'sso',\r\n 'audit-log',\r\n 'custom-branding',\r\n 'api-access',\r\n 'unlimited-seats',\r\n 'source-code-access',\r\n 'dedicated-support',\r\n 'redistribution',\r\n 'custom-licensing',\r\n ],\r\n maxSeats: null,\r\n maxMachines: 10000,\r\n highlights: ['Redistribution rights', 'Custom licensing', 'Full support'],\r\n },\r\n];\r\n\r\n/**\r\n * Initialize default features and plans\r\n */\r\nexport function initializeDefaults(): void {\r\n registerFeatures(DEFAULT_FEATURES);\r\n registerPlans(DEFAULT_PLANS);\r\n}\r\n\r\n// Auto-initialize\r\ninitializeDefaults();\r\n"],"names":["data"],"mappings":"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"}
|