Add Brave CDP automation, replace Oracle browser mode

Connects to user's running Brave via Chrome DevTools Protocol
to automate ChatGPT interaction. Uses puppeteer-core to open a
tab, send the prompt, wait for response, and extract the result.

No cookies, no separate profiles, no copy/paste. Just connects
to the browser where the user is already logged in.

One-time setup: relaunch Brave with --remote-debugging-port=9222

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Taylor Eernisse
2026-02-07 16:16:41 -05:00
parent d776a266a8
commit e7882b917b
4163 changed files with 782828 additions and 148 deletions

22
node_modules/get-uri/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014 Nathan Rajlich <nathan@tootallnate.net>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

109
node_modules/get-uri/README.md generated vendored Normal file
View File

@@ -0,0 +1,109 @@
get-uri
=======
### Returns a `stream.Readable` from a URI string
This high-level module accepts a URI string and returns a `Readable` stream
instance. There is built-in support for a variety of "protocols", and it's
easily extensible with more:
| Protocol | Description | Example
|:---------:|:-------------------------------:|:---------------------------------:
| `data` | [Data URIs][data] | `data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D`
| `file` | [File URIs][file] | `file:///c:/windows/example.ini`
| `ftp` | [FTP URIs][ftp] | `ftp://ftp.kernel.org/pub/site/README`
| `http` | [HTTP URIs][http] | `http://www.example.com/path/to/name`
| `https` | [HTTPS URIs][https] | `https://www.example.com/path/to/name`
Example
-------
To simply get a `stream.Readable` instance from a `file:` URI, try something like:
```ts
import { getUri } from 'get-uri';
// `file:` maps to a `fs.ReadStream` instance…
const stream = await getUri('file:///Users/nrajlich/wat.json');
stream.pipe(process.stdout);
```
Missing Endpoints
-----------------
When you pass in a URI in which the resource referenced does not exist on the
destination server, then a `NotFoundError` will be thrown. The `code` of the
error instance is set to `"ENOTFOUND"`, so you can check for that value
to detect when a bad filename is requested:
```ts
try {
await getUri('http://example.com/resource.json');
} catch (err) {
if (err.code === 'ENOTFOUND') {
// bad file path requested
} else {
// something else bad happened...
throw err;
}
}
```
Cacheability
------------
When calling `getUri()` with the same URI multiple times, the `get-uri` module
supports sending an indicator that the remote resource has not been modified
since the last time it has been retrieved from that node process.
To do this, define a `cache` property on the "options object" argument
with the value set to the `stream.Readable` instance that was previously
returned. If the remote resource has not been changed since the last call for
that same URI, then a `NotModifiedError` instance will be thrown with its
`code` property set to `"ENOTMODIFIED"`.
When the `"ENOTMODIFIED"` error occurs, then you can safely re-use the
results from the previous `getUri()` call for that same URI:
``` js
// First time fetches for real
const stream = await getUri('http://example.com/resource.json');
try {
// … some time later, if you need to get this same URI again, pass in the
// previous `stream.Readable` instance as `cache` option to potentially
// have an "ENOTMODIFIED" error thrown:
await getUri('http://example.com/resource.json', { cache: stream });
} catch (err) {
if (err.code === 'ENOTMODIFIED') {
// source file has not been modified since last time it was requested,
// so you are expected to re-use results from a previous call to `getUri()`
} else {
// something else bad happened...
throw err;
}
}
```
API
---
### getUri(uri: string | URL, options?: Object]): Promise<Readable>
A `uri` is required. An optional `options` object may be passed in:
- `cache` - A `stream.Readable` instance from a previous call to `getUri()` with the same URI. If this option is passed in, and the destination endpoint has not been modified, then an `ENOTMODIFIED` error is thrown
Any other options passed in to the `options` object will be passed through
to the low-level connection creation functions (`http.get()`, `ftp.connect()`,
etc).
Returns a `stream.Readable` instance to read the resource at the given `uri`.
[data]: http://tools.ietf.org/html/rfc2397
[file]: http://tools.ietf.org/html/draft-hoffman-file-uri-03
[ftp]: http://www.w3.org/Protocols/rfc959/
[http]: http://www.w3.org/Protocols/rfc2616/rfc2616.html
[https]: http://wikipedia.org/wiki/HTTP_Secure

