openai-oauth 0.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/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.js ADDED
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ DEFAULT_PORT,
4
+ resolveAuthFileCandidates,
5
+ startOpenAIOAuthServer
6
+ } from "./chunk-VZQM4BY4.js";
7
+
8
+ // src/cli-app.ts
9
+ import { access } from "fs/promises";
10
+ import yargs from "yargs";
11
+ import { hideBin } from "yargs/helpers";
12
+ var parseModels = (value) => {
13
+ if (typeof value !== "string") {
14
+ return void 0;
15
+ }
16
+ const models = value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
17
+ return models.length > 0 ? models : void 0;
18
+ };
19
+ var parseCliArgs = (argv) => {
20
+ const parsed = yargs(argv).scriptName("openai-oauth").strict().help().option("host", {
21
+ type: "string",
22
+ describe: "Host interface to bind the local proxy to."
23
+ }).option("port", {
24
+ type: "number",
25
+ describe: "Port to bind the local proxy to."
26
+ }).option("models", {
27
+ type: "string",
28
+ describe: "Comma-separated list of models exposed by /v1/models.",
29
+ coerce: parseModels
30
+ }).option("base-url", {
31
+ type: "string",
32
+ describe: "Override the upstream Codex responses base URL."
33
+ }).option("oauth-client-id", {
34
+ type: "string",
35
+ describe: "Override the OAuth client id used for token refresh."
36
+ }).option("oauth-token-url", {
37
+ type: "string",
38
+ describe: "Override the OAuth token URL used for token refresh."
39
+ }).option("oauth-file", {
40
+ type: "string",
41
+ describe: "Override the auth.json file path used for local OAuth tokens."
42
+ }).parseSync();
43
+ return {
44
+ host: parsed.host,
45
+ port: parsed.port,
46
+ models: parsed.models,
47
+ baseURL: parsed.baseUrl,
48
+ clientId: parsed.oauthClientId,
49
+ tokenUrl: parsed.oauthTokenUrl,
50
+ authFilePath: parsed.oauthFile
51
+ };
52
+ };
53
+ var toServerOptions = (args) => ({
54
+ host: args.host ?? process.env.HOST,
55
+ port: args.port ?? Number(process.env.PORT ?? String(DEFAULT_PORT)),
56
+ models: args.models,
57
+ baseURL: args.baseURL,
58
+ clientId: args.clientId,
59
+ tokenUrl: args.tokenUrl,
60
+ authFilePath: args.authFilePath
61
+ });
62
+ var findExistingAuthFile = async (authFilePath) => {
63
+ for (const candidate of resolveAuthFileCandidates(authFilePath)) {
64
+ try {
65
+ await access(candidate);
66
+ return candidate;
67
+ } catch {
68
+ }
69
+ }
70
+ return void 0;
71
+ };
72
+ var toMissingAuthFileMessage = (authFilePath) => {
73
+ if (authFilePath) {
74
+ return [
75
+ `No auth file was found at ${authFilePath}.`,
76
+ "Run `npx @openai/codex login` and try again."
77
+ ].join("\n");
78
+ }
79
+ const candidates = resolveAuthFileCandidates(void 0);
80
+ return [
81
+ `No auth file was found in the default search paths: ${candidates.join(", ")}.`,
82
+ "Run `npx @openai/codex login` and try again."
83
+ ].join("\n");
84
+ };
85
+ var toStartupMessage = (options) => {
86
+ const baseUrl = `http://${options.host ?? "127.0.0.1"}:${options.port ?? DEFAULT_PORT}/v1`;
87
+ return [
88
+ `OpenAI-compatible endpoint ready at ${baseUrl}`,
89
+ "Use this as your OpenAI base URL. No API key is required."
90
+ ].join("\n");
91
+ };
92
+ var runCli = async (argv = hideBin(process.argv)) => {
93
+ const args = parseCliArgs(argv);
94
+ const options = toServerOptions(args);
95
+ const existingAuthFile = await findExistingAuthFile(options.authFilePath);
96
+ if (!existingAuthFile) {
97
+ throw new Error(toMissingAuthFileMessage(options.authFilePath));
98
+ }
99
+ const server = await startOpenAIOAuthServer(options);
100
+ console.log(
101
+ toStartupMessage({
102
+ ...options,
103
+ host: server.host,
104
+ port: server.port
105
+ })
106
+ );
107
+ const shutdown = async () => {
108
+ await server.close();
109
+ process.exit(0);
110
+ };
111
+ process.on("SIGINT", () => {
112
+ void shutdown();
113
+ });
114
+ process.on("SIGTERM", () => {
115
+ void shutdown();
116
+ });
117
+ };
118
+
119
+ // src/cli.ts
120
+ void runCli().catch((error) => {
121
+ console.error(
122
+ error instanceof Error ? error.message : "Failed to start openai-oauth."
123
+ );
124
+ process.exit(1);
125
+ });
@@ -0,0 +1,153 @@
1
+ import { Server } from 'node:http';
2
+ import { FetchFunction } from '@ai-sdk/provider-utils';
3
+
4
+ type AuthLoaderOptions = {
5
+ clientId?: string;
6
+ issuer?: string;
7
+ tokenUrl?: string;
8
+ authFilePath?: string;
9
+ fetch: FetchFunction;
10
+ ensureFresh?: boolean;
11
+ now?: () => Date;
12
+ };
13
+
14
+ type JsonRecord = Record<string, unknown>;
15
+ type CodexResponsesStateSnapshot = {
16
+ items: Array<{
17
+ id: string;
18
+ item: JsonRecord;
19
+ }>;
20
+ responses: Array<{
21
+ id: string;
22
+ input: unknown[];
23
+ output: JsonRecord[];
24
+ }>;
25
+ };
26
+ type CodexResponsesStateOptions = {
27
+ snapshot?: CodexResponsesStateSnapshot;
28
+ onChange?: (snapshot: CodexResponsesStateSnapshot) => void;
29
+ };
30
+ declare class CodexResponsesState {
31
+ private readonly items;
32
+ private readonly responses;
33
+ private readonly pendingCaptures;
34
+ private readonly onChange?;
35
+ constructor(options?: CodexResponsesStateOptions);
36
+ waitForPendingCaptures(): Promise<void>;
37
+ trackPendingCapture(promise: Promise<void>): void;
38
+ requiresCachedState(body: JsonRecord): boolean;
39
+ expandRequestBody(body: JsonRecord): JsonRecord;
40
+ rememberResponse(response: unknown, requestBody?: JsonRecord): void;
41
+ snapshot(): CodexResponsesStateSnapshot;
42
+ private expandInput;
43
+ private emitChange;
44
+ }
45
+
46
+ type CodexOAuthSettings = Omit<AuthLoaderOptions, "fetch"> & {
47
+ baseURL?: string;
48
+ fetch?: FetchFunction;
49
+ headers?: Record<string, string>;
50
+ instructions?: string;
51
+ store?: boolean;
52
+ responsesState?: CodexResponsesState | false;
53
+ };
54
+
55
+ type JsonValue = null | boolean | number | string | JsonValue[] | JsonObject;
56
+ type JsonObject = {
57
+ [key: string]: JsonValue;
58
+ };
59
+ type ChatToolDefinition = {
60
+ type?: string;
61
+ function?: {
62
+ name?: string;
63
+ description?: string;
64
+ parameters?: JsonObject;
65
+ };
66
+ };
67
+ type ChatToolChoice = "auto" | "none" | "required" | {
68
+ type?: string;
69
+ function?: {
70
+ name?: string;
71
+ };
72
+ };
73
+ type ChatMessage = {
74
+ role?: string;
75
+ content?: unknown;
76
+ tool_calls?: Array<{
77
+ id?: string;
78
+ type?: string;
79
+ function?: {
80
+ name?: string;
81
+ arguments?: string;
82
+ };
83
+ }>;
84
+ tool_call_id?: string;
85
+ };
86
+ type ChatRequest = {
87
+ model?: string;
88
+ messages?: ChatMessage[];
89
+ stream?: boolean;
90
+ tools?: ChatToolDefinition[];
91
+ tool_choice?: ChatToolChoice;
92
+ temperature?: number;
93
+ top_p?: number;
94
+ stop?: string | string[];
95
+ max_tokens?: number;
96
+ parallel_tool_calls?: boolean;
97
+ reasoning_effort?: "none" | "minimal" | "low" | "medium" | "high";
98
+ };
99
+ type ChatRequestSummary = {
100
+ bodyKeys: string[];
101
+ messageCount: number;
102
+ messageRoles: string[];
103
+ model?: string;
104
+ reasoningEffort?: ChatRequest["reasoning_effort"];
105
+ stream: boolean;
106
+ toolCount: number;
107
+ };
108
+ type UsageLike = {
109
+ inputTokens?: number;
110
+ outputTokens?: number;
111
+ totalTokens?: number;
112
+ reasoningTokens?: number;
113
+ cachedInputTokens?: number;
114
+ };
115
+ type OpenAIOAuthServerLogEvent = ({
116
+ type: "chat_request";
117
+ requestId: string;
118
+ path: "/v1/chat/completions";
119
+ } & ChatRequestSummary) | {
120
+ type: "chat_response";
121
+ durationMs: number;
122
+ finishReason?: string;
123
+ path: "/v1/chat/completions";
124
+ requestId: string;
125
+ status: number;
126
+ stream: boolean;
127
+ usage: UsageLike;
128
+ } | {
129
+ type: "chat_error";
130
+ durationMs: number;
131
+ message: string;
132
+ path: "/v1/chat/completions";
133
+ requestId: string;
134
+ };
135
+ declare const defaultOpenAIOAuthModels: readonly string[];
136
+ type OpenAIOAuthServerOptions = Omit<CodexOAuthSettings, "responsesState"> & {
137
+ host?: string;
138
+ port?: number;
139
+ models?: string[];
140
+ requestLogger?: (event: OpenAIOAuthServerLogEvent) => void;
141
+ };
142
+ type RunningOpenAIOAuthServer = {
143
+ server: Server;
144
+ host: string;
145
+ port: number;
146
+ url: string;
147
+ close: () => Promise<void>;
148
+ };
149
+
150
+ declare const createOpenAIOAuthFetchHandler: (settings?: OpenAIOAuthServerOptions) => ((request: Request) => Promise<Response>);
151
+ declare const startOpenAIOAuthServer: (settings?: OpenAIOAuthServerOptions) => Promise<RunningOpenAIOAuthServer>;
152
+
153
+ export { type OpenAIOAuthServerLogEvent, type OpenAIOAuthServerOptions, type RunningOpenAIOAuthServer, createOpenAIOAuthFetchHandler, defaultOpenAIOAuthModels, startOpenAIOAuthServer };
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ import {
2
+ createOpenAIOAuthFetchHandler,
3
+ defaultOpenAIOAuthModels,
4
+ startOpenAIOAuthServer
5
+ } from "./chunk-VZQM4BY4.js";
6
+ export {
7
+ createOpenAIOAuthFetchHandler,
8
+ defaultOpenAIOAuthModels,
9
+ startOpenAIOAuthServer
10
+ };
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "openai-oauth",
3
+ "version": "0.0.1",
4
+ "description": "Free OpenAI API access with your ChatGPT account.",
5
+ "type": "module",
6
+ "bin": {
7
+ "openai-oauth": "./dist/cli.js"
8
+ },
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup src/index.ts src/cli.ts --format esm --dts --outDir dist --clean",
20
+ "dev": "bun ./src/cli.ts",
21
+ "typecheck": "tsc --noEmit",
22
+ "test": "vitest run",
23
+ "test:live": "LIVE_CODEX_E2E=1 vitest run test/live.e2e.test.ts"
24
+ },
25
+ "dependencies": {
26
+ "ai": "6.0.0-beta.138",
27
+ "yargs": "^17.7.2"
28
+ },
29
+ "devDependencies": {
30
+ "@ai-sdk/openai": "3.0.0-beta.87",
31
+ "@types/node": "20.17.24",
32
+ "@types/yargs": "^17.0.33",
33
+ "openai-oauth-core": "workspace:*",
34
+ "openai-oauth-provider": "workspace:*",
35
+ "typescript": "latest",
36
+ "vitest": "latest",
37
+ "zod": "^3.25.76"
38
+ },
39
+ "author": "EvanZhouDev",
40
+ "license": "AGPL-3.0-only",
41
+ "bugs": {
42
+ "url": "https://github.com/EvanZhouDev/openai-oauth/issues"
43
+ },
44
+ "homepage": "https://github.com/EvanZhouDev/openai-oauth#readme"
45
+ }