@strimz/sdk 0.3.2 → 0.5.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
1
  import { ApiKeyMode } from '@strimz/shared-config';
2
- import { PaymentSession, SubscriptionPlan, MerchantPublicBrand, SubscriptionStatusResult, TokenMetadata, TokenPermitNonce } from '@strimz/shared-types';
2
+ import { PaymentSession, SubscriptionPlan, MerchantPublicBrand, SubscriptionStatusResult, SubscriptionEnrolmentTerms, TokenMetadata, TokenPermitNonce } from '@strimz/shared-types';
3
3
  import { z } from 'zod';
4
4
 
5
5
  /**
@@ -140,6 +140,7 @@ declare class CheckoutResource extends BaseResource {
140
140
  /** Whether a wallet already subscribes to a plan (drives "already
141
141
  * subscribed" on the enrolment page). */
142
142
  subscriptionStatus(planId: string, payer: string): Promise<SubscriptionStatusResult>;
143
+ planTerms(planId: string, payer: string): Promise<SubscriptionEnrolmentTerms>;
143
144
  }
144
145
 
145
146
  /**
@@ -1,5 +1,5 @@
1
1
  import { ApiKeyMode } from '@strimz/shared-config';
2
- import { PaymentSession, SubscriptionPlan, MerchantPublicBrand, SubscriptionStatusResult, TokenMetadata, TokenPermitNonce } from '@strimz/shared-types';
2
+ import { PaymentSession, SubscriptionPlan, MerchantPublicBrand, SubscriptionStatusResult, SubscriptionEnrolmentTerms, TokenMetadata, TokenPermitNonce } from '@strimz/shared-types';
3
3
  import { z } from 'zod';
4
4
 
5
5
  /**
@@ -140,6 +140,7 @@ declare class CheckoutResource extends BaseResource {
140
140
  /** Whether a wallet already subscribes to a plan (drives "already
141
141
  * subscribed" on the enrolment page). */
142
142
  subscriptionStatus(planId: string, payer: string): Promise<SubscriptionStatusResult>;
143
+ planTerms(planId: string, payer: string): Promise<SubscriptionEnrolmentTerms>;
143
144
  }
144
145
 