16
node_modules/get-uri/dist/data.d.ts generated vendored Normal file
View File

@@ -0,0 +1,16 @@
/// <reference types="node" />
/// <reference types="node" />
import { Readable } from 'stream';
import { GetUriProtocol } from './';
declare class DataReadable extends Readable {
hash?: string;
constructor(hash: string, buf: Buffer);
}
export interface DataOptions {
cache?: DataReadable;
}
/**
* Returns a Readable stream from a "data:" URI.
*/
export declare const data: GetUriProtocol<DataOptions>;
export {};

43
node_modules/get-uri/dist/data.js generated vendored Normal file
View File

@@ -0,0 +1,43 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.data = void 0;
const debug_1 = __importDefault(require("debug"));
const stream_1 = require("stream");
const crypto_1 = require("crypto");
const data_uri_to_buffer_1 = require("data-uri-to-buffer");
const notmodified_1 = __importDefault(require("./notmodified"));
const debug = (0, debug_1.default)('get-uri:data');
class DataReadable extends stream_1.Readable {
constructor(hash, buf) {
super();
this.push(buf);
this.push(null);
this.hash = hash;
}
}
/**
* Returns a Readable stream from a "data:" URI.
*/
const data = async ({ href: uri }, { cache } = {}) => {
// need to create a SHA1 hash of the URI string, for cacheability checks
// in future `getUri()` calls with the same data URI passed in.
const shasum = (0, crypto_1.createHash)('sha1');
shasum.update(uri);
const hash = shasum.digest('hex');
debug('generated SHA1 hash for "data:" URI: %o', hash);
// check if the cache is the same "data:" URI that was previously passed in.
if (cache?.hash === hash) {
debug('got matching cache SHA1 hash: %o', hash);
throw new notmodified_1.default();
}
else {
debug('creating Readable stream from "data:" URI buffer');
const { buffer } = (0, data_uri_to_buffer_1.dataUriToBuffer)(uri);
return new DataReadable(hash, Buffer.from(buffer));
}
};
exports.data = data;
//# sourceMappingURL=data.js.map

1
node_modules/get-uri/dist/data.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"data.js","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":";;;;;;AAAA,kDAAgC;AAChC,mCAAkC;AAClC,mCAAoC;AACpC,2DAAqD;AAErD,gEAA6C;AAE7C,MAAM,KAAK,GAAG,IAAA,eAAW,EAAC,cAAc,CAAC,CAAC;AAE1C,MAAM,YAAa,SAAQ,iBAAQ;IAGlC,YAAY,IAAY,EAAE,GAAW;QACpC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;CACD;AAMD;;GAEG;AACI,MAAM,IAAI,GAAgC,KAAK,EACrD,EAAE,IAAI,EAAE,GAAG,EAAE,EACb,EAAE,KAAK,EAAE,GAAG,EAAE,EACb,EAAE;IACH,wEAAwE;IACxE,+DAA+D;IAC/D,MAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC;IAClC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClC,KAAK,CAAC,yCAAyC,EAAE,IAAI,CAAC,CAAC;IAEvD,4EAA4E;IAC5E,IAAI,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE;QACzB,KAAK,CAAC,kCAAkC,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,IAAI,qBAAgB,EAAE,CAAC;KAC7B;SAAM;QACN,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAC1D,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,oCAAe,EAAC,GAAG,CAAC,CAAC;QACxC,OAAO,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;KACnD;AACF,CAAC,CAAC;AApBW,QAAA,IAAI,QAoBf"}

17
node_modules/get-uri/dist/file.d.ts generated vendored Normal file
View File

@@ -0,0 +1,17 @@
/// <reference types="node" />
/// <reference types="node" />
import { Readable } from 'stream';
import { Stats, createReadStream } from 'fs';
import { GetUriProtocol } from './';
type ReadStreamOptions = NonNullable<Exclude<Parameters<typeof createReadStream>[1], string>>;
interface FileReadable extends Readable {
stat?: Stats;
}
export interface FileOptions extends ReadStreamOptions {
cache?: FileReadable;
}
/**
* Returns a `fs.ReadStream` instance from a "file:" URI.
*/
export declare const file: GetUriProtocol<FileOptions>;
export {};

57
node_modules/get-uri/dist/file.js generated vendored Normal file
View File

