website-api 1.0.1

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 ADDED
@@ -0,0 +1,241 @@
1
+ # website-api
2
+
3
+ A TypeScript CLI and library published as `website-api` that uses [chrome-tools](https://github.com/user/chrome-tools) to extract decrypted Chrome cookies on macOS, then queries private/internal website APIs — no manual cookie copy-pasting needed.
4
+
5
+ ---
6
+
7
+ ## Features
8
+
9
+ - 🔑 **Keychain Decryption** — Leverages `chrome-tools` to decrypt Chrome cookies via the macOS Keychain.
10
+ - 📂 **Auto-Loading Adapters** — Drop a folder into `src/website/`, and the adapter is auto-discovered at runtime.
11
+ - 🧩 **Zero-Boilerplate Adapters** — The `defineAdapter()` factory handles cookies, user-agent, fetch, and error handling. Simple adapters are ~10 lines.
12
+ - 👥 **Multi-Profile Support** — Target specific Chrome profiles (e.g., `Default`, `Profile 1`) or custom user data paths.
13
+ - 🚀 **Dual Interface** — Works as both an importable ES module library and a terminal CLI.
14
+
15
+ ---
16
+
17
+ ## Supported Website APIs
18
+
19
+ | ID | Name | Domain | Description |
20
+ |----|------|--------|-------------|
21
+ | `codex-usage` | ChatGPT / Codex Usage | chatgpt.com | Fetches ChatGPT rate limit usage and quota details from the private wham/usage API. |
22
+ | `cursor-usage` | Cursor Usage | cursor.com | Fetches the active Cursor usage summary from the private usage-summary API. |
23
+ | `ollama-usage` | Ollama Usage | ollama.com | Fetches Ollama plan and usage details from the authenticated settings page. |
24
+
25
+ Each adapter has a `request.md` file documenting the exact HTTP requests and expected responses.
26
+
27
+ ---
28
+
29
+ ## Installation & Setup
30
+
31
+ ### Prerequisites
32
+
33
+ - macOS with Google Chrome installed
34
+ - Node.js ≥ 18
35
+ - [pnpm](https://pnpm.io/) package manager
36
+
37
+ ### Install
38
+
39
+ ```bash
40
+ pnpm install
41
+ pnpm run build
42
+ ```
43
+
44
+ ### Link CLI globally (optional)
45
+
46
+ ```bash
47
+ pnpm link --global
48
+ website-api --help
49
+ ```
50
+
51
+ ---
52
+
53
+ ## CLI Usage
54
+
55
+ ```bash
56
+ # Show help
57
+ node dist/bin/cli.js --help
58
+
59
+ # List all supported adapters
60
+ node dist/bin/cli.js list
61
+
62
+ # Query a website API
63
+ node dist/bin/cli.js codex-usage
64
+ node dist/bin/cli.js cursor-usage
65
+ node dist/bin/cli.js ollama-usage
66
+
67
+ # Domain aliases still work too
68
+ node dist/bin/cli.js chatgpt.com
69
+ node dist/bin/cli.js cursor.com
70
+ node dist/bin/cli.js ollama.com
71
+ ```
72
+
73
+ ### Options
74
+
75
+ | Option | Description |
76
+ |--------|-------------|
77
+ | `--profile <name>` | Target a specific Chrome profile (e.g., `Default`, `Profile 1`) |
78
+ | `--current-profile` | Show the currently resolved Chrome profile directory and name |
79
+ | `-u, --user-agent <string>` | Custom User-Agent header for HTTP requests |
80
+
81
+ ### Universal Fallback
82
+
83
+ Any URL or domain not matching a registered adapter will be fetched directly with Chrome cookies:
84
+
85
+ ```bash
86
+ node dist/bin/cli.js https://example.com/api/data
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Library Usage (Programmatic API)
92
+
93
+ ```typescript
94
+ import { queryWebsite } from "website-api";
95
+
96
+ const data = await queryWebsite("chatgpt.com", {
97
+ profile: "Default",
98
+ });
99
+
100
+ // Command IDs also work:
101
+ // await queryWebsite("codex-usage", { profile: "Default" });
102
+
103
+ console.log(JSON.stringify(data, null, 2));
104
+ ```
105
+
106
+ ---
107
+
108
+ ## How to Add a New Website Adapter
109
+
110
+ ### Step 1: Create the adapter folder
111
+
112
+ ```
113
+ src/website/github.com/
114
+ ├── github-adapter.ts ← adapter code
115
+ └── request.md ← document the endpoint (required)
116
+ ```
117
+
118
+ ### Step 2: Write the adapter
119
+
120
+ For **simple single-endpoint** APIs — just declare the endpoint:
121
+
122
+ ```typescript
123
+ // src/website/github.com/github-adapter.ts
124
+ import { defineAdapter } from "../../base-adapter.js";
125
+
126
+ export default defineAdapter({
127
+ id: "github.com",
128
+ name: "GitHub Notifications",
129
+ domain: "github.com",
130
+ description: "Fetches unread notifications from the GitHub API.",
131
+ endpoints: [{ url: "https://api.github.com/notifications" }],
132
+ });
133
+ ```
134
+
135
+ For **multi-step flows** (e.g., session token → API call) — override `fetchData`:
136
+
137
+ ```typescript
138
+ // src/website/example.com/example-adapter.ts
139
+ import { defineAdapter } from "../../base-adapter.js";
140
+
141
+ export default defineAdapter({
142
+ id: "example.com",
143
+ name: "Example Service",
144
+ domain: "example.com",
145
+ description: "Fetches data with a two-step auth flow.",
146
+
147
+ async fetchData(cookies, options) {
148
+ const cookieStr = this.buildCookieString(cookies); // shared helper
149
+ const ua = this.resolveUserAgent(options); // shared helper
150
+
151
+ // Step 1: get token
152
+ const session = await this.fetchJson("https://example.com/auth", {
153
+ headers: { Cookie: cookieStr, "User-Agent": ua },
154
+ });
155
+
156
+ // Step 2: use token
157
+ return this.fetchJson("https://example.com/api/data", {
158
+ headers: { Authorization: `Bearer ${session.token}` },
159
+ });
160
+ },
161
+ });
162
+ ```
163
+
164
+ ### Step 3: Document the endpoint
165
+
166
+ Create `request.md` in the adapter folder documenting the HTTP requests, headers, and example responses. See [chatgpt.com/request.md](src/website/chatgpt.com/request.md) for reference.
167
+
168
+ ### Step 4: Build and test
169
+
170
+ ```bash
171
+ pnpm run build
172
+ node dist/bin/cli.js list # verify it appears
173
+ node dist/bin/cli.js github.com # test it
174
+ ```
175
+
176
+ That's it — **no registration needed**. The adapter is auto-discovered from the `website/` directory at runtime.
177
+
178
+ ---
179
+
180
+ ## Shared Adapter Helpers
181
+
182
+ Every adapter created with `defineAdapter()` automatically gets these methods via `this`:
183
+
184
+ | Method | Description |
185
+ |--------|-------------|
186
+ | `this.buildCookieString(cookies)` | Converts cookies array to `"name=value; ..."` header string |
187
+ | `this.resolveUserAgent(options)` | Resolves User-Agent from options → `.env` → default |
188
+ | `this.fetchJson(url, init?)` | Fetch with error handling + automatic JSON parsing |
189
+
190
+ ---
191
+
192
+ ## Configuration
193
+
194
+ Create a `.env` file in the project root:
195
+
196
+ ```env
197
+ # Custom User-Agent (defaults to Chrome 148 on macOS)
198
+ userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36"
199
+
200
+ # Custom Chrome profile path (defaults to standard macOS location)
201
+ PROFILE_PATH="/Users/yourname/chrome_profile/chrome"
202
+ PROFILE_NAME="Default"
203
+ ```
204
+
205
+ ---
206
+
207
+ ## Project Structure
208
+
209
+ ```
210
+ ├── src/
211
+ │ ├── website-api.ts # Main entry — auto-loads adapters, queryWebsite()
212
+ │ ├── base-adapter.ts # defineAdapter() factory + shared helpers
213
+ │ ├── types.ts # TypeScript interfaces
214
+ │ ├── env.ts # .env file loader
215
+ │ ├── universal-adapter.ts # Fallback for unregistered domains
216
+ │ └── website/
217
+ │ ├── chatgpt.com/
218
+ │ │ ├── chatgpt-adapter.ts
219
+ │ │ └── request.md
220
+ │ ├── cursor.com/
221
+ │ ├── cursor-adapter.ts
222
+ │ └── request.md
223
+ │ └── ollama.com/
224
+ │ ├── ollama-adapter.ts
225
+ │ └── request.md
226
+ ├── bin/
227
+ │ └── cli.ts # CLI entry point
228
+ ├── tsconfig.json
229
+ ├── package.json
230
+ └── .env # Local config (gitignored)
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Security Warning
236
+
237
+ This utility is designed strictly for local development and authorized administrative use. macOS will request explicit Keychain authorization before allowing `chrome-tools` to access the Chrome Safe Storage Password. Only run this tool in trusted environments.
238
+
239
+ ## License
240
+
241
+ MIT License
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import{readFileSync as o}from"node:fs";import{dirname as e,join as r}from"node:path";import{fileURLToPath as n}from"node:url";import{program as t}from"commander";import s from"chalk";import i from"cli-table3";import{getDefaultChromeDir as l}from"chrome-tools";import{queryWebsite as c,websites as a,loadAdapters as p}from"../src/website-api.js";const d=r(e(n(import.meta.url)),"..","..","package.json"),{version:m}=JSON.parse(o(d,"utf8"));process.on("unhandledRejection",()=>{console.error("No login found in browser"),process.exit(1)}),t.name("website-api").description("CLI to query website APIs using decrypted Chrome cookies on macOS").version(m),t.option("--profile <name>","specific Chrome profile directory (e.g., 'Default', 'Profile 1')").option("--current-profile","Show the currently resolved/selected Chrome profile directory and name").option("-u, --user-agent <string>","custom User-Agent header for HTTP requests"),t.command("list").description("List all supported website API adapters").action(async()=>{await p(),console.log(s.bold.green("\n🌐 Supported Website APIs:\n"));const o=new i({head:[s.bold.cyan("ID"),s.bold.cyan("Name"),s.bold.cyan("Domain"),s.bold.cyan("Description")],colWidths:[18,25,20,50],wordWrap:!0,style:{head:[],border:[]}});for(const e of a)o.push([s.yellow(e.id),e.name,s.underline(e.domain),e.description]);console.log(o.toString()),console.log(`\nTo run an API query, execute: ${s.bold.cyan("npx website-api <id>")}\n`)}),t.argument("[website]","website ID or domain to query (e.g. 'chatgpt.com')").action(async o=>{const e=t.opts();if(e.currentProfile){const o=process.env.PROFILE_PATH||process.env.CHROME_PROFILE_PATH||l(),r=e.profile||process.env.PROFILE_NAME||"Default";return console.log(s.bold.green("\n👤 Currently Resolved Profile:\n")),console.log(` ${s.bold("Path:")} ${o}`),void console.log(` ${s.bold("Name:")} ${r}\n`)}if(o)try{const r=await c(o,{profile:e.profile,userAgent:e.userAgent});console.log(JSON.stringify(r,null,2))}catch(o){console.error("No login found in browser"),process.exit(1)}else t.outputHelp()}),t.parse(process.argv);
@@ -0,0 +1,19 @@
1
+ import type { AdapterConfig, WebsiteAdapter } from "./types.js";
2
+ /**
3
+ * Factory function to create a fully-equipped WebsiteAdapter from a minimal config.
4
+ *
5
+ * Simple adapters only need `id`, `name`, `domain`, `description`, and `endpoints`.
6
+ * Complex adapters can provide a custom `fetchData` that uses `this.buildCookieString()`,
7
+ * `this.resolveUserAgent()`, and `this.fetchJson()`.
8
+ *
9
+ * @example
10
+ * // Simple adapter (~5 lines of config):
11
+ * export default defineAdapter({
12
+ * id: "cursor.com",
13
+ * name: "Cursor Usage",
14
+ * domain: "cursor.com",
15
+ * description: "Fetches Cursor usage summary.",
16
+ * endpoints: [{ url: "https://cursor.com/api/usage-summary" }],
17
+ * });
18
+ */
19
+ export declare function defineAdapter(config: AdapterConfig): WebsiteAdapter;
@@ -0,0 +1 @@
1
+ const e={buildCookieString:e=>e.map(e=>`${e.name}=${e.value}`).join("; "),resolveUserAgent:e=>e.userAgent||process.env.userAgent||process.env.USER_AGENT||"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36",async fetchJson(e,t){const n=await fetch(e,t);if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);const s=await n.text();try{return JSON.parse(s)}catch{return{response:s}}}};async function t(e,t){if(!this.endpoints||0===this.endpoints.length)throw new Error(`Adapter "${this.id}" has no endpoints defined and no fetchData override`);const n=this.endpoints[0],s=this.buildCookieString(e),o=this.resolveUserAgent(t);return this.fetchJson(n.url,{method:n.method||"GET",headers:{Cookie:s,"User-Agent":o,Accept:"application/json, text/plain, */*",...n.headers}})}export function defineAdapter(n){const s={...n,...e,fetchData:n.fetchData??t};return s.fetchData=s.fetchData.bind(s),s}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Loads environment variables from the project root .env file.
3
+ * Silently skips if the file doesn't exist.
4
+ */
5
+ export declare function loadEnv(): void;
@@ -0,0 +1 @@
1
+ import{readFileSync as t,existsSync as n}from"node:fs";import{dirname as o,resolve as r}from"node:path";import{fileURLToPath as s}from"node:url";const i=o(s(import.meta.url));export function loadEnv(){try{const o=r(i,"../../.env");if(!n(o))return;const s=t(o,"utf8");for(const t of s.split(/\r?\n/)){const n=t.trim();if(!n||n.startsWith("#"))continue;const o=n.indexOf("=");if(o<=0)continue;const r=n.substring(0,o).trim();let s=n.substring(o+1).trim();(s.startsWith('"')&&s.endsWith('"')||s.startsWith("'")&&s.endsWith("'"))&&(s=s.substring(1,s.length-1)),process.env[r]=s}}catch{}}
@@ -0,0 +1,51 @@
1
+ import type { CookieEntry } from "chrome-tools";
2
+ /**
3
+ * Defines an API endpoint to be fetched by an adapter.
4
+ */
5
+ export interface Endpoint {
6
+ /** Full URL of the API endpoint. */
7
+ url: string;
8
+ /** HTTP method. Defaults to "GET". */
9
+ method?: string;
10
+ /** Additional headers to include in the request. */
11
+ headers?: Record<string, string>;
12
+ }
13
+ /**
14
+ * Configuration for defining a website adapter.
15
+ * Simple adapters declare `endpoints` and get automatic fetch handling.
16
+ * Complex adapters override `fetchData` for custom multi-step flows.
17
+ */
18
+ export interface AdapterConfig {
19
+ /** Unique identifier, typically the domain (e.g. "chatgpt.com"). */
20
+ id: string;
21
+ /** Human-readable name (e.g. "ChatGPT / Codex Usage"). */
22
+ name: string;
23
+ /** Cookie domain to filter Chrome cookies for this site. */
24
+ domain: string;
25
+ /** Short description of what data this adapter fetches. */
26
+ description: string;
27
+ /** Endpoints for simple single-fetch adapters. First endpoint is used by default fetchData. */
28
+ endpoints?: Endpoint[];
29
+ /** Override for complex multi-step flows (e.g. session token → API call). */
30
+ fetchData?: (this: WebsiteAdapter, cookies: CookieEntry[], options: QueryOptions) => Promise<unknown>;
31
+ }
32
+ /**
33
+ * A fully-instantiated website adapter with shared helper methods.
34
+ */
35
+ export interface WebsiteAdapter extends AdapterConfig {
36
+ /** Converts a cookie array into a "name=value; ..." header string. */
37
+ buildCookieString(cookies: CookieEntry[]): string;
38
+ /** Resolves the User-Agent from options → env → default. */
39
+ resolveUserAgent(options: QueryOptions): string;
40
+ /** Fetches a URL and returns parsed JSON, with error handling. */
41
+ fetchJson(url: string, init?: RequestInit): Promise<any>;
42
+ }
43
+ /**
44
+ * Options passed when querying a website API.
45
+ */
46
+ export interface QueryOptions {
47
+ /** Chrome profile directory name (e.g. "Default", "Profile 1"). */
48
+ profile?: string;
49
+ /** Custom User-Agent header for HTTP requests. */
50
+ userAgent?: string;
51
+ }
@@ -0,0 +1 @@
1
+ export{};
@@ -0,0 +1,10 @@
1
+ import type { WebsiteAdapter } from "./types.js";
2
+ /**
3
+ * Creates a universal fallback adapter for any domain that doesn't have
4
+ * a dedicated adapter. Parses the websiteId as a URL and uses the default
5
+ * single-endpoint fetch flow.
6
+ *
7
+ * @param websiteId - A URL or domain string (e.g. "example.com/api/data")
8
+ * @returns A WebsiteAdapter if the URL is valid, or null otherwise.
9
+ */
10
+ export declare function createUniversalAdapter(websiteId: string): WebsiteAdapter | null;
@@ -0,0 +1 @@
1
+ import{defineAdapter as t}from"./base-adapter.js";export function createUniversalAdapter(r){let e=r;e.startsWith("http://")||e.startsWith("https://")||(e="https://"+e);try{const a=new URL(e);return t({id:r,name:r,domain:a.hostname,description:`Universal adapter for ${a.hostname}`,endpoints:[{url:a.href}]})}catch{return null}}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * ChatGPT adapter — fetches rate limit usage from the wham/usage API.
3
+ *
4
+ * This is a multi-step flow:
5
+ * 1. Exchange Chrome cookies for a Bearer JWT via the Next-Auth session endpoint
6
+ * 2. Use the JWT to query the private wham/usage endpoint
7
+ *
8
+ * See request.md in this directory for full endpoint documentation.
9
+ */
10
+ declare const _default: import("../../types.js").WebsiteAdapter;
11
+ export default _default;
@@ -0,0 +1 @@
1
+ import{defineAdapter as e}from"../../base-adapter.js";export default e({id:"codex-usage",name:"ChatGPT / Codex Usage",domain:"chatgpt.com",description:"Fetches ChatGPT rate limit usage and quota details from the private wham/usage API.",async fetchData(e,t){const a=this.buildCookieString(e),s=this.resolveUserAgent(t),o=await this.fetchJson("https://chatgpt.com/api/auth/session",{headers:{Cookie:a,"User-Agent":s,Accept:"application/json"}});if(!o?.accessToken)throw new Error("No login found in browser");return this.fetchJson("https://chatgpt.com/backend-api/wham/usage",{headers:{authorization:`Bearer ${o.accessToken}`}})}});
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Cursor.com adapter — fetches the active usage summary.
3
+ * Simple single-endpoint adapter: just declare the endpoint, BaseAdapter handles the rest.
4
+ */
5
+ declare const _default: import("../../types.js").WebsiteAdapter;
6
+ export default _default;
@@ -0,0 +1 @@
1
+ import{defineAdapter as r}from"../../base-adapter.js";export default r({id:"cursor-usage",name:"Cursor Usage",domain:"cursor.com",description:"Fetches the active Cursor usage summary from the private usage-summary API.",endpoints:[{url:"https://cursor.com/api/usage-summary"}]});
@@ -0,0 +1,2 @@
1
+ declare const _default: import("../../types.js").WebsiteAdapter;
2
+ export default _default;
@@ -0,0 +1 @@
1
+ import{defineAdapter as e}from"../../base-adapter.js";export default e({id:"ollama-usage",name:"Ollama Usage",domain:"ollama.com",description:"Fetches Ollama plan and usage details from the authenticated settings page.",async fetchData(e,a){const n=this.buildCookieString(e),i=this.resolveUserAgent(a),o=await fetch("https://ollama.com/settings",{method:"GET",headers:{Cookie:n,"User-Agent":i,Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}});if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);const r=await o.text(),l=s(r,"Session usage"),m=s(r,"Weekly usage");return{time:(new Date).toISOString(),Plan:t(r),"Session Usage":l.usage,"Session Reset":l.reset,"Weekly Usage":m.usage,"Weekly Reset":m.reset}}});function t(e){const t=e.match(/Cloud Usage[\s\S]*?<\/span>[\s\S]*?<span[^>]*>([\s\S]*?)<\/span/i);return t?.[1]?.trim()??"unknown"}function s(e,t){const s=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");const a=new RegExp(`<div[\\s\\S]*?<span[^>]*>\\s*${s}\\s*<\\/span>[\\s\\S]*?aria-label="${s}\\s+([^"]+)"[\\s\\S]*?data-time="([^"]+)"`,"i"),n=e.match(a);return{usage:n?.[1]?.replace(/\s+used$/i,"").trim()??"unknown",reset:n?.[2]?.trim()??"unknown"}}
@@ -0,0 +1,34 @@
1
+ import type { QueryOptions, WebsiteAdapter } from "./types.js";
2
+ /**
3
+ * All loaded website adapters, populated by `loadAdapters()`.
4
+ */
5
+ export declare let websites: WebsiteAdapter[];
6
+ /**
7
+ * Auto-discovers and loads all website adapters from the `website/` directory.
8
+ *
9
+ * Scans each subdirectory for a file matching `*-adapter.js` and dynamically
10
+ * imports it. Each adapter module must have a default export that is a
11
+ * WebsiteAdapter (created via `defineAdapter()`).
12
+ *
13
+ * This is called once on first use — no manual imports needed when adding
14
+ * new adapters.
15
+ */
16
+ export declare function loadAdapters(): Promise<void>;
17
+ /**
18
+ * Finds an adapter by ID or partial domain match.
19
+ *
20
+ * @param id - Website identifier (e.g. "chatgpt.com", "chatgpt", "cursor")
21
+ * @returns The matching adapter or null
22
+ */
23
+ export declare function getWebsite(id: string): WebsiteAdapter | null;
24
+ /**
25
+ * Queries a registered website API using decrypted Google Chrome cookies on macOS.
26
+ *
27
+ * Cookie retrieval is simplified to a single `getCookies({ domain })` call —
28
+ * no manual extraction or domain matching needed.
29
+ *
30
+ * @param websiteId - The domain or identifier of the website (e.g. "chatgpt.com")
31
+ * @param options - Retrieval options (profile, userAgent)
32
+ * @returns The structured website API response
33
+ */
34
+ export declare function queryWebsite(websiteId: string, options?: QueryOptions): Promise<unknown>;
@@ -0,0 +1 @@
1
+ import{readdirSync as o}from"node:fs";import{dirname as e,join as r}from"node:path";import{fileURLToPath as t,pathToFileURL as i}from"node:url";import{getCookies as n}from"chrome-tools";import{loadEnv as s}from"./env.js";import{createUniversalAdapter as a}from"./universal-adapter.js";s();const c=e(t(import.meta.url)),f=r(c,"website");export let websites=[];export async function loadAdapters(){if(!(websites.length>0))try{const e=o(f,{withFileTypes:!0});for(const t of e){if(!t.isDirectory())continue;const e=r(f,t.name),n=o(e).find(o=>o.endsWith("-adapter.js"));if(!n)continue;const s=i(r(e,n)).href,a=(await import(s)).default;a?.id&&websites.push(a)}}catch(o){}}export function getWebsite(o){if(!o)return null;const e=o.toLowerCase().trim();return websites.find(o=>o.id.toLowerCase()===e||o.id.toLowerCase().replace(".com","")===e)??null}export async function queryWebsite(o,e={}){await loadAdapters();const r=process.env.PROFILE_PATH||process.env.CHROME_PROFILE_PATH||void 0,t=e.profile||process.env.PROFILE_NAME||void 0;let i,s=getWebsite(o);if(!s&&(s=a(o),!s))throw new Error("No login found in browser");try{i=n({chromeDir:r,profile:t,domain:s.domain,decrypt:!0})}catch{throw new Error("No login found in browser")}if(!i||0===i.length)throw new Error("No login found in browser");return s.fetchData(i,e)}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "website-api",
3
+ "version": "1.0.1",
4
+ "description": "CLI and library to fetch website API data using chrome-tools decrypted cookies on macOS",
5
+ "main": "./dist/src/website-api.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "website-api": "./dist/bin/cli.js",
9
+ "chrome-website-api": "./dist/bin/cli.js"
10
+ },
11
+ "keywords": [
12
+ "chrome",
13
+ "cookies",
14
+ "api",
15
+ "chatgpt",
16
+ "codex",
17
+ "macos",
18
+ "cli"
19
+ ],
20
+ "author": "",
21
+ "license": "MIT",
22
+ "dependencies": {
23
+ "chalk": "^5.6.2",
24
+ "chrome-tools": "^1.0.6",
25
+ "cli-table3": "^0.6.5",
26
+ "commander": "^14.0.3"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^25.9.1",
30
+ "terser": "^5.43.1",
31
+ "typescript": "^6.0.3"
32
+ },
33
+ "files": [
34
+ "dist"
35
+ ],
36
+ "scripts": {
37
+ "build": "node scripts/build.mjs",
38
+ "check:secrets": "node scripts/check-secrets.mjs",
39
+ "release": "pnpm version patch && pnpm publish --access public",
40
+ "start": "node dist/bin/cli.js"
41
+ }
42
+ }