@nikeandocean/carbon-factor-matcher 0.2.0 → 0.3.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.
@@ -1,80 +0,0 @@
1
- """License management for Carbon Factor Matcher MCP server."""
2
-
3
- from enum import Enum
4
- from typing import Optional
5
-
6
-
7
- class LicenseTier(Enum):
8
- """License tier levels."""
9
-
10
- FREE = "free"
11
- PRO = "pro"
12
-
13
-
14
- # Daily query limits per tier (None = unlimited)
15
- TIER_DAILY_LIMIT: dict[LicenseTier, Optional[int]] = {
16
- LicenseTier.FREE: 300,
17
- LicenseTier.PRO: None,
18
- }
19
-
20
- UPGRADE_HINT = (
21
- "\n\n---\n"
22
- "Daily free query limit reached (300/day). "
23
- "Upgrade to Pro ($5 one-time) for unlimited queries + ecoinvent + hybrid matching.\n"
24
- "Purchase: https://nikeandocean.github.io/carbon-factor-matcher"
25
- )
26
-
27
-
28
- class LicenseManager:
29
- """Manage user license and feature access.
30
-
31
- One-time purchase model (no expiration):
32
- - free: ELCD only, basic search, 300 queries/day
33
- - pro: ELCD + ecoinvent, hybrid matching, unlimited queries
34
-
35
- Args:
36
- license_key: License key string. Empty = free tier (no key needed).
37
-
38
- Raises:
39
- ValueError: If key format is invalid (looks like a key but isn't PRO-*).
40
- """
41
-
42
- def __init__(self, license_key: str = ""):
43
- self.key = license_key
44
- self.tier = self._parse_tier(license_key)
45
-
46
- def _parse_tier(self, key: str) -> LicenseTier:
47
- """Parse tier from license key prefix.
48
-
49
- Key format: {TIER}-{RANDOM}-{TIMESTAMP}
50
- Examples:
51
- - PRO-KEY-123 -> PRO
52
- - "" -> FREE
53
- - (no key) -> FREE
54
-
55
- Raises ValueError for malformed keys (e.g., "XXX-abc", "garbage-123").
56
- """
57
- if not key:
58
- return LicenseTier.FREE
59
- if "-" not in key:
60
- return LicenseTier.FREE
61
- prefix = key.split("-")[0].upper()
62
- if prefix == "PRO":
63
- return LicenseTier.PRO
64
- raise ValueError(
65
- f"Invalid license key prefix '{prefix}'. "
66
- f"Expected 'PRO-*'. Get a key at https://nikeandocean.github.io/carbon-factor-matcher"
67
- )
68
-
69
- @property
70
- def daily_limit(self) -> Optional[int]:
71
- """Return max daily queries. None = unlimited."""
72
- return TIER_DAILY_LIMIT[self.tier]
73
-
74
- def can_use_ecoinvent(self) -> bool:
75
- """Check if current tier can use ecoinvent data."""
76
- return self.tier == LicenseTier.PRO
77
-
78
- def can_use_advanced_matching(self) -> bool:
79
- """Check if current tier can use hybrid matching + quality rating."""
80
- return self.tier == LicenseTier.PRO