@@ -0,0 +1,57 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.file = void 0;
const debug_1 = __importDefault(require("debug"));
const fs_1 = require("fs");
const notfound_1 = __importDefault(require("./notfound"));
const notmodified_1 = __importDefault(require("./notmodified"));
const url_1 = require("url");
const debug = (0, debug_1.default)('get-uri:file');
/**
* Returns a `fs.ReadStream` instance from a "file:" URI.
*/
const file = async ({ href: uri }, opts = {}) => {
const { cache, flags = 'r', mode = 438, // =0666
} = opts;
try {
// Convert URI → Path
const filepath = (0, url_1.fileURLToPath)(uri);
debug('Normalized pathname: %o', filepath);
// `open()` first to get a file descriptor and ensure that the file
// exists.
const fdHandle = await fs_1.promises.open(filepath, flags, mode);
// extract the numeric file descriptor
const fd = fdHandle.fd;
// store the stat object for the cache.
const stat = await fdHandle.stat();
// if a `cache` was provided, check if the file has not been modified
if (cache && cache.stat && stat && isNotModified(cache.stat, stat)) {
await fdHandle.close();
throw new notmodified_1.default();
}
// `fs.ReadStream` takes care of calling `fs.close()` on the
// fd after it's done reading
const rs = (0, fs_1.createReadStream)(filepath, {
autoClose: true,
...opts,
fd,
});
rs.stat = stat;
return rs;
}
catch (err) {
if (err.code === 'ENOENT') {
throw new notfound_1.default();
}
throw err;
}
};
exports.file = file;
// returns `true` if the `mtime` of the 2 stat objects are equal
function isNotModified(prev, curr) {
return +prev.mtime === +curr.mtime;
}
//# sourceMappingURL=file.js.map

1
node_modules/get-uri/dist/file.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"file.js","sourceRoot":"","sources":["../src/file.ts"],"names":[],"mappings":";;;;;;AACA,kDAAgC;AAChC,2BAAqE;AAErE,0DAAuC;AACvC,gEAA6C;AAC7C,6BAAoC;AAEpC,MAAM,KAAK,GAAG,IAAA,eAAW,EAAC,cAAc,CAAC,CAAC;AAc1C;;GAEG;AAEI,MAAM,IAAI,GAAgC,KAAK,EACrD,EAAE,IAAI,EAAE,GAAG,EAAE,EACb,IAAI,GAAG,EAAE,EACR,EAAE;IACH,MAAM,EACL,KAAK,EACL,KAAK,GAAG,GAAG,EACX,IAAI,GAAG,GAAG,EAAE,QAAQ;MACpB,GAAG,IAAI,CAAC;IAET,IAAI;QACH,qBAAqB;QACrB,MAAM,QAAQ,GAAG,IAAA,mBAAa,EAAC,GAAG,CAAC,CAAC;QACpC,KAAK,CAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC;QAE3C,mEAAmE;QACnE,UAAU;QACV,MAAM,QAAQ,GAAG,MAAM,aAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC9D,sCAAsC;QACtC,MAAM,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;QAEvB,uCAAuC;QACvC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,qEAAqE;QACrE,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;YACnE,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;YACvB,MAAM,IAAI,qBAAgB,EAAE,CAAC;SAC7B;QAED,4DAA4D;QAC5D,6BAA6B;QAC7B,MAAM,EAAE,GAAG,IAAA,qBAAgB,EAAC,QAAQ,EAAE;YACrC,SAAS,EAAE,IAAI;YACf,GAAG,IAAI;YACP,EAAE;SACF,CAAiB,CAAC;QACnB,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC;QACf,OAAO,EAAE,CAAC;KACV;IAAC,OAAO,GAAY,EAAE;QACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE;YACrD,MAAM,IAAI,kBAAa,EAAE,CAAC;SAC1B;QACD,MAAM,GAAG,CAAC;KACV;AACF,CAAC,CAAC;AA7CW,QAAA,IAAI,QA6Cf;AAEF,gEAAgE;AAChE,SAAS,aAAa,CAAC,IAAW,EAAE,IAAW;IAC9C,OAAO,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;AACpC,CAAC"}

14
node_modules/get-uri/dist/ftp.d.ts generated vendored Normal file
View File

