@akira-io/billing-js 0.1.9 → 0.2.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.
package/dist/index.cjs CHANGED
@@ -536,17 +536,248 @@ function buildOauthInitUrl(opts) {
536
536
  return `${base}/auth/${opts.provider}?${params.toString()}`;
537
537
  }
538
538
 
539
+ // src/lifecycle.ts
540
+ function computeState(payload, graceWindowMs, now = /* @__PURE__ */ new Date()) {
541
+ if (!payload) return "none";
542
+ if (!payload.valid_until) return "invalid";
543
+ const expiry = Date.parse(payload.valid_until);
544
+ if (Number.isNaN(expiry)) return "invalid";
545
+ const nowMs = now.getTime();
546
+ if (nowMs <= expiry) {
547
+ return isTrialPayload(payload) ? "trialing" : "active";
548
+ }
549
+ const cutoff = expiry + graceWindowMs;
550
+ if (nowMs <= cutoff) return "grace";
551
+ return "expired";
552
+ }
553
+ function trialDaysLeft(payload, now = /* @__PURE__ */ new Date()) {
554
+ if (!payload || !isTrialPayload(payload)) return 0;
555
+ const expiry = Date.parse(payload.valid_until);
556
+ if (Number.isNaN(expiry)) return 0;
557
+ const delta = expiry - now.getTime();
558
+ if (delta <= 0) return 0;
559
+ const dayMs = 24 * 60 * 60 * 1e3;
560
+ return Math.ceil(delta / dayMs);
561
+ }
562
+ function isTrialPayload(payload) {
563
+ if (payload.features?.__trial === true) return true;
564
+ if (payload.plan_key && payload.plan_key.endsWith(":trial")) return true;
565
+ return false;
566
+ }
567
+
568
+ // src/gate.ts
569
+ var GateDeniedError = class extends Error {
570
+ access;
571
+ constructor(access) {
572
+ super(`billing: feature "${access.feature}" denied (${access.reason})`);
573
+ this.name = "GateDeniedError";
574
+ this.access = access;
575
+ }
576
+ };
577
+ function isGateDenied(err) {
578
+ return err instanceof GateDeniedError;
579
+ }
580
+ var Gate = class {
581
+ loader;
582
+ localConsumption;
583
+ graceWindowMs;
584
+ now;
585
+ inflight = null;
586
+ constructor(opts) {
587
+ if (!opts.loader) throw new Error("billing: Gate requires loader");
588
+ this.loader = opts.loader;
589
+ this.localConsumption = opts.localConsumption ?? (() => 0);
590
+ this.graceWindowMs = opts.graceWindowMs ?? 0;
591
+ this.now = opts.now ?? (() => /* @__PURE__ */ new Date());
592
+ }
593
+ async check(feature) {
594
+ const prev = this.inflight;
595
+ const run = (async () => {
596
+ if (prev) {
597
+ try {
598
+ await prev;
599
+ } catch {
600
+ }
601
+ }
602
+ return this.evaluate(feature);
603
+ })();
604
+ this.inflight = run.catch(() => ({}));
605
+ return run;
606
+ }
607
+ async require(feature) {
608
+ const access = await this.check(feature);
609
+ if (!access.allowed) throw new GateDeniedError(access);
610
+ return access;
611
+ }
612
+ async evaluate(feature) {
613
+ const access = {
614
+ feature,
615
+ allowed: false,
616
+ hasFeature: false,
617
+ unlimited: false,
618
+ remaining: 0,
619
+ reason: "",
620
+ plan: "",
621
+ state: "none"
622
+ };
623
+ let loaded;
624
+ try {
625
+ loaded = await this.loader();
626
+ } catch (err) {
627
+ access.reason = "verify_failed";
628
+ throw Object.assign(err instanceof Error ? err : new Error(String(err)), { access });
629
+ }
630
+ if (!loaded) {
631
+ access.reason = "no_license";
632
+ return access;
633
+ }
634
+ const { payload } = loaded;
635
+ access.plan = payload.plan_key;
636
+ access.state = computeState(payload, this.graceWindowMs, this.now());
637
+ if (access.state === "expired" || access.state === "invalid") {
638
+ access.reason = `license_${access.state}`;
639
+ return access;
640
+ }
641
+ const featureFlag = payload.features?.[feature];
642
+ if (featureFlag !== void 0) {
643
+ access.hasFeature = featureFlag;
644
+ if (!featureFlag) {
645
+ access.reason = "feature_disabled";
646
+ return access;
647
+ }
648
+ }
649
+ let consumed;
650
+ try {
651
+ consumed = await this.localConsumption(feature);
652
+ } catch (err) {
653
+ access.reason = "local_consumption_failed";
654
+ throw Object.assign(err instanceof Error ? err : new Error(String(err)), { access });
655
+ }
656
+ const remaining = computeRemaining(payload, feature, consumed);
657
+ if (remaining === null) {
658
+ if (access.hasFeature) {
659
+ access.allowed = true;
660
+ access.unlimited = true;
661
+ return access;
662
+ }
663
+ access.reason = "feature_missing";
664
+ return access;
665
+ }
666
+ if (remaining === Number.POSITIVE_INFINITY) {
667
+ access.unlimited = true;
668
+ access.hasFeature = true;
669
+ access.allowed = true;
670
+ return access;
671
+ }
672
+ access.remaining = remaining;
673
+ if (remaining > 0) {
674
+ access.allowed = true;
675
+ access.hasFeature = true;
676
+ return access;
677
+ }
678
+ access.reason = "limit_reached";
679
+ return access;
680
+ }
681
+ };
682
+
683
+ // src/usage.ts
684
+ var MemoryBuffer = class {
685
+ state = {};
686
+ add(feature, delta) {
687
+ if (delta === 0) return;
688
+ this.state[feature] = (this.state[feature] ?? 0) + delta;
689
+ }
690
+ drain() {
691
+ const out = this.state;
692
+ this.state = {};
693
+ return out;
694
+ }
695
+ restore(deltas) {
696
+ for (const [k, v] of Object.entries(deltas)) {
697
+ this.state[k] = (this.state[k] ?? 0) + v;
698
+ }
699
+ }
700
+ };
701
+ var DEFAULT_FLUSH_INTERVAL_MS = 5 * 60 * 1e3;
702
+ var UsageTracker = class {
703
+ buffer;
704
+ sync;
705
+ serial;
706
+ onRefresh;
707
+ flushIntervalMs;
708
+ timer = null;
709
+ running = false;
710
+ constructor(opts) {
711
+ if (!opts.buffer) throw new Error("billing: tracker requires buffer");
712
+ if (!opts.sync) throw new Error("billing: tracker requires sync");
713
+ this.buffer = opts.buffer;
714
+ this.sync = opts.sync;
715
+ if (opts.serial !== void 0) this.serial = opts.serial;
716
+ if (opts.onRefresh !== void 0) this.onRefresh = opts.onRefresh;
717
+ this.flushIntervalMs = opts.flushIntervalMs && opts.flushIntervalMs > 0 ? opts.flushIntervalMs : DEFAULT_FLUSH_INTERVAL_MS;
718
+ }
719
+ async track(feature, delta) {
720
+ if (delta === 0) return;
721
+ await this.buffer.add(feature, delta);
722
+ }
723
+ async flush() {
724
+ const deltas = await this.buffer.drain();
725
+ if (!deltas || Object.keys(deltas).length === 0) return;
726
+ let serial = 0;
727
+ if (this.serial) {
728
+ try {
729
+ serial = await this.serial();
730
+ } catch (err) {
731
+ await this.buffer.restore(deltas);
732
+ throw err;
733
+ }
734
+ }
735
+ let resp;
736
+ try {
737
+ resp = await this.sync(deltas, serial);
738
+ } catch (err) {
739
+ await this.buffer.restore(deltas);
740
+ throw err;
741
+ }
742
+ if (this.onRefresh && resp) {
743
+ await this.onRefresh(resp);
744
+ }
745
+ }
746
+ start() {
747
+ if (this.running) return;
748
+ this.running = true;
749
+ this.timer = setInterval(() => {
750
+ void this.flush().catch(() => {
751
+ });
752
+ }, this.flushIntervalMs);
753
+ }
754
+ async stop() {
755
+ if (!this.running) return;
756
+ this.running = false;
757
+ if (this.timer) {
758
+ clearInterval(this.timer);
759
+ this.timer = null;
760
+ }
761
+ await this.flush();
762
+ }
763
+ };
764
+
539
765
  exports.BillingApiError = BillingApiError;
540
766
  exports.BillingClient = BillingClient;
767
+ exports.Gate = Gate;
768
+ exports.GateDeniedError = GateDeniedError;
541
769
  exports.HEADER_NONCE = HEADER_NONCE;
542
770
  exports.HEADER_PRODUCT = HEADER_PRODUCT;
543
771
  exports.HEADER_SIGNATURE = HEADER_SIGNATURE;
544
772
  exports.HEADER_TIMESTAMP = HEADER_TIMESTAMP;
773
+ exports.MemoryBuffer = MemoryBuffer;
774
+ exports.UsageTracker = UsageTracker;
545
775
  exports.buildOauthInitUrl = buildOauthInitUrl;
546
776
  exports.canUseUpdate = canUseUpdate;
547
777
  exports.canonical = canonical;
548
778
  exports.checkoutUrl = checkoutUrl;
549
779
  exports.computeRemaining = computeRemaining;
780
+ exports.computeState = computeState;
550
781
  exports.decodeLicense = decodeLicense;
551
782
  exports.defaultInterval = defaultInterval;
552
783
  exports.downloadUrl = downloadUrl;
@@ -559,6 +790,7 @@ exports.getCtaProps = getCtaProps;
559
790
  exports.hasYearly = hasYearly;
560
791
  exports.isExpired = isExpired;
561
792
  exports.isFreeTier = isFreeTier;
793
+ exports.isGateDenied = isGateDenied;
562
794
  exports.isInGrace = isInGrace;
563
795
  exports.isOneTimeTier = isOneTimeTier;
564
796
  exports.isUnlimited = isUnlimited;
@@ -567,6 +799,7 @@ exports.newNonce = newNonce;
567
799
  exports.periodResetAt = periodResetAt;
568
800
  exports.sendCompletionBeacon = sendCompletionBeacon;
569
801
  exports.sign = sign;
802
+ exports.trialDaysLeft = trialDaysLeft;
570
803
  exports.triggerDownload = triggerDownload;
571
804
  exports.verifyLicense = verifyLicense;
