@feelflow/ffid-sdk 5.25.0 → 5.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo } from '../ffid-client-BZERrMAF.cjs';
2
- export { f as FFIDAddMemberParams, g as FFIDAddMemberRequest, h as FFIDAddMemberResponse, i as FFIDAssignableMemberRole, j as FFIDCacheConfig, k as FFIDClient, l as FFIDConfig, m as FFIDListMembersResponse, n as FFIDMemberRole, o as FFIDOrganization, p as FFIDOrganizationMember, q as FFIDOtpSendResponse, r as FFIDOtpVerifyResponse, s as FFIDPasswordResetConfirmResponse, t as FFIDPasswordResetResponse, u as FFIDPasswordResetVerifyResponse, v as FFIDProfileCallOptions, w as FFIDProvisionMemberPlan, x as FFIDProvisionMemberPlanStatus, y as FFIDProvisionMemberResult, z as FFIDProvisionMemberStatus, A as FFIDProvisionOrganizationDryRun, B as FFIDProvisionOrganizationMemberInput, C as FFIDProvisionOrganizationOutcome, D as FFIDProvisionOrganizationParams, E as FFIDProvisionOrganizationResponse, G as FFIDProvisionUserDryRun, H as FFIDProvisionUserOutcome, I as FFIDProvisionUserParams, J as FFIDProvisionUserProfileInput, K as FFIDProvisionUserResponse, L as FFIDProvisionedOrganization, M as FFIDProvisionedUser, N as FFIDRemoveMemberResponse, O as FFIDResetSessionResponse, P as FFIDSubscription, Q as FFIDUpdateMemberRoleResponse, R as FFIDUpdateUserProfileRequest, S as FFIDUser, T as FFIDUserProfile, U as TokenData, V as TokenStore, W as createFFIDClient, X as createTokenStore } from '../ffid-client-BZERrMAF.cjs';
1
+ import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo, f as FFIDCatalogEnvironment, g as FFIDBillingInterval, h as FFIDTaxBehavior, i as FFIDPublishedCatalog } from '../ffid-client-B_VBvIt4.cjs';
2
+ export { j as FFIDAddMemberParams, k as FFIDAddMemberRequest, l as FFIDAddMemberResponse, m as FFIDAssignableMemberRole, n as FFIDCacheConfig, o as FFIDCatalogPublication, p as FFIDCatalogPublicationStatus, q as FFIDClient, r as FFIDConfig, s as FFIDListMembersResponse, t as FFIDMemberRole, u as FFIDOrganization, v as FFIDOrganizationMember, w as FFIDOtpSendResponse, x as FFIDOtpVerifyResponse, y as FFIDPasswordResetConfirmResponse, z as FFIDPasswordResetResponse, A as FFIDPasswordResetVerifyResponse, B as FFIDProfileCallOptions, C as FFIDProvisionMemberPlan, D as FFIDProvisionMemberPlanStatus, E as FFIDProvisionMemberResult, G as FFIDProvisionMemberStatus, H as FFIDProvisionOrganizationDryRun, I as FFIDProvisionOrganizationMemberInput, J as FFIDProvisionOrganizationOutcome, K as FFIDProvisionOrganizationParams, L as FFIDProvisionOrganizationResponse, M as FFIDProvisionUserDryRun, N as FFIDProvisionUserOutcome, O as FFIDProvisionUserParams, P as FFIDProvisionUserProfileInput, Q as FFIDProvisionUserResponse, R as FFIDProvisionedOrganization, S as FFIDProvisionedUser, T as FFIDPublishedPlan, U as FFIDRemoveMemberResponse, V as FFIDResetSessionResponse, W as FFIDSubscription, X as FFIDUpdateMemberRoleResponse, Y as FFIDUpdateUserProfileRequest, Z as FFIDUser, _ as FFIDUserProfile, $ as FFID_CATALOG_ENVIRONMENTS, a0 as FFID_CATALOG_PUBLICATION_STATUSES, a1 as TokenData, a2 as TokenStore, a3 as createFFIDClient, a4 as createTokenStore } from '../ffid-client-B_VBvIt4.cjs';
3
3
  export { D as DEFAULT_API_BASE_URL, a as DEFAULT_OAUTH_SCOPES } from '../constants-D61jqRIO.cjs';
4
4
  import { z } from 'zod';
