openai-oauth 2.0.0-beta.3 → 2.0.0-beta.4
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 +3 -1
- package/dist/{chunk-KROVQ42X.js → chunk-INHW7GRB.js} +34 -107
- package/dist/cli.js +125 -30
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/package.json +10 -7
package/README.md
CHANGED
|
@@ -50,10 +50,12 @@ Common flags:
|
|
|
50
50
|
| Host binding | `--host` | `127.0.0.1` |
|
|
51
51
|
| Port | `--port` | `10531` |
|
|
52
52
|
| Model allowlist | `--models` | Account-specific Codex models discovered from ChatGPT |
|
|
53
|
-
| Auth file path | `--oauth-file` | `$
|
|
53
|
+
| Auth file path | `--oauth-file` | `$CODEX_HOME/auth.json` or `~/.codex/auth.json` |
|
|
54
54
|
| Open browser | `--open` / `--no-open` | `--open` |
|
|
55
55
|
| Login timeout | `--login-timeout-ms` | `300000` |
|
|
56
56
|
|
|
57
|
+
Binding `--host` beyond loopback exposes the proxy to your network. Anyone who can reach that port can make requests with your ChatGPT account.
|
|
58
|
+
|
|
57
59
|
Login listens on loopback and uses `http://localhost:1455/auth/callback`, the local callback URL accepted by OpenAI OAuth.
|
|
58
60
|
|
|
59
61
|
The CLI resolves the latest published Codex client version automatically. Advanced flags also exist for overriding it, the upstream Codex base URL, OAuth client id, and OAuth token URL.
|
|
@@ -3,7 +3,9 @@ import { createServer } from "http";
|
|
|
3
3
|
import {
|
|
4
4
|
createOpenAIOAuth
|
|
5
5
|
} from "@openai-oauth/ai-sdk";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
createOpenAIOAuthTransport
|
|
8
|
+
} from "@openai-oauth/core";
|
|
7
9
|
import { openaiCredentials } from "@openai-oauth/local";
|
|
8
10
|
|
|
9
11
|
// src/chat-completions.ts
|
|
@@ -25,11 +27,6 @@ var sseHeaders = {
|
|
|
25
27
|
connection: "keep-alive",
|
|
26
28
|
"x-accel-buffering": "no"
|
|
27
29
|
};
|
|
28
|
-
var corsHeaders = {
|
|
29
|
-
"access-control-allow-origin": "*",
|
|
30
|
-
"access-control-allow-methods": "GET,POST,OPTIONS",
|
|
31
|
-
"access-control-allow-headers": "authorization,content-type"
|
|
32
|
-
};
|
|
33
30
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
34
31
|
var isJsonValue = (value) => {
|
|
35
32
|
if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
@@ -46,8 +43,7 @@ var isJsonValue = (value) => {
|
|
|
46
43
|
var toJsonResponse = (body, status = 200) => new Response(JSON.stringify(body), {
|
|
47
44
|
status,
|
|
48
45
|
headers: {
|
|
49
|
-
...jsonHeaders
|
|
50
|
-
...corsHeaders
|
|
46
|
+
...jsonHeaders
|
|
51
47
|
}
|
|
52
48
|
});
|
|
53
49
|
var toErrorResponse = (message, status = 400, type = "invalid_request_error") => toJsonResponse(
|
|
@@ -97,9 +93,6 @@ var copyUpstreamResponse = (response) => {
|
|
|
97
93
|
const headers = new Headers(response.headers);
|
|
98
94
|
headers.delete("content-encoding");
|
|
99
95
|
headers.delete("content-length");
|
|
100
|
-
for (const [key, value] of Object.entries(corsHeaders)) {
|
|
101
|
-
headers.set(key, value);
|
|
102
|
-
}
|
|
103
96
|
if (!headers.has("content-type")) {
|
|
104
97
|
headers.set("content-type", "application/json; charset=utf-8");
|
|
105
98
|
}
|
|
@@ -584,10 +577,7 @@ var streamChatCompletions = async (request, provider, logContext) => {
|
|
|
584
577
|
});
|
|
585
578
|
return new Response(stream, {
|
|
586
579
|
status: 200,
|
|
587
|
-
headers:
|
|
588
|
-
...sseHeaders,
|
|
589
|
-
...corsHeaders
|
|
590
|
-
}
|
|
580
|
+
headers: sseHeaders
|
|
591
581
|
});
|
|
592
582
|
};
|
|
593
583
|
|
|
@@ -719,11 +709,8 @@ var handleImageEditRequest = async (request, client) => {
|
|
|
719
709
|
};
|
|
720
710
|
|
|
721
711
|
// src/models.ts
|
|
722
|
-
var MODELS_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
723
|
-
var IMAGE_MODEL_ID = "gpt-image-2";
|
|
724
712
|
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
725
713
|
var uniqueStrings = (values) => [...new Set(values)];
|
|
726
|
-
var withImageModel = (models) => uniqueStrings([...models, IMAGE_MODEL_ID]);
|
|
727
714
|
var modelListError = (bodyText) => {
|
|
728
715
|
try {
|
|
729
716
|
const parsed = JSON.parse(bodyText);
|
|
@@ -755,41 +742,16 @@ var readModelList = async (client) => {
|
|
|
755
742
|
if (models.length === 0) {
|
|
756
743
|
throw new Error("Codex returned an empty models list.");
|
|
757
744
|
}
|
|
758
|
-
return
|
|
745
|
+
return models;
|
|
759
746
|
};
|
|
760
747
|
var resolveOpenAIOAuthModels = async (client, configuredModels) => Array.isArray(configuredModels) && configuredModels.length > 0 ? uniqueStrings(configuredModels) : readModelList(client);
|
|
761
|
-
var createModelResolver = (client, configuredModels) =>
|
|
762
|
-
let cachedModels;
|
|
763
|
-
let cacheExpiresAt = 0;
|
|
764
|
-
let inflight;
|
|
765
|
-
return async () => {
|
|
766
|
-
const now = Date.now();
|
|
767
|
-
if (cachedModels && now < cacheExpiresAt) {
|
|
768
|
-
return [...cachedModels];
|
|
769
|
-
}
|
|
770
|
-
if (inflight) {
|
|
771
|
-
return [...await inflight];
|
|
772
|
-
}
|
|
773
|
-
inflight = resolveOpenAIOAuthModels(client, configuredModels).then((models) => {
|
|
774
|
-
cachedModels = models;
|
|
775
|
-
cacheExpiresAt = Date.now() + MODELS_CACHE_TTL_MS;
|
|
776
|
-
inflight = void 0;
|
|
777
|
-
return models;
|
|
778
|
-
}).catch((error) => {
|
|
779
|
-
inflight = void 0;
|
|
780
|
-
throw error;
|
|
781
|
-
});
|
|
782
|
-
return [...await inflight];
|
|
783
|
-
};
|
|
784
|
-
};
|
|
748
|
+
var createModelResolver = (client, configuredModels) => () => resolveOpenAIOAuthModels(client, configuredModels);
|
|
785
749
|
|
|
786
750
|
// src/responses.ts
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
} from "@openai-oauth/core";
|
|
792
|
-
var handleResponsesRequest = async (request, settings, client) => {
|
|
751
|
+
var usesServerReplayState = (body) => typeof body.previous_response_id === "string" || Array.isArray(body.input) && body.input.some(
|
|
752
|
+
(item) => isRecord(item) && item.type === "item_reference" && typeof item.id === "string"
|
|
753
|
+
);
|
|
754
|
+
var handleResponsesRequest = async (request, client) => {
|
|
793
755
|
const body = await request.json();
|
|
794
756
|
if (!isRecord(body)) {
|
|
795
757
|
return toErrorResponse("Request body must be a JSON object.");
|
|
@@ -799,45 +761,19 @@ var handleResponsesRequest = async (request, settings, client) => {
|
|
|
799
761
|
"Stateless Codex responses endpoint does not support `previous_response_id` or `item_reference`. Replay the full conversation history in `input` on each request."
|
|
800
762
|
);
|
|
801
763
|
}
|
|
802
|
-
const wantsStream = body.stream === true;
|
|
803
764
|
const upstream = await client.request("/responses", {
|
|
804
765
|
method: "POST",
|
|
805
766
|
headers: {
|
|
806
767
|
"Content-Type": "application/json"
|
|
807
768
|
},
|
|
808
|
-
body: JSON.stringify(
|
|
809
|
-
|
|
810
|
-
forceStream: true,
|
|
811
|
-
instructions: settings.instructions
|
|
812
|
-
})
|
|
813
|
-
)
|
|
769
|
+
body: JSON.stringify(body),
|
|
770
|
+
signal: request.signal
|
|
814
771
|
});
|
|
815
|
-
|
|
816
|
-
return copyUpstreamResponse(upstream);
|
|
817
|
-
}
|
|
818
|
-
if (wantsStream) {
|
|
819
|
-
return new Response(upstream.body, {
|
|
820
|
-
status: upstream.status,
|
|
821
|
-
headers: {
|
|
822
|
-
...sseHeaders,
|
|
823
|
-
...corsHeaders
|
|
824
|
-
}
|
|
825
|
-
});
|
|
826
|
-
}
|
|
827
|
-
const completed = await collectCompletedResponseFromSse(
|
|
828
|
-
upstream.body ?? new ReadableStream()
|
|
829
|
-
);
|
|
830
|
-
return toJsonResponse(completed);
|
|
772
|
+
return copyUpstreamResponse(upstream);
|
|
831
773
|
};
|
|
832
774
|
|
|
833
775
|
// src/server.ts
|
|
834
|
-
var handleRoutes = async (request,
|
|
835
|
-
if (request.method === "OPTIONS") {
|
|
836
|
-
return new Response(null, {
|
|
837
|
-
status: 204,
|
|
838
|
-
headers: corsHeaders
|
|
839
|
-
});
|
|
840
|
-
}
|
|
776
|
+
var handleRoutes = async (request, provider, client, resolveModels, requestLogger) => {
|
|
841
777
|
const url = new URL(request.url);
|
|
842
778
|
if (request.method === "GET" && url.pathname === "/health") {
|
|
843
779
|
return toJsonResponse({
|
|
@@ -866,7 +802,7 @@ var handleRoutes = async (request, settings, provider, client, resolveModels, re
|
|
|
866
802
|
}
|
|
867
803
|
}
|
|
868
804
|
if (request.method === "POST" && url.pathname === "/v1/responses") {
|
|
869
|
-
return handleResponsesRequest(request,
|
|
805
|
+
return handleResponsesRequest(request, client);
|
|
870
806
|
}
|
|
871
807
|
if (request.method === "POST" && url.pathname === "/v1/chat/completions") {
|
|
872
808
|
return handleChatCompletionsRequest(request, provider, requestLogger);
|
|
@@ -879,22 +815,21 @@ var handleRoutes = async (request, settings, provider, client, resolveModels, re
|
|
|
879
815
|
}
|
|
880
816
|
return toErrorResponse("Route not found.", 404, "not_found_error");
|
|
881
817
|
};
|
|
882
|
-
var
|
|
818
|
+
var createOpenAIOAuthRuntime = (settings = {}) => {
|
|
883
819
|
const auth = openaiCredentials(settings);
|
|
884
820
|
const sharedSettings = {
|
|
885
821
|
...settings,
|
|
886
822
|
auth: () => auth.getSession(),
|
|
887
823
|
responsesState: false
|
|
888
824
|
};
|
|
889
|
-
const client =
|
|
890
|
-
const provider = createOpenAIOAuth(
|
|
825
|
+
const client = createOpenAIOAuthTransport(sharedSettings);
|
|
826
|
+
const provider = createOpenAIOAuth(client);
|
|
891
827
|
const resolveModels = createModelResolver(client, settings.models);
|
|
892
828
|
const requestLogger = createRequestLogger(settings);
|
|
893
|
-
|
|
829
|
+
const handler = async (request) => {
|
|
894
830
|
try {
|
|
895
831
|
return await handleRoutes(
|
|
896
832
|
request,
|
|
897
|
-
settings,
|
|
898
833
|
provider,
|
|
899
834
|
client,
|
|
900
835
|
resolveModels,
|
|
@@ -908,11 +843,15 @@ var createOpenAIOAuthFetchHandler = (settings = {}) => {
|
|
|
908
843
|
);
|
|
909
844
|
}
|
|
910
845
|
};
|
|
846
|
+
return { handler, resolveModels };
|
|
911
847
|
};
|
|
848
|
+
var createOpenAIOAuthFetchHandler = (settings = {}) => createOpenAIOAuthRuntime(settings).handler;
|
|
912
849
|
var startOpenAIOAuthServer = async (settings = {}) => {
|
|
913
850
|
const host = settings.host ?? DEFAULT_HOST;
|
|
914
851
|
const port = settings.port ?? DEFAULT_PORT;
|
|
915
|
-
const
|
|
852
|
+
const runtime = createOpenAIOAuthRuntime(settings);
|
|
853
|
+
const models = await runtime.resolveModels();
|
|
854
|
+
const handler = runtime.handler;
|
|
916
855
|
const server = createServer(async (req, res) => {
|
|
917
856
|
try {
|
|
918
857
|
const request = await toWebRequest(req, { host, port });
|
|
@@ -940,6 +879,7 @@ var startOpenAIOAuthServer = async (settings = {}) => {
|
|
|
940
879
|
host: address.host,
|
|
941
880
|
port: address.port,
|
|
942
881
|
url: `http://${address.host}:${address.port}/v1`,
|
|
882
|
+
models,
|
|
943
883
|
close: () => new Promise((resolve, reject) => {
|
|
944
884
|
server.close((error) => {
|
|
945
885
|
if (error) {
|
|
@@ -958,9 +898,11 @@ import { createServer as createServer2 } from "http";
|
|
|
958
898
|
import { createConnection } from "net";
|
|
959
899
|
import {
|
|
960
900
|
createOpenAIOAuthRequest,
|
|
961
|
-
exchangeOpenAIOAuthCode
|
|
962
|
-
saveAuthTokens
|
|
901
|
+
exchangeOpenAIOAuthCode
|
|
963
902
|
} from "@openai-oauth/core";
|
|
903
|
+
import {
|
|
904
|
+
saveAuthTokens
|
|
905
|
+
} from "@openai-oauth/local/auth-file";
|
|
964
906
|
|
|
965
907
|
// src/callback-success.html?raw
|
|
966
908
|
var callback_success_default = `<!doctype html>
|
|
@@ -1155,24 +1097,10 @@ var isAddressUnavailableError = (error) => error instanceof Error && "code" in e
|
|
|
1155
1097
|
String(error.code)
|
|
1156
1098
|
);
|
|
1157
1099
|
var createLoginCancelledError = () => new Error("OpenAI OAuth login cancelled.");
|
|
1158
|
-
var toCallbackHtml = (title, message) =>
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
<title>${title}</title>
|
|
1163
|
-
<style>
|
|
1164
|
-
body {
|
|
1165
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
1166
|
-
margin: 3rem;
|
|
1167
|
-
line-height: 1.5;
|
|
1168
|
-
}
|
|
1169
|
-
</style>
|
|
1170
|
-
</head>
|
|
1171
|
-
<body>
|
|
1172
|
-
<h1>${title}</h1>
|
|
1173
|
-
<p>${message}</p>
|
|
1174
|
-
</body>
|
|
1175
|
-
</html>`;
|
|
1100
|
+
var toCallbackHtml = (title, message) => callback_success_default.replace("Sign-in complete", title).replace(
|
|
1101
|
+
/Your ChatGPT credentials are saved locally\. You can close this\s+window and return to your terminal\./,
|
|
1102
|
+
message
|
|
1103
|
+
);
|
|
1176
1104
|
var htmlHeaders = {
|
|
1177
1105
|
"Content-Type": "text/html; charset=utf-8",
|
|
1178
1106
|
Connection: "close"
|
|
@@ -1393,7 +1321,6 @@ var runOpenAIOAuthLogin = async (options = {}) => {
|
|
|
1393
1321
|
};
|
|
1394
1322
|
|
|
1395
1323
|
export {
|
|
1396
|
-
resolveOpenAIOAuthModels,
|
|
1397
1324
|
DEFAULT_PORT,
|
|
1398
1325
|
createOpenAIOAuthFetchHandler,
|
|
1399
1326
|
startOpenAIOAuthServer,
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DEFAULT_PORT,
|
|
4
|
-
resolveOpenAIOAuthModels,
|
|
5
4
|
runOpenAIOAuthLogin,
|
|
6
5
|
startOpenAIOAuthServer
|
|
7
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-INHW7GRB.js";
|
|
8
7
|
|
|
9
8
|
// src/cli-app.ts
|
|
10
9
|
import { access } from "fs/promises";
|
|
@@ -12,7 +11,7 @@ import { createInterface } from "readline/promises";
|
|
|
12
11
|
import {
|
|
13
12
|
resolveAuthFileCandidates,
|
|
14
13
|
resolveCodexAuthFilePath
|
|
15
|
-
} from "@openai-oauth/
|
|
14
|
+
} from "@openai-oauth/local/auth-file";
|
|
16
15
|
import yargs from "yargs";
|
|
17
16
|
import { hideBin } from "yargs/helpers";
|
|
18
17
|
|
|
@@ -362,7 +361,7 @@ var activateCliRuntime = async (lock, options) => {
|
|
|
362
361
|
}
|
|
363
362
|
if (request.method === "POST" && request.url === "/stop") {
|
|
364
363
|
response.writeHead(202).end();
|
|
365
|
-
setImmediate(
|
|
364
|
+
setImmediate(options.onStop);
|
|
366
365
|
return;
|
|
367
366
|
}
|
|
368
367
|
response.writeHead(404).end();
|
|
@@ -668,8 +667,6 @@ var sendDetachedError = (message) => new Promise((resolve) => {
|
|
|
668
667
|
});
|
|
669
668
|
|
|
670
669
|
// src/cli-worker.ts
|
|
671
|
-
import { createCodexOAuthClient } from "@openai-oauth/core";
|
|
672
|
-
import { openaiCredentials } from "@openai-oauth/local";
|
|
673
670
|
var isWorkerCommand = (value) => {
|
|
674
671
|
if (typeof value !== "object" || value == null) {
|
|
675
672
|
return false;
|
|
@@ -681,13 +678,6 @@ var startCliInstance = async (options, mode, version, onRemoteStop) => {
|
|
|
681
678
|
const lock = await acquireCliRuntimeLock();
|
|
682
679
|
let server;
|
|
683
680
|
try {
|
|
684
|
-
const auth = openaiCredentials(options);
|
|
685
|
-
const client = createCodexOAuthClient({
|
|
686
|
-
...options,
|
|
687
|
-
auth: () => auth.getSession(),
|
|
688
|
-
responsesState: false
|
|
689
|
-
});
|
|
690
|
-
const models = await resolveOpenAIOAuthModels(client, options.models);
|
|
691
681
|
server = await startOpenAIOAuthServer(options);
|
|
692
682
|
const runtime = await activateCliRuntime(lock, {
|
|
693
683
|
mode,
|
|
@@ -695,7 +685,7 @@ var startCliInstance = async (options, mode, version, onRemoteStop) => {
|
|
|
695
685
|
version,
|
|
696
686
|
onStop: onRemoteStop
|
|
697
687
|
});
|
|
698
|
-
return { server, runtime, models };
|
|
688
|
+
return { server, runtime, models: server.models };
|
|
699
689
|
} catch (error) {
|
|
700
690
|
await server?.close().catch(() => void 0);
|
|
701
691
|
await lock.release();
|
|
@@ -724,9 +714,12 @@ var runCliWorker = async (options, initialMode, version) => {
|
|
|
724
714
|
}
|
|
725
715
|
process.exit(0);
|
|
726
716
|
};
|
|
727
|
-
instance = await startCliInstance(
|
|
728
|
-
|
|
729
|
-
|
|
717
|
+
instance = await startCliInstance(
|
|
718
|
+
options,
|
|
719
|
+
initialMode,
|
|
720
|
+
version,
|
|
721
|
+
() => shutdown("remote")
|
|
722
|
+
);
|
|
730
723
|
const onMessage = (value) => {
|
|
731
724
|
if (!isWorkerCommand(value) || stopping) {
|
|
732
725
|
return;
|
|
@@ -752,7 +745,7 @@ var runCliWorker = async (options, initialMode, version) => {
|
|
|
752
745
|
void shutdown("disconnect");
|
|
753
746
|
}
|
|
754
747
|
};
|
|
755
|
-
const onSignal = () =>
|
|
748
|
+
const onSignal = () => shutdown("signal");
|
|
756
749
|
process.on("message", onMessage);
|
|
757
750
|
process.once("disconnect", onDisconnect);
|
|
758
751
|
process.once("SIGINT", onSignal);
|
|
@@ -762,17 +755,19 @@ var runCliWorker = async (options, initialMode, version) => {
|
|
|
762
755
|
};
|
|
763
756
|
|
|
764
757
|
// src/update-check.ts
|
|
765
|
-
var
|
|
758
|
+
var registryUrl = "https://registry.npmjs.org/openai-oauth/latest";
|
|
766
759
|
var normalizeVersion = (value) => {
|
|
767
760
|
if (typeof value !== "string") {
|
|
768
761
|
return void 0;
|
|
769
762
|
}
|
|
770
|
-
const match = value.trim().match(/^\d+\.\d+\.\d
|
|
763
|
+
const match = value.trim().match(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/);
|
|
771
764
|
return match?.[0];
|
|
772
765
|
};
|
|
773
766
|
var compareSemver = (left, right) => {
|
|
774
|
-
const
|
|
775
|
-
const
|
|
767
|
+
const [leftCore = "", leftPrerelease] = left.split("-", 2);
|
|
768
|
+
const [rightCore = "", rightPrerelease] = right.split("-", 2);
|
|
769
|
+
const leftParts = leftCore.split(".").map(Number);
|
|
770
|
+
const rightParts = rightCore.split(".").map(Number);
|
|
776
771
|
for (let index = 0; index < 3; index += 1) {
|
|
777
772
|
const leftPart = leftParts[index] ?? 0;
|
|
778
773
|
const rightPart = rightParts[index] ?? 0;
|
|
@@ -783,6 +778,26 @@ var compareSemver = (left, right) => {
|
|
|
783
778
|
return 1;
|
|
784
779
|
}
|
|
785
780
|
}
|
|
781
|
+
if (leftPrerelease == null) return rightPrerelease == null ? 0 : 1;
|
|
782
|
+
if (rightPrerelease == null) return -1;
|
|
783
|
+
const leftIdentifiers = leftPrerelease.split(".");
|
|
784
|
+
const rightIdentifiers = rightPrerelease.split(".");
|
|
785
|
+
const length = Math.max(leftIdentifiers.length, rightIdentifiers.length);
|
|
786
|
+
for (let index = 0; index < length; index += 1) {
|
|
787
|
+
const leftIdentifier = leftIdentifiers[index];
|
|
788
|
+
const rightIdentifier = rightIdentifiers[index];
|
|
789
|
+
if (leftIdentifier == null) return -1;
|
|
790
|
+
if (rightIdentifier == null) return 1;
|
|
791
|
+
if (leftIdentifier === rightIdentifier) continue;
|
|
792
|
+
const leftNumber = /^\d+$/.test(leftIdentifier) ? Number(leftIdentifier) : void 0;
|
|
793
|
+
const rightNumber = /^\d+$/.test(rightIdentifier) ? Number(rightIdentifier) : void 0;
|
|
794
|
+
if (leftNumber != null && rightNumber != null) {
|
|
795
|
+
return leftNumber < rightNumber ? -1 : 1;
|
|
796
|
+
}
|
|
797
|
+
if (leftNumber != null) return -1;
|
|
798
|
+
if (rightNumber != null) return 1;
|
|
799
|
+
return leftIdentifier < rightIdentifier ? -1 : 1;
|
|
800
|
+
}
|
|
786
801
|
return 0;
|
|
787
802
|
};
|
|
788
803
|
var fetchLatestVersion = async (fetchImpl, signal) => {
|
|
@@ -795,7 +810,7 @@ var fetchLatestVersion = async (fetchImpl, signal) => {
|
|
|
795
810
|
if (signal) {
|
|
796
811
|
requestInit.signal = signal;
|
|
797
812
|
}
|
|
798
|
-
const response = await fetchImpl(
|
|
813
|
+
const response = await fetchImpl(registryUrl, requestInit);
|
|
799
814
|
if (!response.ok) {
|
|
800
815
|
return void 0;
|
|
801
816
|
}
|
|
@@ -834,10 +849,82 @@ Run \`npx openai-oauth@latest\` to use the newest version.`
|
|
|
834
849
|
);
|
|
835
850
|
};
|
|
836
851
|
|
|
852
|
+
// package.json
|
|
853
|
+
var package_default = {
|
|
854
|
+
name: "openai-oauth",
|
|
855
|
+
version: "2.0.0-beta.4",
|
|
856
|
+
description: "Free OpenAI API access with your ChatGPT account.",
|
|
857
|
+
keywords: [
|
|
858
|
+
"openai",
|
|
859
|
+
"oauth",
|
|
860
|
+
"chatgpt",
|
|
861
|
+
"codex",
|
|
862
|
+
"cli",
|
|
863
|
+
"openai-compatible"
|
|
864
|
+
],
|
|
865
|
+
type: "module",
|
|
866
|
+
engines: {
|
|
867
|
+
node: ">=20"
|
|
868
|
+
},
|
|
869
|
+
sideEffects: false,
|
|
870
|
+
main: "./dist/index.js",
|
|
871
|
+
types: "./dist/index.d.ts",
|
|
872
|
+
bin: {
|
|
873
|
+
"openai-oauth": "dist/cli.js"
|
|
874
|
+
},
|
|
875
|
+
exports: {
|
|
876
|
+
".": {
|
|
877
|
+
types: "./dist/index.d.ts",
|
|
878
|
+
import: "./dist/index.js",
|
|
879
|
+
default: "./dist/index.js"
|
|
880
|
+
}
|
|
881
|
+
},
|
|
882
|
+
files: [
|
|
883
|
+
"dist",
|
|
884
|
+
"README.md",
|
|
885
|
+
"LICENSE"
|
|
886
|
+
],
|
|
887
|
+
scripts: {
|
|
888
|
+
build: "tsup src/index.ts src/cli.ts --format esm --dts --outDir dist --clean --loader .html=text",
|
|
889
|
+
dev: "bun ./src/cli.ts",
|
|
890
|
+
prepublishOnly: "bun run build",
|
|
891
|
+
typecheck: "tsc --noEmit",
|
|
892
|
+
test: "vitest run",
|
|
893
|
+
"test:live": "LIVE_CODEX_E2E=1 vitest run test/live.e2e.test.ts"
|
|
894
|
+
},
|
|
895
|
+
dependencies: {
|
|
896
|
+
"@openai-oauth/ai-sdk": "workspace:*",
|
|
897
|
+
"@openai-oauth/core": "workspace:*",
|
|
898
|
+
"@openai-oauth/local": "workspace:*",
|
|
899
|
+
ai: "6.0.116",
|
|
900
|
+
yargs: "17.7.3"
|
|
901
|
+
},
|
|
902
|
+
devDependencies: {
|
|
903
|
+
"@ai-sdk/openai": "3.0.41",
|
|
904
|
+
"@types/node": "20.17.24",
|
|
905
|
+
"@types/yargs": "^17.0.33",
|
|
906
|
+
typescript: "5.9.2",
|
|
907
|
+
vitest: "4.1.10",
|
|
908
|
+
zod: "^3.25.76"
|
|
909
|
+
},
|
|
910
|
+
author: "EvanZhouDev",
|
|
911
|
+
license: "AGPL-3.0-only",
|
|
912
|
+
repository: {
|
|
913
|
+
type: "git",
|
|
914
|
+
url: "git+https://github.com/EvanZhouDev/openai-oauth.git",
|
|
915
|
+
directory: "packages/openai-oauth"
|
|
916
|
+
},
|
|
917
|
+
bugs: {
|
|
918
|
+
url: "https://github.com/EvanZhouDev/openai-oauth/issues"
|
|
919
|
+
},
|
|
920
|
+
homepage: "https://github.com/EvanZhouDev/openai-oauth#readme"
|
|
921
|
+
};
|
|
922
|
+
|
|
837
923
|
// src/version.ts
|
|
838
|
-
var packageVersion =
|
|
924
|
+
var packageVersion = package_default.version;
|
|
839
925
|
|
|
840
926
|
// src/cli-app.ts
|
|
927
|
+
var cliCommand = "npx openai-oauth@latest";
|
|
841
928
|
var defaultUpdateCheckWarning = (message) => {
|
|
842
929
|
console.error(message);
|
|
843
930
|
};
|
|
@@ -852,12 +939,12 @@ var helpLines = [
|
|
|
852
939
|
"Free OpenAI API access with your ChatGPT account.",
|
|
853
940
|
"",
|
|
854
941
|
"Usage",
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
942
|
+
` ${cliCommand} [options]`,
|
|
943
|
+
` ${cliCommand} --detach [options]`,
|
|
944
|
+
` ${cliCommand} status`,
|
|
945
|
+
` ${cliCommand} logs [--follow]`,
|
|
946
|
+
` ${cliCommand} stop`,
|
|
947
|
+
` ${cliCommand} login [options]`,
|
|
861
948
|
"",
|
|
862
949
|
"Options",
|
|
863
950
|
" --host <host> Proxy host. Login callback always listens on loopback.",
|
|
@@ -1041,6 +1128,13 @@ var toMissingAuthFileMessage = (authFilePath) => {
|
|
|
1041
1128
|
var runUpdateCheck = () => checkForOpenAIOAuthUpdates(packageVersion, {
|
|
1042
1129
|
onWarning: defaultUpdateCheckWarning
|
|
1043
1130
|
});
|
|
1131
|
+
var warnAboutNetworkBinding = (host) => {
|
|
1132
|
+
if (host && host !== "127.0.0.1" && host !== "localhost" && host !== "::1") {
|
|
1133
|
+
console.warn(
|
|
1134
|
+
`Warning: --host ${host} exposes OpenAI OAuth to your network. Anyone who can reach this port can make requests with your ChatGPT account.`
|
|
1135
|
+
);
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1044
1138
|
var createLoginCancellation = () => {
|
|
1045
1139
|
const abortController = new AbortController();
|
|
1046
1140
|
let signalName;
|
|
@@ -1348,6 +1442,7 @@ var runCli = async (argv = hideBin(process.argv)) => {
|
|
|
1348
1442
|
}
|
|
1349
1443
|
const updateCheck = runUpdateCheck();
|
|
1350
1444
|
const options = toServerOptions(args);
|
|
1445
|
+
warnAboutNetworkBinding(options.host);
|
|
1351
1446
|
const existingAuthFile = await findExistingAuthFile(options.authFilePath);
|
|
1352
1447
|
if (!existingAuthFile) {
|
|
1353
1448
|
await updateCheck;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SavedAuthTokens } from '@openai-oauth/
|
|
1
|
+
import { SavedAuthTokens } from '@openai-oauth/local/auth-file';
|
|
2
2
|
import { Server } from 'node:http';
|
|
3
3
|
import { LocalOpenAIOAuthOptions } from '@openai-oauth/local';
|
|
4
4
|
|
|
@@ -108,6 +108,7 @@ type RunningOpenAIOAuthServer = {
|
|
|
108
108
|
host: string;
|
|
109
109
|
port: number;
|
|
110
110
|
url: string;
|
|
111
|
+
models: string[];
|
|
111
112
|
close: () => Promise<void>;
|
|
112
113
|
};
|
|
113
114
|
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openai-oauth",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.4",
|
|
4
4
|
"description": "Free OpenAI API access with your ChatGPT account.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openai",
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
"openai-compatible"
|
|
12
12
|
],
|
|
13
13
|
"type": "module",
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=20"
|
|
16
|
+
},
|
|
14
17
|
"sideEffects": false,
|
|
15
18
|
"main": "./dist/index.js",
|
|
16
19
|
"types": "./dist/index.d.ts",
|
|
@@ -38,18 +41,18 @@
|
|
|
38
41
|
"test:live": "LIVE_CODEX_E2E=1 vitest run test/live.e2e.test.ts"
|
|
39
42
|
},
|
|
40
43
|
"dependencies": {
|
|
41
|
-
"@openai-oauth/ai-sdk": "2.0.0-beta.
|
|
42
|
-
"@openai-oauth/core": "2.0.0-beta.
|
|
43
|
-
"@openai-oauth/local": "2.0.0-beta.
|
|
44
|
+
"@openai-oauth/ai-sdk": "2.0.0-beta.4",
|
|
45
|
+
"@openai-oauth/core": "2.0.0-beta.4",
|
|
46
|
+
"@openai-oauth/local": "2.0.0-beta.4",
|
|
44
47
|
"ai": "6.0.116",
|
|
45
|
-
"yargs": "
|
|
48
|
+
"yargs": "17.7.3"
|
|
46
49
|
},
|
|
47
50
|
"devDependencies": {
|
|
48
51
|
"@ai-sdk/openai": "3.0.41",
|
|
49
52
|
"@types/node": "20.17.24",
|
|
50
53
|
"@types/yargs": "^17.0.33",
|
|
51
|
-
"typescript": "
|
|
52
|
-
"vitest": "
|
|
54
|
+
"typescript": "5.9.2",
|
|
55
|
+
"vitest": "4.1.10",
|
|
53
56
|
"zod": "^3.25.76"
|
|
54
57
|
},
|
|
55
58
|
"author": "EvanZhouDev",
|