Skip to content

Commit 882955e

Browse files
committed
Merge branch 'main' of github.com:PostHog/Array into feat/repo-selection
2 parents c033f2d + 9dc2071 commit 882955e

File tree

29 files changed

+5915
-453
lines changed

29 files changed

+5915
-453
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"dependencies": {
6363
"@ai-sdk/openai": "^2.0.52",
6464
"@phosphor-icons/react": "^2.1.10",
65-
"@posthog/agent": "1.16.1",
65+
"@posthog/agent": "1.16.4",
6666
"@radix-ui/react-icons": "^1.3.2",
6767
"@radix-ui/themes": "^3.2.1",
6868
"@recallai/desktop-sdk": "^1.3.0",

pnpm-lock.yaml

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/update-openapi-client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const INCLUDED_ENDPOINT_PREFIXES = [
1212
"/api/projects/{project_id}/tasks",
1313
"/api/users/",
1414
"/api/environments/",
15+
"/api/projects/",
1516
];
1617

1718
async function fetchSchema() {

src/api/fetcher.ts

Lines changed: 58 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,72 @@ import type { createApiClient } from "./generated";
22

33
export const buildApiFetcher: (config: {
44
apiToken: string;
5+
onTokenRefresh?: () => Promise<string>;
56
}) => Parameters<typeof createApiClient>[0] = (config) => {
6-
return {
7-
fetch: async (input) => {
8-
const headers = new Headers();
9-
headers.set("Authorization", `Bearer ${config.apiToken}`);
7+
const makeRequest = async (
8+
input: Parameters<Parameters<typeof createApiClient>[0]["fetch"]>[0],
9+
token: string,
10+
): Promise<Response> => {
11+
const headers = new Headers();
12+
headers.set("Authorization", `Bearer ${token}`);
1013

11-
if (input.urlSearchParams) {
12-
input.url.search = input.urlSearchParams.toString();
13-
}
14+
if (input.urlSearchParams) {
15+
input.url.search = input.urlSearchParams.toString();
16+
}
1417

15-
const body = ["post", "put", "patch", "delete"].includes(
16-
input.method.toLowerCase(),
17-
)
18-
? JSON.stringify(input.parameters?.body)
19-
: undefined;
18+
const body = ["post", "put", "patch", "delete"].includes(
19+
input.method.toLowerCase(),
20+
)
21+
? JSON.stringify(input.parameters?.body)
22+
: undefined;
2023

21-
if (body) {
22-
headers.set("Content-Type", "application/json");
23-
}
24+
if (body) {
25+
headers.set("Content-Type", "application/json");
26+
}
2427

25-
if (input.parameters?.header) {
26-
for (const [key, value] of Object.entries(input.parameters.header)) {
27-
if (value != null) {
28-
headers.set(key, String(value));
29-
}
28+
if (input.parameters?.header) {
29+
for (const [key, value] of Object.entries(input.parameters.header)) {
30+
if (value != null) {
31+
headers.set(key, String(value));
3032
}
3133
}
34+
}
3235

33-
let response: Response;
34-
try {
35-
response = await fetch(input.url, {
36-
method: input.method.toUpperCase(),
37-
...(body && { body }),
38-
headers,
39-
...input.overrides,
40-
});
41-
} catch (err) {
42-
throw new Error(
43-
`Network request failed for ${input.method.toUpperCase()} ${input.url}: ${
44-
err instanceof Error ? err.message : String(err)
45-
}`,
46-
{ cause: err instanceof Error ? err : undefined },
47-
);
36+
try {
37+
const response = await fetch(input.url, {
38+
method: input.method.toUpperCase(),
39+
...(body && { body }),
40+
headers,
41+
...input.overrides,
42+
});
43+
44+
return response;
45+
} catch (err) {
46+
throw new Error(
47+
`Network request failed for ${input.method.toUpperCase()} ${input.url}: ${
48+
err instanceof Error ? err.message : String(err)
49+
}`,
50+
{ cause: err instanceof Error ? err : undefined },
51+
);
52+
}
53+
};
54+
55+
return {
56+
fetch: async (input) => {
57+
let response = await makeRequest(input, config.apiToken);
58+
59+
// Handle 401 with automatic token refresh
60+
if (!response.ok && response.status === 401 && config.onTokenRefresh) {
61+
try {
62+
const newToken = await config.onTokenRefresh();
63+
response = await makeRequest(input, newToken);
64+
} catch {
65+
// Token refresh failed - throw the original 401 error
66+
const errorResponse = await response.json();
67+
throw new Error(
68+
`Failed request: [${response.status}] ${JSON.stringify(errorResponse)}`,
69+
);
70+
}
4871
}
4972

5073
if (!response.ok) {

0 commit comments

Comments
 (0)