5
5
  import '../types-Cjb9J0rL.cjs';
@@ -389,4 +389,181 @@ declare const sessionCookies: {
389
389
  */
390
390
  declare function generateServerState(): string;
391
391
 
392
- export { ALL_DENIED_EXCEPT_NECESSARY, type BuildAuthorizeUrlOptions, type BuildAuthorizeUrlResult, CONSENT_COOKIE_NAME, COOKIE_VERSION, type CookieOptions, FFIDCacheAdapter, type FFIDConsentCategories, type FFIDConsentCategoryCode, type FFIDCookieStoreLike, type FFIDErrorCode, FFIDOAuthUserInfo, FFIDVerifyAccessTokenOptions, FFID_ERROR_CODES, FFID_SESSION_COOKIE_NAME, type HandleCallbackInput, type KVNamespaceLike, type ServerAuthClient, type ServerAuthConfig, type ServerSessionTokens, type ServerTokenResult, createKVCacheAdapter, createMemoryCacheAdapter, createServerAuthClient, createVerifyAccessToken, decodeConsentCookie, encodeConsentCookie, generateServerState, getFFIDConsentFromCookieHeader, getFFIDConsentFromCookies, sessionCookies };
392
+ /**
393
+ * Catalog approval hash helpers (#4342 / ASDD-PRICING-002 SP4A)
394
+ *
395
+ * Shared canonicalization + SHA-256 helpers that FIX the cross-repo hash
396
+ * contract between FFID (publisher) and consumers (Praxis). Both sides compute
397
+ * hashes with these helpers and refuse new sales on any mismatch, so the
398
+ * canonical form below is a compatibility contract:
399
+ *
400
+ * 1. Objects serialize with keys sorted by UTF-16 code unit order,
401
+ * recursively. Arrays keep their element order.
402
+ * 2. Serialization is `JSON.stringify`-compatible per token (string
403
+ * escaping, number formatting) with NO whitespace.
404
+ * 3. `undefined`, non-finite numbers (NaN/±Infinity), functions, symbols,
405
+ * bigints and non-plain objects (Date, Map, class instances) are
406
+ * REJECTED with FFIDCatalogHashError — never silently dropped, because a
407
+ * dropped key would let two semantically different payloads collide.
408
+ * Only own enumerable string-keyed properties participate; symbol-keyed
409
+ * properties are ignored (same as `JSON.stringify`).
410
+ * 4. The hash is lowercase SHA-256 hex over the UTF-8 bytes of the
411
+ * canonical string (no domain-separation prefix).
412
+ *
413
+ * Changing ANY of these rules is a breaking change to published catalog
414
+ * verification and requires re-publishing catalogs — the fixed test vectors
415
+ * in `__tests__/catalog-hash.test.ts` exist to make such a change loud.
416
+ */
417
+
418
+ /** Lowercase SHA-256 hex format shared by all catalog approval hashes */
419
+ declare const CATALOG_HASH_PATTERN: RegExp;
420
+ /**
421
+ * Thrown when a value cannot be canonicalized (or an embedded hash is
422
+ * malformed). Always indicates a programming error on the hashing side —
423
+ * never caused by end-user input.
424
+ */
425
+ declare class FFIDCatalogHashError extends Error {
426
+ constructor(message: string);
427
+ }
428
+ /** JSON value accepted by the canonicalizer */
429
+ type FFIDCanonicalJsonValue = string | number | boolean | null | FFIDCanonicalJsonValue[] | {
430
+ [key: string]: FFIDCanonicalJsonValue;
431
+ };
432
+ /**
433
+ * Serializes a JSON-plain value into its canonical string form (see module
434
+ * doc for the exact rules). Exposed so both sides can debug hash mismatches
435
+ * by diffing canonical strings instead of opaque digests.
436
+ */
437
+ declare function canonicalizeCatalogValue(value: FFIDCanonicalJsonValue): string;
438
+ /**
439
+ * Lowercase SHA-256 hex of the UTF-8 bytes of `text`.
440
+ *
441
+ * Requires Web Crypto (`globalThis.crypto.subtle`) — available by default in
442
+ * Node.js >= 19 (Node 18 needs `--experimental-global-webcrypto`), browsers,
443
+ * and edge runtimes. Throws instead of falling back to a weaker digest so a
444
+ * missing crypto implementation can never silently change the contract.
445
+ */
446
+ declare function sha256Hex(text: string): Promise<string>;
447
+ /** Canonicalizes `value` and returns its lowercase SHA-256 hex digest. */
448
+ declare function hashCanonicalJson(value: FFIDCanonicalJsonValue): Promise<string>;
449
+ /**
450
+ * Human-approved tax configuration snapshot hashed into
451
+ * `publication.taxConfigurationHash`. FFID re-computes this from its live
452
+ * Stripe Tax settings at paid-checkout start and refuses the session on
453
+ * mismatch.
454
+ */
455
+ interface FFIDTaxConfiguration {
456
+ /** ISO 3166-1 alpha-2 country/region codes where paid sales are allowed */
457
+ allowedCountries: string[];
458
+ /** Country/region codes with completed Stripe Tax registrations */
459
+ stripeTaxRegistrations: string[];
460
+ /** Whether full billing address collection is required before paid checkout */
461
+ billingAddressRequired: boolean;
462
+ /** Stripe Product tax code per plan code (e.g. `txcd_10000000`) */
463
+ planTaxCodes: Record<string, string>;
464
+ /** Tax behavior per plan code */
465
+ planTaxBehaviors: Record<string, FFIDTaxBehavior>;
466
+ }
467
+ /**
468
+ * Human-approved payment configuration snapshot hashed into
469
+ * `publication.paymentConfigurationHash`.
470
+ */
471
+ interface FFIDPaymentConfiguration {
472
+ environment: FFIDCatalogEnvironment;
473
+ /** Lowercase ISO 4217 currency (e.g. `jpy`) */
474
+ currency: string;
475
+ /** Explicit Stripe payment method allow-list (initial sales: `['card']`) */
476
+ paymentMethodTypes: string[];
477
+ /** Stripe Dashboard dynamic payment methods must stay disabled for sales */
478
+ dynamicPaymentMethodsEnabled: boolean;
479
+ manualInvoiceAllowed: boolean;
480
+ customerBalanceAllowed: boolean;
481
+ delayedPaymentMethodsAllowed: boolean;
482
+ /** Required Stripe Customer invoice credit balance before checkout (spec: 0) */
483
+ customerInvoiceBalanceRequired: number;
484
+ }
485
+ /** Sales-scope-relevant snapshot of one published plan (subset of the catalog) */
486
+ interface FFIDScopeHashPlan {
487
+ code: string;
488
+ priceMonthly: number | null;
489
+ priceYearly: number | null;
490
+ currency: string;
491
+ billingIntervals: FFIDBillingInterval[];
492
+ taxBehavior: FFIDTaxBehavior;
493
+ minSeats: number;
494
+ }
495
+ /**
496
+ * Input of `computeScopeHash` — the published plans' sales conditions plus
497
+ * the five content/config hashes. Changing any of them changes `scopeHash`,
498
+ * which invalidates the previous publication approval (fail-closed).
499
+ */
500
+ interface FFIDScopeHashInput {
501
+ plans: FFIDScopeHashPlan[];
502
+ praxisCopyHash: string;
503
+ ffidCheckoutCopyHash: string;
504
+ legalDisclosureHash: string;
505
+ taxConfigurationHash: string;
506
+ paymentConfigurationHash: string;
507
+ }
508
+ /**
509
+ * `praxisCopyHash`: hash of the consumer's entire structured sales
510
+ * presentation (`PRAXIS_SALES_PRESENTATION` — locales, plan display names,
511
+ * prices, feature matrix, CTAs, eligibility). The consumer re-hashes what it
512
+ * actually renders and must refuse new sales on mismatch.
513
+ */
514
+ declare function computePraxisCopyHash(presentation: Record<string, FFIDCanonicalJsonValue>): Promise<string>;
515
+ /** `ffidCheckoutCopyHash`: hash of FFID's structured final-confirmation copy */
516
+ declare function computeFFIDCheckoutCopyHash(checkoutCopy: Record<string, FFIDCanonicalJsonValue>): Promise<string>;
517
+ /**
518
+ * `legalDisclosureHash`: hash of the canonical body text of the reviewed
519
+ * legal disclosure document version. Line endings are normalized to LF before
520
+ * hashing so the digest is independent of platform line-ending conventions;
521
+ * the text is otherwise hashed byte-exact (no trimming, no Unicode
522
+ * normalization).
523
+ */
524
+ declare function computeLegalDisclosureHash(canonicalText: string): Promise<string>;
525
+ /**
526
+ * `taxConfigurationHash`: hash of the human-approved tax configuration.
527
+ * Country lists are treated as sets (sorted + deduplicated) so representation
528
+ * order cannot flip the digest.
529
+ */
530
+ declare function computeTaxConfigurationHash(config: FFIDTaxConfiguration): Promise<string>;
531
+ /**
532
+ * `paymentConfigurationHash`: hash of the human-approved payment
533
+ * configuration. `paymentMethodTypes` is treated as a set.
534
+ */
535
+ declare function computePaymentConfigurationHash(config: FFIDPaymentConfiguration): Promise<string>;
536
+ /**
537
+ * `scopeHash`: hash of the published sales scope — plan codes, amounts,
538
+ * currency, intervals, tax behavior, minimum seats, plus the five embedded
539
+ * content/config hashes. Plans are sorted by `code`; duplicate codes are
540
+ * rejected. Embedded hashes are validated for format so a malformed digest
541
+ * can never be baked into an approval.
542
+ */
543
+ declare function computeScopeHash(input: FFIDScopeHashInput): Promise<string>;
544
+
545
+ /** Published catalog methods (#4342 / ASDD-PRICING-002 SP4A) */
546
+
547
+ /**
548
+ * Validates the full published-catalog shape the SDK's compile-time types
549
+ * promise to consumers:
550
+ * - `service.code` / `service.name` are non-empty strings
551
+ * - top-level `catalogVersion` equals `publication.catalogVersion`
552
+ * - `publication.status` is one of the four known literals (unknown statuses
553
+ * must fail loud here, NOT be treated as sellable downstream) and
554
+ * `publication.environment` is a known environment
555
+ * - the six approval hashes are lowercase SHA-256 hex; `salesEpoch` is a
556
+ * positive integer; timestamps are present (or explicitly null where the
557
+ * type allows null)
558
+ * - every plan carries the full `FFIDPublishedPlan` field set with
559
+ * cross-field invariants (an offered interval has its price;
560
+ * `minSeats <= maxSeats`), and no plan field NAME mentions Stripe
561
+ * (defense-in-depth heuristic — the authoritative no-Stripe-ID guard is
562
+ * the FFID server's `.strict()` snapshot schema)
563
+ *
564
+ * Throws FFIDSDKError on violation so a server regression surfaces at the
565
+ * SDK boundary instead of silently reaching a consumer's sales gate.
566
+ */
567
+ declare function validatePublishedCatalog(catalog: unknown): asserts catalog is FFIDPublishedCatalog;
568
+
569
+ export { ALL_DENIED_EXCEPT_NECESSARY, type BuildAuthorizeUrlOptions, type BuildAuthorizeUrlResult, CATALOG_HASH_PATTERN, CONSENT_COOKIE_NAME, COOKIE_VERSION, type CookieOptions, FFIDCacheAdapter, type FFIDCanonicalJsonValue, FFIDCatalogEnvironment, FFIDCatalogHashError, type FFIDConsentCategories, type FFIDConsentCategoryCode, type FFIDCookieStoreLike, type FFIDErrorCode, FFIDOAuthUserInfo, type FFIDPaymentConfiguration, FFIDPublishedCatalog, type FFIDScopeHashInput, type FFIDScopeHashPlan, FFIDTaxBehavior, type FFIDTaxConfiguration, FFIDVerifyAccessTokenOptions, FFID_ERROR_CODES, FFID_SESSION_COOKIE_NAME, type HandleCallbackInput, type KVNamespaceLike, type ServerAuthClient, type ServerAuthConfig, type ServerSessionTokens, type ServerTokenResult, canonicalizeCatalogValue, computeFFIDCheckoutCopyHash, computeLegalDisclosureHash, computePaymentConfigurationHash, computePraxisCopyHash, computeScopeHash, computeTaxConfigurationHash, createKVCacheAdapter, createMemoryCacheAdapter, createServerAuthClient, createVerifyAccessToken, decodeConsentCookie, encodeConsentCookie, generateServerState, getFFIDConsentFromCookieHeader, getFFIDConsentFromCookies, hashCanonicalJson, sessionCookies, sha256Hex, validatePublishedCatalog };
@@ -1,5 +1,5 @@
1
- import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo } from '../ffid-client-CFZPX5ej.js';
2
- export { f as FFIDAddMemberParams, g as FFIDAddMemberRequest, h as FFIDAddMemberResponse, i as FFIDAssignableMemberRole, j as FFIDCacheConfig, k as FFIDClient, l as FFIDConfig, m as FFIDListMembersResponse, n as FFIDMemberRole, o as FFIDOrganization, p as FFIDOrganizationMember, q as FFIDOtpSendResponse, r as FFIDOtpVerifyResponse, s as FFIDPasswordResetConfirmResponse, t as FFIDPasswordResetResponse, u as FFIDPasswordResetVerifyResponse, v as FFIDProfileCallOptions, w as FFIDProvisionMemberPlan, x as FFIDProvisionMemberPlanStatus, y as FFIDProvisionMemberResult, z as FFIDProvisionMemberStatus, A as FFIDProvisionOrganizationDryRun, B as FFIDProvisionOrganizationMemberInput, C as FFIDProvisionOrganizationOutcome, D as FFIDProvisionOrganizationParams, E as FFIDProvisionOrganizationResponse, G as FFIDProvisionUserDryRun, H as FFIDProvisionUserOutcome, I as FFIDProvisionUserParams, J as FFIDProvisionUserProfileInput, K as FFIDProvisionUserResponse, L as FFIDProvisionedOrganization, M as FFIDProvisionedUser, N as FFIDRemoveMemberResponse, O as FFIDResetSessionResponse, P as FFIDSubscription, Q as FFIDUpdateMemberRoleResponse, R as FFIDUpdateUserProfileRequest, S as FFIDUser, T as FFIDUserProfile, U as TokenData, V as TokenStore, W as createFFIDClient, X as createTokenStore } from '../ffid-client-CFZPX5ej.js';
1
+ import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo, f as FFIDCatalogEnvironment, g as FFIDBillingInterval, h as FFIDTaxBehavior, i as FFIDPublishedCatalog } from '../ffid-client-DEM1nYqe.js';
2
+ export { j as FFIDAddMemberParams, k as FFIDAddMemberRequest, l as FFIDAddMemberResponse, m as FFIDAssignableMemberRole, n as FFIDCacheConfig, o as FFIDCatalogPublication, p as FFIDCatalogPublicationStatus, q as FFIDClient, r as FFIDConfig, s as FFIDListMembersResponse, t as FFIDMemberRole, u as FFIDOrganization, v as FFIDOrganizationMember, w as FFIDOtpSendResponse, x as FFIDOtpVerifyResponse, y as FFIDPasswordResetConfirmResponse, z as FFIDPasswordResetResponse, A as FFIDPasswordResetVerifyResponse, B as FFIDProfileCallOptions, C as FFIDProvisionMemberPlan, D as FFIDProvisionMemberPlanStatus, E as FFIDProvisionMemberResult, G as FFIDProvisionMemberStatus, H as FFIDProvisionOrganizationDryRun, I as FFIDProvisionOrganizationMemberInput, J as FFIDProvisionOrganizationOutcome, K as FFIDProvisionOrganizationParams, L as FFIDProvisionOrganizationResponse, M as FFIDProvisionUserDryRun, N as FFIDProvisionUserOutcome, O as FFIDProvisionUserParams, P as FFIDProvisionUserProfileInput, Q as FFIDProvisionUserResponse, R as FFIDProvisionedOrganization, S as FFIDProvisionedUser, T as FFIDPublishedPlan, U as FFIDRemoveMemberResponse, V as FFIDResetSessionResponse, W as FFIDSubscription, X as FFIDUpdateMemberRoleResponse, Y as FFIDUpdateUserProfileRequest, Z as FFIDUser, _ as FFIDUserProfile, $ as FFID_CATALOG_ENVIRONMENTS, a0 as FFID_CATALOG_PUBLICATION_STATUSES, a1 as TokenData, a2 as TokenStore, a3 as createFFIDClient, a4 as createTokenStore } from '../ffid-client-DEM1nYqe.js';
3
3
  export { D as DEFAULT_API_BASE_URL, a as DEFAULT_OAUTH_SCOPES } from '../constants-D61jqRIO.js';