572
805
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/signature.ts","../src/client.ts","../src/pricing.ts","../src/checkout.ts","../src/downloads.ts","../src/helpers.ts","../src/license.ts","../src/oauth.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export const HEADER_PRODUCT = 'X-Akira-Product';\nexport const HEADER_TIMESTAMP = 'X-Akira-Timestamp';\nexport const HEADER_NONCE = 'X-Akira-Nonce';\nexport const HEADER_SIGNATURE = 'X-Akira-Signature';\n\nasync function sha256Hex(bytes: Uint8Array): Promise<string> {\n const digest = await getSubtle().digest('SHA-256', bytes as BufferSource);\n return bufferToHex(new Uint8Array(digest));\n}\n\nfunction getSubtle(): SubtleCrypto {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new Error('Web Crypto SubtleCrypto API is not available in this runtime.');\n }\n return subtle;\n}\n\nfunction bufferToHex(buffer: Uint8Array): string {\n let out = '';\n for (const byte of buffer) {\n out += byte.toString(16).padStart(2, '0');\n }\n return out;\n}\n\nexport function newNonce(): string {\n const buf = new Uint8Array(16);\n if (globalThis.crypto?.getRandomValues) {\n globalThis.crypto.getRandomValues(buf);\n } else {\n for (let i = 0; i < buf.length; i += 1) {\n buf[i] = Math.floor(Math.random() * 256);\n }\n }\n return bufferToHex(buf);\n}\n\nexport async function canonical(\n productSlug: string,\n timestamp: number,\n nonce: string,\n method: string,\n path: string,\n body: Uint8Array,\n): Promise<string> {\n const bodyHash = await sha256Hex(body);\n return `${productSlug}\\n${timestamp}\\n${nonce}\\n${method.toUpperCase()}\\n${path}\\n${bodyHash}`;\n}\n\nexport async function sign(productSecret: string, canonicalString: string): Promise<string> {\n const subtle = getSubtle();\n const keyData = new TextEncoder().encode(productSecret) as BufferSource;\n const key = await subtle.importKey(\n 'raw',\n keyData,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const sig = await subtle.sign('HMAC', key, new TextEncoder().encode(canonicalString) as BufferSource);\n return bufferToHex(new Uint8Array(sig));\n}\n","import {\n HEADER_NONCE,\n HEADER_PRODUCT,\n HEADER_SIGNATURE,\n HEADER_TIMESTAMP,\n canonical,\n newNonce,\n sign,\n} from './signature';\nimport type {\n BillingPortalResponse,\n Customer,\n EntitlementsResponse,\n LicenseActivatePayload,\n LicenseActivateResponse,\n LicenseCheckPayload,\n LicenseCheckResponse,\n LicensePublicKeysResponse,\n LicenseRefreshPayload,\n LicenseSyncUsagePayload,\n LicenseSyncUsageResponse,\n GithubAppInfo,\n GithubInstallationTokenPayload,\n GithubInstallationTokenResponse,\n GithubUserInstallationsResponse,\n OauthExchangePayload,\n OauthExchangeResponse,\n OauthProvidersResponse,\n OtpRequestPayload,\n OtpVerifyPayload,\n OtpVerifyResponse,\n UsagePayload,\n UsageResponse,\n} from './client-types';\n\nexport interface BillingClientConfig {\n baseUrl: string;\n productSlug: string;\n productSecret: string;\n customerToken?: string;\n fetcher?: typeof fetch;\n}\n\nexport class BillingApiError extends Error {\n status: number;\n code: string;\n constructor(status: number, code: string) {\n super(`billing api ${status}: ${code}`);\n this.status = status;\n this.code = code;\n }\n}\n\nexport class BillingClient {\n private readonly baseUrl: string;\n private readonly productSlug: string;\n private readonly productSecret: string;\n private customerToken: string | undefined;\n private readonly fetcher: typeof fetch;\n\n constructor(config: BillingClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.productSlug = config.productSlug;\n this.productSecret = config.productSecret;\n this.customerToken = config.customerToken;\n this.fetcher = config.fetcher ?? globalThis.fetch;\n if (!this.fetcher) {\n throw new Error('No fetch implementation available. Pass `fetcher` or use a runtime with global fetch.');\n }\n }\n\n setCustomerToken(token: string): void {\n this.customerToken = token;\n }\n\n async requestOtp(payload: OtpRequestPayload): Promise<void> {\n await this.signed('POST', '/api/auth/customer/otp/request', payload);\n }\n\n async verifyOtp(payload: OtpVerifyPayload): Promise<OtpVerifyResponse> {\n const res = await this.signed<OtpVerifyResponse>('POST', '/api/auth/customer/otp/verify', payload);\n this.setCustomerToken(res.access_token);\n return res;\n }\n\n async customerMe(): Promise<Customer> {\n return this.signed<Customer>('GET', '/api/me');\n }\n\n async licenseCheck(payload: LicenseCheckPayload): Promise<LicenseCheckResponse> {\n return this.signed<LicenseCheckResponse>('POST', '/api/licenses/check', payload);\n }\n\n async licenseActivate(payload: LicenseActivatePayload): Promise<LicenseActivateResponse> {\n return this.signed<LicenseActivateResponse>('POST', '/api/licenses/activate', payload);\n }\n\n async licenseRefresh(payload: LicenseRefreshPayload): Promise<LicenseActivateResponse> {\n return this.signed<LicenseActivateResponse>('POST', '/api/licenses/refresh', payload);\n }\n\n async licenseSyncUsage(payload: LicenseSyncUsagePayload): Promise<LicenseSyncUsageResponse> {\n return this.signed<LicenseSyncUsageResponse>('POST', '/api/licenses/sync-usage', payload);\n }\n\n async listOauthProviders(product: string): Promise<OauthProvidersResponse> {\n return this.signed<OauthProvidersResponse>('GET', `/api/v1/products/${encodeURIComponent(product)}/auth/providers`);\n }\n\n async exchangeOauthCode(payload: OauthExchangePayload): Promise<OauthExchangeResponse> {\n const res = await this.signed<OauthExchangeResponse>('POST', '/api/auth/oauth/exchange', payload);\n this.setCustomerToken(res.access_token);\n return res;\n }\n\n async githubInstallationToken(\n payload: GithubInstallationTokenPayload = {},\n ): Promise<GithubInstallationTokenResponse> {\n return this.signed<GithubInstallationTokenResponse>(\n 'POST',\n '/api/me/github/installation-token',\n payload,\n );\n }\n\n async meGithubInstallations(): Promise<GithubUserInstallationsResponse> {\n return this.signed<GithubUserInstallationsResponse>('GET', '/api/me/github/installations');\n }\n\n async entitlements(): Promise<EntitlementsResponse> {\n return this.signed<EntitlementsResponse>('GET', '/api/me/entitlements');\n }\n\n async billingPortal(returnUrl: string): Promise<BillingPortalResponse> {\n const path = `/api/billing/portal?return_url=${encodeURIComponent(returnUrl)}`;\n return this.signed<BillingPortalResponse>('GET', path);\n }\n\n async trackUsage(payload: UsagePayload): Promise<UsageResponse> {\n return this.signed<UsageResponse>('POST', '/api/me/usage', payload);\n }\n\n async trackAnonymousUsage(payload: UsagePayload): Promise<UsageResponse> {\n return this.signed<UsageResponse>('POST', '/api/v1/usage/anonymous', payload);\n }\n\n async publicLicenseKeys(): Promise<LicensePublicKeysResponse> {\n return this.unsigned<LicensePublicKeysResponse>('GET', '/api/v1/license-keys/public');\n }\n\n async githubAppInfo(): Promise<GithubAppInfo> {\n return this.unsigned<GithubAppInfo>('GET', '/api/v1/github/app');\n }\n\n private async signed<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const bodyBytes = body === undefined ? new Uint8Array() : new TextEncoder().encode(JSON.stringify(body));\n const timestamp = Math.floor(Date.now() / 1000);\n const nonce = newNonce();\n const canonicalString = await canonical(this.productSlug, timestamp, nonce, method, path, bodyBytes);\n const signature = await sign(this.productSecret, canonicalString);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n [HEADER_PRODUCT]: this.productSlug,\n [HEADER_TIMESTAMP]: String(timestamp),\n [HEADER_NONCE]: nonce,\n [HEADER_SIGNATURE]: signature,\n };\n if (bodyBytes.length > 0) headers['Content-Type'] = 'application/json';\n if (this.customerToken) headers.Authorization = `Bearer ${this.customerToken}`;\n\n const res = await this.fetcher(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: bodyBytes.length > 0 ? bodyBytes : undefined,\n });\n\n return this.parseResponse<T>(res);\n }\n\n private async unsigned<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const headers: Record<string, string> = { Accept: 'application/json' };\n let bodyInit: BodyInit | undefined;\n if (body !== undefined) {\n headers['Content-Type'] = 'application/json';\n bodyInit = JSON.stringify(body);\n }\n\n const res = await this.fetcher(`${this.baseUrl}${path}`, { method, headers, body: bodyInit });\n return this.parseResponse<T>(res);\n }\n\n private async parseResponse<T>(res: Response): Promise<T> {\n if (!res.ok) {\n let code: string;\n try {\n const parsed = (await res.json()) as { error?: string };\n code = parsed?.error ?? '';\n } catch {\n try {\n code = await res.text();\n } catch {\n code = '';\n }\n }\n throw new BillingApiError(res.status, code);\n }\n\n if (res.status === 204) {\n return undefined as T;\n }\n\n return (await res.json()) as T;\n }\n}\n","import type {\n BillingInterval,\n PricingFeature,\n PricingPayload,\n PricingTier,\n TierMeta,\n} from './types';\n\nexport type FetchPricingConfig = {\n baseUrl: string;\n productKey: string;\n tierMeta?: Record<string, TierMeta>;\n yearlyMonthsFree?: number;\n /** Override the global fetch (e.g. Node 18+ or custom retry). */\n fetcher?: typeof fetch;\n};\n\ntype ApiFeature = {\n key: string;\n name: string;\n description: string | null;\n};\n\ntype ApiPlan = {\n key: string;\n name: string;\n description: string | null;\n amount: number | null;\n currency: string | null;\n billing_interval: BillingInterval | null;\n trial_period_days: number;\n is_coming_soon?: boolean;\n features: ApiFeature[];\n};\n\ntype ApiPayload = {\n product: string;\n name: string;\n description: string | null;\n beta_active: boolean;\n plans: ApiPlan[];\n};\n\nconst INTERVAL_SUFFIXES = ['_monthly', '_yearly', '_month', '_year', '_one_time'];\n\nfunction tierKeyFromPlanKey(planKey: string): string {\n for (const suf of INTERVAL_SUFFIXES) {\n if (planKey.endsWith(suf)) {\n return planKey.slice(0, -suf.length);\n }\n }\n return planKey;\n}\n\nfunction titleCase(s: string): string {\n return s.replace(/[_-]+/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction emptyPayload(productKey: string): PricingPayload {\n return { product: productKey, betaActive: false, tiers: [] };\n}\n\nfunction shapeFromApi(payload: ApiPayload, config: FetchPricingConfig): PricingPayload {\n const meta = config.tierMeta ?? {};\n const monthsFree = config.yearlyMonthsFree ?? 2;\n const tiersMap = new Map<string, PricingTier>();\n\n for (const plan of payload.plans) {\n const tierKey = tierKeyFromPlanKey(plan.key);\n const m = meta[tierKey];\n\n if (!tiersMap.has(tierKey)) {\n tiersMap.set(tierKey, {\n key: tierKey,\n name: m?.label ?? titleCase(tierKey),\n tagline: m?.tagline ?? plan.description ?? '',\n highlighted: m?.highlighted ?? false,\n monthly: null,\n yearly: null,\n oneTime: null,\n isComingSoon: false,\n features: plan.features.map(\n (f): PricingFeature => ({ key: f.key, name: f.name, description: f.description }),\n ),\n });\n }\n\n const tier = tiersMap.get(tierKey)!;\n\n if (plan.is_coming_soon === true) {\n tier.isComingSoon = true;\n }\n\n if (tier.features.length === 0 && plan.features.length > 0) {\n tier.features = plan.features.map((f) => ({ key: f.key, name: f.name, description: f.description }));\n }\n\n if (plan.billing_interval === 'month' && plan.amount !== null && plan.currency !== null) {\n tier.monthly = { amount: plan.amount, currency: plan.currency, planKey: plan.key };\n continue;\n }\n\n if (plan.billing_interval === 'year' && plan.amount !== null && plan.currency !== null) {\n tier.yearly = { amount: plan.amount, currency: plan.currency, monthsFree, planKey: plan.key };\n continue;\n }\n\n if (plan.billing_interval === null) {\n const amount = plan.amount ?? 0;\n const currency = plan.currency ?? 'eur';\n if (amount === 0) {\n tier.monthly = { amount: 0, currency, planKey: plan.key };\n } else {\n tier.oneTime = { amount, currency, planKey: plan.key };\n }\n }\n }\n\n const tiers = Array.from(tiersMap.values()).sort((a, b) => {\n const oa = meta[a.key]?.order ?? 999;\n const ob = meta[b.key]?.order ?? 999;\n return oa - ob;\n });\n\n return {\n product: payload.product,\n betaActive: payload.beta_active,\n tiers,\n };\n}\n\nexport async function fetchPricing(config: FetchPricingConfig): Promise<PricingPayload> {\n const base = config.baseUrl?.replace(/\\/$/, '');\n if (!base) return emptyPayload(config.productKey);\n\n const f = config.fetcher ?? globalThis.fetch;\n if (!f) {\n throw new Error('No fetch implementation available. Pass a fetcher in config or use Node 18+.');\n }\n\n try {\n const res = await f(`${base}/api/v1/products/${config.productKey}/plans`, {\n headers: { Accept: 'application/json' },\n });\n if (!res.ok) return emptyPayload(config.productKey);\n const data = (await res.json()) as ApiPayload;\n return shapeFromApi(data, config);\n } catch {\n return emptyPayload(config.productKey);\n }\n}\n\nexport function formatPrice(amountInCents: number, currency: string): string {\n const symbol = currency.toLowerCase() === 'eur' ? '€' : currency.toUpperCase() + ' ';\n const major = (amountInCents / 100).toFixed(amountInCents % 100 === 0 ? 0 : 2);\n return `${symbol}${major}`;\n}\n\nexport type { PricingFeature, PricingPayload, PricingTier, TierMeta };\n","export function checkoutUrl(baseUrl: string, productKey: string, planKey: string): string {\n return `${baseUrl.replace(/\\/$/, '')}/subscribe/${productKey}/${planKey}`;\n}\n","import type { AssetPlatform, IssuedDownload, ReleaseChannel } from './types';\n\nexport type DownloadConfig = {\n baseUrl: string;\n product: string;\n channel: ReleaseChannel;\n platform: AssetPlatform;\n /** Optional UTM + landing tracking. */\n query?: Record<string, string | undefined>;\n /** Delay before firing the completion beacon, ms. Default 1500. */\n beaconDelayMs?: number;\n fetcher?: typeof fetch;\n};\n\nexport function downloadUrl(config: Pick<DownloadConfig, 'baseUrl' | 'product' | 'channel' | 'platform' | 'query'>): string {\n const base = config.baseUrl.replace(/\\/$/, '');\n const path = `/api/v1/downloads/${config.product}/${config.channel}/${config.platform}`;\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(config.query ?? {})) {\n if (v !== undefined && v !== '') params.set(k, v);\n }\n const qs = params.toString();\n return qs ? `${base}${path}?${qs}` : `${base}${path}`;\n}\n\n/**\n * Issues a download via the billing API and returns the signed asset URL +\n * beacon URL without redirecting. Useful when you want full control of the\n * UX (e.g. fetch then trigger your own `<a download>` flow).\n */\nexport async function issueDownload(config: DownloadConfig): Promise<IssuedDownload> {\n const f = config.fetcher ?? globalThis.fetch;\n if (!f) {\n throw new Error('No fetch implementation available. Pass a fetcher in config or use Node 18+.');\n }\n\n const url = downloadUrl(config);\n const res = await f(url, { headers: { Accept: 'application/json' } });\n\n if (!res.ok) {\n throw new Error(`download issue failed: HTTP ${res.status}`);\n }\n\n return (await res.json()) as IssuedDownload;\n}\n\n/**\n * Fires the completion beacon for an issued download. Uses\n * `navigator.sendBeacon` when available (survives page navigation), falls\n * back to `fetch` with `keepalive: true`. Safe to call at unload time.\n */\nexport function sendCompletionBeacon(beaconUrl: string): void {\n if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') {\n navigator.sendBeacon(beaconUrl);\n return;\n }\n\n if (typeof fetch !== 'undefined') {\n void fetch(beaconUrl, { method: 'POST', keepalive: true }).catch(() => {});\n }\n}\n\n/**\n * One-shot helper for landing-page download CTAs: fetches a signed URL,\n * navigates the current tab to the asset, then schedules the completion\n * beacon. The function resolves once the navigation has been triggered.\n */\nexport async function triggerDownload(config: DownloadConfig): Promise<IssuedDownload> {\n const issued = await issueDownload(config);\n const delay = config.beaconDelayMs ?? 1500;\n\n if (typeof window !== 'undefined') {\n window.location.href = issued.signedUrl;\n setTimeout(() => sendCompletionBeacon(issued.beaconUrl), delay);\n }\n\n return issued;\n}\n","import { checkoutUrl } from './checkout';\nimport { formatPrice } from './pricing';\nimport type { PricingTier, TierMeta } from './types';\n\nexport type IntervalKey = 'monthly' | 'yearly' | 'oneTime';\n\nexport type CtaProps = {\n label: string;\n href: string | null;\n disabled: boolean;\n monthlyHref: string | null;\n yearlyHref: string | null;\n oneTimeHref: string | null;\n};\n\nexport type CtaOptions = {\n billingBaseUrl: string;\n productKey: string;\n tierMeta?: TierMeta;\n interval?: IntervalKey;\n freeLabel?: string;\n subscribeLabel?: string;\n buyLabel?: string;\n comingSoonLabel?: string;\n};\n\nexport function isFreeTier(tier: PricingTier): boolean {\n return tier.monthly?.amount === 0 && tier.yearly === null && tier.oneTime === null;\n}\n\nexport function isOneTimeTier(tier: PricingTier): boolean {\n return tier.oneTime !== null && tier.monthly === null;\n}\n\nexport function hasYearly(tier: PricingTier): boolean {\n return tier.yearly !== null && tier.monthly !== null;\n}\n\n/**\n * Resolves all CTA fields for a tier — label, primary href, per-interval\n * hrefs (so a UI toggle can hot-swap without re-deriving), and disabled\n * state for coming-soon plans. Replaces hand-rolled if/else trees in\n * landing pages.\n */\nexport function getCtaProps(tier: PricingTier, opts: CtaOptions): CtaProps {\n const meta = opts.tierMeta;\n const monthlyHref = tier.monthly\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.monthly.planKey)\n : null;\n const yearlyHref = tier.yearly\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.yearly.planKey)\n : null;\n const oneTimeHref = tier.oneTime\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.oneTime.planKey)\n : null;\n\n if (tier.isComingSoon) {\n return {\n label: opts.comingSoonLabel ?? 'Coming soon',\n href: null,\n disabled: true,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n }\n\n if (meta?.ctaHref) {\n return {\n label: meta.ctaLabel ?? 'Get started',\n href: meta.ctaHref,\n disabled: false,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n }\n\n let primary: string | null;\n let defaultLabel: string;\n\n if (isFreeTier(tier)) {\n primary = null;\n defaultLabel = opts.freeLabel ?? 'Get started';\n } else if (isOneTimeTier(tier)) {\n primary = oneTimeHref;\n defaultLabel = opts.buyLabel ?? 'Buy';\n } else {\n primary = opts.interval === 'yearly' ? yearlyHref ?? monthlyHref : monthlyHref;\n defaultLabel = opts.subscribeLabel ?? 'Subscribe';\n }\n\n return {\n label: meta?.ctaLabel ?? defaultLabel,\n href: primary,\n disabled: false,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n}\n\nexport type FormattedPrice = {\n amount: string;\n suffix: string;\n raw: { amount: number; currency: string } | null;\n note?: string;\n};\n\n/**\n * Returns the price + suffix to render for a tier given the active\n * interval. Falls back gracefully: a tier with only monthly always\n * shows monthly; a free tier shows €0; a one-time tier shows the amount\n * with a 'one-time' suffix.\n */\nexport function getActivePrice(tier: PricingTier, interval: IntervalKey): FormattedPrice {\n if (interval === 'yearly' && tier.yearly) {\n return {\n amount: formatPrice(tier.yearly.amount, tier.yearly.currency),\n suffix: '/year',\n raw: { amount: tier.yearly.amount, currency: tier.yearly.currency },\n note: tier.yearly.monthsFree > 0 ? `${tier.yearly.monthsFree} months free` : undefined,\n };\n }\n\n if (interval === 'oneTime' && tier.oneTime) {\n return {\n amount: formatPrice(tier.oneTime.amount, tier.oneTime.currency),\n suffix: ' one-time',\n raw: { amount: tier.oneTime.amount, currency: tier.oneTime.currency },\n };\n }\n\n if (tier.monthly) {\n return {\n amount: formatPrice(tier.monthly.amount, tier.monthly.currency),\n suffix: '/month',\n raw: { amount: tier.monthly.amount, currency: tier.monthly.currency },\n };\n }\n\n if (tier.oneTime) {\n return {\n amount: formatPrice(tier.oneTime.amount, tier.oneTime.currency),\n suffix: ' one-time',\n raw: { amount: tier.oneTime.amount, currency: tier.oneTime.currency },\n };\n }\n\n return { amount: '—', suffix: '', raw: null };\n}\n\n/**\n * Picks the natural default interval for a list of tiers: 'yearly' if\n * any tier has a yearly option, else 'monthly'. Useful as the initial\n * state for a billing-interval toggle.\n */\nexport function defaultInterval(tiers: PricingTier[]): IntervalKey {\n if (tiers.some(hasYearly)) return 'monthly';\n if (tiers.every((t) => t.monthly === null && t.oneTime !== null)) return 'oneTime';\n return 'monthly';\n}\n","import type {\n LicenseSnapshotPayload,\n SignedLicense,\n UsageFeatureState,\n} from './client-types';\n\nexport interface DecodedLicense {\n raw: SignedLicense;\n payload: LicenseSnapshotPayload;\n}\n\nfunction base64Decode(input: string): Uint8Array<ArrayBuffer> {\n const bin = atob(input);\n const buf = new ArrayBuffer(bin.length);\n const out = new Uint8Array(buf);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nexport function decodeLicense(signed: SignedLicense): DecodedLicense {\n const payloadJson = new TextDecoder().decode(base64Decode(signed.payload));\n const payload = JSON.parse(payloadJson) as LicenseSnapshotPayload;\n return { raw: signed, payload };\n}\n\nexport async function verifyLicense(signed: SignedLicense, publicKeyBase64: string): Promise<boolean> {\n if (signed.algorithm !== 'ed25519') return false;\n\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('crypto.subtle not available; cannot verify license');\n\n const payloadBytes = base64Decode(signed.payload);\n const signatureBytes = base64Decode(signed.signature);\n const publicKeyBytes = base64Decode(publicKeyBase64);\n\n const key = await subtle.importKey(\n 'raw',\n publicKeyBytes,\n { name: 'Ed25519' } as AlgorithmIdentifier,\n false,\n ['verify'],\n );\n\n return subtle.verify({ name: 'Ed25519' } as AlgorithmIdentifier, key, signatureBytes, payloadBytes);\n}\n\nexport function computeRemaining(\n payload: LicenseSnapshotPayload,\n feature: string,\n consumedLocal = 0,\n): number | null {\n const state = payload.usage?.[feature];\n if (!state) return null;\n if (state.type === 'bool') return state.enabled ? Number.POSITIVE_INFINITY : 0;\n return Math.max(0, state.allowance - state.consumed_at_issue - consumedLocal);\n}\n\nexport function isUnlimited(state: UsageFeatureState | undefined): boolean {\n if (!state) return false;\n if (state.type === 'bool') return state.enabled;\n return state.allowance === 0;\n}\n\nexport function isExpired(payload: LicenseSnapshotPayload, now: Date = new Date()): boolean {\n return new Date(payload.valid_until).getTime() < now.getTime();\n}\n\nexport function isInGrace(\n payload: LicenseSnapshotPayload,\n graceSeconds: number,\n now: Date = new Date(),\n): boolean {\n const expiry = new Date(payload.valid_until).getTime();\n return now.getTime() <= expiry + graceSeconds * 1000;\n}\n\nexport function canUseUpdate(payload: LicenseSnapshotPayload, releaseDate: string | Date): boolean {\n const release = releaseDate instanceof Date ? releaseDate : new Date(releaseDate);\n\n const paidUpMs = payload.paid_up_until ? new Date(payload.paid_up_until).getTime() : null;\n const fallbackMs = payload.fallback_release_date\n ? new Date(payload.fallback_release_date).getTime()\n : null;\n\n if (paidUpMs === null && fallbackMs === null) return true;\n\n const effective = Math.max(paidUpMs ?? -Infinity, fallbackMs ?? -Infinity);\n const windowMs = (payload.updates_window_days ?? 0) * 86_400_000;\n return release.getTime() <= effective + windowMs;\n}\n\nexport function periodResetAt(payload: LicenseSnapshotPayload, feature: string): Date | null {\n const state = payload.usage?.[feature];\n if (!state || state.type !== 'counter') return null;\n return new Date(state.period_end);\n}\n","import type { BuildOauthInitUrlOptions, PkceChallenge } from './client-types';\n\nfunction bytesToUrlSafeBase64(bytes: Uint8Array): string {\n let bin = '';\n for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i] as number);\n return btoa(bin).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nfunction randomBytes(length: number): Uint8Array {\n const buf = new Uint8Array(length);\n globalThis.crypto.getRandomValues(buf);\n return buf;\n}\n\nexport async function generatePkceChallenge(): Promise<PkceChallenge> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('crypto.subtle not available; cannot generate PKCE challenge');\n\n const verifier = bytesToUrlSafeBase64(randomBytes(48));\n const hash = await subtle.digest('SHA-256', new TextEncoder().encode(verifier));\n const challenge = bytesToUrlSafeBase64(new Uint8Array(hash));\n\n return { verifier, challenge, method: 'S256' };\n}\n\nexport function generateOauthState(): string {\n return bytesToUrlSafeBase64(randomBytes(24));\n}\n\nexport function buildOauthInitUrl(opts: BuildOauthInitUrlOptions): string {\n const base = opts.baseUrl.replace(/\\/$/, '');\n const params = new URLSearchParams({\n product: opts.product,\n redirect_uri: opts.redirectUri,\n code_challenge: opts.codeChallenge,\n code_challenge_method: opts.codeChallengeMethod ?? 'S256',\n });\n if (opts.state) params.set('state', opts.state);\n\n return `${base}/auth/${opts.provider}?${params.toString()}`;\n}\n"]}
1
+ {"version":3,"sources":["../src/signature.ts","../src/client.ts","../src/pricing.ts","../src/checkout.ts","../src/downloads.ts","../src/helpers.ts","../src/license.ts","../src/oauth.ts","../src/lifecycle.ts","../src/gate.ts","../src/usage.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export const HEADER_PRODUCT = 'X-Akira-Product';\nexport const HEADER_TIMESTAMP = 'X-Akira-Timestamp';\nexport const HEADER_NONCE = 'X-Akira-Nonce';\nexport const HEADER_SIGNATURE = 'X-Akira-Signature';\n\nasync function sha256Hex(bytes: Uint8Array): Promise<string> {\n const digest = await getSubtle().digest('SHA-256', bytes as BufferSource);\n return bufferToHex(new Uint8Array(digest));\n}\n\nfunction getSubtle(): SubtleCrypto {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new Error('Web Crypto SubtleCrypto API is not available in this runtime.');\n }\n return subtle;\n}\n\nfunction bufferToHex(buffer: Uint8Array): string {\n let out = '';\n for (const byte of buffer) {\n out += byte.toString(16).padStart(2, '0');\n }\n return out;\n}\n\nexport function newNonce(): string {\n const buf = new Uint8Array(16);\n if (globalThis.crypto?.getRandomValues) {\n globalThis.crypto.getRandomValues(buf);\n } else {\n for (let i = 0; i < buf.length; i += 1) {\n buf[i] = Math.floor(Math.random() * 256);\n }\n }\n return bufferToHex(buf);\n}\n\nexport async function canonical(\n productSlug: string,\n timestamp: number,\n nonce: string,\n method: string,\n path: string,\n body: Uint8Array,\n): Promise<string> {\n const bodyHash = await sha256Hex(body);\n return `${productSlug}\\n${timestamp}\\n${nonce}\\n${method.toUpperCase()}\\n${path}\\n${bodyHash}`;\n}\n\nexport async function sign(productSecret: string, canonicalString: string): Promise<string> {\n const subtle = getSubtle();\n const keyData = new TextEncoder().encode(productSecret) as BufferSource;\n const key = await subtle.importKey(\n 'raw',\n keyData,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const sig = await subtle.sign('HMAC', key, new TextEncoder().encode(canonicalString) as BufferSource);\n return bufferToHex(new Uint8Array(sig));\n}\n","import {\n HEADER_NONCE,\n HEADER_PRODUCT,\n HEADER_SIGNATURE,\n HEADER_TIMESTAMP,\n canonical,\n newNonce,\n sign,\n} from './signature';\nimport type {\n BillingPortalResponse,\n Customer,\n EntitlementsResponse,\n LicenseActivatePayload,\n LicenseActivateResponse,\n LicenseCheckPayload,\n LicenseCheckResponse,\n LicensePublicKeysResponse,\n LicenseRefreshPayload,\n LicenseSyncUsagePayload,\n LicenseSyncUsageResponse,\n GithubAppInfo,\n GithubInstallationTokenPayload,\n GithubInstallationTokenResponse,\n GithubUserInstallationsResponse,\n OauthExchangePayload,\n OauthExchangeResponse,\n OauthProvidersResponse,\n OtpRequestPayload,\n OtpVerifyPayload,\n OtpVerifyResponse,\n UsagePayload,\n UsageResponse,\n} from './client-types';\n\nexport interface BillingClientConfig {\n baseUrl: string;\n productSlug: string;\n productSecret: string;\n customerToken?: string;\n fetcher?: typeof fetch;\n}\n\nexport class BillingApiError extends Error {\n status: number;\n code: string;\n constructor(status: number, code: string) {\n super(`billing api ${status}: ${code}`);\n this.status = status;\n this.code = code;\n }\n}\n\nexport class BillingClient {\n private readonly baseUrl: string;\n private readonly productSlug: string;\n private readonly productSecret: string;\n private customerToken: string | undefined;\n private readonly fetcher: typeof fetch;\n\n constructor(config: BillingClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.productSlug = config.productSlug;\n this.productSecret = config.productSecret;\n this.customerToken = config.customerToken;\n this.fetcher = config.fetcher ?? globalThis.fetch;\n if (!this.fetcher) {\n throw new Error('No fetch implementation available. Pass `fetcher` or use a runtime with global fetch.');\n }\n }\n\n setCustomerToken(token: string): void {\n this.customerToken = token;\n }\n\n async requestOtp(payload: OtpRequestPayload): Promise<void> {\n await this.signed('POST', '/api/auth/customer/otp/request', payload);\n }\n\n async verifyOtp(payload: OtpVerifyPayload): Promise<OtpVerifyResponse> {\n const res = await this.signed<OtpVerifyResponse>('POST', '/api/auth/customer/otp/verify', payload);\n this.setCustomerToken(res.access_token);\n return res;\n }\n\n async customerMe(): Promise<Customer> {\n return this.signed<Customer>('GET', '/api/me');\n }\n\n async licenseCheck(payload: LicenseCheckPayload): Promise<LicenseCheckResponse> {\n return this.signed<LicenseCheckResponse>('POST', '/api/licenses/check', payload);\n }\n\n async licenseActivate(payload: LicenseActivatePayload): Promise<LicenseActivateResponse> {\n return this.signed<LicenseActivateResponse>('POST', '/api/licenses/activate', payload);\n }\n\n async licenseRefresh(payload: LicenseRefreshPayload): Promise<LicenseActivateResponse> {\n return this.signed<LicenseActivateResponse>('POST', '/api/licenses/refresh', payload);\n }\n\n async licenseSyncUsage(payload: LicenseSyncUsagePayload): Promise<LicenseSyncUsageResponse> {\n return this.signed<LicenseSyncUsageResponse>('POST', '/api/licenses/sync-usage', payload);\n }\n\n async listOauthProviders(product: string): Promise<OauthProvidersResponse> {\n return this.signed<OauthProvidersResponse>('GET', `/api/v1/products/${encodeURIComponent(product)}/auth/providers`);\n }\n\n async exchangeOauthCode(payload: OauthExchangePayload): Promise<OauthExchangeResponse> {\n const res = await this.signed<OauthExchangeResponse>('POST', '/api/auth/oauth/exchange', payload);\n this.setCustomerToken(res.access_token);\n return res;\n }\n\n async githubInstallationToken(\n payload: GithubInstallationTokenPayload = {},\n ): Promise<GithubInstallationTokenResponse> {\n return this.signed<GithubInstallationTokenResponse>(\n 'POST',\n '/api/me/github/installation-token',\n payload,\n );\n }\n\n async meGithubInstallations(): Promise<GithubUserInstallationsResponse> {\n return this.signed<GithubUserInstallationsResponse>('GET', '/api/me/github/installations');\n }\n\n async entitlements(): Promise<EntitlementsResponse> {\n return this.signed<EntitlementsResponse>('GET', '/api/me/entitlements');\n }\n\n async billingPortal(returnUrl: string): Promise<BillingPortalResponse> {\n const path = `/api/billing/portal?return_url=${encodeURIComponent(returnUrl)}`;\n return this.signed<BillingPortalResponse>('GET', path);\n }\n\n async trackUsage(payload: UsagePayload): Promise<UsageResponse> {\n return this.signed<UsageResponse>('POST', '/api/me/usage', payload);\n }\n\n async trackAnonymousUsage(payload: UsagePayload): Promise<UsageResponse> {\n return this.signed<UsageResponse>('POST', '/api/v1/usage/anonymous', payload);\n }\n\n async publicLicenseKeys(): Promise<LicensePublicKeysResponse> {\n return this.unsigned<LicensePublicKeysResponse>('GET', '/api/v1/license-keys/public');\n }\n\n async githubAppInfo(): Promise<GithubAppInfo> {\n return this.unsigned<GithubAppInfo>('GET', '/api/v1/github/app');\n }\n\n private async signed<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const bodyBytes = body === undefined ? new Uint8Array() : new TextEncoder().encode(JSON.stringify(body));\n const timestamp = Math.floor(Date.now() / 1000);\n const nonce = newNonce();\n const canonicalString = await canonical(this.productSlug, timestamp, nonce, method, path, bodyBytes);\n const signature = await sign(this.productSecret, canonicalString);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n [HEADER_PRODUCT]: this.productSlug,\n [HEADER_TIMESTAMP]: String(timestamp),\n [HEADER_NONCE]: nonce,\n [HEADER_SIGNATURE]: signature,\n };\n if (bodyBytes.length > 0) headers['Content-Type'] = 'application/json';\n if (this.customerToken) headers.Authorization = `Bearer ${this.customerToken}`;\n\n const res = await this.fetcher(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: bodyBytes.length > 0 ? bodyBytes : undefined,\n });\n\n return this.parseResponse<T>(res);\n }\n\n private async unsigned<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const headers: Record<string, string> = { Accept: 'application/json' };\n let bodyInit: BodyInit | undefined;\n if (body !== undefined) {\n headers['Content-Type'] = 'application/json';\n bodyInit = JSON.stringify(body);\n }\n\n const res = await this.fetcher(`${this.baseUrl}${path}`, { method, headers, body: bodyInit });\n return this.parseResponse<T>(res);\n }\n\n private async parseResponse<T>(res: Response): Promise<T> {\n if (!res.ok) {\n let code: string;\n try {\n const parsed = (await res.json()) as { error?: string };\n code = parsed?.error ?? '';\n } catch {\n try {\n code = await res.text();\n } catch {\n code = '';\n }\n }\n throw new BillingApiError(res.status, code);\n }\n\n if (res.status === 204) {\n return undefined as T;\n }\n\n return (await res.json()) as T;\n }\n}\n","import type {\n BillingInterval,\n PricingFeature,\n PricingPayload,\n PricingTier,\n TierMeta,\n} from './types';\n\nexport type FetchPricingConfig = {\n baseUrl: string;\n productKey: string;\n tierMeta?: Record<string, TierMeta>;\n yearlyMonthsFree?: number;\n /** Override the global fetch (e.g. Node 18+ or custom retry). */\n fetcher?: typeof fetch;\n};\n\ntype ApiFeature = {\n key: string;\n name: string;\n description: string | null;\n};\n\ntype ApiPlan = {\n key: string;\n name: string;\n description: string | null;\n amount: number | null;\n currency: string | null;\n billing_interval: BillingInterval | null;\n trial_period_days: number;\n is_coming_soon?: boolean;\n features: ApiFeature[];\n};\n\ntype ApiPayload = {\n product: string;\n name: string;\n description: string | null;\n beta_active: boolean;\n plans: ApiPlan[];\n};\n\nconst INTERVAL_SUFFIXES = ['_monthly', '_yearly', '_month', '_year', '_one_time'];\n\nfunction tierKeyFromPlanKey(planKey: string): string {\n for (const suf of INTERVAL_SUFFIXES) {\n if (planKey.endsWith(suf)) {\n return planKey.slice(0, -suf.length);\n }\n }\n return planKey;\n}\n\nfunction titleCase(s: string): string {\n return s.replace(/[_-]+/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction emptyPayload(productKey: string): PricingPayload {\n return { product: productKey, betaActive: false, tiers: [] };\n}\n\nfunction shapeFromApi(payload: ApiPayload, config: FetchPricingConfig): PricingPayload {\n const meta = config.tierMeta ?? {};\n const monthsFree = config.yearlyMonthsFree ?? 2;\n const tiersMap = new Map<string, PricingTier>();\n\n for (const plan of payload.plans) {\n const tierKey = tierKeyFromPlanKey(plan.key);\n const m = meta[tierKey];\n\n if (!tiersMap.has(tierKey)) {\n tiersMap.set(tierKey, {\n key: tierKey,\n name: m?.label ?? titleCase(tierKey),\n tagline: m?.tagline ?? plan.description ?? '',\n highlighted: m?.highlighted ?? false,\n monthly: null,\n yearly: null,\n oneTime: null,\n isComingSoon: false,\n features: plan.features.map(\n (f): PricingFeature => ({ key: f.key, name: f.name, description: f.description }),\n ),\n });\n }\n\n const tier = tiersMap.get(tierKey)!;\n\n if (plan.is_coming_soon === true) {\n tier.isComingSoon = true;\n }\n\n if (tier.features.length === 0 && plan.features.length > 0) {\n tier.features = plan.features.map((f) => ({ key: f.key, name: f.name, description: f.description }));\n }\n\n if (plan.billing_interval === 'month' && plan.amount !== null && plan.currency !== null) {\n tier.monthly = { amount: plan.amount, currency: plan.currency, planKey: plan.key };\n continue;\n }\n\n if (plan.billing_interval === 'year' && plan.amount !== null && plan.currency !== null) {\n tier.yearly = { amount: plan.amount, currency: plan.currency, monthsFree, planKey: plan.key };\n continue;\n }\n\n if (plan.billing_interval === null) {\n const amount = plan.amount ?? 0;\n const currency = plan.currency ?? 'eur';\n if (amount === 0) {\n tier.monthly = { amount: 0, currency, planKey: plan.key };\n } else {\n tier.oneTime = { amount, currency, planKey: plan.key };\n }\n }\n }\n\n const tiers = Array.from(tiersMap.values()).sort((a, b) => {\n const oa = meta[a.key]?.order ?? 999;\n const ob = meta[b.key]?.order ?? 999;\n return oa - ob;\n });\n\n return {\n product: payload.product,\n betaActive: payload.beta_active,\n tiers,\n };\n}\n\nexport async function fetchPricing(config: FetchPricingConfig): Promise<PricingPayload> {\n const base = config.baseUrl?.replace(/\\/$/, '');\n if (!base) return emptyPayload(config.productKey);\n\n const f = config.fetcher ?? globalThis.fetch;\n if (!f) {\n throw new Error('No fetch implementation available. Pass a fetcher in config or use Node 18+.');\n }\n\n try {\n const res = await f(`${base}/api/v1/products/${config.productKey}/plans`, {\n headers: { Accept: 'application/json' },\n });\n if (!res.ok) return emptyPayload(config.productKey);\n const data = (await res.json()) as ApiPayload;\n return shapeFromApi(data, config);\n } catch {\n return emptyPayload(config.productKey);\n }\n}\n\nexport function formatPrice(amountInCents: number, currency: string): string {\n const symbol = currency.toLowerCase() === 'eur' ? '€' : currency.toUpperCase() + ' ';\n const major = (amountInCents / 100).toFixed(amountInCents % 100 === 0 ? 0 : 2);\n return `${symbol}${major}`;\n}\n\nexport type { PricingFeature, PricingPayload, PricingTier, TierMeta };\n","export function checkoutUrl(baseUrl: string, productKey: string, planKey: string): string {\n return `${baseUrl.replace(/\\/$/, '')}/subscribe/${productKey}/${planKey}`;\n}\n","import type { AssetPlatform, IssuedDownload, ReleaseChannel } from './types';\n\nexport type DownloadConfig = {\n baseUrl: string;\n product: string;\n channel: ReleaseChannel;\n platform: AssetPlatform;\n /** Optional UTM + landing tracking. */\n query?: Record<string, string | undefined>;\n /** Delay before firing the completion beacon, ms. Default 1500. */\n beaconDelayMs?: number;\n fetcher?: typeof fetch;\n};\n\nexport function downloadUrl(config: Pick<DownloadConfig, 'baseUrl' | 'product' | 'channel' | 'platform' | 'query'>): string {\n const base = config.baseUrl.replace(/\\/$/, '');\n const path = `/api/v1/downloads/${config.product}/${config.channel}/${config.platform}`;\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(config.query ?? {})) {\n if (v !== undefined && v !== '') params.set(k, v);\n }\n const qs = params.toString();\n return qs ? `${base}${path}?${qs}` : `${base}${path}`;\n}\n\n/**\n * Issues a download via the billing API and returns the signed asset URL +\n * beacon URL without redirecting. Useful when you want full control of the\n * UX (e.g. fetch then trigger your own `<a download>` flow).\n */\nexport async function issueDownload(config: DownloadConfig): Promise<IssuedDownload> {\n const f = config.fetcher ?? globalThis.fetch;\n if (!f) {\n throw new Error('No fetch implementation available. Pass a fetcher in config or use Node 18+.');\n }\n\n const url = downloadUrl(config);\n const res = await f(url, { headers: { Accept: 'application/json' } });\n\n if (!res.ok) {\n throw new Error(`download issue failed: HTTP ${res.status}`);\n }\n\n return (await res.json()) as IssuedDownload;\n}\n\n/**\n * Fires the completion beacon for an issued download. Uses\n * `navigator.sendBeacon` when available (survives page navigation), falls\n * back to `fetch` with `keepalive: true`. Safe to call at unload time.\n */\nexport function sendCompletionBeacon(beaconUrl: string): void {\n if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') {\n navigator.sendBeacon(beaconUrl);\n return;\n }\n\n if (typeof fetch !== 'undefined') {\n void fetch(beaconUrl, { method: 'POST', keepalive: true }).catch(() => {});\n }\n}\n\n/**\n * One-shot helper for landing-page download CTAs: fetches a signed URL,\n * navigates the current tab to the asset, then schedules the completion\n * beacon. The function resolves once the navigation has been triggered.\n */\nexport async function triggerDownload(config: DownloadConfig): Promise<IssuedDownload> {\n const issued = await issueDownload(config);\n const delay = config.beaconDelayMs ?? 1500;\n\n if (typeof window !== 'undefined') {\n window.location.href = issued.signedUrl;\n setTimeout(() => sendCompletionBeacon(issued.beaconUrl), delay);\n }\n\n return issued;\n}\n","import { checkoutUrl } from './checkout';\nimport { formatPrice } from './pricing';\nimport type { PricingTier, TierMeta } from './types';\n\nexport type IntervalKey = 'monthly' | 'yearly' | 'oneTime';\n\nexport type CtaProps = {\n label: string;\n href: string | null;\n disabled: boolean;\n monthlyHref: string | null;\n yearlyHref: string | null;\n oneTimeHref: string | null;\n};\n\nexport type CtaOptions = {\n billingBaseUrl: string;\n productKey: string;\n tierMeta?: TierMeta;\n interval?: IntervalKey;\n freeLabel?: string;\n subscribeLabel?: string;\n buyLabel?: string;\n comingSoonLabel?: string;\n};\n\nexport function isFreeTier(tier: PricingTier): boolean {\n return tier.monthly?.amount === 0 && tier.yearly === null && tier.oneTime === null;\n}\n\nexport function isOneTimeTier(tier: PricingTier): boolean {\n return tier.oneTime !== null && tier.monthly === null;\n}\n\nexport function hasYearly(tier: PricingTier): boolean {\n return tier.yearly !== null && tier.monthly !== null;\n}\n\n/**\n * Resolves all CTA fields for a tier — label, primary href, per-interval\n * hrefs (so a UI toggle can hot-swap without re-deriving), and disabled\n * state for coming-soon plans. Replaces hand-rolled if/else trees in\n * landing pages.\n */\nexport function getCtaProps(tier: PricingTier, opts: CtaOptions): CtaProps {\n const meta = opts.tierMeta;\n const monthlyHref = tier.monthly\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.monthly.planKey)\n : null;\n const yearlyHref = tier.yearly\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.yearly.planKey)\n : null;\n const oneTimeHref = tier.oneTime\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.oneTime.planKey)\n : null;\n\n if (tier.isComingSoon) {\n return {\n label: opts.comingSoonLabel ?? 'Coming soon',\n href: null,\n disabled: true,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n }\n\n if (meta?.ctaHref) {\n return {\n label: meta.ctaLabel ?? 'Get started',\n href: meta.ctaHref,\n disabled: false,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n }\n\n let primary: string | null;\n let defaultLabel: string;\n\n if (isFreeTier(tier)) {\n primary = null;\n defaultLabel = opts.freeLabel ?? 'Get started';\n } else if (isOneTimeTier(tier)) {\n primary = oneTimeHref;\n defaultLabel = opts.buyLabel ?? 'Buy';\n } else {\n primary = opts.interval === 'yearly' ? yearlyHref ?? monthlyHref : monthlyHref;\n defaultLabel = opts.subscribeLabel ?? 'Subscribe';\n }\n\n return {\n label: meta?.ctaLabel ?? defaultLabel,\n href: primary,\n disabled: false,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n}\n\nexport type FormattedPrice = {\n amount: string;\n suffix: string;\n raw: { amount: number; currency: string } | null;\n note?: string;\n};\n\n/**\n * Returns the price + suffix to render for a tier given the active\n * interval. Falls back gracefully: a tier with only monthly always\n * shows monthly; a free tier shows €0; a one-time tier shows the amount\n * with a 'one-time' suffix.\n */\nexport function getActivePrice(tier: PricingTier, interval: IntervalKey): FormattedPrice {\n if (interval === 'yearly' && tier.yearly) {\n return {\n amount: formatPrice(tier.yearly.amount, tier.yearly.currency),\n suffix: '/year',\n raw: { amount: tier.yearly.amount, currency: tier.yearly.currency },\n note: tier.yearly.monthsFree > 0 ? `${tier.yearly.monthsFree} months free` : undefined,\n };\n }\n\n if (interval === 'oneTime' && tier.oneTime) {\n return {\n amount: formatPrice(tier.oneTime.amount, tier.oneTime.currency),\n suffix: ' one-time',\n raw: { amount: tier.oneTime.amount, currency: tier.oneTime.currency },\n };\n }\n\n if (tier.monthly) {\n return {\n amount: formatPrice(tier.monthly.amount, tier.monthly.currency),\n suffix: '/month',\n raw: { amount: tier.monthly.amount, currency: tier.monthly.currency },\n };\n }\n\n if (tier.oneTime) {\n return {\n amount: formatPrice(tier.oneTime.amount, tier.oneTime.currency),\n suffix: ' one-time',\n raw: { amount: tier.oneTime.amount, currency: tier.oneTime.currency },\n };\n }\n\n return { amount: '—', suffix: '', raw: null };\n}\n\n/**\n * Picks the natural default interval for a list of tiers: 'yearly' if\n * any tier has a yearly option, else 'monthly'. Useful as the initial\n * state for a billing-interval toggle.\n */\nexport function defaultInterval(tiers: PricingTier[]): IntervalKey {\n if (tiers.some(hasYearly)) return 'monthly';\n if (tiers.every((t) => t.monthly === null && t.oneTime !== null)) return 'oneTime';\n return 'monthly';\n}\n","import type {\n LicenseSnapshotPayload,\n SignedLicense,\n UsageFeatureState,\n} from './client-types';\n\nexport interface DecodedLicense {\n raw: SignedLicense;\n payload: LicenseSnapshotPayload;\n}\n\nfunction base64Decode(input: string): Uint8Array<ArrayBuffer> {\n const bin = atob(input);\n const buf = new ArrayBuffer(bin.length);\n const out = new Uint8Array(buf);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nexport function decodeLicense(signed: SignedLicense): DecodedLicense {\n const payloadJson = new TextDecoder().decode(base64Decode(signed.payload));\n const payload = JSON.parse(payloadJson) as LicenseSnapshotPayload;\n return { raw: signed, payload };\n}\n\nexport async function verifyLicense(signed: SignedLicense, publicKeyBase64: string): Promise<boolean> {\n if (signed.algorithm !== 'ed25519') return false;\n\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('crypto.subtle not available; cannot verify license');\n\n const payloadBytes = base64Decode(signed.payload);\n const signatureBytes = base64Decode(signed.signature);\n const publicKeyBytes = base64Decode(publicKeyBase64);\n\n const key = await subtle.importKey(\n 'raw',\n publicKeyBytes,\n { name: 'Ed25519' } as AlgorithmIdentifier,\n false,\n ['verify'],\n );\n\n return subtle.verify({ name: 'Ed25519' } as AlgorithmIdentifier, key, signatureBytes, payloadBytes);\n}\n\nexport function computeRemaining(\n payload: LicenseSnapshotPayload,\n feature: string,\n consumedLocal = 0,\n): number | null {\n const state = payload.usage?.[feature];\n if (!state) return null;\n if (state.type === 'bool') return state.enabled ? Number.POSITIVE_INFINITY : 0;\n return Math.max(0, state.allowance - state.consumed_at_issue - consumedLocal);\n}\n\nexport function isUnlimited(state: UsageFeatureState | undefined): boolean {\n if (!state) return false;\n if (state.type === 'bool') return state.enabled;\n return state.allowance === 0;\n}\n\nexport function isExpired(payload: LicenseSnapshotPayload, now: Date = new Date()): boolean {\n return new Date(payload.valid_until).getTime() < now.getTime();\n}\n\nexport function isInGrace(\n payload: LicenseSnapshotPayload,\n graceSeconds: number,\n now: Date = new Date(),\n): boolean {\n const expiry = new Date(payload.valid_until).getTime();\n return now.getTime() <= expiry + graceSeconds * 1000;\n}\n\nexport function canUseUpdate(payload: LicenseSnapshotPayload, releaseDate: string | Date): boolean {\n const release = releaseDate instanceof Date ? releaseDate : new Date(releaseDate);\n\n const paidUpMs = payload.paid_up_until ? new Date(payload.paid_up_until).getTime() : null;\n const fallbackMs = payload.fallback_release_date\n ? new Date(payload.fallback_release_date).getTime()\n : null;\n\n if (paidUpMs === null && fallbackMs === null) return true;\n\n const effective = Math.max(paidUpMs ?? -Infinity, fallbackMs ?? -Infinity);\n const windowMs = (payload.updates_window_days ?? 0) * 86_400_000;\n return release.getTime() <= effective + windowMs;\n}\n\nexport function periodResetAt(payload: LicenseSnapshotPayload, feature: string): Date | null {\n const state = payload.usage?.[feature];\n if (!state || state.type !== 'counter') return null;\n return new Date(state.period_end);\n}\n","import type { BuildOauthInitUrlOptions, PkceChallenge } from './client-types';\n\nfunction bytesToUrlSafeBase64(bytes: Uint8Array): string {\n let bin = '';\n for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i] as number);\n return btoa(bin).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nfunction randomBytes(length: number): Uint8Array {\n const buf = new Uint8Array(length);\n globalThis.crypto.getRandomValues(buf);\n return buf;\n}\n\nexport async function generatePkceChallenge(): Promise<PkceChallenge> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('crypto.subtle not available; cannot generate PKCE challenge');\n\n const verifier = bytesToUrlSafeBase64(randomBytes(48));\n const hash = await subtle.digest('SHA-256', new TextEncoder().encode(verifier));\n const challenge = bytesToUrlSafeBase64(new Uint8Array(hash));\n\n return { verifier, challenge, method: 'S256' };\n}\n\nexport function generateOauthState(): string {\n return bytesToUrlSafeBase64(randomBytes(24));\n}\n\nexport function buildOauthInitUrl(opts: BuildOauthInitUrlOptions): string {\n const base = opts.baseUrl.replace(/\\/$/, '');\n const params = new URLSearchParams({\n product: opts.product,\n redirect_uri: opts.redirectUri,\n code_challenge: opts.codeChallenge,\n code_challenge_method: opts.codeChallengeMethod ?? 'S256',\n });\n if (opts.state) params.set('state', opts.state);\n\n return `${base}/auth/${opts.provider}?${params.toString()}`;\n}\n","import type { LicenseSnapshotPayload } from './client-types';\n\nexport type LicenseState = 'none' | 'invalid' | 'active' | 'trialing' | 'grace' | 'expired';\n\nexport function computeState(\n payload: LicenseSnapshotPayload | null | undefined,\n graceWindowMs: number,\n now: Date = new Date(),\n): LicenseState {\n if (!payload) return 'none';\n if (!payload.valid_until) return 'invalid';\n\n const expiry = Date.parse(payload.valid_until);\n if (Number.isNaN(expiry)) return 'invalid';\n\n const nowMs = now.getTime();\n if (nowMs <= expiry) {\n return isTrialPayload(payload) ? 'trialing' : 'active';\n }\n\n const cutoff = expiry + graceWindowMs;\n if (nowMs <= cutoff) return 'grace';\n return 'expired';\n}\n\nexport function trialDaysLeft(\n payload: LicenseSnapshotPayload | null | undefined,\n now: Date = new Date(),\n): number {\n if (!payload || !isTrialPayload(payload)) return 0;\n const expiry = Date.parse(payload.valid_until);\n if (Number.isNaN(expiry)) return 0;\n const delta = expiry - now.getTime();\n if (delta <= 0) return 0;\n const dayMs = 24 * 60 * 60 * 1000;\n return Math.ceil(delta / dayMs);\n}\n\nfunction isTrialPayload(payload: LicenseSnapshotPayload): boolean {\n if (payload.features?.__trial === true) return true;\n if (payload.plan_key && payload.plan_key.endsWith(':trial')) return true;\n return false;\n}\n","import type { LicenseSnapshotPayload, SignedLicense } from './client-types';\nimport { computeRemaining } from './license';\nimport { computeState, type LicenseState } from './lifecycle';\n\nexport interface LoadedLicense {\n license: SignedLicense;\n payload: LicenseSnapshotPayload;\n}\n\nexport type LicenseLoader = () => Promise<LoadedLicense | null>;\nexport type LocalConsumptionFn = (feature: string) => Promise<number> | number;\n\nexport interface GateOptions {\n loader: LicenseLoader;\n localConsumption?: LocalConsumptionFn;\n graceWindowMs?: number;\n now?: () => Date;\n}\n\nexport interface FeatureAccess {\n feature: string;\n allowed: boolean;\n hasFeature: boolean;\n unlimited: boolean;\n remaining: number;\n reason: string;\n plan: string;\n state: LicenseState;\n}\n\nexport class GateDeniedError extends Error {\n readonly access: FeatureAccess;\n\n constructor(access: FeatureAccess) {\n super(`billing: feature \"${access.feature}\" denied (${access.reason})`);\n this.name = 'GateDeniedError';\n this.access = access;\n }\n}\n\nexport function isGateDenied(err: unknown): err is GateDeniedError {\n return err instanceof GateDeniedError;\n}\n\nexport class Gate {\n private readonly loader: LicenseLoader;\n private readonly localConsumption: LocalConsumptionFn;\n private readonly graceWindowMs: number;\n private readonly now: () => Date;\n private inflight: Promise<FeatureAccess> | null = null;\n\n constructor(opts: GateOptions) {\n if (!opts.loader) throw new Error('billing: Gate requires loader');\n this.loader = opts.loader;\n this.localConsumption = opts.localConsumption ?? (() => 0);\n this.graceWindowMs = opts.graceWindowMs ?? 0;\n this.now = opts.now ?? (() => new Date());\n }\n\n async check(feature: string): Promise<FeatureAccess> {\n const prev = this.inflight;\n const run = (async () => {\n if (prev) {\n try {\n await prev;\n } catch {\n /* prior failure does not block current call */\n }\n }\n return this.evaluate(feature);\n })();\n this.inflight = run.catch(() => ({}) as FeatureAccess) as Promise<FeatureAccess>;\n return run;\n }\n\n async require(feature: string): Promise<FeatureAccess> {\n const access = await this.check(feature);\n if (!access.allowed) throw new GateDeniedError(access);\n return access;\n }\n\n private async evaluate(feature: string): Promise<FeatureAccess> {\n const access: FeatureAccess = {\n feature,\n allowed: false,\n hasFeature: false,\n unlimited: false,\n remaining: 0,\n reason: '',\n plan: '',\n state: 'none',\n };\n\n let loaded: LoadedLicense | null;\n try {\n loaded = await this.loader();\n } catch (err) {\n access.reason = 'verify_failed';\n throw Object.assign(err instanceof Error ? err : new Error(String(err)), { access });\n }\n\n if (!loaded) {\n access.reason = 'no_license';\n return access;\n }\n\n const { payload } = loaded;\n access.plan = payload.plan_key;\n access.state = computeState(payload, this.graceWindowMs, this.now());\n\n if (access.state === 'expired' || access.state === 'invalid') {\n access.reason = `license_${access.state}`;\n return access;\n }\n\n const featureFlag = payload.features?.[feature];\n if (featureFlag !== undefined) {\n access.hasFeature = featureFlag;\n if (!featureFlag) {\n access.reason = 'feature_disabled';\n return access;\n }\n }\n\n let consumed: number;\n try {\n consumed = await this.localConsumption(feature);\n } catch (err) {\n access.reason = 'local_consumption_failed';\n throw Object.assign(err instanceof Error ? err : new Error(String(err)), { access });\n }\n\n const remaining = computeRemaining(payload, feature, consumed);\n if (remaining === null) {\n if (access.hasFeature) {\n access.allowed = true;\n access.unlimited = true;\n return access;\n }\n access.reason = 'feature_missing';\n return access;\n }\n\n if (remaining === Number.POSITIVE_INFINITY) {\n access.unlimited = true;\n access.hasFeature = true;\n access.allowed = true;\n return access;\n }\n\n access.remaining = remaining;\n if (remaining > 0) {\n access.allowed = true;\n access.hasFeature = true;\n return access;\n }\n\n access.reason = 'limit_reached';\n return access;\n }\n}\n","import type { LicenseSyncUsageResponse } from './client-types';\n\nexport interface UsageBuffer {\n add(feature: string, delta: number): Promise<void> | void;\n drain(): Promise<Record<string, number>> | Record<string, number>;\n restore(deltas: Record<string, number>): Promise<void> | void;\n}\n\nexport class MemoryBuffer implements UsageBuffer {\n private state: Record<string, number> = {};\n\n add(feature: string, delta: number): void {\n if (delta === 0) return;\n this.state[feature] = (this.state[feature] ?? 0) + delta;\n }\n\n drain(): Record<string, number> {\n const out = this.state;\n this.state = {};\n return out;\n }\n\n restore(deltas: Record<string, number>): void {\n for (const [k, v] of Object.entries(deltas)) {\n this.state[k] = (this.state[k] ?? 0) + v;\n }\n }\n}\n\nexport type SyncUsageFn = (\n deltas: Record<string, number>,\n serial: number,\n) => Promise<LicenseSyncUsageResponse>;\n\nexport type SerialProviderFn = () => Promise<number> | number;\nexport type RefreshHandlerFn = (resp: LicenseSyncUsageResponse) => Promise<void> | void;\n\nexport interface UsageTrackerOptions {\n buffer: UsageBuffer;\n sync: SyncUsageFn;\n serial?: SerialProviderFn;\n onRefresh?: RefreshHandlerFn;\n flushIntervalMs?: number;\n}\n\nconst DEFAULT_FLUSH_INTERVAL_MS = 5 * 60 * 1000;\n\nexport class UsageTracker {\n private readonly buffer: UsageBuffer;\n private readonly sync: SyncUsageFn;\n private readonly serial?: SerialProviderFn;\n private readonly onRefresh?: RefreshHandlerFn;\n private readonly flushIntervalMs: number;\n private timer: ReturnType<typeof setInterval> | null = null;\n private running = false;\n\n constructor(opts: UsageTrackerOptions) {\n if (!opts.buffer) throw new Error('billing: tracker requires buffer');\n if (!opts.sync) throw new Error('billing: tracker requires sync');\n this.buffer = opts.buffer;\n this.sync = opts.sync;\n if (opts.serial !== undefined) this.serial = opts.serial;\n if (opts.onRefresh !== undefined) this.onRefresh = opts.onRefresh;\n this.flushIntervalMs =\n opts.flushIntervalMs && opts.flushIntervalMs > 0\n ? opts.flushIntervalMs\n : DEFAULT_FLUSH_INTERVAL_MS;\n }\n\n async track(feature: string, delta: number): Promise<void> {\n if (delta === 0) return;\n await this.buffer.add(feature, delta);\n }\n\n async flush(): Promise<void> {\n const deltas = await this.buffer.drain();\n if (!deltas || Object.keys(deltas).length === 0) return;\n\n let serial = 0;\n if (this.serial) {\n try {\n serial = await this.serial();\n } catch (err) {\n await this.buffer.restore(deltas);\n throw err;\n }\n }\n\n let resp: LicenseSyncUsageResponse;\n try {\n resp = await this.sync(deltas, serial);\n } catch (err) {\n await this.buffer.restore(deltas);\n throw err;\n }\n\n if (this.onRefresh && resp) {\n await this.onRefresh(resp);\n }\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n this.timer = setInterval(() => {\n void this.flush().catch(() => {\n /* swallow; next tick retries via restored buffer */\n });\n }, this.flushIntervalMs);\n }\n\n async stop(): Promise<void> {\n if (!this.running) return;\n this.running = false;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n await this.flush();\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { A as AssetPlatform, B as BillingInterval, I as IssuedDownload, P as PricingFeature, a as PricingPayload, b as PricingTier, R as ReleaseChannel, T as TierMeta } from './types-CH4Vkivj.cjs';
2
- export { A as ActivatedDevice, B as BillingPortalResponse, a as BuildOauthInitUrlOptions, C as Customer, E as EntitlementCustomer, b as EntitlementsResponse, G as GithubAppInfo, c as GithubInstallationTokenPayload, d as GithubInstallationTokenResponse, e as GithubUserInstallation, f as GithubUserInstallationsResponse, g as GithubUserSummary, L as LicenseActivatePayload, h as LicenseActivateResponse, i as LicenseCheckPayload, j as LicenseCheckResponse, k as LicensePublicKey, l as LicensePublicKeysResponse, m as LicenseRefreshPayload, n as LicenseSnapshotPayload, o as LicenseSyncUsagePayload, p as LicenseSyncUsageResponse, q as LicensingMode, O as OauthExchangeEntitlement, r as OauthExchangePayload, s as OauthExchangeResponse, t as OauthProvider, u as OauthProviderInfo, v as OauthProvidersResponse, w as OtpCustomer, x as OtpRequestPayload, y as OtpVerifyPayload, z as OtpVerifyResponse, P as PkceChallenge, S as SignedLicense, U as UsageFeatureState, D as UsagePayload, F as UsageResponse } from './client-types-CtRkHWna.cjs';
2
+ import { n as LicenseSnapshotPayload, S as SignedLicense, p as LicenseSyncUsageResponse } from './client-types-CtRkHWna.cjs';
3
+ export { A as ActivatedDevice, B as BillingPortalResponse, a as BuildOauthInitUrlOptions, C as Customer, E as EntitlementCustomer, b as EntitlementsResponse, G as GithubAppInfo, c as GithubInstallationTokenPayload, d as GithubInstallationTokenResponse, e as GithubUserInstallation, f as GithubUserInstallationsResponse, g as GithubUserSummary, L as LicenseActivatePayload, h as LicenseActivateResponse, i as LicenseCheckPayload, j as LicenseCheckResponse, k as LicensePublicKey, l as LicensePublicKeysResponse, m as LicenseRefreshPayload, o as LicenseSyncUsagePayload, q as LicensingMode, O as OauthExchangeEntitlement, r as OauthExchangePayload, s as OauthExchangeResponse, t as OauthProvider, u as OauthProviderInfo, v as OauthProvidersResponse, w as OtpCustomer, x as OtpRequestPayload, y as OtpVerifyPayload, z as OtpVerifyResponse, P as PkceChallenge, U as UsageFeatureState, D as UsagePayload, F as UsageResponse } from './client-types-CtRkHWna.cjs';
3
4
  export { BillingApiError, BillingClient, BillingClientConfig } from './client.cjs';
4
5
  export { FetchPricingConfig, fetchPricing, formatPrice } from './pricing.cjs';
5
6
  export { checkoutUrl } from './checkout.cjs';
@@ -16,4 +17,83 @@ declare function newNonce(): string;
16
17
  declare function canonical(productSlug: string, timestamp: number, nonce: string, method: string, path: string, body: Uint8Array): Promise<string>;
17
18
  declare function sign(productSecret: string, canonicalString: string): Promise<string>;
18
19
 
19
- export { HEADER_NONCE, HEADER_PRODUCT, HEADER_SIGNATURE, HEADER_TIMESTAMP, canonical, newNonce, sign };
20
+ type LicenseState = 'none' | 'invalid' | 'active' | 'trialing' | 'grace' | 'expired';
21
+ declare function computeState(payload: LicenseSnapshotPayload | null | undefined, graceWindowMs: number, now?: Date): LicenseState;
22
+ declare function trialDaysLeft(payload: LicenseSnapshotPayload | null | undefined, now?: Date): number;
23
+
24
+ interface LoadedLicense {
25
+ license: SignedLicense;
26
+ payload: LicenseSnapshotPayload;
27
+ }
28
+ type LicenseLoader = () => Promise<LoadedLicense | null>;
29
+ type LocalConsumptionFn = (feature: string) => Promise<number> | number;
30
+ interface GateOptions {
31
+ loader: LicenseLoader;
32
+ localConsumption?: LocalConsumptionFn;
33
+ graceWindowMs?: number;
34
+ now?: () => Date;
35
+ }
36
+ interface FeatureAccess {
37
+ feature: string;
38
+ allowed: boolean;
39
+ hasFeature: boolean;
40
+ unlimited: boolean;
41
+ remaining: number;
42
+ reason: string;
43
+ plan: string;
44
+ state: LicenseState;
45
+ }
46
+ declare class GateDeniedError extends Error {
47
+ readonly access: FeatureAccess;
48
+ constructor(access: FeatureAccess);
49
+ }
50
+ declare function isGateDenied(err: unknown): err is GateDeniedError;
51
+ declare class Gate {
52
+ private readonly loader;
53
+ private readonly localConsumption;
54
+ private readonly graceWindowMs;
55
+ private readonly now;
56
+ private inflight;
57
+ constructor(opts: GateOptions);
58
+ check(feature: string): Promise<FeatureAccess>;
59
+ require(feature: string): Promise<FeatureAccess>;
60
+ private evaluate;
61
+ }
62
+
63
+ interface UsageBuffer {
64
+ add(feature: string, delta: number): Promise<void> | void;
65
+ drain(): Promise<Record<string, number>> | Record<string, number>;
66
+ restore(deltas: Record<string, number>): Promise<void> | void;
67
+ }
68
+ declare class MemoryBuffer implements UsageBuffer {
69
+ private state;
70
+ add(feature: string, delta: number): void;
71
+ drain(): Record<string, number>;
72
+ restore(deltas: Record<string, number>): void;
73
+ }
74
+ type SyncUsageFn = (deltas: Record<string, number>, serial: number) => Promise<LicenseSyncUsageResponse>;
75
+ type SerialProviderFn = () => Promise<number> | number;
76
+ type RefreshHandlerFn = (resp: LicenseSyncUsageResponse) => Promise<void> | void;
77
+ interface UsageTrackerOptions {
78
+ buffer: UsageBuffer;
79
+ sync: SyncUsageFn;
80
+ serial?: SerialProviderFn;
81
+ onRefresh?: RefreshHandlerFn;
82
+ flushIntervalMs?: number;
83
+ }
84
+ declare class UsageTracker {
85
+ private readonly buffer;
86
+ private readonly sync;
87
+ private readonly serial?;
88
+ private readonly onRefresh?;
89
+ private readonly flushIntervalMs;
90
+ private timer;
91
+ private running;
92
+ constructor(opts: UsageTrackerOptions);
93
+ track(feature: string, delta: number): Promise<void>;
94
+ flush(): Promise<void>;
95
+ start(): void;
96
+ stop(): Promise<void>;
97
+ }
98
+
99
+ export { type FeatureAccess, Gate, GateDeniedError, type GateOptions, HEADER_NONCE, HEADER_PRODUCT, HEADER_SIGNATURE, HEADER_TIMESTAMP, type LicenseLoader, LicenseSnapshotPayload, type LicenseState, LicenseSyncUsageResponse, type LoadedLicense, type LocalConsumptionFn, MemoryBuffer, type RefreshHandlerFn, type SerialProviderFn, SignedLicense, type SyncUsageFn, type UsageBuffer, UsageTracker, type UsageTrackerOptions, canonical, computeState, isGateDenied, newNonce, sign, trialDaysLeft };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { A as AssetPlatform, B as BillingInterval, I as IssuedDownload, P as PricingFeature, a as PricingPayload, b as PricingTier, R as ReleaseChannel, T as TierMeta } from './types-CH4Vkivj.js';
2
- export { A as ActivatedDevice, B as BillingPortalResponse, a as BuildOauthInitUrlOptions, C as Customer, E as EntitlementCustomer, b as EntitlementsResponse, G as GithubAppInfo, c as GithubInstallationTokenPayload, d as GithubInstallationTokenResponse, e as GithubUserInstallation, f as GithubUserInstallationsResponse, g as GithubUserSummary, L as LicenseActivatePayload, h as LicenseActivateResponse, i as LicenseCheckPayload, j as LicenseCheckResponse, k as LicensePublicKey, l as LicensePublicKeysResponse, m as LicenseRefreshPayload, n as LicenseSnapshotPayload, o as LicenseSyncUsagePayload, p as LicenseSyncUsageResponse, q as LicensingMode, O as OauthExchangeEntitlement, r as OauthExchangePayload, s as OauthExchangeResponse, t as OauthProvider, u as OauthProviderInfo, v as OauthProvidersResponse, w as OtpCustomer, x as OtpRequestPayload, y as OtpVerifyPayload, z as OtpVerifyResponse, P as PkceChallenge, S as SignedLicense, U as UsageFeatureState, D as UsagePayload, F as UsageResponse } from './client-types-CtRkHWna.js';
2
+ import { n as LicenseSnapshotPayload, S as SignedLicense, p as LicenseSyncUsageResponse } from './client-types-CtRkHWna.js';
3
+ export { A as ActivatedDevice, B as BillingPortalResponse, a as BuildOauthInitUrlOptions, C as Customer, E as EntitlementCustomer, b as EntitlementsResponse, G as GithubAppInfo, c as GithubInstallationTokenPayload, d as GithubInstallationTokenResponse, e as GithubUserInstallation, f as GithubUserInstallationsResponse, g as GithubUserSummary, L as LicenseActivatePayload, h as LicenseActivateResponse, i as LicenseCheckPayload, j as LicenseCheckResponse, k as LicensePublicKey, l as LicensePublicKeysResponse, m as LicenseRefreshPayload, o as LicenseSyncUsagePayload, q as LicensingMode, O as OauthExchangeEntitlement, r as OauthExchangePayload, s as OauthExchangeResponse, t as OauthProvider, u as OauthProviderInfo, v as OauthProvidersResponse, w as OtpCustomer, x as OtpRequestPayload, y as OtpVerifyPayload, z as OtpVerifyResponse, P as PkceChallenge, U as UsageFeatureState, D as UsagePayload, F as UsageResponse } from './client-types-CtRkHWna.js';
3
4
  export { BillingApiError, BillingClient, BillingClientConfig } from './client.js';
4
5
  export { FetchPricingConfig, fetchPricing, formatPrice } from './pricing.js';
5
6
  export { checkoutUrl } from './checkout.js';
@@ -16,4 +17,83 @@ declare function newNonce(): string;
16
17
  declare function canonical(productSlug: string, timestamp: number, nonce: string, method: string, path: string, body: Uint8Array): Promise<string>;
17
18
  declare function sign(productSecret: string, canonicalString: string): Promise<string>;
18
19
 
19
- export { HEADER_NONCE, HEADER_PRODUCT, HEADER_SIGNATURE, HEADER_TIMESTAMP, canonical, newNonce, sign };
20
+ type LicenseState = 'none' | 'invalid' | 'active' | 'trialing' | 'grace' | 'expired';
21
+ declare function computeState(payload: LicenseSnapshotPayload | null | undefined, graceWindowMs: number, now?: Date): LicenseState;
22
+ declare function trialDaysLeft(payload: LicenseSnapshotPayload | null | undefined, now?: Date): number;
23
+
24
+ interface LoadedLicense {
25
+ license: SignedLicense;
26
+ payload: LicenseSnapshotPayload;
27
+ }
28
+ type LicenseLoader = () => Promise<LoadedLicense | null>;
29
+ type LocalConsumptionFn = (feature: string) => Promise<number> | number;
30
+ interface GateOptions {
31
+ loader: LicenseLoader;
32
+ localConsumption?: LocalConsumptionFn;
33
+ graceWindowMs?: number;
34
+ now?: () => Date;
35
+ }
36
+ interface FeatureAccess {
37
+ feature: string;
38
+ allowed: boolean;
39
+ hasFeature: boolean;
40
+ unlimited: boolean;
41
+ remaining: number;
42
+ reason: string;
43
+ plan: string;
44
+ state: LicenseState;
45
+ }
46
+ declare class GateDeniedError extends Error {
47
+ readonly access: FeatureAccess;
48
+ constructor(access: FeatureAccess);
49
+ }
50
+ declare function isGateDenied(err: unknown): err is GateDeniedError;
51
+ declare class Gate {
52
+ private readonly loader;
53
+ private readonly localConsumption;
54
+ private readonly graceWindowMs;
55
+ private readonly now;
56
+ private inflight;
57
+ constructor(opts: GateOptions);
58
+ check(feature: string): Promise<FeatureAccess>;
59
+ require(feature: string): Promise<FeatureAccess>;
60
+ private evaluate;
61
+ }
62
+
63
+ interface UsageBuffer {
64
+ add(feature: string, delta: number): Promise<void> | void;
65
+ drain(): Promise<Record<string, number>> | Record<string, number>;
66
+ restore(deltas: Record<string, number>): Promise<void> | void;
67
+ }
68
+ declare class MemoryBuffer implements UsageBuffer {
69
+ private state;
70
+ add(feature: string, delta: number): void;
71
+ drain(): Record<string, number>;
72
+ restore(deltas: Record<string, number>): void;
73
+ }
74
+ type SyncUsageFn = (deltas: Record<string, number>, serial: number) => Promise<LicenseSyncUsageResponse>;
75
+ type SerialProviderFn = () => Promise<number> | number;
76
+ type RefreshHandlerFn = (resp: LicenseSyncUsageResponse) => Promise<void> | void;
77
+ interface UsageTrackerOptions {
78
+ buffer: UsageBuffer;
79
+ sync: SyncUsageFn;
80
+ serial?: SerialProviderFn;
81
+ onRefresh?: RefreshHandlerFn;
82
+ flushIntervalMs?: number;
83
+ }
84
+ declare class UsageTracker {
85
+ private readonly buffer;
86
+ private readonly sync;
87
+ private readonly serial?;
88
+ private readonly onRefresh?;
89
+ private readonly flushIntervalMs;
90
+ private timer;
91
+ private running;
92
+ constructor(opts: UsageTrackerOptions);
93
+ track(feature: string, delta: number): Promise<void>;
94
+ flush(): Promise<void>;
95
+ start(): void;
96
+ stop(): Promise<void>;
97
+ }
98
+
99
+ export { type FeatureAccess, Gate, GateDeniedError, type GateOptions, HEADER_NONCE, HEADER_PRODUCT, HEADER_SIGNATURE, HEADER_TIMESTAMP, type LicenseLoader, LicenseSnapshotPayload, type LicenseState, LicenseSyncUsageResponse, type LoadedLicense, type LocalConsumptionFn, MemoryBuffer, type RefreshHandlerFn, type SerialProviderFn, SignedLicense, type SyncUsageFn, type UsageBuffer, UsageTracker, type UsageTrackerOptions, canonical, computeState, isGateDenied, newNonce, sign, trialDaysLeft };
package/dist/index.js CHANGED
@@ -534,6 +534,232 @@ function buildOauthInitUrl(opts) {
534
534
  return `${base}/auth/${opts.provider}?${params.toString()}`;
535
535
  }
536
536
 
537
- export { BillingApiError, BillingClient, HEADER_NONCE, HEADER_PRODUCT, HEADER_SIGNATURE, HEADER_TIMESTAMP, buildOauthInitUrl, canUseUpdate, canonical, checkoutUrl, computeRemaining, decodeLicense, defaultInterval, downloadUrl, fetchPricing, formatPrice, generateOauthState, generatePkceChallenge, getActivePrice, getCtaProps, hasYearly, isExpired, isFreeTier, isInGrace, isOneTimeTier, isUnlimited, issueDownload, newNonce, periodResetAt, sendCompletionBeacon, sign, triggerDownload, verifyLicense };
537
+ // src/lifecycle.ts
538
+ function computeState(payload, graceWindowMs, now = /* @__PURE__ */ new Date()) {
539
+ if (!payload) return "none";
540
+ if (!payload.valid_until) return "invalid";
541
+ const expiry = Date.parse(payload.valid_until);
542
+ if (Number.isNaN(expiry)) return "invalid";
543
+ const nowMs = now.getTime();
544
+ if (nowMs <= expiry) {
545
+ return isTrialPayload(payload) ? "trialing" : "active";
546
+ }
547
+ const cutoff = expiry + graceWindowMs;
548
+ if (nowMs <= cutoff) return "grace";
549
+ return "expired";
550
+ }
551
+ function trialDaysLeft(payload, now = /* @__PURE__ */ new Date()) {
552
+ if (!payload || !isTrialPayload(payload)) return 0;
553
+ const expiry = Date.parse(payload.valid_until);
554
+ if (Number.isNaN(expiry)) return 0;
555
+ const delta = expiry - now.getTime();
556
+ if (delta <= 0) return 0;
557
+ const dayMs = 24 * 60 * 60 * 1e3;
558
+ return Math.ceil(delta / dayMs);
559
+ }
560
+ function isTrialPayload(payload) {
561
+ if (payload.features?.__trial === true) return true;
562
+ if (payload.plan_key && payload.plan_key.endsWith(":trial")) return true;
563
+ return false;
564
+ }
565
+
566
+ // src/gate.ts
567
+ var GateDeniedError = class extends Error {
568
+ access;
569
+ constructor(access) {
570
+ super(`billing: feature "${access.feature}" denied (${access.reason})`);
571
+ this.name = "GateDeniedError";
572
+ this.access = access;
573
+ }
574
+ };
575
+ function isGateDenied(err) {
576
+ return err instanceof GateDeniedError;
577
+ }
578
+ var Gate = class {
579
+ loader;
580
+ localConsumption;
581
+ graceWindowMs;
582
+ now;
583
+ inflight = null;
584
+ constructor(opts) {
585
+ if (!opts.loader) throw new Error("billing: Gate requires loader");
586
+ this.loader = opts.loader;
587
+ this.localConsumption = opts.localConsumption ?? (() => 0);
588
+ this.graceWindowMs = opts.graceWindowMs ?? 0;
589
+ this.now = opts.now ?? (() => /* @__PURE__ */ new Date());
590
+ }
591
+ async check(feature) {
592
+ const prev = this.inflight;
593
+ const run = (async () => {
594
+ if (prev) {
595
+ try {
596
+ await prev;
597
+ } catch {
598
+ }
599
+ }
600
+ return this.evaluate(feature);
601
+ })();
602
+ this.inflight = run.catch(() => ({}));
603
+ return run;
604
+ }
605
+ async require(feature) {
606
+ const access = await this.check(feature);
607
+ if (!access.allowed) throw new GateDeniedError(access);
608
+ return access;
609
+ }
610
+ async evaluate(feature) {
611
+ const access = {
612
+ feature,
613
+ allowed: false,
614
+ hasFeature: false,
615
+ unlimited: false,
616
+ remaining: 0,
617
+ reason: "",
618
+ plan: "",
619
+ state: "none"
620
+ };
621
+ let loaded;
622
+ try {
623
+ loaded = await this.loader();
624
+ } catch (err) {
625
+ access.reason = "verify_failed";
626
+ throw Object.assign(err instanceof Error ? err : new Error(String(err)), { access });
627
+ }
628
+ if (!loaded) {
629
+ access.reason = "no_license";
630
+ return access;
631
+ }
632
+ const { payload } = loaded;
633
+ access.plan = payload.plan_key;
634
+ access.state = computeState(payload, this.graceWindowMs, this.now());
635
+ if (access.state === "expired" || access.state === "invalid") {
636
+ access.reason = `license_${access.state}`;
637
+ return access;
638
+ }
639
+ const featureFlag = payload.features?.[feature];
640
+ if (featureFlag !== void 0) {
641
+ access.hasFeature = featureFlag;
642
+ if (!featureFlag) {
643
+ access.reason = "feature_disabled";
644
+ return access;
645
+ }
646
+ }
647
+ let consumed;
648
+ try {
649
+ consumed = await this.localConsumption(feature);
650
+ } catch (err) {
651
+ access.reason = "local_consumption_failed";
652
+ throw Object.assign(err instanceof Error ? err : new Error(String(err)), { access });
653
+ }
654
+ const remaining = computeRemaining(payload, feature, consumed);
655
+ if (remaining === null) {
656
+ if (access.hasFeature) {
657
+ access.allowed = true;
658
+ access.unlimited = true;
659
+ return access;
660
+ }
661
+ access.reason = "feature_missing";
662
+ return access;
663
+ }
664
+ if (remaining === Number.POSITIVE_INFINITY) {
665
+ access.unlimited = true;
666
+ access.hasFeature = true;
667
+ access.allowed = true;
668
+ return access;
669
+ }
670
+ access.remaining = remaining;
671
+ if (remaining > 0) {
672
+ access.allowed = true;
673
+ access.hasFeature = true;
674
+ return access;
675
+ }
676
+ access.reason = "limit_reached";
677
+ return access;
678
+ }
679
+ };
680
+
681
+ // src/usage.ts
682
+ var MemoryBuffer = class {
683
+ state = {};
684
+ add(feature, delta) {
685
+ if (delta === 0) return;
686
+ this.state[feature] = (this.state[feature] ?? 0) + delta;
687
+ }
688
+ drain() {
689
+ const out = this.state;
690
+ this.state = {};
691
+ return out;
692
+ }
693
+ restore(deltas) {
694
+ for (const [k, v] of Object.entries(deltas)) {
695
+ this.state[k] = (this.state[k] ?? 0) + v;
696
+ }
697
+ }
698
+ };
699
+ var DEFAULT_FLUSH_INTERVAL_MS = 5 * 60 * 1e3;
700
+ var UsageTracker = class {
701
+ buffer;
702
+ sync;
703
+ serial;
704
+ onRefresh;
705
+ flushIntervalMs;
706
+ timer = null;
707
+ running = false;
708
+ constructor(opts) {
709
+ if (!opts.buffer) throw new Error("billing: tracker requires buffer");
710
+ if (!opts.sync) throw new Error("billing: tracker requires sync");
711
+ this.buffer = opts.buffer;
712
+ this.sync = opts.sync;
713
+ if (opts.serial !== void 0) this.serial = opts.serial;
714
+ if (opts.onRefresh !== void 0) this.onRefresh = opts.onRefresh;
715
+ this.flushIntervalMs = opts.flushIntervalMs && opts.flushIntervalMs > 0 ? opts.flushIntervalMs : DEFAULT_FLUSH_INTERVAL_MS;
716
+ }
717
+ async track(feature, delta) {
718
+ if (delta === 0) return;
719
+ await this.buffer.add(feature, delta);
720
+ }
721
+ async flush() {
722
+ const deltas = await this.buffer.drain();
723
+ if (!deltas || Object.keys(deltas).length === 0) return;
724
+ let serial = 0;
725
+ if (this.serial) {
726
+ try {
727
+ serial = await this.serial();
728
+ } catch (err) {
729
+ await this.buffer.restore(deltas);
730
+ throw err;
731
+ }
732
+ }
733
+ let resp;
734
+ try {
735
+ resp = await this.sync(deltas, serial);
736
+ } catch (err) {
737
+ await this.buffer.restore(deltas);
738
+ throw err;
739
+ }
740
+ if (this.onRefresh && resp) {
741
+ await this.onRefresh(resp);
742
+ }
743
+ }
744
+ start() {
745
+ if (this.running) return;
746
+ this.running = true;
747
+ this.timer = setInterval(() => {
748
+ void this.flush().catch(() => {
749
+ });
750
+ }, this.flushIntervalMs);
751
+ }
752
+ async stop() {
753
+ if (!this.running) return;
754
+ this.running = false;
755
+ if (this.timer) {
756
+ clearInterval(this.timer);
757
+ this.timer = null;
758
+ }
759
+ await this.flush();
760
+ }
761
+ };
762
+
763
+ export { BillingApiError, BillingClient, Gate, GateDeniedError, HEADER_NONCE, HEADER_PRODUCT, HEADER_SIGNATURE, HEADER_TIMESTAMP, MemoryBuffer, UsageTracker, buildOauthInitUrl, canUseUpdate, canonical, checkoutUrl, computeRemaining, computeState, decodeLicense, defaultInterval, downloadUrl, fetchPricing, formatPrice, generateOauthState, generatePkceChallenge, getActivePrice, getCtaProps, hasYearly, isExpired, isFreeTier, isGateDenied, isInGrace, isOneTimeTier, isUnlimited, issueDownload, newNonce, periodResetAt, sendCompletionBeacon, sign, trialDaysLeft, triggerDownload, verifyLicense };
538
764
  //# sourceMappingURL=index.js.map
539
765
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/signature.ts","../src/client.ts","../src/pricing.ts","../src/checkout.ts","../src/downloads.ts","../src/helpers.ts","../src/license.ts","../src/oauth.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export const HEADER_PRODUCT = 'X-Akira-Product';\nexport const HEADER_TIMESTAMP = 'X-Akira-Timestamp';\nexport const HEADER_NONCE = 'X-Akira-Nonce';\nexport const HEADER_SIGNATURE = 'X-Akira-Signature';\n\nasync function sha256Hex(bytes: Uint8Array): Promise<string> {\n const digest = await getSubtle().digest('SHA-256', bytes as BufferSource);\n return bufferToHex(new Uint8Array(digest));\n}\n\nfunction getSubtle(): SubtleCrypto {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new Error('Web Crypto SubtleCrypto API is not available in this runtime.');\n }\n return subtle;\n}\n\nfunction bufferToHex(buffer: Uint8Array): string {\n let out = '';\n for (const byte of buffer) {\n out += byte.toString(16).padStart(2, '0');\n }\n return out;\n}\n\nexport function newNonce(): string {\n const buf = new Uint8Array(16);\n if (globalThis.crypto?.getRandomValues) {\n globalThis.crypto.getRandomValues(buf);\n } else {\n for (let i = 0; i < buf.length; i += 1) {\n buf[i] = Math.floor(Math.random() * 256);\n }\n }\n return bufferToHex(buf);\n}\n\nexport async function canonical(\n productSlug: string,\n timestamp: number,\n nonce: string,\n method: string,\n path: string,\n body: Uint8Array,\n): Promise<string> {\n const bodyHash = await sha256Hex(body);\n return `${productSlug}\\n${timestamp}\\n${nonce}\\n${method.toUpperCase()}\\n${path}\\n${bodyHash}`;\n}\n\nexport async function sign(productSecret: string, canonicalString: string): Promise<string> {\n const subtle = getSubtle();\n const keyData = new TextEncoder().encode(productSecret) as BufferSource;\n const key = await subtle.importKey(\n 'raw',\n keyData,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const sig = await subtle.sign('HMAC', key, new TextEncoder().encode(canonicalString) as BufferSource);\n return bufferToHex(new Uint8Array(sig));\n}\n","import {\n HEADER_NONCE,\n HEADER_PRODUCT,\n HEADER_SIGNATURE,\n HEADER_TIMESTAMP,\n canonical,\n newNonce,\n sign,\n} from './signature';\nimport type {\n BillingPortalResponse,\n Customer,\n EntitlementsResponse,\n LicenseActivatePayload,\n LicenseActivateResponse,\n LicenseCheckPayload,\n LicenseCheckResponse,\n LicensePublicKeysResponse,\n LicenseRefreshPayload,\n LicenseSyncUsagePayload,\n LicenseSyncUsageResponse,\n GithubAppInfo,\n GithubInstallationTokenPayload,\n GithubInstallationTokenResponse,\n GithubUserInstallationsResponse,\n OauthExchangePayload,\n OauthExchangeResponse,\n OauthProvidersResponse,\n OtpRequestPayload,\n OtpVerifyPayload,\n OtpVerifyResponse,\n UsagePayload,\n UsageResponse,\n} from './client-types';\n\nexport interface BillingClientConfig {\n baseUrl: string;\n productSlug: string;\n productSecret: string;\n customerToken?: string;\n fetcher?: typeof fetch;\n}\n\nexport class BillingApiError extends Error {\n status: number;\n code: string;\n constructor(status: number, code: string) {\n super(`billing api ${status}: ${code}`);\n this.status = status;\n this.code = code;\n }\n}\n\nexport class BillingClient {\n private readonly baseUrl: string;\n private readonly productSlug: string;\n private readonly productSecret: string;\n private customerToken: string | undefined;\n private readonly fetcher: typeof fetch;\n\n constructor(config: BillingClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.productSlug = config.productSlug;\n this.productSecret = config.productSecret;\n this.customerToken = config.customerToken;\n this.fetcher = config.fetcher ?? globalThis.fetch;\n if (!this.fetcher) {\n throw new Error('No fetch implementation available. Pass `fetcher` or use a runtime with global fetch.');\n }\n }\n\n setCustomerToken(token: string): void {\n this.customerToken = token;\n }\n\n async requestOtp(payload: OtpRequestPayload): Promise<void> {\n await this.signed('POST', '/api/auth/customer/otp/request', payload);\n }\n\n async verifyOtp(payload: OtpVerifyPayload): Promise<OtpVerifyResponse> {\n const res = await this.signed<OtpVerifyResponse>('POST', '/api/auth/customer/otp/verify', payload);\n this.setCustomerToken(res.access_token);\n return res;\n }\n\n async customerMe(): Promise<Customer> {\n return this.signed<Customer>('GET', '/api/me');\n }\n\n async licenseCheck(payload: LicenseCheckPayload): Promise<LicenseCheckResponse> {\n return this.signed<LicenseCheckResponse>('POST', '/api/licenses/check', payload);\n }\n\n async licenseActivate(payload: LicenseActivatePayload): Promise<LicenseActivateResponse> {\n return this.signed<LicenseActivateResponse>('POST', '/api/licenses/activate', payload);\n }\n\n async licenseRefresh(payload: LicenseRefreshPayload): Promise<LicenseActivateResponse> {\n return this.signed<LicenseActivateResponse>('POST', '/api/licenses/refresh', payload);\n }\n\n async licenseSyncUsage(payload: LicenseSyncUsagePayload): Promise<LicenseSyncUsageResponse> {\n return this.signed<LicenseSyncUsageResponse>('POST', '/api/licenses/sync-usage', payload);\n }\n\n async listOauthProviders(product: string): Promise<OauthProvidersResponse> {\n return this.signed<OauthProvidersResponse>('GET', `/api/v1/products/${encodeURIComponent(product)}/auth/providers`);\n }\n\n async exchangeOauthCode(payload: OauthExchangePayload): Promise<OauthExchangeResponse> {\n const res = await this.signed<OauthExchangeResponse>('POST', '/api/auth/oauth/exchange', payload);\n this.setCustomerToken(res.access_token);\n return res;\n }\n\n async githubInstallationToken(\n payload: GithubInstallationTokenPayload = {},\n ): Promise<GithubInstallationTokenResponse> {\n return this.signed<GithubInstallationTokenResponse>(\n 'POST',\n '/api/me/github/installation-token',\n payload,\n );\n }\n\n async meGithubInstallations(): Promise<GithubUserInstallationsResponse> {\n return this.signed<GithubUserInstallationsResponse>('GET', '/api/me/github/installations');\n }\n\n async entitlements(): Promise<EntitlementsResponse> {\n return this.signed<EntitlementsResponse>('GET', '/api/me/entitlements');\n }\n\n async billingPortal(returnUrl: string): Promise<BillingPortalResponse> {\n const path = `/api/billing/portal?return_url=${encodeURIComponent(returnUrl)}`;\n return this.signed<BillingPortalResponse>('GET', path);\n }\n\n async trackUsage(payload: UsagePayload): Promise<UsageResponse> {\n return this.signed<UsageResponse>('POST', '/api/me/usage', payload);\n }\n\n async trackAnonymousUsage(payload: UsagePayload): Promise<UsageResponse> {\n return this.signed<UsageResponse>('POST', '/api/v1/usage/anonymous', payload);\n }\n\n async publicLicenseKeys(): Promise<LicensePublicKeysResponse> {\n return this.unsigned<LicensePublicKeysResponse>('GET', '/api/v1/license-keys/public');\n }\n\n async githubAppInfo(): Promise<GithubAppInfo> {\n return this.unsigned<GithubAppInfo>('GET', '/api/v1/github/app');\n }\n\n private async signed<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const bodyBytes = body === undefined ? new Uint8Array() : new TextEncoder().encode(JSON.stringify(body));\n const timestamp = Math.floor(Date.now() / 1000);\n const nonce = newNonce();\n const canonicalString = await canonical(this.productSlug, timestamp, nonce, method, path, bodyBytes);\n const signature = await sign(this.productSecret, canonicalString);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n [HEADER_PRODUCT]: this.productSlug,\n [HEADER_TIMESTAMP]: String(timestamp),\n [HEADER_NONCE]: nonce,\n [HEADER_SIGNATURE]: signature,\n };\n if (bodyBytes.length > 0) headers['Content-Type'] = 'application/json';\n if (this.customerToken) headers.Authorization = `Bearer ${this.customerToken}`;\n\n const res = await this.fetcher(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: bodyBytes.length > 0 ? bodyBytes : undefined,\n });\n\n return this.parseResponse<T>(res);\n }\n\n private async unsigned<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const headers: Record<string, string> = { Accept: 'application/json' };\n let bodyInit: BodyInit | undefined;\n if (body !== undefined) {\n headers['Content-Type'] = 'application/json';\n bodyInit = JSON.stringify(body);\n }\n\n const res = await this.fetcher(`${this.baseUrl}${path}`, { method, headers, body: bodyInit });\n return this.parseResponse<T>(res);\n }\n\n private async parseResponse<T>(res: Response): Promise<T> {\n if (!res.ok) {\n let code: string;\n try {\n const parsed = (await res.json()) as { error?: string };\n code = parsed?.error ?? '';\n } catch {\n try {\n code = await res.text();\n } catch {\n code = '';\n }\n }\n throw new BillingApiError(res.status, code);\n }\n\n if (res.status === 204) {\n return undefined as T;\n }\n\n return (await res.json()) as T;\n }\n}\n","import type {\n BillingInterval,\n PricingFeature,\n PricingPayload,\n PricingTier,\n TierMeta,\n} from './types';\n\nexport type FetchPricingConfig = {\n baseUrl: string;\n productKey: string;\n tierMeta?: Record<string, TierMeta>;\n yearlyMonthsFree?: number;\n /** Override the global fetch (e.g. Node 18+ or custom retry). */\n fetcher?: typeof fetch;\n};\n\ntype ApiFeature = {\n key: string;\n name: string;\n description: string | null;\n};\n\ntype ApiPlan = {\n key: string;\n name: string;\n description: string | null;\n amount: number | null;\n currency: string | null;\n billing_interval: BillingInterval | null;\n trial_period_days: number;\n is_coming_soon?: boolean;\n features: ApiFeature[];\n};\n\ntype ApiPayload = {\n product: string;\n name: string;\n description: string | null;\n beta_active: boolean;\n plans: ApiPlan[];\n};\n\nconst INTERVAL_SUFFIXES = ['_monthly', '_yearly', '_month', '_year', '_one_time'];\n\nfunction tierKeyFromPlanKey(planKey: string): string {\n for (const suf of INTERVAL_SUFFIXES) {\n if (planKey.endsWith(suf)) {\n return planKey.slice(0, -suf.length);\n }\n }\n return planKey;\n}\n\nfunction titleCase(s: string): string {\n return s.replace(/[_-]+/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction emptyPayload(productKey: string): PricingPayload {\n return { product: productKey, betaActive: false, tiers: [] };\n}\n\nfunction shapeFromApi(payload: ApiPayload, config: FetchPricingConfig): PricingPayload {\n const meta = config.tierMeta ?? {};\n const monthsFree = config.yearlyMonthsFree ?? 2;\n const tiersMap = new Map<string, PricingTier>();\n\n for (const plan of payload.plans) {\n const tierKey = tierKeyFromPlanKey(plan.key);\n const m = meta[tierKey];\n\n if (!tiersMap.has(tierKey)) {\n tiersMap.set(tierKey, {\n key: tierKey,\n name: m?.label ?? titleCase(tierKey),\n tagline: m?.tagline ?? plan.description ?? '',\n highlighted: m?.highlighted ?? false,\n monthly: null,\n yearly: null,\n oneTime: null,\n isComingSoon: false,\n features: plan.features.map(\n (f): PricingFeature => ({ key: f.key, name: f.name, description: f.description }),\n ),\n });\n }\n\n const tier = tiersMap.get(tierKey)!;\n\n if (plan.is_coming_soon === true) {\n tier.isComingSoon = true;\n }\n\n if (tier.features.length === 0 && plan.features.length > 0) {\n tier.features = plan.features.map((f) => ({ key: f.key, name: f.name, description: f.description }));\n }\n\n if (plan.billing_interval === 'month' && plan.amount !== null && plan.currency !== null) {\n tier.monthly = { amount: plan.amount, currency: plan.currency, planKey: plan.key };\n continue;\n }\n\n if (plan.billing_interval === 'year' && plan.amount !== null && plan.currency !== null) {\n tier.yearly = { amount: plan.amount, currency: plan.currency, monthsFree, planKey: plan.key };\n continue;\n }\n\n if (plan.billing_interval === null) {\n const amount = plan.amount ?? 0;\n const currency = plan.currency ?? 'eur';\n if (amount === 0) {\n tier.monthly = { amount: 0, currency, planKey: plan.key };\n } else {\n tier.oneTime = { amount, currency, planKey: plan.key };\n }\n }\n }\n\n const tiers = Array.from(tiersMap.values()).sort((a, b) => {\n const oa = meta[a.key]?.order ?? 999;\n const ob = meta[b.key]?.order ?? 999;\n return oa - ob;\n });\n\n return {\n product: payload.product,\n betaActive: payload.beta_active,\n tiers,\n };\n}\n\nexport async function fetchPricing(config: FetchPricingConfig): Promise<PricingPayload> {\n const base = config.baseUrl?.replace(/\\/$/, '');\n if (!base) return emptyPayload(config.productKey);\n\n const f = config.fetcher ?? globalThis.fetch;\n if (!f) {\n throw new Error('No fetch implementation available. Pass a fetcher in config or use Node 18+.');\n }\n\n try {\n const res = await f(`${base}/api/v1/products/${config.productKey}/plans`, {\n headers: { Accept: 'application/json' },\n });\n if (!res.ok) return emptyPayload(config.productKey);\n const data = (await res.json()) as ApiPayload;\n return shapeFromApi(data, config);\n } catch {\n return emptyPayload(config.productKey);\n }\n}\n\nexport function formatPrice(amountInCents: number, currency: string): string {\n const symbol = currency.toLowerCase() === 'eur' ? '€' : currency.toUpperCase() + ' ';\n const major = (amountInCents / 100).toFixed(amountInCents % 100 === 0 ? 0 : 2);\n return `${symbol}${major}`;\n}\n\nexport type { PricingFeature, PricingPayload, PricingTier, TierMeta };\n","export function checkoutUrl(baseUrl: string, productKey: string, planKey: string): string {\n return `${baseUrl.replace(/\\/$/, '')}/subscribe/${productKey}/${planKey}`;\n}\n","import type { AssetPlatform, IssuedDownload, ReleaseChannel } from './types';\n\nexport type DownloadConfig = {\n baseUrl: string;\n product: string;\n channel: ReleaseChannel;\n platform: AssetPlatform;\n /** Optional UTM + landing tracking. */\n query?: Record<string, string | undefined>;\n /** Delay before firing the completion beacon, ms. Default 1500. */\n beaconDelayMs?: number;\n fetcher?: typeof fetch;\n};\n\nexport function downloadUrl(config: Pick<DownloadConfig, 'baseUrl' | 'product' | 'channel' | 'platform' | 'query'>): string {\n const base = config.baseUrl.replace(/\\/$/, '');\n const path = `/api/v1/downloads/${config.product}/${config.channel}/${config.platform}`;\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(config.query ?? {})) {\n if (v !== undefined && v !== '') params.set(k, v);\n }\n const qs = params.toString();\n return qs ? `${base}${path}?${qs}` : `${base}${path}`;\n}\n\n/**\n * Issues a download via the billing API and returns the signed asset URL +\n * beacon URL without redirecting. Useful when you want full control of the\n * UX (e.g. fetch then trigger your own `<a download>` flow).\n */\nexport async function issueDownload(config: DownloadConfig): Promise<IssuedDownload> {\n const f = config.fetcher ?? globalThis.fetch;\n if (!f) {\n throw new Error('No fetch implementation available. Pass a fetcher in config or use Node 18+.');\n }\n\n const url = downloadUrl(config);\n const res = await f(url, { headers: { Accept: 'application/json' } });\n\n if (!res.ok) {\n throw new Error(`download issue failed: HTTP ${res.status}`);\n }\n\n return (await res.json()) as IssuedDownload;\n}\n\n/**\n * Fires the completion beacon for an issued download. Uses\n * `navigator.sendBeacon` when available (survives page navigation), falls\n * back to `fetch` with `keepalive: true`. Safe to call at unload time.\n */\nexport function sendCompletionBeacon(beaconUrl: string): void {\n if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') {\n navigator.sendBeacon(beaconUrl);\n return;\n }\n\n if (typeof fetch !== 'undefined') {\n void fetch(beaconUrl, { method: 'POST', keepalive: true }).catch(() => {});\n }\n}\n\n/**\n * One-shot helper for landing-page download CTAs: fetches a signed URL,\n * navigates the current tab to the asset, then schedules the completion\n * beacon. The function resolves once the navigation has been triggered.\n */\nexport async function triggerDownload(config: DownloadConfig): Promise<IssuedDownload> {\n const issued = await issueDownload(config);\n const delay = config.beaconDelayMs ?? 1500;\n\n if (typeof window !== 'undefined') {\n window.location.href = issued.signedUrl;\n setTimeout(() => sendCompletionBeacon(issued.beaconUrl), delay);\n }\n\n return issued;\n}\n","import { checkoutUrl } from './checkout';\nimport { formatPrice } from './pricing';\nimport type { PricingTier, TierMeta } from './types';\n\nexport type IntervalKey = 'monthly' | 'yearly' | 'oneTime';\n\nexport type CtaProps = {\n label: string;\n href: string | null;\n disabled: boolean;\n monthlyHref: string | null;\n yearlyHref: string | null;\n oneTimeHref: string | null;\n};\n\nexport type CtaOptions = {\n billingBaseUrl: string;\n productKey: string;\n tierMeta?: TierMeta;\n interval?: IntervalKey;\n freeLabel?: string;\n subscribeLabel?: string;\n buyLabel?: string;\n comingSoonLabel?: string;\n};\n\nexport function isFreeTier(tier: PricingTier): boolean {\n return tier.monthly?.amount === 0 && tier.yearly === null && tier.oneTime === null;\n}\n\nexport function isOneTimeTier(tier: PricingTier): boolean {\n return tier.oneTime !== null && tier.monthly === null;\n}\n\nexport function hasYearly(tier: PricingTier): boolean {\n return tier.yearly !== null && tier.monthly !== null;\n}\n\n/**\n * Resolves all CTA fields for a tier — label, primary href, per-interval\n * hrefs (so a UI toggle can hot-swap without re-deriving), and disabled\n * state for coming-soon plans. Replaces hand-rolled if/else trees in\n * landing pages.\n */\nexport function getCtaProps(tier: PricingTier, opts: CtaOptions): CtaProps {\n const meta = opts.tierMeta;\n const monthlyHref = tier.monthly\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.monthly.planKey)\n : null;\n const yearlyHref = tier.yearly\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.yearly.planKey)\n : null;\n const oneTimeHref = tier.oneTime\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.oneTime.planKey)\n : null;\n\n if (tier.isComingSoon) {\n return {\n label: opts.comingSoonLabel ?? 'Coming soon',\n href: null,\n disabled: true,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n }\n\n if (meta?.ctaHref) {\n return {\n label: meta.ctaLabel ?? 'Get started',\n href: meta.ctaHref,\n disabled: false,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n }\n\n let primary: string | null;\n let defaultLabel: string;\n\n if (isFreeTier(tier)) {\n primary = null;\n defaultLabel = opts.freeLabel ?? 'Get started';\n } else if (isOneTimeTier(tier)) {\n primary = oneTimeHref;\n defaultLabel = opts.buyLabel ?? 'Buy';\n } else {\n primary = opts.interval === 'yearly' ? yearlyHref ?? monthlyHref : monthlyHref;\n defaultLabel = opts.subscribeLabel ?? 'Subscribe';\n }\n\n return {\n label: meta?.ctaLabel ?? defaultLabel,\n href: primary,\n disabled: false,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n}\n\nexport type FormattedPrice = {\n amount: string;\n suffix: string;\n raw: { amount: number; currency: string } | null;\n note?: string;\n};\n\n/**\n * Returns the price + suffix to render for a tier given the active\n * interval. Falls back gracefully: a tier with only monthly always\n * shows monthly; a free tier shows €0; a one-time tier shows the amount\n * with a 'one-time' suffix.\n */\nexport function getActivePrice(tier: PricingTier, interval: IntervalKey): FormattedPrice {\n if (interval === 'yearly' && tier.yearly) {\n return {\n amount: formatPrice(tier.yearly.amount, tier.yearly.currency),\n suffix: '/year',\n raw: { amount: tier.yearly.amount, currency: tier.yearly.currency },\n note: tier.yearly.monthsFree > 0 ? `${tier.yearly.monthsFree} months free` : undefined,\n };\n }\n\n if (interval === 'oneTime' && tier.oneTime) {\n return {\n amount: formatPrice(tier.oneTime.amount, tier.oneTime.currency),\n suffix: ' one-time',\n raw: { amount: tier.oneTime.amount, currency: tier.oneTime.currency },\n };\n }\n\n if (tier.monthly) {\n return {\n amount: formatPrice(tier.monthly.amount, tier.monthly.currency),\n suffix: '/month',\n raw: { amount: tier.monthly.amount, currency: tier.monthly.currency },\n };\n }\n\n if (tier.oneTime) {\n return {\n amount: formatPrice(tier.oneTime.amount, tier.oneTime.currency),\n suffix: ' one-time',\n raw: { amount: tier.oneTime.amount, currency: tier.oneTime.currency },\n };\n }\n\n return { amount: '—', suffix: '', raw: null };\n}\n\n/**\n * Picks the natural default interval for a list of tiers: 'yearly' if\n * any tier has a yearly option, else 'monthly'. Useful as the initial\n * state for a billing-interval toggle.\n */\nexport function defaultInterval(tiers: PricingTier[]): IntervalKey {\n if (tiers.some(hasYearly)) return 'monthly';\n if (tiers.every((t) => t.monthly === null && t.oneTime !== null)) return 'oneTime';\n return 'monthly';\n}\n","import type {\n LicenseSnapshotPayload,\n SignedLicense,\n UsageFeatureState,\n} from './client-types';\n\nexport interface DecodedLicense {\n raw: SignedLicense;\n payload: LicenseSnapshotPayload;\n}\n\nfunction base64Decode(input: string): Uint8Array<ArrayBuffer> {\n const bin = atob(input);\n const buf = new ArrayBuffer(bin.length);\n const out = new Uint8Array(buf);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nexport function decodeLicense(signed: SignedLicense): DecodedLicense {\n const payloadJson = new TextDecoder().decode(base64Decode(signed.payload));\n const payload = JSON.parse(payloadJson) as LicenseSnapshotPayload;\n return { raw: signed, payload };\n}\n\nexport async function verifyLicense(signed: SignedLicense, publicKeyBase64: string): Promise<boolean> {\n if (signed.algorithm !== 'ed25519') return false;\n\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('crypto.subtle not available; cannot verify license');\n\n const payloadBytes = base64Decode(signed.payload);\n const signatureBytes = base64Decode(signed.signature);\n const publicKeyBytes = base64Decode(publicKeyBase64);\n\n const key = await subtle.importKey(\n 'raw',\n publicKeyBytes,\n { name: 'Ed25519' } as AlgorithmIdentifier,\n false,\n ['verify'],\n );\n\n return subtle.verify({ name: 'Ed25519' } as AlgorithmIdentifier, key, signatureBytes, payloadBytes);\n}\n\nexport function computeRemaining(\n payload: LicenseSnapshotPayload,\n feature: string,\n consumedLocal = 0,\n): number | null {\n const state = payload.usage?.[feature];\n if (!state) return null;\n if (state.type === 'bool') return state.enabled ? Number.POSITIVE_INFINITY : 0;\n return Math.max(0, state.allowance - state.consumed_at_issue - consumedLocal);\n}\n\nexport function isUnlimited(state: UsageFeatureState | undefined): boolean {\n if (!state) return false;\n if (state.type === 'bool') return state.enabled;\n return state.allowance === 0;\n}\n\nexport function isExpired(payload: LicenseSnapshotPayload, now: Date = new Date()): boolean {\n return new Date(payload.valid_until).getTime() < now.getTime();\n}\n\nexport function isInGrace(\n payload: LicenseSnapshotPayload,\n graceSeconds: number,\n now: Date = new Date(),\n): boolean {\n const expiry = new Date(payload.valid_until).getTime();\n return now.getTime() <= expiry + graceSeconds * 1000;\n}\n\nexport function canUseUpdate(payload: LicenseSnapshotPayload, releaseDate: string | Date): boolean {\n const release = releaseDate instanceof Date ? releaseDate : new Date(releaseDate);\n\n const paidUpMs = payload.paid_up_until ? new Date(payload.paid_up_until).getTime() : null;\n const fallbackMs = payload.fallback_release_date\n ? new Date(payload.fallback_release_date).getTime()\n : null;\n\n if (paidUpMs === null && fallbackMs === null) return true;\n\n const effective = Math.max(paidUpMs ?? -Infinity, fallbackMs ?? -Infinity);\n const windowMs = (payload.updates_window_days ?? 0) * 86_400_000;\n return release.getTime() <= effective + windowMs;\n}\n\nexport function periodResetAt(payload: LicenseSnapshotPayload, feature: string): Date | null {\n const state = payload.usage?.[feature];\n if (!state || state.type !== 'counter') return null;\n return new Date(state.period_end);\n}\n","import type { BuildOauthInitUrlOptions, PkceChallenge } from './client-types';\n\nfunction bytesToUrlSafeBase64(bytes: Uint8Array): string {\n let bin = '';\n for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i] as number);\n return btoa(bin).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nfunction randomBytes(length: number): Uint8Array {\n const buf = new Uint8Array(length);\n globalThis.crypto.getRandomValues(buf);\n return buf;\n}\n\nexport async function generatePkceChallenge(): Promise<PkceChallenge> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('crypto.subtle not available; cannot generate PKCE challenge');\n\n const verifier = bytesToUrlSafeBase64(randomBytes(48));\n const hash = await subtle.digest('SHA-256', new TextEncoder().encode(verifier));\n const challenge = bytesToUrlSafeBase64(new Uint8Array(hash));\n\n return { verifier, challenge, method: 'S256' };\n}\n\nexport function generateOauthState(): string {\n return bytesToUrlSafeBase64(randomBytes(24));\n}\n\nexport function buildOauthInitUrl(opts: BuildOauthInitUrlOptions): string {\n const base = opts.baseUrl.replace(/\\/$/, '');\n const params = new URLSearchParams({\n product: opts.product,\n redirect_uri: opts.redirectUri,\n code_challenge: opts.codeChallenge,\n code_challenge_method: opts.codeChallengeMethod ?? 'S256',\n });\n if (opts.state) params.set('state', opts.state);\n\n return `${base}/auth/${opts.provider}?${params.toString()}`;\n}\n"]}
1
+ {"version":3,"sources":["../src/signature.ts","../src/client.ts","../src/pricing.ts","../src/checkout.ts","../src/downloads.ts","../src/helpers.ts","../src/license.ts","../src/oauth.ts","../src/lifecycle.ts","../src/gate.ts","../src/usage.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export const HEADER_PRODUCT = 'X-Akira-Product';\nexport const HEADER_TIMESTAMP = 'X-Akira-Timestamp';\nexport const HEADER_NONCE = 'X-Akira-Nonce';\nexport const HEADER_SIGNATURE = 'X-Akira-Signature';\n\nasync function sha256Hex(bytes: Uint8Array): Promise<string> {\n const digest = await getSubtle().digest('SHA-256', bytes as BufferSource);\n return bufferToHex(new Uint8Array(digest));\n}\n\nfunction getSubtle(): SubtleCrypto {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new Error('Web Crypto SubtleCrypto API is not available in this runtime.');\n }\n return subtle;\n}\n\nfunction bufferToHex(buffer: Uint8Array): string {\n let out = '';\n for (const byte of buffer) {\n out += byte.toString(16).padStart(2, '0');\n }\n return out;\n}\n\nexport function newNonce(): string {\n const buf = new Uint8Array(16);\n if (globalThis.crypto?.getRandomValues) {\n globalThis.crypto.getRandomValues(buf);\n } else {\n for (let i = 0; i < buf.length; i += 1) {\n buf[i] = Math.floor(Math.random() * 256);\n }\n }\n return bufferToHex(buf);\n}\n\nexport async function canonical(\n productSlug: string,\n timestamp: number,\n nonce: string,\n method: string,\n path: string,\n body: Uint8Array,\n): Promise<string> {\n const bodyHash = await sha256Hex(body);\n return `${productSlug}\\n${timestamp}\\n${nonce}\\n${method.toUpperCase()}\\n${path}\\n${bodyHash}`;\n}\n\nexport async function sign(productSecret: string, canonicalString: string): Promise<string> {\n const subtle = getSubtle();\n const keyData = new TextEncoder().encode(productSecret) as BufferSource;\n const key = await subtle.importKey(\n 'raw',\n keyData,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const sig = await subtle.sign('HMAC', key, new TextEncoder().encode(canonicalString) as BufferSource);\n return bufferToHex(new Uint8Array(sig));\n}\n","import {\n HEADER_NONCE,\n HEADER_PRODUCT,\n HEADER_SIGNATURE,\n HEADER_TIMESTAMP,\n canonical,\n newNonce,\n sign,\n} from './signature';\nimport type {\n BillingPortalResponse,\n Customer,\n EntitlementsResponse,\n LicenseActivatePayload,\n LicenseActivateResponse,\n LicenseCheckPayload,\n LicenseCheckResponse,\n LicensePublicKeysResponse,\n LicenseRefreshPayload,\n LicenseSyncUsagePayload,\n LicenseSyncUsageResponse,\n GithubAppInfo,\n GithubInstallationTokenPayload,\n GithubInstallationTokenResponse,\n GithubUserInstallationsResponse,\n OauthExchangePayload,\n OauthExchangeResponse,\n OauthProvidersResponse,\n OtpRequestPayload,\n OtpVerifyPayload,\n OtpVerifyResponse,\n UsagePayload,\n UsageResponse,\n} from './client-types';\n\nexport interface BillingClientConfig {\n baseUrl: string;\n productSlug: string;\n productSecret: string;\n customerToken?: string;\n fetcher?: typeof fetch;\n}\n\nexport class BillingApiError extends Error {\n status: number;\n code: string;\n constructor(status: number, code: string) {\n super(`billing api ${status}: ${code}`);\n this.status = status;\n this.code = code;\n }\n}\n\nexport class BillingClient {\n private readonly baseUrl: string;\n private readonly productSlug: string;\n private readonly productSecret: string;\n private customerToken: string | undefined;\n private readonly fetcher: typeof fetch;\n\n constructor(config: BillingClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.productSlug = config.productSlug;\n this.productSecret = config.productSecret;\n this.customerToken = config.customerToken;\n this.fetcher = config.fetcher ?? globalThis.fetch;\n if (!this.fetcher) {\n throw new Error('No fetch implementation available. Pass `fetcher` or use a runtime with global fetch.');\n }\n }\n\n setCustomerToken(token: string): void {\n this.customerToken = token;\n }\n\n async requestOtp(payload: OtpRequestPayload): Promise<void> {\n await this.signed('POST', '/api/auth/customer/otp/request', payload);\n }\n\n async verifyOtp(payload: OtpVerifyPayload): Promise<OtpVerifyResponse> {\n const res = await this.signed<OtpVerifyResponse>('POST', '/api/auth/customer/otp/verify', payload);\n this.setCustomerToken(res.access_token);\n return res;\n }\n\n async customerMe(): Promise<Customer> {\n return this.signed<Customer>('GET', '/api/me');\n }\n\n async licenseCheck(payload: LicenseCheckPayload): Promise<LicenseCheckResponse> {\n return this.signed<LicenseCheckResponse>('POST', '/api/licenses/check', payload);\n }\n\n async licenseActivate(payload: LicenseActivatePayload): Promise<LicenseActivateResponse> {\n return this.signed<LicenseActivateResponse>('POST', '/api/licenses/activate', payload);\n }\n\n async licenseRefresh(payload: LicenseRefreshPayload): Promise<LicenseActivateResponse> {\n return this.signed<LicenseActivateResponse>('POST', '/api/licenses/refresh', payload);\n }\n\n async licenseSyncUsage(payload: LicenseSyncUsagePayload): Promise<LicenseSyncUsageResponse> {\n return this.signed<LicenseSyncUsageResponse>('POST', '/api/licenses/sync-usage', payload);\n }\n\n async listOauthProviders(product: string): Promise<OauthProvidersResponse> {\n return this.signed<OauthProvidersResponse>('GET', `/api/v1/products/${encodeURIComponent(product)}/auth/providers`);\n }\n\n async exchangeOauthCode(payload: OauthExchangePayload): Promise<OauthExchangeResponse> {\n const res = await this.signed<OauthExchangeResponse>('POST', '/api/auth/oauth/exchange', payload);\n this.setCustomerToken(res.access_token);\n return res;\n }\n\n async githubInstallationToken(\n payload: GithubInstallationTokenPayload = {},\n ): Promise<GithubInstallationTokenResponse> {\n return this.signed<GithubInstallationTokenResponse>(\n 'POST',\n '/api/me/github/installation-token',\n payload,\n );\n }\n\n async meGithubInstallations(): Promise<GithubUserInstallationsResponse> {\n return this.signed<GithubUserInstallationsResponse>('GET', '/api/me/github/installations');\n }\n\n async entitlements(): Promise<EntitlementsResponse> {\n return this.signed<EntitlementsResponse>('GET', '/api/me/entitlements');\n }\n\n async billingPortal(returnUrl: string): Promise<BillingPortalResponse> {\n const path = `/api/billing/portal?return_url=${encodeURIComponent(returnUrl)}`;\n return this.signed<BillingPortalResponse>('GET', path);\n }\n\n async trackUsage(payload: UsagePayload): Promise<UsageResponse> {\n return this.signed<UsageResponse>('POST', '/api/me/usage', payload);\n }\n\n async trackAnonymousUsage(payload: UsagePayload): Promise<UsageResponse> {\n return this.signed<UsageResponse>('POST', '/api/v1/usage/anonymous', payload);\n }\n\n async publicLicenseKeys(): Promise<LicensePublicKeysResponse> {\n return this.unsigned<LicensePublicKeysResponse>('GET', '/api/v1/license-keys/public');\n }\n\n async githubAppInfo(): Promise<GithubAppInfo> {\n return this.unsigned<GithubAppInfo>('GET', '/api/v1/github/app');\n }\n\n private async signed<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const bodyBytes = body === undefined ? new Uint8Array() : new TextEncoder().encode(JSON.stringify(body));\n const timestamp = Math.floor(Date.now() / 1000);\n const nonce = newNonce();\n const canonicalString = await canonical(this.productSlug, timestamp, nonce, method, path, bodyBytes);\n const signature = await sign(this.productSecret, canonicalString);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n [HEADER_PRODUCT]: this.productSlug,\n [HEADER_TIMESTAMP]: String(timestamp),\n [HEADER_NONCE]: nonce,\n [HEADER_SIGNATURE]: signature,\n };\n if (bodyBytes.length > 0) headers['Content-Type'] = 'application/json';\n if (this.customerToken) headers.Authorization = `Bearer ${this.customerToken}`;\n\n const res = await this.fetcher(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: bodyBytes.length > 0 ? bodyBytes : undefined,\n });\n\n return this.parseResponse<T>(res);\n }\n\n private async unsigned<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const headers: Record<string, string> = { Accept: 'application/json' };\n let bodyInit: BodyInit | undefined;\n if (body !== undefined) {\n headers['Content-Type'] = 'application/json';\n bodyInit = JSON.stringify(body);\n }\n\n const res = await this.fetcher(`${this.baseUrl}${path}`, { method, headers, body: bodyInit });\n return this.parseResponse<T>(res);\n }\n\n private async parseResponse<T>(res: Response): Promise<T> {\n if (!res.ok) {\n let code: string;\n try {\n const parsed = (await res.json()) as { error?: string };\n code = parsed?.error ?? '';\n } catch {\n try {\n code = await res.text();\n } catch {\n code = '';\n }\n }\n throw new BillingApiError(res.status, code);\n }\n\n if (res.status === 204) {\n return undefined as T;\n }\n\n return (await res.json()) as T;\n }\n}\n","import type {\n BillingInterval,\n PricingFeature,\n PricingPayload,\n PricingTier,\n TierMeta,\n} from './types';\n\nexport type FetchPricingConfig = {\n baseUrl: string;\n productKey: string;\n tierMeta?: Record<string, TierMeta>;\n yearlyMonthsFree?: number;\n /** Override the global fetch (e.g. Node 18+ or custom retry). */\n fetcher?: typeof fetch;\n};\n\ntype ApiFeature = {\n key: string;\n name: string;\n description: string | null;\n};\n\ntype ApiPlan = {\n key: string;\n name: string;\n description: string | null;\n amount: number | null;\n currency: string | null;\n billing_interval: BillingInterval | null;\n trial_period_days: number;\n is_coming_soon?: boolean;\n features: ApiFeature[];\n};\n\ntype ApiPayload = {\n product: string;\n name: string;\n description: string | null;\n beta_active: boolean;\n plans: ApiPlan[];\n};\n\nconst INTERVAL_SUFFIXES = ['_monthly', '_yearly', '_month', '_year', '_one_time'];\n\nfunction tierKeyFromPlanKey(planKey: string): string {\n for (const suf of INTERVAL_SUFFIXES) {\n if (planKey.endsWith(suf)) {\n return planKey.slice(0, -suf.length);\n }\n }\n return planKey;\n}\n\nfunction titleCase(s: string): string {\n return s.replace(/[_-]+/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction emptyPayload(productKey: string): PricingPayload {\n return { product: productKey, betaActive: false, tiers: [] };\n}\n\nfunction shapeFromApi(payload: ApiPayload, config: FetchPricingConfig): PricingPayload {\n const meta = config.tierMeta ?? {};\n const monthsFree = config.yearlyMonthsFree ?? 2;\n const tiersMap = new Map<string, PricingTier>();\n\n for (const plan of payload.plans) {\n const tierKey = tierKeyFromPlanKey(plan.key);\n const m = meta[tierKey];\n\n if (!tiersMap.has(tierKey)) {\n tiersMap.set(tierKey, {\n key: tierKey,\n name: m?.label ?? titleCase(tierKey),\n tagline: m?.tagline ?? plan.description ?? '',\n highlighted: m?.highlighted ?? false,\n monthly: null,\n yearly: null,\n oneTime: null,\n isComingSoon: false,\n features: plan.features.map(\n (f): PricingFeature => ({ key: f.key, name: f.name, description: f.description }),\n ),\n });\n }\n\n const tier = tiersMap.get(tierKey)!;\n\n if (plan.is_coming_soon === true) {\n tier.isComingSoon = true;\n }\n\n if (tier.features.length === 0 && plan.features.length > 0) {\n tier.features = plan.features.map((f) => ({ key: f.key, name: f.name, description: f.description }));\n }\n\n if (plan.billing_interval === 'month' && plan.amount !== null && plan.currency !== null) {\n tier.monthly = { amount: plan.amount, currency: plan.currency, planKey: plan.key };\n continue;\n }\n\n if (plan.billing_interval === 'year' && plan.amount !== null && plan.currency !== null) {\n tier.yearly = { amount: plan.amount, currency: plan.currency, monthsFree, planKey: plan.key };\n continue;\n }\n\n if (plan.billing_interval === null) {\n const amount = plan.amount ?? 0;\n const currency = plan.currency ?? 'eur';\n if (amount === 0) {\n tier.monthly = { amount: 0, currency, planKey: plan.key };\n } else {\n tier.oneTime = { amount, currency, planKey: plan.key };\n }\n }\n }\n\n const tiers = Array.from(tiersMap.values()).sort((a, b) => {\n const oa = meta[a.key]?.order ?? 999;\n const ob = meta[b.key]?.order ?? 999;\n return oa - ob;\n });\n\n return {\n product: payload.product,\n betaActive: payload.beta_active,\n tiers,\n };\n}\n\nexport async function fetchPricing(config: FetchPricingConfig): Promise<PricingPayload> {\n const base = config.baseUrl?.replace(/\\/$/, '');\n if (!base) return emptyPayload(config.productKey);\n\n const f = config.fetcher ?? globalThis.fetch;\n if (!f) {\n throw new Error('No fetch implementation available. Pass a fetcher in config or use Node 18+.');\n }\n\n try {\n const res = await f(`${base}/api/v1/products/${config.productKey}/plans`, {\n headers: { Accept: 'application/json' },\n });\n if (!res.ok) return emptyPayload(config.productKey);\n const data = (await res.json()) as ApiPayload;\n return shapeFromApi(data, config);\n } catch {\n return emptyPayload(config.productKey);\n }\n}\n\nexport function formatPrice(amountInCents: number, currency: string): string {\n const symbol = currency.toLowerCase() === 'eur' ? '€' : currency.toUpperCase() + ' ';\n const major = (amountInCents / 100).toFixed(amountInCents % 100 === 0 ? 0 : 2);\n return `${symbol}${major}`;\n}\n\nexport type { PricingFeature, PricingPayload, PricingTier, TierMeta };\n","export function checkoutUrl(baseUrl: string, productKey: string, planKey: string): string {\n return `${baseUrl.replace(/\\/$/, '')}/subscribe/${productKey}/${planKey}`;\n}\n","import type { AssetPlatform, IssuedDownload, ReleaseChannel } from './types';\n\nexport type DownloadConfig = {\n baseUrl: string;\n product: string;\n channel: ReleaseChannel;\n platform: AssetPlatform;\n /** Optional UTM + landing tracking. */\n query?: Record<string, string | undefined>;\n /** Delay before firing the completion beacon, ms. Default 1500. */\n beaconDelayMs?: number;\n fetcher?: typeof fetch;\n};\n\nexport function downloadUrl(config: Pick<DownloadConfig, 'baseUrl' | 'product' | 'channel' | 'platform' | 'query'>): string {\n const base = config.baseUrl.replace(/\\/$/, '');\n const path = `/api/v1/downloads/${config.product}/${config.channel}/${config.platform}`;\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(config.query ?? {})) {\n if (v !== undefined && v !== '') params.set(k, v);\n }\n const qs = params.toString();\n return qs ? `${base}${path}?${qs}` : `${base}${path}`;\n}\n\n/**\n * Issues a download via the billing API and returns the signed asset URL +\n * beacon URL without redirecting. Useful when you want full control of the\n * UX (e.g. fetch then trigger your own `<a download>` flow).\n */\nexport async function issueDownload(config: DownloadConfig): Promise<IssuedDownload> {\n const f = config.fetcher ?? globalThis.fetch;\n if (!f) {\n throw new Error('No fetch implementation available. Pass a fetcher in config or use Node 18+.');\n }\n\n const url = downloadUrl(config);\n const res = await f(url, { headers: { Accept: 'application/json' } });\n\n if (!res.ok) {\n throw new Error(`download issue failed: HTTP ${res.status}`);\n }\n\n return (await res.json()) as IssuedDownload;\n}\n\n/**\n * Fires the completion beacon for an issued download. Uses\n * `navigator.sendBeacon` when available (survives page navigation), falls\n * back to `fetch` with `keepalive: true`. Safe to call at unload time.\n */\nexport function sendCompletionBeacon(beaconUrl: string): void {\n if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') {\n navigator.sendBeacon(beaconUrl);\n return;\n }\n\n if (typeof fetch !== 'undefined') {\n void fetch(beaconUrl, { method: 'POST', keepalive: true }).catch(() => {});\n }\n}\n\n/**\n * One-shot helper for landing-page download CTAs: fetches a signed URL,\n * navigates the current tab to the asset, then schedules the completion\n * beacon. The function resolves once the navigation has been triggered.\n */\nexport async function triggerDownload(config: DownloadConfig): Promise<IssuedDownload> {\n const issued = await issueDownload(config);\n const delay = config.beaconDelayMs ?? 1500;\n\n if (typeof window !== 'undefined') {\n window.location.href = issued.signedUrl;\n setTimeout(() => sendCompletionBeacon(issued.beaconUrl), delay);\n }\n\n return issued;\n}\n","import { checkoutUrl } from './checkout';\nimport { formatPrice } from './pricing';\nimport type { PricingTier, TierMeta } from './types';\n\nexport type IntervalKey = 'monthly' | 'yearly' | 'oneTime';\n\nexport type CtaProps = {\n label: string;\n href: string | null;\n disabled: boolean;\n monthlyHref: string | null;\n yearlyHref: string | null;\n oneTimeHref: string | null;\n};\n\nexport type CtaOptions = {\n billingBaseUrl: string;\n productKey: string;\n tierMeta?: TierMeta;\n interval?: IntervalKey;\n freeLabel?: string;\n subscribeLabel?: string;\n buyLabel?: string;\n comingSoonLabel?: string;\n};\n\nexport function isFreeTier(tier: PricingTier): boolean {\n return tier.monthly?.amount === 0 && tier.yearly === null && tier.oneTime === null;\n}\n\nexport function isOneTimeTier(tier: PricingTier): boolean {\n return tier.oneTime !== null && tier.monthly === null;\n}\n\nexport function hasYearly(tier: PricingTier): boolean {\n return tier.yearly !== null && tier.monthly !== null;\n}\n\n/**\n * Resolves all CTA fields for a tier — label, primary href, per-interval\n * hrefs (so a UI toggle can hot-swap without re-deriving), and disabled\n * state for coming-soon plans. Replaces hand-rolled if/else trees in\n * landing pages.\n */\nexport function getCtaProps(tier: PricingTier, opts: CtaOptions): CtaProps {\n const meta = opts.tierMeta;\n const monthlyHref = tier.monthly\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.monthly.planKey)\n : null;\n const yearlyHref = tier.yearly\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.yearly.planKey)\n : null;\n const oneTimeHref = tier.oneTime\n ? checkoutUrl(opts.billingBaseUrl, opts.productKey, tier.oneTime.planKey)\n : null;\n\n if (tier.isComingSoon) {\n return {\n label: opts.comingSoonLabel ?? 'Coming soon',\n href: null,\n disabled: true,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n }\n\n if (meta?.ctaHref) {\n return {\n label: meta.ctaLabel ?? 'Get started',\n href: meta.ctaHref,\n disabled: false,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n }\n\n let primary: string | null;\n let defaultLabel: string;\n\n if (isFreeTier(tier)) {\n primary = null;\n defaultLabel = opts.freeLabel ?? 'Get started';\n } else if (isOneTimeTier(tier)) {\n primary = oneTimeHref;\n defaultLabel = opts.buyLabel ?? 'Buy';\n } else {\n primary = opts.interval === 'yearly' ? yearlyHref ?? monthlyHref : monthlyHref;\n defaultLabel = opts.subscribeLabel ?? 'Subscribe';\n }\n\n return {\n label: meta?.ctaLabel ?? defaultLabel,\n href: primary,\n disabled: false,\n monthlyHref,\n yearlyHref,\n oneTimeHref,\n };\n}\n\nexport type FormattedPrice = {\n amount: string;\n suffix: string;\n raw: { amount: number; currency: string } | null;\n note?: string;\n};\n\n/**\n * Returns the price + suffix to render for a tier given the active\n * interval. Falls back gracefully: a tier with only monthly always\n * shows monthly; a free tier shows €0; a one-time tier shows the amount\n * with a 'one-time' suffix.\n */\nexport function getActivePrice(tier: PricingTier, interval: IntervalKey): FormattedPrice {\n if (interval === 'yearly' && tier.yearly) {\n return {\n amount: formatPrice(tier.yearly.amount, tier.yearly.currency),\n suffix: '/year',\n raw: { amount: tier.yearly.amount, currency: tier.yearly.currency },\n note: tier.yearly.monthsFree > 0 ? `${tier.yearly.monthsFree} months free` : undefined,\n };\n }\n\n if (interval === 'oneTime' && tier.oneTime) {\n return {\n amount: formatPrice(tier.oneTime.amount, tier.oneTime.currency),\n suffix: ' one-time',\n raw: { amount: tier.oneTime.amount, currency: tier.oneTime.currency },\n };\n }\n\n if (tier.monthly) {\n return {\n amount: formatPrice(tier.monthly.amount, tier.monthly.currency),\n suffix: '/month',\n raw: { amount: tier.monthly.amount, currency: tier.monthly.currency },\n };\n }\n\n if (tier.oneTime) {\n return {\n amount: formatPrice(tier.oneTime.amount, tier.oneTime.currency),\n suffix: ' one-time',\n raw: { amount: tier.oneTime.amount, currency: tier.oneTime.currency },\n };\n }\n\n return { amount: '—', suffix: '', raw: null };\n}\n\n/**\n * Picks the natural default interval for a list of tiers: 'yearly' if\n * any tier has a yearly option, else 'monthly'. Useful as the initial\n * state for a billing-interval toggle.\n */\nexport function defaultInterval(tiers: PricingTier[]): IntervalKey {\n if (tiers.some(hasYearly)) return 'monthly';\n if (tiers.every((t) => t.monthly === null && t.oneTime !== null)) return 'oneTime';\n return 'monthly';\n}\n","import type {\n LicenseSnapshotPayload,\n SignedLicense,\n UsageFeatureState,\n} from './client-types';\n\nexport interface DecodedLicense {\n raw: SignedLicense;\n payload: LicenseSnapshotPayload;\n}\n\nfunction base64Decode(input: string): Uint8Array<ArrayBuffer> {\n const bin = atob(input);\n const buf = new ArrayBuffer(bin.length);\n const out = new Uint8Array(buf);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nexport function decodeLicense(signed: SignedLicense): DecodedLicense {\n const payloadJson = new TextDecoder().decode(base64Decode(signed.payload));\n const payload = JSON.parse(payloadJson) as LicenseSnapshotPayload;\n return { raw: signed, payload };\n}\n\nexport async function verifyLicense(signed: SignedLicense, publicKeyBase64: string): Promise<boolean> {\n if (signed.algorithm !== 'ed25519') return false;\n\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('crypto.subtle not available; cannot verify license');\n\n const payloadBytes = base64Decode(signed.payload);\n const signatureBytes = base64Decode(signed.signature);\n const publicKeyBytes = base64Decode(publicKeyBase64);\n\n const key = await subtle.importKey(\n 'raw',\n publicKeyBytes,\n { name: 'Ed25519' } as AlgorithmIdentifier,\n false,\n ['verify'],\n );\n\n return subtle.verify({ name: 'Ed25519' } as AlgorithmIdentifier, key, signatureBytes, payloadBytes);\n}\n\nexport function computeRemaining(\n payload: LicenseSnapshotPayload,\n feature: string,\n consumedLocal = 0,\n): number | null {\n const state = payload.usage?.[feature];\n if (!state) return null;\n if (state.type === 'bool') return state.enabled ? Number.POSITIVE_INFINITY : 0;\n return Math.max(0, state.allowance - state.consumed_at_issue - consumedLocal);\n}\n\nexport function isUnlimited(state: UsageFeatureState | undefined): boolean {\n if (!state) return false;\n if (state.type === 'bool') return state.enabled;\n return state.allowance === 0;\n}\n\nexport function isExpired(payload: LicenseSnapshotPayload, now: Date = new Date()): boolean {\n return new Date(payload.valid_until).getTime() < now.getTime();\n}\n\nexport function isInGrace(\n payload: LicenseSnapshotPayload,\n graceSeconds: number,\n now: Date = new Date(),\n): boolean {\n const expiry = new Date(payload.valid_until).getTime();\n return now.getTime() <= expiry + graceSeconds * 1000;\n}\n\nexport function canUseUpdate(payload: LicenseSnapshotPayload, releaseDate: string | Date): boolean {\n const release = releaseDate instanceof Date ? releaseDate : new Date(releaseDate);\n\n const paidUpMs = payload.paid_up_until ? new Date(payload.paid_up_until).getTime() : null;\n const fallbackMs = payload.fallback_release_date\n ? new Date(payload.fallback_release_date).getTime()\n : null;\n\n if (paidUpMs === null && fallbackMs === null) return true;\n\n const effective = Math.max(paidUpMs ?? -Infinity, fallbackMs ?? -Infinity);\n const windowMs = (payload.updates_window_days ?? 0) * 86_400_000;\n return release.getTime() <= effective + windowMs;\n}\n\nexport function periodResetAt(payload: LicenseSnapshotPayload, feature: string): Date | null {\n const state = payload.usage?.[feature];\n if (!state || state.type !== 'counter') return null;\n return new Date(state.period_end);\n}\n","import type { BuildOauthInitUrlOptions, PkceChallenge } from './client-types';\n\nfunction bytesToUrlSafeBase64(bytes: Uint8Array): string {\n let bin = '';\n for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i] as number);\n return btoa(bin).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nfunction randomBytes(length: number): Uint8Array {\n const buf = new Uint8Array(length);\n globalThis.crypto.getRandomValues(buf);\n return buf;\n}\n\nexport async function generatePkceChallenge(): Promise<PkceChallenge> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('crypto.subtle not available; cannot generate PKCE challenge');\n\n const verifier = bytesToUrlSafeBase64(randomBytes(48));\n const hash = await subtle.digest('SHA-256', new TextEncoder().encode(verifier));\n const challenge = bytesToUrlSafeBase64(new Uint8Array(hash));\n\n return { verifier, challenge, method: 'S256' };\n}\n\nexport function generateOauthState(): string {\n return bytesToUrlSafeBase64(randomBytes(24));\n}\n\nexport function buildOauthInitUrl(opts: BuildOauthInitUrlOptions): string {\n const base = opts.baseUrl.replace(/\\/$/, '');\n const params = new URLSearchParams({\n product: opts.product,\n redirect_uri: opts.redirectUri,\n code_challenge: opts.codeChallenge,\n code_challenge_method: opts.codeChallengeMethod ?? 'S256',\n });\n if (opts.state) params.set('state', opts.state);\n\n return `${base}/auth/${opts.provider}?${params.toString()}`;\n}\n","import type { LicenseSnapshotPayload } from './client-types';\n\nexport type LicenseState = 'none' | 'invalid' | 'active' | 'trialing' | 'grace' | 'expired';\n\nexport function computeState(\n payload: LicenseSnapshotPayload | null | undefined,\n graceWindowMs: number,\n now: Date = new Date(),\n): LicenseState {\n if (!payload) return 'none';\n if (!payload.valid_until) return 'invalid';\n\n const expiry = Date.parse(payload.valid_until);\n if (Number.isNaN(expiry)) return 'invalid';\n\n const nowMs = now.getTime();\n if (nowMs <= expiry) {\n return isTrialPayload(payload) ? 'trialing' : 'active';\n }\n\n const cutoff = expiry + graceWindowMs;\n if (nowMs <= cutoff) return 'grace';\n return 'expired';\n}\n\nexport function trialDaysLeft(\n payload: LicenseSnapshotPayload | null | undefined,\n now: Date = new Date(),\n): number {\n if (!payload || !isTrialPayload(payload)) return 0;\n const expiry = Date.parse(payload.valid_until);\n if (Number.isNaN(expiry)) return 0;\n const delta = expiry - now.getTime();\n if (delta <= 0) return 0;\n const dayMs = 24 * 60 * 60 * 1000;\n return Math.ceil(delta / dayMs);\n}\n\nfunction isTrialPayload(payload: LicenseSnapshotPayload): boolean {\n if (payload.features?.__trial === true) return true;\n if (payload.plan_key && payload.plan_key.endsWith(':trial')) return true;\n return false;\n}\n","import type { LicenseSnapshotPayload, SignedLicense } from './client-types';\nimport { computeRemaining } from './license';\nimport { computeState, type LicenseState } from './lifecycle';\n\nexport interface LoadedLicense {\n license: SignedLicense;\n payload: LicenseSnapshotPayload;\n}\n\nexport type LicenseLoader = () => Promise<LoadedLicense | null>;\nexport type LocalConsumptionFn = (feature: string) => Promise<number> | number;\n\nexport interface GateOptions {\n loader: LicenseLoader;\n localConsumption?: LocalConsumptionFn;\n graceWindowMs?: number;\n now?: () => Date;\n}\n\nexport interface FeatureAccess {\n feature: string;\n allowed: boolean;\n hasFeature: boolean;\n unlimited: boolean;\n remaining: number;\n reason: string;\n plan: string;\n state: LicenseState;\n}\n\nexport class GateDeniedError extends Error {\n readonly access: FeatureAccess;\n\n constructor(access: FeatureAccess) {\n super(`billing: feature \"${access.feature}\" denied (${access.reason})`);\n this.name = 'GateDeniedError';\n this.access = access;\n }\n}\n\nexport function isGateDenied(err: unknown): err is GateDeniedError {\n return err instanceof GateDeniedError;\n}\n\nexport class Gate {\n private readonly loader: LicenseLoader;\n private readonly localConsumption: LocalConsumptionFn;\n private readonly graceWindowMs: number;\n private readonly now: () => Date;\n private inflight: Promise<FeatureAccess> | null = null;\n\n constructor(opts: GateOptions) {\n if (!opts.loader) throw new Error('billing: Gate requires loader');\n this.loader = opts.loader;\n this.localConsumption = opts.localConsumption ?? (() => 0);\n this.graceWindowMs = opts.graceWindowMs ?? 0;\n this.now = opts.now ?? (() => new Date());\n }\n\n async check(feature: string): Promise<FeatureAccess> {\n const prev = this.inflight;\n const run = (async () => {\n if (prev) {\n try {\n await prev;\n } catch {\n /* prior failure does not block current call */\n }\n }\n return this.evaluate(feature);\n })();\n this.inflight = run.catch(() => ({}) as FeatureAccess) as Promise<FeatureAccess>;\n return run;\n }\n\n async require(feature: string): Promise<FeatureAccess> {\n const access = await this.check(feature);\n if (!access.allowed) throw new GateDeniedError(access);\n return access;\n }\n\n private async evaluate(feature: string): Promise<FeatureAccess> {\n const access: FeatureAccess = {\n feature,\n allowed: false,\n hasFeature: false,\n unlimited: false,\n remaining: 0,\n reason: '',\n plan: '',\n state: 'none',\n };\n\n let loaded: LoadedLicense | null;\n try {\n loaded = await this.loader();\n } catch (err) {\n access.reason = 'verify_failed';\n throw Object.assign(err instanceof Error ? err : new Error(String(err)), { access });\n }\n\n if (!loaded) {\n access.reason = 'no_license';\n return access;\n }\n\n const { payload } = loaded;\n access.plan = payload.plan_key;\n access.state = computeState(payload, this.graceWindowMs, this.now());\n\n if (access.state === 'expired' || access.state === 'invalid') {\n access.reason = `license_${access.state}`;\n return access;\n }\n\n const featureFlag = payload.features?.[feature];\n if (featureFlag !== undefined) {\n access.hasFeature = featureFlag;\n if (!featureFlag) {\n access.reason = 'feature_disabled';\n return access;\n }\n }\n\n let consumed: number;\n try {\n consumed = await this.localConsumption(feature);\n } catch (err) {\n access.reason = 'local_consumption_failed';\n throw Object.assign(err instanceof Error ? err : new Error(String(err)), { access });\n }\n\n const remaining = computeRemaining(payload, feature, consumed);\n if (remaining === null) {\n if (access.hasFeature) {\n access.allowed = true;\n access.unlimited = true;\n return access;\n }\n access.reason = 'feature_missing';\n return access;\n }\n\n if (remaining === Number.POSITIVE_INFINITY) {\n access.unlimited = true;\n access.hasFeature = true;\n access.allowed = true;\n return access;\n }\n\n access.remaining = remaining;\n if (remaining > 0) {\n access.allowed = true;\n access.hasFeature = true;\n return access;\n }\n\n access.reason = 'limit_reached';\n return access;\n }\n}\n","import type { LicenseSyncUsageResponse } from './client-types';\n\nexport interface UsageBuffer {\n add(feature: string, delta: number): Promise<void> | void;\n drain(): Promise<Record<string, number>> | Record<string, number>;\n restore(deltas: Record<string, number>): Promise<void> | void;\n}\n\nexport class MemoryBuffer implements UsageBuffer {\n private state: Record<string, number> = {};\n\n add(feature: string, delta: number): void {\n if (delta === 0) return;\n this.state[feature] = (this.state[feature] ?? 0) + delta;\n }\n\n drain(): Record<string, number> {\n const out = this.state;\n this.state = {};\n return out;\n }\n\n restore(deltas: Record<string, number>): void {\n for (const [k, v] of Object.entries(deltas)) {\n this.state[k] = (this.state[k] ?? 0) + v;\n }\n }\n}\n\nexport type SyncUsageFn = (\n deltas: Record<string, number>,\n serial: number,\n) => Promise<LicenseSyncUsageResponse>;\n\nexport type SerialProviderFn = () => Promise<number> | number;\nexport type RefreshHandlerFn = (resp: LicenseSyncUsageResponse) => Promise<void> | void;\n\nexport interface UsageTrackerOptions {\n buffer: UsageBuffer;\n sync: SyncUsageFn;\n serial?: SerialProviderFn;\n onRefresh?: RefreshHandlerFn;\n flushIntervalMs?: number;\n}\n\nconst DEFAULT_FLUSH_INTERVAL_MS = 5 * 60 * 1000;\n\nexport class UsageTracker {\n private readonly buffer: UsageBuffer;\n private readonly sync: SyncUsageFn;\n private readonly serial?: SerialProviderFn;\n private readonly onRefresh?: RefreshHandlerFn;\n private readonly flushIntervalMs: number;\n private timer: ReturnType<typeof setInterval> | null = null;\n private running = false;\n\n constructor(opts: UsageTrackerOptions) {\n if (!opts.buffer) throw new Error('billing: tracker requires buffer');\n if (!opts.sync) throw new Error('billing: tracker requires sync');\n this.buffer = opts.buffer;\n this.sync = opts.sync;\n if (opts.serial !== undefined) this.serial = opts.serial;\n if (opts.onRefresh !== undefined) this.onRefresh = opts.onRefresh;\n this.flushIntervalMs =\n opts.flushIntervalMs && opts.flushIntervalMs > 0\n ? opts.flushIntervalMs\n : DEFAULT_FLUSH_INTERVAL_MS;\n }\n\n async track(feature: string, delta: number): Promise<void> {\n if (delta === 0) return;\n await this.buffer.add(feature, delta);\n }\n\n async flush(): Promise<void> {\n const deltas = await this.buffer.drain();\n if (!deltas || Object.keys(deltas).length === 0) return;\n\n let serial = 0;\n if (this.serial) {\n try {\n serial = await this.serial();\n } catch (err) {\n await this.buffer.restore(deltas);\n throw err;\n }\n }\n\n let resp: LicenseSyncUsageResponse;\n try {\n resp = await this.sync(deltas, serial);\n } catch (err) {\n await this.buffer.restore(deltas);\n throw err;\n }\n\n if (this.onRefresh && resp) {\n await this.onRefresh(resp);\n }\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n this.timer = setInterval(() => {\n void this.flush().catch(() => {\n /* swallow; next tick retries via restored buffer */\n });\n }, this.flushIntervalMs);\n }\n\n async stop(): Promise<void> {\n if (!this.running) return;\n this.running = false;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n await this.flush();\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akira-io/billing-js",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
4
  "description": "TypeScript client for the Akira Billing API. Pricing, downloads, checkout helpers for landing pages and web apps.",
5
5
  "license": "MIT",
6
6
  "type": "module",