notebooklm-sdk 0.3.1 → 0.3.3
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 +22 -9
- package/dist/{auth-Dxsm8894.d.cts → auth-BlG6x47F.d.cts} +2 -1
- package/dist/{auth-Dxsm8894.d.ts → auth-BlG6x47F.d.ts} +2 -1
- package/dist/auth.cjs +7 -0
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +2 -2
- package/dist/auth.d.ts +2 -2
- package/dist/auth.js +7 -1
- package/dist/auth.js.map +1 -1
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js.map +1 -1
- package/dist/index.cjs +588 -400
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -7
- package/dist/index.d.ts +31 -7
- package/dist/index.js +540 -373
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -311,356 +311,176 @@ var init_enums = __esm({
|
|
|
311
311
|
}
|
|
312
312
|
});
|
|
313
313
|
|
|
314
|
+
// src/api/artifacts.ts
|
|
315
|
+
init_enums();
|
|
316
|
+
|
|
314
317
|
// src/types/errors.ts
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
constructor(message) {
|
|
320
|
-
super(message);
|
|
321
|
-
this.name = this.constructor.name;
|
|
322
|
-
}
|
|
323
|
-
};
|
|
324
|
-
exports.NetworkError = class extends exports.NotebookLMError {
|
|
325
|
-
methodId;
|
|
326
|
-
originalError;
|
|
327
|
-
constructor(message, opts = {}) {
|
|
328
|
-
super(message);
|
|
329
|
-
this.methodId = opts.methodId;
|
|
330
|
-
this.originalError = opts.originalError;
|
|
331
|
-
}
|
|
332
|
-
};
|
|
333
|
-
exports.RPCTimeoutError = class extends exports.NetworkError {
|
|
334
|
-
};
|
|
335
|
-
exports.RPCError = class extends exports.NotebookLMError {
|
|
336
|
-
methodId;
|
|
337
|
-
rawResponse;
|
|
338
|
-
rpcCode;
|
|
339
|
-
foundIds;
|
|
340
|
-
constructor(message, opts = {}) {
|
|
341
|
-
super(message);
|
|
342
|
-
this.methodId = opts.methodId;
|
|
343
|
-
this.rawResponse = opts.rawResponse ? opts.rawResponse.slice(0, 500) : void 0;
|
|
344
|
-
this.rpcCode = opts.rpcCode;
|
|
345
|
-
this.foundIds = opts.foundIds ?? [];
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
exports.AuthError = class extends exports.RPCError {
|
|
349
|
-
};
|
|
350
|
-
exports.RateLimitError = class extends exports.RPCError {
|
|
351
|
-
retryAfter;
|
|
352
|
-
constructor(message, opts = {}) {
|
|
353
|
-
super(message, opts);
|
|
354
|
-
this.retryAfter = opts.retryAfter;
|
|
355
|
-
}
|
|
356
|
-
};
|
|
357
|
-
exports.ServerError = class extends exports.RPCError {
|
|
358
|
-
statusCode;
|
|
359
|
-
constructor(message, opts = {}) {
|
|
360
|
-
super(message, opts);
|
|
361
|
-
this.statusCode = opts.statusCode;
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
exports.ClientError = class extends exports.RPCError {
|
|
365
|
-
statusCode;
|
|
366
|
-
constructor(message, opts = {}) {
|
|
367
|
-
super(message, opts);
|
|
368
|
-
this.statusCode = opts.statusCode;
|
|
369
|
-
}
|
|
370
|
-
};
|
|
371
|
-
exports.NotebookError = class extends exports.NotebookLMError {
|
|
372
|
-
};
|
|
373
|
-
exports.NotebookNotFoundError = class extends exports.NotebookError {
|
|
374
|
-
notebookId;
|
|
375
|
-
constructor(notebookId) {
|
|
376
|
-
super(`Notebook not found: ${notebookId}`);
|
|
377
|
-
this.notebookId = notebookId;
|
|
378
|
-
}
|
|
379
|
-
};
|
|
380
|
-
exports.SourceError = class extends exports.NotebookLMError {
|
|
381
|
-
};
|
|
382
|
-
exports.SourceNotFoundError = class extends exports.SourceError {
|
|
383
|
-
sourceId;
|
|
384
|
-
constructor(sourceId) {
|
|
385
|
-
super(`Source not found: ${sourceId}`);
|
|
386
|
-
this.sourceId = sourceId;
|
|
387
|
-
}
|
|
388
|
-
};
|
|
389
|
-
exports.SourceAddError = class extends exports.SourceError {
|
|
390
|
-
url;
|
|
391
|
-
cause;
|
|
392
|
-
constructor(url, opts = {}) {
|
|
393
|
-
super(
|
|
394
|
-
opts.message ?? `Failed to add source: ${url}
|
|
395
|
-
Possible causes:
|
|
396
|
-
- URL is invalid or inaccessible
|
|
397
|
-
- Content is behind a paywall or requires authentication
|
|
398
|
-
- Rate limiting or quota exceeded`
|
|
399
|
-
);
|
|
400
|
-
this.url = url;
|
|
401
|
-
this.cause = opts.cause;
|
|
402
|
-
}
|
|
403
|
-
};
|
|
404
|
-
exports.SourceProcessingError = class extends exports.SourceError {
|
|
405
|
-
sourceId;
|
|
406
|
-
status;
|
|
407
|
-
constructor(sourceId, status = 3, message) {
|
|
408
|
-
super(message ?? `Source ${sourceId} failed to process`);
|
|
409
|
-
this.sourceId = sourceId;
|
|
410
|
-
this.status = status;
|
|
411
|
-
}
|
|
412
|
-
};
|
|
413
|
-
exports.SourceTimeoutError = class extends exports.SourceError {
|
|
414
|
-
sourceId;
|
|
415
|
-
timeout;
|
|
416
|
-
lastStatus;
|
|
417
|
-
constructor(sourceId, timeout, lastStatus) {
|
|
418
|
-
const statusInfo = lastStatus != null ? ` (last status: ${lastStatus})` : "";
|
|
419
|
-
super(`Source ${sourceId} not ready after ${timeout.toFixed(1)}s${statusInfo}`);
|
|
420
|
-
this.sourceId = sourceId;
|
|
421
|
-
this.timeout = timeout;
|
|
422
|
-
this.lastStatus = lastStatus;
|
|
423
|
-
}
|
|
424
|
-
};
|
|
425
|
-
exports.ArtifactError = class extends exports.NotebookLMError {
|
|
426
|
-
};
|
|
427
|
-
exports.ArtifactNotFoundError = class extends exports.ArtifactError {
|
|
428
|
-
artifactId;
|
|
429
|
-
artifactType;
|
|
430
|
-
constructor(artifactId, artifactType) {
|
|
431
|
-
const typeInfo = artifactType ? ` ${artifactType}` : "";
|
|
432
|
-
super(`${typeInfo.trim() || "Artifact"} ${artifactId} not found`);
|
|
433
|
-
this.artifactId = artifactId;
|
|
434
|
-
this.artifactType = artifactType;
|
|
435
|
-
}
|
|
436
|
-
};
|
|
437
|
-
exports.ArtifactNotReadyError = class extends exports.ArtifactError {
|
|
438
|
-
artifactType;
|
|
439
|
-
artifactId;
|
|
440
|
-
status;
|
|
441
|
-
constructor(artifactType, opts = {}) {
|
|
442
|
-
const base = opts.artifactId ? `${artifactType} artifact ${opts.artifactId} is not ready` : `No completed ${artifactType} found`;
|
|
443
|
-
const statusInfo = opts.status ? ` (status: ${opts.status})` : "";
|
|
444
|
-
super(`${base}${statusInfo}`);
|
|
445
|
-
this.artifactType = artifactType;
|
|
446
|
-
this.artifactId = opts.artifactId;
|
|
447
|
-
this.status = opts.status;
|
|
448
|
-
}
|
|
449
|
-
};
|
|
450
|
-
exports.ArtifactParseError = class extends exports.ArtifactError {
|
|
451
|
-
artifactType;
|
|
452
|
-
artifactId;
|
|
453
|
-
details;
|
|
454
|
-
cause;
|
|
455
|
-
constructor(artifactType, opts = {}) {
|
|
456
|
-
let msg = `Failed to parse ${artifactType} artifact`;
|
|
457
|
-
if (opts.artifactId) msg += ` ${opts.artifactId}`;
|
|
458
|
-
if (opts.details) msg += `: ${opts.details}`;
|
|
459
|
-
super(msg);
|
|
460
|
-
this.artifactType = artifactType;
|
|
461
|
-
this.artifactId = opts.artifactId;
|
|
462
|
-
this.details = opts.details;
|
|
463
|
-
this.cause = opts.cause;
|
|
464
|
-
}
|
|
465
|
-
};
|
|
466
|
-
exports.ArtifactDownloadError = class extends exports.ArtifactError {
|
|
467
|
-
artifactType;
|
|
468
|
-
artifactId;
|
|
469
|
-
details;
|
|
470
|
-
cause;
|
|
471
|
-
constructor(artifactType, opts = {}) {
|
|
472
|
-
let msg = `Failed to download ${artifactType} artifact`;
|
|
473
|
-
if (opts.artifactId) msg += ` ${opts.artifactId}`;
|
|
474
|
-
if (opts.details) msg += `: ${opts.details}`;
|
|
475
|
-
super(msg);
|
|
476
|
-
this.artifactType = artifactType;
|
|
477
|
-
this.artifactId = opts.artifactId;
|
|
478
|
-
this.details = opts.details;
|
|
479
|
-
this.cause = opts.cause;
|
|
480
|
-
}
|
|
481
|
-
};
|
|
482
|
-
exports.ChatError = class extends exports.NotebookLMError {
|
|
483
|
-
};
|
|
318
|
+
var NotebookLMError = class extends Error {
|
|
319
|
+
constructor(message) {
|
|
320
|
+
super(message);
|
|
321
|
+
this.name = this.constructor.name;
|
|
484
322
|
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
fetchTokens: () => fetchTokens,
|
|
494
|
-
loadCookiesFromFile: () => loadCookiesFromFile,
|
|
495
|
-
loadCookiesFromMap: () => loadCookiesFromMap,
|
|
496
|
-
loadCookiesFromObject: () => loadCookiesFromObject,
|
|
497
|
-
loadCookiesFromString: () => loadCookiesFromString
|
|
498
|
-
});
|
|
499
|
-
function loadCookiesFromFile(filePath) {
|
|
500
|
-
let raw;
|
|
501
|
-
try {
|
|
502
|
-
raw = fs.readFileSync(filePath, "utf-8");
|
|
503
|
-
} catch {
|
|
504
|
-
throw new exports.AuthError(`Session file not found: ${filePath}
|
|
505
|
-
Run: npx notebooklm-sdk login`);
|
|
323
|
+
};
|
|
324
|
+
var NetworkError = class extends NotebookLMError {
|
|
325
|
+
methodId;
|
|
326
|
+
originalError;
|
|
327
|
+
constructor(message, opts = {}) {
|
|
328
|
+
super(message);
|
|
329
|
+
this.methodId = opts.methodId;
|
|
330
|
+
this.originalError = opts.originalError;
|
|
506
331
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
332
|
+
};
|
|
333
|
+
var RPCTimeoutError = class extends NetworkError {
|
|
334
|
+
};
|
|
335
|
+
var RPCError = class extends NotebookLMError {
|
|
336
|
+
methodId;
|
|
337
|
+
rawResponse;
|
|
338
|
+
rpcCode;
|
|
339
|
+
foundIds;
|
|
340
|
+
constructor(message, opts = {}) {
|
|
341
|
+
super(message);
|
|
342
|
+
this.methodId = opts.methodId;
|
|
343
|
+
this.rawResponse = opts.rawResponse ? opts.rawResponse.slice(0, 500) : void 0;
|
|
344
|
+
this.rpcCode = opts.rpcCode;
|
|
345
|
+
this.foundIds = opts.foundIds ?? [];
|
|
518
346
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
const idx = part.indexOf("=");
|
|
528
|
-
if (idx > 0) {
|
|
529
|
-
const name = part.slice(0, idx).trim();
|
|
530
|
-
const value = part.slice(idx + 1).trim();
|
|
531
|
-
if (name) map[name] = value;
|
|
532
|
-
}
|
|
347
|
+
};
|
|
348
|
+
var AuthError = class extends RPCError {
|
|
349
|
+
};
|
|
350
|
+
var RateLimitError = class extends RPCError {
|
|
351
|
+
retryAfter;
|
|
352
|
+
constructor(message, opts = {}) {
|
|
353
|
+
super(message, opts);
|
|
354
|
+
this.retryAfter = opts.retryAfter;
|
|
533
355
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
if (!isAllowedDomain(domain) || !name) continue;
|
|
541
|
-
const isBase = domain === ".google.com";
|
|
542
|
-
if (!(name in cookies) || isBase) {
|
|
543
|
-
cookies[name] = value;
|
|
544
|
-
}
|
|
356
|
+
};
|
|
357
|
+
var ServerError = class extends RPCError {
|
|
358
|
+
statusCode;
|
|
359
|
+
constructor(message, opts = {}) {
|
|
360
|
+
super(message, opts);
|
|
361
|
+
this.statusCode = opts.statusCode;
|
|
545
362
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
363
|
+
};
|
|
364
|
+
var ClientError = class extends RPCError {
|
|
365
|
+
statusCode;
|
|
366
|
+
constructor(message, opts = {}) {
|
|
367
|
+
super(message, opts);
|
|
368
|
+
this.statusCode = opts.statusCode;
|
|
550
369
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
370
|
+
};
|
|
371
|
+
var NotebookError = class extends NotebookLMError {
|
|
372
|
+
};
|
|
373
|
+
var NotebookNotFoundError = class extends NotebookError {
|
|
374
|
+
notebookId;
|
|
375
|
+
constructor(notebookId) {
|
|
376
|
+
super(`Notebook not found: ${notebookId}`);
|
|
377
|
+
this.notebookId = notebookId;
|
|
556
378
|
}
|
|
557
|
-
|
|
558
|
-
|
|
379
|
+
};
|
|
380
|
+
var SourceError = class extends NotebookLMError {
|
|
381
|
+
};
|
|
382
|
+
var SourceNotFoundError = class extends SourceError {
|
|
383
|
+
sourceId;
|
|
384
|
+
constructor(sourceId) {
|
|
385
|
+
super(`Source not found: ${sourceId}`);
|
|
386
|
+
this.sourceId = sourceId;
|
|
559
387
|
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
388
|
+
};
|
|
389
|
+
var SourceAddError = class extends SourceError {
|
|
390
|
+
url;
|
|
391
|
+
cause;
|
|
392
|
+
constructor(url, opts = {}) {
|
|
393
|
+
super(
|
|
394
|
+
opts.message ?? `Failed to add source: ${url}
|
|
395
|
+
Possible causes:
|
|
396
|
+
- URL is invalid or inaccessible
|
|
397
|
+
- Content is behind a paywall or requires authentication
|
|
398
|
+
- Rate limiting or quota exceeded`
|
|
399
|
+
);
|
|
400
|
+
this.url = url;
|
|
401
|
+
this.cause = opts.cause;
|
|
573
402
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
403
|
+
};
|
|
404
|
+
var SourceProcessingError = class extends SourceError {
|
|
405
|
+
sourceId;
|
|
406
|
+
status;
|
|
407
|
+
constructor(sourceId, status = 3, message) {
|
|
408
|
+
super(message ?? `Source ${sourceId} failed to process`);
|
|
409
|
+
this.sourceId = sourceId;
|
|
410
|
+
this.status = status;
|
|
577
411
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
throw new exports.AuthError("CSRF token (SNlM0e) not found in NotebookLM page HTML.");
|
|
412
|
+
};
|
|
413
|
+
var SourceTimeoutError = class extends SourceError {
|
|
414
|
+
sourceId;
|
|
415
|
+
timeout;
|
|
416
|
+
lastStatus;
|
|
417
|
+
constructor(sourceId, timeout, lastStatus) {
|
|
418
|
+
const statusInfo = lastStatus != null ? ` (last status: ${lastStatus})` : "";
|
|
419
|
+
super(`Source ${sourceId} not ready after ${timeout.toFixed(1)}s${statusInfo}`);
|
|
420
|
+
this.sourceId = sourceId;
|
|
421
|
+
this.timeout = timeout;
|
|
422
|
+
this.lastStatus = lastStatus;
|
|
590
423
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
}
|
|
599
|
-
|
|
424
|
+
};
|
|
425
|
+
var ArtifactError = class extends NotebookLMError {
|
|
426
|
+
};
|
|
427
|
+
var ArtifactNotFoundError = class extends ArtifactError {
|
|
428
|
+
artifactId;
|
|
429
|
+
artifactType;
|
|
430
|
+
constructor(artifactId, artifactType) {
|
|
431
|
+
const typeInfo = artifactType ? ` ${artifactType}` : "";
|
|
432
|
+
super(`${typeInfo.trim() || "Artifact"} ${artifactId} not found`);
|
|
433
|
+
this.artifactId = artifactId;
|
|
434
|
+
this.artifactType = artifactType;
|
|
600
435
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
} else if (opts.cookiesObject) {
|
|
614
|
-
if ("cookies" in opts.cookiesObject && Array.isArray(opts.cookiesObject.cookies)) {
|
|
615
|
-
const storageState = opts.cookiesObject;
|
|
616
|
-
cookieMap = loadCookiesFromObject(storageState);
|
|
617
|
-
googleCookieHeader = buildGoogleCookieHeader(storageState);
|
|
618
|
-
} else {
|
|
619
|
-
cookieMap = loadCookiesFromMap(opts.cookiesObject);
|
|
620
|
-
}
|
|
621
|
-
} else {
|
|
622
|
-
const envCookies = process.env["NOTEBOOKLM_COOKIES"];
|
|
623
|
-
const envFile = process.env["NOTEBOOKLM_COOKIES_FILE"];
|
|
624
|
-
if (envFile) {
|
|
625
|
-
cookieMap = loadCookiesFromFile(envFile);
|
|
626
|
-
} else if (fs.existsSync(DEFAULT_SESSION_FILE)) {
|
|
627
|
-
const raw = fs.readFileSync(DEFAULT_SESSION_FILE, "utf-8");
|
|
628
|
-
const storageState = JSON.parse(raw);
|
|
629
|
-
cookieMap = loadCookiesFromObject(storageState);
|
|
630
|
-
googleCookieHeader = buildGoogleCookieHeader(storageState);
|
|
631
|
-
} else if (fs.existsSync("storage_state.json")) {
|
|
632
|
-
const raw = fs.readFileSync("storage_state.json", "utf-8");
|
|
633
|
-
const storageState = JSON.parse(raw);
|
|
634
|
-
cookieMap = loadCookiesFromObject(storageState);
|
|
635
|
-
googleCookieHeader = buildGoogleCookieHeader(storageState);
|
|
636
|
-
} else if (envCookies) {
|
|
637
|
-
cookieMap = loadCookiesFromString(envCookies);
|
|
638
|
-
} else {
|
|
639
|
-
throw new exports.AuthError("No session found. Run: npx notebooklm-sdk login");
|
|
640
|
-
}
|
|
436
|
+
};
|
|
437
|
+
var ArtifactNotReadyError = class extends ArtifactError {
|
|
438
|
+
artifactType;
|
|
439
|
+
artifactId;
|
|
440
|
+
status;
|
|
441
|
+
constructor(artifactType, opts = {}) {
|
|
442
|
+
const base = opts.artifactId ? `${artifactType} artifact ${opts.artifactId} is not ready` : `No completed ${artifactType} found`;
|
|
443
|
+
const statusInfo = opts.status ? ` (status: ${opts.status})` : "";
|
|
444
|
+
super(`${base}${statusInfo}`);
|
|
445
|
+
this.artifactType = artifactType;
|
|
446
|
+
this.artifactId = opts.artifactId;
|
|
447
|
+
this.status = opts.status;
|
|
641
448
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
NOTEBOOKLM_URL = "https://notebooklm.google.com/";
|
|
449
|
+
};
|
|
450
|
+
var ArtifactParseError = class extends ArtifactError {
|
|
451
|
+
artifactType;
|
|
452
|
+
artifactId;
|
|
453
|
+
details;
|
|
454
|
+
cause;
|
|
455
|
+
constructor(artifactType, opts = {}) {
|
|
456
|
+
let msg = `Failed to parse ${artifactType} artifact`;
|
|
457
|
+
if (opts.artifactId) msg += ` ${opts.artifactId}`;
|
|
458
|
+
if (opts.details) msg += `: ${opts.details}`;
|
|
459
|
+
super(msg);
|
|
460
|
+
this.artifactType = artifactType;
|
|
461
|
+
this.artifactId = opts.artifactId;
|
|
462
|
+
this.details = opts.details;
|
|
463
|
+
this.cause = opts.cause;
|
|
658
464
|
}
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
465
|
+
};
|
|
466
|
+
var ArtifactDownloadError = class extends ArtifactError {
|
|
467
|
+
artifactType;
|
|
468
|
+
artifactId;
|
|
469
|
+
details;
|
|
470
|
+
cause;
|
|
471
|
+
constructor(artifactType, opts = {}) {
|
|
472
|
+
let msg = `Failed to download ${artifactType} artifact`;
|
|
473
|
+
if (opts.artifactId) msg += ` ${opts.artifactId}`;
|
|
474
|
+
if (opts.details) msg += `: ${opts.details}`;
|
|
475
|
+
super(msg);
|
|
476
|
+
this.artifactType = artifactType;
|
|
477
|
+
this.artifactId = opts.artifactId;
|
|
478
|
+
this.details = opts.details;
|
|
479
|
+
this.cause = opts.cause;
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
var ChatError = class extends NotebookLMError {
|
|
483
|
+
};
|
|
664
484
|
|
|
665
485
|
// src/types/models.ts
|
|
666
486
|
init_enums();
|
|
@@ -1124,30 +944,49 @@ ${opts.extraInstructions}` : cfg.prompt;
|
|
|
1124
944
|
const deadline = Date.now() + timeout * 1e3;
|
|
1125
945
|
while (Date.now() < deadline) {
|
|
1126
946
|
const artifact = await this.get(notebookId, artifactId);
|
|
1127
|
-
if (artifact?.status === "completed")
|
|
947
|
+
if (artifact?.status === "completed") {
|
|
948
|
+
if (artifact.kind === "audio" && !artifact.audioUrl || artifact.kind === "video" && !artifact.videoUrl) {
|
|
949
|
+
await sleep(pollInterval * 1e3);
|
|
950
|
+
continue;
|
|
951
|
+
}
|
|
952
|
+
return artifact;
|
|
953
|
+
}
|
|
1128
954
|
if (artifact?.status === "failed") {
|
|
1129
|
-
throw new
|
|
955
|
+
throw new ArtifactNotReadyError(artifact.kind, { artifactId, status: "failed" });
|
|
1130
956
|
}
|
|
1131
957
|
await sleep(pollInterval * 1e3);
|
|
1132
958
|
}
|
|
1133
|
-
throw new
|
|
959
|
+
throw new ArtifactNotReadyError("artifact", { artifactId, status: "timeout" });
|
|
960
|
+
}
|
|
961
|
+
/** Get the current status of a generated artifact without waiting. */
|
|
962
|
+
async pollStatus(notebookId, artifactId) {
|
|
963
|
+
const rawList = await this._listRaw(notebookId);
|
|
964
|
+
for (const item of rawList) {
|
|
965
|
+
if (!Array.isArray(item) || item[0] !== artifactId) continue;
|
|
966
|
+
const statusCode = typeof item[4] === "number" ? item[4] : null;
|
|
967
|
+
return {
|
|
968
|
+
artifactId,
|
|
969
|
+
status: statusCode != null ? artifactStatusFromCode(statusCode) : "pending"
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
return { artifactId, status: "pending" };
|
|
1134
973
|
}
|
|
1135
974
|
/** Download audio content as a Buffer. */
|
|
1136
975
|
async downloadAudio(notebookId, artifactId) {
|
|
1137
976
|
const artifact = await this.get(notebookId, artifactId);
|
|
1138
977
|
if (!artifact || artifact.status !== "completed") {
|
|
1139
|
-
throw new
|
|
978
|
+
throw new ArtifactNotReadyError("audio", { artifactId, status: artifact?.status });
|
|
1140
979
|
}
|
|
1141
|
-
if (!artifact.audioUrl) throw new
|
|
980
|
+
if (!artifact.audioUrl) throw new ArtifactNotReadyError("audio", { artifactId });
|
|
1142
981
|
return this._fetchMediaWithCookies(artifact.audioUrl);
|
|
1143
982
|
}
|
|
1144
983
|
/** Download video content as a Buffer. */
|
|
1145
984
|
async downloadVideo(notebookId, artifactId) {
|
|
1146
985
|
const artifact = await this.get(notebookId, artifactId);
|
|
1147
986
|
if (!artifact || artifact.status !== "completed") {
|
|
1148
|
-
throw new
|
|
987
|
+
throw new ArtifactNotReadyError("video", { artifactId, status: artifact?.status });
|
|
1149
988
|
}
|
|
1150
|
-
if (!artifact.videoUrl) throw new
|
|
989
|
+
if (!artifact.videoUrl) throw new ArtifactNotReadyError("video", { artifactId });
|
|
1151
990
|
return this._fetchMediaWithCookies(artifact.videoUrl);
|
|
1152
991
|
}
|
|
1153
992
|
/** Get markdown content for a completed report artifact. */
|
|
@@ -1176,12 +1015,12 @@ ${opts.extraInstructions}` : cfg.prompt;
|
|
|
1176
1015
|
const raw = rawList.find(
|
|
1177
1016
|
(a) => a[0] === artifactId && a[2] === exports.ArtifactTypeCode.SLIDE_DECK
|
|
1178
1017
|
);
|
|
1179
|
-
if (!raw) throw new
|
|
1018
|
+
if (!raw) throw new ArtifactNotReadyError("slide_deck", { artifactId });
|
|
1180
1019
|
const metadata = raw[16];
|
|
1181
|
-
if (!Array.isArray(metadata)) throw new
|
|
1020
|
+
if (!Array.isArray(metadata)) throw new ArtifactNotReadyError("slide_deck", { artifactId });
|
|
1182
1021
|
const url = format === "pptx" ? metadata[4] : metadata[3];
|
|
1183
1022
|
if (typeof url !== "string" || !url.startsWith("http")) {
|
|
1184
|
-
throw new
|
|
1023
|
+
throw new ArtifactNotReadyError("slide_deck", { artifactId, status: `no ${format} url` });
|
|
1185
1024
|
}
|
|
1186
1025
|
return this._fetchMediaWithCookies(url);
|
|
1187
1026
|
}
|
|
@@ -1191,7 +1030,7 @@ ${opts.extraInstructions}` : cfg.prompt;
|
|
|
1191
1030
|
const raw = rawList.find(
|
|
1192
1031
|
(a) => a[0] === artifactId && a[2] === exports.ArtifactTypeCode.INFOGRAPHIC
|
|
1193
1032
|
);
|
|
1194
|
-
if (!raw) throw new
|
|
1033
|
+
if (!raw) throw new ArtifactNotReadyError("infographic", { artifactId });
|
|
1195
1034
|
let url = null;
|
|
1196
1035
|
for (let i = raw.length - 1; i >= 0; i--) {
|
|
1197
1036
|
const item = raw[i];
|
|
@@ -1200,7 +1039,7 @@ ${opts.extraInstructions}` : cfg.prompt;
|
|
|
1200
1039
|
break;
|
|
1201
1040
|
}
|
|
1202
1041
|
}
|
|
1203
|
-
if (!url) throw new
|
|
1042
|
+
if (!url) throw new ArtifactNotReadyError("infographic", { artifactId });
|
|
1204
1043
|
return this._fetchMediaWithCookies(url);
|
|
1205
1044
|
}
|
|
1206
1045
|
/** Get AI-suggested report formats based on notebook content. */
|
|
@@ -1247,6 +1086,24 @@ ${opts.extraInstructions}` : cfg.prompt;
|
|
|
1247
1086
|
}
|
|
1248
1087
|
// ---------------------------------------------------------------------------
|
|
1249
1088
|
// Internal
|
|
1089
|
+
/** Export a completed report artifact to Google Docs. Returns the created document URL. */
|
|
1090
|
+
async exportReport(notebookId, artifactId, title) {
|
|
1091
|
+
const params = [null, artifactId, null, title, exports.ExportType.DOCS];
|
|
1092
|
+
const result = await this.rpc.call(exports.RPCMethod.EXPORT_ARTIFACT, params, {
|
|
1093
|
+
sourcePath: `/notebook/${notebookId}`,
|
|
1094
|
+
allowNull: true
|
|
1095
|
+
});
|
|
1096
|
+
return extractExportUrl(result);
|
|
1097
|
+
}
|
|
1098
|
+
/** Export a completed data table artifact to Google Sheets. Returns the created spreadsheet URL. */
|
|
1099
|
+
async exportDataTable(notebookId, artifactId, title) {
|
|
1100
|
+
const params = [null, artifactId, null, title, exports.ExportType.SHEETS];
|
|
1101
|
+
const result = await this.rpc.call(exports.RPCMethod.EXPORT_ARTIFACT, params, {
|
|
1102
|
+
sourcePath: `/notebook/${notebookId}`,
|
|
1103
|
+
allowNull: true
|
|
1104
|
+
});
|
|
1105
|
+
return extractExportUrl(result);
|
|
1106
|
+
}
|
|
1250
1107
|
// ---------------------------------------------------------------------------
|
|
1251
1108
|
/**
|
|
1252
1109
|
* Fetch a Google-hosted media URL, manually following redirects to ensure
|
|
@@ -1329,6 +1186,21 @@ function parseDataTable(rawData) {
|
|
|
1329
1186
|
throw new Error(`Failed to parse data table: ${e}`);
|
|
1330
1187
|
}
|
|
1331
1188
|
}
|
|
1189
|
+
function extractExportUrl(result) {
|
|
1190
|
+
if (!Array.isArray(result)) return null;
|
|
1191
|
+
function findUrl(data, depth = 5) {
|
|
1192
|
+
if (depth <= 0 || data == null) return null;
|
|
1193
|
+
if (typeof data === "string" && data.startsWith("https://")) return data;
|
|
1194
|
+
if (Array.isArray(data)) {
|
|
1195
|
+
for (const item of data) {
|
|
1196
|
+
const found = findUrl(item, depth - 1);
|
|
1197
|
+
if (found) return found;
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
return null;
|
|
1201
|
+
}
|
|
1202
|
+
return findUrl(result);
|
|
1203
|
+
}
|
|
1332
1204
|
function sleep(ms) {
|
|
1333
1205
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1334
1206
|
}
|
|
@@ -1349,14 +1221,14 @@ function isTrustedDomain(url) {
|
|
|
1349
1221
|
|
|
1350
1222
|
// src/api/chat.ts
|
|
1351
1223
|
init_enums();
|
|
1352
|
-
init_errors();
|
|
1353
1224
|
var QUERY_URL = "https://notebooklm.google.com/_/LabsTailwindUi/data/google.internal.labs.tailwind.orchestration.v1.LabsTailwindOrchestrationService/GenerateFreeFormStreamed";
|
|
1354
1225
|
var DEFAULT_BL = "boq_labs-tailwind-frontend_20260301.03_p0";
|
|
1355
1226
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
1356
1227
|
var ChatAPI = class {
|
|
1357
|
-
constructor(rpc, auth) {
|
|
1228
|
+
constructor(rpc, auth, refreshAuth) {
|
|
1358
1229
|
this.rpc = rpc;
|
|
1359
1230
|
this.auth = auth;
|
|
1231
|
+
this.refreshAuth = refreshAuth;
|
|
1360
1232
|
}
|
|
1361
1233
|
conversationCache = /* @__PURE__ */ new Map();
|
|
1362
1234
|
reqid = Math.floor(Math.random() * 9e5) + 1e5;
|
|
@@ -1386,20 +1258,7 @@ var ChatAPI = class {
|
|
|
1386
1258
|
const bodyParts = [`f.req=${encodeURIComponent(fReq)}`];
|
|
1387
1259
|
if (this.auth.csrfToken) bodyParts.push(`at=${encodeURIComponent(this.auth.csrfToken)}`);
|
|
1388
1260
|
const body = bodyParts.join("&") + "&";
|
|
1389
|
-
|
|
1390
|
-
try {
|
|
1391
|
-
response = await fetch(`${QUERY_URL}?${urlParams.toString()}`, {
|
|
1392
|
-
method: "POST",
|
|
1393
|
-
headers: {
|
|
1394
|
-
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
|
|
1395
|
-
Cookie: this.auth.cookieHeader
|
|
1396
|
-
},
|
|
1397
|
-
body
|
|
1398
|
-
});
|
|
1399
|
-
} catch (e) {
|
|
1400
|
-
throw new exports.ChatError(`Chat request failed: ${String(e)}`);
|
|
1401
|
-
}
|
|
1402
|
-
if (!response.ok) throw new exports.ChatError(`Chat request failed: HTTP ${response.status}`);
|
|
1261
|
+
const response = await this._postChatRequest(`${QUERY_URL}?${urlParams.toString()}`, body);
|
|
1403
1262
|
const text = await response.text();
|
|
1404
1263
|
const { answer, conversationId: serverConvId, references } = parseStreamingResponse(text);
|
|
1405
1264
|
const finalConvId = serverConvId ?? conversationId;
|
|
@@ -1459,12 +1318,47 @@ var ChatAPI = class {
|
|
|
1459
1318
|
}
|
|
1460
1319
|
return null;
|
|
1461
1320
|
}
|
|
1321
|
+
async getHistory(notebookId, limit = 100, conversationId) {
|
|
1322
|
+
const convId = conversationId ?? await this.getLastConversationId(notebookId);
|
|
1323
|
+
if (!convId) return [];
|
|
1324
|
+
const params = [[], null, null, convId, limit];
|
|
1325
|
+
const result = await this.rpc.call(exports.RPCMethod.GET_CONVERSATION_TURNS, params, {
|
|
1326
|
+
sourcePath: `/notebook/${notebookId}`,
|
|
1327
|
+
allowNull: true
|
|
1328
|
+
});
|
|
1329
|
+
if (!Array.isArray(result) || !Array.isArray(result[0])) return [];
|
|
1330
|
+
const rawTurns = [...result[0]].reverse();
|
|
1331
|
+
const history = [];
|
|
1332
|
+
let i = 0;
|
|
1333
|
+
while (i < rawTurns.length) {
|
|
1334
|
+
const turn = rawTurns[i];
|
|
1335
|
+
if (!Array.isArray(turn) || turn.length < 3) {
|
|
1336
|
+
i++;
|
|
1337
|
+
continue;
|
|
1338
|
+
}
|
|
1339
|
+
if (turn[2] === 1 && turn.length > 3) {
|
|
1340
|
+
const query = typeof turn[3] === "string" ? turn[3] : "";
|
|
1341
|
+
let answer = "";
|
|
1342
|
+
const next = rawTurns[i + 1];
|
|
1343
|
+
if (Array.isArray(next) && next.length > 4 && next[2] === 2) {
|
|
1344
|
+
try {
|
|
1345
|
+
answer = String(next[4][0][0] ?? "");
|
|
1346
|
+
} catch {
|
|
1347
|
+
}
|
|
1348
|
+
i++;
|
|
1349
|
+
}
|
|
1350
|
+
history.push([query, answer]);
|
|
1351
|
+
}
|
|
1352
|
+
i++;
|
|
1353
|
+
}
|
|
1354
|
+
return history;
|
|
1355
|
+
}
|
|
1462
1356
|
/**
|
|
1463
1357
|
* Low-level chat configuration. Set goal, response length, and optional
|
|
1464
1358
|
* custom instructions directly. Persists on the server per notebook.
|
|
1465
1359
|
* Use `setMode()` for preset combinations instead.
|
|
1466
1360
|
*/
|
|
1467
|
-
async configure(notebookId, goal, length, customPrompt) {
|
|
1361
|
+
async configure(notebookId, goal = exports.ChatGoal.DEFAULT, length = exports.ChatResponseLength.DEFAULT, customPrompt) {
|
|
1468
1362
|
if (goal === exports.ChatGoal.CUSTOM && !customPrompt) {
|
|
1469
1363
|
throw new Error("customPrompt is required when goal is ChatGoal.CUSTOM");
|
|
1470
1364
|
}
|
|
@@ -1496,6 +1390,14 @@ var ChatAPI = class {
|
|
|
1496
1390
|
this.conversationCache.clear();
|
|
1497
1391
|
}
|
|
1498
1392
|
}
|
|
1393
|
+
getCachedTurns(conversationId) {
|
|
1394
|
+
const turns = this.conversationCache.get(conversationId) ?? [];
|
|
1395
|
+
return turns.map((turn) => ({
|
|
1396
|
+
query: turn.query,
|
|
1397
|
+
answer: turn.answer,
|
|
1398
|
+
turnNumber: turn.turnNumber
|
|
1399
|
+
}));
|
|
1400
|
+
}
|
|
1499
1401
|
_buildHistory(conversationId) {
|
|
1500
1402
|
const turns = this.conversationCache.get(conversationId) ?? [];
|
|
1501
1403
|
if (!turns.length) return null;
|
|
@@ -1506,6 +1408,27 @@ var ChatAPI = class {
|
|
|
1506
1408
|
}
|
|
1507
1409
|
return history;
|
|
1508
1410
|
}
|
|
1411
|
+
async _postChatRequest(url, body, retried = false) {
|
|
1412
|
+
let response;
|
|
1413
|
+
try {
|
|
1414
|
+
response = await fetch(url, {
|
|
1415
|
+
method: "POST",
|
|
1416
|
+
headers: {
|
|
1417
|
+
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
|
|
1418
|
+
Cookie: this.auth.cookieHeader
|
|
1419
|
+
},
|
|
1420
|
+
body
|
|
1421
|
+
});
|
|
1422
|
+
} catch (e) {
|
|
1423
|
+
throw new ChatError(`Chat request failed: ${String(e)}`);
|
|
1424
|
+
}
|
|
1425
|
+
if ((response.status === 401 || response.status === 403) && !retried && this.refreshAuth) {
|
|
1426
|
+
await this.refreshAuth();
|
|
1427
|
+
return this._postChatRequest(url, body, true);
|
|
1428
|
+
}
|
|
1429
|
+
if (!response.ok) throw new ChatError(`Chat request failed: HTTP ${response.status}`);
|
|
1430
|
+
return response;
|
|
1431
|
+
}
|
|
1509
1432
|
};
|
|
1510
1433
|
function parseStreamingResponse(rawText) {
|
|
1511
1434
|
let text = rawText;
|
|
@@ -1662,6 +1585,12 @@ var NotebooksAPI = class {
|
|
|
1662
1585
|
async removeFromRecent(notebookId) {
|
|
1663
1586
|
await this.rpc.call(exports.RPCMethod.REMOVE_RECENTLY_VIEWED, [notebookId], { allowNull: true });
|
|
1664
1587
|
}
|
|
1588
|
+
async getRaw(notebookId) {
|
|
1589
|
+
const params = [notebookId, null, [2], null, 0];
|
|
1590
|
+
return this.rpc.call(exports.RPCMethod.GET_NOTEBOOK, params, {
|
|
1591
|
+
sourcePath: `/notebook/${notebookId}`
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1665
1594
|
async getDescription(notebookId) {
|
|
1666
1595
|
const params = [notebookId, [2]];
|
|
1667
1596
|
const result = await this.rpc.call(exports.RPCMethod.SUMMARIZE, params, {
|
|
@@ -1689,6 +1618,41 @@ var NotebooksAPI = class {
|
|
|
1689
1618
|
}
|
|
1690
1619
|
return { summary, suggestedTopics };
|
|
1691
1620
|
}
|
|
1621
|
+
async share(notebookId, publicAccess = true, artifactId) {
|
|
1622
|
+
const shareOptions = publicAccess ? [1] : [0];
|
|
1623
|
+
const params = artifactId ? [shareOptions, notebookId, artifactId] : [shareOptions, notebookId];
|
|
1624
|
+
await this.rpc.call(exports.RPCMethod.SHARE_ARTIFACT, params, {
|
|
1625
|
+
sourcePath: `/notebook/${notebookId}`,
|
|
1626
|
+
allowNull: true
|
|
1627
|
+
});
|
|
1628
|
+
return {
|
|
1629
|
+
public: publicAccess,
|
|
1630
|
+
url: publicAccess ? this.getShareUrl(notebookId, artifactId) : null,
|
|
1631
|
+
artifactId: artifactId ?? null
|
|
1632
|
+
};
|
|
1633
|
+
}
|
|
1634
|
+
getShareUrl(notebookId, artifactId) {
|
|
1635
|
+
const baseUrl = `https://notebooklm.google.com/notebook/${notebookId}`;
|
|
1636
|
+
return artifactId ? `${baseUrl}?artifactId=${artifactId}` : baseUrl;
|
|
1637
|
+
}
|
|
1638
|
+
async getMetadata(notebookId) {
|
|
1639
|
+
const raw = await this.getRaw(notebookId);
|
|
1640
|
+
const notebookData = Array.isArray(raw) && raw.length > 0 && Array.isArray(raw[0]) ? raw[0] : [];
|
|
1641
|
+
const notebook = parseNotebook(notebookData);
|
|
1642
|
+
const sourcesRaw = Array.isArray(notebookData[1]) ? notebookData[1] : [];
|
|
1643
|
+
const sources = sourcesRaw.filter((source) => Array.isArray(source) && source.length > 0).map((source) => parseSource(source));
|
|
1644
|
+
return {
|
|
1645
|
+
id: notebook.id,
|
|
1646
|
+
title: notebook.title,
|
|
1647
|
+
createdAt: notebook.createdAt,
|
|
1648
|
+
isOwner: notebook.isOwner,
|
|
1649
|
+
sources: sources.map((source) => ({
|
|
1650
|
+
kind: source.kind,
|
|
1651
|
+
title: source.title,
|
|
1652
|
+
url: source.url
|
|
1653
|
+
}))
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1692
1656
|
};
|
|
1693
1657
|
|
|
1694
1658
|
// src/api/notes.ts
|
|
@@ -1701,6 +1665,10 @@ var NotesAPI = class {
|
|
|
1701
1665
|
const all = await this._fetchAll(notebookId);
|
|
1702
1666
|
return all.filter((n) => !this._isMindMap(n.content));
|
|
1703
1667
|
}
|
|
1668
|
+
async get(notebookId, noteId) {
|
|
1669
|
+
const all = await this._fetchAll(notebookId);
|
|
1670
|
+
return all.find((note) => note.id === noteId) ?? null;
|
|
1671
|
+
}
|
|
1704
1672
|
async listMindMaps(notebookId) {
|
|
1705
1673
|
const all = await this._fetchAll(notebookId);
|
|
1706
1674
|
return all.filter((n) => this._isMindMap(n.content));
|
|
@@ -1732,6 +1700,9 @@ var NotesAPI = class {
|
|
|
1732
1700
|
});
|
|
1733
1701
|
return true;
|
|
1734
1702
|
}
|
|
1703
|
+
async deleteMindMap(notebookId, mindMapId) {
|
|
1704
|
+
return this.delete(notebookId, mindMapId);
|
|
1705
|
+
}
|
|
1735
1706
|
async _fetchAll(notebookId) {
|
|
1736
1707
|
const result = await this.rpc.call(exports.RPCMethod.GET_NOTES_AND_MIND_MAPS, [notebookId], {
|
|
1737
1708
|
sourcePath: `/notebook/${notebookId}`,
|
|
@@ -2108,7 +2079,6 @@ function parseShareStatus(data, notebookId) {
|
|
|
2108
2079
|
|
|
2109
2080
|
// src/api/sources.ts
|
|
2110
2081
|
init_enums();
|
|
2111
|
-
init_errors();
|
|
2112
2082
|
var UPLOAD_URL = "https://notebooklm.google.com/upload/_/";
|
|
2113
2083
|
var SourcesAPI = class {
|
|
2114
2084
|
constructor(rpc, auth) {
|
|
@@ -2391,6 +2361,29 @@ var SourcesAPI = class {
|
|
|
2391
2361
|
});
|
|
2392
2362
|
return true;
|
|
2393
2363
|
}
|
|
2364
|
+
async rename(notebookId, sourceId, newTitle) {
|
|
2365
|
+
const params = [null, [sourceId], [[[newTitle]]]];
|
|
2366
|
+
const result = await this.rpc.call(exports.RPCMethod.UPDATE_SOURCE, params, {
|
|
2367
|
+
sourcePath: `/notebook/${notebookId}`,
|
|
2368
|
+
allowNull: true
|
|
2369
|
+
});
|
|
2370
|
+
if (Array.isArray(result) && result.length > 0) {
|
|
2371
|
+
try {
|
|
2372
|
+
const parsed = parseSource(result);
|
|
2373
|
+
return parsed.title ? parsed : { ...parsed, title: newTitle };
|
|
2374
|
+
} catch {
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
return {
|
|
2378
|
+
id: sourceId,
|
|
2379
|
+
title: newTitle,
|
|
2380
|
+
url: null,
|
|
2381
|
+
kind: "unknown",
|
|
2382
|
+
createdAt: null,
|
|
2383
|
+
status: "ready",
|
|
2384
|
+
_typeCode: null
|
|
2385
|
+
};
|
|
2386
|
+
}
|
|
2394
2387
|
async waitUntilReady(notebookId, sourceId, timeout = 120, initialInterval = 1, maxInterval = 10, backoffFactor = 1.5) {
|
|
2395
2388
|
const deadline = Date.now() + timeout * 1e3;
|
|
2396
2389
|
let interval = initialInterval;
|
|
@@ -2400,14 +2393,28 @@ var SourcesAPI = class {
|
|
|
2400
2393
|
if (source) {
|
|
2401
2394
|
if (source.status === "ready") return source;
|
|
2402
2395
|
if (source.status === "error") {
|
|
2403
|
-
throw new
|
|
2396
|
+
throw new SourceProcessingError(sourceId, 3);
|
|
2404
2397
|
}
|
|
2405
2398
|
lastStatus = source._typeCode ?? void 0;
|
|
2406
2399
|
}
|
|
2407
2400
|
await sleep2(interval * 1e3);
|
|
2408
2401
|
interval = Math.min(interval * backoffFactor, maxInterval);
|
|
2409
2402
|
}
|
|
2410
|
-
throw new
|
|
2403
|
+
throw new SourceTimeoutError(sourceId, timeout, lastStatus);
|
|
2404
|
+
}
|
|
2405
|
+
async waitForSources(notebookId, sourceIds, timeout = 120, initialInterval = 1, maxInterval = 10, backoffFactor = 1.5) {
|
|
2406
|
+
return Promise.all(
|
|
2407
|
+
sourceIds.map(
|
|
2408
|
+
(sourceId) => this.waitUntilReady(
|
|
2409
|
+
notebookId,
|
|
2410
|
+
sourceId,
|
|
2411
|
+
timeout,
|
|
2412
|
+
initialInterval,
|
|
2413
|
+
maxInterval,
|
|
2414
|
+
backoffFactor
|
|
2415
|
+
)
|
|
2416
|
+
)
|
|
2417
|
+
);
|
|
2411
2418
|
}
|
|
2412
2419
|
};
|
|
2413
2420
|
function extractSourceId(result) {
|
|
@@ -2441,18 +2448,169 @@ function extractAllText(data, maxDepth = 100) {
|
|
|
2441
2448
|
function sleep2(ms) {
|
|
2442
2449
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2443
2450
|
}
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2451
|
+
var DEFAULT_SESSION_FILE = path.join(os.homedir(), ".notebooklm", "session.json");
|
|
2452
|
+
function loadCookiesFromFile(filePath) {
|
|
2453
|
+
let raw;
|
|
2454
|
+
try {
|
|
2455
|
+
raw = fs.readFileSync(filePath, "utf-8");
|
|
2456
|
+
} catch {
|
|
2457
|
+
throw new AuthError(`Session file not found: ${filePath}
|
|
2458
|
+
Run: npx notebooklm-sdk login`);
|
|
2459
|
+
}
|
|
2460
|
+
return extractCookiesFromStorageState(JSON.parse(raw));
|
|
2461
|
+
}
|
|
2462
|
+
function loadCookiesFromObject(storageState) {
|
|
2463
|
+
return extractCookiesFromStorageState(storageState);
|
|
2464
|
+
}
|
|
2465
|
+
function buildGoogleCookieHeader(storageState) {
|
|
2466
|
+
const map = {};
|
|
2467
|
+
for (const c of storageState.cookies ?? []) {
|
|
2468
|
+
if (c.domain === ".google.com" && c.name && c.value) {
|
|
2469
|
+
map[c.name] = map[c.name] ?? c.value;
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
return buildCookieHeader(map);
|
|
2473
|
+
}
|
|
2474
|
+
function loadCookiesFromMap(map) {
|
|
2475
|
+
return { ...map };
|
|
2476
|
+
}
|
|
2477
|
+
function loadCookiesFromString(cookieStr) {
|
|
2478
|
+
const map = {};
|
|
2479
|
+
for (const part of cookieStr.split(/;\s*/)) {
|
|
2480
|
+
const idx = part.indexOf("=");
|
|
2481
|
+
if (idx > 0) {
|
|
2482
|
+
const name = part.slice(0, idx).trim();
|
|
2483
|
+
const value = part.slice(idx + 1).trim();
|
|
2484
|
+
if (name) map[name] = value;
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
return map;
|
|
2488
|
+
}
|
|
2489
|
+
function extractCookiesFromStorageState(storageState) {
|
|
2490
|
+
const cookies = {};
|
|
2491
|
+
for (const cookie of storageState.cookies ?? []) {
|
|
2492
|
+
const { domain, name, value } = cookie;
|
|
2493
|
+
if (!isAllowedDomain(domain) || !name) continue;
|
|
2494
|
+
const isBase = domain === ".google.com";
|
|
2495
|
+
if (!(name in cookies) || isBase) {
|
|
2496
|
+
cookies[name] = value;
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
if (!cookies["SID"]) {
|
|
2500
|
+
throw new AuthError(
|
|
2501
|
+
"Missing required cookie: SID. Session may be invalid or expired.\nRun: npx notebooklm-sdk login"
|
|
2502
|
+
);
|
|
2503
|
+
}
|
|
2504
|
+
return cookies;
|
|
2505
|
+
}
|
|
2506
|
+
function isAllowedDomain(domain) {
|
|
2507
|
+
if (domain === ".google.com" || domain === "notebooklm.google.com" || domain === ".googleusercontent.com") {
|
|
2508
|
+
return true;
|
|
2509
|
+
}
|
|
2510
|
+
if (domain.startsWith(".google.")) {
|
|
2511
|
+
return true;
|
|
2512
|
+
}
|
|
2513
|
+
return false;
|
|
2514
|
+
}
|
|
2515
|
+
function buildCookieHeader(cookies) {
|
|
2516
|
+
return Object.entries(cookies).map(([k, v]) => `${k}=${v}`).join("; ");
|
|
2517
|
+
}
|
|
2518
|
+
var NOTEBOOKLM_URL = "https://notebooklm.google.com/";
|
|
2519
|
+
async function fetchTokens(cookies) {
|
|
2520
|
+
const cookieHeader = buildCookieHeader(cookies);
|
|
2521
|
+
const response = await fetch(NOTEBOOKLM_URL, {
|
|
2522
|
+
headers: { Cookie: cookieHeader },
|
|
2523
|
+
redirect: "follow"
|
|
2524
|
+
});
|
|
2525
|
+
if (!response.ok) {
|
|
2526
|
+
throw new AuthError(`Failed to fetch NotebookLM page: HTTP ${response.status}`);
|
|
2527
|
+
}
|
|
2528
|
+
const finalUrl = response.url;
|
|
2529
|
+
if (isGoogleAuthRedirect(finalUrl)) {
|
|
2530
|
+
throw new AuthError(`Redirected to login page: ${finalUrl}. Cookies may be expired.`);
|
|
2531
|
+
}
|
|
2532
|
+
const html = await response.text();
|
|
2533
|
+
const csrfToken = extractCsrfToken(html, finalUrl);
|
|
2534
|
+
const sessionId = extractSessionId(html, finalUrl);
|
|
2535
|
+
return { csrfToken, sessionId };
|
|
2536
|
+
}
|
|
2537
|
+
async function refreshAuthTokens(auth) {
|
|
2538
|
+
const { csrfToken, sessionId } = await fetchTokens(auth.cookies);
|
|
2539
|
+
auth.csrfToken = csrfToken;
|
|
2540
|
+
auth.sessionId = sessionId;
|
|
2541
|
+
return auth;
|
|
2542
|
+
}
|
|
2543
|
+
function extractCsrfToken(html, finalUrl) {
|
|
2544
|
+
const match = /"SNlM0e"\s*:\s*"([^"]+)"/.exec(html);
|
|
2545
|
+
if (!match?.[1]) {
|
|
2546
|
+
if (isGoogleAuthRedirect(finalUrl) || html.includes("accounts.google.com")) {
|
|
2547
|
+
throw new AuthError("Session expired or invalid.\nRun: npx notebooklm-sdk login");
|
|
2548
|
+
}
|
|
2549
|
+
throw new AuthError("CSRF token (SNlM0e) not found in NotebookLM page HTML.");
|
|
2550
|
+
}
|
|
2551
|
+
return match[1];
|
|
2552
|
+
}
|
|
2553
|
+
function extractSessionId(html, finalUrl) {
|
|
2554
|
+
const match = /"FdrFJe"\s*:\s*"([^"]+)"/.exec(html);
|
|
2555
|
+
if (!match?.[1]) {
|
|
2556
|
+
if (isGoogleAuthRedirect(finalUrl) || html.includes("accounts.google.com")) {
|
|
2557
|
+
throw new AuthError("Session expired or invalid.\nRun: npx notebooklm-sdk login");
|
|
2558
|
+
}
|
|
2559
|
+
throw new AuthError("Session ID (FdrFJe) not found in NotebookLM page HTML.");
|
|
2560
|
+
}
|
|
2561
|
+
return match[1];
|
|
2562
|
+
}
|
|
2563
|
+
function isGoogleAuthRedirect(url) {
|
|
2564
|
+
return url.includes("accounts.google.com") || url.includes("signin");
|
|
2565
|
+
}
|
|
2566
|
+
async function connect(opts = {}) {
|
|
2567
|
+
let cookieMap;
|
|
2568
|
+
let googleCookieHeader = null;
|
|
2569
|
+
if (opts.cookies) {
|
|
2570
|
+
cookieMap = loadCookiesFromString(opts.cookies);
|
|
2571
|
+
} else if (opts.cookiesFile) {
|
|
2572
|
+
cookieMap = loadCookiesFromFile(opts.cookiesFile);
|
|
2573
|
+
} else if (opts.cookiesObject) {
|
|
2574
|
+
if ("cookies" in opts.cookiesObject && Array.isArray(opts.cookiesObject.cookies)) {
|
|
2575
|
+
const storageState = opts.cookiesObject;
|
|
2576
|
+
cookieMap = loadCookiesFromObject(storageState);
|
|
2577
|
+
googleCookieHeader = buildGoogleCookieHeader(storageState);
|
|
2578
|
+
} else {
|
|
2579
|
+
cookieMap = loadCookiesFromMap(opts.cookiesObject);
|
|
2580
|
+
}
|
|
2581
|
+
} else {
|
|
2582
|
+
const envCookies = process.env["NOTEBOOKLM_COOKIES"];
|
|
2583
|
+
const envFile = process.env["NOTEBOOKLM_COOKIES_FILE"];
|
|
2584
|
+
if (envFile) {
|
|
2585
|
+
cookieMap = loadCookiesFromFile(envFile);
|
|
2586
|
+
} else if (fs.existsSync(DEFAULT_SESSION_FILE)) {
|
|
2587
|
+
const raw = fs.readFileSync(DEFAULT_SESSION_FILE, "utf-8");
|
|
2588
|
+
const storageState = JSON.parse(raw);
|
|
2589
|
+
cookieMap = loadCookiesFromObject(storageState);
|
|
2590
|
+
googleCookieHeader = buildGoogleCookieHeader(storageState);
|
|
2591
|
+
} else if (fs.existsSync("storage_state.json")) {
|
|
2592
|
+
const raw = fs.readFileSync("storage_state.json", "utf-8");
|
|
2593
|
+
const storageState = JSON.parse(raw);
|
|
2594
|
+
cookieMap = loadCookiesFromObject(storageState);
|
|
2595
|
+
googleCookieHeader = buildGoogleCookieHeader(storageState);
|
|
2596
|
+
} else if (envCookies) {
|
|
2597
|
+
cookieMap = loadCookiesFromString(envCookies);
|
|
2598
|
+
} else {
|
|
2599
|
+
throw new AuthError("No session found. Run: npx notebooklm-sdk login");
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2602
|
+
const { csrfToken, sessionId } = await fetchTokens(cookieMap);
|
|
2603
|
+
const cookieHeader = buildCookieHeader(cookieMap);
|
|
2604
|
+
return {
|
|
2605
|
+
cookies: cookieMap,
|
|
2606
|
+
csrfToken,
|
|
2607
|
+
sessionId,
|
|
2608
|
+
cookieHeader,
|
|
2609
|
+
googleCookieHeader: googleCookieHeader ?? cookieHeader
|
|
2610
|
+
};
|
|
2611
|
+
}
|
|
2453
2612
|
|
|
2454
2613
|
// src/rpc/decoder.ts
|
|
2455
|
-
init_errors();
|
|
2456
2614
|
function stripAntiXSSI(response) {
|
|
2457
2615
|
if (response.startsWith(")]}'")) {
|
|
2458
2616
|
const match = /\)\]\}'\r?\n/.exec(response);
|
|
@@ -2496,7 +2654,7 @@ function parseChunkedResponse(response) {
|
|
|
2496
2654
|
if (skippedCount > 0 && lines.length > 0) {
|
|
2497
2655
|
const errorRate = skippedCount / lines.length;
|
|
2498
2656
|
if (errorRate > 0.1) {
|
|
2499
|
-
throw new
|
|
2657
|
+
throw new RPCError(
|
|
2500
2658
|
`Response parsing failed: ${skippedCount} of ${lines.length} chunks malformed`,
|
|
2501
2659
|
{ rawResponse: response.slice(0, 500) }
|
|
2502
2660
|
);
|
|
@@ -2544,13 +2702,13 @@ function extractRPCResult(chunks, rpcId) {
|
|
|
2544
2702
|
} else if (typeof code === "string") {
|
|
2545
2703
|
msg = code;
|
|
2546
2704
|
}
|
|
2547
|
-
throw new
|
|
2705
|
+
throw new RPCError(msg, { methodId: rpcId, rpcCode: code });
|
|
2548
2706
|
}
|
|
2549
2707
|
if (item[0] === "wrb.fr" && item[1] === rpcId) {
|
|
2550
2708
|
const resultData = item[2];
|
|
2551
2709
|
if (resultData === null && item.length > 5 && item[5] != null) {
|
|
2552
2710
|
if (containsUserDisplayableError(item[5])) {
|
|
2553
|
-
throw new
|
|
2711
|
+
throw new RateLimitError(
|
|
2554
2712
|
"API rate limit or quota exceeded. Please wait before retrying.",
|
|
2555
2713
|
{ methodId: rpcId, rpcCode: "USER_DISPLAYABLE_ERROR" }
|
|
2556
2714
|
);
|
|
@@ -2584,8 +2742,8 @@ function decodeResponse(rawResponse, rpcId, allowNull = false) {
|
|
|
2584
2742
|
try {
|
|
2585
2743
|
result = extractRPCResult(chunks, rpcId);
|
|
2586
2744
|
} catch (e) {
|
|
2587
|
-
if (e instanceof
|
|
2588
|
-
throw new
|
|
2745
|
+
if (e instanceof RPCError && e.foundIds.length === 0) {
|
|
2746
|
+
throw new RPCError(e.message, {
|
|
2589
2747
|
methodId: e.methodId,
|
|
2590
2748
|
rpcCode: e.rpcCode,
|
|
2591
2749
|
foundIds,
|
|
@@ -2596,12 +2754,12 @@ function decodeResponse(rawResponse, rpcId, allowNull = false) {
|
|
|
2596
2754
|
}
|
|
2597
2755
|
if (result === void 0 && !allowNull) {
|
|
2598
2756
|
if (foundIds.length > 0 && !foundIds.includes(rpcId)) {
|
|
2599
|
-
throw new
|
|
2757
|
+
throw new RPCError(
|
|
2600
2758
|
`No result for RPC ID '${rpcId}'. Response has IDs: ${foundIds.join(", ")}. Method ID may have changed.`,
|
|
2601
2759
|
{ methodId: rpcId, foundIds, rawResponse: responsePreview }
|
|
2602
2760
|
);
|
|
2603
2761
|
}
|
|
2604
|
-
throw new
|
|
2762
|
+
throw new RPCError(`No result found for RPC ID: ${rpcId} (${chunks.length} chunks parsed)`, {
|
|
2605
2763
|
methodId: rpcId,
|
|
2606
2764
|
foundIds,
|
|
2607
2765
|
rawResponse: responsePreview
|
|
@@ -2636,11 +2794,13 @@ var DEFAULT_TIMEOUT_MS = 3e4;
|
|
|
2636
2794
|
var RPCCore = class {
|
|
2637
2795
|
auth;
|
|
2638
2796
|
timeoutMs;
|
|
2639
|
-
|
|
2797
|
+
refreshAuth;
|
|
2798
|
+
constructor(auth, timeoutMs = DEFAULT_TIMEOUT_MS, refreshAuth) {
|
|
2640
2799
|
this.auth = auth;
|
|
2641
2800
|
this.timeoutMs = timeoutMs;
|
|
2801
|
+
this.refreshAuth = refreshAuth;
|
|
2642
2802
|
}
|
|
2643
|
-
async call(methodId, params, opts = {}) {
|
|
2803
|
+
async call(methodId, params, opts = {}, retried = false) {
|
|
2644
2804
|
const sourcePath = opts.sourcePath ?? "/";
|
|
2645
2805
|
const allowNull = opts.allowNull ?? false;
|
|
2646
2806
|
const timeoutMs = opts.timeoutMs ?? this.timeoutMs;
|
|
@@ -2664,12 +2824,12 @@ var RPCCore = class {
|
|
|
2664
2824
|
} catch (e) {
|
|
2665
2825
|
clearTimeout(timer);
|
|
2666
2826
|
if (e instanceof Error && e.name === "AbortError") {
|
|
2667
|
-
throw new
|
|
2827
|
+
throw new RPCTimeoutError(`Request timed out calling ${methodId}`, {
|
|
2668
2828
|
methodId,
|
|
2669
2829
|
originalError: e
|
|
2670
2830
|
});
|
|
2671
2831
|
}
|
|
2672
|
-
throw new
|
|
2832
|
+
throw new NetworkError(`Request failed calling ${methodId}: ${String(e)}`, {
|
|
2673
2833
|
methodId,
|
|
2674
2834
|
originalError: e instanceof Error ? e : void 0
|
|
2675
2835
|
});
|
|
@@ -2681,29 +2841,33 @@ var RPCCore = class {
|
|
|
2681
2841
|
if (status === 429) {
|
|
2682
2842
|
const retryAfterHeader = response.headers.get("retry-after");
|
|
2683
2843
|
const retryAfter = retryAfterHeader ? parseInt(retryAfterHeader, 10) : void 0;
|
|
2684
|
-
throw new
|
|
2844
|
+
throw new RateLimitError(`API rate limit exceeded calling ${methodId}`, {
|
|
2685
2845
|
methodId,
|
|
2686
2846
|
retryAfter: isNaN(retryAfter ?? NaN) ? void 0 : retryAfter
|
|
2687
2847
|
});
|
|
2688
2848
|
}
|
|
2689
2849
|
if (status === 401 || status === 403) {
|
|
2690
|
-
|
|
2850
|
+
if (!retried && this.refreshAuth) {
|
|
2851
|
+
await this.refreshAuth();
|
|
2852
|
+
return this.call(methodId, params, opts, true);
|
|
2853
|
+
}
|
|
2854
|
+
throw new AuthError(`HTTP ${status} calling ${methodId}: authentication required`, {
|
|
2691
2855
|
methodId
|
|
2692
2856
|
});
|
|
2693
2857
|
}
|
|
2694
2858
|
if (status >= 500) {
|
|
2695
|
-
throw new
|
|
2859
|
+
throw new ServerError(`Server error ${status} calling ${methodId}`, {
|
|
2696
2860
|
methodId,
|
|
2697
2861
|
statusCode: status
|
|
2698
2862
|
});
|
|
2699
2863
|
}
|
|
2700
2864
|
if (status >= 400) {
|
|
2701
|
-
throw new
|
|
2865
|
+
throw new ClientError(`Client error ${status} calling ${methodId}`, {
|
|
2702
2866
|
methodId,
|
|
2703
2867
|
statusCode: status
|
|
2704
2868
|
});
|
|
2705
2869
|
}
|
|
2706
|
-
throw new
|
|
2870
|
+
throw new RPCError(`HTTP ${status} calling ${methodId}`, { methodId });
|
|
2707
2871
|
}
|
|
2708
2872
|
const text = await response.text();
|
|
2709
2873
|
return decodeResponse(text, methodId, allowNull);
|
|
@@ -2739,12 +2903,13 @@ var RPCCore = class {
|
|
|
2739
2903
|
var NotebookLMClient = class _NotebookLMClient {
|
|
2740
2904
|
constructor(auth, opts = {}) {
|
|
2741
2905
|
this.auth = auth;
|
|
2742
|
-
const
|
|
2906
|
+
const refreshAuth = this.refreshTokens.bind(this);
|
|
2907
|
+
const rpc = new RPCCore(auth, opts.timeoutMs, refreshAuth);
|
|
2743
2908
|
this.notebooks = new NotebooksAPI(rpc);
|
|
2744
2909
|
this.sources = new SourcesAPI(rpc, auth);
|
|
2745
2910
|
this.notes = new NotesAPI(rpc);
|
|
2746
2911
|
this.artifacts = new ArtifactsAPI(rpc, auth, this.notes);
|
|
2747
|
-
this.chat = new ChatAPI(rpc, auth);
|
|
2912
|
+
this.chat = new ChatAPI(rpc, auth, refreshAuth);
|
|
2748
2913
|
this.research = new ResearchAPI(rpc);
|
|
2749
2914
|
this.settings = new SettingsAPI(rpc);
|
|
2750
2915
|
this.sharing = new SharingAPI(rpc);
|
|
@@ -2757,6 +2922,7 @@ var NotebookLMClient = class _NotebookLMClient {
|
|
|
2757
2922
|
research;
|
|
2758
2923
|
settings;
|
|
2759
2924
|
sharing;
|
|
2925
|
+
refreshPromise = null;
|
|
2760
2926
|
/**
|
|
2761
2927
|
* Connect to NotebookLM using cookies.
|
|
2762
2928
|
* Fetches CSRF and session tokens from the NotebookLM homepage.
|
|
@@ -2769,25 +2935,47 @@ var NotebookLMClient = class _NotebookLMClient {
|
|
|
2769
2935
|
* Refresh CSRF and session tokens (e.g. if they expire mid-session).
|
|
2770
2936
|
*/
|
|
2771
2937
|
async refreshTokens() {
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2938
|
+
if (!this.refreshPromise) {
|
|
2939
|
+
this.refreshPromise = refreshAuthTokens(this.auth).then(() => void 0).finally(() => {
|
|
2940
|
+
this.refreshPromise = null;
|
|
2941
|
+
});
|
|
2942
|
+
}
|
|
2943
|
+
await this.refreshPromise;
|
|
2776
2944
|
}
|
|
2777
2945
|
};
|
|
2778
2946
|
|
|
2779
2947
|
// src/index.ts
|
|
2780
2948
|
init_enums();
|
|
2781
|
-
init_errors();
|
|
2782
2949
|
|
|
2950
|
+
exports.ArtifactDownloadError = ArtifactDownloadError;
|
|
2951
|
+
exports.ArtifactError = ArtifactError;
|
|
2952
|
+
exports.ArtifactNotFoundError = ArtifactNotFoundError;
|
|
2953
|
+
exports.ArtifactNotReadyError = ArtifactNotReadyError;
|
|
2954
|
+
exports.ArtifactParseError = ArtifactParseError;
|
|
2783
2955
|
exports.ArtifactsAPI = ArtifactsAPI;
|
|
2956
|
+
exports.AuthError = AuthError;
|
|
2784
2957
|
exports.ChatAPI = ChatAPI;
|
|
2958
|
+
exports.ChatError = ChatError;
|
|
2959
|
+
exports.ClientError = ClientError;
|
|
2960
|
+
exports.NetworkError = NetworkError;
|
|
2961
|
+
exports.NotebookError = NotebookError;
|
|
2785
2962
|
exports.NotebookLMClient = NotebookLMClient;
|
|
2963
|
+
exports.NotebookLMError = NotebookLMError;
|
|
2964
|
+
exports.NotebookNotFoundError = NotebookNotFoundError;
|
|
2786
2965
|
exports.NotebooksAPI = NotebooksAPI;
|
|
2787
2966
|
exports.NotesAPI = NotesAPI;
|
|
2967
|
+
exports.RPCError = RPCError;
|
|
2968
|
+
exports.RPCTimeoutError = RPCTimeoutError;
|
|
2969
|
+
exports.RateLimitError = RateLimitError;
|
|
2788
2970
|
exports.ResearchAPI = ResearchAPI;
|
|
2971
|
+
exports.ServerError = ServerError;
|
|
2789
2972
|
exports.SettingsAPI = SettingsAPI;
|
|
2790
2973
|
exports.SharingAPI = SharingAPI;
|
|
2974
|
+
exports.SourceAddError = SourceAddError;
|
|
2975
|
+
exports.SourceError = SourceError;
|
|
2976
|
+
exports.SourceNotFoundError = SourceNotFoundError;
|
|
2977
|
+
exports.SourceProcessingError = SourceProcessingError;
|
|
2978
|
+
exports.SourceTimeoutError = SourceTimeoutError;
|
|
2791
2979
|
exports.SourcesAPI = SourcesAPI;
|
|
2792
2980
|
exports.connect = connect;
|
|
2793
2981
|
//# sourceMappingURL=index.cjs.map
|