@mks2508/bundlp 0.1.4 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -457,7 +457,7 @@ function isDrmOnly(formats) {
457
457
 
458
458
  //#endregion
459
459
  //#region src/innertube/client.ts
460
- const log = logger.withPrefix("[InnerTube]");
460
+ const log$5 = logger.scope("InnerTube");
461
461
  /**
462
462
  * Client for interacting with YouTube's InnerTube API.
463
463
  */
@@ -521,7 +521,7 @@ var InnerTubeClient = class {
521
521
  */
522
522
  async fetchPlayer(videoId, options = {}) {
523
523
  const config = INNERTUBE_CLIENTS[this.currentClient];
524
- log.debug(`Fetching player for ${videoId} with client ${this.currentClient}`);
524
+ log$5.debug(`Fetching player for ${videoId} with client ${this.currentClient}`);
525
525
  const payload = {
526
526
  context: this.buildContext(),
527
527
  videoId,
@@ -532,45 +532,45 @@ var InnerTubeClient = class {
532
532
  if (options.poToken) {
533
533
  if (!payload.serviceIntegrityDimensions) payload.serviceIntegrityDimensions = {};
534
534
  payload.serviceIntegrityDimensions.poToken = options.poToken;
535
- log.debug(`Using po_token (length: ${options.poToken.length})`);
535
+ log$5.debug(`Using po_token (length: ${options.poToken.length})`);
536
536
  }
537
537
  const url = `${INNER_TUBE_API_URL}/player?key=${config.API_KEY || ""}`;
538
538
  const responseResult = await httpClient.post(url, payload, { headers: this.getHeaders() });
539
539
  if (isErr(responseResult)) {
540
- log.error(`HTTP request failed for client ${this.currentClient}:`, responseResult.error.message);
540
+ log$5.error(`HTTP request failed for client ${this.currentClient}:`, responseResult.error.message);
541
541
  return responseResult;
542
542
  }
543
543
  const response = responseResult.value;
544
544
  if (!response.ok) {
545
- log.error(`Player request failed for ${this.currentClient}: HTTP ${response.status}`);
545
+ log$5.error(`Player request failed for ${this.currentClient}: HTTP ${response.status}`);
546
546
  return err(createError("INNERTUBE_ERROR", `Player request failed with status ${response.status}`));
547
547
  }
548
548
  try {
549
549
  const validated = PlayerResponseSchema(await response.json());
550
550
  if (validated instanceof type.errors) {
551
- log.error(`Parse error for ${this.currentClient}:`, validated.summary);
551
+ log$5.error(`Parse error for ${this.currentClient}:`, validated.summary);
552
552
  return err(createError("PARSE_ERROR", `Invalid player response: ${validated.summary}`));
553
553
  }
554
554
  const status = validated.playabilityStatus.status;
555
555
  const reason = validated.playabilityStatus.reason || "No reason";
556
- log.debug(`Client ${this.currentClient} response: status=${status}, reason=${reason}`);
556
+ log$5.debug(`Client ${this.currentClient} response: status=${status}, reason=${reason}`);
557
557
  if (status === "ERROR") {
558
- log.warn(`Client ${this.currentClient} returned ERROR: ${reason}`);
558
+ log$5.warn(`Client ${this.currentClient} returned ERROR: ${reason}`);
559
559
  return err(createError("VIDEO_UNAVAILABLE", reason));
560
560
  }
561
561
  if (status === "LOGIN_REQUIRED") {
562
- log.warn(`Client ${this.currentClient} requires login: ${reason}`);
562
+ log$5.warn(`Client ${this.currentClient} requires login: ${reason}`);
563
563
  return err(createError("VIDEO_UNAVAILABLE", `Login required: ${reason}`));
564
564
  }
565
565
  if (status === "UNPLAYABLE") {
566
- log.warn(`Client ${this.currentClient} unplayable: ${reason}`);
566
+ log$5.warn(`Client ${this.currentClient} unplayable: ${reason}`);
567
567
  return err(createError("VIDEO_UNAVAILABLE", `Unplayable: ${reason}`));
568
568
  }
569
569
  const formatsCount = (validated.streamingData?.formats?.length || 0) + (validated.streamingData?.adaptiveFormats?.length || 0);
570
- log.info(`Client ${this.currentClient} success: ${formatsCount} formats`);
570
+ log$5.info(`Client ${this.currentClient} success: ${formatsCount} formats`);
571
571
  return ok(validated);
572
572
  } catch (error) {
573
- log.error(`Parse exception for ${this.currentClient}:`, error);
573
+ log$5.error(`Parse exception for ${this.currentClient}:`, error);
574
574
  return err(createError("PARSE_ERROR", "Failed to parse InnerTube response", error));
575
575
  }
576
576
  }
@@ -583,35 +583,35 @@ var InnerTubeClient = class {
583
583
  */
584
584
  async fetchPlayerWithFallback(videoId, options = {}) {
585
585
  const errors = [];
586
- log.info(`Starting fallback extraction for ${videoId}`);
587
- log.info(`Fallback order: ${this.FALLBACK_ORDER.join(" → ")}`);
586
+ log$5.info(`Starting fallback extraction for ${videoId}`);
587
+ log$5.info(`Fallback order: ${this.FALLBACK_ORDER.join(" → ")}`);
588
588
  for (const clientName of this.FALLBACK_ORDER) {
589
- log.info(`Trying client: ${clientName}`);
589
+ log$5.info(`Trying client: ${clientName}`);
590
590
  if (isErr(this.setClient(clientName))) {
591
- log.warn(`Failed to set client ${clientName}`);
591
+ log$5.warn(`Failed to set client ${clientName}`);
592
592
  continue;
593
593
  }
594
594
  const result = await this.fetchPlayer(videoId, options);
595
595
  if (isOk(result)) {
596
596
  const validationResult = this.isValidResponse(result.value);
597
597
  if (validationResult.valid) {
598
- log.success(`Client ${clientName} returned valid response`);
598
+ log$5.success(`Client ${clientName} returned valid response`);
599
599
  return result;
600
600
  }
601
- log.warn(`Client ${clientName} response invalid: ${validationResult.reason}`);
601
+ log$5.warn(`Client ${clientName} response invalid: ${validationResult.reason}`);
602
602
  errors.push({
603
603
  client: clientName,
604
604
  error: createError("VIDEO_UNAVAILABLE", validationResult.reason)
605
605
  });
606
606
  } else {
607
- log.warn(`Client ${clientName} failed: ${result.error.message}`);
607
+ log$5.warn(`Client ${clientName} failed: ${result.error.message}`);
608
608
  errors.push({
609
609
  client: clientName,
610
610
  error: result.error
611
611
  });
612
612
  }
613
613
  }
614
- log.error(`All clients failed for ${videoId}. Errors:`, errors.map((e) => ({
614
+ log$5.error(`All clients failed for ${videoId}. Errors:`, errors.map((e) => ({
615
615
  client: e.client,
616
616
  error: e.error.message
617
617
  })));
@@ -2385,6 +2385,7 @@ const PO_TOKEN_POLICIES = {
2385
2385
 
2386
2386
  //#endregion
2387
2387
  //#region src/po-token/botguard/challenge.ts
2388
+ const log$4 = logger.scope("ChallengeFetcher");
2388
2389
  const WAA_CREATE_ENDPOINT = "https://jnn-pa.googleapis.com/$rpc/google.internal.waa.v1.Waa/Create";
2389
2390
  const INNERTUBE_ATT_ENDPOINT = "https://www.youtube.com/youtubei/v1/att/get";
2390
2391
  const GOOG_API_KEY$1 = "AIzaSyDyT5W0Jh49F30Pqqtyfdf7pDLFKLJoAnw";
@@ -2395,6 +2396,7 @@ var ChallengeFetcher = class {
2395
2396
  this.timeout = options.timeout ?? 15e3;
2396
2397
  }
2397
2398
  async fetchAttestation() {
2399
+ log$4.info(`Fetching attestation from ${INNERTUBE_ATT_ENDPOINT}`);
2398
2400
  const payload = { context: { client: {
2399
2401
  clientName: "WEB",
2400
2402
  clientVersion: "2.20250222.10.00",
@@ -2402,6 +2404,7 @@ var ChallengeFetcher = class {
2402
2404
  gl: "US"
2403
2405
  } } };
2404
2406
  try {
2407
+ log$4.debug("Sending POST request...");
2405
2408
  const response = await fetch(INNERTUBE_ATT_ENDPOINT, {
2406
2409
  method: "POST",
2407
2410
  headers: {
@@ -2413,11 +2416,22 @@ var ChallengeFetcher = class {
2413
2416
  body: JSON.stringify(payload),
2414
2417
  signal: AbortSignal.timeout(this.timeout)
2415
2418
  });
2416
- if (!response.ok) return err(createError("BOTGUARD_INIT_FAILED", `Attestation request failed with status ${response.status}`));
2419
+ log$4.debug(`Response status: ${response.status}`);
2420
+ if (!response.ok) {
2421
+ log$4.error(`Attestation request failed with status ${response.status}`);
2422
+ return err(createError("BOTGUARD_INIT_FAILED", `Attestation request failed with status ${response.status}`));
2423
+ }
2417
2424
  const data = await response.json();
2418
- return this.parseAttestationResponse(data);
2425
+ log$4.debug("Parsing attestation response...");
2426
+ const result = this.parseAttestationResponse(data);
2427
+ if (result.ok) log$4.success(`Attestation fetched successfully (visitorData length: ${result.value.visitorData.length})`);
2428
+ return result;
2419
2429
  } catch (error) {
2420
- if (error instanceof Error && error.name === "TimeoutError") return err(createError("BOTGUARD_INIT_FAILED", "Attestation fetch timeout"));
2430
+ if (error instanceof Error && error.name === "TimeoutError") {
2431
+ log$4.error(`Attestation fetch timeout after ${this.timeout}ms`);
2432
+ return err(createError("BOTGUARD_INIT_FAILED", "Attestation fetch timeout"));
2433
+ }
2434
+ log$4.error("Failed to fetch attestation", error);
2421
2435
  return err(createError("BOTGUARD_INIT_FAILED", "Failed to fetch attestation", error));
2422
2436
  }
2423
2437
  }
@@ -2437,7 +2451,9 @@ var ChallengeFetcher = class {
2437
2451
  });
2438
2452
  }
2439
2453
  async fetchWaaChallenge() {
2454
+ log$4.info(`Fetching WAA challenge from ${WAA_CREATE_ENDPOINT}`);
2440
2455
  try {
2456
+ log$4.debug("Sending POST request with API key...");
2441
2457
  const response = await fetch(WAA_CREATE_ENDPOINT, {
2442
2458
  method: "POST",
2443
2459
  headers: {
@@ -2447,12 +2463,26 @@ var ChallengeFetcher = class {
2447
2463
  body: JSON.stringify([REQUEST_KEY$1]),
2448
2464
  signal: AbortSignal.timeout(this.timeout)
2449
2465
  });
2450
- if (!response.ok) return err(createError("BOTGUARD_INIT_FAILED", `WAA Create request failed with status ${response.status}`));
2466
+ log$4.debug(`Response status: ${response.status}`);
2467
+ if (!response.ok) {
2468
+ log$4.error(`WAA Create request failed with status ${response.status}`);
2469
+ return err(createError("BOTGUARD_INIT_FAILED", `WAA Create request failed with status ${response.status}`));
2470
+ }
2451
2471
  const encoded = (await response.json())[1];
2452
- if (!encoded || typeof encoded !== "string") return err(createError("PARSE_ERROR", "Invalid WAA response format"));
2453
- return this.descrambleWaaResponse(encoded);
2472
+ if (!encoded || typeof encoded !== "string") {
2473
+ log$4.error("Invalid WAA response format - missing encoded data");
2474
+ return err(createError("PARSE_ERROR", "Invalid WAA response format"));
2475
+ }
2476
+ log$4.debug(`Descrambling WAA response (encoded length: ${encoded.length})...`);
2477
+ const result = this.descrambleWaaResponse(encoded);
2478
+ if (result.ok) log$4.success(`WAA challenge descrambled (program: ${result.value.program.length} bytes, globalName: ${result.value.globalName})`);
2479
+ return result;
2454
2480
  } catch (error) {
2455
- if (error instanceof Error && error.name === "TimeoutError") return err(createError("BOTGUARD_INIT_FAILED", "WAA Create fetch timeout"));
2481
+ if (error instanceof Error && error.name === "TimeoutError") {
2482
+ log$4.error(`WAA Create fetch timeout after ${this.timeout}ms`);
2483
+ return err(createError("BOTGUARD_INIT_FAILED", "WAA Create fetch timeout"));
2484
+ }
2485
+ log$4.error("Failed to fetch WAA challenge", error);
2456
2486
  return err(createError("BOTGUARD_INIT_FAILED", "Failed to fetch WAA challenge", error));
2457
2487
  }
2458
2488
  }
@@ -2493,6 +2523,7 @@ var ChallengeFetcher = class {
2493
2523
 
2494
2524
  //#endregion
2495
2525
  //#region src/po-token/botguard/client.ts
2526
+ const log$3 = logger.scope("BotGuardClient");
2496
2527
  var DeferredPromise = class {
2497
2528
  promise;
2498
2529
  resolve;
@@ -2520,13 +2551,21 @@ var BotGuardClient = class BotGuardClient {
2520
2551
  this.snapshotTimeout = 5e3;
2521
2552
  }
2522
2553
  static async create(challenge, options = {}) {
2554
+ log$3.info("Creating BotGuard client...");
2555
+ log$3.debug(`Options: timeout=${options.timeout || "default"}`);
2523
2556
  const client = new BotGuardClient(challenge, options);
2524
2557
  const loadResult = await client.load(challenge);
2525
- if (!isOk(loadResult)) return loadResult;
2558
+ if (!isOk(loadResult)) {
2559
+ log$3.error("Client creation failed", loadResult.error);
2560
+ return loadResult;
2561
+ }
2562
+ log$3.success("BotGuard client created successfully");
2526
2563
  return ok(client);
2527
2564
  }
2528
2565
  async load(challenge) {
2566
+ log$3.debug("Loading BotGuard VM environment...");
2529
2567
  try {
2568
+ log$3.debug("Creating JSDOM instance with YouTube context");
2530
2569
  this.dom = new JSDOM("<!DOCTYPE html><html><head></head><body></body></html>", {
2531
2570
  url: "https://www.youtube.com/",
2532
2571
  runScripts: "dangerously",
@@ -2543,15 +2582,25 @@ var BotGuardClient = class BotGuardClient {
2543
2582
  window.Request = globalThis.Request;
2544
2583
  window.Response = globalThis.Response;
2545
2584
  window.Headers = globalThis.Headers;
2585
+ log$3.debug(`Evaluating interpreter script (${challenge.interpreterScript.length} bytes)...`);
2546
2586
  const evalFn = window.eval;
2547
2587
  evalFn(challenge.interpreterScript);
2548
2588
  this.vm = window[this.globalName];
2549
- if (!this.vm) return err(createError("BOTGUARD_INIT_FAILED", `VM not found at globalName: ${this.globalName}`));
2550
- if (typeof this.vm.a !== "function") return err(createError("BOTGUARD_INIT_FAILED", "VM init function (a) not found"));
2589
+ if (!this.vm) {
2590
+ log$3.error(`VM not found at globalName: ${this.globalName}`);
2591
+ return err(createError("BOTGUARD_INIT_FAILED", `VM not found at globalName: ${this.globalName}`));
2592
+ }
2593
+ if (typeof this.vm.a !== "function") {
2594
+ log$3.error("VM init function (a) not found");
2595
+ return err(createError("BOTGUARD_INIT_FAILED", "VM init function (a) not found"));
2596
+ }
2597
+ log$3.debug("Loading BotGuard program...");
2551
2598
  const loadResult = await this.loadProgram();
2552
2599
  if (!isOk(loadResult)) return loadResult;
2600
+ log$3.success("BotGuard VM loaded successfully");
2553
2601
  return ok(void 0);
2554
2602
  } catch (error) {
2603
+ log$3.error("Failed to load BotGuard", error);
2555
2604
  return err(createError("BOTGUARD_INIT_FAILED", `Failed to load BotGuard: ${error.message}`, error));
2556
2605
  }
2557
2606
  }
@@ -2607,6 +2656,7 @@ var BotGuardClient = class BotGuardClient {
2607
2656
  }
2608
2657
  }
2609
2658
  async snapshotWithSignalOutput(binding) {
2659
+ log$3.info("Generating snapshot with signal output...");
2610
2660
  const webPoSignalOutput = [];
2611
2661
  const snapshotArgs = [
2612
2662
  binding,
@@ -2616,10 +2666,17 @@ var BotGuardClient = class BotGuardClient {
2616
2666
  ];
2617
2667
  try {
2618
2668
  let snapshot;
2619
- if (this.syncSnapshotFunction) snapshot = await this.syncSnapshotFunction(snapshotArgs);
2620
- else {
2669
+ if (this.syncSnapshotFunction) {
2670
+ log$3.debug("Using sync snapshot function");
2671
+ snapshot = await this.syncSnapshotFunction(snapshotArgs);
2672
+ } else {
2673
+ log$3.debug("Using async snapshot function, waiting for VM functions...");
2621
2674
  const vmFunctions = await Promise.race([this.deferredVmFunctions.promise, new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error("Timeout waiting for VM functions")), this.snapshotTimeout))]);
2622
- if (!vmFunctions.asyncSnapshotFunction) return err(createError("BOTGUARD_SNAPSHOT_FAILED", "No snapshot function available"));
2675
+ if (!vmFunctions.asyncSnapshotFunction) {
2676
+ log$3.error("No snapshot function available in VM");
2677
+ return err(createError("BOTGUARD_SNAPSHOT_FAILED", "No snapshot function available"));
2678
+ }
2679
+ log$3.debug("Executing async snapshot...");
2623
2680
  snapshot = await new Promise((resolve, reject) => {
2624
2681
  const timeout = setTimeout(() => reject(/* @__PURE__ */ new Error("Snapshot timeout")), this.snapshotTimeout);
2625
2682
  vmFunctions.asyncSnapshotFunction((response) => {
@@ -2628,11 +2685,13 @@ var BotGuardClient = class BotGuardClient {
2628
2685
  }, snapshotArgs);
2629
2686
  });
2630
2687
  }
2688
+ log$3.success(`Snapshot generated (length: ${snapshot.length}, signals: ${webPoSignalOutput.length})`);
2631
2689
  return ok({
2632
2690
  snapshot,
2633
2691
  webPoSignalOutput
2634
2692
  });
2635
2693
  } catch (error) {
2694
+ log$3.error("Snapshot generation failed", error);
2636
2695
  return err(createError("BOTGUARD_SNAPSHOT_FAILED", `Snapshot failed: ${error.message}`, error));
2637
2696
  }
2638
2697
  }
@@ -2679,6 +2738,7 @@ function u8ToBase64Url$1(u8) {
2679
2738
 
2680
2739
  //#endregion
2681
2740
  //#region src/po-token/minter/web-minter.ts
2741
+ const log$2 = logger.scope("WebPoMinter");
2682
2742
  const WAA_GENERATE_IT_ENDPOINT = "https://jnn-pa.googleapis.com/$rpc/google.internal.waa.v1.Waa/GenerateIT";
2683
2743
  const GOOG_API_KEY = "AIzaSyDyT5W0Jh49F30Pqqtyfdf7pDLFKLJoAnw";
2684
2744
  const REQUEST_KEY = "O43z0dpjhgX20SCx4KAo";
@@ -2688,38 +2748,73 @@ var WebPoMinter = class WebPoMinter {
2688
2748
  this.mintCallback = mintCallback;
2689
2749
  }
2690
2750
  static async create(integrityTokenData, webPoSignalOutput) {
2751
+ log$2.info("Creating WebPoMinter...");
2691
2752
  const getMinter = webPoSignalOutput[0];
2692
- if (!getMinter || typeof getMinter !== "function") return err(createError("INTEGRITY_TOKEN_FAILED", "Minter function not found in webPoSignalOutput"));
2693
- if (!integrityTokenData.integrityToken) return err(createError("INTEGRITY_TOKEN_FAILED", "No integrity token provided"));
2753
+ if (!getMinter || typeof getMinter !== "function") {
2754
+ log$2.error("Minter function not found in webPoSignalOutput");
2755
+ return err(createError("INTEGRITY_TOKEN_FAILED", "Minter function not found in webPoSignalOutput"));
2756
+ }
2757
+ if (!integrityTokenData.integrityToken) {
2758
+ log$2.error("No integrity token provided");
2759
+ return err(createError("INTEGRITY_TOKEN_FAILED", "No integrity token provided"));
2760
+ }
2694
2761
  try {
2695
- const mintCallback = await getMinter(base64ToU8(integrityTokenData.integrityToken));
2696
- if (typeof mintCallback !== "function") return err(createError("INTEGRITY_TOKEN_FAILED", "Invalid mint callback returned"));
2762
+ log$2.debug(`Decoding integrity token (length: ${integrityTokenData.integrityToken.length})...`);
2763
+ const integrityTokenBytes = base64ToU8(integrityTokenData.integrityToken);
2764
+ log$2.debug("Calling getMinter with integrity token bytes...");
2765
+ const mintCallback = await getMinter(integrityTokenBytes);
2766
+ if (typeof mintCallback !== "function") {
2767
+ log$2.error("Invalid mint callback returned (not a function)");
2768
+ return err(createError("INTEGRITY_TOKEN_FAILED", "Invalid mint callback returned"));
2769
+ }
2770
+ log$2.success("WebPoMinter created successfully");
2697
2771
  return ok(new WebPoMinter(mintCallback));
2698
2772
  } catch (error) {
2773
+ log$2.error("Failed to create minter", error);
2699
2774
  return err(createError("INTEGRITY_TOKEN_FAILED", `Failed to create minter: ${error.message}`, error));
2700
2775
  }
2701
2776
  }
2702
2777
  async mint(identifier) {
2778
+ log$2.debug(`Minting for identifier: ${identifier.substring(0, 30)}...`);
2703
2779
  try {
2704
2780
  const identifierBytes = new TextEncoder().encode(identifier);
2705
2781
  const result = await this.mintCallback(identifierBytes);
2706
- if (!result) return err(createError("INTEGRITY_TOKEN_FAILED", "Mint returned undefined"));
2707
- if (result instanceof Uint8Array) return ok(result);
2708
- if (ArrayBuffer.isView(result)) return ok(new Uint8Array(result.buffer));
2709
- if (Array.isArray(result)) return ok(new Uint8Array(result));
2782
+ if (!result) {
2783
+ log$2.error("Mint returned undefined");
2784
+ return err(createError("INTEGRITY_TOKEN_FAILED", "Mint returned undefined"));
2785
+ }
2786
+ if (result instanceof Uint8Array) {
2787
+ log$2.debug(`Mint successful (Uint8Array, ${result.length} bytes)`);
2788
+ return ok(result);
2789
+ }
2790
+ if (ArrayBuffer.isView(result)) {
2791
+ log$2.debug(`Mint successful (ArrayBufferView, ${result.buffer.byteLength} bytes)`);
2792
+ return ok(new Uint8Array(result.buffer));
2793
+ }
2794
+ if (Array.isArray(result)) {
2795
+ log$2.debug(`Mint successful (Array, ${result.length} bytes)`);
2796
+ return ok(new Uint8Array(result));
2797
+ }
2798
+ log$2.error(`Mint returned invalid type: ${typeof result}`);
2710
2799
  return err(createError("INTEGRITY_TOKEN_FAILED", `Mint returned invalid type: ${typeof result}`));
2711
2800
  } catch (error) {
2801
+ log$2.error("Mint failed", error);
2712
2802
  return err(createError("INTEGRITY_TOKEN_FAILED", `Mint failed: ${error.message}`, error));
2713
2803
  }
2714
2804
  }
2715
2805
  async mintAsWebsafeString(identifier) {
2806
+ log$2.info(`Minting as websafe string for: ${identifier.substring(0, 30)}...`);
2716
2807
  const mintResult = await this.mint(identifier);
2717
2808
  if (!isOk(mintResult)) return mintResult;
2718
- return ok(u8ToBase64Url(mintResult.value));
2809
+ const token = u8ToBase64Url(mintResult.value);
2810
+ log$2.success(`Websafe token generated (length: ${token.length})`);
2811
+ return ok(token);
2719
2812
  }
2720
2813
  };
2721
2814
  async function fetchIntegrityToken(botguardResponse, options = {}) {
2722
2815
  const timeout = options.timeout ?? 1e4;
2816
+ log$2.info("Fetching integrity token from GenerateIT...");
2817
+ log$2.debug(`BotGuard response length: ${botguardResponse.length}, timeout: ${timeout}ms`);
2723
2818
  try {
2724
2819
  const response = await fetch(WAA_GENERATE_IT_ENDPOINT, {
2725
2820
  method: "POST",
@@ -2730,13 +2825,21 @@ async function fetchIntegrityToken(botguardResponse, options = {}) {
2730
2825
  body: JSON.stringify([REQUEST_KEY, botguardResponse]),
2731
2826
  signal: AbortSignal.timeout(timeout)
2732
2827
  });
2733
- if (!response.ok) return err(createError("INTEGRITY_TOKEN_FAILED", `GenerateIT request failed with status ${response.status}`));
2828
+ log$2.debug(`GenerateIT response status: ${response.status}`);
2829
+ if (!response.ok) {
2830
+ log$2.error(`GenerateIT request failed with status ${response.status}`);
2831
+ return err(createError("INTEGRITY_TOKEN_FAILED", `GenerateIT request failed with status ${response.status}`));
2832
+ }
2734
2833
  const json = await response.json();
2735
2834
  const integrityToken = json[0];
2736
2835
  const estimatedTtlSecs = json[1];
2737
2836
  const mintRefreshThreshold = json[2];
2738
2837
  const websafeFallbackToken = json[3];
2739
- if (!integrityToken) return err(createError("INTEGRITY_TOKEN_FAILED", "No integrity token in response"));
2838
+ if (!integrityToken) {
2839
+ log$2.error("No integrity token in GenerateIT response");
2840
+ return err(createError("INTEGRITY_TOKEN_FAILED", "No integrity token in response"));
2841
+ }
2842
+ log$2.success(`Integrity token received (length: ${integrityToken.length}, TTL: ${estimatedTtlSecs}s, threshold: ${mintRefreshThreshold})`);
2740
2843
  return ok({
2741
2844
  integrityToken,
2742
2845
  estimatedTtlSecs: estimatedTtlSecs ?? 3600,
@@ -2744,7 +2847,11 @@ async function fetchIntegrityToken(botguardResponse, options = {}) {
2744
2847
  websafeFallbackToken
2745
2848
  });
2746
2849
  } catch (error) {
2747
- if (error instanceof Error && error.name === "TimeoutError") return err(createError("INTEGRITY_TOKEN_FAILED", "GenerateIT request timeout"));
2850
+ if (error instanceof Error && error.name === "TimeoutError") {
2851
+ log$2.error(`GenerateIT request timeout after ${timeout}ms`);
2852
+ return err(createError("INTEGRITY_TOKEN_FAILED", "GenerateIT request timeout"));
2853
+ }
2854
+ log$2.error("Failed to fetch integrity token", error);
2748
2855
  return err(createError("INTEGRITY_TOKEN_FAILED", "Failed to fetch integrity token", error));
2749
2856
  }
2750
2857
  }
@@ -2761,6 +2868,7 @@ function u8ToBase64Url(u8) {
2761
2868
 
2762
2869
  //#endregion
2763
2870
  //#region src/po-token/providers/local.provider.ts
2871
+ const log$1 = logger.scope("LocalBotGuard");
2764
2872
  const REFRESH_MARGIN_MS = 600 * 1e3;
2765
2873
  var LocalBotGuardProvider = class {
2766
2874
  name = "local-botguard";
@@ -2781,19 +2889,33 @@ var LocalBotGuardProvider = class {
2781
2889
  async isAvailable() {
2782
2890
  try {
2783
2891
  await import("jsdom");
2892
+ log$1.debug("jsdom available - provider is ready");
2784
2893
  return true;
2785
- } catch {
2894
+ } catch (e) {
2895
+ log$1.warn("jsdom not available - provider disabled", e);
2786
2896
  return false;
2787
2897
  }
2788
2898
  }
2789
2899
  async generate(identifier, _binding) {
2900
+ log$1.info(`generate() called for identifier: ${identifier.substring(0, 30)}...`);
2790
2901
  const initResult = await this.ensureInitialized();
2791
- if (!isOk(initResult)) return initResult;
2792
- if (!this.minter || !this.integrityData) return err(createError("BOTGUARD_INIT_FAILED", "Minter not initialized"));
2902
+ if (!isOk(initResult)) {
2903
+ log$1.error("Initialization failed", initResult.error);
2904
+ return initResult;
2905
+ }
2906
+ if (!this.minter || !this.integrityData) {
2907
+ log$1.error("Minter or integrityData is null after initialization");
2908
+ return err(createError("BOTGUARD_INIT_FAILED", "Minter not initialized"));
2909
+ }
2910
+ log$1.info("Minting po_token...");
2793
2911
  const tokenResult = await this.minter.mintAsWebsafeString(identifier);
2794
- if (!isOk(tokenResult)) return tokenResult;
2912
+ if (!isOk(tokenResult)) {
2913
+ log$1.error("Minting failed", tokenResult.error);
2914
+ return tokenResult;
2915
+ }
2795
2916
  const now = Date.now();
2796
2917
  const ttlMs = (this.integrityData.estimatedTtlSecs ?? 43200) * 1e3;
2918
+ log$1.success(`Token minted successfully (length: ${tokenResult.value.length}, TTL: ${Math.round(ttlMs / 1e3)}s)`);
2797
2919
  return ok({
2798
2920
  token: tokenResult.value,
2799
2921
  createdAt: now,
@@ -2819,25 +2941,71 @@ var LocalBotGuardProvider = class {
2819
2941
  return result;
2820
2942
  }
2821
2943
  async initialize() {
2944
+ log$1.info("=== Starting BotGuard initialization ===");
2945
+ log$1.time("botguard-init");
2946
+ log$1.info("[1/6] Fetching WAA challenge...");
2947
+ log$1.time("waa-challenge");
2822
2948
  const challengeResult = await this.challengeFetcher.fetchFullChallenge();
2823
- if (!isOk(challengeResult)) return challengeResult;
2949
+ log$1.timeEnd("waa-challenge");
2950
+ if (!isOk(challengeResult)) {
2951
+ log$1.error("[1/6] FAILED: Could not fetch WAA challenge", challengeResult.error);
2952
+ return challengeResult;
2953
+ }
2824
2954
  this.challenge = challengeResult.value;
2955
+ log$1.success(`[1/6] Challenge received (program: ${this.challenge.program.length} bytes, globalName: ${this.challenge.globalName})`);
2956
+ log$1.info("[2/6] Fetching attestation...");
2957
+ log$1.time("attestation");
2825
2958
  const attResult = await this.challengeFetcher.fetchAttestation();
2826
- if (!isOk(attResult)) return attResult;
2959
+ log$1.timeEnd("attestation");
2960
+ if (!isOk(attResult)) {
2961
+ log$1.error("[2/6] FAILED: Could not fetch attestation", attResult.error);
2962
+ return attResult;
2963
+ }
2827
2964
  this.attestation = attResult.value;
2965
+ log$1.success(`[2/6] Attestation received (visitorData: ${this.attestation.visitorData.substring(0, 30)}...)`);
2966
+ log$1.info("[3/6] Creating BotGuard client (JSDOM VM)...");
2967
+ log$1.time("botguard-client");
2828
2968
  const clientResult = await BotGuardClient.create(this.challenge, { timeout: this.options.timeout });
2829
- if (!isOk(clientResult)) return clientResult;
2969
+ log$1.timeEnd("botguard-client");
2970
+ if (!isOk(clientResult)) {
2971
+ log$1.error("[3/6] FAILED: Could not create BotGuard client", clientResult.error);
2972
+ return clientResult;
2973
+ }
2830
2974
  this.client = clientResult.value;
2975
+ log$1.success("[3/6] BotGuard client created");
2976
+ log$1.info("[4/6] Generating BotGuard snapshot...");
2977
+ log$1.time("snapshot");
2831
2978
  const snapshotResult = await this.client.snapshotWithSignalOutput();
2832
- if (!isOk(snapshotResult)) return snapshotResult;
2979
+ log$1.timeEnd("snapshot");
2980
+ if (!isOk(snapshotResult)) {
2981
+ log$1.error("[4/6] FAILED: Could not generate snapshot", snapshotResult.error);
2982
+ return snapshotResult;
2983
+ }
2833
2984
  const { snapshot, webPoSignalOutput } = snapshotResult.value;
2985
+ log$1.success(`[4/6] Snapshot generated (length: ${snapshot.length}, signals: ${webPoSignalOutput.length})`);
2986
+ log$1.info("[5/6] Fetching integrity token from GenerateIT...");
2987
+ log$1.time("integrity-token");
2834
2988
  const integrityResult = await fetchIntegrityToken(snapshot, { timeout: this.options.timeout });
2835
- if (!isOk(integrityResult)) return integrityResult;
2989
+ log$1.timeEnd("integrity-token");
2990
+ if (!isOk(integrityResult)) {
2991
+ log$1.error("[5/6] FAILED: Could not fetch integrity token", integrityResult.error);
2992
+ return integrityResult;
2993
+ }
2836
2994
  this.integrityData = integrityResult.value;
2837
2995
  this.createdAt = Date.now();
2996
+ log$1.success(`[5/6] Integrity token received (TTL: ${this.integrityData.estimatedTtlSecs}s, refreshThreshold: ${this.integrityData.mintRefreshThreshold})`);
2997
+ log$1.info("[6/6] Creating WebPoMinter...");
2998
+ log$1.time("minter-create");
2838
2999
  const minterResult = await WebPoMinter.create(this.integrityData, webPoSignalOutput);
2839
- if (!isOk(minterResult)) return minterResult;
3000
+ log$1.timeEnd("minter-create");
3001
+ if (!isOk(minterResult)) {
3002
+ log$1.error("[6/6] FAILED: Could not create WebPoMinter", minterResult.error);
3003
+ return minterResult;
3004
+ }
2840
3005
  this.minter = minterResult.value;
3006
+ log$1.success("[6/6] WebPoMinter created");
3007
+ log$1.timeEnd("botguard-init");
3008
+ log$1.success("=== BotGuard initialization COMPLETE ===");
2841
3009
  return ok(void 0);
2842
3010
  }
2843
3011
  reset() {
@@ -3005,6 +3173,7 @@ var TokenCache = class {
3005
3173
 
3006
3174
  //#endregion
3007
3175
  //#region src/po-token/manager.ts
3176
+ const log = logger.scope("PoTokenManager");
3008
3177
  var PoTokenManager = class {
3009
3178
  staticToken;
3010
3179
  policies;
@@ -3018,22 +3187,53 @@ var PoTokenManager = class {
3018
3187
  if (config.cacheEnabled !== false && config.cachePath) this.cache = new TokenCache(config.cachePath);
3019
3188
  }
3020
3189
  async getToken(identifier, client = "WEB", binding) {
3021
- if (this.staticToken) return ok(this.staticToken);
3022
- if (!this.isRequired(client)) return ok("");
3190
+ log.info(`getToken called`, {
3191
+ identifier: identifier.substring(0, 20) + "...",
3192
+ client,
3193
+ hasBinding: !!binding
3194
+ });
3195
+ if (this.staticToken) {
3196
+ log.debug(`Using static token (length: ${this.staticToken.length})`);
3197
+ return ok(this.staticToken);
3198
+ }
3199
+ if (!this.isRequired(client)) {
3200
+ log.debug(`Token not required for client ${client}`);
3201
+ return ok("");
3202
+ }
3023
3203
  const context = binding ? "GVS" : "GVS";
3024
3204
  if (this.cache) {
3025
3205
  const cachedResult = this.cache.get(identifier, client, context);
3026
- if (isOk(cachedResult) && cachedResult.value && cachedResult.value.expiresAt > Date.now()) return ok(cachedResult.value.token);
3027
- }
3028
- for (const provider of this.providers) {
3029
- if (!await provider.isAvailable()) continue;
3206
+ if (isOk(cachedResult) && cachedResult.value && cachedResult.value.expiresAt > Date.now()) {
3207
+ log.success(`Cache HIT - using cached token (expires in ${Math.round((cachedResult.value.expiresAt - Date.now()) / 1e3)}s)`);
3208
+ return ok(cachedResult.value.token);
3209
+ }
3210
+ log.debug(`Cache MISS - need to generate new token`);
3211
+ }
3212
+ log.info(`Trying ${this.providers.length} provider(s) to generate token`);
3213
+ for (let i = 0; i < this.providers.length; i++) {
3214
+ const provider = this.providers[i];
3215
+ const providerName = provider.constructor.name;
3216
+ log.debug(`Checking provider ${i + 1}/${this.providers.length}: ${providerName}`);
3217
+ if (!await provider.isAvailable()) {
3218
+ log.warn(`Provider ${providerName} not available, skipping`);
3219
+ continue;
3220
+ }
3221
+ log.info(`Provider ${providerName} available, generating token...`);
3030
3222
  const result = await provider.generate(identifier, binding);
3031
3223
  if (isOk(result)) {
3032
- if (this.cache) this.cache.set(result.value);
3224
+ log.success(`Provider ${providerName} generated token successfully (length: ${result.value.token.length})`);
3225
+ if (this.cache) {
3226
+ this.cache.set(result.value);
3227
+ log.debug(`Token cached`);
3228
+ }
3033
3229
  return ok(result.value.token);
3034
3230
  }
3231
+ log.warn(`Provider ${providerName} failed to generate token`);
3035
3232
  }
3036
- return ok(generateColdStartToken(identifier));
3233
+ log.warn(`All providers failed, generating cold start token`);
3234
+ const coldToken = generateColdStartToken(identifier);
3235
+ log.info(`Cold start token generated (length: ${coldToken.length})`);
3236
+ return ok(coldToken);
3037
3237
  }
3038
3238
  async getTokenData(identifier, client = "WEB", binding) {
3039
3239
  if (this.staticToken) return ok({