@@ -0,0 +1,14 @@
/// <reference types="node" />
import { AccessOptions } from 'basic-ftp';
import { Readable } from 'stream';
import { GetUriProtocol } from '.';
export interface FTPReadable extends Readable {
lastModified?: Date;
}
export interface FTPOptions extends AccessOptions {
cache?: FTPReadable;
}
/**
* Returns a Readable stream from an "ftp:" URI.
*/
export declare const ftp: GetUriProtocol<FTPOptions>;

93
node_modules/get-uri/dist/ftp.js generated vendored Normal file
View File

@@ -0,0 +1,93 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ftp = void 0;
const basic_ftp_1 = require("basic-ftp");
const stream_1 = require("stream");
const path_1 = require("path");
const debug_1 = __importDefault(require("debug"));
const notfound_1 = __importDefault(require("./notfound"));
const notmodified_1 = __importDefault(require("./notmodified"));
const debug = (0, debug_1.default)('get-uri:ftp');
/**
* Returns a Readable stream from an "ftp:" URI.
*/
const ftp = async (url, opts = {}) => {
const { cache } = opts;
const filepath = decodeURIComponent(url.pathname);
let lastModified;
if (!filepath) {
throw new TypeError('No "pathname"!');
}
const client = new basic_ftp_1.Client();
try {
const host = url.hostname || url.host || 'localhost';
const port = parseInt(url.port || '0', 10) || 21;
const user = url.username
? decodeURIComponent(url.username)
: undefined;
const password = url.password
? decodeURIComponent(url.password)
: undefined;
await client.access({
host,
port,
user,
password,
...opts,
});
// first we have to figure out the Last Modified date.
// try the MDTM command first, which is an optional extension command.
try {
lastModified = await client.lastMod(filepath);
}
catch (err) {
// handle the "file not found" error code
if (err.code === 550) {
throw new notfound_1.default();
}
}
if (!lastModified) {
// Try to get the last modified date via the LIST command (uses
// more bandwidth, but is more compatible with older FTP servers
const list = await client.list((0, path_1.dirname)(filepath));
// attempt to find the "entry" with a matching "name"
const name = (0, path_1.basename)(filepath);
const entry = list.find((e) => e.name === name);
if (entry) {
lastModified = entry.modifiedAt;
}
}
if (lastModified) {
if (isNotModified()) {
throw new notmodified_1.default();
}
}
else {
throw new notfound_1.default();
}
const stream = new stream_1.PassThrough();
const rs = stream;
client.downloadTo(stream, filepath).then((result) => {
debug(result.message);
client.close();
});
rs.lastModified = lastModified;
return rs;
}
catch (err) {
client.close();
throw err;
}
// called when `lastModified` is set, and a "cache" stream was provided
function isNotModified() {
if (cache?.lastModified && lastModified) {
return +cache.lastModified === +lastModified;
}
return false;
}
};
exports.ftp = ftp;
//# sourceMappingURL=ftp.js.map

1
node_modules/get-uri/dist/ftp.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"ftp.js","sourceRoot":"","sources":["../src/ftp.ts"],"names":[],"mappings":"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"}

8
node_modules/get-uri/dist/http-error.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
/**
* Error subclass to use when an HTTP application error has occurred.
*/
export default class HTTPError extends Error {
code: string;
statusCode: number;
constructor(statusCode: number, message?: string | undefined);
}

15
node_modules/get-uri/dist/http-error.js generated vendored Normal file
View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const http_1 = require("http");
/**
* Error subclass to use when an HTTP application error has occurred.
*/
class HTTPError extends Error {
constructor(statusCode, message = http_1.STATUS_CODES[statusCode]) {
super(message);
this.statusCode = statusCode;
this.code = `E${String(message).toUpperCase().replace(/\s+/g, '')}`;
}
}
exports.default = HTTPError;
//# sourceMappingURL=http-error.js.map

1
node_modules/get-uri/dist/http-error.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"http-error.js","sourceRoot":"","sources":["../src/http-error.ts"],"names":[],"mappings":";;AAAA,+BAAoC;AAEpC;;GAEG;AACH,MAAqB,SAAU,SAAQ,KAAK;IAI3C,YAAY,UAAkB,EAAE,OAAO,GAAG,mBAAY,CAAC,UAAU,CAAC;QACjE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;IACrE,CAAC;CACD;AATD,4BASC"}

