@getsupertab/supertab-connect-sdk 0.1.0-beta.33 → 0.1.0-beta.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,31 +12,23 @@ yarn add @getsupertab/supertab-connect-sdk
12
12
 
13
13
  ## Basic Usage
14
14
 
15
- ### Manual setup
15
+ ### Cloudflare Workers
16
16
 
17
- ```js
18
- import { SupertabConnect } from "@getsupertab/supertab-connect-sdk";
19
-
20
- // Initialize the SDK
21
- const supertabConnect = new SupertabConnect({
22
- apiKey: "stc_live_your_api_key",
23
- merchantSystemUrn: "your_merchant_system_urn",
24
- });
25
-
26
- // Verify a license token
27
- const verification = await supertabConnect.verifyLicenseToken(
28
- licenseToken,
29
- "https://example.com/article"
30
- );
17
+ ```ts
18
+ import { SupertabConnect, Env, ExecutionContext } from "@getsupertab/supertab-connect-sdk";
31
19
 
32
- // Record an event
33
- await supertabConnect.recordEvent("page_viewed", {
34
- page_url: "https://example.com/article",
35
- user_agent: "Mozilla/5.0...",
36
- });
20
+ export default {
21
+ async fetch(
22
+ request: Request,
23
+ env: Env,
24
+ ctx: ExecutionContext
25
+ ): Promise<Response> {
26
+ return SupertabConnect.cloudflareHandleRequests(request, env, ctx);
27
+ },
28
+ };
37
29
  ```
38
30
 
39
- ### Fastly Compute Example
31
+ ### Fastly Compute
40
32
 
41
33
  ```js
42
34
  /// <reference types="@fastly/js-compute" />
@@ -44,54 +36,41 @@ import { SecretStore } from "fastly:secret-store";
44
36
  import { SupertabConnect } from "@getsupertab/supertab-connect-sdk";
45
37
 
46
38
  const configDict = new SecretStore("demo");
47
- const config = {
48
- apiKey: configDict.get("MERCHANT_API_KEY"),
49
- merchantSystemUrn: configDict.get("MERCHANT_SYSTEM_URN"),
50
- };
39
+ const merchantSystemUrn = configDict.get("MERCHANT_SYSTEM_URN");
40
+ const merchantApiKey = configDict.get("MERCHANT_API_KEY");
51
41
 
52
- // The entry point for the request handler.
53
42
  addEventListener("fetch", (event) =>
54
43
  event.respondWith(
55
44
  SupertabConnect.fastlyHandleRequests(
56
45
  event.request,
57
- config.merchantSystemUrn,
58
- config.apiKey
46
+ merchantSystemUrn,
47
+ merchantApiKey,
48
+ "origin-backend"
59
49
  )
60
50
  )
61
51
  );
62
52
  ```
63
53
 
64
- ### CloudFlare Worker Example
54
+ ### AWS CloudFront Lambda@Edge
65
55
 
66
56
  ```ts
67
- import { SupertabConnect, Env } from "@getsupertab/supertab-connect-sdk";
68
-
69
- export default {
70
- async fetch(
71
- request: Request,
72
- env: Env,
73
- ctx: ExecutionContext
74
- ): Promise<Response> {
75
- return SupertabConnect.cloudflareHandleRequests(request, env, ctx);
76
- },
77
- };
57
+ import {
58
+ SupertabConnect,
59
+ CloudFrontRequestEvent,
60
+ CloudFrontRequestResult,
61
+ } from "@getsupertab/supertab-connect-sdk";
62
+
63
+ export async function handler(
64
+ event: CloudFrontRequestEvent
65
+ ): Promise<CloudFrontRequestResult> {
66
+ return SupertabConnect.cloudfrontHandleRequests(event, {
67
+ apiKey: "stc_live_your_api_key",
68
+ merchantSystemUrn: "your_merchant_system_urn",
69
+ });
70
+ }
78
71
  ```
79
72
 
80
- ## Configuration Options
81
-
82
- The SDK is configured using the `SupertabConnectConfig` object
83
-
84
- | Parameter | Type | Required | Default | Description |
85
- | ------------------- | ------ | -------- | ------- | ------------------------------- |
86
- | `apiKey` | string | Yes | - | Your Supertab merchant API key |
87
- | `merchantSystemUrn` | string | Yes | - | Your merchant system identifier |
88
-
89
- ## Public API Reference
90
-
91
- ### `constructor(config: SupertabConnectConfig, reset: boolean = false)`
92
-
93
- Creates a new instance of the SupertabConnect SDK.
94
- If the SDK was already initialized and the config parameters are different, it will throw an error unless `reset` is set to true.
73
+ ### Manual Setup
95
74
 
96
75
  ```ts
97
76
  import { SupertabConnect } from "@getsupertab/supertab-connect-sdk";
@@ -100,148 +79,137 @@ const supertabConnect = new SupertabConnect({
100
79
  apiKey: "stc_live_your_api_key",
101
80
  merchantSystemUrn: "your_merchant_system_urn",
102
81
  });
103
- ```
104
82
 
105
- ### `resetInstance(): void`
83
+ // Verify a license token and record an analytics event
84
+ const result = await supertabConnect.verifyAndRecord({
85
+ token: licenseToken,
86
+ resourceUrl: "https://example.com/article",
87
+ userAgent: request.headers.get("User-Agent") ?? undefined,
88
+ ctx, // pass your platform's execution context for non-blocking event recording
89
+ });
106
90
 
107
- Resets the singleton instance of SupertabConnect allowing to create an instance with a new config.
108
- We expect this to not be called in the usual production setup as the SDK is designed to intercept requests using specific public methods.
91
+ if (result.valid) {
92
+ // Allow access
93
+ } else {
94
+ console.log("Denied:", result.error);
95
+ }
96
+ ```
109
97
 
110
- ### `fastlyHandleRequests(request: Request, merchantSystemUrn: string, merchantApiKey: string, enableRSL?: boolean): Promise<Response>`
98
+ ## Configuration Options
111
99
 
112
- Handles the Supertab Connect part for each incoming HTTP request within Fastly CDN: it verifies the license token and records the event.
100
+ The SDK is configured using the `SupertabConnectConfig` object:
113
101
 