145
146
  /**
@@ -392,6 +392,12 @@ var CheckoutResource = class extends BaseResource {
392
392
  sharedTypes.subscriptionStatusResultSchema
393
393
  );
394
394
  }
395
+ planTerms(planId, payer) {
396
+ return this.get(
397
+ `/v1/checkout/plans/${encodeURIComponent(planId)}/terms?payer=${encodeURIComponent(payer)}`,
398
+ sharedTypes.subscriptionEnrolmentTermsSchema
399
+ );
400
+ }
395
401
  };
396
402
  var TokensResource = class extends BaseResource {
397
403
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http/headers.ts","../src/http/fetcher.ts","../src/idempotency.ts","../src/pagination.ts","../src/resources/base-resource.ts","../src/resources/checkout.ts","../src/resources/tokens.ts","../src/browser-client.ts"],"names":["uuid","paymentSessionSchema","subscriptionPlanSchema","merchantPublicBrandSchema","subscriptionStatusResultSchema","tokenMetadataSchema","tokenPermitNonceSchema","kindFromKey","modeFromKey"],"mappings":";;;;;;;;;AAsCO,IAAM,WAAA,GAAN,cAA0B,KAAA,CAAM;AAAA,EACrB,IAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EAEhB,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAClB,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACtB;AACF,CAAA;AAEO,IAAM,yBAAA,GAAN,cAAwC,WAAA,CAAY;AAAA,EACzD,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,qBAAA,GAAN,cAAoC,WAAA,CAAY;AAAA,EACrD,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,uBAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,qBAAA,GAAN,cAAoC,WAAA,CAAY;AAAA,EACrD,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,uBAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,mBAAA,GAAN,cAAkC,WAAA,CAAY;AAAA,EACnD,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,sBAAA,GAAN,cAAqC,WAAA,CAAY;AAAA,EACtD,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,wBAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,oBAAA,GAAN,cAAmC,WAAA,CAAY;AAAA,EACpC,YAAA;AAAA,EAChB,WAAA,CAAY,IAAA,EAAuB,UAAA,EAAqB,YAAA,EAAuB;AAC7E,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AAAA,EACtB;AACF,CAAA;AAEO,IAAM,kBAAA,GAAN,cAAiC,WAAA,CAAY;AAAA,EACzB,KAAA;AAAA,EACzB,WAAA,CAAY,SAAiB,KAAA,EAAgB;AAC3C,IAAA,KAAA,CAAM,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,CAAA;AACxC,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,EACf;AACF,CAAA;AAEO,IAAM,kBAAA,GAAN,cAAiC,WAAA,CAAY;AAAA,EAClD,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,EAAE,IAAA,EAAM,SAAA,EAAW,OAAA,EAAS,CAAA;AAClC,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AAAA,EACd;AACF,CAAA;AAUO,SAAS,aAAA,CACd,UAAA,EACA,IAAA,EACA,YAAA,EACa;AACb,EAAA,IAAI,eAAe,GAAA,EAAK,OAAO,IAAI,yBAAA,CAA0B,MAAM,UAAU,CAAA;AAC7E,EAAA,IAAI,eAAe,GAAA,EAAK,OAAO,IAAI,qBAAA,CAAsB,MAAM,UAAU,CAAA;AACzE,EAAA,IAAI,eAAe,GAAA,EAAK,OAAO,IAAI,mBAAA,CAAoB,MAAM,UAAU,CAAA;AACvE,EAAA,IAAI,UAAA,KAAe,GAAA,IAAO,IAAA,CAAK,IAAA,KAAS,mBAAA,EAAqB;AAC3D,IAAA,OAAO,IAAI,sBAAA,CAAuB,IAAA,EAAM,UAAU,CAAA;AAAA,EACpD;AACA,EAAA,IAAI,eAAe,GAAA,EAAK,OAAO,IAAI,qBAAA,CAAsB,MAAM,UAAU,CAAA;AACzE,EAAA,IAAI,eAAe,GAAA,EAAK,OAAO,IAAI,oBAAA,CAAqB,IAAA,EAAM,YAAY,YAAY,CAAA;AACtF,EAAA,OAAO,IAAI,WAAA,CAAY,IAAA,EAAM,UAAU,CAAA;AACzC;;;ACjIO,IAAM,OAAA,GAAU;AAAA,EACrB,aAAA,EAAe,eAAA;AAAA,EACf,cAAA,EAAgB,0BAAA;AAAA,EAEhB,OAAA,EAAS,cAAA;AAAA,EACT,UAAA,EAAY,sBAAA;AAAA,EACZ,UAAA,EAAY;AACd,CAAA;AAEO,IAAM,QAAA,GAAW,aAAA;AAGjB,IAAM,WAAA,GAAc,OAAA;AAEpB,SAAS,gBAAA,CAAiB,QAAgB,OAAA,EAAyC;AACxF,EAAA,OAAO;AAAA,IACL,CAAC,OAAA,CAAQ,aAAa,GAAG,UAAU,MAAM,CAAA,CAAA;AAAA,IACzC,CAAC,OAAA,CAAQ,OAAO,GAAG,QAAA;AAAA,IACnB,CAAC,OAAA,CAAQ,UAAU,GAAG,WAAA;AAAA,IACtB,CAAC,OAAA,CAAQ,UAAU,GAAG,OAAA;AAAA,IACtB,MAAA,EAAQ;AAAA,GACV;AACF;;;ACuBA,IAAM,kBAAA,GAAqB,GAAA;AAC3B,IAAM,mBAAA,GAAsB,CAAA;AAC5B,IAAM,0BAAA,GAA6B,GAAA;AAE5B,IAAM,UAAN,MAAc;AAAA,EACF,OAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,gBAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EAEjB,YAAY,IAAA,EAAsB;AAChC,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAA;AAC7C,IAAA,IAAA,CAAK,cAAc,IAAA,CAAK,WAAA;AACxB,IAAA,IAAA,CAAK,SAAA,GAAY,KAAK,SAAA,IAAa,kBAAA;AACnC,IAAA,IAAA,CAAK,UAAA,GAAa,KAAK,UAAA,IAAc,mBAAA;AACrC,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAK,gBAAA,IAAoB,0BAAA;AACjD,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AACvB,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,KAAA,IAAS,UAAA,CAAW,KAAA,CAAM,KAAK,UAAU,CAAA;AAAA,EACjE;AAAA,EAEA,MAAM,QAAW,IAAA,EAA+B;AAC9C,IAAA,MAAM,MAAM,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,KAAK,KAAK,CAAA;AAC/C,IAAA,MAAM,UAAA,GAAa,aAAa,IAAI,CAAA;AACpC,IAAA,MAAM,OAAA,GAAkC,EAAE,GAAG,IAAA,CAAK,WAAA,EAAY;AAC9D,IAAA,IAAI,IAAA,CAAK,IAAA,IAAQ,IAAA,EAAM,OAAA,CAAQ,cAAc,CAAA,GAAI,kBAAA;AACjD,IAAA,IAAI,KAAK,cAAA,EAAgB,OAAA,CAAQ,OAAA,CAAQ,cAAc,IAAI,IAAA,CAAK,cAAA;AAEhE,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,IAAI,OAAA;AACJ,IAAA,OAAO,OAAA,IAAW,KAAK,UAAA,EAAY;AACjC,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,YAAY,EAAE,MAAA,EAAQ,KAAK,MAAA,EAAQ,GAAA,EAAK,SAAS,CAAA;AACtD,QAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,EAAI;AACvB,QAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,gBAAA;AAAA,UACrB,GAAA;AAAA,UACA;AAAA,YACE,QAAQ,IAAA,CAAK,MAAA;AAAA,YACb,OAAA;AAAA,YACA,IAAA,EAAM,KAAK,IAAA,IAAQ,IAAA,GAAO,SAAY,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI;AAAA,WAChE;AAAA,UACA,IAAA,CAAK,aAAa,IAAA,CAAK;AAAA,SACzB;AACA,QAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA;AACxB,QAAA,IAAA,CAAK,UAAA,GAAa,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,GAAA,EAAK,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAQ,EAAA,EAAI,OAAA,EAAS,CAAA;AAE/E,QAAA,IAAI,IAAI,EAAA,EAAI;AACV,UAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,EAAK,OAAO,KAAA,CAAA;AAC/B,UAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AAAA,QACzB;AAEA,QAAA,MAAM,SAAA,GAAY,MAAM,cAAA,CAAe,GAAG,CAAA;AAC1C,QAAA,MAAM,YAAA,GAAe,gBAAgB,GAAG,CAAA;AAGxC,QAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,IAAO,OAAA,GAAU,KAAK,UAAA,EAAY;AACnD,UAAA,MAAM,KAAA,CAAM,YAAA,IAAgB,IAAA,CAAK,UAAA,CAAW,OAAO,CAAC,CAAA;AACpD,UAAA,OAAA,EAAA;AACA,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,IAAI,MAAA,IAAU,GAAA,IAAO,UAAA,IAAc,OAAA,GAAU,KAAK,UAAA,EAAY;AAChE,UAAA,MAAM,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,OAAO,CAAC,CAAA;AACpC,UAAA,OAAA,EAAA;AACA,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,aAAA,CAAc,GAAA,CAAI,MAAA,EAAQ,SAAA,EAAW,YAAY,CAAA;AAAA,MACzD,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,GAAA,YAAe,aAAa,MAAM,GAAA;AACtC,QAAA,OAAA,GAAU,GAAA;AACV,QAAA,IAAI,CAAC,aAAA,CAAc,GAAG,CAAA,IAAK,OAAA,IAAW,KAAK,UAAA,EAAY;AACrD,UAAA,IAAI,GAAA,YAAe,oBAAoB,MAAM,GAAA;AAC7C,UAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,eAAA,EAAkB,SAAS,GAAG,CAAC,IAAI,GAAG,CAAA;AAAA,QACrE;AACA,QAAA,MAAM,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,OAAO,CAAC,CAAA;AACpC,QAAA,OAAA,EAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,oBAAA,EAAuB,IAAA,CAAK,UAAU,YAAY,OAAO,CAAA;AAAA,EACxF;AAAA,EAEA,MAAc,gBAAA,CACZ,GAAA,EACA,IAAA,EACA,SAAA,EACmB;AACnB,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,SAAS,CAAA;AAC5D,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,CAAK,SAAA,CAAU,GAAA,EAAK,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AAAA,IACzE,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,YAAA,CAAa,GAAG,CAAA,EAAG;AACrB,QAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,wBAAA,EAA2B,SAAS,CAAA,EAAA,CAAI,CAAA;AAAA,MACvE;AACA,MAAA,MAAM,GAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAEQ,QAAA,CAAS,MAAc,KAAA,EAAsC;AACnE,IAAA,MAAM,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,EAAG,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,IAAA,GAAO,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAA,CAAA;AACvE,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,IAAA,MAAM,GAAA,GAAM,IAAI,eAAA,EAAgB;AAChC,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC1C,MAAA,IAAI,KAAK,IAAA,EAAM;AACf,MAAA,GAAA,CAAI,MAAA,CAAO,CAAA,EAAG,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IACzB;AACA,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,EAAS;AACxB,IAAA,OAAO,EAAA,GAAK,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,GAAK,IAAA;AAAA,EAChC;AAAA,EAEQ,WAAW,OAAA,EAAyB;AAC1C,IAAA,MAAM,OAAO,IAAA,CAAK,gBAAA,GAAmB,IAAA,CAAK,GAAA,CAAI,GAAG,OAAO,CAAA;AACxD,IAAA,OAAO,KAAK,GAAA,CAAI,IAAA,GAAO,aAAa,IAAA,CAAK,gBAAgB,GAAG,GAAK,CAAA;AAAA,EACnE;AACF,CAAA;AAIA,SAAS,aAAa,KAAA,EAAuB;AAC3C,EAAA,MAAM,CAAA,GAAI,UAAA;AACV,EAAA,IAAI,CAAA,CAAE,QAAQ,eAAA,EAAiB;AAC7B,IAAA,MAAM,GAAA,GAAM,IAAI,WAAA,CAAY,CAAC,CAAA;AAC7B,IAAA,CAAA,CAAE,MAAA,CAAO,gBAAgB,GAAG,CAAA;AAC5B,IAAA,OAAA,CAAS,GAAA,CAAI,CAAC,CAAA,IAAK,CAAA,IAAK,UAAA,GAAe,KAAA;AAAA,EACzC;AACA,EAAA,OAAO,IAAA,CAAK,QAAO,GAAI,KAAA;AACzB;AAEA,SAAS,aAAa,IAAA,EAA4B;AAChD,EAAA,IAAI,KAAK,MAAA,KAAW,KAAA,IAAS,IAAA,CAAK,MAAA,KAAW,UAAU,OAAO,IAAA;AAC9D,EAAA,OAAO,KAAK,cAAA,IAAkB,IAAA;AAChC;AAEA,eAAe,eAAe,GAAA,EAAyC;AACrE,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAC7B,IAAA,MAAM,GAAA,GACJ,OAAO,IAAA,KAAS,QAAA,IAAY,SAAS,IAAA,IAAQ,OAAA,IAAW,IAAA,GACnD,IAAA,CAA4B,KAAA,GAC7B,IAAA;AACN,IAAA,IAAI,OAAO,QAAQ,QAAA,IAAY,GAAA,KAAQ,QAAQ,MAAA,IAAU,GAAA,IAAO,aAAa,GAAA,EAAK;AAChF,MAAA,OAAO,kBAAkB,GAA8B,CAAA;AAAA,IACzD;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,WAAA,EAAa,SAAS,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,CAAA,CAAA,EAAG;AAC5D;AAKA,IAAM,mBAAA,uBAA0B,GAAA,CAAI,CAAC,UAAU,OAAA,EAAS,QAAA,EAAU,iBAAiB,CAAC,CAAA;AAEpF,SAAS,kBAAkB,GAAA,EAA+C;AACxE,EAAA,MAAM,OAAA,GACJ,OAAO,GAAA,CAAI,OAAA,KAAY,YAAY,GAAA,CAAI,OAAA,KAAY,OAC/C,MAAA,CAAO,WAAA;AAAA,IACL,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,OAAkC,CAAA,CAAE,MAAA;AAAA,MAAO,CAAC,CAAC,CAAC,CAAA,KAC/D,mBAAA,CAAoB,IAAI,CAAC;AAAA;AAC3B,GACF,GACA,MAAA;AACN,EAAA,OAAO;AAAA,IACL,MAAM,OAAO,GAAA,CAAI,IAAA,KAAS,QAAA,GAAY,IAAI,IAAA,GAAmC,WAAA;AAAA,IAC7E,SAAS,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,GAAW,IAAI,OAAA,GAAU,gBAAA;AAAA,IACzD,OAAO,OAAO,GAAA,CAAI,KAAA,KAAU,QAAA,GAAW,IAAI,KAAA,GAAQ,MAAA;AAAA,IACnD,WAAW,OAAO,GAAA,CAAI,SAAA,KAAc,QAAA,GAAW,IAAI,SAAA,GAAY,MAAA;AAAA,IAC/D,OAAA,EAAS,WAAW,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,CAAE,MAAA,GAAS,IAAI,OAAA,GAAU;AAAA,GAClE;AACF;AAEA,SAAS,gBAAgB,GAAA,EAAmC;AAC1D,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AACvC,EAAA,IAAI,CAAC,GAAG,OAAO,MAAA;AACf,EAAA,MAAM,CAAA,GAAI,OAAO,CAAC,CAAA;AAClB,EAAA,IAAI,MAAA,CAAO,SAAS,CAAC,CAAA,SAAU,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA,GAAI,GAAA;AAChD,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AACzB,EAAA,IAAI,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,GAAO,IAAA,CAAK,GAAA,EAAK,CAAA;AAC/D,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;AAEA,SAAS,aAAa,GAAA,EAAuB;AAC3C,EAAA,OAAO,GAAA,YAAe,KAAA,IAAS,GAAA,CAAI,IAAA,KAAS,YAAA;AAC9C;AAEA,SAAS,cAAc,GAAA,EAAuB;AAC5C,EAAA,IAAI,GAAA,YAAe,WAAW,OAAO,IAAA;AACrC,EAAA,IAAI,eAAe,KAAA,IAAS,sBAAA,CAAuB,KAAK,GAAA,CAAI,OAAO,GAAG,OAAO,IAAA;AAC7E,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,SAAS,GAAA,EAAsB;AACtC,EAAA,IAAI,GAAA,YAAe,KAAA,EAAO,OAAO,GAAA,CAAI,OAAA;AACrC,EAAA,OAAO,OAAO,GAAG,CAAA;AACnB;AC9PO,SAAS,sBAAA,GAAiC;AAC/C,EAAA,OAAO,CAAA,OAAA,EAAUA,mBAAM,CAAA,CAAA;AACzB;;;ACYO,IAAM,qBAAN,MAAwD;AAAA,EAC7D,YAA6B,SAAA,EAAwD;AAAxD,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA,EAAyD;AAAA,EAAzD,SAAA;AAAA,EAE7B,QAAQ,MAAA,CAAO,aAAa,CAAA,GAAsB;AAChD,IAAA,IAAI,MAAA,GAAwB,IAAA;AAC5B,IAAA,IAAI,KAAA,GAAQ,IAAA;AACZ,IAAA,OAAO,KAAA,IAAS,WAAW,IAAA,EAAM;AAC/B,MAAA,KAAA,GAAQ,KAAA;AACR,MAAA,MAAM,IAAA,GAAgB,MAAM,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AACjD,MAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,IAAA,EAAM;AAC5B,QAAA,MAAM,IAAA;AAAA,MACR;AACA,MAAA,MAAA,GAAS,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,OAAA,EAA2D;AACvE,IAAA,WAAA,MAAiB,QAAQ,IAAA,EAAM;AAC7B,MAAA,MAAM,QAAQ,IAAI,CAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAM,OAAA,GAAwB;AAC5B,IAAA,MAAM,MAAW,EAAC;AAClB,IAAA,WAAA,MAAiB,IAAA,IAAQ,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA;AAC5C,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACvBO,IAAe,eAAf,MAA4B;AAAA,EACjC,YAA+B,GAAA,EAAsB;AAAtB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAuB;AAAA,EAAvB,GAAA;AAAA,EAE/B,MAAgB,GAAA,CACd,IAAA,EACA,MAAA,EACA,KAAA,EACsB;AACtB,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,OAAA,CAAiB,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,CAAA;AACnF,IAAA,OAAO,KAAA,CAAM,MAAM,MAAM,CAAA;AAAA,EAC3B;AAAA,EAEA,MAAgB,IAAA,CACd,IAAA,EACA,IAAA,EACA,QACA,OAAA,EACsB;AACtB,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAI,QAAQ,OAAA,CAAiB;AAAA,MACnD,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA;AAAA,MACA,IAAA;AAAA,MACA,cAAA,EAAgB,OAAA,EAAS,cAAA,IAAkB,sBAAA,EAAuB;AAAA,MAClE,WAAW,OAAA,EAAS;AAAA,KACrB,CAAA;AACD,IAAA,OAAO,KAAA,CAAM,MAAM,MAAM,CAAA;AAAA,EAC3B;AAAA,EAEA,MAAgB,KAAA,CACd,IAAA,EACA,IAAA,EACA,QACA,OAAA,EACsB;AACtB,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAI,QAAQ,OAAA,CAAiB;AAAA,MACnD,MAAA,EAAQ,OAAA;AAAA,MACR,IAAA;AAAA,MACA,IAAA;AAAA,MACA,cAAA,EAAgB,OAAA,EAAS,cAAA,IAAkB,sBAAA,EAAuB;AAAA,MAClE,WAAW,OAAA,EAAS;AAAA,KACrB,CAAA;AACD,IAAA,OAAO,KAAA,CAAM,MAAM,MAAM,CAAA;AAAA,EAC3B;AAAA,EAEA,MAAgB,MAAA,CAA4B,IAAA,EAAc,MAAA,EAAkC;AAC1F,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,QAAiB,EAAE,MAAA,EAAQ,QAAA,EAAU,IAAA,EAAM,CAAA;AAC/E,IAAA,OAAO,KAAA,CAAM,MAAM,MAAM,CAAA;AAAA,EAC3B;AAAA,EAEU,QAAA,CACR,IAAA,EACA,UAAA,EACA,MAAA,EAC4B;AAC5B,IAAA,OAAO,IAAA,CAAK,IAAI,OAAA,CACb,OAAA,CAAiB,EAAE,MAAA,EAAQ,KAAA,EAAO,MAAM,KAAA,EAAO,OAAA,CAAQ,MAAM,CAAA,EAAG,EAChE,IAAA,CAAK,CAAC,QAAQ,SAAA,CAAU,GAAA,EAAK,UAAU,CAAC,CAAA;AAAA,EAC7C;AAAA,EAEU,QAAA,CACR,IAAA,EACA,UAAA,EACA,MAAA,EACiC;AACjC,IAAA,OAAO,IAAI,kBAAA;AAAA,MAAmB,CAAC,MAAA,KAC7B,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,YAAY,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ;AAAA,KACvD;AAAA,EACF;AACF,CAAA;AAIA,SAAS,QACP,MAAA,EAC6B;AAC7B,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAC;AACrB,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,KAAA,CAA2B,MAAe,MAAA,EAAyB;AAC1E,EAAA,OAAQ,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,GAAI,IAAA;AACxC;AAEA,SAAS,SAAA,CAA+B,KAAc,UAAA,EAAkC;AACtF,EAAA,MAAM,GAAA,GAAM,GAAA;AACZ,EAAA,MAAM,KAAA,GAAA,CAAS,GAAA,EAAK,IAAA,IAAQ,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,UAAA,CAAW,KAAA,CAAM,CAAC,CAAgB,CAAA;AAC7E,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,KAAA;AAAA,IACN,UAAA,EAAY,KAAK,UAAA,IAAc,IAAA;AAAA,IAC/B,OAAA,EAAS,KAAK,OAAA,KAAY;AAAA,GAC5B;AACF;;;AC1FO,IAAM,gBAAA,GAAN,cAA+B,YAAA,CAAa;AAAA;AAAA,EAEjD,QAAQ,EAAA,EAAqC;AAC3C,IAAA,OAAO,KAAK,GAAA,CAAI,CAAA,sBAAA,EAAyB,mBAAmB,EAAE,CAAC,IAAIC,gCAAoB,CAAA;AAAA,EACzF;AAAA;AAAA,EAGA,KAAK,EAAA,EAAuC;AAC1C,IAAA,OAAO,KAAK,GAAA,CAAI,CAAA,mBAAA,EAAsB,mBAAmB,EAAE,CAAC,IAAIC,kCAAsB,CAAA;AAAA,EACxF;AAAA;AAAA,EAGA,SAAS,EAAA,EAA0C;AACjD,IAAA,OAAO,KAAK,GAAA,CAAI,CAAA,uBAAA,EAA0B,mBAAmB,EAAE,CAAC,IAAIC,qCAAyB,CAAA;AAAA,EAC/F;AAAA;AAAA;AAAA,EAIA,kBAAA,CAAmB,QAAgB,KAAA,EAAkD;AACnF,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,MACV,sBAAsB,kBAAA,CAAmB,MAAM,CAAC,CAAA,oBAAA,EAAuB,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAAA,MAChGC;AAAA,KACF;AAAA,EACF;AACF,CAAA;AChCO,IAAM,cAAA,GAAN,cAA6B,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/C,SAAS,OAAA,EAAyC;AAChD,IAAA,OAAO,IAAA,CAAK,IAAI,CAAA,WAAA,EAAc,kBAAA,CAAmB,QAAQ,WAAA,EAAa,CAAC,CAAA,CAAA,EAAIC,+BAAmB,CAAA;AAAA,EAChG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAA,CAAY,SAAiB,KAAA,EAA0C;AACrE,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,MACV,CAAA,WAAA,EAAc,kBAAA,CAAmB,OAAA,CAAQ,WAAA,EAAa,CAAC,CAAA,aAAA,CAAA;AAAA,MACvDC,kCAAA;AAAA,MACA,EAAE,KAAA,EAAO,KAAA,CAAM,WAAA,EAAY;AAAE,KAC/B;AAAA,EACF;AACF,CAAA;AAsBO,SAAS,kBAAkB,IAAA,EAAgC;AAChE,EAAA,OAAO,IAAA,CAAK,YAAA,CAAa,gBAAA,GAAmB,wBAAA,GAA2B,kBAAA;AACzE;AAEO,SAAS,uBAAuB,IAAA,EAAgC;AACrE,EAAA,OAAO,IAAA,CAAK,YAAA,CAAa,UAAA,GACrB,gCAAA,GACA,kCAAA;AACN;;;ACtCA,IAAM,gBAAA,GAAmB,4BAAA;AAclB,IAAM,sBAAN,MAA0B;AAAA,EACf,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAA;AAAA;AAAA,EAEA,MAAA;AAAA,EAEhB,YAAY,OAAA,EAAqC;AAC/C,IAAA,MAAM,MAAM,OAAA,CAAQ,cAAA;AACpB,IAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AACnC,MAAA,MAAM,IAAI,yBAAA;AAAA,QACR,EAAE,IAAA,EAAM,sBAAA,EAAwB,OAAA,EAAS,4BAAA,EAA6B;AAAA,QACtE;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAIC,wBAAA,CAAY,GAAG,CAAA,KAAM,aAAA,EAAe;AACtC,MAAA,MAAM,IAAI,yBAAA;AAAA,QACR;AAAA,UACE,IAAA,EAAM,sBAAA;AAAA,UACN,OAAA,EACE;AAAA,SACJ;AAAA,QACA;AAAA,OACF;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAOC,yBAAY,GAAG,CAAA;AAC5B,IAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,MAAM,IAAI,yBAAA;AAAA,QACR,EAAE,IAAA,EAAM,sBAAA,EAAwB,OAAA,EAAS,6BAAA,EAA8B;AAAA,QACvE;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAEZ,IAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ;AAAA,MAC1B,OAAA,EAAS,QAAQ,OAAA,IAAW,gBAAA;AAAA,MAC5B,WAAA,EAAa,gBAAA,CAAiB,GAAA,EAAK,SAAS,CAAA;AAAA,MAC5C,WAAW,OAAA,CAAQ,SAAA;AAAA,MACnB,UAAA,EAAY;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,gBAAA,CAAiB,EAAE,SAAS,CAAA;AAChD,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,cAAA,CAAe,EAAE,SAAS,CAAA;AAAA,EAC9C;AACF","file":"browser-client.cjs","sourcesContent":["/**\n * Error hierarchy for the Strimz SDK.\n *\n * Every error thrown by the SDK extends `StrimzError`. The SDK throws\n * on failure rather than resolving to `{ ok: false }` so call sites\n * stay linear and consumers can narrow with `instanceof` on the\n * exported subclasses.\n */\n\nexport type StrimzErrorCode =\n | 'authentication_error'\n | 'permission_denied'\n | 'invalid_request'\n | 'not_found'\n | 'idempotency_error'\n | 'rate_limited'\n | 'mode_mismatch'\n | 'merchant_not_found'\n | 'merchant_inactive'\n | 'token_not_whitelisted'\n | 'compliance_blocked'\n | 'session_expired'\n | 'session_invalid_state'\n | 'webhook_signature_invalid'\n | 'api_error'\n | 'network_error'\n | 'timeout'\n | 'parse_error'\n | 'unknown'\n\nexport interface StrimzErrorBody {\n code: StrimzErrorCode\n message: string\n param?: string\n requestId?: string\n details?: Record<string, unknown>\n}\n\nexport class StrimzError extends Error {\n public readonly code: StrimzErrorCode\n public readonly httpStatus: number | undefined\n public readonly requestId: string | undefined\n public readonly param: string | undefined\n public readonly details: Record<string, unknown> | undefined\n\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body.message)\n this.name = 'StrimzError'\n this.code = body.code\n this.httpStatus = httpStatus\n this.requestId = body.requestId\n this.param = body.param\n this.details = body.details\n }\n}\n\nexport class StrimzAuthenticationError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzAuthenticationError'\n }\n}\n\nexport class StrimzPermissionError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzPermissionError'\n }\n}\n\nexport class StrimzValidationError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzValidationError'\n }\n}\n\nexport class StrimzNotFoundError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzNotFoundError'\n }\n}\n\nexport class StrimzIdempotencyError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzIdempotencyError'\n }\n}\n\nexport class StrimzRateLimitError extends StrimzError {\n public readonly retryAfterMs: number | undefined\n constructor(body: StrimzErrorBody, httpStatus?: number, retryAfterMs?: number) {\n super(body, httpStatus)\n this.name = 'StrimzRateLimitError'\n this.retryAfterMs = retryAfterMs\n }\n}\n\nexport class StrimzNetworkError extends StrimzError {\n public override readonly cause: unknown\n constructor(message: string, cause: unknown) {\n super({ code: 'network_error', message })\n this.name = 'StrimzNetworkError'\n this.cause = cause\n }\n}\n\nexport class StrimzTimeoutError extends StrimzError {\n constructor(message: string) {\n super({ code: 'timeout', message })\n this.name = 'StrimzTimeoutError'\n }\n}\n\nexport class StrimzModeMismatchError extends StrimzError {\n constructor(message: string) {\n super({ code: 'mode_mismatch', message })\n this.name = 'StrimzModeMismatchError'\n }\n}\n\n/** Map an HTTP status + body to the right StrimzError subclass. */\nexport function classifyError(\n httpStatus: number,\n body: StrimzErrorBody,\n retryAfterMs?: number,\n): StrimzError {\n if (httpStatus === 401) return new StrimzAuthenticationError(body, httpStatus)\n if (httpStatus === 403) return new StrimzPermissionError(body, httpStatus)\n if (httpStatus === 404) return new StrimzNotFoundError(body, httpStatus)\n if (httpStatus === 409 && body.code === 'idempotency_error') {\n return new StrimzIdempotencyError(body, httpStatus)\n }\n if (httpStatus === 422) return new StrimzValidationError(body, httpStatus)\n if (httpStatus === 429) return new StrimzRateLimitError(body, httpStatus, retryAfterMs)\n return new StrimzError(body, httpStatus)\n}\n","/**\n * Strimz HTTP header conventions.\n *\n * `Authorization: Bearer <secret_key>`: primary auth.\n * `X-Strimz-Idempotency-Key`: mutating calls.\n * `X-Strimz-Sdk`: telemetry.\n * `X-Strimz-Sdk-Version`: telemetry.\n */\n\nexport const HEADERS = {\n authorization: 'Authorization',\n idempotencyKey: 'X-Strimz-Idempotency-Key',\n requestId: 'X-Strimz-Request-Id',\n sdkName: 'X-Strimz-Sdk',\n sdkVersion: 'X-Strimz-Sdk-Version',\n sdkRuntime: 'X-Strimz-Sdk-Runtime',\n} as const\n\nexport const SDK_NAME = '@strimz/sdk'\n\n/** The SDK version. Updated by the build pipeline if a version is published. */\nexport const SDK_VERSION = '0.0.0'\n\nexport function buildBaseHeaders(apiKey: string, runtime: string): Record<string, string> {\n return {\n [HEADERS.authorization]: `Bearer ${apiKey}`,\n [HEADERS.sdkName]: SDK_NAME,\n [HEADERS.sdkVersion]: SDK_VERSION,\n [HEADERS.sdkRuntime]: runtime,\n Accept: 'application/json',\n }\n}\n","/**\n * Fetch wrapper with retry, idempotency, and Strimz error parsing.\n *\n * Retries on:\n * - Network failures (TypeError on fetch).\n * - 5xx responses for idempotent methods (GET, POST with idempotency key).\n * - 429 with Retry-After.\n *\n * Does NOT retry on:\n * - 4xx other than 429 (caller's bug).\n * - 5xx for non-idempotent calls without an idempotency key.\n */\n\nimport {\n classifyError,\n StrimzError,\n StrimzNetworkError,\n StrimzTimeoutError,\n type StrimzErrorBody,\n} from '../errors.js'\nimport { HEADERS } from './headers.js'\n\nexport interface FetcherOptions {\n baseUrl: string\n baseHeaders: Record<string, string>\n /** Default timeout per attempt, milliseconds. */\n timeoutMs?: number\n /** How many retries before giving up. */\n maxRetries?: number\n /** Initial backoff in ms; doubled with jitter on each retry. */\n initialBackoffMs?: number\n /** Optional logger. */\n onRequest?: (info: { method: string; url: string; attempt: number }) => void\n onResponse?: (info: {\n method: string\n url: string\n status: number\n ms: number\n attempt: number\n }) => void\n /** Override the global fetch (for tests or Edge polyfills). */\n fetch?: typeof globalThis.fetch\n}\n\nexport interface RequestSpec {\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE'\n path: string\n query?: Record<string, string | number | boolean | null | undefined>\n body?: unknown\n idempotencyKey?: string\n /** Per-call timeout override. */\n timeoutMs?: number\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000\nconst DEFAULT_MAX_RETRIES = 3\nconst DEFAULT_INITIAL_BACKOFF_MS = 250\n\nexport class Fetcher {\n private readonly baseUrl: string\n private readonly baseHeaders: Record<string, string>\n private readonly timeoutMs: number\n private readonly maxRetries: number\n private readonly initialBackoffMs: number\n private readonly onRequest: FetcherOptions['onRequest']\n private readonly onResponse: FetcherOptions['onResponse']\n private readonly fetchImpl: typeof globalThis.fetch\n\n constructor(opts: FetcherOptions) {\n this.baseUrl = opts.baseUrl.replace(/\\/$/, '')\n this.baseHeaders = opts.baseHeaders\n this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES\n this.initialBackoffMs = opts.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS\n this.onRequest = opts.onRequest\n this.onResponse = opts.onResponse\n this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n async request<T>(spec: RequestSpec): Promise<T> {\n const url = this.buildUrl(spec.path, spec.query)\n const idempotent = isIdempotent(spec)\n const headers: Record<string, string> = { ...this.baseHeaders }\n if (spec.body != null) headers['Content-Type'] = 'application/json'\n if (spec.idempotencyKey) headers[HEADERS.idempotencyKey] = spec.idempotencyKey\n\n let attempt = 0\n let lastErr: unknown\n while (attempt <= this.maxRetries) {\n try {\n this.onRequest?.({ method: spec.method, url, attempt })\n const start = Date.now()\n const res = await this.fetchWithTimeout(\n url,\n {\n method: spec.method,\n headers,\n body: spec.body == null ? undefined : JSON.stringify(spec.body),\n },\n spec.timeoutMs ?? this.timeoutMs,\n )\n const ms = Date.now() - start\n this.onResponse?.({ method: spec.method, url, status: res.status, ms, attempt })\n\n if (res.ok) {\n if (res.status === 204) return undefined as T\n return (await res.json()) as T\n }\n\n const errorBody = await parseErrorBody(res)\n const retryAfterMs = parseRetryAfter(res)\n\n // 429. Back off and retry up to maxRetries.\n if (res.status === 429 && attempt < this.maxRetries) {\n await delay(retryAfterMs ?? this.backoffFor(attempt))\n attempt++\n continue\n }\n // 5xx. Retry only if idempotent.\n if (res.status >= 500 && idempotent && attempt < this.maxRetries) {\n await delay(this.backoffFor(attempt))\n attempt++\n continue\n }\n\n throw classifyError(res.status, errorBody, retryAfterMs)\n } catch (err) {\n if (err instanceof StrimzError) throw err\n lastErr = err\n if (!isNetworkLike(err) || attempt >= this.maxRetries) {\n if (err instanceof StrimzTimeoutError) throw err\n throw new StrimzNetworkError(`Network error: ${describe(err)}`, err)\n }\n await delay(this.backoffFor(attempt))\n attempt++\n }\n }\n throw new StrimzNetworkError(`Network error after ${this.maxRetries} retries`, lastErr)\n }\n\n private async fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n ): Promise<Response> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n return await this.fetchImpl(url, { ...init, signal: controller.signal })\n } catch (err) {\n if (isAbortError(err)) {\n throw new StrimzTimeoutError(`Request timed out after ${timeoutMs}ms`)\n }\n throw err\n } finally {\n clearTimeout(timer)\n }\n }\n\n private buildUrl(path: string, query?: RequestSpec['query']): string {\n const base = `${this.baseUrl}${path.startsWith('/') ? path : `/${path}`}`\n if (!query) return base\n const usp = new URLSearchParams()\n for (const [k, v] of Object.entries(query)) {\n if (v == null) continue\n usp.append(k, String(v))\n }\n const qs = usp.toString()\n return qs ? `${base}?${qs}` : base\n }\n\n private backoffFor(attempt: number): number {\n const expo = this.initialBackoffMs * Math.pow(2, attempt)\n return Math.min(expo + cryptoJitter(this.initialBackoffMs), 8_000)\n }\n}\n\n// Uses crypto so retry timing does not seed off Math.random in\n// environments where that's been monkey-patched.\nfunction cryptoJitter(maxMs: number): number {\n const g = globalThis as { crypto?: { getRandomValues?: (a: Uint32Array) => Uint32Array } }\n if (g.crypto?.getRandomValues) {\n const buf = new Uint32Array(1)\n g.crypto.getRandomValues(buf)\n return ((buf[0] ?? 0) / 0xffff_ffff) * maxMs\n }\n return Math.random() * maxMs\n}\n\nfunction isIdempotent(spec: RequestSpec): boolean {\n if (spec.method === 'GET' || spec.method === 'DELETE') return true\n return spec.idempotencyKey != null\n}\n\nasync function parseErrorBody(res: Response): Promise<StrimzErrorBody> {\n try {\n const json = (await res.json()) as unknown\n const raw =\n typeof json === 'object' && json !== null && 'error' in json\n ? (json as { error: unknown }).error\n : json\n if (typeof raw === 'object' && raw !== null && 'code' in raw && 'message' in raw) {\n return sanitiseErrorBody(raw as Record<string, unknown>)\n }\n } catch {\n // fall through\n }\n return { code: 'api_error', message: `HTTP ${res.status}` }\n}\n\n// Whitelist server-provided fields. A bugged endpoint that dumps stack\n// traces or internal metadata into the error payload never reaches SDK\n// consumers.\nconst ALLOWED_DETAIL_KEYS = new Set(['issues', 'field', 'reason', 'chargeAttemptId'])\n\nfunction sanitiseErrorBody(raw: Record<string, unknown>): StrimzErrorBody {\n const details =\n typeof raw.details === 'object' && raw.details !== null\n ? Object.fromEntries(\n Object.entries(raw.details as Record<string, unknown>).filter(([k]) =>\n ALLOWED_DETAIL_KEYS.has(k),\n ),\n )\n : undefined\n return {\n code: typeof raw.code === 'string' ? (raw.code as StrimzErrorBody['code']) : 'api_error',\n message: typeof raw.message === 'string' ? raw.message : 'Request failed',\n param: typeof raw.param === 'string' ? raw.param : undefined,\n requestId: typeof raw.requestId === 'string' ? raw.requestId : undefined,\n details: details && Object.keys(details).length > 0 ? details : undefined,\n }\n}\n\nfunction parseRetryAfter(res: Response): number | undefined {\n const v = res.headers.get('Retry-After')\n if (!v) return undefined\n const n = Number(v)\n if (Number.isFinite(n)) return Math.max(0, n) * 1_000\n const date = Date.parse(v)\n if (Number.isFinite(date)) return Math.max(0, date - Date.now())\n return undefined\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction isAbortError(err: unknown): boolean {\n return err instanceof Error && err.name === 'AbortError'\n}\n\nfunction isNetworkLike(err: unknown): boolean {\n if (err instanceof TypeError) return true // fetch network failures\n if (err instanceof Error && /fetch|network|econn/i.test(err.message)) return true\n return false\n}\n\nfunction describe(err: unknown): string {\n if (err instanceof Error) return err.message\n return String(err)\n}\n","import { uuid } from '@strimz/shared-crypto'\n\n/**\n * Generate an idempotency key for a mutating SDK call. The key is a\n * UUID with a stable `strimz_` prefix so it stays greppable in logs.\n */\nexport function generateIdempotencyKey(): string {\n return `strimz_${uuid()}`\n}\n\n/** RFC 4122 UUID-shaped, optionally with the strimz_ prefix. */\nconst IDEMPOTENCY_KEY_PATTERN =\n /^(strimz_)?[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/\n\nexport function isValidIdempotencyKey(key: string): boolean {\n if (typeof key !== 'string') return false\n if (key.length > 255) return false\n return IDEMPOTENCY_KEY_PATTERN.test(key)\n}\n","/**\n * Cursor-based pagination, identical shape to the API's list responses.\n */\n\nexport interface Page<T> {\n data: T[]\n nextCursor: string | null\n hasMore: boolean\n}\n\nexport interface PaginationParams {\n limit?: number\n cursor?: string | null\n}\n\n/**\n * Async-iterable wrapper that auto-paginates through every page of a list.\n *\n * for await (const tx of strimz.transactions.listAll()) { ... }\n */\nexport class AutoPagingIterator<T> implements AsyncIterable<T> {\n constructor(private readonly fetchPage: (cursor: string | null) => Promise<Page<T>>) {}\n\n async *[Symbol.asyncIterator](): AsyncIterator<T> {\n let cursor: string | null = null\n let first = true\n while (first || cursor !== null) {\n first = false\n const page: Page<T> = await this.fetchPage(cursor)\n for (const item of page.data) {\n yield item\n }\n cursor = page.hasMore ? page.nextCursor : null\n }\n }\n\n async forEach(handler: (item: T) => void | Promise<void>): Promise<void> {\n for await (const item of this) {\n await handler(item)\n }\n }\n\n async toArray(): Promise<T[]> {\n const out: T[] = []\n for await (const item of this) out.push(item)\n return out\n }\n}\n","/**\n * Base class every resource extends. Centralises endpoint plumbing so\n * resource classes are tiny declarative wrappers.\n */\n\nimport type { z } from 'zod'\nimport type { Fetcher, RequestSpec } from '../http/fetcher.js'\nimport { generateIdempotencyKey } from '../idempotency.js'\nimport { AutoPagingIterator, type Page, type PaginationParams } from '../pagination.js'\n\ntype AnySchema = z.ZodTypeAny\ntype Inferred<S extends AnySchema> = z.output<S>\n\nexport interface ResourceContext {\n fetcher: Fetcher\n}\n\nexport interface RequestOptions {\n /** Override or supply the idempotency key for a mutating call. */\n idempotencyKey?: string\n /** Per-request timeout in ms. */\n timeoutMs?: number\n}\n\nexport abstract class BaseResource {\n constructor(protected readonly ctx: ResourceContext) {}\n\n protected async get<S extends AnySchema>(\n path: string,\n schema?: S,\n query?: RequestSpec['query'],\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({ method: 'GET', path, query })\n return parse(data, schema)\n }\n\n protected async post<S extends AnySchema>(\n path: string,\n body: unknown,\n schema?: S,\n options?: RequestOptions,\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({\n method: 'POST',\n path,\n body,\n idempotencyKey: options?.idempotencyKey ?? generateIdempotencyKey(),\n timeoutMs: options?.timeoutMs,\n })\n return parse(data, schema)\n }\n\n protected async patch<S extends AnySchema>(\n path: string,\n body: unknown,\n schema?: S,\n options?: RequestOptions,\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({\n method: 'PATCH',\n path,\n body,\n idempotencyKey: options?.idempotencyKey ?? generateIdempotencyKey(),\n timeoutMs: options?.timeoutMs,\n })\n return parse(data, schema)\n }\n\n protected async delete<S extends AnySchema>(path: string, schema?: S): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({ method: 'DELETE', path })\n return parse(data, schema)\n }\n\n protected listPage<S extends AnySchema>(\n path: string,\n itemSchema: S,\n params?: PaginationParams | Record<string, ScalarParam>,\n ): Promise<Page<Inferred<S>>> {\n return this.ctx.fetcher\n .request<unknown>({ method: 'GET', path, query: toQuery(params) })\n .then((raw) => parsePage(raw, itemSchema))\n }\n\n protected listAuto<S extends AnySchema>(\n path: string,\n itemSchema: S,\n params?: Record<string, ScalarParam>,\n ): AutoPagingIterator<Inferred<S>> {\n return new AutoPagingIterator((cursor) =>\n this.listPage(path, itemSchema, { ...params, cursor }),\n )\n }\n}\n\ntype ScalarParam = string | number | boolean | null | undefined\n\nfunction toQuery(\n params: PaginationParams | Record<string, ScalarParam> | undefined,\n): Record<string, ScalarParam> {\n if (!params) return {}\n return params as Record<string, ScalarParam>\n}\n\nfunction parse<S extends AnySchema>(data: unknown, schema?: S): Inferred<S> {\n return (schema ? schema.parse(data) : data) as Inferred<S>\n}\n\nfunction parsePage<S extends AnySchema>(raw: unknown, itemSchema: S): Page<Inferred<S>> {\n const obj = raw as { data?: unknown[]; nextCursor?: string | null; hasMore?: boolean }\n const items = (obj?.data ?? []).map((d) => itemSchema.parse(d) as Inferred<S>)\n return {\n data: items,\n nextCursor: obj?.nextCursor ?? null,\n hasMore: obj?.hasMore === true,\n }\n}\n","import {\n merchantPublicBrandSchema,\n paymentSessionSchema,\n subscriptionPlanSchema,\n subscriptionStatusResultSchema,\n type MerchantPublicBrand,\n type PaymentSession,\n type SubscriptionPlan,\n type SubscriptionStatusResult,\n} from '@strimz/shared-types'\nimport { BaseResource } from './base-resource.js'\n\n/**\n * Public hosted-checkout reads.\n *\n * Backed by the `/v1/checkout/*` namespace on the Strimz API, which\n * is intentionally unauthenticated. Session and plan records are\n * what a merchant offers to payers, so a payer landing on a checkout\n * URL must be able to load the terms without holding any API key.\n *\n * Use this resource (via `StrimzBrowserClient.checkout`) from the\n * browser. The merchant-scoped `paymentSessions` / `subscriptionPlans`\n * resources on `StrimzClient` remain the right call from server-side\n * code with a secret key.\n */\nexport class CheckoutResource extends BaseResource {\n /** Load a payment session by id (public, no merchant scoping). */\n session(id: string): Promise<PaymentSession> {\n return this.get(`/v1/checkout/sessions/${encodeURIComponent(id)}`, paymentSessionSchema)\n }\n\n /** Load a subscription plan by id (public, no merchant scoping). */\n plan(id: string): Promise<SubscriptionPlan> {\n return this.get(`/v1/checkout/plans/${encodeURIComponent(id)}`, subscriptionPlanSchema)\n }\n\n /** Load the merchant's public brand card by id. */\n merchant(id: string): Promise<MerchantPublicBrand> {\n return this.get(`/v1/checkout/merchants/${encodeURIComponent(id)}`, merchantPublicBrandSchema)\n }\n\n /** Whether a wallet already subscribes to a plan (drives \"already\n * subscribed\" on the enrolment page). */\n subscriptionStatus(planId: string, payer: string): Promise<SubscriptionStatusResult> {\n return this.get(\n `/v1/checkout/plans/${encodeURIComponent(planId)}/subscription?payer=${encodeURIComponent(payer)}`,\n subscriptionStatusResultSchema,\n )\n }\n}\n","import {\n tokenMetadataSchema,\n tokenPermitNonceSchema,\n type TokenMetadata,\n type TokenPermitNonce,\n} from '@strimz/shared-types'\nimport { BaseResource } from './base-resource.js'\n\n/**\n * Token metadata and capability lookup.\n *\n * The two endpoints are public on the API (no key required). Token\n * metadata is purely chain-derived, has no PII, and is what the\n * browser SDK consults to pick which meta-tx path to take for a\n * given token. Bundled here so consumers don't have to write the HTTP\n * fetch themselves.\n */\nexport class TokensResource extends BaseResource {\n /**\n * Fetch full metadata for a token. Throws via the underlying fetcher\n * (404 maps to `StrimzNotFoundError`) if the token isn't whitelisted.\n */\n retrieve(address: string): Promise<TokenMetadata> {\n return this.get(`/v1/tokens/${encodeURIComponent(address.toLowerCase())}`, tokenMetadataSchema)\n }\n\n /**\n * Read an owner's current EIP-2612 permit nonce. Call this\n * immediately before signing a Permit. The token contract rejects\n * stale nonces, and the value advances on every successful permit.\n */\n permitNonce(address: string, owner: string): Promise<TokenPermitNonce> {\n return this.get(\n `/v1/tokens/${encodeURIComponent(address.toLowerCase())}/permit-nonce`,\n tokenPermitNonceSchema,\n { owner: owner.toLowerCase() },\n )\n }\n}\n\n/**\n * Path selector. Decides which meta-tx flow to take given a token's\n * capabilities and the action a merchant wants to perform.\n *\n * The choice is unambiguous in 99% of cases:\n * - One-shot pay. Prefers EIP-3009. Falls back to approve+pay if the\n * token has neither.\n * - Subscription enrol. Prefers EIP-2612 (the only meta-tx path that\n * grants the recurring allowance subscribers need). If unavailable,\n * the merchant must use the classic approve+create flow.\n *\n * Returned `path` values are strings (not enums) so future schemes\n * can extend the union without breaking existing call sites.\n */\nexport type RelayPath =\n | 'pay_with_authorization'\n | 'permit_and_create_subscription'\n | 'approve_then_pay'\n | 'approve_then_create_subscription'\n\nexport function selectPaymentPath(meta: TokenMetadata): RelayPath {\n return meta.capabilities.transferAuth3009 ? 'pay_with_authorization' : 'approve_then_pay'\n}\n\nexport function selectSubscriptionPath(meta: TokenMetadata): RelayPath {\n return meta.capabilities.permit2612\n ? 'permit_and_create_subscription'\n : 'approve_then_create_subscription'\n}\n","/**\n * StrimzBrowserClient. The publishable-key, browser-safe SDK entry point.\n *\n * Used by `@strimz/sdk-react` and any other browser code that should\n * never see a secret key. Surfaces a strict subset of resource methods,\n * only those safe to call from a browser with a `pk_test_...` or\n * `pk_live_...` key.\n */\n\nimport { kindFromKey, modeFromKey, type ApiKeyMode } from '@strimz/shared-config'\nimport { Fetcher } from './http/fetcher.js'\nimport { buildBaseHeaders } from './http/headers.js'\nimport { StrimzAuthenticationError } from './errors.js'\nimport { CheckoutResource } from './resources/checkout.js'\nimport {\n TokensResource,\n selectPaymentPath,\n selectSubscriptionPath,\n type RelayPath,\n} from './resources/tokens.js'\n\nexport interface StrimzBrowserClientOptions {\n /** Publishable key. Either `pk_test_...` or `pk_live_...`. */\n publishableKey: string\n /** Override the API base URL. */\n baseUrl?: string\n /** Per-request timeout in milliseconds. Default 30s. */\n timeoutMs?: number\n}\n\nconst DEFAULT_BASE_URL = 'https://api.strimz.finance'\n\n/**\n * Browser-safe Strimz client.\n *\n * Designed for hosted-checkout state polling and the React component\n * family. Read-only on most resources. Refuses a secret key.\n *\n * The `tokens` resource and the `selectPaymentPath` /\n * `selectSubscriptionPath` selectors form the capability-detection\n * layer. Given a token, the SDK asks the API which meta-tx flows the\n * token supports, and the selectors map that to a `RelayPath` the\n * checkout UI uses to decide which typed-data to build.\n */\nexport class StrimzBrowserClient {\n public readonly mode: ApiKeyMode\n /**\n * Public hosted-checkout reads. Payment sessions and subscription\n * plans by id. Backed by the `/v1/checkout/*` namespace on the API,\n * which is intentionally unauthenticated.\n */\n public readonly checkout: CheckoutResource\n /** Token metadata and EIP-2612 permit nonce lookup. */\n public readonly tokens: TokensResource\n\n constructor(options: StrimzBrowserClientOptions) {\n const key = options.publishableKey\n if (!key || typeof key !== 'string') {\n throw new StrimzAuthenticationError(\n { code: 'authentication_error', message: 'publishableKey is required' },\n 401,\n )\n }\n if (kindFromKey(key) !== 'publishable') {\n throw new StrimzAuthenticationError(\n {\n code: 'authentication_error',\n message:\n 'StrimzBrowserClient must be initialised with a publishable key (pk_test_... / pk_live_...). Never expose secret keys to a browser.',\n },\n 401,\n )\n }\n const mode = modeFromKey(key)\n if (mode == null) {\n throw new StrimzAuthenticationError(\n { code: 'authentication_error', message: 'Unrecognised API key prefix' },\n 401,\n )\n }\n this.mode = mode\n\n const fetcher = new Fetcher({\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n baseHeaders: buildBaseHeaders(key, 'browser'),\n timeoutMs: options.timeoutMs,\n maxRetries: 2,\n })\n this.checkout = new CheckoutResource({ fetcher })\n this.tokens = new TokensResource({ fetcher })\n }\n}\n\n// Re-export the selectors and path type so consumers don't need a\n// second import: `import { StrimzBrowserClient, selectPaymentPath }\n// from '@strimz/sdk/browser'`.\nexport { selectPaymentPath, selectSubscriptionPath, type RelayPath }\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/http/headers.ts","../src/http/fetcher.ts","../src/idempotency.ts","../src/pagination.ts","../src/resources/base-resource.ts","../src/resources/checkout.ts","../src/resources/tokens.ts","../src/browser-client.ts"],"names":["uuid","paymentSessionSchema","subscriptionPlanSchema","merchantPublicBrandSchema","subscriptionStatusResultSchema","subscriptionEnrolmentTermsSchema","tokenMetadataSchema","tokenPermitNonceSchema","kindFromKey","modeFromKey"],"mappings":";;;;;;;;;AAsCO,IAAM,WAAA,GAAN,cAA0B,KAAA,CAAM;AAAA,EACrB,IAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EAEhB,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAClB,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACtB;AACF,CAAA;AAEO,IAAM,yBAAA,GAAN,cAAwC,WAAA,CAAY;AAAA,EACzD,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,qBAAA,GAAN,cAAoC,WAAA,CAAY;AAAA,EACrD,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,uBAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,qBAAA,GAAN,cAAoC,WAAA,CAAY;AAAA,EACrD,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,uBAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,mBAAA,GAAN,cAAkC,WAAA,CAAY;AAAA,EACnD,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,sBAAA,GAAN,cAAqC,WAAA,CAAY;AAAA,EACtD,WAAA,CAAY,MAAuB,UAAA,EAAqB;AACtD,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,wBAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,oBAAA,GAAN,cAAmC,WAAA,CAAY;AAAA,EACpC,YAAA;AAAA,EAChB,WAAA,CAAY,IAAA,EAAuB,UAAA,EAAqB,YAAA,EAAuB;AAC7E,IAAA,KAAA,CAAM,MAAM,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AAAA,EACtB;AACF,CAAA;AAEO,IAAM,kBAAA,GAAN,cAAiC,WAAA,CAAY;AAAA,EACzB,KAAA;AAAA,EACzB,WAAA,CAAY,SAAiB,KAAA,EAAgB;AAC3C,IAAA,KAAA,CAAM,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,CAAA;AACxC,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,EACf;AACF,CAAA;AAEO,IAAM,kBAAA,GAAN,cAAiC,WAAA,CAAY;AAAA,EAClD,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,EAAE,IAAA,EAAM,SAAA,EAAW,OAAA,EAAS,CAAA;AAClC,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AAAA,EACd;AACF,CAAA;AAUO,SAAS,aAAA,CACd,UAAA,EACA,IAAA,EACA,YAAA,EACa;AACb,EAAA,IAAI,eAAe,GAAA,EAAK,OAAO,IAAI,yBAAA,CAA0B,MAAM,UAAU,CAAA;AAC7E,EAAA,IAAI,eAAe,GAAA,EAAK,OAAO,IAAI,qBAAA,CAAsB,MAAM,UAAU,CAAA;AACzE,EAAA,IAAI,eAAe,GAAA,EAAK,OAAO,IAAI,mBAAA,CAAoB,MAAM,UAAU,CAAA;AACvE,EAAA,IAAI,UAAA,KAAe,GAAA,IAAO,IAAA,CAAK,IAAA,KAAS,mBAAA,EAAqB;AAC3D,IAAA,OAAO,IAAI,sBAAA,CAAuB,IAAA,EAAM,UAAU,CAAA;AAAA,EACpD;AACA,EAAA,IAAI,eAAe,GAAA,EAAK,OAAO,IAAI,qBAAA,CAAsB,MAAM,UAAU,CAAA;AACzE,EAAA,IAAI,eAAe,GAAA,EAAK,OAAO,IAAI,oBAAA,CAAqB,IAAA,EAAM,YAAY,YAAY,CAAA;AACtF,EAAA,OAAO,IAAI,WAAA,CAAY,IAAA,EAAM,UAAU,CAAA;AACzC;;;ACjIO,IAAM,OAAA,GAAU;AAAA,EACrB,aAAA,EAAe,eAAA;AAAA,EACf,cAAA,EAAgB,0BAAA;AAAA,EAEhB,OAAA,EAAS,cAAA;AAAA,EACT,UAAA,EAAY,sBAAA;AAAA,EACZ,UAAA,EAAY;AACd,CAAA;AAEO,IAAM,QAAA,GAAW,aAAA;AAGjB,IAAM,WAAA,GAAc,OAAA;AAEpB,SAAS,gBAAA,CAAiB,QAAgB,OAAA,EAAyC;AACxF,EAAA,OAAO;AAAA,IACL,CAAC,OAAA,CAAQ,aAAa,GAAG,UAAU,MAAM,CAAA,CAAA;AAAA,IACzC,CAAC,OAAA,CAAQ,OAAO,GAAG,QAAA;AAAA,IACnB,CAAC,OAAA,CAAQ,UAAU,GAAG,WAAA;AAAA,IACtB,CAAC,OAAA,CAAQ,UAAU,GAAG,OAAA;AAAA,IACtB,MAAA,EAAQ;AAAA,GACV;AACF;;;ACuBA,IAAM,kBAAA,GAAqB,GAAA;AAC3B,IAAM,mBAAA,GAAsB,CAAA;AAC5B,IAAM,0BAAA,GAA6B,GAAA;AAE5B,IAAM,UAAN,MAAc;AAAA,EACF,OAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,gBAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EAEjB,YAAY,IAAA,EAAsB;AAChC,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAA;AAC7C,IAAA,IAAA,CAAK,cAAc,IAAA,CAAK,WAAA;AACxB,IAAA,IAAA,CAAK,SAAA,GAAY,KAAK,SAAA,IAAa,kBAAA;AACnC,IAAA,IAAA,CAAK,UAAA,GAAa,KAAK,UAAA,IAAc,mBAAA;AACrC,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAK,gBAAA,IAAoB,0BAAA;AACjD,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AACvB,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,KAAA,IAAS,UAAA,CAAW,KAAA,CAAM,KAAK,UAAU,CAAA;AAAA,EACjE;AAAA,EAEA,MAAM,QAAW,IAAA,EAA+B;AAC9C,IAAA,MAAM,MAAM,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,KAAK,KAAK,CAAA;AAC/C,IAAA,MAAM,UAAA,GAAa,aAAa,IAAI,CAAA;AACpC,IAAA,MAAM,OAAA,GAAkC,EAAE,GAAG,IAAA,CAAK,WAAA,EAAY;AAC9D,IAAA,IAAI,IAAA,CAAK,IAAA,IAAQ,IAAA,EAAM,OAAA,CAAQ,cAAc,CAAA,GAAI,kBAAA;AACjD,IAAA,IAAI,KAAK,cAAA,EAAgB,OAAA,CAAQ,OAAA,CAAQ,cAAc,IAAI,IAAA,CAAK,cAAA;AAEhE,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,IAAI,OAAA;AACJ,IAAA,OAAO,OAAA,IAAW,KAAK,UAAA,EAAY;AACjC,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,YAAY,EAAE,MAAA,EAAQ,KAAK,MAAA,EAAQ,GAAA,EAAK,SAAS,CAAA;AACtD,QAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,EAAI;AACvB,QAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,gBAAA;AAAA,UACrB,GAAA;AAAA,UACA;AAAA,YACE,QAAQ,IAAA,CAAK,MAAA;AAAA,YACb,OAAA;AAAA,YACA,IAAA,EAAM,KAAK,IAAA,IAAQ,IAAA,GAAO,SAAY,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI;AAAA,WAChE;AAAA,UACA,IAAA,CAAK,aAAa,IAAA,CAAK;AAAA,SACzB;AACA,QAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA;AACxB,QAAA,IAAA,CAAK,UAAA,GAAa,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,GAAA,EAAK,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAQ,EAAA,EAAI,OAAA,EAAS,CAAA;AAE/E,QAAA,IAAI,IAAI,EAAA,EAAI;AACV,UAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,EAAK,OAAO,KAAA,CAAA;AAC/B,UAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AAAA,QACzB;AAEA,QAAA,MAAM,SAAA,GAAY,MAAM,cAAA,CAAe,GAAG,CAAA;AAC1C,QAAA,MAAM,YAAA,GAAe,gBAAgB,GAAG,CAAA;AAGxC,QAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,IAAO,OAAA,GAAU,KAAK,UAAA,EAAY;AACnD,UAAA,MAAM,KAAA,CAAM,YAAA,IAAgB,IAAA,CAAK,UAAA,CAAW,OAAO,CAAC,CAAA;AACpD,UAAA,OAAA,EAAA;AACA,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,IAAI,MAAA,IAAU,GAAA,IAAO,UAAA,IAAc,OAAA,GAAU,KAAK,UAAA,EAAY;AAChE,UAAA,MAAM,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,OAAO,CAAC,CAAA;AACpC,UAAA,OAAA,EAAA;AACA,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,aAAA,CAAc,GAAA,CAAI,MAAA,EAAQ,SAAA,EAAW,YAAY,CAAA;AAAA,MACzD,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,GAAA,YAAe,aAAa,MAAM,GAAA;AACtC,QAAA,OAAA,GAAU,GAAA;AACV,QAAA,IAAI,CAAC,aAAA,CAAc,GAAG,CAAA,IAAK,OAAA,IAAW,KAAK,UAAA,EAAY;AACrD,UAAA,IAAI,GAAA,YAAe,oBAAoB,MAAM,GAAA;AAC7C,UAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,eAAA,EAAkB,SAAS,GAAG,CAAC,IAAI,GAAG,CAAA;AAAA,QACrE;AACA,QAAA,MAAM,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,OAAO,CAAC,CAAA;AACpC,QAAA,OAAA,EAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,oBAAA,EAAuB,IAAA,CAAK,UAAU,YAAY,OAAO,CAAA;AAAA,EACxF;AAAA,EAEA,MAAc,gBAAA,CACZ,GAAA,EACA,IAAA,EACA,SAAA,EACmB;AACnB,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,SAAS,CAAA;AAC5D,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,CAAK,SAAA,CAAU,GAAA,EAAK,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AAAA,IACzE,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,YAAA,CAAa,GAAG,CAAA,EAAG;AACrB,QAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,wBAAA,EAA2B,SAAS,CAAA,EAAA,CAAI,CAAA;AAAA,MACvE;AACA,MAAA,MAAM,GAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAEQ,QAAA,CAAS,MAAc,KAAA,EAAsC;AACnE,IAAA,MAAM,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,EAAG,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,IAAA,GAAO,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAA,CAAA;AACvE,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,IAAA,MAAM,GAAA,GAAM,IAAI,eAAA,EAAgB;AAChC,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC1C,MAAA,IAAI,KAAK,IAAA,EAAM;AACf,MAAA,GAAA,CAAI,MAAA,CAAO,CAAA,EAAG,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IACzB;AACA,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,EAAS;AACxB,IAAA,OAAO,EAAA,GAAK,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,GAAK,IAAA;AAAA,EAChC;AAAA,EAEQ,WAAW,OAAA,EAAyB;AAC1C,IAAA,MAAM,OAAO,IAAA,CAAK,gBAAA,GAAmB,IAAA,CAAK,GAAA,CAAI,GAAG,OAAO,CAAA;AACxD,IAAA,OAAO,KAAK,GAAA,CAAI,IAAA,GAAO,aAAa,IAAA,CAAK,gBAAgB,GAAG,GAAK,CAAA;AAAA,EACnE;AACF,CAAA;AAIA,SAAS,aAAa,KAAA,EAAuB;AAC3C,EAAA,MAAM,CAAA,GAAI,UAAA;AACV,EAAA,IAAI,CAAA,CAAE,QAAQ,eAAA,EAAiB;AAC7B,IAAA,MAAM,GAAA,GAAM,IAAI,WAAA,CAAY,CAAC,CAAA;AAC7B,IAAA,CAAA,CAAE,MAAA,CAAO,gBAAgB,GAAG,CAAA;AAC5B,IAAA,OAAA,CAAS,GAAA,CAAI,CAAC,CAAA,IAAK,CAAA,IAAK,UAAA,GAAe,KAAA;AAAA,EACzC;AACA,EAAA,OAAO,IAAA,CAAK,QAAO,GAAI,KAAA;AACzB;AAEA,SAAS,aAAa,IAAA,EAA4B;AAChD,EAAA,IAAI,KAAK,MAAA,KAAW,KAAA,IAAS,IAAA,CAAK,MAAA,KAAW,UAAU,OAAO,IAAA;AAC9D,EAAA,OAAO,KAAK,cAAA,IAAkB,IAAA;AAChC;AAEA,eAAe,eAAe,GAAA,EAAyC;AACrE,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAC7B,IAAA,MAAM,GAAA,GACJ,OAAO,IAAA,KAAS,QAAA,IAAY,SAAS,IAAA,IAAQ,OAAA,IAAW,IAAA,GACnD,IAAA,CAA4B,KAAA,GAC7B,IAAA;AACN,IAAA,IAAI,OAAO,QAAQ,QAAA,IAAY,GAAA,KAAQ,QAAQ,MAAA,IAAU,GAAA,IAAO,aAAa,GAAA,EAAK;AAChF,MAAA,OAAO,kBAAkB,GAA8B,CAAA;AAAA,IACzD;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,WAAA,EAAa,SAAS,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,CAAA,CAAA,EAAG;AAC5D;AAKA,IAAM,mBAAA,uBAA0B,GAAA,CAAI,CAAC,UAAU,OAAA,EAAS,QAAA,EAAU,iBAAiB,CAAC,CAAA;AAEpF,SAAS,kBAAkB,GAAA,EAA+C;AACxE,EAAA,MAAM,OAAA,GACJ,OAAO,GAAA,CAAI,OAAA,KAAY,YAAY,GAAA,CAAI,OAAA,KAAY,OAC/C,MAAA,CAAO,WAAA;AAAA,IACL,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,OAAkC,CAAA,CAAE,MAAA;AAAA,MAAO,CAAC,CAAC,CAAC,CAAA,KAC/D,mBAAA,CAAoB,IAAI,CAAC;AAAA;AAC3B,GACF,GACA,MAAA;AACN,EAAA,OAAO;AAAA,IACL,MAAM,OAAO,GAAA,CAAI,IAAA,KAAS,QAAA,GAAY,IAAI,IAAA,GAAmC,WAAA;AAAA,IAC7E,SAAS,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,GAAW,IAAI,OAAA,GAAU,gBAAA;AAAA,IACzD,OAAO,OAAO,GAAA,CAAI,KAAA,KAAU,QAAA,GAAW,IAAI,KAAA,GAAQ,MAAA;AAAA,IACnD,WAAW,OAAO,GAAA,CAAI,SAAA,KAAc,QAAA,GAAW,IAAI,SAAA,GAAY,MAAA;AAAA,IAC/D,OAAA,EAAS,WAAW,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,CAAE,MAAA,GAAS,IAAI,OAAA,GAAU;AAAA,GAClE;AACF;AAEA,SAAS,gBAAgB,GAAA,EAAmC;AAC1D,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AACvC,EAAA,IAAI,CAAC,GAAG,OAAO,MAAA;AACf,EAAA,MAAM,CAAA,GAAI,OAAO,CAAC,CAAA;AAClB,EAAA,IAAI,MAAA,CAAO,SAAS,CAAC,CAAA,SAAU,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA,GAAI,GAAA;AAChD,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AACzB,EAAA,IAAI,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,GAAO,IAAA,CAAK,GAAA,EAAK,CAAA;AAC/D,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;AAEA,SAAS,aAAa,GAAA,EAAuB;AAC3C,EAAA,OAAO,GAAA,YAAe,KAAA,IAAS,GAAA,CAAI,IAAA,KAAS,YAAA;AAC9C;AAEA,SAAS,cAAc,GAAA,EAAuB;AAC5C,EAAA,IAAI,GAAA,YAAe,WAAW,OAAO,IAAA;AACrC,EAAA,IAAI,eAAe,KAAA,IAAS,sBAAA,CAAuB,KAAK,GAAA,CAAI,OAAO,GAAG,OAAO,IAAA;AAC7E,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,SAAS,GAAA,EAAsB;AACtC,EAAA,IAAI,GAAA,YAAe,KAAA,EAAO,OAAO,GAAA,CAAI,OAAA;AACrC,EAAA,OAAO,OAAO,GAAG,CAAA;AACnB;AC9PO,SAAS,sBAAA,GAAiC;AAC/C,EAAA,OAAO,CAAA,OAAA,EAAUA,mBAAM,CAAA,CAAA;AACzB;;;ACYO,IAAM,qBAAN,MAAwD;AAAA,EAC7D,YAA6B,SAAA,EAAwD;AAAxD,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA,EAAyD;AAAA,EAAzD,SAAA;AAAA,EAE7B,QAAQ,MAAA,CAAO,aAAa,CAAA,GAAsB;AAChD,IAAA,IAAI,MAAA,GAAwB,IAAA;AAC5B,IAAA,IAAI,KAAA,GAAQ,IAAA;AACZ,IAAA,OAAO,KAAA,IAAS,WAAW,IAAA,EAAM;AAC/B,MAAA,KAAA,GAAQ,KAAA;AACR,MAAA,MAAM,IAAA,GAAgB,MAAM,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AACjD,MAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,IAAA,EAAM;AAC5B,QAAA,MAAM,IAAA;AAAA,MACR;AACA,MAAA,MAAA,GAAS,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,OAAA,EAA2D;AACvE,IAAA,WAAA,MAAiB,QAAQ,IAAA,EAAM;AAC7B,MAAA,MAAM,QAAQ,IAAI,CAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAM,OAAA,GAAwB;AAC5B,IAAA,MAAM,MAAW,EAAC;AAClB,IAAA,WAAA,MAAiB,IAAA,IAAQ,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA;AAC5C,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACvBO,IAAe,eAAf,MAA4B;AAAA,EACjC,YAA+B,GAAA,EAAsB;AAAtB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAuB;AAAA,EAAvB,GAAA;AAAA,EAE/B,MAAgB,GAAA,CACd,IAAA,EACA,MAAA,EACA,KAAA,EACsB;AACtB,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,OAAA,CAAiB,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,CAAA;AACnF,IAAA,OAAO,KAAA,CAAM,MAAM,MAAM,CAAA;AAAA,EAC3B;AAAA,EAEA,MAAgB,IAAA,CACd,IAAA,EACA,IAAA,EACA,QACA,OAAA,EACsB;AACtB,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAI,QAAQ,OAAA,CAAiB;AAAA,MACnD,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA;AAAA,MACA,IAAA;AAAA,MACA,cAAA,EAAgB,OAAA,EAAS,cAAA,IAAkB,sBAAA,EAAuB;AAAA,MAClE,WAAW,OAAA,EAAS;AAAA,KACrB,CAAA;AACD,IAAA,OAAO,KAAA,CAAM,MAAM,MAAM,CAAA;AAAA,EAC3B;AAAA,EAEA,MAAgB,KAAA,CACd,IAAA,EACA,IAAA,EACA,QACA,OAAA,EACsB;AACtB,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAI,QAAQ,OAAA,CAAiB;AAAA,MACnD,MAAA,EAAQ,OAAA;AAAA,MACR,IAAA;AAAA,MACA,IAAA;AAAA,MACA,cAAA,EAAgB,OAAA,EAAS,cAAA,IAAkB,sBAAA,EAAuB;AAAA,MAClE,WAAW,OAAA,EAAS;AAAA,KACrB,CAAA;AACD,IAAA,OAAO,KAAA,CAAM,MAAM,MAAM,CAAA;AAAA,EAC3B;AAAA,EAEA,MAAgB,MAAA,CAA4B,IAAA,EAAc,MAAA,EAAkC;AAC1F,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,QAAiB,EAAE,MAAA,EAAQ,QAAA,EAAU,IAAA,EAAM,CAAA;AAC/E,IAAA,OAAO,KAAA,CAAM,MAAM,MAAM,CAAA;AAAA,EAC3B;AAAA,EAEU,QAAA,CACR,IAAA,EACA,UAAA,EACA,MAAA,EAC4B;AAC5B,IAAA,OAAO,IAAA,CAAK,IAAI,OAAA,CACb,OAAA,CAAiB,EAAE,MAAA,EAAQ,KAAA,EAAO,MAAM,KAAA,EAAO,OAAA,CAAQ,MAAM,CAAA,EAAG,EAChE,IAAA,CAAK,CAAC,QAAQ,SAAA,CAAU,GAAA,EAAK,UAAU,CAAC,CAAA;AAAA,EAC7C;AAAA,EAEU,QAAA,CACR,IAAA,EACA,UAAA,EACA,MAAA,EACiC;AACjC,IAAA,OAAO,IAAI,kBAAA;AAAA,MAAmB,CAAC,MAAA,KAC7B,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,YAAY,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ;AAAA,KACvD;AAAA,EACF;AACF,CAAA;AAIA,SAAS,QACP,MAAA,EAC6B;AAC7B,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAC;AACrB,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,KAAA,CAA2B,MAAe,MAAA,EAAyB;AAC1E,EAAA,OAAQ,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,GAAI,IAAA;AACxC;AAEA,SAAS,SAAA,CAA+B,KAAc,UAAA,EAAkC;AACtF,EAAA,MAAM,GAAA,GAAM,GAAA;AACZ,EAAA,MAAM,KAAA,GAAA,CAAS,GAAA,EAAK,IAAA,IAAQ,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,UAAA,CAAW,KAAA,CAAM,CAAC,CAAgB,CAAA;AAC7E,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,KAAA;AAAA,IACN,UAAA,EAAY,KAAK,UAAA,IAAc,IAAA;AAAA,IAC/B,OAAA,EAAS,KAAK,OAAA,KAAY;AAAA,GAC5B;AACF;;;ACxFO,IAAM,gBAAA,GAAN,cAA+B,YAAA,CAAa;AAAA;AAAA,EAEjD,QAAQ,EAAA,EAAqC;AAC3C,IAAA,OAAO,KAAK,GAAA,CAAI,CAAA,sBAAA,EAAyB,mBAAmB,EAAE,CAAC,IAAIC,gCAAoB,CAAA;AAAA,EACzF;AAAA;AAAA,EAGA,KAAK,EAAA,EAAuC;AAC1C,IAAA,OAAO,KAAK,GAAA,CAAI,CAAA,mBAAA,EAAsB,mBAAmB,EAAE,CAAC,IAAIC,kCAAsB,CAAA;AAAA,EACxF;AAAA;AAAA,EAGA,SAAS,EAAA,EAA0C;AACjD,IAAA,OAAO,KAAK,GAAA,CAAI,CAAA,uBAAA,EAA0B,mBAAmB,EAAE,CAAC,IAAIC,qCAAyB,CAAA;AAAA,EAC/F;AAAA;AAAA;AAAA,EAIA,kBAAA,CAAmB,QAAgB,KAAA,EAAkD;AACnF,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,MACV,sBAAsB,kBAAA,CAAmB,MAAM,CAAC,CAAA,oBAAA,EAAuB,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAAA,MAChGC;AAAA,KACF;AAAA,EACF;AAAA,EAEA,SAAA,CAAU,QAAgB,KAAA,EAAoD;AAC5E,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,MACV,sBAAsB,kBAAA,CAAmB,MAAM,CAAC,CAAA,aAAA,EAAgB,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAAA,MACzFC;AAAA,KACF;AAAA,EACF;AACF,CAAA;ACzCO,IAAM,cAAA,GAAN,cAA6B,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/C,SAAS,OAAA,EAAyC;AAChD,IAAA,OAAO,IAAA,CAAK,IAAI,CAAA,WAAA,EAAc,kBAAA,CAAmB,QAAQ,WAAA,EAAa,CAAC,CAAA,CAAA,EAAIC,+BAAmB,CAAA;AAAA,EAChG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAA,CAAY,SAAiB,KAAA,EAA0C;AACrE,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,MACV,CAAA,WAAA,EAAc,kBAAA,CAAmB,OAAA,CAAQ,WAAA,EAAa,CAAC,CAAA,aAAA,CAAA;AAAA,MACvDC,kCAAA;AAAA,MACA,EAAE,KAAA,EAAO,KAAA,CAAM,WAAA,EAAY;AAAE,KAC/B;AAAA,EACF;AACF,CAAA;AAsBO,SAAS,kBAAkB,IAAA,EAAgC;AAChE,EAAA,OAAO,IAAA,CAAK,YAAA,CAAa,gBAAA,GAAmB,wBAAA,GAA2B,kBAAA;AACzE;AAEO,SAAS,uBAAuB,IAAA,EAAgC;AACrE,EAAA,OAAO,IAAA,CAAK,YAAA,CAAa,UAAA,GACrB,gCAAA,GACA,kCAAA;AACN;;;ACtCA,IAAM,gBAAA,GAAmB,4BAAA;AAclB,IAAM,sBAAN,MAA0B;AAAA,EACf,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAA;AAAA;AAAA,EAEA,MAAA;AAAA,EAEhB,YAAY,OAAA,EAAqC;AAC/C,IAAA,MAAM,MAAM,OAAA,CAAQ,cAAA;AACpB,IAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AACnC,MAAA,MAAM,IAAI,yBAAA;AAAA,QACR,EAAE,IAAA,EAAM,sBAAA,EAAwB,OAAA,EAAS,4BAAA,EAA6B;AAAA,QACtE;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAIC,wBAAA,CAAY,GAAG,CAAA,KAAM,aAAA,EAAe;AACtC,MAAA,MAAM,IAAI,yBAAA;AAAA,QACR;AAAA,UACE,IAAA,EAAM,sBAAA;AAAA,UACN,OAAA,EACE;AAAA,SACJ;AAAA,QACA;AAAA,OACF;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAOC,yBAAY,GAAG,CAAA;AAC5B,IAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,MAAM,IAAI,yBAAA;AAAA,QACR,EAAE,IAAA,EAAM,sBAAA,EAAwB,OAAA,EAAS,6BAAA,EAA8B;AAAA,QACvE;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAEZ,IAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ;AAAA,MAC1B,OAAA,EAAS,QAAQ,OAAA,IAAW,gBAAA;AAAA,MAC5B,WAAA,EAAa,gBAAA,CAAiB,GAAA,EAAK,SAAS,CAAA;AAAA,MAC5C,WAAW,OAAA,CAAQ,SAAA;AAAA,MACnB,UAAA,EAAY;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,gBAAA,CAAiB,EAAE,SAAS,CAAA;AAChD,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,cAAA,CAAe,EAAE,SAAS,CAAA;AAAA,EAC9C;AACF","file":"browser-client.cjs","sourcesContent":["/**\n * Error hierarchy for the Strimz SDK.\n *\n * Every error thrown by the SDK extends `StrimzError`. The SDK throws\n * on failure rather than resolving to `{ ok: false }` so call sites\n * stay linear and consumers can narrow with `instanceof` on the\n * exported subclasses.\n */\n\nexport type StrimzErrorCode =\n | 'authentication_error'\n | 'permission_denied'\n | 'invalid_request'\n | 'not_found'\n | 'idempotency_error'\n | 'rate_limited'\n | 'mode_mismatch'\n | 'merchant_not_found'\n | 'merchant_inactive'\n | 'token_not_whitelisted'\n | 'compliance_blocked'\n | 'session_expired'\n | 'session_invalid_state'\n | 'webhook_signature_invalid'\n | 'api_error'\n | 'network_error'\n | 'timeout'\n | 'parse_error'\n | 'unknown'\n\nexport interface StrimzErrorBody {\n code: StrimzErrorCode\n message: string\n param?: string\n requestId?: string\n details?: Record<string, unknown>\n}\n\nexport class StrimzError extends Error {\n public readonly code: StrimzErrorCode\n public readonly httpStatus: number | undefined\n public readonly requestId: string | undefined\n public readonly param: string | undefined\n public readonly details: Record<string, unknown> | undefined\n\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body.message)\n this.name = 'StrimzError'\n this.code = body.code\n this.httpStatus = httpStatus\n this.requestId = body.requestId\n this.param = body.param\n this.details = body.details\n }\n}\n\nexport class StrimzAuthenticationError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzAuthenticationError'\n }\n}\n\nexport class StrimzPermissionError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzPermissionError'\n }\n}\n\nexport class StrimzValidationError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzValidationError'\n }\n}\n\nexport class StrimzNotFoundError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzNotFoundError'\n }\n}\n\nexport class StrimzIdempotencyError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzIdempotencyError'\n }\n}\n\nexport class StrimzRateLimitError extends StrimzError {\n public readonly retryAfterMs: number | undefined\n constructor(body: StrimzErrorBody, httpStatus?: number, retryAfterMs?: number) {\n super(body, httpStatus)\n this.name = 'StrimzRateLimitError'\n this.retryAfterMs = retryAfterMs\n }\n}\n\nexport class StrimzNetworkError extends StrimzError {\n public override readonly cause: unknown\n constructor(message: string, cause: unknown) {\n super({ code: 'network_error', message })\n this.name = 'StrimzNetworkError'\n this.cause = cause\n }\n}\n\nexport class StrimzTimeoutError extends StrimzError {\n constructor(message: string) {\n super({ code: 'timeout', message })\n this.name = 'StrimzTimeoutError'\n }\n}\n\nexport class StrimzModeMismatchError extends StrimzError {\n constructor(message: string) {\n super({ code: 'mode_mismatch', message })\n this.name = 'StrimzModeMismatchError'\n }\n}\n\n/** Map an HTTP status + body to the right StrimzError subclass. */\nexport function classifyError(\n httpStatus: number,\n body: StrimzErrorBody,\n retryAfterMs?: number,\n): StrimzError {\n if (httpStatus === 401) return new StrimzAuthenticationError(body, httpStatus)\n if (httpStatus === 403) return new StrimzPermissionError(body, httpStatus)\n if (httpStatus === 404) return new StrimzNotFoundError(body, httpStatus)\n if (httpStatus === 409 && body.code === 'idempotency_error') {\n return new StrimzIdempotencyError(body, httpStatus)\n }\n if (httpStatus === 422) return new StrimzValidationError(body, httpStatus)\n if (httpStatus === 429) return new StrimzRateLimitError(body, httpStatus, retryAfterMs)\n return new StrimzError(body, httpStatus)\n}\n","/**\n * Strimz HTTP header conventions.\n *\n * `Authorization: Bearer <secret_key>`: primary auth.\n * `X-Strimz-Idempotency-Key`: mutating calls.\n * `X-Strimz-Sdk`: telemetry.\n * `X-Strimz-Sdk-Version`: telemetry.\n */\n\nexport const HEADERS = {\n authorization: 'Authorization',\n idempotencyKey: 'X-Strimz-Idempotency-Key',\n requestId: 'X-Strimz-Request-Id',\n sdkName: 'X-Strimz-Sdk',\n sdkVersion: 'X-Strimz-Sdk-Version',\n sdkRuntime: 'X-Strimz-Sdk-Runtime',\n} as const\n\nexport const SDK_NAME = '@strimz/sdk'\n\n/** The SDK version. Updated by the build pipeline if a version is published. */\nexport const SDK_VERSION = '0.0.0'\n\nexport function buildBaseHeaders(apiKey: string, runtime: string): Record<string, string> {\n return {\n [HEADERS.authorization]: `Bearer ${apiKey}`,\n [HEADERS.sdkName]: SDK_NAME,\n [HEADERS.sdkVersion]: SDK_VERSION,\n [HEADERS.sdkRuntime]: runtime,\n Accept: 'application/json',\n }\n}\n","/**\n * Fetch wrapper with retry, idempotency, and Strimz error parsing.\n *\n * Retries on:\n * - Network failures (TypeError on fetch).\n * - 5xx responses for idempotent methods (GET, POST with idempotency key).\n * - 429 with Retry-After.\n *\n * Does NOT retry on:\n * - 4xx other than 429 (caller's bug).\n * - 5xx for non-idempotent calls without an idempotency key.\n */\n\nimport {\n classifyError,\n StrimzError,\n StrimzNetworkError,\n StrimzTimeoutError,\n type StrimzErrorBody,\n} from '../errors.js'\nimport { HEADERS } from './headers.js'\n\nexport interface FetcherOptions {\n baseUrl: string\n baseHeaders: Record<string, string>\n /** Default timeout per attempt, milliseconds. */\n timeoutMs?: number\n /** How many retries before giving up. */\n maxRetries?: number\n /** Initial backoff in ms; doubled with jitter on each retry. */\n initialBackoffMs?: number\n /** Optional logger. */\n onRequest?: (info: { method: string; url: string; attempt: number }) => void\n onResponse?: (info: {\n method: string\n url: string\n status: number\n ms: number\n attempt: number\n }) => void\n /** Override the global fetch (for tests or Edge polyfills). */\n fetch?: typeof globalThis.fetch\n}\n\nexport interface RequestSpec {\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE'\n path: string\n query?: Record<string, string | number | boolean | null | undefined>\n body?: unknown\n idempotencyKey?: string\n /** Per-call timeout override. */\n timeoutMs?: number\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000\nconst DEFAULT_MAX_RETRIES = 3\nconst DEFAULT_INITIAL_BACKOFF_MS = 250\n\nexport class Fetcher {\n private readonly baseUrl: string\n private readonly baseHeaders: Record<string, string>\n private readonly timeoutMs: number\n private readonly maxRetries: number\n private readonly initialBackoffMs: number\n private readonly onRequest: FetcherOptions['onRequest']\n private readonly onResponse: FetcherOptions['onResponse']\n private readonly fetchImpl: typeof globalThis.fetch\n\n constructor(opts: FetcherOptions) {\n this.baseUrl = opts.baseUrl.replace(/\\/$/, '')\n this.baseHeaders = opts.baseHeaders\n this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES\n this.initialBackoffMs = opts.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS\n this.onRequest = opts.onRequest\n this.onResponse = opts.onResponse\n this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n async request<T>(spec: RequestSpec): Promise<T> {\n const url = this.buildUrl(spec.path, spec.query)\n const idempotent = isIdempotent(spec)\n const headers: Record<string, string> = { ...this.baseHeaders }\n if (spec.body != null) headers['Content-Type'] = 'application/json'\n if (spec.idempotencyKey) headers[HEADERS.idempotencyKey] = spec.idempotencyKey\n\n let attempt = 0\n let lastErr: unknown\n while (attempt <= this.maxRetries) {\n try {\n this.onRequest?.({ method: spec.method, url, attempt })\n const start = Date.now()\n const res = await this.fetchWithTimeout(\n url,\n {\n method: spec.method,\n headers,\n body: spec.body == null ? undefined : JSON.stringify(spec.body),\n },\n spec.timeoutMs ?? this.timeoutMs,\n )\n const ms = Date.now() - start\n this.onResponse?.({ method: spec.method, url, status: res.status, ms, attempt })\n\n if (res.ok) {\n if (res.status === 204) return undefined as T\n return (await res.json()) as T\n }\n\n const errorBody = await parseErrorBody(res)\n const retryAfterMs = parseRetryAfter(res)\n\n // 429. Back off and retry up to maxRetries.\n if (res.status === 429 && attempt < this.maxRetries) {\n await delay(retryAfterMs ?? this.backoffFor(attempt))\n attempt++\n continue\n }\n // 5xx. Retry only if idempotent.\n if (res.status >= 500 && idempotent && attempt < this.maxRetries) {\n await delay(this.backoffFor(attempt))\n attempt++\n continue\n }\n\n throw classifyError(res.status, errorBody, retryAfterMs)\n } catch (err) {\n if (err instanceof StrimzError) throw err\n lastErr = err\n if (!isNetworkLike(err) || attempt >= this.maxRetries) {\n if (err instanceof StrimzTimeoutError) throw err\n throw new StrimzNetworkError(`Network error: ${describe(err)}`, err)\n }\n await delay(this.backoffFor(attempt))\n attempt++\n }\n }\n throw new StrimzNetworkError(`Network error after ${this.maxRetries} retries`, lastErr)\n }\n\n private async fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n ): Promise<Response> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n return await this.fetchImpl(url, { ...init, signal: controller.signal })\n } catch (err) {\n if (isAbortError(err)) {\n throw new StrimzTimeoutError(`Request timed out after ${timeoutMs}ms`)\n }\n throw err\n } finally {\n clearTimeout(timer)\n }\n }\n\n private buildUrl(path: string, query?: RequestSpec['query']): string {\n const base = `${this.baseUrl}${path.startsWith('/') ? path : `/${path}`}`\n if (!query) return base\n const usp = new URLSearchParams()\n for (const [k, v] of Object.entries(query)) {\n if (v == null) continue\n usp.append(k, String(v))\n }\n const qs = usp.toString()\n return qs ? `${base}?${qs}` : base\n }\n\n private backoffFor(attempt: number): number {\n const expo = this.initialBackoffMs * Math.pow(2, attempt)\n return Math.min(expo + cryptoJitter(this.initialBackoffMs), 8_000)\n }\n}\n\n// Uses crypto so retry timing does not seed off Math.random in\n// environments where that's been monkey-patched.\nfunction cryptoJitter(maxMs: number): number {\n const g = globalThis as { crypto?: { getRandomValues?: (a: Uint32Array) => Uint32Array } }\n if (g.crypto?.getRandomValues) {\n const buf = new Uint32Array(1)\n g.crypto.getRandomValues(buf)\n return ((buf[0] ?? 0) / 0xffff_ffff) * maxMs\n }\n return Math.random() * maxMs\n}\n\nfunction isIdempotent(spec: RequestSpec): boolean {\n if (spec.method === 'GET' || spec.method === 'DELETE') return true\n return spec.idempotencyKey != null\n}\n\nasync function parseErrorBody(res: Response): Promise<StrimzErrorBody> {\n try {\n const json = (await res.json()) as unknown\n const raw =\n typeof json === 'object' && json !== null && 'error' in json\n ? (json as { error: unknown }).error\n : json\n if (typeof raw === 'object' && raw !== null && 'code' in raw && 'message' in raw) {\n return sanitiseErrorBody(raw as Record<string, unknown>)\n }\n } catch {\n // fall through\n }\n return { code: 'api_error', message: `HTTP ${res.status}` }\n}\n\n// Whitelist server-provided fields. A bugged endpoint that dumps stack\n// traces or internal metadata into the error payload never reaches SDK\n// consumers.\nconst ALLOWED_DETAIL_KEYS = new Set(['issues', 'field', 'reason', 'chargeAttemptId'])\n\nfunction sanitiseErrorBody(raw: Record<string, unknown>): StrimzErrorBody {\n const details =\n typeof raw.details === 'object' && raw.details !== null\n ? Object.fromEntries(\n Object.entries(raw.details as Record<string, unknown>).filter(([k]) =>\n ALLOWED_DETAIL_KEYS.has(k),\n ),\n )\n : undefined\n return {\n code: typeof raw.code === 'string' ? (raw.code as StrimzErrorBody['code']) : 'api_error',\n message: typeof raw.message === 'string' ? raw.message : 'Request failed',\n param: typeof raw.param === 'string' ? raw.param : undefined,\n requestId: typeof raw.requestId === 'string' ? raw.requestId : undefined,\n details: details && Object.keys(details).length > 0 ? details : undefined,\n }\n}\n\nfunction parseRetryAfter(res: Response): number | undefined {\n const v = res.headers.get('Retry-After')\n if (!v) return undefined\n const n = Number(v)\n if (Number.isFinite(n)) return Math.max(0, n) * 1_000\n const date = Date.parse(v)\n if (Number.isFinite(date)) return Math.max(0, date - Date.now())\n return undefined\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction isAbortError(err: unknown): boolean {\n return err instanceof Error && err.name === 'AbortError'\n}\n\nfunction isNetworkLike(err: unknown): boolean {\n if (err instanceof TypeError) return true // fetch network failures\n if (err instanceof Error && /fetch|network|econn/i.test(err.message)) return true\n return false\n}\n\nfunction describe(err: unknown): string {\n if (err instanceof Error) return err.message\n return String(err)\n}\n","import { uuid } from '@strimz/shared-crypto'\n\n/**\n * Generate an idempotency key for a mutating SDK call. The key is a\n * UUID with a stable `strimz_` prefix so it stays greppable in logs.\n */\nexport function generateIdempotencyKey(): string {\n return `strimz_${uuid()}`\n}\n\n/** RFC 4122 UUID-shaped, optionally with the strimz_ prefix. */\nconst IDEMPOTENCY_KEY_PATTERN =\n /^(strimz_)?[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/\n\nexport function isValidIdempotencyKey(key: string): boolean {\n if (typeof key !== 'string') return false\n if (key.length > 255) return false\n return IDEMPOTENCY_KEY_PATTERN.test(key)\n}\n","/**\n * Cursor-based pagination, identical shape to the API's list responses.\n */\n\nexport interface Page<T> {\n data: T[]\n nextCursor: string | null\n hasMore: boolean\n}\n\nexport interface PaginationParams {\n limit?: number\n cursor?: string | null\n}\n\n/**\n * Async-iterable wrapper that auto-paginates through every page of a list.\n *\n * for await (const tx of strimz.transactions.listAll()) { ... }\n */\nexport class AutoPagingIterator<T> implements AsyncIterable<T> {\n constructor(private readonly fetchPage: (cursor: string | null) => Promise<Page<T>>) {}\n\n async *[Symbol.asyncIterator](): AsyncIterator<T> {\n let cursor: string | null = null\n let first = true\n while (first || cursor !== null) {\n first = false\n const page: Page<T> = await this.fetchPage(cursor)\n for (const item of page.data) {\n yield item\n }\n cursor = page.hasMore ? page.nextCursor : null\n }\n }\n\n async forEach(handler: (item: T) => void | Promise<void>): Promise<void> {\n for await (const item of this) {\n await handler(item)\n }\n }\n\n async toArray(): Promise<T[]> {\n const out: T[] = []\n for await (const item of this) out.push(item)\n return out\n }\n}\n","/**\n * Base class every resource extends. Centralises endpoint plumbing so\n * resource classes are tiny declarative wrappers.\n */\n\nimport type { z } from 'zod'\nimport type { Fetcher, RequestSpec } from '../http/fetcher.js'\nimport { generateIdempotencyKey } from '../idempotency.js'\nimport { AutoPagingIterator, type Page, type PaginationParams } from '../pagination.js'\n\ntype AnySchema = z.ZodTypeAny\ntype Inferred<S extends AnySchema> = z.output<S>\n\nexport interface ResourceContext {\n fetcher: Fetcher\n}\n\nexport interface RequestOptions {\n /** Override or supply the idempotency key for a mutating call. */\n idempotencyKey?: string\n /** Per-request timeout in ms. */\n timeoutMs?: number\n}\n\nexport abstract class BaseResource {\n constructor(protected readonly ctx: ResourceContext) {}\n\n protected async get<S extends AnySchema>(\n path: string,\n schema?: S,\n query?: RequestSpec['query'],\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({ method: 'GET', path, query })\n return parse(data, schema)\n }\n\n protected async post<S extends AnySchema>(\n path: string,\n body: unknown,\n schema?: S,\n options?: RequestOptions,\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({\n method: 'POST',\n path,\n body,\n idempotencyKey: options?.idempotencyKey ?? generateIdempotencyKey(),\n timeoutMs: options?.timeoutMs,\n })\n return parse(data, schema)\n }\n\n protected async patch<S extends AnySchema>(\n path: string,\n body: unknown,\n schema?: S,\n options?: RequestOptions,\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({\n method: 'PATCH',\n path,\n body,\n idempotencyKey: options?.idempotencyKey ?? generateIdempotencyKey(),\n timeoutMs: options?.timeoutMs,\n })\n return parse(data, schema)\n }\n\n protected async delete<S extends AnySchema>(path: string, schema?: S): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({ method: 'DELETE', path })\n return parse(data, schema)\n }\n\n protected listPage<S extends AnySchema>(\n path: string,\n itemSchema: S,\n params?: PaginationParams | Record<string, ScalarParam>,\n ): Promise<Page<Inferred<S>>> {\n return this.ctx.fetcher\n .request<unknown>({ method: 'GET', path, query: toQuery(params) })\n .then((raw) => parsePage(raw, itemSchema))\n }\n\n protected listAuto<S extends AnySchema>(\n path: string,\n itemSchema: S,\n params?: Record<string, ScalarParam>,\n ): AutoPagingIterator<Inferred<S>> {\n return new AutoPagingIterator((cursor) =>\n this.listPage(path, itemSchema, { ...params, cursor }),\n )\n }\n}\n\ntype ScalarParam = string | number | boolean | null | undefined\n\nfunction toQuery(\n params: PaginationParams | Record<string, ScalarParam> | undefined,\n): Record<string, ScalarParam> {\n if (!params) return {}\n return params as Record<string, ScalarParam>\n}\n\nfunction parse<S extends AnySchema>(data: unknown, schema?: S): Inferred<S> {\n return (schema ? schema.parse(data) : data) as Inferred<S>\n}\n\nfunction parsePage<S extends AnySchema>(raw: unknown, itemSchema: S): Page<Inferred<S>> {\n const obj = raw as { data?: unknown[]; nextCursor?: string | null; hasMore?: boolean }\n const items = (obj?.data ?? []).map((d) => itemSchema.parse(d) as Inferred<S>)\n return {\n data: items,\n nextCursor: obj?.nextCursor ?? null,\n hasMore: obj?.hasMore === true,\n }\n}\n","import {\n merchantPublicBrandSchema,\n paymentSessionSchema,\n subscriptionEnrolmentTermsSchema,\n subscriptionPlanSchema,\n subscriptionStatusResultSchema,\n type MerchantPublicBrand,\n type PaymentSession,\n type SubscriptionEnrolmentTerms,\n type SubscriptionPlan,\n type SubscriptionStatusResult,\n} from '@strimz/shared-types'\nimport { BaseResource } from './base-resource.js'\n\n/**\n * Public hosted-checkout reads.\n *\n * Backed by the `/v1/checkout/*` namespace on the Strimz API, which\n * is intentionally unauthenticated. Session and plan records are\n * what a merchant offers to payers, so a payer landing on a checkout\n * URL must be able to load the terms without holding any API key.\n *\n * Use this resource (via `StrimzBrowserClient.checkout`) from the\n * browser. The merchant-scoped `paymentSessions` / `subscriptionPlans`\n * resources on `StrimzClient` remain the right call from server-side\n * code with a secret key.\n */\nexport class CheckoutResource extends BaseResource {\n /** Load a payment session by id (public, no merchant scoping). */\n session(id: string): Promise<PaymentSession> {\n return this.get(`/v1/checkout/sessions/${encodeURIComponent(id)}`, paymentSessionSchema)\n }\n\n /** Load a subscription plan by id (public, no merchant scoping). */\n plan(id: string): Promise<SubscriptionPlan> {\n return this.get(`/v1/checkout/plans/${encodeURIComponent(id)}`, subscriptionPlanSchema)\n }\n\n /** Load the merchant's public brand card by id. */\n merchant(id: string): Promise<MerchantPublicBrand> {\n return this.get(`/v1/checkout/merchants/${encodeURIComponent(id)}`, merchantPublicBrandSchema)\n }\n\n /** Whether a wallet already subscribes to a plan (drives \"already\n * subscribed\" on the enrolment page). */\n subscriptionStatus(planId: string, payer: string): Promise<SubscriptionStatusResult> {\n return this.get(\n `/v1/checkout/plans/${encodeURIComponent(planId)}/subscription?payer=${encodeURIComponent(payer)}`,\n subscriptionStatusResultSchema,\n )\n }\n\n planTerms(planId: string, payer: string): Promise<SubscriptionEnrolmentTerms> {\n return this.get(\n `/v1/checkout/plans/${encodeURIComponent(planId)}/terms?payer=${encodeURIComponent(payer)}`,\n subscriptionEnrolmentTermsSchema,\n )\n }\n}\n","import {\n tokenMetadataSchema,\n tokenPermitNonceSchema,\n type TokenMetadata,\n type TokenPermitNonce,\n} from '@strimz/shared-types'\nimport { BaseResource } from './base-resource.js'\n\n/**\n * Token metadata and capability lookup.\n *\n * The two endpoints are public on the API (no key required). Token\n * metadata is purely chain-derived, has no PII, and is what the\n * browser SDK consults to pick which meta-tx path to take for a\n * given token. Bundled here so consumers don't have to write the HTTP\n * fetch themselves.\n */\nexport class TokensResource extends BaseResource {\n /**\n * Fetch full metadata for a token. Throws via the underlying fetcher\n * (404 maps to `StrimzNotFoundError`) if the token isn't whitelisted.\n */\n retrieve(address: string): Promise<TokenMetadata> {\n return this.get(`/v1/tokens/${encodeURIComponent(address.toLowerCase())}`, tokenMetadataSchema)\n }\n\n /**\n * Read an owner's current EIP-2612 permit nonce. Call this\n * immediately before signing a Permit. The token contract rejects\n * stale nonces, and the value advances on every successful permit.\n */\n permitNonce(address: string, owner: string): Promise<TokenPermitNonce> {\n return this.get(\n `/v1/tokens/${encodeURIComponent(address.toLowerCase())}/permit-nonce`,\n tokenPermitNonceSchema,\n { owner: owner.toLowerCase() },\n )\n }\n}\n\n/**\n * Path selector. Decides which meta-tx flow to take given a token's\n * capabilities and the action a merchant wants to perform.\n *\n * The choice is unambiguous in 99% of cases:\n * - One-shot pay. Prefers EIP-3009. Falls back to approve+pay if the\n * token has neither.\n * - Subscription enrol. Prefers EIP-2612 (the only meta-tx path that\n * grants the recurring allowance subscribers need). If unavailable,\n * the merchant must use the classic approve+create flow.\n *\n * Returned `path` values are strings (not enums) so future schemes\n * can extend the union without breaking existing call sites.\n */\nexport type RelayPath =\n | 'pay_with_authorization'\n | 'permit_and_create_subscription'\n | 'approve_then_pay'\n | 'approve_then_create_subscription'\n\nexport function selectPaymentPath(meta: TokenMetadata): RelayPath {\n return meta.capabilities.transferAuth3009 ? 'pay_with_authorization' : 'approve_then_pay'\n}\n\nexport function selectSubscriptionPath(meta: TokenMetadata): RelayPath {\n return meta.capabilities.permit2612\n ? 'permit_and_create_subscription'\n : 'approve_then_create_subscription'\n}\n","/**\n * StrimzBrowserClient. The publishable-key, browser-safe SDK entry point.\n *\n * Used by `@strimz/sdk-react` and any other browser code that should\n * never see a secret key. Surfaces a strict subset of resource methods,\n * only those safe to call from a browser with a `pk_test_...` or\n * `pk_live_...` key.\n */\n\nimport { kindFromKey, modeFromKey, type ApiKeyMode } from '@strimz/shared-config'\nimport { Fetcher } from './http/fetcher.js'\nimport { buildBaseHeaders } from './http/headers.js'\nimport { StrimzAuthenticationError } from './errors.js'\nimport { CheckoutResource } from './resources/checkout.js'\nimport {\n TokensResource,\n selectPaymentPath,\n selectSubscriptionPath,\n type RelayPath,\n} from './resources/tokens.js'\n\nexport interface StrimzBrowserClientOptions {\n /** Publishable key. Either `pk_test_...` or `pk_live_...`. */\n publishableKey: string\n /** Override the API base URL. */\n baseUrl?: string\n /** Per-request timeout in milliseconds. Default 30s. */\n timeoutMs?: number\n}\n\nconst DEFAULT_BASE_URL = 'https://api.strimz.finance'\n\n/**\n * Browser-safe Strimz client.\n *\n * Designed for hosted-checkout state polling and the React component\n * family. Read-only on most resources. Refuses a secret key.\n *\n * The `tokens` resource and the `selectPaymentPath` /\n * `selectSubscriptionPath` selectors form the capability-detection\n * layer. Given a token, the SDK asks the API which meta-tx flows the\n * token supports, and the selectors map that to a `RelayPath` the\n * checkout UI uses to decide which typed-data to build.\n */\nexport class StrimzBrowserClient {\n public readonly mode: ApiKeyMode\n /**\n * Public hosted-checkout reads. Payment sessions and subscription\n * plans by id. Backed by the `/v1/checkout/*` namespace on the API,\n * which is intentionally unauthenticated.\n */\n public readonly checkout: CheckoutResource\n /** Token metadata and EIP-2612 permit nonce lookup. */\n public readonly tokens: TokensResource\n\n constructor(options: StrimzBrowserClientOptions) {\n const key = options.publishableKey\n if (!key || typeof key !== 'string') {\n throw new StrimzAuthenticationError(\n { code: 'authentication_error', message: 'publishableKey is required' },\n 401,\n )\n }\n if (kindFromKey(key) !== 'publishable') {\n throw new StrimzAuthenticationError(\n {\n code: 'authentication_error',\n message:\n 'StrimzBrowserClient must be initialised with a publishable key (pk_test_... / pk_live_...). Never expose secret keys to a browser.',\n },\n 401,\n )\n }\n const mode = modeFromKey(key)\n if (mode == null) {\n throw new StrimzAuthenticationError(\n { code: 'authentication_error', message: 'Unrecognised API key prefix' },\n 401,\n )\n }\n this.mode = mode\n\n const fetcher = new Fetcher({\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n baseHeaders: buildBaseHeaders(key, 'browser'),\n timeoutMs: options.timeoutMs,\n maxRetries: 2,\n })\n this.checkout = new CheckoutResource({ fetcher })\n this.tokens = new TokensResource({ fetcher })\n }\n}\n\n// Re-export the selectors and path type so consumers don't need a\n// second import: `import { StrimzBrowserClient, selectPaymentPath }\n// from '@strimz/sdk/browser'`.\nexport { selectPaymentPath, selectSubscriptionPath, type RelayPath }\n"]}
@@ -1,4 +1,4 @@
1
1
  import '@strimz/shared-config';
2
- export { c as RelayPath, S as StrimzBrowserClient, b as StrimzBrowserClientOptions, s as selectPaymentPath, d as selectSubscriptionPath } from './browser-client-BrywIX-s.cjs';
2
+ export { c as RelayPath, S as StrimzBrowserClient, b as StrimzBrowserClientOptions, s as selectPaymentPath, d as selectSubscriptionPath } from './browser-client-CklP_z_M.cjs';
3
3
  import '@strimz/shared-types';
4
4
  import 'zod';
@@ -1,4 +1,4 @@
1
1
  import '@strimz/shared-config';
2
- export { c as RelayPath, S as StrimzBrowserClient, b as StrimzBrowserClientOptions, s as selectPaymentPath, d as selectSubscriptionPath } from './browser-client-BrywIX-s.js';
2
+ export { c as RelayPath, S as StrimzBrowserClient, b as StrimzBrowserClientOptions, s as selectPaymentPath, d as selectSubscriptionPath } from './browser-client-CklP_z_M.js';
3
3
  import '@strimz/shared-types';
4
4
  import 'zod';
@@ -1,5 +1,5 @@
1
1
  import { kindFromKey, modeFromKey } from '@strimz/shared-config';
2
- import { paymentSessionSchema, subscriptionPlanSchema, merchantPublicBrandSchema, subscriptionStatusResultSchema, tokenMetadataSchema, tokenPermitNonceSchema } from '@strimz/shared-types';
2
+ import { paymentSessionSchema, subscriptionPlanSchema, merchantPublicBrandSchema, subscriptionStatusResultSchema, subscriptionEnrolmentTermsSchema, tokenMetadataSchema, tokenPermitNonceSchema } from '@strimz/shared-types';
3
3
  import { uuid } from '@strimz/shared-crypto';
4
4
 
5
5
  // src/browser-client.ts
@@ -390,6 +390,12 @@ var CheckoutResource = class extends BaseResource {
390
390
  subscriptionStatusResultSchema
391
391
  );
392
392
  }
393
+ planTerms(planId, payer) {
394
+ return this.get(
395
+ `/v1/checkout/plans/${encodeURIComponent(planId)}/terms?payer=${encodeURIComponent(payer)}`,
396
+ subscriptionEnrolmentTermsSchema
397
+ );
398
+ }
393
399
  };
394
400
  var TokensResource = class extends BaseResource {
395
401
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http/headers.ts","../src/http/fetcher.ts","../src/idempotency.ts","../src/pagination.ts","../src/resources/base-resource.ts","../src/resources/checkout.ts","../src/resources/tokens.ts","../src/browser-client.ts"],"names":[],"mappings":"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","file":"browser-client.js","sourcesContent":["/**\n * Error hierarchy for the Strimz SDK.\n *\n * Every error thrown by the SDK extends `StrimzError`. The SDK throws\n * on failure rather than resolving to `{ ok: false }` so call sites\n * stay linear and consumers can narrow with `instanceof` on the\n * exported subclasses.\n */\n\nexport type StrimzErrorCode =\n | 'authentication_error'\n | 'permission_denied'\n | 'invalid_request'\n | 'not_found'\n | 'idempotency_error'\n | 'rate_limited'\n | 'mode_mismatch'\n | 'merchant_not_found'\n | 'merchant_inactive'\n | 'token_not_whitelisted'\n | 'compliance_blocked'\n | 'session_expired'\n | 'session_invalid_state'\n | 'webhook_signature_invalid'\n | 'api_error'\n | 'network_error'\n | 'timeout'\n | 'parse_error'\n | 'unknown'\n\nexport interface StrimzErrorBody {\n code: StrimzErrorCode\n message: string\n param?: string\n requestId?: string\n details?: Record<string, unknown>\n}\n\nexport class StrimzError extends Error {\n public readonly code: StrimzErrorCode\n public readonly httpStatus: number | undefined\n public readonly requestId: string | undefined\n public readonly param: string | undefined\n public readonly details: Record<string, unknown> | undefined\n\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body.message)\n this.name = 'StrimzError'\n this.code = body.code\n this.httpStatus = httpStatus\n this.requestId = body.requestId\n this.param = body.param\n this.details = body.details\n }\n}\n\nexport class StrimzAuthenticationError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzAuthenticationError'\n }\n}\n\nexport class StrimzPermissionError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzPermissionError'\n }\n}\n\nexport class StrimzValidationError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzValidationError'\n }\n}\n\nexport class StrimzNotFoundError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzNotFoundError'\n }\n}\n\nexport class StrimzIdempotencyError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzIdempotencyError'\n }\n}\n\nexport class StrimzRateLimitError extends StrimzError {\n public readonly retryAfterMs: number | undefined\n constructor(body: StrimzErrorBody, httpStatus?: number, retryAfterMs?: number) {\n super(body, httpStatus)\n this.name = 'StrimzRateLimitError'\n this.retryAfterMs = retryAfterMs\n }\n}\n\nexport class StrimzNetworkError extends StrimzError {\n public override readonly cause: unknown\n constructor(message: string, cause: unknown) {\n super({ code: 'network_error', message })\n this.name = 'StrimzNetworkError'\n this.cause = cause\n }\n}\n\nexport class StrimzTimeoutError extends StrimzError {\n constructor(message: string) {\n super({ code: 'timeout', message })\n this.name = 'StrimzTimeoutError'\n }\n}\n\nexport class StrimzModeMismatchError extends StrimzError {\n constructor(message: string) {\n super({ code: 'mode_mismatch', message })\n this.name = 'StrimzModeMismatchError'\n }\n}\n\n/** Map an HTTP status + body to the right StrimzError subclass. */\nexport function classifyError(\n httpStatus: number,\n body: StrimzErrorBody,\n retryAfterMs?: number,\n): StrimzError {\n if (httpStatus === 401) return new StrimzAuthenticationError(body, httpStatus)\n if (httpStatus === 403) return new StrimzPermissionError(body, httpStatus)\n if (httpStatus === 404) return new StrimzNotFoundError(body, httpStatus)\n if (httpStatus === 409 && body.code === 'idempotency_error') {\n return new StrimzIdempotencyError(body, httpStatus)\n }\n if (httpStatus === 422) return new StrimzValidationError(body, httpStatus)\n if (httpStatus === 429) return new StrimzRateLimitError(body, httpStatus, retryAfterMs)\n return new StrimzError(body, httpStatus)\n}\n","/**\n * Strimz HTTP header conventions.\n *\n * `Authorization: Bearer <secret_key>`: primary auth.\n * `X-Strimz-Idempotency-Key`: mutating calls.\n * `X-Strimz-Sdk`: telemetry.\n * `X-Strimz-Sdk-Version`: telemetry.\n */\n\nexport const HEADERS = {\n authorization: 'Authorization',\n idempotencyKey: 'X-Strimz-Idempotency-Key',\n requestId: 'X-Strimz-Request-Id',\n sdkName: 'X-Strimz-Sdk',\n sdkVersion: 'X-Strimz-Sdk-Version',\n sdkRuntime: 'X-Strimz-Sdk-Runtime',\n} as const\n\nexport const SDK_NAME = '@strimz/sdk'\n\n/** The SDK version. Updated by the build pipeline if a version is published. */\nexport const SDK_VERSION = '0.0.0'\n\nexport function buildBaseHeaders(apiKey: string, runtime: string): Record<string, string> {\n return {\n [HEADERS.authorization]: `Bearer ${apiKey}`,\n [HEADERS.sdkName]: SDK_NAME,\n [HEADERS.sdkVersion]: SDK_VERSION,\n [HEADERS.sdkRuntime]: runtime,\n Accept: 'application/json',\n }\n}\n","/**\n * Fetch wrapper with retry, idempotency, and Strimz error parsing.\n *\n * Retries on:\n * - Network failures (TypeError on fetch).\n * - 5xx responses for idempotent methods (GET, POST with idempotency key).\n * - 429 with Retry-After.\n *\n * Does NOT retry on:\n * - 4xx other than 429 (caller's bug).\n * - 5xx for non-idempotent calls without an idempotency key.\n */\n\nimport {\n classifyError,\n StrimzError,\n StrimzNetworkError,\n StrimzTimeoutError,\n type StrimzErrorBody,\n} from '../errors.js'\nimport { HEADERS } from './headers.js'\n\nexport interface FetcherOptions {\n baseUrl: string\n baseHeaders: Record<string, string>\n /** Default timeout per attempt, milliseconds. */\n timeoutMs?: number\n /** How many retries before giving up. */\n maxRetries?: number\n /** Initial backoff in ms; doubled with jitter on each retry. */\n initialBackoffMs?: number\n /** Optional logger. */\n onRequest?: (info: { method: string; url: string; attempt: number }) => void\n onResponse?: (info: {\n method: string\n url: string\n status: number\n ms: number\n attempt: number\n }) => void\n /** Override the global fetch (for tests or Edge polyfills). */\n fetch?: typeof globalThis.fetch\n}\n\nexport interface RequestSpec {\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE'\n path: string\n query?: Record<string, string | number | boolean | null | undefined>\n body?: unknown\n idempotencyKey?: string\n /** Per-call timeout override. */\n timeoutMs?: number\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000\nconst DEFAULT_MAX_RETRIES = 3\nconst DEFAULT_INITIAL_BACKOFF_MS = 250\n\nexport class Fetcher {\n private readonly baseUrl: string\n private readonly baseHeaders: Record<string, string>\n private readonly timeoutMs: number\n private readonly maxRetries: number\n private readonly initialBackoffMs: number\n private readonly onRequest: FetcherOptions['onRequest']\n private readonly onResponse: FetcherOptions['onResponse']\n private readonly fetchImpl: typeof globalThis.fetch\n\n constructor(opts: FetcherOptions) {\n this.baseUrl = opts.baseUrl.replace(/\\/$/, '')\n this.baseHeaders = opts.baseHeaders\n this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES\n this.initialBackoffMs = opts.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS\n this.onRequest = opts.onRequest\n this.onResponse = opts.onResponse\n this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n async request<T>(spec: RequestSpec): Promise<T> {\n const url = this.buildUrl(spec.path, spec.query)\n const idempotent = isIdempotent(spec)\n const headers: Record<string, string> = { ...this.baseHeaders }\n if (spec.body != null) headers['Content-Type'] = 'application/json'\n if (spec.idempotencyKey) headers[HEADERS.idempotencyKey] = spec.idempotencyKey\n\n let attempt = 0\n let lastErr: unknown\n while (attempt <= this.maxRetries) {\n try {\n this.onRequest?.({ method: spec.method, url, attempt })\n const start = Date.now()\n const res = await this.fetchWithTimeout(\n url,\n {\n method: spec.method,\n headers,\n body: spec.body == null ? undefined : JSON.stringify(spec.body),\n },\n spec.timeoutMs ?? this.timeoutMs,\n )\n const ms = Date.now() - start\n this.onResponse?.({ method: spec.method, url, status: res.status, ms, attempt })\n\n if (res.ok) {\n if (res.status === 204) return undefined as T\n return (await res.json()) as T\n }\n\n const errorBody = await parseErrorBody(res)\n const retryAfterMs = parseRetryAfter(res)\n\n // 429. Back off and retry up to maxRetries.\n if (res.status === 429 && attempt < this.maxRetries) {\n await delay(retryAfterMs ?? this.backoffFor(attempt))\n attempt++\n continue\n }\n // 5xx. Retry only if idempotent.\n if (res.status >= 500 && idempotent && attempt < this.maxRetries) {\n await delay(this.backoffFor(attempt))\n attempt++\n continue\n }\n\n throw classifyError(res.status, errorBody, retryAfterMs)\n } catch (err) {\n if (err instanceof StrimzError) throw err\n lastErr = err\n if (!isNetworkLike(err) || attempt >= this.maxRetries) {\n if (err instanceof StrimzTimeoutError) throw err\n throw new StrimzNetworkError(`Network error: ${describe(err)}`, err)\n }\n await delay(this.backoffFor(attempt))\n attempt++\n }\n }\n throw new StrimzNetworkError(`Network error after ${this.maxRetries} retries`, lastErr)\n }\n\n private async fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n ): Promise<Response> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n return await this.fetchImpl(url, { ...init, signal: controller.signal })\n } catch (err) {\n if (isAbortError(err)) {\n throw new StrimzTimeoutError(`Request timed out after ${timeoutMs}ms`)\n }\n throw err\n } finally {\n clearTimeout(timer)\n }\n }\n\n private buildUrl(path: string, query?: RequestSpec['query']): string {\n const base = `${this.baseUrl}${path.startsWith('/') ? path : `/${path}`}`\n if (!query) return base\n const usp = new URLSearchParams()\n for (const [k, v] of Object.entries(query)) {\n if (v == null) continue\n usp.append(k, String(v))\n }\n const qs = usp.toString()\n return qs ? `${base}?${qs}` : base\n }\n\n private backoffFor(attempt: number): number {\n const expo = this.initialBackoffMs * Math.pow(2, attempt)\n return Math.min(expo + cryptoJitter(this.initialBackoffMs), 8_000)\n }\n}\n\n// Uses crypto so retry timing does not seed off Math.random in\n// environments where that's been monkey-patched.\nfunction cryptoJitter(maxMs: number): number {\n const g = globalThis as { crypto?: { getRandomValues?: (a: Uint32Array) => Uint32Array } }\n if (g.crypto?.getRandomValues) {\n const buf = new Uint32Array(1)\n g.crypto.getRandomValues(buf)\n return ((buf[0] ?? 0) / 0xffff_ffff) * maxMs\n }\n return Math.random() * maxMs\n}\n\nfunction isIdempotent(spec: RequestSpec): boolean {\n if (spec.method === 'GET' || spec.method === 'DELETE') return true\n return spec.idempotencyKey != null\n}\n\nasync function parseErrorBody(res: Response): Promise<StrimzErrorBody> {\n try {\n const json = (await res.json()) as unknown\n const raw =\n typeof json === 'object' && json !== null && 'error' in json\n ? (json as { error: unknown }).error\n : json\n if (typeof raw === 'object' && raw !== null && 'code' in raw && 'message' in raw) {\n return sanitiseErrorBody(raw as Record<string, unknown>)\n }\n } catch {\n // fall through\n }\n return { code: 'api_error', message: `HTTP ${res.status}` }\n}\n\n// Whitelist server-provided fields. A bugged endpoint that dumps stack\n// traces or internal metadata into the error payload never reaches SDK\n// consumers.\nconst ALLOWED_DETAIL_KEYS = new Set(['issues', 'field', 'reason', 'chargeAttemptId'])\n\nfunction sanitiseErrorBody(raw: Record<string, unknown>): StrimzErrorBody {\n const details =\n typeof raw.details === 'object' && raw.details !== null\n ? Object.fromEntries(\n Object.entries(raw.details as Record<string, unknown>).filter(([k]) =>\n ALLOWED_DETAIL_KEYS.has(k),\n ),\n )\n : undefined\n return {\n code: typeof raw.code === 'string' ? (raw.code as StrimzErrorBody['code']) : 'api_error',\n message: typeof raw.message === 'string' ? raw.message : 'Request failed',\n param: typeof raw.param === 'string' ? raw.param : undefined,\n requestId: typeof raw.requestId === 'string' ? raw.requestId : undefined,\n details: details && Object.keys(details).length > 0 ? details : undefined,\n }\n}\n\nfunction parseRetryAfter(res: Response): number | undefined {\n const v = res.headers.get('Retry-After')\n if (!v) return undefined\n const n = Number(v)\n if (Number.isFinite(n)) return Math.max(0, n) * 1_000\n const date = Date.parse(v)\n if (Number.isFinite(date)) return Math.max(0, date - Date.now())\n return undefined\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction isAbortError(err: unknown): boolean {\n return err instanceof Error && err.name === 'AbortError'\n}\n\nfunction isNetworkLike(err: unknown): boolean {\n if (err instanceof TypeError) return true // fetch network failures\n if (err instanceof Error && /fetch|network|econn/i.test(err.message)) return true\n return false\n}\n\nfunction describe(err: unknown): string {\n if (err instanceof Error) return err.message\n return String(err)\n}\n","import { uuid } from '@strimz/shared-crypto'\n\n/**\n * Generate an idempotency key for a mutating SDK call. The key is a\n * UUID with a stable `strimz_` prefix so it stays greppable in logs.\n */\nexport function generateIdempotencyKey(): string {\n return `strimz_${uuid()}`\n}\n\n/** RFC 4122 UUID-shaped, optionally with the strimz_ prefix. */\nconst IDEMPOTENCY_KEY_PATTERN =\n /^(strimz_)?[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/\n\nexport function isValidIdempotencyKey(key: string): boolean {\n if (typeof key !== 'string') return false\n if (key.length > 255) return false\n return IDEMPOTENCY_KEY_PATTERN.test(key)\n}\n","/**\n * Cursor-based pagination, identical shape to the API's list responses.\n */\n\nexport interface Page<T> {\n data: T[]\n nextCursor: string | null\n hasMore: boolean\n}\n\nexport interface PaginationParams {\n limit?: number\n cursor?: string | null\n}\n\n/**\n * Async-iterable wrapper that auto-paginates through every page of a list.\n *\n * for await (const tx of strimz.transactions.listAll()) { ... }\n */\nexport class AutoPagingIterator<T> implements AsyncIterable<T> {\n constructor(private readonly fetchPage: (cursor: string | null) => Promise<Page<T>>) {}\n\n async *[Symbol.asyncIterator](): AsyncIterator<T> {\n let cursor: string | null = null\n let first = true\n while (first || cursor !== null) {\n first = false\n const page: Page<T> = await this.fetchPage(cursor)\n for (const item of page.data) {\n yield item\n }\n cursor = page.hasMore ? page.nextCursor : null\n }\n }\n\n async forEach(handler: (item: T) => void | Promise<void>): Promise<void> {\n for await (const item of this) {\n await handler(item)\n }\n }\n\n async toArray(): Promise<T[]> {\n const out: T[] = []\n for await (const item of this) out.push(item)\n return out\n }\n}\n","/**\n * Base class every resource extends. Centralises endpoint plumbing so\n * resource classes are tiny declarative wrappers.\n */\n\nimport type { z } from 'zod'\nimport type { Fetcher, RequestSpec } from '../http/fetcher.js'\nimport { generateIdempotencyKey } from '../idempotency.js'\nimport { AutoPagingIterator, type Page, type PaginationParams } from '../pagination.js'\n\ntype AnySchema = z.ZodTypeAny\ntype Inferred<S extends AnySchema> = z.output<S>\n\nexport interface ResourceContext {\n fetcher: Fetcher\n}\n\nexport interface RequestOptions {\n /** Override or supply the idempotency key for a mutating call. */\n idempotencyKey?: string\n /** Per-request timeout in ms. */\n timeoutMs?: number\n}\n\nexport abstract class BaseResource {\n constructor(protected readonly ctx: ResourceContext) {}\n\n protected async get<S extends AnySchema>(\n path: string,\n schema?: S,\n query?: RequestSpec['query'],\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({ method: 'GET', path, query })\n return parse(data, schema)\n }\n\n protected async post<S extends AnySchema>(\n path: string,\n body: unknown,\n schema?: S,\n options?: RequestOptions,\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({\n method: 'POST',\n path,\n body,\n idempotencyKey: options?.idempotencyKey ?? generateIdempotencyKey(),\n timeoutMs: options?.timeoutMs,\n })\n return parse(data, schema)\n }\n\n protected async patch<S extends AnySchema>(\n path: string,\n body: unknown,\n schema?: S,\n options?: RequestOptions,\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({\n method: 'PATCH',\n path,\n body,\n idempotencyKey: options?.idempotencyKey ?? generateIdempotencyKey(),\n timeoutMs: options?.timeoutMs,\n })\n return parse(data, schema)\n }\n\n protected async delete<S extends AnySchema>(path: string, schema?: S): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({ method: 'DELETE', path })\n return parse(data, schema)\n }\n\n protected listPage<S extends AnySchema>(\n path: string,\n itemSchema: S,\n params?: PaginationParams | Record<string, ScalarParam>,\n ): Promise<Page<Inferred<S>>> {\n return this.ctx.fetcher\n .request<unknown>({ method: 'GET', path, query: toQuery(params) })\n .then((raw) => parsePage(raw, itemSchema))\n }\n\n protected listAuto<S extends AnySchema>(\n path: string,\n itemSchema: S,\n params?: Record<string, ScalarParam>,\n ): AutoPagingIterator<Inferred<S>> {\n return new AutoPagingIterator((cursor) =>\n this.listPage(path, itemSchema, { ...params, cursor }),\n )\n }\n}\n\ntype ScalarParam = string | number | boolean | null | undefined\n\nfunction toQuery(\n params: PaginationParams | Record<string, ScalarParam> | undefined,\n): Record<string, ScalarParam> {\n if (!params) return {}\n return params as Record<string, ScalarParam>\n}\n\nfunction parse<S extends AnySchema>(data: unknown, schema?: S): Inferred<S> {\n return (schema ? schema.parse(data) : data) as Inferred<S>\n}\n\nfunction parsePage<S extends AnySchema>(raw: unknown, itemSchema: S): Page<Inferred<S>> {\n const obj = raw as { data?: unknown[]; nextCursor?: string | null; hasMore?: boolean }\n const items = (obj?.data ?? []).map((d) => itemSchema.parse(d) as Inferred<S>)\n return {\n data: items,\n nextCursor: obj?.nextCursor ?? null,\n hasMore: obj?.hasMore === true,\n }\n}\n","import {\n merchantPublicBrandSchema,\n paymentSessionSchema,\n subscriptionPlanSchema,\n subscriptionStatusResultSchema,\n type MerchantPublicBrand,\n type PaymentSession,\n type SubscriptionPlan,\n type SubscriptionStatusResult,\n} from '@strimz/shared-types'\nimport { BaseResource } from './base-resource.js'\n\n/**\n * Public hosted-checkout reads.\n *\n * Backed by the `/v1/checkout/*` namespace on the Strimz API, which\n * is intentionally unauthenticated. Session and plan records are\n * what a merchant offers to payers, so a payer landing on a checkout\n * URL must be able to load the terms without holding any API key.\n *\n * Use this resource (via `StrimzBrowserClient.checkout`) from the\n * browser. The merchant-scoped `paymentSessions` / `subscriptionPlans`\n * resources on `StrimzClient` remain the right call from server-side\n * code with a secret key.\n */\nexport class CheckoutResource extends BaseResource {\n /** Load a payment session by id (public, no merchant scoping). */\n session(id: string): Promise<PaymentSession> {\n return this.get(`/v1/checkout/sessions/${encodeURIComponent(id)}`, paymentSessionSchema)\n }\n\n /** Load a subscription plan by id (public, no merchant scoping). */\n plan(id: string): Promise<SubscriptionPlan> {\n return this.get(`/v1/checkout/plans/${encodeURIComponent(id)}`, subscriptionPlanSchema)\n }\n\n /** Load the merchant's public brand card by id. */\n merchant(id: string): Promise<MerchantPublicBrand> {\n return this.get(`/v1/checkout/merchants/${encodeURIComponent(id)}`, merchantPublicBrandSchema)\n }\n\n /** Whether a wallet already subscribes to a plan (drives \"already\n * subscribed\" on the enrolment page). */\n subscriptionStatus(planId: string, payer: string): Promise<SubscriptionStatusResult> {\n return this.get(\n `/v1/checkout/plans/${encodeURIComponent(planId)}/subscription?payer=${encodeURIComponent(payer)}`,\n subscriptionStatusResultSchema,\n )\n }\n}\n","import {\n tokenMetadataSchema,\n tokenPermitNonceSchema,\n type TokenMetadata,\n type TokenPermitNonce,\n} from '@strimz/shared-types'\nimport { BaseResource } from './base-resource.js'\n\n/**\n * Token metadata and capability lookup.\n *\n * The two endpoints are public on the API (no key required). Token\n * metadata is purely chain-derived, has no PII, and is what the\n * browser SDK consults to pick which meta-tx path to take for a\n * given token. Bundled here so consumers don't have to write the HTTP\n * fetch themselves.\n */\nexport class TokensResource extends BaseResource {\n /**\n * Fetch full metadata for a token. Throws via the underlying fetcher\n * (404 maps to `StrimzNotFoundError`) if the token isn't whitelisted.\n */\n retrieve(address: string): Promise<TokenMetadata> {\n return this.get(`/v1/tokens/${encodeURIComponent(address.toLowerCase())}`, tokenMetadataSchema)\n }\n\n /**\n * Read an owner's current EIP-2612 permit nonce. Call this\n * immediately before signing a Permit. The token contract rejects\n * stale nonces, and the value advances on every successful permit.\n */\n permitNonce(address: string, owner: string): Promise<TokenPermitNonce> {\n return this.get(\n `/v1/tokens/${encodeURIComponent(address.toLowerCase())}/permit-nonce`,\n tokenPermitNonceSchema,\n { owner: owner.toLowerCase() },\n )\n }\n}\n\n/**\n * Path selector. Decides which meta-tx flow to take given a token's\n * capabilities and the action a merchant wants to perform.\n *\n * The choice is unambiguous in 99% of cases:\n * - One-shot pay. Prefers EIP-3009. Falls back to approve+pay if the\n * token has neither.\n * - Subscription enrol. Prefers EIP-2612 (the only meta-tx path that\n * grants the recurring allowance subscribers need). If unavailable,\n * the merchant must use the classic approve+create flow.\n *\n * Returned `path` values are strings (not enums) so future schemes\n * can extend the union without breaking existing call sites.\n */\nexport type RelayPath =\n | 'pay_with_authorization'\n | 'permit_and_create_subscription'\n | 'approve_then_pay'\n | 'approve_then_create_subscription'\n\nexport function selectPaymentPath(meta: TokenMetadata): RelayPath {\n return meta.capabilities.transferAuth3009 ? 'pay_with_authorization' : 'approve_then_pay'\n}\n\nexport function selectSubscriptionPath(meta: TokenMetadata): RelayPath {\n return meta.capabilities.permit2612\n ? 'permit_and_create_subscription'\n : 'approve_then_create_subscription'\n}\n","/**\n * StrimzBrowserClient. The publishable-key, browser-safe SDK entry point.\n *\n * Used by `@strimz/sdk-react` and any other browser code that should\n * never see a secret key. Surfaces a strict subset of resource methods,\n * only those safe to call from a browser with a `pk_test_...` or\n * `pk_live_...` key.\n */\n\nimport { kindFromKey, modeFromKey, type ApiKeyMode } from '@strimz/shared-config'\nimport { Fetcher } from './http/fetcher.js'\nimport { buildBaseHeaders } from './http/headers.js'\nimport { StrimzAuthenticationError } from './errors.js'\nimport { CheckoutResource } from './resources/checkout.js'\nimport {\n TokensResource,\n selectPaymentPath,\n selectSubscriptionPath,\n type RelayPath,\n} from './resources/tokens.js'\n\nexport interface StrimzBrowserClientOptions {\n /** Publishable key. Either `pk_test_...` or `pk_live_...`. */\n publishableKey: string\n /** Override the API base URL. */\n baseUrl?: string\n /** Per-request timeout in milliseconds. Default 30s. */\n timeoutMs?: number\n}\n\nconst DEFAULT_BASE_URL = 'https://api.strimz.finance'\n\n/**\n * Browser-safe Strimz client.\n *\n * Designed for hosted-checkout state polling and the React component\n * family. Read-only on most resources. Refuses a secret key.\n *\n * The `tokens` resource and the `selectPaymentPath` /\n * `selectSubscriptionPath` selectors form the capability-detection\n * layer. Given a token, the SDK asks the API which meta-tx flows the\n * token supports, and the selectors map that to a `RelayPath` the\n * checkout UI uses to decide which typed-data to build.\n */\nexport class StrimzBrowserClient {\n public readonly mode: ApiKeyMode\n /**\n * Public hosted-checkout reads. Payment sessions and subscription\n * plans by id. Backed by the `/v1/checkout/*` namespace on the API,\n * which is intentionally unauthenticated.\n */\n public readonly checkout: CheckoutResource\n /** Token metadata and EIP-2612 permit nonce lookup. */\n public readonly tokens: TokensResource\n\n constructor(options: StrimzBrowserClientOptions) {\n const key = options.publishableKey\n if (!key || typeof key !== 'string') {\n throw new StrimzAuthenticationError(\n { code: 'authentication_error', message: 'publishableKey is required' },\n 401,\n )\n }\n if (kindFromKey(key) !== 'publishable') {\n throw new StrimzAuthenticationError(\n {\n code: 'authentication_error',\n message:\n 'StrimzBrowserClient must be initialised with a publishable key (pk_test_... / pk_live_...). Never expose secret keys to a browser.',\n },\n 401,\n )\n }\n const mode = modeFromKey(key)\n if (mode == null) {\n throw new StrimzAuthenticationError(\n { code: 'authentication_error', message: 'Unrecognised API key prefix' },\n 401,\n )\n }\n this.mode = mode\n\n const fetcher = new Fetcher({\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n baseHeaders: buildBaseHeaders(key, 'browser'),\n timeoutMs: options.timeoutMs,\n maxRetries: 2,\n })\n this.checkout = new CheckoutResource({ fetcher })\n this.tokens = new TokensResource({ fetcher })\n }\n}\n\n// Re-export the selectors and path type so consumers don't need a\n// second import: `import { StrimzBrowserClient, selectPaymentPath }\n// from '@strimz/sdk/browser'`.\nexport { selectPaymentPath, selectSubscriptionPath, type RelayPath }\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/http/headers.ts","../src/http/fetcher.ts","../src/idempotency.ts","../src/pagination.ts","../src/resources/base-resource.ts","../src/resources/checkout.ts","../src/resources/tokens.ts","../src/browser-client.ts"],"names":[],"mappings":"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","file":"browser-client.js","sourcesContent":["/**\n * Error hierarchy for the Strimz SDK.\n *\n * Every error thrown by the SDK extends `StrimzError`. The SDK throws\n * on failure rather than resolving to `{ ok: false }` so call sites\n * stay linear and consumers can narrow with `instanceof` on the\n * exported subclasses.\n */\n\nexport type StrimzErrorCode =\n | 'authentication_error'\n | 'permission_denied'\n | 'invalid_request'\n | 'not_found'\n | 'idempotency_error'\n | 'rate_limited'\n | 'mode_mismatch'\n | 'merchant_not_found'\n | 'merchant_inactive'\n | 'token_not_whitelisted'\n | 'compliance_blocked'\n | 'session_expired'\n | 'session_invalid_state'\n | 'webhook_signature_invalid'\n | 'api_error'\n | 'network_error'\n | 'timeout'\n | 'parse_error'\n | 'unknown'\n\nexport interface StrimzErrorBody {\n code: StrimzErrorCode\n message: string\n param?: string\n requestId?: string\n details?: Record<string, unknown>\n}\n\nexport class StrimzError extends Error {\n public readonly code: StrimzErrorCode\n public readonly httpStatus: number | undefined\n public readonly requestId: string | undefined\n public readonly param: string | undefined\n public readonly details: Record<string, unknown> | undefined\n\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body.message)\n this.name = 'StrimzError'\n this.code = body.code\n this.httpStatus = httpStatus\n this.requestId = body.requestId\n this.param = body.param\n this.details = body.details\n }\n}\n\nexport class StrimzAuthenticationError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzAuthenticationError'\n }\n}\n\nexport class StrimzPermissionError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzPermissionError'\n }\n}\n\nexport class StrimzValidationError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzValidationError'\n }\n}\n\nexport class StrimzNotFoundError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzNotFoundError'\n }\n}\n\nexport class StrimzIdempotencyError extends StrimzError {\n constructor(body: StrimzErrorBody, httpStatus?: number) {\n super(body, httpStatus)\n this.name = 'StrimzIdempotencyError'\n }\n}\n\nexport class StrimzRateLimitError extends StrimzError {\n public readonly retryAfterMs: number | undefined\n constructor(body: StrimzErrorBody, httpStatus?: number, retryAfterMs?: number) {\n super(body, httpStatus)\n this.name = 'StrimzRateLimitError'\n this.retryAfterMs = retryAfterMs\n }\n}\n\nexport class StrimzNetworkError extends StrimzError {\n public override readonly cause: unknown\n constructor(message: string, cause: unknown) {\n super({ code: 'network_error', message })\n this.name = 'StrimzNetworkError'\n this.cause = cause\n }\n}\n\nexport class StrimzTimeoutError extends StrimzError {\n constructor(message: string) {\n super({ code: 'timeout', message })\n this.name = 'StrimzTimeoutError'\n }\n}\n\nexport class StrimzModeMismatchError extends StrimzError {\n constructor(message: string) {\n super({ code: 'mode_mismatch', message })\n this.name = 'StrimzModeMismatchError'\n }\n}\n\n/** Map an HTTP status + body to the right StrimzError subclass. */\nexport function classifyError(\n httpStatus: number,\n body: StrimzErrorBody,\n retryAfterMs?: number,\n): StrimzError {\n if (httpStatus === 401) return new StrimzAuthenticationError(body, httpStatus)\n if (httpStatus === 403) return new StrimzPermissionError(body, httpStatus)\n if (httpStatus === 404) return new StrimzNotFoundError(body, httpStatus)\n if (httpStatus === 409 && body.code === 'idempotency_error') {\n return new StrimzIdempotencyError(body, httpStatus)\n }\n if (httpStatus === 422) return new StrimzValidationError(body, httpStatus)\n if (httpStatus === 429) return new StrimzRateLimitError(body, httpStatus, retryAfterMs)\n return new StrimzError(body, httpStatus)\n}\n","/**\n * Strimz HTTP header conventions.\n *\n * `Authorization: Bearer <secret_key>`: primary auth.\n * `X-Strimz-Idempotency-Key`: mutating calls.\n * `X-Strimz-Sdk`: telemetry.\n * `X-Strimz-Sdk-Version`: telemetry.\n */\n\nexport const HEADERS = {\n authorization: 'Authorization',\n idempotencyKey: 'X-Strimz-Idempotency-Key',\n requestId: 'X-Strimz-Request-Id',\n sdkName: 'X-Strimz-Sdk',\n sdkVersion: 'X-Strimz-Sdk-Version',\n sdkRuntime: 'X-Strimz-Sdk-Runtime',\n} as const\n\nexport const SDK_NAME = '@strimz/sdk'\n\n/** The SDK version. Updated by the build pipeline if a version is published. */\nexport const SDK_VERSION = '0.0.0'\n\nexport function buildBaseHeaders(apiKey: string, runtime: string): Record<string, string> {\n return {\n [HEADERS.authorization]: `Bearer ${apiKey}`,\n [HEADERS.sdkName]: SDK_NAME,\n [HEADERS.sdkVersion]: SDK_VERSION,\n [HEADERS.sdkRuntime]: runtime,\n Accept: 'application/json',\n }\n}\n","/**\n * Fetch wrapper with retry, idempotency, and Strimz error parsing.\n *\n * Retries on:\n * - Network failures (TypeError on fetch).\n * - 5xx responses for idempotent methods (GET, POST with idempotency key).\n * - 429 with Retry-After.\n *\n * Does NOT retry on:\n * - 4xx other than 429 (caller's bug).\n * - 5xx for non-idempotent calls without an idempotency key.\n */\n\nimport {\n classifyError,\n StrimzError,\n StrimzNetworkError,\n StrimzTimeoutError,\n type StrimzErrorBody,\n} from '../errors.js'\nimport { HEADERS } from './headers.js'\n\nexport interface FetcherOptions {\n baseUrl: string\n baseHeaders: Record<string, string>\n /** Default timeout per attempt, milliseconds. */\n timeoutMs?: number\n /** How many retries before giving up. */\n maxRetries?: number\n /** Initial backoff in ms; doubled with jitter on each retry. */\n initialBackoffMs?: number\n /** Optional logger. */\n onRequest?: (info: { method: string; url: string; attempt: number }) => void\n onResponse?: (info: {\n method: string\n url: string\n status: number\n ms: number\n attempt: number\n }) => void\n /** Override the global fetch (for tests or Edge polyfills). */\n fetch?: typeof globalThis.fetch\n}\n\nexport interface RequestSpec {\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE'\n path: string\n query?: Record<string, string | number | boolean | null | undefined>\n body?: unknown\n idempotencyKey?: string\n /** Per-call timeout override. */\n timeoutMs?: number\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000\nconst DEFAULT_MAX_RETRIES = 3\nconst DEFAULT_INITIAL_BACKOFF_MS = 250\n\nexport class Fetcher {\n private readonly baseUrl: string\n private readonly baseHeaders: Record<string, string>\n private readonly timeoutMs: number\n private readonly maxRetries: number\n private readonly initialBackoffMs: number\n private readonly onRequest: FetcherOptions['onRequest']\n private readonly onResponse: FetcherOptions['onResponse']\n private readonly fetchImpl: typeof globalThis.fetch\n\n constructor(opts: FetcherOptions) {\n this.baseUrl = opts.baseUrl.replace(/\\/$/, '')\n this.baseHeaders = opts.baseHeaders\n this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES\n this.initialBackoffMs = opts.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS\n this.onRequest = opts.onRequest\n this.onResponse = opts.onResponse\n this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n async request<T>(spec: RequestSpec): Promise<T> {\n const url = this.buildUrl(spec.path, spec.query)\n const idempotent = isIdempotent(spec)\n const headers: Record<string, string> = { ...this.baseHeaders }\n if (spec.body != null) headers['Content-Type'] = 'application/json'\n if (spec.idempotencyKey) headers[HEADERS.idempotencyKey] = spec.idempotencyKey\n\n let attempt = 0\n let lastErr: unknown\n while (attempt <= this.maxRetries) {\n try {\n this.onRequest?.({ method: spec.method, url, attempt })\n const start = Date.now()\n const res = await this.fetchWithTimeout(\n url,\n {\n method: spec.method,\n headers,\n body: spec.body == null ? undefined : JSON.stringify(spec.body),\n },\n spec.timeoutMs ?? this.timeoutMs,\n )\n const ms = Date.now() - start\n this.onResponse?.({ method: spec.method, url, status: res.status, ms, attempt })\n\n if (res.ok) {\n if (res.status === 204) return undefined as T\n return (await res.json()) as T\n }\n\n const errorBody = await parseErrorBody(res)\n const retryAfterMs = parseRetryAfter(res)\n\n // 429. Back off and retry up to maxRetries.\n if (res.status === 429 && attempt < this.maxRetries) {\n await delay(retryAfterMs ?? this.backoffFor(attempt))\n attempt++\n continue\n }\n // 5xx. Retry only if idempotent.\n if (res.status >= 500 && idempotent && attempt < this.maxRetries) {\n await delay(this.backoffFor(attempt))\n attempt++\n continue\n }\n\n throw classifyError(res.status, errorBody, retryAfterMs)\n } catch (err) {\n if (err instanceof StrimzError) throw err\n lastErr = err\n if (!isNetworkLike(err) || attempt >= this.maxRetries) {\n if (err instanceof StrimzTimeoutError) throw err\n throw new StrimzNetworkError(`Network error: ${describe(err)}`, err)\n }\n await delay(this.backoffFor(attempt))\n attempt++\n }\n }\n throw new StrimzNetworkError(`Network error after ${this.maxRetries} retries`, lastErr)\n }\n\n private async fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n ): Promise<Response> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n return await this.fetchImpl(url, { ...init, signal: controller.signal })\n } catch (err) {\n if (isAbortError(err)) {\n throw new StrimzTimeoutError(`Request timed out after ${timeoutMs}ms`)\n }\n throw err\n } finally {\n clearTimeout(timer)\n }\n }\n\n private buildUrl(path: string, query?: RequestSpec['query']): string {\n const base = `${this.baseUrl}${path.startsWith('/') ? path : `/${path}`}`\n if (!query) return base\n const usp = new URLSearchParams()\n for (const [k, v] of Object.entries(query)) {\n if (v == null) continue\n usp.append(k, String(v))\n }\n const qs = usp.toString()\n return qs ? `${base}?${qs}` : base\n }\n\n private backoffFor(attempt: number): number {\n const expo = this.initialBackoffMs * Math.pow(2, attempt)\n return Math.min(expo + cryptoJitter(this.initialBackoffMs), 8_000)\n }\n}\n\n// Uses crypto so retry timing does not seed off Math.random in\n// environments where that's been monkey-patched.\nfunction cryptoJitter(maxMs: number): number {\n const g = globalThis as { crypto?: { getRandomValues?: (a: Uint32Array) => Uint32Array } }\n if (g.crypto?.getRandomValues) {\n const buf = new Uint32Array(1)\n g.crypto.getRandomValues(buf)\n return ((buf[0] ?? 0) / 0xffff_ffff) * maxMs\n }\n return Math.random() * maxMs\n}\n\nfunction isIdempotent(spec: RequestSpec): boolean {\n if (spec.method === 'GET' || spec.method === 'DELETE') return true\n return spec.idempotencyKey != null\n}\n\nasync function parseErrorBody(res: Response): Promise<StrimzErrorBody> {\n try {\n const json = (await res.json()) as unknown\n const raw =\n typeof json === 'object' && json !== null && 'error' in json\n ? (json as { error: unknown }).error\n : json\n if (typeof raw === 'object' && raw !== null && 'code' in raw && 'message' in raw) {\n return sanitiseErrorBody(raw as Record<string, unknown>)\n }\n } catch {\n // fall through\n }\n return { code: 'api_error', message: `HTTP ${res.status}` }\n}\n\n// Whitelist server-provided fields. A bugged endpoint that dumps stack\n// traces or internal metadata into the error payload never reaches SDK\n// consumers.\nconst ALLOWED_DETAIL_KEYS = new Set(['issues', 'field', 'reason', 'chargeAttemptId'])\n\nfunction sanitiseErrorBody(raw: Record<string, unknown>): StrimzErrorBody {\n const details =\n typeof raw.details === 'object' && raw.details !== null\n ? Object.fromEntries(\n Object.entries(raw.details as Record<string, unknown>).filter(([k]) =>\n ALLOWED_DETAIL_KEYS.has(k),\n ),\n )\n : undefined\n return {\n code: typeof raw.code === 'string' ? (raw.code as StrimzErrorBody['code']) : 'api_error',\n message: typeof raw.message === 'string' ? raw.message : 'Request failed',\n param: typeof raw.param === 'string' ? raw.param : undefined,\n requestId: typeof raw.requestId === 'string' ? raw.requestId : undefined,\n details: details && Object.keys(details).length > 0 ? details : undefined,\n }\n}\n\nfunction parseRetryAfter(res: Response): number | undefined {\n const v = res.headers.get('Retry-After')\n if (!v) return undefined\n const n = Number(v)\n if (Number.isFinite(n)) return Math.max(0, n) * 1_000\n const date = Date.parse(v)\n if (Number.isFinite(date)) return Math.max(0, date - Date.now())\n return undefined\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction isAbortError(err: unknown): boolean {\n return err instanceof Error && err.name === 'AbortError'\n}\n\nfunction isNetworkLike(err: unknown): boolean {\n if (err instanceof TypeError) return true // fetch network failures\n if (err instanceof Error && /fetch|network|econn/i.test(err.message)) return true\n return false\n}\n\nfunction describe(err: unknown): string {\n if (err instanceof Error) return err.message\n return String(err)\n}\n","import { uuid } from '@strimz/shared-crypto'\n\n/**\n * Generate an idempotency key for a mutating SDK call. The key is a\n * UUID with a stable `strimz_` prefix so it stays greppable in logs.\n */\nexport function generateIdempotencyKey(): string {\n return `strimz_${uuid()}`\n}\n\n/** RFC 4122 UUID-shaped, optionally with the strimz_ prefix. */\nconst IDEMPOTENCY_KEY_PATTERN =\n /^(strimz_)?[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/\n\nexport function isValidIdempotencyKey(key: string): boolean {\n if (typeof key !== 'string') return false\n if (key.length > 255) return false\n return IDEMPOTENCY_KEY_PATTERN.test(key)\n}\n","/**\n * Cursor-based pagination, identical shape to the API's list responses.\n */\n\nexport interface Page<T> {\n data: T[]\n nextCursor: string | null\n hasMore: boolean\n}\n\nexport interface PaginationParams {\n limit?: number\n cursor?: string | null\n}\n\n/**\n * Async-iterable wrapper that auto-paginates through every page of a list.\n *\n * for await (const tx of strimz.transactions.listAll()) { ... }\n */\nexport class AutoPagingIterator<T> implements AsyncIterable<T> {\n constructor(private readonly fetchPage: (cursor: string | null) => Promise<Page<T>>) {}\n\n async *[Symbol.asyncIterator](): AsyncIterator<T> {\n let cursor: string | null = null\n let first = true\n while (first || cursor !== null) {\n first = false\n const page: Page<T> = await this.fetchPage(cursor)\n for (const item of page.data) {\n yield item\n }\n cursor = page.hasMore ? page.nextCursor : null\n }\n }\n\n async forEach(handler: (item: T) => void | Promise<void>): Promise<void> {\n for await (const item of this) {\n await handler(item)\n }\n }\n\n async toArray(): Promise<T[]> {\n const out: T[] = []\n for await (const item of this) out.push(item)\n return out\n }\n}\n","/**\n * Base class every resource extends. Centralises endpoint plumbing so\n * resource classes are tiny declarative wrappers.\n */\n\nimport type { z } from 'zod'\nimport type { Fetcher, RequestSpec } from '../http/fetcher.js'\nimport { generateIdempotencyKey } from '../idempotency.js'\nimport { AutoPagingIterator, type Page, type PaginationParams } from '../pagination.js'\n\ntype AnySchema = z.ZodTypeAny\ntype Inferred<S extends AnySchema> = z.output<S>\n\nexport interface ResourceContext {\n fetcher: Fetcher\n}\n\nexport interface RequestOptions {\n /** Override or supply the idempotency key for a mutating call. */\n idempotencyKey?: string\n /** Per-request timeout in ms. */\n timeoutMs?: number\n}\n\nexport abstract class BaseResource {\n constructor(protected readonly ctx: ResourceContext) {}\n\n protected async get<S extends AnySchema>(\n path: string,\n schema?: S,\n query?: RequestSpec['query'],\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({ method: 'GET', path, query })\n return parse(data, schema)\n }\n\n protected async post<S extends AnySchema>(\n path: string,\n body: unknown,\n schema?: S,\n options?: RequestOptions,\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({\n method: 'POST',\n path,\n body,\n idempotencyKey: options?.idempotencyKey ?? generateIdempotencyKey(),\n timeoutMs: options?.timeoutMs,\n })\n return parse(data, schema)\n }\n\n protected async patch<S extends AnySchema>(\n path: string,\n body: unknown,\n schema?: S,\n options?: RequestOptions,\n ): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({\n method: 'PATCH',\n path,\n body,\n idempotencyKey: options?.idempotencyKey ?? generateIdempotencyKey(),\n timeoutMs: options?.timeoutMs,\n })\n return parse(data, schema)\n }\n\n protected async delete<S extends AnySchema>(path: string, schema?: S): Promise<Inferred<S>> {\n const data = await this.ctx.fetcher.request<unknown>({ method: 'DELETE', path })\n return parse(data, schema)\n }\n\n protected listPage<S extends AnySchema>(\n path: string,\n itemSchema: S,\n params?: PaginationParams | Record<string, ScalarParam>,\n ): Promise<Page<Inferred<S>>> {\n return this.ctx.fetcher\n .request<unknown>({ method: 'GET', path, query: toQuery(params) })\n .then((raw) => parsePage(raw, itemSchema))\n }\n\n protected listAuto<S extends AnySchema>(\n path: string,\n itemSchema: S,\n params?: Record<string, ScalarParam>,\n ): AutoPagingIterator<Inferred<S>> {\n return new AutoPagingIterator((cursor) =>\n this.listPage(path, itemSchema, { ...params, cursor }),\n )\n }\n}\n\ntype ScalarParam = string | number | boolean | null | undefined\n\nfunction toQuery(\n params: PaginationParams | Record<string, ScalarParam> | undefined,\n): Record<string, ScalarParam> {\n if (!params) return {}\n return params as Record<string, ScalarParam>\n}\n\nfunction parse<S extends AnySchema>(data: unknown, schema?: S): Inferred<S> {\n return (schema ? schema.parse(data) : data) as Inferred<S>\n}\n\nfunction parsePage<S extends AnySchema>(raw: unknown, itemSchema: S): Page<Inferred<S>> {\n const obj = raw as { data?: unknown[]; nextCursor?: string | null; hasMore?: boolean }\n const items = (obj?.data ?? []).map((d) => itemSchema.parse(d) as Inferred<S>)\n return {\n data: items,\n nextCursor: obj?.nextCursor ?? null,\n hasMore: obj?.hasMore === true,\n }\n}\n","import {\n merchantPublicBrandSchema,\n paymentSessionSchema,\n subscriptionEnrolmentTermsSchema,\n subscriptionPlanSchema,\n subscriptionStatusResultSchema,\n type MerchantPublicBrand,\n type PaymentSession,\n type SubscriptionEnrolmentTerms,\n type SubscriptionPlan,\n type SubscriptionStatusResult,\n} from '@strimz/shared-types'\nimport { BaseResource } from './base-resource.js'\n\n/**\n * Public hosted-checkout reads.\n *\n * Backed by the `/v1/checkout/*` namespace on the Strimz API, which\n * is intentionally unauthenticated. Session and plan records are\n * what a merchant offers to payers, so a payer landing on a checkout\n * URL must be able to load the terms without holding any API key.\n *\n * Use this resource (via `StrimzBrowserClient.checkout`) from the\n * browser. The merchant-scoped `paymentSessions` / `subscriptionPlans`\n * resources on `StrimzClient` remain the right call from server-side\n * code with a secret key.\n */\nexport class CheckoutResource extends BaseResource {\n /** Load a payment session by id (public, no merchant scoping). */\n session(id: string): Promise<PaymentSession> {\n return this.get(`/v1/checkout/sessions/${encodeURIComponent(id)}`, paymentSessionSchema)\n }\n\n /** Load a subscription plan by id (public, no merchant scoping). */\n plan(id: string): Promise<SubscriptionPlan> {\n return this.get(`/v1/checkout/plans/${encodeURIComponent(id)}`, subscriptionPlanSchema)\n }\n\n /** Load the merchant's public brand card by id. */\n merchant(id: string): Promise<MerchantPublicBrand> {\n return this.get(`/v1/checkout/merchants/${encodeURIComponent(id)}`, merchantPublicBrandSchema)\n }\n\n /** Whether a wallet already subscribes to a plan (drives \"already\n * subscribed\" on the enrolment page). */\n subscriptionStatus(planId: string, payer: string): Promise<SubscriptionStatusResult> {\n return this.get(\n `/v1/checkout/plans/${encodeURIComponent(planId)}/subscription?payer=${encodeURIComponent(payer)}`,\n subscriptionStatusResultSchema,\n )\n }\n\n planTerms(planId: string, payer: string): Promise<SubscriptionEnrolmentTerms> {\n return this.get(\n `/v1/checkout/plans/${encodeURIComponent(planId)}/terms?payer=${encodeURIComponent(payer)}`,\n subscriptionEnrolmentTermsSchema,\n )\n }\n}\n","import {\n tokenMetadataSchema,\n tokenPermitNonceSchema,\n type TokenMetadata,\n type TokenPermitNonce,\n} from '@strimz/shared-types'\nimport { BaseResource } from './base-resource.js'\n\n/**\n * Token metadata and capability lookup.\n *\n * The two endpoints are public on the API (no key required). Token\n * metadata is purely chain-derived, has no PII, and is what the\n * browser SDK consults to pick which meta-tx path to take for a\n * given token. Bundled here so consumers don't have to write the HTTP\n * fetch themselves.\n */\nexport class TokensResource extends BaseResource {\n /**\n * Fetch full metadata for a token. Throws via the underlying fetcher\n * (404 maps to `StrimzNotFoundError`) if the token isn't whitelisted.\n */\n retrieve(address: string): Promise<TokenMetadata> {\n return this.get(`/v1/tokens/${encodeURIComponent(address.toLowerCase())}`, tokenMetadataSchema)\n }\n\n /**\n * Read an owner's current EIP-2612 permit nonce. Call this\n * immediately before signing a Permit. The token contract rejects\n * stale nonces, and the value advances on every successful permit.\n */\n permitNonce(address: string, owner: string): Promise<TokenPermitNonce> {\n return this.get(\n `/v1/tokens/${encodeURIComponent(address.toLowerCase())}/permit-nonce`,\n tokenPermitNonceSchema,\n { owner: owner.toLowerCase() },\n )\n }\n}\n\n/**\n * Path selector. Decides which meta-tx flow to take given a token's\n * capabilities and the action a merchant wants to perform.\n *\n * The choice is unambiguous in 99% of cases:\n * - One-shot pay. Prefers EIP-3009. Falls back to approve+pay if the\n * token has neither.\n * - Subscription enrol. Prefers EIP-2612 (the only meta-tx path that\n * grants the recurring allowance subscribers need). If unavailable,\n * the merchant must use the classic approve+create flow.\n *\n * Returned `path` values are strings (not enums) so future schemes\n * can extend the union without breaking existing call sites.\n */\nexport type RelayPath =\n | 'pay_with_authorization'\n | 'permit_and_create_subscription'\n | 'approve_then_pay'\n | 'approve_then_create_subscription'\n\nexport function selectPaymentPath(meta: TokenMetadata): RelayPath {\n return meta.capabilities.transferAuth3009 ? 'pay_with_authorization' : 'approve_then_pay'\n}\n\nexport function selectSubscriptionPath(meta: TokenMetadata): RelayPath {\n return meta.capabilities.permit2612\n ? 'permit_and_create_subscription'\n : 'approve_then_create_subscription'\n}\n","/**\n * StrimzBrowserClient. The publishable-key, browser-safe SDK entry point.\n *\n * Used by `@strimz/sdk-react` and any other browser code that should\n * never see a secret key. Surfaces a strict subset of resource methods,\n * only those safe to call from a browser with a `pk_test_...` or\n * `pk_live_...` key.\n */\n\nimport { kindFromKey, modeFromKey, type ApiKeyMode } from '@strimz/shared-config'\nimport { Fetcher } from './http/fetcher.js'\nimport { buildBaseHeaders } from './http/headers.js'\nimport { StrimzAuthenticationError } from './errors.js'\nimport { CheckoutResource } from './resources/checkout.js'\nimport {\n TokensResource,\n selectPaymentPath,\n selectSubscriptionPath,\n type RelayPath,\n} from './resources/tokens.js'\n\nexport interface StrimzBrowserClientOptions {\n /** Publishable key. Either `pk_test_...` or `pk_live_...`. */\n publishableKey: string\n /** Override the API base URL. */\n baseUrl?: string\n /** Per-request timeout in milliseconds. Default 30s. */\n timeoutMs?: number\n}\n\nconst DEFAULT_BASE_URL = 'https://api.strimz.finance'\n\n/**\n * Browser-safe Strimz client.\n *\n * Designed for hosted-checkout state polling and the React component\n * family. Read-only on most resources. Refuses a secret key.\n *\n * The `tokens` resource and the `selectPaymentPath` /\n * `selectSubscriptionPath` selectors form the capability-detection\n * layer. Given a token, the SDK asks the API which meta-tx flows the\n * token supports, and the selectors map that to a `RelayPath` the\n * checkout UI uses to decide which typed-data to build.\n */\nexport class StrimzBrowserClient {\n public readonly mode: ApiKeyMode\n /**\n * Public hosted-checkout reads. Payment sessions and subscription\n * plans by id. Backed by the `/v1/checkout/*` namespace on the API,\n * which is intentionally unauthenticated.\n */\n public readonly checkout: CheckoutResource\n /** Token metadata and EIP-2612 permit nonce lookup. */\n public readonly tokens: TokensResource\n\n constructor(options: StrimzBrowserClientOptions) {\n const key = options.publishableKey\n if (!key || typeof key !== 'string') {\n throw new StrimzAuthenticationError(\n { code: 'authentication_error', message: 'publishableKey is required' },\n 401,\n )\n }\n if (kindFromKey(key) !== 'publishable') {\n throw new StrimzAuthenticationError(\n {\n code: 'authentication_error',\n message:\n 'StrimzBrowserClient must be initialised with a publishable key (pk_test_... / pk_live_...). Never expose secret keys to a browser.',\n },\n 401,\n )\n }\n const mode = modeFromKey(key)\n if (mode == null) {\n throw new StrimzAuthenticationError(\n { code: 'authentication_error', message: 'Unrecognised API key prefix' },\n 401,\n )\n }\n this.mode = mode\n\n const fetcher = new Fetcher({\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n baseHeaders: buildBaseHeaders(key, 'browser'),\n timeoutMs: options.timeoutMs,\n maxRetries: 2,\n })\n this.checkout = new CheckoutResource({ fetcher })\n this.tokens = new TokensResource({ fetcher })\n }\n}\n\n// Re-export the selectors and path type so consumers don't need a\n// second import: `import { StrimzBrowserClient, selectPaymentPath }\n// from '@strimz/sdk/browser'`.\nexport { selectPaymentPath, selectSubscriptionPath, type RelayPath }\n"]}
package/dist/index.cjs CHANGED
@@ -761,6 +761,12 @@ var CheckoutResource = class extends BaseResource {
761
761
  sharedTypes.subscriptionStatusResultSchema
762
762
  );
763
763
  }
764
+ planTerms(planId, payer) {
765
+ return this.get(
766
+ `/v1/checkout/plans/${encodeURIComponent(planId)}/terms?payer=${encodeURIComponent(payer)}`,
767
+ sharedTypes.subscriptionEnrolmentTermsSchema
768
+ );
769
+ }
764
770
  };
765
771
  var TokensResource = class extends BaseResource {
766
772
  /**