29
node_modules/get-uri/dist/http.d.ts generated vendored Normal file
View File

@@ -0,0 +1,29 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import http_ from 'http';
import https from 'https';
import { Readable } from 'stream';
import { GetUriProtocol } from '.';
type HttpOrHttpsModule = typeof http_ | typeof https;
export interface HttpReadableProps {
date?: number;
parsed?: URL;
redirects?: HttpReadable[];
}
export interface HttpReadable extends Readable, HttpReadableProps {
}
export interface HttpIncomingMessage extends http_.IncomingMessage, HttpReadableProps {
}
export interface HttpOptions extends https.RequestOptions {
cache?: HttpReadable;
http?: HttpOrHttpsModule;
redirects?: HttpReadable[];
maxRedirects?: number;
}
/**
* Returns a Readable stream from an "http:" URI.
*/
export declare const http: GetUriProtocol<HttpOptions>;
export {};

191
node_modules/get-uri/dist/http.js generated vendored Normal file
View File

@@ -0,0 +1,191 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.http = void 0;
const http_1 = __importDefault(require("http"));
const https_1 = __importDefault(require("https"));
const events_1 = require("events");
const debug_1 = __importDefault(require("debug"));
const http_error_1 = __importDefault(require("./http-error"));
const notfound_1 = __importDefault(require("./notfound"));
const notmodified_1 = __importDefault(require("./notmodified"));
const debug = (0, debug_1.default)('get-uri:http');
/**
* Returns a Readable stream from an "http:" URI.
*/
const http = async (url, opts = {}) => {
debug('GET %o', url.href);
const cache = getCache(url, opts.cache);
// first check the previous Expires and/or Cache-Control headers
// of a previous response if a `cache` was provided
if (cache && isFresh(cache) && typeof cache.statusCode === 'number') {
// check for a 3xx "redirect" status code on the previous cache
const type = (cache.statusCode / 100) | 0;
if (type === 3 && cache.headers.location) {
debug('cached redirect');
throw new Error('TODO: implement cached redirects!');
}
// otherwise we assume that it's the destination endpoint,
// since there's nowhere else to redirect to
throw new notmodified_1.default();
}
// 5 redirects allowed by default
const maxRedirects = typeof opts.maxRedirects === 'number' ? opts.maxRedirects : 5;
debug('allowing %o max redirects', maxRedirects);
let mod;
if (opts.http) {
// the `https` module passed in from the "http.js" file
mod = opts.http;
debug('using secure `https` core module');
}
else {
mod = http_1.default;
debug('using `http` core module');
}
const options = { ...opts };
// add "cache validation" headers if a `cache` was provided
if (cache) {
if (!options.headers) {
options.headers = {};
}
const lastModified = cache.headers['last-modified'];
if (lastModified) {
options.headers['If-Modified-Since'] = lastModified;
debug('added "If-Modified-Since" request header: %o', lastModified);
}
const etag = cache.headers.etag;
if (etag) {
options.headers['If-None-Match'] = etag;
debug('added "If-None-Match" request header: %o', etag);
}
}
const req = mod.get(url, options);
const [res] = await (0, events_1.once)(req, 'response');
const code = res.statusCode || 0;
// assign a Date to this response for the "Cache-Control" delta calculation
res.date = Date.now();
res.parsed = url;
debug('got %o response status code', code);
// any 2xx response is a "success" code
const type = (code / 100) | 0;
// check for a 3xx "redirect" status code
const location = res.headers.location;
if (type === 3 && location) {
if (!opts.redirects)
opts.redirects = [];
const redirects = opts.redirects;
if (redirects.length < maxRedirects) {
debug('got a "redirect" status code with Location: %o', location);
// flush this response - we're not going to use it
res.resume();
// hang on to this Response object for the "redirects" Array
redirects.push(res);
const newUri = new URL(location, url.href);
debug('resolved redirect URL: %o', newUri.href);
const left = maxRedirects - redirects.length;
debug('%o more redirects allowed after this one', left);
// check if redirecting to a different protocol
if (newUri.protocol !== url.protocol) {
opts.http = newUri.protocol === 'https:' ? https_1.default : undefined;
}
return (0, exports.http)(newUri, opts);
}
}
// if we didn't get a 2xx "success" status code, then create an Error object
if (type !== 2) {
res.resume();
if (code === 304) {
throw new notmodified_1.default();
}
else if (code === 404) {
throw new notfound_1.default();
}
// other HTTP-level error
throw new http_error_1.default(code);
}
if (opts.redirects) {
// store a reference to the "redirects" Array on the Response object so that
// they can be inspected during a subsequent call to GET the same URI
res.redirects = opts.redirects;
}
return res;
};
exports.http = http;
/**
* Returns `true` if the provided cache's "freshness" is valid. That is, either
* the Cache-Control header or Expires header values are still within the allowed
* time period.
*
* @return {Boolean}
* @api private
*/
function isFresh(cache) {
let fresh = false;
let expires = parseInt(cache.headers.expires || '', 10);
const cacheControl = cache.headers['cache-control'];
if (cacheControl) {
// for Cache-Control rules, see: http://www.mnot.net/cache_docs/#CACHE-CONTROL
debug('Cache-Control: %o', cacheControl);
const parts = cacheControl.split(/,\s*?\b/);
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
const subparts = part.split('=');
const name = subparts[0];
switch (name) {
case 'max-age':
expires =
(cache.date || 0) + parseInt(subparts[1], 10) * 1000;
fresh = Date.now() < expires;
if (fresh) {
debug('cache is "fresh" due to previous %o Cache-Control param', part);
}
return fresh;
case 'must-revalidate':
// XXX: what we supposed to do here?
break;
case 'no-cache':
case 'no-store':
debug('cache is "stale" due to explicit %o Cache-Control param', name);
return false;
default:
// ignore unknown cache value
break;
}
}
}
else if (expires) {
// for Expires rules, see: http://www.mnot.net/cache_docs/#EXPIRES
debug('Expires: %o', expires);
fresh = Date.now() < expires;
if (fresh) {
debug('cache is "fresh" due to previous Expires response header');
}
return fresh;
}
return false;
}
/**
* Attempts to return a previous Response object from a previous GET call to the
* same URI.
*
* @api private
*/
function getCache(url, cache) {
if (cache) {
if (cache.parsed && cache.parsed.href === url.href) {
return cache;
}
if (cache.redirects) {
for (let i = 0; i < cache.redirects.length; i++) {
const c = getCache(url, cache.redirects[i]);
if (c) {
return c;
}
}
}
}
return null;
}
//# sourceMappingURL=http.js.map