114
- For examples see the [Fastly Compute Example](#fastly-compute-example) section above.
102
+ | Parameter | Type | Required | Default | Description |
103
+ | ------------------- | ------------------ | -------- | -------- | ------------------------------------------------------------------ |
104
+ | `apiKey` | `string` | Yes | - | Your Supertab merchant API key |
105
+ | `merchantSystemUrn` | `string` | Yes | - | Your merchant system identifier |
106
+ | `enforcement` | `EnforcementMode` | No | `SOFT` | Enforcement mode: `DISABLED`, `SOFT`, or `STRICT` |
107
+ | `botDetector` | `BotDetector` | No | - | Custom bot detection function `(request, ctx?) => boolean` |
108
+ | `debug` | `boolean` | No | `false` | Enable debug logging |
115
109
 
116
- **Parameters:**
110
+ ## Public API Reference
117
111
 
118
- - `request` (Request): The incoming HTTP request object
119
- - `merchantSystemUrn` (string): Your merchant system identifier (recommended to be stored in a Fastly SecretStore)
120
- - `merchantApiKey` (string): Your Supertab merchant API key (recommended to be stored in a Fastly SecretStore)
121
- - `enableRSL` (boolean, optional): Enable RSL license.xml hosting (default: false)
112
+ ### `constructor(config: SupertabConnectConfig, reset?: boolean)`
122
113
 
123
- **Returns:**
114
+ Creates a new SupertabConnect instance (singleton). Returns the existing instance if one already exists with the same config. Throws if an instance with different config exists unless `reset` is `true`.
124
115
 
125
- - `Promise<Response>`: Result of bot detection, verification and event recording
126
- - If the requester is not a bot to be blocked, or if the license token is present and valid, returns 200 OK
127
- - If license token is invalid or missing, returns 401 Unauthorized
116
+ ### `resetInstance(): void`
128
117
 
129
- ### `cloudflareHandleRequests(request: Request, env: Env, ctx: any = null): Promise<Response>`
118
+ Clear the singleton instance, allowing a new one to be created with different config.
130
119
 
131
- Handles the Supertab Connect part for each incoming HTTP request within CloudFlare CDN: it verifies the license token and records the event.
120
+ ### `verify(options): Promise<RSLVerificationResult>` (static)
132
121
 
133
- For examples see the [CloudFlare Worker Example](#cloudflare-worker-example) section above.
122
+ Pure token verification verifies a license token without recording any events.
134
123
 
135
- **Parameters:**
124
+ **Parameters (options object):**
136
125
 
137
- - `request` (Request): The incoming HTTP request object
138
- - `env` (Env): Environment variables provided for CloudFlare Workers (MERCHANT_API_KEY and MERCHANT_SYSTEM_URN must be present)
139
- - `ctx` (ExecutionContext): Execution context passed from `fetch` worker method for awaiting async operations
126
+ | Parameter | Type | Required | Description |
127
+ | ------------- | --------- | -------- | ------------------------------------------------ |
128
+ | `token` | `string` | Yes | The license token to verify |
129
+ | `resourceUrl` | `string` | Yes | The URL of the resource being accessed |
130
+ | `baseUrl` | `string` | No | Override for the Supertab Connect API base URL |
131
+ | `debug` | `boolean` | No | Enable debug logging |
140
132
 
141
- **Returns:**
133
+ **Returns:** `{ valid: boolean; error?: string }`
142
134
 
143
- - `Promise<Response>`: Result of bot detection, verification and event recording
144
- - If the requester is not a bot to be blocked, or if the license token is present and valid, returns 200 OK
145
- - If license token is invalid or missing, returns 401 Unauthorized
135
+ ```ts
136
+ const result = await SupertabConnect.verify({
137
+ token: licenseToken,
138
+ resourceUrl: "https://example.com/article",
139
+ });
140
+ ```
146
141
 
147
- ### `handleRequest(request: Request, botDetectionHandler?: (request: Request, ctx?: any) => boolean, ctx?: any): Promise<Response>`
142
+ ### `verifyAndRecord(options): Promise<RSLVerificationResult>`
148
143
 
149
- A method for handling requests in a generic way, allowing custom bot detection logic.
150
- Any of out-of-the-box bot detector methods can be used or a custom one can be supplied provided it follows the specified signature.
144
+ Verifies a license token and records an analytics event. Uses the instance's `apiKey` and `merchantSystemUrn` for event recording.
151
145
 
152
- **Parameters:**
146
+ **Parameters (options object):**
153
147
 
154
- - `request` (Request): The incoming HTTP request object
155
- - `botDetectionHandler` (function, optional): Custom function to detect bots. It should return a boolean indicating if the request is from a bot.
156
- - `ctx` (ExecutionContext, optional): Context object to for awaiting async operations
148
+ | Parameter | Type | Required | Description |
149
+ | ------------- | ------------------ | -------- | ---------------------------------------------------------------- |
150
+ | `token` | `string` | Yes | The license token to verify |
151
+ | `resourceUrl` | `string` | Yes | The URL of the resource being accessed |
152
+ | `userAgent` | `string` | No | User agent string for event recording |
153
+ | `debug` | `boolean` | No | Enable debug logging |
154
+ | `ctx` | `ExecutionContext` | No | Execution context for non-blocking event recording |
157
155
 
158
- **Returns:**
156
+ **Returns:** `{ valid: boolean; error?: string }`
159
157
 
160
- - `Promise<Response>`: Result of bot detection, verification and event recording
161
- - If the requester is not a bot to be blocked, or if the license token is present and valid, returns 200 OK
162
- - If license token is invalid or missing, returns 401 Unauthorized
158
+ ### `handleRequest(request, ctx?): Promise<HandlerResult>`
163
159
 
164
- ### `verifyLicenseToken(licenseToken: string, requestUrl: string): Promise<LicenseTokenVerificationResult>`
165
-
166
- Verifies license tokens issued by the Supertab platform. Internally, it fetches the platform JWKs hosted by Supertab Connect and verifies the ES256 signature.
160
+ Handles an incoming request end-to-end: extracts the license token from the `Authorization` header, verifies it, records an analytics event, and applies bot detection and enforcement mode when no token is present.
167
161
 
168
162
  **Parameters:**
169
163
 
170
- - `licenseToken` (string): The license token to verify
171
- - `requestUrl` (string): The URL of the request being made (used for audience validation)
164
+ - `request` (`Request`): The incoming HTTP request
165
+ - `ctx` (`ExecutionContext`, optional): Execution context for non-blocking event recording
172
166
 
173
- **Returns:**
167
+ **Returns:** `HandlerResult` — either `{ action: "allow" }` or `{ action: "block", status, body, headers }`.
174
168
 
175
- - `Promise<LicenseTokenVerificationResult>`: Object with verification result
176
- - `valid`: boolean indicating if token is valid
177
- - `reason`: string reason for failure (if invalid)
178
- - `licenseId`: the license ID (if valid)
179
- - `payload`: decoded token payload (if valid)
169
+ ### `cloudflareHandleRequests(request, env, ctx): Promise<Response>` (static)
180
170
 
181
- Example
171
+ Convenience handler for Cloudflare Workers. Reads config from Worker environment bindings (`MERCHANT_API_KEY`, `MERCHANT_SYSTEM_URN`).
182
172
 
183
- ```js
184
- const licenseToken = "eyJhbGciOiJFUzI1..."; // Token from Authorization header
185
- const verification = await supertabConnect.verifyLicenseToken(
186
- licenseToken,
187
- "https://example.com/article"
188
- );
173
+ **Parameters:**
189
174
 
190
- if (verification.valid) {
191
- // Allow access to content
192
- console.log("License verified successfully", verification.licenseId);
193
- } else {
194
- // Block access
195
- console.log("License verification failed:", verification.reason);
196
- }
197
- ```
175
+ - `request` (`Request`): The incoming Worker request
176
+ - `env` (`Env`): Worker environment bindings
177
+ - `ctx` (`ExecutionContext`): Worker execution context
198
178
 
199
- ### `recordEvent(eventName: string, properties?: Record<string, any>, licenseId?: string): Promise<void>`
179
+ ### `fastlyHandleRequests(request, merchantSystemUrn, merchantApiKey, originBackend, options?): Promise<Response>` (static)
200
180
 
201
- Records an event in the Supertab Connect platform.
181
+ Convenience handler for Fastly Compute.
202
182
 
203
183
  **Parameters:**
204
184
 
205
- - `eventName` (string): Name of the event to record
206
- - `properties` (object, optional): Additional properties to include with the event
207
- - `licenseId` (string, optional): License ID associated with the event
185
+ - `request` (`Request`): The incoming Fastly request
186
+ - `merchantSystemUrn` (`string`): Your merchant system identifier
187
+ - `merchantApiKey` (`string`): Your Supertab merchant API key
188
+ - `originBackend` (`string`): The Fastly backend name to forward allowed requests to
189
+ - `options.enableRSL` (`boolean`, optional): Serve `license.xml` at `/license.xml` for RSL-compliant clients (default: `false`)
190
+ - `options.botDetector` (`BotDetector`, optional): Custom bot detection function
191
+ - `options.enforcement` (`EnforcementMode`, optional): Enforcement mode
208
192
 
209
- Example:
193
+ ### `cloudfrontHandleRequests(event, options): Promise<CloudFrontRequestResult>` (static)
210
194
 
211
- ```js
212
- // Record a page view with additional properties
213
- await supertabConnect.recordEvent("page_viewed", {
214
- page_url: request.url,
215
- user_agent: request.headers.get("User-Agent"),
216
- referrer: request.headers.get("Referer"),
217
- article_id: "12345",
218
- });
219
- ```
220
-
221
- ### `checkIfBotRequest(request: Request): boolean`
222
-
223
- A simple check based on the information passed in request's Headers to decide whether it comes from a crawler/bot/AI agent or not.
195
+ Convenience handler for AWS CloudFront Lambda@Edge viewer-request functions.
224
196
 
225
197
  **Parameters:**
226
198
 
227
- - `request` (Request): The incoming HTTP request object
228
-
229
- **Returns:**
199
+ - `event` (`CloudFrontRequestEvent`): The CloudFront viewer-request event
200
+ - `options` (`CloudfrontHandlerOptions`): Configuration object with `apiKey`, `merchantSystemUrn`, and optional `botDetector`/`enforcement`
230
201
 
231
- - `boolean`: True if the request's Headers fall into the conditions to identify requester as a bot; False otherwise.
202
+ ### `obtainLicenseToken(options): Promise<string>` (static)
232
203
 
233
- ### `generateLicenseToken(clientId: string, kid: string, privateKeyPem: string, resourceUrl: string, licenseXml: string): Promise<string>`
204
+ Request a license token from the Supertab Connect token endpoint using OAuth2 client credentials.
234
205
 
235
- Requests a license token from the Supertab Connect token endpoint using OAuth2 client assertion.
206
+ **Parameters (options object):**
236
207
 
237
- **Parameters:**
238
-
239
- - `clientId` (string): OAuth client identifier used for the assertion issuer/subject claims, fetched from the System Detail page
240
- - `kid` (string): Key ID to include in the JWT header
241
- - `privateKeyPem` (string): Private key in PEM format used to sign the client assertion
242
- - `resourceUrl` (string): Resource URL attempting to access with a License
243
- - `licenseXml` (string): XML license document associated with the resource url attempting to access
208
+ | Parameter | Type | Required | Description |
209
+ | -------------- | --------- | -------- | ----------------------------------------------- |
210
+ | `clientId` | `string` | Yes | OAuth client identifier |
211
+ | `clientSecret` | `string` | Yes | OAuth client secret for client_credentials flow |
212
+ | `resourceUrl` | `string` | Yes | Resource URL to obtain a license for |
213
+ | `debug` | `boolean` | No | Enable debug logging |
244
214
 
245
- **Returns:**
246
-
247
- - `Promise<string>`: The issued license access token
215
+ ```
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var H=Object.create;var R=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var V=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var X=(n,e)=>{for(var r in e)R(n,r,{get:e[r],enumerable:!0})},P=(n,e,r,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of M(e))!j.call(n,s)&&s!==r&&R(n,s,{get:()=>e[s],enumerable:!(t=W(e,s))||t.enumerable});return n};var G=(n,e,r)=>(r=n!=null?H(V(n)):{},P(e||!n||!n.__esModule?R(r,"default",{value:n,enumerable:!0}):r,n)),z=n=>P(R({},"__esModule",{value:!0}),n);var oe={};X(oe,{EnforcementMode:()=>L,HandlerAction:()=>y,SupertabConnect:()=>U,defaultBotDetector:()=>K});module.exports=z(oe);var L=(t=>(t.DISABLED="disabled",t.SOFT="soft",t.STRICT="strict",t))(L||{});var g="stc-backend",y=(r=>(r.ALLOW="allow",r.BLOCK="block",r))(y||{});var E=null;function v(){return E||(E=import("jose")),E}async function Y(n,e,r){try{let t=await fetch(n,e);if(!t.ok){let o=await t.text().catch(()=>""),i=`Failed to obtain license token: ${t.status} ${t.statusText}${o?` - ${o}`:""}`;throw new Error(i)}let s;try{s=await t.json()}catch(o){throw r&&console.error("Failed to parse license token response as JSON:",o),new Error("Failed to parse license token response as JSON")}if(!s?.access_token)throw new Error("License token response missing access_token");return s.access_token}catch(t){throw r&&console.error("Error generating license token:",t),t}}async function Q(n,e){let t=`${new URL(n).origin}/license.xml`,s=await fetch(t);if(!s.ok)throw e&&console.error(`Failed to fetch license.xml from ${t}: ${s.status}`),new Error(`Failed to fetch license.xml from ${t}: ${s.status}`);let o=await s.text();return e&&console.debug("Fetched license.xml from",t),o}function Z(n,e){let r=[],t=/<content\s([^>]*)>([\s\S]*?)<\/content>/gi,s=/url\s*=\s*"([^"]*)"/i,o=/server\s*=\s*"([^"]*)"/i,i=/<license[^>]*>[\s\S]*?<\/license>/i,a=0,c;for(;(c=t.exec(n))!==null;){a++;let l=c[1],d=c[2],f=l.match(s),h=l.match(o),m=d.match(i);if(f&&h&&m)r.push({urlPattern:f[1],server:h[1],licenseXml:m[0]});else if(e){let w=[!f&&"url",!h&&"server",!m&&"<license>"].filter(Boolean).join(", ");console.debug(`Skipping <content> element #${a}: missing ${w}`)}}return e&&console.debug(`Found ${a} <content> element(s), ${r.length} valid`),r}function ee(n,e,r){let t=new URL(e),s=t.host,o=t.pathname;r&&console.debug(`Matching resource URL: ${e} (host=${s}, path=${o})`);let i=null,a=-1;for(let c of n){let l;try{l=new URL(c.urlPattern)}catch{r&&console.debug(`Skipping block with invalid URL pattern: ${c.urlPattern}`);continue}if(l.host!==s){r&&console.debug(`Skipping block: host mismatch (pattern=${l.host}, resource=${s})`);continue}let d=l.pathname;if(d===o)return r&&console.debug(`Exact match found: ${c.urlPattern}`),c;if(d.endsWith("/*")){let f=d.slice(0,-1);if(o.startsWith(f)){let h=f.length;h>a&&(a=h,i=c)}}}return r&&console.debug(i?`Wildcard match found: ${i.urlPattern} (specificity=${a})`:`No matching content block found for ${e}`),i}async function C({clientId:n,clientSecret:e,resourceUrl:r,debug:t}){let s=await Q(r,t);t&&console.debug(`Fetched license.xml (${s.length} chars)`);let o=Z(s,t);if(o.length===0)throw t&&console.error("No valid <content> elements with <license> found in license.xml"),new Error("No valid <content> elements with <license> found in license.xml");let i=ee(o,r,t);if(!i){if(t){let d=o.map(f=>f.urlPattern).join(", ");console.error(`No <content> element matches resource URL: ${r}. Available patterns: ${d}`)}throw new Error(`No <content> element in license.xml matches resource URL: ${r}`)}t&&(console.debug("Matched content block for resource URL:",r),console.debug("Using license XML:",i.licenseXml));let a=i.server+"/token";t&&console.debug(`Requesting license token from ${a}`);let c=new URLSearchParams({grant_type:"client_credentials",license:i.licenseXml,resource:i.urlPattern}),l={method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json",Authorization:"Basic "+btoa(`${n}:${e}`)},body:c.toString()};return Y(a,l,t)}var A=new Map;function te(){let n={method:"GET"};return globalThis?.fastly&&(n={...n,backend:g}),n}async function ne({cacheKey:n,url:e,debug:r,failureMessage:t,logLabel:s}){if(!A.has(n))try{let o=await fetch(e,te());if(!o.ok)throw new Error(`${t}: ${o.status}`);let i=await o.json();A.set(n,i)}catch(o){throw r&&console.error(s,o),o}return A.get(n)}async function D(n,e){let r=`${n}/.well-known/jwks.json/platform`;return e&&console.debug(`Fetching platform JWKS from URL: ${r}`),ne({cacheKey:"platform_jwks",url:r,debug:e,failureMessage:"Failed to fetch platform JWKS",logLabel:"Error fetching platform JWKS:"})}var k=n=>n.trim().replace(/\/+$/,"");async function S({licenseToken:n,requestUrl:e,supertabBaseUrl:r,debug:t}){let{decodeProtectedHeader:s,decodeJwt:o,jwtVerify:i}=await v();if(!n)return{valid:!1,reason:"missing_license_token"};let a;try{a=s(n)}catch(p){return t&&console.error("Invalid license JWT header:",p),{valid:!1,reason:"invalid_license_header"}}if(a.alg!=="ES256")return t&&console.error("Unsupported license JWT alg:",a.alg),{valid:!1,reason:"invalid_license_algorithm"};let c;try{c=o(n)}catch(p){return t&&console.error("Invalid license JWT payload:",p),{valid:!1,reason:"invalid_license_payload"}}let l=c.license_id,d=c.iss,f=d?k(d):void 0,h=k(r);if(!f||!f.startsWith(h))return t&&console.error("License JWT issuer is missing or malformed:",d),{valid:!1,reason:"invalid_license_issuer",licenseId:l};let m=Array.isArray(c.aud)?c.aud.filter(p=>typeof p=="string"):typeof c.aud=="string"?[c.aud]:[],w=k(e);if(!m.some(p=>{let b=k(p);return b?w.startsWith(b):!1}))return t&&console.error("License JWT audience does not match request URL:",c.aud),{valid:!1,reason:"invalid_license_audience",licenseId:l};let _;try{_=await D(r,t)}catch(p){return t&&console.error("Failed to fetch platform JWKS:",p),{valid:!1,reason:"server_error",licenseId:l}}try{let b=await i(n,async I=>{let x=_.keys.find(q=>q.kid===I.kid);if(!x)throw new Error(`No matching platform key found: ${I.kid}`);return x},{issuer:d,algorithms:[a.alg],clockTolerance:"1m"});return{valid:!0,licenseId:l,payload:b.payload}}catch(p){return t&&console.error("License JWT verification failed:",p),p instanceof Error&&p.message?.includes("exp")?{valid:!1,reason:"license_token_expired",licenseId:l}:{valid:!1,reason:"license_signature_verification_failed",licenseId:l}}}function B({requestUrl:n}){let e=new URL(n);return`${e.protocol}//${e.host}/license.xml`}function N(n){let e=B({requestUrl:n});return{action:"allow",headers:{Link:`<${e}>; rel="license"; type="application/rsl+xml"`,"X-RSL-Status":"token_required","X-RSL-Reason":"missing"}}}function T({reason:n,requestUrl:e,supertabBaseUrl:r}){let t,s,o;switch(n){case"missing_license_token":o=401,t="invalid_request",s="Authorization header missing or malformed";break;case"invalid_license_algorithm":o=401,t="invalid_request",s="Unsupported token algorithm";break;case"license_token_expired":o=401,t="invalid_token",s="The license token has expired";break;case"license_signature_verification_failed":o=401,t="invalid_token",s="The license token signature is invalid";break;case"invalid_license_header":o=401,t="invalid_token",s="The license token header is malformed";break;case"invalid_license_payload":o=401,t="invalid_token",s="The license token payload is malformed";break;case"invalid_license_issuer":o=401,t="invalid_token",s="The license token issuer is not recognized";break;case"invalid_license_audience":o=403,t="insufficient_scope",s="The license does not grant access to this resource";break;case"server_error":o=503,t="server_error",s="The server encountered an error validating the license";break;default:o=401,t="invalid_token",s="License token missing, expired, revoked, or malformed"}let i=B({requestUrl:e});return{action:"block",status:o,body:`Access to this resource requires a valid license token. Error: ${t} - ${s}`,headers:{"Content-Type":"text/plain; charset=UTF-8","WWW-Authenticate":`License error="${t}", error_description="${s}"`,Link:`<${i}>; rel="license"; type="application/rsl+xml"`}}}function se(){let n={method:"GET"};return globalThis?.fastly&&(n={...n,backend:g}),n}async function $(n,e){let r=`${n}/merchants/systems/${e}/license.xml`,t=await fetch(r,se());if(!t.ok)return new Response("License not found",{status:404});let s=await t.text();return new Response(s,{status:200,headers:new Headers({"Content-Type":"application/xml"})})}async function O(n){let e=await S({licenseToken:n.token,requestUrl:n.url,supertabBaseUrl:n.supertabBaseUrl,debug:n.debug});if(n.recordEvent){let r=e.valid?"license_used":e.reason,t={page_url:n.url,user_agent:n.userAgent,verification_status:e.valid?"valid":"invalid",verification_reason:e.valid?"success":e.reason},s=n.recordEvent(r,t,e.licenseId);n.ctx?.waitUntil&&n.ctx.waitUntil(s)}return e.valid?{action:"allow"}:T({reason:e.reason,requestUrl:n.url,supertabBaseUrl:n.supertabBaseUrl})}async function F(n,e,r){let t=await n.handleRequest(e,r);if(t.action==="block")return new Response(t.body,{status:t.status,headers:new Headers(t.headers)});let s=await fetch(e);if(t.headers){let o=new Response(s.body,s);for(let[i,a]of Object.entries(t.headers))o.headers.set(i,a);return o}return s}async function J(n,e,r,t){if(t&&new URL(e.url).pathname==="/license.xml")return await $(t.baseUrl,t.merchantSystemUrn);let s=await n.handleRequest(e);if(s.action==="block")return new Response(s.body,{status:s.status,headers:new Headers(s.headers)});let o=await fetch(e,{backend:r});if(s.headers){let i=new Response(o.body,o);for(let[a,c]of Object.entries(s.headers))i.headers.set(a,c);return i}return o}function K(n){let e=n.headers.get("User-Agent")||"",r=n.headers.get("accept")||"",t=n.headers.get("sec-ch-ua"),s=n.headers.get("accept-language"),o=n.cf?.botManagement?.score,i=["chatgpt-user","perplexitybot","gptbot","anthropic-ai","ccbot","claude-web","claudebot","cohere-ai","youbot","diffbot","oai-searchbot","meta-externalagent","timpibot","amazonbot","bytespider","perplexity-user","googlebot","bot","curl","wget"],a=e.toLowerCase(),c=i.some(m=>a.includes(m)),l=e.toLowerCase().includes("headless")||e.toLowerCase().includes("puppeteer")||!t,d=!e.toLowerCase().includes("headless")&&!e.toLowerCase().includes("puppeteer")&&!t,f=!r||!s,h=typeof o=="number"&&o<30;return(a.includes("safari")||a.includes("mozilla"))&&l&&d?!1:c||l||f||h}var u=class u{constructor(e,r=!1){if(!r&&u._instance){if(!(e.apiKey===u._instance.apiKey&&e.merchantSystemUrn===u._instance.merchantSystemUrn))throw new Error("Cannot create a new instance with different configuration. Use resetInstance to clear the existing instance.");return u._instance}if(r&&u._instance&&u.resetInstance(),!e.apiKey||!e.merchantSystemUrn)throw new Error("Missing required configuration: apiKey and merchantSystemUrn are required");this.apiKey=e.apiKey,this.merchantSystemUrn=e.merchantSystemUrn,this.enforcement=e.enforcement??"soft",this.botDetector=e.botDetector,this.debug=e.debug??!1,u._instance=this}static resetInstance(){u._instance=null}static setBaseUrl(e){u.baseUrl=e}static getBaseUrl(){return u.baseUrl}async verifyLicenseToken(e,r){return S({licenseToken:e,requestUrl:r,supertabBaseUrl:u.baseUrl,debug:this.debug})}async recordEvent(e,r={},t){let s={event_name:e,merchant_system_urn:this.merchantSystemUrn?this.merchantSystemUrn:"",license_id:t,properties:r};try{let o={method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},body:JSON.stringify(s)};globalThis?.fastly&&(o={...o,backend:g});let i=await fetch(`${u.baseUrl}/events`,o);i.ok||console.log(`Failed to record event: ${i.status}`)}catch(o){console.log("Error recording event:",o)}}async handleRequest(e,r){let t=e.headers.get("Authorization")||"",s=t.startsWith("License ")?t.slice(8):null,o=e.url,i=e.headers.get("User-Agent")||"unknown";if(s)return this.enforcement==="disabled"?{action:"allow"}:O({token:s,url:o,userAgent:i,supertabBaseUrl:u.baseUrl,debug:this.debug,recordEvent:this.recordEvent.bind(this),ctx:r});if(!(this.botDetector?.(e,r)??!1))return{action:"allow"};switch(this.enforcement){case"strict":return T({reason:"missing_license_token",requestUrl:o,supertabBaseUrl:u.baseUrl});case"soft":return N(o);default:return{action:"allow"}}}static async obtainLicenseToken(e,r,t,s=!1){return C({clientId:e,clientSecret:r,resourceUrl:t,debug:s})}static async cloudflareHandleRequests(e,r,t){let s=new u({apiKey:r.MERCHANT_API_KEY,merchantSystemUrn:r.MERCHANT_SYSTEM_URN});return F(s,e,t)}static async fastlyHandleRequests(e,r,t,s,o){let{enableRSL:i=!1,botDetector:a,enforcement:c}=o??{},l=new u({apiKey:t,merchantSystemUrn:r,botDetector:a,enforcement:c});return J(l,e,s,i?{baseUrl:u.baseUrl,merchantSystemUrn:r}:void 0)}};u.baseUrl="https://api-connect.supertab.co",u._instance=null;var U=u;0&&(module.exports={EnforcementMode,HandlerAction,SupertabConnect,defaultBotDetector});
1
+ "use strict";var W=Object.create;var b=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var X=Object.getPrototypeOf,z=Object.prototype.hasOwnProperty;var Y=(t,e)=>{for(var r in e)b(t,r,{get:e[r],enumerable:!0})},P=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of G(e))!z.call(t,s)&&s!==r&&b(t,s,{get:()=>e[s],enumerable:!(n=j(e,s))||n.enumerable});return t};var Q=(t,e,r)=>(r=t!=null?W(X(t)):{},P(e||!t||!t.__esModule?b(r,"default",{value:t,enumerable:!0}):r,t)),Z=t=>P(b({},"__esModule",{value:!0}),t);var ue={};Y(ue,{EnforcementMode:()=>I,HandlerAction:()=>R,SupertabConnect:()=>T,defaultBotDetector:()=>J});module.exports=Z(ue);var I=(n=>(n.DISABLED="disabled",n.SOFT="soft",n.STRICT="strict",n))(I||{});var y="stc-backend",R=(r=>(r.ALLOW="allow",r.BLOCK="block",r))(R||{});var w=null;function S(){return w||(w=import("jose")),w}async function ee(t,e,r){try{let n=await fetch(t,e);if(!n.ok){let o=await n.text().catch(()=>""),a=`Failed to obtain license token: ${n.status} ${n.statusText}${o?` - ${o}`:""}`;throw new Error(a)}let s;try{s=await n.json()}catch(o){throw r&&console.error("Failed to parse license token response as JSON:",o),new Error("Failed to parse license token response as JSON")}if(!s?.access_token)throw new Error("License token response missing access_token");return s.access_token}catch(n){throw r&&console.error("Error generating license token:",n),n}}async function te(t,e){let n=`${new URL(t).origin}/license.xml`,s=await fetch(n);if(!s.ok)throw e&&console.error(`Failed to fetch license.xml from ${n}: ${s.status}`),new Error(`Failed to fetch license.xml from ${n}: ${s.status}`);let o=await s.text();return e&&console.debug("Fetched license.xml from",n),o}function re(t,e){let r=[],n=/<content\s([^>]*)>([\s\S]*?)<\/content>/gi,s=/url\s*=\s*"([^"]*)"/i,o=/server\s*=\s*"([^"]*)"/i,a=/<license[^>]*>[\s\S]*?<\/license>/i,c=0,i;for(;(i=n.exec(t))!==null;){c++;let l=i[1],d=i[2],p=l.match(s),m=l.match(o),g=d.match(a);if(p&&m&&g)r.push({urlPattern:p[1],server:m[1],licenseXml:g[0]});else if(e){let A=[!p&&"url",!m&&"server",!g&&"<license>"].filter(Boolean).join(", ");console.debug(`Skipping <content> element #${c}: missing ${A}`)}}return e&&console.debug(`Found ${c} <content> element(s), ${r.length} valid`),r}function ne(t,e,r){let n=new URL(e),s=n.host,o=n.pathname;r&&console.debug(`Matching resource URL: ${e} (host=${s}, path=${o})`);let a=null,c=-1;for(let i of t){let l;try{l=new URL(i.urlPattern)}catch{r&&console.debug(`Skipping block with invalid URL pattern: ${i.urlPattern}`);continue}if(l.host!==s){r&&console.debug(`Skipping block: host mismatch (pattern=${l.host}, resource=${s})`);continue}let d=l.pathname;if(d===o)return r&&console.debug(`Exact match found: ${i.urlPattern}`),i;if(d.endsWith("/*")){let p=d.slice(0,-1);if(o.startsWith(p)){let m=p.length;m>c&&(c=m,a=i)}}}return r&&console.debug(a?`Wildcard match found: ${a.urlPattern} (specificity=${c})`:`No matching content block found for ${e}`),a}async function N({clientId:t,clientSecret:e,resourceUrl:r,debug:n}){let s=await te(r,n);n&&console.debug(`Fetched license.xml (${s.length} chars)`);let o=re(s,n);if(o.length===0)throw n&&console.error("No valid <content> elements with <license> found in license.xml"),new Error("No valid <content> elements with <license> found in license.xml");let a=ne(o,r,n);if(!a){if(n){let d=o.map(p=>p.urlPattern).join(", ");console.error(`No <content> element matches resource URL: ${r}. Available patterns: ${d}`)}throw new Error(`No <content> element in license.xml matches resource URL: ${r}`)}n&&(console.debug("Matched content block for resource URL:",r),console.debug("Using license XML:",a.licenseXml));let c=a.server+"/token";n&&console.debug(`Requesting license token from ${c}`);let i=new URLSearchParams({grant_type:"client_credentials",license:a.licenseXml,resource:a.urlPattern}),l={method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json",Authorization:"Basic "+btoa(`${t}:${e}`)},body:i.toString()};return ee(c,l,n)}var k=new Map;function se(){let t={method:"GET"};return globalThis?.fastly&&(t={...t,backend:y}),t}async function oe({cacheKey:t,url:e,debug:r,failureMessage:n,logLabel:s}){if(!k.has(t))try{let o=await fetch(e,se());if(!o.ok)throw new Error(`${n}: ${o.status}`);let a=await o.json();k.set(t,a)}catch(o){throw r&&console.error(s,o),o}return k.get(t)}async function q(t,e){let r=`${t}/.well-known/jwks.json/platform`;return e&&console.debug(`Fetching platform JWKS from URL: ${r}`),oe({cacheKey:"platform_jwks",url:r,debug:e,failureMessage:"Failed to fetch platform JWKS",logLabel:"Error fetching platform JWKS:"})}async function F({apiKey:t,merchantSystemUrn:e,baseUrl:r,eventName:n,properties:s,licenseId:o,debug:a=!1}){let c={event_name:n,merchant_system_urn:e,license_id:o,properties:s};try{let i={method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(c)};globalThis?.fastly&&(i={...i,backend:y});let l=await fetch(`${r}/events`,i);!l.ok&&a&&console.error(`Failed to record event: ${l.status}`)}catch(i){a&&console.error("Error recording event:",i)}}var L=t=>t.trim().replace(/\/+$/,"");function h(t){switch(t){case"missing_license_token":return"Authorization header missing or malformed";case"invalid_license_algorithm":return"Unsupported token algorithm";case"license_token_expired":return"The license token has expired";case"license_signature_verification_failed":return"The license token signature is invalid";case"invalid_license_header":return"The license token header is malformed";case"invalid_license_payload":return"The license token payload is malformed";case"invalid_license_issuer":return"The license token issuer is not recognized";case"invalid_license_audience":return"The license does not grant access to this resource";case"server_error":return"The server encountered an error validating the license";default:return"License token missing, expired, revoked, or malformed"}}async function x({licenseToken:t,requestUrl:e,supertabBaseUrl:r,debug:n}){let{decodeProtectedHeader:s,decodeJwt:o,jwtVerify:a}=await S();if(!t)return{valid:!1,reason:"missing_license_token",error:h("missing_license_token")};let c;try{c=s(t)}catch(f){return n&&console.error("Invalid license JWT header:",f),{valid:!1,reason:"invalid_license_header",error:h("invalid_license_header")}}if(c.alg!=="ES256")return n&&console.error("Unsupported license JWT alg:",c.alg),{valid:!1,reason:"invalid_license_algorithm",error:h("invalid_license_algorithm")};let i;try{i=o(t)}catch(f){return n&&console.error("Invalid license JWT payload:",f),{valid:!1,reason:"invalid_license_payload",error:h("invalid_license_payload")}}let l=i.license_id,d=i.iss,p=d?L(d):void 0,m=L(r);if(!p||!p.startsWith(m))return n&&console.error("License JWT issuer is missing or malformed:",d),{valid:!1,reason:"invalid_license_issuer",error:h("invalid_license_issuer"),licenseId:l};let g=Array.isArray(i.aud)?i.aud.filter(f=>typeof f=="string"):typeof i.aud=="string"?[i.aud]:[],A=L(e);if(!g.some(f=>{let E=L(f);return E?A.startsWith(E):!1}))return n&&console.error("License JWT audience does not match request URL:",i.aud),{valid:!1,reason:"invalid_license_audience",error:h("invalid_license_audience"),licenseId:l};let C;try{C=await q(r,n)}catch(f){return n&&console.error("Failed to fetch platform JWKS:",f),{valid:!1,reason:"server_error",error:h("server_error"),licenseId:l}}try{let E=await a(t,async _=>{let D=C.keys.find(M=>M.kid===_.kid);if(!D)throw new Error(`No matching platform key found: ${_.kid}`);return D},{issuer:d,algorithms:[c.alg],clockTolerance:"1m"});return{valid:!0,licenseId:l,payload:E.payload}}catch(f){return n&&console.error("License JWT verification failed:",f),f instanceof Error&&f.message?.includes("exp")?{valid:!1,reason:"license_token_expired",error:h("license_token_expired"),licenseId:l}:{valid:!1,reason:"license_signature_verification_failed",error:h("license_signature_verification_failed"),licenseId:l}}}function O({requestUrl:t}){let e=new URL(t);return`${e.protocol}//${e.host}/license.xml`}function $(t){let e=O({requestUrl:t});return{action:"allow",headers:{Link:`<${e}>; rel="license"; type="application/rsl+xml"`,"X-RSL-Status":"token_required","X-RSL-Reason":"missing"}}}function ae(t){switch(t){case"missing_license_token":case"invalid_license_algorithm":return{rslError:"invalid_request",status:401};case"license_token_expired":case"license_signature_verification_failed":case"invalid_license_header":case"invalid_license_payload":case"invalid_license_issuer":return{rslError:"invalid_token",status:401};case"invalid_license_audience":return{rslError:"insufficient_scope",status:403};case"server_error":return{rslError:"server_error",status:503};default:return{rslError:"invalid_token",status:401}}}function ce(t){return t.replace(/[\r\n]/g,"").replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function U({reason:t,error:e,requestUrl:r}){let{rslError:n,status:s}=ae(t),o=ce(e),a=O({requestUrl:r});return{action:"block",status:s,body:`Access to this resource requires a valid license token. Error: ${n} - ${e}`,headers:{"Content-Type":"text/plain; charset=UTF-8","WWW-Authenticate":`License error="${n}", error_description="${o}"`,Link:`<${a}>; rel="license"; type="application/rsl+xml"`}}}function le(){let t={method:"GET"};return globalThis?.fastly&&(t={...t,backend:y}),t}async function B(t,e){let r=`${t}/merchants/systems/${e}/license.xml`,n=await fetch(r,le());if(!n.ok)return new Response("License not found",{status:404});let s=await n.text();return new Response(s,{status:200,headers:new Headers({"Content-Type":"application/xml"})})}async function v(t){let e=await x({licenseToken:t.token,requestUrl:t.url,supertabBaseUrl:t.supertabBaseUrl,debug:t.debug}),r=F({apiKey:t.apiKey,merchantSystemUrn:t.merchantSystemUrn,baseUrl:t.supertabBaseUrl,eventName:e.valid?"license_used":e.reason,properties:{page_url:t.url,user_agent:t.userAgent,verification_status:e.valid?"valid":"invalid",verification_reason:e.valid?"success":e.reason},licenseId:e.licenseId,debug:t.debug});return t.ctx?.waitUntil&&t.ctx.waitUntil(r),e}async function H(t,e,r){let n=await t.handleRequest(e,r);if(n.action==="block")return new Response(n.body,{status:n.status,headers:new Headers(n.headers)});let s=await fetch(e);if(n.headers){let o=new Response(s.body,s);for(let[a,c]of Object.entries(n.headers))o.headers.set(a,c);return o}return s}async function K(t,e,r,n){if(n&&new URL(e.url).pathname==="/license.xml")return await B(n.baseUrl,n.merchantSystemUrn);let s=await t.handleRequest(e);if(s.action==="block")return new Response(s.body,{status:s.status,headers:new Headers(s.headers)});let o=await fetch(e,{backend:r});if(s.headers){let a=new Response(o.body,o);for(let[c,i]of Object.entries(s.headers))a.headers.set(c,i);return a}return o}async function V(t,e){let r=e.Records[0].cf.request,n=`https://${r.headers.host[0].value}${r.uri}${r.querystring?"?"+r.querystring:""}`,s=new Headers;Object.entries(r.headers).forEach(([c,i])=>{i.forEach(({value:l})=>s.append(c,l))});let o=new Request(n,{method:r.method,headers:s}),a=await t.handleRequest(o);if(a.action==="block"){let c={};return Object.entries(a.headers).forEach(([i,l])=>{c[i.toLowerCase()]=[{key:i,value:l}]}),{status:a.status.toString(),statusDescription:a.status===401?"Unauthorized":"Payment Required",headers:c,body:a.body}}return r}function J(t){let e=t.headers.get("User-Agent")||"",r=t.headers.get("accept")||"",n=t.headers.get("sec-ch-ua"),s=t.headers.get("accept-language"),o=t.cf?.botManagement?.score,a=["chatgpt-user","perplexitybot","gptbot","anthropic-ai","ccbot","claude-web","claudebot","cohere-ai","youbot","diffbot","oai-searchbot","meta-externalagent","timpibot","amazonbot","bytespider","perplexity-user","googlebot","bot","curl","wget"],c=e.toLowerCase(),i=a.some(g=>c.includes(g)),l=c.includes("headless")||c.includes("puppeteer")||!n,d=!c.includes("headless")&&!c.includes("puppeteer")&&!n,p=!r||!s,m=typeof o=="number"&&o<30;return(c.includes("safari")||c.includes("mozilla"))&&l&&d?!1:i||l||p||m}var u=class u{constructor(e,r=!1){if(!r&&u._instance){if(!(e.apiKey===u._instance.apiKey&&e.merchantSystemUrn===u._instance.merchantSystemUrn))throw new Error("Cannot create a new instance with different configuration. Use resetInstance to clear the existing instance.");return u._instance}if(r&&u._instance&&u.resetInstance(),!e.apiKey||!e.merchantSystemUrn)throw new Error("Missing required configuration: apiKey and merchantSystemUrn are required");this.apiKey=e.apiKey,this.merchantSystemUrn=e.merchantSystemUrn,this.enforcement=e.enforcement??"soft",this.botDetector=e.botDetector,this.debug=e.debug??!1,u._instance=this}static resetInstance(){u._instance=null}static setBaseUrl(e){u.baseUrl=e}static getBaseUrl(){return u.baseUrl}static async verify(e){let r=e.baseUrl??u.baseUrl,n=await x({licenseToken:e.token,requestUrl:e.resourceUrl,supertabBaseUrl:r,debug:e.debug??!1});return n.valid?{valid:!0}:{valid:!1,error:n.error}}async verifyAndRecord(e){let r=await v({token:e.token,url:e.resourceUrl,userAgent:e.userAgent??"unknown",supertabBaseUrl:u.baseUrl,debug:e.debug??this.debug,apiKey:this.apiKey,merchantSystemUrn:this.merchantSystemUrn,ctx:e.ctx});return r.valid?{valid:!0}:{valid:!1,error:r.error}}async handleRequest(e,r){let n=e.headers.get("Authorization")||"",s=n.startsWith("License ")?n.slice(8):null,o=e.url,a=e.headers.get("User-Agent")||"unknown";if(s){if(this.enforcement==="disabled")return{action:"allow"};let i=await v({token:s,url:o,userAgent:a,supertabBaseUrl:u.baseUrl,debug:this.debug,apiKey:this.apiKey,merchantSystemUrn:this.merchantSystemUrn,ctx:r});return i.valid?{action:"allow"}:U({reason:i.reason,error:i.error,requestUrl:o})}if(!(this.botDetector?.(e,r)??!1))return{action:"allow"};switch(this.enforcement){case"strict":return U({reason:"missing_license_token",error:"Authorization header missing or malformed",requestUrl:o});case"soft":return $(o);default:return{action:"allow"}}}static async obtainLicenseToken(e){return N({clientId:e.clientId,clientSecret:e.clientSecret,resourceUrl:e.resourceUrl,debug:e.debug})}static async cloudflareHandleRequests(e,r,n){let s=new u({apiKey:r.MERCHANT_API_KEY,merchantSystemUrn:r.MERCHANT_SYSTEM_URN});return H(s,e,n)}static async fastlyHandleRequests(e,r,n,s,o){let{enableRSL:a=!1,botDetector:c,enforcement:i}=o??{},l=new u({apiKey:n,merchantSystemUrn:r,botDetector:c,enforcement:i});return K(l,e,s,a?{baseUrl:u.baseUrl,merchantSystemUrn:r}:void 0)}static async cloudfrontHandleRequests(e,r){let n=new u({apiKey:r.apiKey,merchantSystemUrn:r.merchantSystemUrn,botDetector:r.botDetector,enforcement:r.enforcement});return V(n,e)}};u.baseUrl="https://api-connect.supertab.co",u._instance=null;var T=u;0&&(module.exports={EnforcementMode,HandlerAction,SupertabConnect,defaultBotDetector});
2
2
  //# sourceMappingURL=index.cjs.map