4
4
  import { z } from 'zod';
5
5
  import '../types-Cjb9J0rL.js';
@@ -389,4 +389,181 @@ declare const sessionCookies: {
389
389
  */
390
390
  declare function generateServerState(): string;
391
391
 
392
- export { ALL_DENIED_EXCEPT_NECESSARY, type BuildAuthorizeUrlOptions, type BuildAuthorizeUrlResult, CONSENT_COOKIE_NAME, COOKIE_VERSION, type CookieOptions, FFIDCacheAdapter, type FFIDConsentCategories, type FFIDConsentCategoryCode, type FFIDCookieStoreLike, type FFIDErrorCode, FFIDOAuthUserInfo, FFIDVerifyAccessTokenOptions, FFID_ERROR_CODES, FFID_SESSION_COOKIE_NAME, type HandleCallbackInput, type KVNamespaceLike, type ServerAuthClient, type ServerAuthConfig, type ServerSessionTokens, type ServerTokenResult, createKVCacheAdapter, createMemoryCacheAdapter, createServerAuthClient, createVerifyAccessToken, decodeConsentCookie, encodeConsentCookie, generateServerState, getFFIDConsentFromCookieHeader, getFFIDConsentFromCookies, sessionCookies };
392
+ /**
393
+ * Catalog approval hash helpers (#4342 / ASDD-PRICING-002 SP4A)
394
+ *
395
+ * Shared canonicalization + SHA-256 helpers that FIX the cross-repo hash
396
+ * contract between FFID (publisher) and consumers (Praxis). Both sides compute
397
+ * hashes with these helpers and refuse new sales on any mismatch, so the
398
+ * canonical form below is a compatibility contract:
399
+ *
400
+ * 1. Objects serialize with keys sorted by UTF-16 code unit order,
401
+ * recursively. Arrays keep their element order.
402
+ * 2. Serialization is `JSON.stringify`-compatible per token (string
403
+ * escaping, number formatting) with NO whitespace.
404
+ * 3. `undefined`, non-finite numbers (NaN/±Infinity), functions, symbols,
405
+ * bigints and non-plain objects (Date, Map, class instances) are
406
+ * REJECTED with FFIDCatalogHashError — never silently dropped, because a
407
+ * dropped key would let two semantically different payloads collide.
408
+ * Only own enumerable string-keyed properties participate; symbol-keyed
409
+ * properties are ignored (same as `JSON.stringify`).
410
+ * 4. The hash is lowercase SHA-256 hex over the UTF-8 bytes of the
411
+ * canonical string (no domain-separation prefix).
412
+ *
413
+ * Changing ANY of these rules is a breaking change to published catalog
414
+ * verification and requires re-publishing catalogs — the fixed test vectors
415
+ * in `__tests__/catalog-hash.test.ts` exist to make such a change loud.
416
+ */
417
+
418
+ /** Lowercase SHA-256 hex format shared by all catalog approval hashes */
419
+ declare const CATALOG_HASH_PATTERN: RegExp;
420
+ /**
421
+ * Thrown when a value cannot be canonicalized (or an embedded hash is
422
+ * malformed). Always indicates a programming error on the hashing side —
423
+ * never caused by end-user input.
424
+ */
425
+ declare class FFIDCatalogHashError extends Error {
426
+ constructor(message: string);
427
+ }
428
+ /** JSON value accepted by the canonicalizer */
429
+ type FFIDCanonicalJsonValue = string | number | boolean | null | FFIDCanonicalJsonValue[] | {
430
+ [key: string]: FFIDCanonicalJsonValue;
431
+ };
432
+ /**
433
+ * Serializes a JSON-plain value into its canonical string form (see module
434
+ * doc for the exact rules). Exposed so both sides can debug hash mismatches
435
+ * by diffing canonical strings instead of opaque digests.
436
+ */
437
+ declare function canonicalizeCatalogValue(value: FFIDCanonicalJsonValue): string;
438
+ /**
439
+ * Lowercase SHA-256 hex of the UTF-8 bytes of `text`.
440
+ *
441
+ * Requires Web Crypto (`globalThis.crypto.subtle`) — available by default in
442
+ * Node.js >= 19 (Node 18 needs `--experimental-global-webcrypto`), browsers,
443
+ * and edge runtimes. Throws instead of falling back to a weaker digest so a
444
+ * missing crypto implementation can never silently change the contract.
445
+ */
446
+ declare function sha256Hex(text: string): Promise<string>;
447
+ /** Canonicalizes `value` and returns its lowercase SHA-256 hex digest. */
448
+ declare function hashCanonicalJson(value: FFIDCanonicalJsonValue): Promise<string>;
449
+ /**
450
+ * Human-approved tax configuration snapshot hashed into
451
+ * `publication.taxConfigurationHash`. FFID re-computes this from its live
452
+ * Stripe Tax settings at paid-checkout start and refuses the session on
453
+ * mismatch.
454
+ */
455
+ interface FFIDTaxConfiguration {
456
+ /** ISO 3166-1 alpha-2 country/region codes where paid sales are allowed */
457
+ allowedCountries: string[];
458
+ /** Country/region codes with completed Stripe Tax registrations */
459
+ stripeTaxRegistrations: string[];
460
+ /** Whether full billing address collection is required before paid checkout */
461
+ billingAddressRequired: boolean;
462
+ /** Stripe Product tax code per plan code (e.g. `txcd_10000000`) */
463
+ planTaxCodes: Record<string, string>;
464
+ /** Tax behavior per plan code */
465
+ planTaxBehaviors: Record<string, FFIDTaxBehavior>;
466
+ }
467
+ /**
468
+ * Human-approved payment configuration snapshot hashed into
469
+ * `publication.paymentConfigurationHash`.
470
+ */
471
+ interface FFIDPaymentConfiguration {
472
+ environment: FFIDCatalogEnvironment;
473
+ /** Lowercase ISO 4217 currency (e.g. `jpy`) */
474
+ currency: string;
475
+ /** Explicit Stripe payment method allow-list (initial sales: `['card']`) */
476
+ paymentMethodTypes: string[];
477
+ /** Stripe Dashboard dynamic payment methods must stay disabled for sales */
478
+ dynamicPaymentMethodsEnabled: boolean;
479
+ manualInvoiceAllowed: boolean;
480
+ customerBalanceAllowed: boolean;
481
+ delayedPaymentMethodsAllowed: boolean;
482
+ /** Required Stripe Customer invoice credit balance before checkout (spec: 0) */
483
+ customerInvoiceBalanceRequired: number;
484
+ }
485
+ /** Sales-scope-relevant snapshot of one published plan (subset of the catalog) */
486
+ interface FFIDScopeHashPlan {
487
+ code: string;
488
+ priceMonthly: number | null;
489
+ priceYearly: number | null;
490
+ currency: string;
491
+ billingIntervals: FFIDBillingInterval[];
492
+ taxBehavior: FFIDTaxBehavior;
493
+ minSeats: number;
494
+ }
495
+ /**
496
+ * Input of `computeScopeHash` — the published plans' sales conditions plus
497
+ * the five content/config hashes. Changing any of them changes `scopeHash`,
498
+ * which invalidates the previous publication approval (fail-closed).
499
+ */
500
+ interface FFIDScopeHashInput {
501
+ plans: FFIDScopeHashPlan[];
502
+ praxisCopyHash: string;
503
+ ffidCheckoutCopyHash: string;
504
+ legalDisclosureHash: string;
505
+ taxConfigurationHash: string;
506
+ paymentConfigurationHash: string;
507
+ }
508
+ /**
509
+ * `praxisCopyHash`: hash of the consumer's entire structured sales
510
+ * presentation (`PRAXIS_SALES_PRESENTATION` — locales, plan display names,
511
+ * prices, feature matrix, CTAs, eligibility). The consumer re-hashes what it
512
+ * actually renders and must refuse new sales on mismatch.
513
+ */
514
+ declare function computePraxisCopyHash(presentation: Record<string, FFIDCanonicalJsonValue>): Promise<string>;
515
+ /** `ffidCheckoutCopyHash`: hash of FFID's structured final-confirmation copy */
516
+ declare function computeFFIDCheckoutCopyHash(checkoutCopy: Record<string, FFIDCanonicalJsonValue>): Promise<string>;
517
+ /**
518
+ * `legalDisclosureHash`: hash of the canonical body text of the reviewed
519
+ * legal disclosure document version. Line endings are normalized to LF before
520
+ * hashing so the digest is independent of platform line-ending conventions;
521
+ * the text is otherwise hashed byte-exact (no trimming, no Unicode
522
+ * normalization).
523
+ */
524
+ declare function computeLegalDisclosureHash(canonicalText: string): Promise<string>;
525
+ /**
526
+ * `taxConfigurationHash`: hash of the human-approved tax configuration.
527
+ * Country lists are treated as sets (sorted + deduplicated) so representation
528
+ * order cannot flip the digest.
529
+ */
530
+ declare function computeTaxConfigurationHash(config: FFIDTaxConfiguration): Promise<string>;
531
+ /**
532
+ * `paymentConfigurationHash`: hash of the human-approved payment
533
+ * configuration. `paymentMethodTypes` is treated as a set.
534
+ */
535
+ declare function computePaymentConfigurationHash(config: FFIDPaymentConfiguration): Promise<string>;
536
+ /**
537
+ * `scopeHash`: hash of the published sales scope — plan codes, amounts,
538
+ * currency, intervals, tax behavior, minimum seats, plus the five embedded
539
+ * content/config hashes. Plans are sorted by `code`; duplicate codes are
540
+ * rejected. Embedded hashes are validated for format so a malformed digest
541
+ * can never be baked into an approval.
542
+ */
543
+ declare function computeScopeHash(input: FFIDScopeHashInput): Promise<string>;
544
+
545
+ /** Published catalog methods (#4342 / ASDD-PRICING-002 SP4A) */
546
+
547
+ /**
548
+ * Validates the full published-catalog shape the SDK's compile-time types
549
+ * promise to consumers:
550
+ * - `service.code` / `service.name` are non-empty strings
551
+ * - top-level `catalogVersion` equals `publication.catalogVersion`
552
+ * - `publication.status` is one of the four known literals (unknown statuses
553
+ * must fail loud here, NOT be treated as sellable downstream) and
554
+ * `publication.environment` is a known environment
555
+ * - the six approval hashes are lowercase SHA-256 hex; `salesEpoch` is a
556
+ * positive integer; timestamps are present (or explicitly null where the
557
+ * type allows null)
558
+ * - every plan carries the full `FFIDPublishedPlan` field set with
559
+ * cross-field invariants (an offered interval has its price;
560
+ * `minSeats <= maxSeats`), and no plan field NAME mentions Stripe
561
+ * (defense-in-depth heuristic — the authoritative no-Stripe-ID guard is
562
+ * the FFID server's `.strict()` snapshot schema)
563
+ *
564
+ * Throws FFIDSDKError on violation so a server regression surfaces at the
565
+ * SDK boundary instead of silently reaching a consumer's sales gate.
566
+ */
567
+ declare function validatePublishedCatalog(catalog: unknown): asserts catalog is FFIDPublishedCatalog;
568
+
569
+ export { ALL_DENIED_EXCEPT_NECESSARY, type BuildAuthorizeUrlOptions, type BuildAuthorizeUrlResult, CATALOG_HASH_PATTERN, CONSENT_COOKIE_NAME, COOKIE_VERSION, type CookieOptions, FFIDCacheAdapter, type FFIDCanonicalJsonValue, FFIDCatalogEnvironment, FFIDCatalogHashError, type FFIDConsentCategories, type FFIDConsentCategoryCode, type FFIDCookieStoreLike, type FFIDErrorCode, FFIDOAuthUserInfo, type FFIDPaymentConfiguration, FFIDPublishedCatalog, type FFIDScopeHashInput, type FFIDScopeHashPlan, FFIDTaxBehavior, type FFIDTaxConfiguration, FFIDVerifyAccessTokenOptions, FFID_ERROR_CODES, FFID_SESSION_COOKIE_NAME, type HandleCallbackInput, type KVNamespaceLike, type ServerAuthClient, type ServerAuthConfig, type ServerSessionTokens, type ServerTokenResult, canonicalizeCatalogValue, computeFFIDCheckoutCopyHash, computeLegalDisclosureHash, computePaymentConfigurationHash, computePraxisCopyHash, computeScopeHash, computeTaxConfigurationHash, createKVCacheAdapter, createMemoryCacheAdapter, createServerAuthClient, createVerifyAccessToken, decodeConsentCookie, encodeConsentCookie, generateServerState, getFFIDConsentFromCookieHeader, getFFIDConsentFromCookies, hashCanonicalJson, sessionCookies, sha256Hex, validatePublishedCatalog };