1
node_modules/get-uri/dist/http.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

6
node_modules/get-uri/dist/https.d.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
import { HttpOptions } from './http';
import type { GetUriProtocol } from '.';
/**
* Returns a Readable stream from an "https:" URI.
*/
export declare const https: GetUriProtocol<HttpOptions>;

16
node_modules/get-uri/dist/https.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.https = void 0;
const https_1 = __importDefault(require("https"));
const http_1 = require("./http");
/**
* Returns a Readable stream from an "https:" URI.
*/
const https = (url, opts) => {
return (0, http_1.http)(url, { ...opts, http: https_1.default });
};
exports.https = https;
//# sourceMappingURL=https.js.map

1
node_modules/get-uri/dist/https.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"https.js","sourceRoot":"","sources":["../src/https.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA2B;AAC3B,iCAA2C;AAG3C;;GAEG;AACI,MAAM,KAAK,GAAgC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;IAC/D,OAAO,IAAA,WAAI,EAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,eAAM,EAAE,CAAC,CAAC;AAC7C,CAAC,CAAC;AAFW,QAAA,KAAK,SAEhB"}

37
node_modules/get-uri/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,37 @@
/// <reference types="node" />
/// <reference types="node" />
import { Readable } from 'stream';
type Protocol<T> = T extends `${infer Protocol}:${infer _}` ? Protocol : never;
export type GetUriProtocol<T> = (parsed: URL, opts?: T) => Promise<Readable>;
export declare const protocols: {
data: GetUriProtocol<import("./data").DataOptions>;
file: GetUriProtocol<import("./file").FileOptions>;
ftp: GetUriProtocol<import("./ftp").FTPOptions>;
http: GetUriProtocol<import("./http").HttpOptions>;
https: GetUriProtocol<import("./http").HttpOptions>;
};
export type Protocols = typeof protocols;
export type ProtocolsOptions = {
[P in keyof Protocols]: NonNullable<Parameters<Protocols[P]>[1]>;
};
export type ProtocolOpts<T> = {
[P in keyof ProtocolsOptions]: Protocol<T> extends P ? ProtocolsOptions[P] : never;
}[keyof Protocols];
export declare function isValidProtocol(p: string): p is keyof Protocols;
/**
* Async function that returns a `stream.Readable` instance that will output
* the contents of the given URI.
*
* For caching purposes, you can pass in a `stream` instance from a previous
* `getUri()` call as a `cache: stream` option, and if the destination has
* not changed since the last time the endpoint was retrieved then the callback
* will be invoked with an Error object with `code` set to "ENOTMODIFIED" and
* `null` for the "stream" instance argument. In this case, you can skip
* retrieving the file again and continue to use the previous payload.
*
* @param {String} uri URI to retrieve
* @param {Object} opts optional "options" object
* @api public
*/
export declare function getUri<Uri extends string>(uri: Uri | URL, opts?: ProtocolOpts<Uri>): Promise<Readable>;
export {};

