@sidub-inc/licensing-client 1.3.43

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.
@@ -0,0 +1,1058 @@
1
+ import React, { ReactNode } from 'react';
2
+
3
+ /**
4
+ * Error class for licensing-related errors
5
+ */
6
+ declare class LicensingError extends Error {
7
+ statusCode?: number | undefined;
8
+ response?: unknown | undefined;
9
+ constructor(message: string, statusCode?: number | undefined, response?: unknown | undefined);
10
+ }
11
+
12
+ /**
13
+ * License classification types
14
+ */
15
+ declare enum LicenseClassificationType {
16
+ /** Perpetual license with no expiration */
17
+ Perpetual = "Perpetual",
18
+ /** Subscription license with recurring billing */
19
+ Subscription = "Subscription",
20
+ /** Trial license with time-based expiration */
21
+ Trial = "Trial"
22
+ }
23
+ /**
24
+ * Normalizes a license classification value from server integer or string to the TypeScript enum.
25
+ * The .NET server serializes enums as integers (0=Trial, 1=Subscription, 2=Perpetual).
26
+ */
27
+ declare function normalizeLicenseClassificationType(value: number | string | null | undefined): LicenseClassificationType | undefined;
28
+ /**
29
+ * Billing interval units for subscription licenses.
30
+ * Matches .NET BillingIntervalUnit enum with singular names.
31
+ */
32
+ declare enum BillingIntervalUnit {
33
+ Hour = "Hour",
34
+ Day = "Day",
35
+ Week = "Week",
36
+ Month = "Month",
37
+ Year = "Year"
38
+ }
39
+ /**
40
+ * Normalizes a billing interval unit value from server integer or string to the TypeScript enum.
41
+ */
42
+ declare function normalizeBillingIntervalUnit(value: number | string | null | undefined): BillingIntervalUnit | undefined;
43
+
44
+ /**
45
+ * Base interface for license features
46
+ */
47
+ interface ILicenseFeature {
48
+ /** Unique identifier for the feature type */
49
+ featureId: string;
50
+ }
51
+ /**
52
+ * Rate agreement for subscription-based licenses
53
+ */
54
+ interface RateAgreement {
55
+ /** Amount charged per billing interval */
56
+ amount: number;
57
+ /** Currency code (e.g., 'USD', 'EUR') */
58
+ currency: string;
59
+ /** Billing interval (e.g., 1, 3, 12) */
60
+ billingInterval?: number;
61
+ /** Unit of billing interval */
62
+ billingIntervalUnit?: BillingIntervalUnit;
63
+ }
64
+ /**
65
+ * License information returned from the server
66
+ */
67
+ interface License {
68
+ /** Unique identifier for the license */
69
+ licenseId: string;
70
+ /** Client ID this license belongs to */
71
+ clientId: string;
72
+ /** Issuer client ID */
73
+ issuerClientId: string;
74
+ /** License classification */
75
+ classification: LicenseClassificationType;
76
+ /** Display name for the license */
77
+ name: string;
78
+ /** Features included in the license */
79
+ features?: ILicenseFeature[];
80
+ /** Rate agreement for subscription licenses */
81
+ rateAgreement?: RateAgreement;
82
+ /** Creation timestamp */
83
+ createdAt?: Date;
84
+ /** Last updated timestamp */
85
+ updatedAt?: Date;
86
+ }
87
+ /**
88
+ * License authorization containing validated license information.
89
+ * Includes cryptographic signature for integrity verification.
90
+ */
91
+ interface LicenseAuthorization {
92
+ /** Unique identifier for the authorization */
93
+ authorizationId?: string;
94
+ /** Unique identifier for the license */
95
+ licenseId: string;
96
+ /** License classification */
97
+ classification: LicenseClassificationType;
98
+ /** Features available in this authorization */
99
+ features: ILicenseFeature[];
100
+ /** When this authorization was issued */
101
+ issuedAt: Date;
102
+ /** When this authorization expires (optional) */
103
+ expiresAt?: Date;
104
+ /** Base64-encoded cryptographic signature for integrity verification */
105
+ signature?: string;
106
+ /** Whether signature has been validated */
107
+ signatureValidated?: boolean;
108
+ }
109
+ /**
110
+ * License feature state operation for consumption reporting
111
+ */
112
+ interface LicenseFeatureStateOperation<T extends ILicenseFeature> {
113
+ /** License ID */
114
+ licenseId: string;
115
+ /** Feature being consumed */
116
+ feature: T;
117
+ /** Operation type (e.g., 'increment', 'decrement') */
118
+ operationType: string;
119
+ /** Quantity of consumption */
120
+ quantity?: number;
121
+ /** Timestamp of the operation */
122
+ timestamp: Date;
123
+ /** Additional metadata */
124
+ metadata?: Record<string, unknown>;
125
+ }
126
+ /**
127
+ * Configuration for the licensing client
128
+ */
129
+ interface LicensingConfig {
130
+ /** Base URI for the licensing service */
131
+ licenseServiceUri: string;
132
+ /** Optional: Base URI for consumption reporting service */
133
+ consumptionServiceUri?: string;
134
+ /** Optional: Default API key for authentication */
135
+ apiKey?: string;
136
+ /** Optional: Timeout for HTTP requests in milliseconds */
137
+ timeout?: number;
138
+ /**
139
+ * Optional: Encoded credential string (SIDUB_LIC_...) containing all license credentials.
140
+ * If provided, this will be decoded to extract licenseId, serviceKeyId, serviceKeyPublicMember, and apiKey.
141
+ */
142
+ encodedCredential?: string;
143
+ /** Optional: Service key ID for signature verification (extracted from encodedCredential if not set) */
144
+ serviceKeyId?: string;
145
+ /** Optional: Base64-encoded public key for signature verification (extracted from encodedCredential if not set) */
146
+ serviceKeyPublicMember?: string;
147
+ /** Optional: License ID (extracted from encodedCredential if not set) */
148
+ licenseId?: string;
149
+ /**
150
+ * Optional: Whether to validate authorization signatures (default: true if crypto config available).
151
+ * Set to false to disable signature validation (not recommended for production).
152
+ */
153
+ validateSignatures?: boolean;
154
+ /** Optional: Billable resource ID for consumption metering (GUID string) */
155
+ billableResourceId?: string;
156
+ /** Optional: Billable plan ID for consumption metering */
157
+ billablePlanId?: string;
158
+ /** Optional: Enable or disable authorization caching (default: true) */
159
+ cacheEnabled?: boolean;
160
+ /** Optional: Maximum number of cached authorizations (default: 100) */
161
+ cacheMaxSize?: number;
162
+ /** Optional: Custom context provider for multi-tenant credential resolution */
163
+ contextProvider?: {
164
+ resolveContext(): Promise<{
165
+ licenseId: string;
166
+ serviceKeyId: string;
167
+ serviceKeyPublicMember: string;
168
+ apiAccessKey: string;
169
+ billableResourceId?: string;
170
+ billablePlanId?: string;
171
+ } | null>;
172
+ };
173
+ }
174
+ /**
175
+ * Client license configuration
176
+ */
177
+ interface ClientLicenseConfiguration {
178
+ /** Client ID */
179
+ clientId: string;
180
+ /** API key for the client */
181
+ apiKey: string;
182
+ /** Configuration metadata */
183
+ metadata?: Record<string, unknown>;
184
+ }
185
+
186
+ /**
187
+ * Licensing credential containing the essential license identification and authentication values.
188
+ * This matches the .NET LicensingCredential record for cross-platform compatibility.
189
+ */
190
+ interface LicensingCredential {
191
+ /** Unique identifier for the license */
192
+ licenseId: string;
193
+ /** Unique identifier for the service key used for signature verification */
194
+ serviceKeyId: string;
195
+ /** Base64-encoded public key for signature verification */
196
+ serviceKeyPublicMember: string;
197
+ /** API access key for authentication */
198
+ apiAccessKey: string;
199
+ }
200
+ /**
201
+ * Encodes a licensing credential to a portable string.
202
+ * This matches the .NET LicensingCredential.ToEncodedString() format.
203
+ *
204
+ * @param credential The credential to encode
205
+ * @returns A portable encoded string prefixed with SIDUB_LIC_
206
+ */
207
+ declare function encodeCredential(credential: LicensingCredential): string;
208
+ /**
209
+ * Decodes a licensing credential from an encoded string.
210
+ * This matches the .NET LicensingCredential.FromEncodedString() format.
211
+ *
212
+ * @param encodedString The encoded credential string
213
+ * @returns The decoded credential
214
+ * @throws {Error} If the format is invalid
215
+ */
216
+ declare function decodeCredential(encodedString: string): LicensingCredential;
217
+ /**
218
+ * Attempts to parse an encoded credential string.
219
+ *
220
+ * @param encodedString The encoded credential string
221
+ * @returns The decoded credential, or null if parsing failed
222
+ */
223
+ declare function tryDecodeCredential(encodedString: string | null | undefined): LicensingCredential | null;
224
+ /**
225
+ * Validates that a credential has all required fields for signature verification.
226
+ *
227
+ * @param credential The credential to validate
228
+ * @returns True if the credential has all required cryptography fields
229
+ */
230
+ declare function hasValidCryptoConfig(credential: LicensingCredential | null | undefined): boolean;
231
+
232
+ /**
233
+ * Extended feature interface that accounts for server response casing variations.
234
+ * The server may return features with PascalCase (FeatureKey) or camelCase (featureId).
235
+ */
236
+ interface ServerFeature extends ILicenseFeature {
237
+ /** Server-side PascalCase feature key */
238
+ FeatureKey?: string;
239
+ /** Server-side service access level (PascalCase, may be string or integer) */
240
+ ServiceAccessLevel?: string | number;
241
+ /** Server-side sample seconds (PascalCase) */
242
+ SampleSeconds?: number;
243
+ /** Server-side rate limit (PascalCase) */
244
+ RateLimit?: number;
245
+ /** Server-side current consumption (PascalCase) */
246
+ CurrentConsumption?: number;
247
+ /** Client-side service access level (camelCase) */
248
+ serviceAccessLevel?: string;
249
+ /** Client-side sample seconds (camelCase) */
250
+ sampleSeconds?: number;
251
+ /** Client-side rate limit (camelCase) */
252
+ rateLimit?: number;
253
+ /** Client-side current consumption (camelCase) */
254
+ currentConsumption?: number;
255
+ /** Additional server properties */
256
+ [key: string]: unknown;
257
+ }
258
+ /**
259
+ * Gets the normalized feature key from a feature object.
260
+ * Handles both client-side (featureId) and server-side (FeatureKey) naming conventions.
261
+ *
262
+ * @param feature The feature object to extract the key from
263
+ * @returns The feature key, or empty string if not found
264
+ */
265
+ declare function getFeatureKey(feature: ILicenseFeature | ServerFeature): string;
266
+ /**
267
+ * Checks if a feature matches the specified feature key.
268
+ * Handles both client-side (featureId) and server-side (FeatureKey) naming conventions.
269
+ *
270
+ * @param feature The feature to check
271
+ * @param featureKey The key to match against
272
+ * @returns True if the feature matches the key
273
+ */
274
+ declare function matchesFeatureKey(feature: ILicenseFeature | ServerFeature, featureKey: string): boolean;
275
+ /**
276
+ * Finds a feature by key in a feature array.
277
+ *
278
+ * @param features Array of features to search
279
+ * @param featureKey The key to find
280
+ * @returns The matching feature, or undefined if not found
281
+ */
282
+ declare function findFeatureByKey<T extends ILicenseFeature>(features: T[] | undefined | null, featureKey: string): T | undefined;
283
+ /**
284
+ * Checks if a feature with the specified key exists in the array.
285
+ *
286
+ * @param features Array of features to search
287
+ * @param featureKey The key to check for
288
+ * @returns True if a feature with the key exists
289
+ */
290
+ declare function hasFeature(features: ILicenseFeature[] | undefined | null, featureKey: string): boolean;
291
+
292
+ /**
293
+ * Status of a checkout session.
294
+ */
295
+ type CheckoutSessionStatus = 'pending' | 'completed' | 'failed';
296
+ /**
297
+ * Request parameters for creating an embedded checkout session.
298
+ * Matches .NET CreateCheckoutSessionParameters entity.
299
+ */
300
+ interface CheckoutRequest {
301
+ /** The offering to purchase */
302
+ offeringId: string;
303
+ /** The issuer client ID */
304
+ issuerClientId: string;
305
+ /** Correlation ID for tracking this checkout across systems */
306
+ correlationId: string;
307
+ /** Customer email address */
308
+ customerEmail: string;
309
+ /** URL to redirect to on successful checkout (absolute HTTPS URL) */
310
+ successUrl?: string;
311
+ /** URL to redirect to on cancelled checkout (absolute HTTPS URL) */
312
+ cancelUrl?: string;
313
+ }
314
+ /**
315
+ * Response from creating a checkout session.
316
+ * Matches .NET CheckoutSession entity.
317
+ */
318
+ interface CheckoutSession {
319
+ /** Unique session identifier */
320
+ sessionId: string;
321
+ /** Payment provider URL for checkout (null for free/trial offerings) */
322
+ sessionUrl?: string | null;
323
+ }
324
+ /**
325
+ * Result of polling a checkout session for completion.
326
+ * Matches .NET CheckoutSessionResult entity.
327
+ */
328
+ interface CheckoutSessionResult {
329
+ /** Current session status */
330
+ status: CheckoutSessionStatus;
331
+ /** Correlation ID from the original request */
332
+ correlationId?: string;
333
+ /** Encoded licensing credential (SIDUB_LIC_...) — present when status is 'completed' */
334
+ encodedCredential?: string;
335
+ /** License ID provisioned by checkout — present when status is 'completed' */
336
+ licenseId?: string;
337
+ /** Offering ID from the original request */
338
+ offeringId?: string;
339
+ /** Error message — present when status is 'failed' */
340
+ error?: string;
341
+ }
342
+
343
+ /**
344
+ * Base interface for license assertions.
345
+ * Assertions encapsulate the logic for checking if a license satisfies specific conditions.
346
+ *
347
+ * @typeParam _T The type of license feature this assertion operates on (for documentation purposes)
348
+ */
349
+ interface ILicenseAssertion<_T extends ILicenseFeature = ILicenseFeature> {
350
+ /**
351
+ * The feature key identifying the license feature this assertion targets.
352
+ */
353
+ readonly featureKey: string;
354
+ /**
355
+ * Evaluates whether the assertion is satisfied for the given authorization.
356
+ * @param authorization The license authorization to evaluate
357
+ * @returns True if the assertion is satisfied, false otherwise
358
+ */
359
+ isSatisfied(authorization: LicenseAuthorization): boolean;
360
+ }
361
+ /**
362
+ * Base class for implementing license assertions.
363
+ * Provides a foundation for creating custom assertion logic.
364
+ *
365
+ * @typeParam T The type of license feature this assertion operates on
366
+ */
367
+ declare abstract class LicenseAssertion<T extends ILicenseFeature = ILicenseFeature> implements ILicenseAssertion<T> {
368
+ /**
369
+ * The feature key identifying the license feature this assertion targets.
370
+ */
371
+ abstract readonly featureKey: string;
372
+ /**
373
+ * Evaluates whether the assertion is satisfied.
374
+ * Must be implemented by derived classes.
375
+ */
376
+ abstract isSatisfied(authorization: LicenseAuthorization): boolean;
377
+ }
378
+
379
+ /**
380
+ * Service access level types
381
+ */
382
+ declare enum ServiceAccessLevel {
383
+ Denied = "Denied",
384
+ Allowed = "Allowed"
385
+ }
386
+ /**
387
+ * Normalizes a service access level value from server integer or string to the TypeScript enum.
388
+ * The .NET server serializes enums as integers (0=Denied, 1=Allowed).
389
+ */
390
+ declare function normalizeServiceAccessLevel(value: number | string | null | undefined): ServiceAccessLevel | undefined;
391
+ /**
392
+ * Service access license feature with access control
393
+ */
394
+ interface ServiceAccessLicenseFeature extends ILicenseFeature {
395
+ featureId: string;
396
+ /** Service type identifier */
397
+ serviceType?: string;
398
+ /** Access level for this feature */
399
+ serviceAccessLevel?: ServiceAccessLevel;
400
+ }
401
+ /**
402
+ * Assertion that checks if a service/feature has the required access level.
403
+ *
404
+ * @example
405
+ * ```typescript
406
+ * // Check if 'premium-features' is allowed
407
+ * const assertion = ServiceAccessAssertion.create('premium-features', ServiceAccessLevel.Allowed);
408
+ * const hasAccess = assertion.isSatisfied(authorization);
409
+ * ```
410
+ */
411
+ declare class ServiceAccessAssertion extends LicenseAssertion<ServiceAccessLicenseFeature> {
412
+ readonly requiredAccessLevel: ServiceAccessLevel;
413
+ readonly serviceType?: string | undefined;
414
+ readonly featureKey: string;
415
+ /**
416
+ * Creates a new service access assertion
417
+ * @param featureKey The feature key to check
418
+ * @param requiredAccessLevel The required access level (default: Allowed)
419
+ * @param serviceType Optional service type to filter by
420
+ */
421
+ constructor(featureKey: string, requiredAccessLevel?: ServiceAccessLevel, serviceType?: string | undefined);
422
+ /**
423
+ * Checks if the authorization contains the feature with the required access level
424
+ */
425
+ isSatisfied(authorization: LicenseAuthorization): boolean;
426
+ /**
427
+ * Factory method to create a service access assertion
428
+ * @param featureKey The feature key to check
429
+ * @param requiredAccessLevel The required access level (default: Allowed)
430
+ * @param serviceType Optional service type to filter by
431
+ */
432
+ static create(featureKey: string, requiredAccessLevel?: ServiceAccessLevel, serviceType?: string): ServiceAccessAssertion;
433
+ }
434
+
435
+ /**
436
+ * Tracks timestamped consumption metrics for a rate-limited feature.
437
+ * Mirrors the .NET RateLimitLicenseFeatureState pattern.
438
+ *
439
+ * Entries older than sampleSeconds are pruned on every getConsumption() call.
440
+ * Local state is additive/conservative — may over-count (safer than under-counting).
441
+ */
442
+ declare class RateLimitFeatureState {
443
+ private metrics;
444
+ private sampleSeconds;
445
+ constructor(sampleSeconds: number);
446
+ /** Records a consumption event with the current timestamp */
447
+ consumeRate(amount: number): void;
448
+ /** Returns total consumption within the sample window, pruning stale entries */
449
+ getConsumption(): number;
450
+ }
451
+
452
+ /**
453
+ * Rate limit license feature with consumption tracking
454
+ */
455
+ interface RateLimitLicenseFeature extends ILicenseFeature {
456
+ featureId: string;
457
+ /** Sample period in seconds */
458
+ sampleSeconds?: number;
459
+ /** Rate limit (max requests per sample period) */
460
+ rateLimit?: number;
461
+ /** Current consumption count */
462
+ currentConsumption?: number;
463
+ }
464
+ /**
465
+ * Assertion that checks if a rate-limited feature is within its limit.
466
+ *
467
+ * @example
468
+ * ```typescript
469
+ * // Key-based construction (preferred)
470
+ * const assertion = RateLimitAssertion.create('api-calls');
471
+ * const withinLimit = assertion.isSatisfied(authorization);
472
+ *
473
+ * // Feature-based construction (when you already have the feature)
474
+ * const assertion = RateLimitAssertion.create(feature);
475
+ * ```
476
+ */
477
+ declare class RateLimitAssertion extends LicenseAssertion<RateLimitLicenseFeature> {
478
+ readonly featureKey: string;
479
+ /**
480
+ * Creates a new rate limit assertion.
481
+ * @param featureKeyOrFeature A feature key string or a rate limit feature instance.
482
+ */
483
+ constructor(featureKeyOrFeature: string | RateLimitLicenseFeature);
484
+ /**
485
+ * Checks if the feature's consumption is within its rate limit.
486
+ * Prefers local feature state when available, falls back to server currentConsumption.
487
+ */
488
+ isSatisfied(authorization: LicenseAuthorization, featureStates?: Map<string, RateLimitFeatureState>): boolean;
489
+ /**
490
+ * Factory method to create a rate limit assertion from a feature key.
491
+ * @param featureKey The feature key to check
492
+ */
493
+ static create(featureKey: string): RateLimitAssertion;
494
+ /**
495
+ * Factory method to create a rate limit assertion from a feature instance.
496
+ * @param feature The rate limit feature to check
497
+ */
498
+ static create(feature: RateLimitLicenseFeature): RateLimitAssertion;
499
+ }
500
+
501
+ /**
502
+ * Assertion that checks if a feature with a specific key exists in the authorization.
503
+ * This is the simplest form of assertion for basic feature checking.
504
+ *
505
+ * @example
506
+ * ```typescript
507
+ * const assertion = FeatureExistsAssertion.create('premium-analytics');
508
+ * const hasFeature = assertion.isSatisfied(authorization);
509
+ * ```
510
+ */
511
+ declare class FeatureExistsAssertion extends LicenseAssertion {
512
+ readonly featureKey: string;
513
+ /**
514
+ * Creates a new feature exists assertion
515
+ * @param featureKey The feature key to check for
516
+ */
517
+ constructor(featureKey: string);
518
+ /**
519
+ * Checks if the authorization contains a feature with the specified key
520
+ */
521
+ isSatisfied(authorization: LicenseAuthorization): boolean;
522
+ /**
523
+ * Factory method to create a feature exists assertion
524
+ * @param featureKey The feature key to check for
525
+ */
526
+ static create(featureKey: string): FeatureExistsAssertion;
527
+ }
528
+ /**
529
+ * Assertion that combines multiple assertions with AND logic.
530
+ * All assertions must be satisfied for this to return true.
531
+ *
532
+ * @example
533
+ * ```typescript
534
+ * const assertion = CompositeAssertion.and(
535
+ * FeatureExistsAssertion.create('feature1'),
536
+ * FeatureExistsAssertion.create('feature2')
537
+ * );
538
+ * ```
539
+ */
540
+ declare class CompositeAssertion extends LicenseAssertion {
541
+ readonly assertions: LicenseAssertion[];
542
+ readonly logic: 'and' | 'or';
543
+ readonly featureKey: string;
544
+ /**
545
+ * Creates a new composite assertion
546
+ * @param assertions The assertions to combine
547
+ * @param logic The logic to apply ('and' or 'or')
548
+ */
549
+ constructor(assertions: LicenseAssertion[], logic?: 'and' | 'or');
550
+ /**
551
+ * Evaluates all assertions according to the logic
552
+ */
553
+ isSatisfied(authorization: LicenseAuthorization): boolean;
554
+ /**
555
+ * Factory method to create an AND composite assertion
556
+ * @param assertions The assertions to combine with AND logic
557
+ */
558
+ static and(...assertions: LicenseAssertion[]): CompositeAssertion;
559
+ /**
560
+ * Factory method to create an OR composite assertion
561
+ * @param assertions The assertions to combine with OR logic
562
+ */
563
+ static or(...assertions: LicenseAssertion[]): CompositeAssertion;
564
+ }
565
+ /**
566
+ * Assertion that inverts another assertion's result.
567
+ *
568
+ * @example
569
+ * ```typescript
570
+ * const assertion = NotAssertion.create(
571
+ * FeatureExistsAssertion.create('blocked-feature')
572
+ * );
573
+ * // Returns true if the feature does NOT exist
574
+ * ```
575
+ */
576
+ declare class NotAssertion extends LicenseAssertion {
577
+ readonly assertion: LicenseAssertion;
578
+ readonly featureKey: string;
579
+ /**
580
+ * Creates a new NOT assertion
581
+ * @param assertion The assertion to invert
582
+ */
583
+ constructor(assertion: LicenseAssertion);
584
+ /**
585
+ * Returns the opposite of the wrapped assertion's result
586
+ */
587
+ isSatisfied(authorization: LicenseAuthorization): boolean;
588
+ /**
589
+ * Factory method to create a NOT assertion
590
+ * @param assertion The assertion to invert
591
+ */
592
+ static create(assertion: LicenseAssertion): NotAssertion;
593
+ }
594
+
595
+ /**
596
+ * Parameters for generating a license authorization
597
+ */
598
+ interface GenerateLicenseAuthorizationParameters {
599
+ RequestId?: string;
600
+ LicenseClassification?: LicenseClassificationType;
601
+ LicenseId: string;
602
+ }
603
+ /**
604
+ * Main client for interacting with the Sidub Licensing service.
605
+ * Provides minimal API surface with only 3 core operations needed for runtime enforcement.
606
+ *
607
+ * Supports cryptographic signature validation to ensure authorization integrity.
608
+ */
609
+ declare class LicensingClient {
610
+ private config;
611
+ private readonly credential;
612
+ private signatureValidator;
613
+ private validateSignatures;
614
+ private readonly authorizationCache;
615
+ private readonly cacheEnabled;
616
+ private readonly featureStates;
617
+ private readonly featureMetadata;
618
+ private contextResolved;
619
+ private contextResolutionPromise;
620
+ /**
621
+ * Creates a new instance of the LicensingClient
622
+ * @param config Configuration for the licensing service
623
+ */
624
+ constructor(config: LicensingConfig);
625
+ /**
626
+ * Ensures context provider has been resolved before making API calls.
627
+ * Called once per client lifetime; concurrent callers share the same promise.
628
+ */
629
+ private ensureContextResolved;
630
+ /**
631
+ * Builds the cryptography configuration from the resolved config values
632
+ */
633
+ private buildCryptoConfig;
634
+ /**
635
+ * Gets whether cryptographic signature validation is enabled
636
+ */
637
+ get isSignatureValidationEnabled(): boolean;
638
+ /**
639
+ * Gets the configured license ID (from credential or explicit config)
640
+ */
641
+ get configuredLicenseId(): string | undefined;
642
+ /**
643
+ * Retrieves a license authorization from the server.
644
+ * This is the primary method for validating and obtaining license information.
645
+ *
646
+ * If cryptographic configuration is provided, the authorization signature will be
647
+ * validated to ensure integrity. This mirrors the .NET LicensingService behavior.
648
+ *
649
+ * @param licenseId The unique identifier of the license (optional if configured via encodedCredential)
650
+ * @param apiKey Optional API key for authentication (overrides config default)
651
+ * @returns A promise resolving to the license authorization
652
+ * @throws {LicensingError} If the request fails or authorization is denied
653
+ * @throws {CryptoError} If signature validation fails (when crypto config is provided)
654
+ */
655
+ getAuthorization(licenseId?: string, apiKey?: string): Promise<LicenseAuthorization>;
656
+ /**
657
+ * Maps server feature format to client format.
658
+ * Explicitly constructs camelCase feature objects instead of spreading server properties.
659
+ * This prevents PascalCase duplicates and ensures consistent property access.
660
+ */
661
+ private mapFeatures;
662
+ /**
663
+ * Normalizes the signature from server response.
664
+ * Handles both base64 string format (from .NET Convert.ToBase64String)
665
+ * and byte array format (JSON array of numbers).
666
+ *
667
+ * @param rawSignature The raw signature from server response
668
+ * @returns Normalized base64 string, or undefined if not present
669
+ */
670
+ private normalizeSignature;
671
+ /**
672
+ * Asserts whether a license condition is satisfied using the provided assertion.
673
+ * This evaluates the assertion against a license authorization.
674
+ *
675
+ * @param assertion The license assertion to evaluate
676
+ * @param authorization The license authorization to check against (if not provided, you must call getAuthorization first)
677
+ * @returns True if the assertion is satisfied, false otherwise
678
+ *
679
+ * @example
680
+ * ```typescript
681
+ * const authorization = await client.getAuthorization('license-id');
682
+ * const assertion = ServiceAccessAssertion.create('premium-features');
683
+ * const hasAccess = client.assertLicense(assertion, authorization);
684
+ * ```
685
+ */
686
+ assertLicense<T extends ILicenseFeature = ILicenseFeature>(assertion: ILicenseAssertion<T>, authorization: LicenseAuthorization): boolean;
687
+ /** Clears all cached authorizations */
688
+ clearCache(): void;
689
+ /** Invalidates all cached authorizations for a specific license */
690
+ invalidateCache(licenseId: string): void;
691
+ /** Gets the local feature state for a license+feature combination */
692
+ getFeatureState(licenseId: string, featureKey: string): RateLimitFeatureState | undefined;
693
+ /** Sets/replaces the local feature state for a license+feature combination */
694
+ setFeatureState(licenseId: string, featureKey: string, state: RateLimitFeatureState): void;
695
+ /**
696
+ * Reports license feature consumption/usage to the server.
697
+ * This is used for metering and billing purposes.
698
+ *
699
+ * @param operation The operation to report
700
+ * @returns A promise that resolves when the operation is reported
701
+ * @throws {LicensingError} If the request fails
702
+ */
703
+ performOperation<T extends ILicenseFeature>(operation: LicenseFeatureStateOperation<T>): Promise<void>;
704
+ /**
705
+ * Reports a telemetry-only access check event to the server.
706
+ * This does not affect billing — IsBillable is always false.
707
+ * Used for tracking feature access patterns without metering costs.
708
+ *
709
+ * @param licenseId The license ID (optional if configured)
710
+ * @param featureKey The feature being accessed
711
+ * @param apiKey Optional API key override
712
+ */
713
+ reportAccessCheck(licenseId?: string, featureKey?: string, apiKey?: string): Promise<void>;
714
+ /**
715
+ * Creates an embedded checkout session for purchasing an offering.
716
+ * For free/trial offerings, the license is provisioned immediately (sessionUrl will be null).
717
+ * For paid offerings, sessionUrl will contain the payment provider URL.
718
+ *
719
+ * Uses licenseServiceUri (not consumptionServiceUri) — checkout is a licensing operation.
720
+ *
721
+ * @param request Checkout request parameters
722
+ * @param apiKey Optional API key override (reseller's API key)
723
+ * @returns The created checkout session with sessionId and optional sessionUrl
724
+ * @throws {LicensingError} If the request fails
725
+ */
726
+ createCheckoutSession(request: CheckoutRequest, apiKey?: string): Promise<CheckoutSession>;
727
+ /**
728
+ * Retrieves the result of a checkout session.
729
+ * Poll this method after creating a checkout session to check if the purchase is complete.
730
+ *
731
+ * For free/trial offerings, the result is immediately available (status = 'completed').
732
+ * For paid offerings, status will be 'pending' until the customer completes payment.
733
+ *
734
+ * @param sessionId The session ID from createCheckoutSession()
735
+ * @param apiKey Optional API key override
736
+ * @returns The checkout session result with status, credential, and error fields
737
+ * @throws {LicensingError} If the request fails
738
+ */
739
+ getCheckoutResult(sessionId: string, apiKey?: string): Promise<CheckoutSessionResult>;
740
+ /**
741
+ * Generates a unique request ID for tracking
742
+ * @private
743
+ */
744
+ private generateRequestId;
745
+ /**
746
+ * Polls for a checkout session result with exponential backoff.
747
+ * Replaces the useCheckout hook pattern with an imperative API.
748
+ *
749
+ * @param sessionId The session ID from createCheckoutSession()
750
+ * @param options Optional: apiKey override, AbortSignal for cancellation, maxAttempts (default 60)
751
+ * @returns The completed or failed checkout session result
752
+ * @throws {LicensingError} If polling times out or the request fails
753
+ */
754
+ pollCheckoutResult(sessionId: string, options?: {
755
+ apiKey?: string;
756
+ signal?: AbortSignal;
757
+ maxAttempts?: number;
758
+ }): Promise<CheckoutSessionResult>;
759
+ /**
760
+ * Gets the current configuration
761
+ */
762
+ getConfig(): Readonly<LicensingConfig>;
763
+ }
764
+
765
+ declare class LicensingConfigurationException extends LicensingError {
766
+ constructor(message: string);
767
+ }
768
+
769
+ /**
770
+ * Cryptography service for license signature validation.
771
+ * Uses the Web Crypto API for cross-platform compatibility.
772
+ */
773
+ /**
774
+ * Configuration for the cryptography service
775
+ */
776
+ interface CryptoConfig {
777
+ /** The service key ID used for signature verification */
778
+ serviceKeyId: string;
779
+ /** Base64-encoded public key for signature verification */
780
+ serviceKeyPublicMember: string;
781
+ }
782
+ /**
783
+ * Service for cryptographic operations on license entities.
784
+ * Implements signature verification using ECDSA with P-256 curve and SHA-256.
785
+ */
786
+ declare class CryptoService {
787
+ private publicKey;
788
+ private readonly config;
789
+ constructor(config: CryptoConfig);
790
+ /**
791
+ * Gets the service key ID
792
+ */
793
+ get serviceKeyId(): string;
794
+ /**
795
+ * Initializes the public key from the configured base64 string.
796
+ * Must be called before verifying signatures.
797
+ */
798
+ initialize(): Promise<void>;
799
+ /**
800
+ * Verifies the signature of a signed entity.
801
+ *
802
+ * @param data The data that was signed (serialized entity without signature)
803
+ * @param signature The signature to verify (base64-encoded)
804
+ * @returns True if the signature is valid, false otherwise
805
+ */
806
+ verifySignature(data: ArrayBuffer, signature: string): Promise<boolean>;
807
+ /**
808
+ * Converts a base64 string to an ArrayBuffer.
809
+ * Handles both standard base64 and base64url encoding.
810
+ */
811
+ private base64ToArrayBuffer;
812
+ }
813
+ /**
814
+ * Error class for cryptography-related errors
815
+ */
816
+ declare class CryptoError extends Error {
817
+ readonly code: 'KEY_IMPORT_FAILED' | 'VERIFICATION_FAILED' | 'NOT_INITIALIZED' | 'INVALID_SIGNATURE';
818
+ constructor(message: string, code: 'KEY_IMPORT_FAILED' | 'VERIFICATION_FAILED' | 'NOT_INITIALIZED' | 'INVALID_SIGNATURE');
819
+ }
820
+
821
+ /**
822
+ * Signature validator for license authorization entities.
823
+ * Validates that the authorization returned from the server has not been tampered with.
824
+ */
825
+
826
+ /**
827
+ * Options for signature validation behavior
828
+ */
829
+ interface SignatureValidationOptions {
830
+ /** Whether to throw an error if signature validation fails (default: true) */
831
+ throwOnInvalid?: boolean;
832
+ /** Whether signature validation is required (default: true if crypto config provided) */
833
+ required?: boolean;
834
+ }
835
+ /**
836
+ * Result of signature validation
837
+ */
838
+ interface SignatureValidationResult {
839
+ /** Whether the signature is valid */
840
+ isValid: boolean;
841
+ /** Whether validation was skipped (e.g., no signature present and not required) */
842
+ skipped: boolean;
843
+ /** Error message if validation failed */
844
+ error?: string;
845
+ }
846
+ /**
847
+ * Raw server response for authorization (before client mapping).
848
+ * Uses PascalCase property names matching the .NET server response.
849
+ */
850
+ interface RawAuthorizationResponse {
851
+ AuthorizationId: string;
852
+ LicenseId: string;
853
+ LicenseClassification: string | number;
854
+ IssueDate: string;
855
+ ExpiryDate?: string;
856
+ Features: unknown[];
857
+ __sidub_entitySignature?: string;
858
+ [key: string]: unknown;
859
+ }
860
+ /**
861
+ * Validates license authorization signatures to ensure integrity.
862
+ *
863
+ * This class implements the client-side portion of the signature verification
864
+ * that mirrors the .NET LicensingService.GetAuthorization() validation logic.
865
+ */
866
+ declare class SignatureValidator {
867
+ private cryptoService;
868
+ private initialized;
869
+ /**
870
+ * Creates a new SignatureValidator instance.
871
+ *
872
+ * @param config Cryptography configuration. If null, validation will be skipped.
873
+ */
874
+ constructor(config: CryptoConfig | null);
875
+ /**
876
+ * Gets whether cryptographic validation is configured
877
+ */
878
+ get isConfigured(): boolean;
879
+ /**
880
+ * Initializes the validator. Must be called before validating signatures.
881
+ */
882
+ initialize(): Promise<void>;
883
+ /**
884
+ * Validates the signature of a license authorization using the raw server response.
885
+ *
886
+ * The validation process:
887
+ * 1. Extracts the signature from __sidub_entitySignature
888
+ * 2. Serializes the raw response data (excluding signature field)
889
+ * 3. Verifies the signature using the configured public key
890
+ *
891
+ * @param rawResponse The raw server response (before client mapping)
892
+ * @param options Validation options
893
+ * @returns Validation result
894
+ * @throws {CryptoError} If throwOnInvalid is true and validation fails
895
+ */
896
+ validateRawResponse(rawResponse: RawAuthorizationResponse, options?: SignatureValidationOptions): Promise<SignatureValidationResult>;
897
+ /**
898
+ * Serializes the raw server response for signature verification.
899
+ * Removes the __sidub_entitySignature field and serializes to JSON.
900
+ */
901
+ private serializeRawForVerification;
902
+ }
903
+
904
+ /**
905
+ * In-memory authorization cache with TTL-based expiry and pseudo-LRU eviction.
906
+ * Cache key format: {licenseId}.{serviceKeyId}
907
+ * One cache instance per LicensingClient — no singletons.
908
+ */
909
+ declare class AuthorizationCache {
910
+ private cache;
911
+ private maxSize;
912
+ constructor(maxSize?: number);
913
+ /**
914
+ * Gets a cached authorization if it exists and has not expired.
915
+ * On hit, re-inserts the entry to move it to the end (pseudo-LRU freshness).
916
+ */
917
+ get(licenseId: string, serviceKeyId: string): LicenseAuthorization | null;
918
+ /**
919
+ * Stores an authorization in the cache.
920
+ * Evicts the oldest entry if max size is reached.
921
+ */
922
+ set(licenseId: string, serviceKeyId: string, authorization: LicenseAuthorization): void;
923
+ /** Removes all cached entries */
924
+ clearCache(): void;
925
+ /** Removes all cached entries for a specific license across all service keys */
926
+ invalidate(licenseId: string): void;
927
+ }
928
+
929
+ /**
930
+ * Context for providing the LicensingClient to React components
931
+ */
932
+ interface LicensingContextValue {
933
+ client: LicensingClient;
934
+ /** Whether signature validation is enabled */
935
+ isSignatureValidationEnabled: boolean;
936
+ /** The configured license ID (if provided via credential) */
937
+ configuredLicenseId: string | undefined;
938
+ }
939
+ /**
940
+ * Props for the LicensingProvider component
941
+ */
942
+ interface LicensingProviderProps {
943
+ /** Configuration for the licensing client */
944
+ config: LicensingConfig;
945
+ /** Child components */
946
+ children: ReactNode;
947
+ }
948
+ /**
949
+ * Provider component for the Sidub Licensing context.
950
+ * Wraps your application to provide licensing functionality to all child components.
951
+ *
952
+ * Supports cryptographic signature validation when configured with serviceKeyId
953
+ * and serviceKeyPublicMember (either directly or via encodedCredential).
954
+ *
955
+ * @example
956
+ * ```tsx
957
+ * // Basic usage (no signature validation)
958
+ * <LicensingProvider config={{
959
+ * licenseServiceUri: 'https://api.example.com',
960
+ * apiKey: 'your-api-key'
961
+ * }}>
962
+ * <App />
963
+ * </LicensingProvider>
964
+ *
965
+ * // With encoded credential (includes signature validation)
966
+ * <LicensingProvider config={{
967
+ * licenseServiceUri: 'https://api.example.com',
968
+ * encodedCredential: 'SIDUB_LIC_...'
969
+ * }}>
970
+ * <App />
971
+ * </LicensingProvider>
972
+ * ```
973
+ */
974
+ declare const LicensingProvider: React.FC<LicensingProviderProps>;
975
+ /**
976
+ * Hook to access the LicensingClient from context.
977
+ * Must be used within a LicensingProvider.
978
+ *
979
+ * @throws {Error} If used outside of a LicensingProvider
980
+ * @returns The LicensingClient instance
981
+ *
982
+ * @example
983
+ * ```tsx
984
+ * function MyComponent() {
985
+ * const client = useLicensingContext();
986
+ * // Use client.getAuthorization(), etc.
987
+ * }
988
+ * ```
989
+ */
990
+ declare const useLicensingContext: () => LicensingClient;
991
+ /**
992
+ * Hook to access the full licensing context including metadata.
993
+ * Must be used within a LicensingProvider.
994
+ *
995
+ * @throws {Error} If used outside of a LicensingProvider
996
+ * @returns The full licensing context value
997
+ *
998
+ * @example
999
+ * ```tsx
1000
+ * function MyComponent() {
1001
+ * const { client, isSignatureValidationEnabled, configuredLicenseId } = useLicensingContextValue();
1002
+ *
1003
+ * if (!isSignatureValidationEnabled) {
1004
+ * console.warn('Signature validation is disabled');
1005
+ * }
1006
+ * }
1007
+ * ```
1008
+ */
1009
+ declare const useLicensingContextValue: () => LicensingContextValue;
1010
+
1011
+ /**
1012
+ * Licensing context data type matching the .NET LicensingContext sealed record.
1013
+ * Named LicensingContextType to avoid collision with the React context in LicensingContext.tsx.
1014
+ */
1015
+ interface LicensingContextType {
1016
+ licenseId: string;
1017
+ serviceKeyId: string;
1018
+ serviceKeyPublicMember: string;
1019
+ apiAccessKey: string;
1020
+ billableResourceId?: string;
1021
+ billablePlanId?: string;
1022
+ }
1023
+ /**
1024
+ * Creates a LicensingContextType from an encoded credential string.
1025
+ * Billable fields are NOT included in the encoding (per .NET behavior) and must be provided separately.
1026
+ */
1027
+ declare function licensingContextFromEncodedString(encoded: string, billableResourceId?: string, billablePlanId?: string): LicensingContextType;
1028
+ /**
1029
+ * Encodes a LicensingContextType to a portable string.
1030
+ * Per .NET behavior: only the 4 credential fields are encoded, NOT billable fields.
1031
+ */
1032
+ declare function licensingContextToEncodedString(context: LicensingContextType): string;
1033
+
1034
+ /**
1035
+ * Interface for pluggable licensing context resolution.
1036
+ * Matches the .NET ILicensingContextProvider pattern.
1037
+ *
1038
+ * Implement this interface for custom credential resolution strategies
1039
+ * (e.g., per-tenant lookup from database or session store).
1040
+ */
1041
+ interface ILicensingContextProvider {
1042
+ resolveContext(): Promise<LicensingContextType | null>;
1043
+ }
1044
+
1045
+ /**
1046
+ * Default context provider that builds a LicensingContextType from LicensingConfig.
1047
+ * Returns null when no credentials are configured (user hasn't purchased a license yet).
1048
+ * Caches the result after first resolution (lazy, one-shot).
1049
+ */
1050
+ declare class ConfigurationContextProvider implements ILicensingContextProvider {
1051
+ private readonly config;
1052
+ private cached;
1053
+ constructor(config: LicensingConfig);
1054
+ resolveContext(): Promise<LicensingContextType | null>;
1055
+ }
1056
+
1057
+ export { AuthorizationCache, BillingIntervalUnit, CompositeAssertion, ConfigurationContextProvider, CryptoError, CryptoService, FeatureExistsAssertion, LicenseAssertion, LicenseClassificationType, LicensingClient, LicensingConfigurationException, LicensingError, LicensingProvider, NotAssertion, RateLimitAssertion, RateLimitFeatureState, ServiceAccessAssertion, ServiceAccessLevel, SignatureValidator, decodeCredential, encodeCredential, findFeatureByKey, getFeatureKey, hasFeature, hasValidCryptoConfig, licensingContextFromEncodedString, licensingContextToEncodedString, matchesFeatureKey, normalizeBillingIntervalUnit, normalizeLicenseClassificationType, normalizeServiceAccessLevel, tryDecodeCredential, useLicensingContext, useLicensingContextValue };
1058
+ export type { CheckoutRequest, CheckoutSession, CheckoutSessionResult, CheckoutSessionStatus, ClientLicenseConfiguration, CryptoConfig, GenerateLicenseAuthorizationParameters, ILicenseAssertion, ILicenseFeature, ILicensingContextProvider, License, LicenseAuthorization, LicenseFeatureStateOperation, LicensingConfig, LicensingContextType, LicensingCredential, LicensingProviderProps, RateAgreement, RateLimitLicenseFeature, RawAuthorizationResponse, ServerFeature, ServiceAccessLicenseFeature, SignatureValidationOptions, SignatureValidationResult };