57
node_modules/get-uri/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,57 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUri = exports.isValidProtocol = exports.protocols = void 0;
const debug_1 = __importDefault(require("debug"));
// Built-in protocols
const data_1 = require("./data");
const file_1 = require("./file");
const ftp_1 = require("./ftp");
const http_1 = require("./http");
const https_1 = require("./https");
const debug = (0, debug_1.default)('get-uri');
exports.protocols = {
data: data_1.data,
file: file_1.file,
ftp: ftp_1.ftp,
http: http_1.http,
https: https_1.https,
};
const VALID_PROTOCOLS = new Set(Object.keys(exports.protocols));
function isValidProtocol(p) {
return VALID_PROTOCOLS.has(p);
}
exports.isValidProtocol = isValidProtocol;
/**
* Async function that returns a `stream.Readable` instance that will output
* the contents of the given URI.
*
* For caching purposes, you can pass in a `stream` instance from a previous
* `getUri()` call as a `cache: stream` option, and if the destination has
* not changed since the last time the endpoint was retrieved then the callback
* will be invoked with an Error object with `code` set to "ENOTMODIFIED" and
* `null` for the "stream" instance argument. In this case, you can skip
* retrieving the file again and continue to use the previous payload.
*
* @param {String} uri URI to retrieve
* @param {Object} opts optional "options" object
* @api public
*/
async function getUri(uri, opts) {
debug('getUri(%o)', uri);
if (!uri) {
throw new TypeError('Must pass in a URI to "getUri()"');
}
const url = typeof uri === 'string' ? new URL(uri) : uri;
// Strip trailing `:`
const protocol = url.protocol.replace(/:$/, '');
if (!isValidProtocol(protocol)) {
throw new TypeError(`Unsupported protocol "${protocol}" specified in URI: "${uri}"`);
}
const getter = exports.protocols[protocol];
return getter(url, opts);
}
exports.getUri = getUri;
//# sourceMappingURL=index.js.map

1
node_modules/get-uri/dist/index.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,kDAAgC;AAGhC,qBAAqB;AACrB,iCAA8B;AAC9B,iCAA8B;AAC9B,+BAA4B;AAC5B,iCAA8B;AAC9B,mCAAgC;AAEhC,MAAM,KAAK,GAAG,IAAA,eAAW,EAAC,SAAS,CAAC,CAAC;AAOxB,QAAA,SAAS,GAAG;IACxB,IAAI,EAAJ,WAAI;IACJ,IAAI,EAAJ,WAAI;IACJ,GAAG,EAAH,SAAG;IACH,IAAI,EAAJ,WAAI;IACJ,KAAK,EAAL,aAAK;CACL,CAAC;AAcF,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAS,CAAC,CAAC,CAAC;AAExD,SAAgB,eAAe,CAAC,CAAS;IACxC,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC/B,CAAC;AAFD,0CAEC;AAED;;;;;;;;;;;;;;GAcG;AACI,KAAK,UAAU,MAAM,CAC3B,GAAc,EACd,IAAwB;IAExB,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IAEzB,IAAI,CAAC,GAAG,EAAE;QACT,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAC;KACxD;IAED,MAAM,GAAG,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAEzD,qBAAqB;IACrB,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE;QAC/B,MAAM,IAAI,SAAS,CAClB,yBAAyB,QAAQ,wBAAwB,GAAG,GAAG,CAC/D,CAAC;KACF;IAED,MAAM,MAAM,GAAG,iBAAS,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,GAAG,EAAE,IAAa,CAAC,CAAC;AACnC,CAAC;AAtBD,wBAsBC"}

10
node_modules/get-uri/dist/notfound.d.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
/**
* Error subclass to use when the source does not exist at the specified endpoint.
*
* @param {String} message optional "message" property to set
* @api protected
*/
export default class NotFoundError extends Error {
code: string;
constructor(message?: string);
}

16
node_modules/get-uri/dist/notfound.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
"use strict";
/**
* Error subclass to use when the source does not exist at the specified endpoint.
*
* @param {String} message optional "message" property to set
* @api protected
*/
Object.defineProperty(exports, "__esModule", { value: true });
class NotFoundError extends Error {
constructor(message) {
super(message || 'File does not exist at the specified endpoint');
this.code = 'ENOTFOUND';
}
}
exports.default = NotFoundError;
//# sourceMappingURL=notfound.js.map

1
node_modules/get-uri/dist/notfound.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"notfound.js","sourceRoot":"","sources":["../src/notfound.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAEH,MAAqB,aAAc,SAAQ,KAAK;IAG/C,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,IAAI,+CAA+C,CAAC,CAAC;QAH5D,SAAI,GAAG,WAAW,CAAC;IAI1B,CAAC;CACD;AAND,gCAMC"}

10
node_modules/get-uri/dist/notmodified.d.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
/**
* Error subclass to use when the source has not been modified.
*
* @param {String} message optional "message" property to set
* @api protected
*/
export default class NotModifiedError extends Error {
code: string;
constructor(message?: string);
}

17
node_modules/get-uri/dist/notmodified.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Error subclass to use when the source has not been modified.
*
* @param {String} message optional "message" property to set
* @api protected
*/
class NotModifiedError extends Error {
constructor(message) {
super(message ||
'Source has not been modified since the provied "cache", re-use previous results');
this.code = 'ENOTMODIFIED';
}
}
exports.default = NotModifiedError;
//# sourceMappingURL=notmodified.js.map

1
node_modules/get-uri/dist/notmodified.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"notmodified.js","sourceRoot":"","sources":["../src/notmodified.ts"],"names":[],"mappings":";;AAAA;;;;;GAKG;AACH,MAAqB,gBAAiB,SAAQ,KAAK;IAGlD,YAAY,OAAgB;QAC3B,KAAK,CACJ,OAAO;YACN,iFAAiF,CAClF,CAAC;QANI,SAAI,GAAG,cAAc,CAAC;IAO7B,CAAC;CACD;AATD,mCASC"}

58
node_modules/get-uri/package.json generated vendored Normal file
View File

@@ -0,0 +1,58 @@
{
"name": "get-uri",
"version": "6.0.5",
"description": "Returns a `stream.Readable` from a URI string",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"repository": {
"type": "git",
"url": "https://github.com/TooTallNate/proxy-agents.git",
"directory": "packages/get-uri"
},
"keywords": [
"uri",
"read",
"readstream",
"stream",
"get",
"http",
"https",
"ftp",
"file",
"data",
"protocol",
"url"
],
"author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)",
"license": "MIT",
"devDependencies": {
"@types/debug": "^4.1.7",
"@types/ftpd": "^0.2.35",
"@types/jest": "^29.5.1",
"@types/node": "^14.18.45",
"async-listen": "^3.0.0",
"ftpd": "https://files-jg1s1zt9l.n8.io/ftpd-v0.2.14.tgz",
"jest": "^29.5.0",
"st": "^3.0.0",
"ts-jest": "^29.1.0",
"typescript": "^5.0.4",
"tsconfig": "0.0.0"
},
"dependencies": {
"basic-ftp": "^5.0.2",
"data-uri-to-buffer": "^6.0.2",
"debug": "^4.3.4"
},
"engines": {
"node": ">= 14"
},
"scripts": {
"build": "tsc",
"test": "jest --env node --verbose --bail",
"lint": "eslint . --ext .ts",
"pack": "node ../../scripts/pack.mjs"
}
}