Skip to content

Commit 08934bf

Browse files
revert(cli): keep HeyGen API traffic on stable prod (#3202)
* Revert "fix(cli): route HeyGen API calls through canary (#3201)" This reverts commit 5545521. * fix(cli): remove remaining EF canary routes
1 parent 5545521 commit 08934bf

10 files changed

Lines changed: 23 additions & 76 deletions

packages/cli/src/auth/client.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,13 @@ describe("auth/client", () => {
8484
authorization: "Bearer at_123",
8585
[HEYGEN_CLI_SOURCE_HEADER]: HEYGEN_CLI_SOURCE,
8686
[HEYGEN_CLIENT_SOURCE_HEADER]: HEYGEN_CLIENT_SOURCE,
87-
heygen_route: "canary",
8887
});
8988
});
9089

9190
it("buildAuthHeaders uses x-api-key for api_key, without the cli-source header but with the tool tag", () => {
9291
expect(buildAuthHeaders(apiKeyCred())).toEqual({
9392
"x-api-key": "hg_x",
9493
[HEYGEN_CLIENT_SOURCE_HEADER]: HEYGEN_CLIENT_SOURCE,
95-
heygen_route: "canary",
9694
});
9795
});
9896

packages/cli/src/auth/client.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import { ErrApi, ErrUnauthenticated, isAuthError } from "./errors.js";
1919
import type { ResolvedCredential } from "./resolver.js";
2020
import { scrubCredentials } from "./scrub.js";
2121
import type { OAuthTokens } from "./store.js";
22-
import { withHeygenCanaryRoute } from "../utils/heygenRoute.js";
2322

2423
const DEFAULT_BASE_URL = "https://api.heygen.com";
2524
export const HEYGEN_CLI_SOURCE_HEADER = "X-HeyGen-Source";
@@ -186,20 +185,17 @@ export class AuthClient {
186185

187186
export function buildAuthHeaders(credential: ResolvedCredential): Record<string, string> {
188187
if (credential.type === "oauth") {
189-
return withHeygenCanaryRoute({
188+
return {
190189
authorization: `Bearer ${credential.access_token}`,
191190
[HEYGEN_CLI_SOURCE_HEADER]: HEYGEN_CLI_SOURCE,
192191
[HEYGEN_CLIENT_SOURCE_HEADER]: HEYGEN_CLIENT_SOURCE,
193-
});
192+
};
194193
}
195194
// API-key traffic keeps the normal billing path; the backend ignores the
196195
// cli-source header for it, so we don't send it (avoids a contradictory
197196
// "cli-source claim on an API-key request"). The tool-attribution header IS
198197
// sent here — an API-key hyperframes call is still hyperframes usage.
199-
return withHeygenCanaryRoute({
200-
"x-api-key": credential.key,
201-
[HEYGEN_CLIENT_SOURCE_HEADER]: HEYGEN_CLIENT_SOURCE,
202-
});
198+
return { "x-api-key": credential.key, [HEYGEN_CLIENT_SOURCE_HEADER]: HEYGEN_CLIENT_SOURCE };
203199
}
204200

205201
async function safeText(res: Response): Promise<string> {

packages/cli/src/auth/oauth.test.ts

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,8 @@ describe("auth/oauth", () => {
173173
it("posts grant_type=refresh_token and persists the response", async () => {
174174
process.env["HEYGEN_API_URL"] = "https://api.test.example";
175175
let capturedBody: string | undefined;
176-
let capturedHeaders: HeadersInit | undefined;
177176
const fetchImpl = (async (_url: string, init?: RequestInit) => {
178177
capturedBody = init?.body as string;
179-
capturedHeaders = init?.headers;
180178
return new Response(
181179
JSON.stringify({
182180
access_token: "new_at",
@@ -194,7 +192,6 @@ describe("auth/oauth", () => {
194192
expect(tokens.refresh_token).toBe("new_rt");
195193
expect(capturedBody).toContain("grant_type=refresh_token");
196194
expect(capturedBody).toContain("refresh_token=old_rt");
197-
expect(capturedHeaders).toMatchObject({ heygen_route: "canary" });
198195

199196
// Should have persisted.
200197
const { credentials } = await readStore();
@@ -298,18 +295,15 @@ describe("auth/oauth", () => {
298295

299296
it("sends token_type_hint when provided", async () => {
300297
let capturedBody = "";
301-
let capturedHeaders: HeadersInit | undefined;
302298
const fetchImpl = (async (_url: string, init?: RequestInit) => {
303299
capturedBody = init?.body as string;
304-
capturedHeaders = init?.headers;
305300
return new Response("", { status: 200 });
306301
}) as unknown as typeof fetch;
307302
await revokeTokens("tok", {
308303
fetchImpl,
309304
token_type_hint: "refresh_token",
310305
});
311306
expect(capturedBody).toContain("token_type_hint=refresh_token");
312-
expect(capturedHeaders).toMatchObject({ heygen_route: "canary" });
313307
});
314308

315309
it("returns silently when client_id is unconfigured (no throw)", async () => {
@@ -343,21 +337,6 @@ describe("auth/oauth", () => {
343337
});
344338

345339
describe("startAuthorizationCodeFlow persistence", () => {
346-
it("routes the authorization-code exchange through canary", async () => {
347-
let capturedHeaders: HeadersInit | undefined;
348-
const fetchImpl = (async (_url: string | URL | Request, init?: RequestInit) => {
349-
capturedHeaders = init?.headers;
350-
return new Response(JSON.stringify({ access_token: "new_at" }), {
351-
status: 200,
352-
headers: { "content-type": "application/json" },
353-
});
354-
}) as typeof fetch;
355-
356-
await startAuthorizationCodeFlow({ fetchImpl });
357-
358-
expect(capturedHeaders).toMatchObject({ heygen_route: "canary" });
359-
});
360-
361340
it("overwrites the OAuth block on fresh login (no inherited refresh_token)", async () => {
362341
// Pre-seed a prior session whose refresh_token must NOT leak into
363342
// the new login when the new response omits one.
@@ -471,11 +450,7 @@ describe("auth/oauth", () => {
471450
});
472451

473452
it("polls pending and slow_down responses without persisting before identity verification", async () => {
474-
const requests: Array<{
475-
url: string;
476-
body: URLSearchParams;
477-
headers: HeadersInit | undefined;
478-
}> = [];
453+
const requests: Array<{ url: string; body: URLSearchParams }> = [];
479454
const responses = [
480455
new Response(
481456
JSON.stringify({
@@ -510,7 +485,6 @@ describe("auth/oauth", () => {
510485
requests.push({
511486
url: String(url),
512487
body: new URLSearchParams(String(init?.body ?? "")),
513-
headers: init?.headers,
514488
});
515489
});
516490
const sleeps: number[] = [];
@@ -540,12 +514,6 @@ describe("auth/oauth", () => {
540514
expect(requests[1]?.body.get("grant_type")).toBe(
541515
"urn:ietf:params:oauth:grant-type:device_code",
542516
);
543-
expect(requests.map(({ headers }) => headers)).toEqual([
544-
expect.objectContaining({ heygen_route: "canary" }),
545-
expect.objectContaining({ heygen_route: "canary" }),
546-
expect.objectContaining({ heygen_route: "canary" }),
547-
expect.objectContaining({ heygen_route: "canary" }),
548-
]);
549517
expect((await readStore()).source).toBe("absent");
550518

551519
await persistFreshOAuth(tokens);

packages/cli/src/auth/oauth.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ import {
5454
type StoredUserInfo,
5555
} from "./store.js";
5656
import { c } from "../ui/colors.js";
57-
import { withHeygenCanaryRoute } from "../utils/heygenRoute.js";
5857

5958
const REVOKE_TIMEOUT_MS = 5_000;
6059
const MIN_EXPIRES_IN_SECONDS = 30;
@@ -256,10 +255,10 @@ async function requestDeviceAuthorization(
256255
async (signal) => {
257256
const response = await runtime.fetchImpl(deviceAuthorizationEndpoint(), {
258257
method: "POST",
259-
headers: withHeygenCanaryRoute({
258+
headers: {
260259
"content-type": "application/x-www-form-urlencoded",
261260
accept: "application/json",
262-
}),
261+
},
263262
body: new URLSearchParams({ client_id: runtime.clientId, scope }).toString(),
264263
signal,
265264
});
@@ -304,10 +303,10 @@ async function requestDeviceToken(
304303
async (signal) => {
305304
const response = await runtime.fetchImpl(tokenEndpoint(), {
306305
method: "POST",
307-
headers: withHeygenCanaryRoute({
306+
headers: {
308307
"content-type": "application/x-www-form-urlencoded",
309308
accept: "application/json",
310-
}),
309+
},
311310
body: new URLSearchParams({
312311
grant_type: DEVICE_CODE_GRANT_TYPE,
313312
device_code: deviceCode,
@@ -395,10 +394,10 @@ export async function refreshTokens(
395394

396395
const res = await fetchImpl(tokenEndpoint(), {
397396
method: "POST",
398-
headers: withHeygenCanaryRoute({
397+
headers: {
399398
"content-type": "application/x-www-form-urlencoded",
400399
accept: "application/json",
401-
}),
400+
},
402401
body: body.toString(),
403402
});
404403

@@ -447,9 +446,7 @@ export async function revokeTokens(token: string, opts: RevokeOptions = {}): Pro
447446
try {
448447
const res = await fetchImpl(revokeEndpoint(), {
449448
method: "POST",
450-
headers: withHeygenCanaryRoute({
451-
"content-type": "application/x-www-form-urlencoded",
452-
}),
449+
headers: { "content-type": "application/x-www-form-urlencoded" },
453450
body: body.toString(),
454451
signal: controller.signal,
455452
});
@@ -510,10 +507,10 @@ async function exchangeCodeForTokens(args: {
510507
});
511508
const res = await fetchImpl(tokenEndpoint(), {
512509
method: "POST",
513-
headers: withHeygenCanaryRoute({
510+
headers: {
514511
"content-type": "application/x-www-form-urlencoded",
515512
accept: "application/json",
516-
}),
513+
},
517514
body: body.toString(),
518515
});
519516
if (res.status === 400 || res.status === 401) {

packages/cli/src/utils/heygenRoute.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

packages/cli/src/utils/publishProject.e2e.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ describeE2E("publish stable-URL round trip (live server)", () => {
3636
async function fetchPublicProject(projectId: string): Promise<Record<string, unknown>> {
3737
const response = await fetch(
3838
`${getPublishApiBaseUrl()}/v1/hyperframes/projects/${projectId}/public`,
39-
{ headers: { heygen_route: "canary" } },
4039
);
4140
expect(response.ok).toBe(true);
4241
const payload = (await response.json()) as { data: Record<string, unknown> };

packages/cli/src/utils/publishProject.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ afterEach(() => {
551551
vi.unstubAllEnvs();
552552
});
553553

554-
const jsonHeaders = { "content-type": "application/json", heygen_route: "canary" };
554+
const jsonHeaders = { "content-type": "application/json" };
555555
const signedStagedS3Url =
556556
"https://s3.example.com/upload?X-Amz-SignedHeaders=content-length;content-type;host;x-amz-server-side-encryption";
557557

@@ -662,7 +662,7 @@ describe("publishProjectArchive", () => {
662662
expect(fetchMock).toHaveBeenCalledTimes(2);
663663
expectFetchCall(fetchMock, 2, "https://api2.heygen.com/v1/hyperframes/projects/publish", {
664664
method: "POST",
665-
headers: { heygen_route: "canary" },
665+
headers: {},
666666
});
667667
} finally {
668668
rmSync(dir, { recursive: true, force: true });

packages/cli/src/utils/publishProject.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import AdmZip from "adm-zip";
55
import ignore, { type Ignore } from "ignore";
66
import { CSS_URL_RE, isNonRelativeUrl, isPathInside } from "@hyperframes/core";
77
import { buildAuthHeaders } from "../auth/client.js";
8-
import { withHeygenCanaryRoute } from "./heygenRoute.js";
98
import { tryResolveCredential } from "../auth/index.js";
109
import { writeProjectLink } from "./projectLink.js";
1110

@@ -558,7 +557,7 @@ async function publishProjectArchiveDirect(
558557
"file",
559558
new File([archiveArrayBuffer(archive)], `${title}.zip`, { type: PUBLISH_CONTENT_TYPE }),
560559
);
561-
const headers = withHeygenCanaryRoute(authHeaders);
560+
const headers: Record<string, string> = { ...authHeaders };
562561

563562
const response = await fetchForPublish(
564563
`${apiBaseUrl}/v1/hyperframes/projects/publish`,
@@ -621,10 +620,10 @@ async function publishProjectArchiveStaged(
621620
content_type: PUBLISH_CONTENT_TYPE,
622621
content_length: archive.buffer.byteLength,
623622
}),
624-
headers: withHeygenCanaryRoute({
623+
headers: {
625624
...authHeaders,
626625
"content-type": "application/json",
627-
}),
626+
},
628627
signal: AbortSignal.timeout(PUBLISH_METADATA_TIMEOUT_MS),
629628
}),
630629
"Failed to prepare project upload",
@@ -654,10 +653,10 @@ async function publishProjectArchiveStaged(
654653
...(isPublic ? { is_public: true } : {}),
655654
...(projectId ? { project_id: projectId } : {}),
656655
}),
657-
headers: withHeygenCanaryRoute({
656+
headers: {
658657
...authHeaders,
659658
"content-type": "application/json",
660-
}),
659+
},
661660
signal: AbortSignal.timeout(uploadTimeoutMs(archive.buffer.byteLength)),
662661
}),
663662
"Failed to finalize project publish",

packages/cli/src/utils/submitFeedback.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe("submitFeedback", () => {
3535
"https://api.example.com/v1/hyperframes/feedback",
3636
expect.objectContaining({
3737
method: "POST",
38-
headers: { "content-type": "application/json", heygen_route: "canary" },
38+
headers: { "content-type": "application/json" },
3939
body: JSON.stringify({
4040
rating: 4,
4141
rating_scale: 10,

packages/cli/src/utils/submitFeedback.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { getPublishApiBaseUrl } from "./publishProject.js";
22
import { FEEDBACK_RATING_SCALE } from "./feedbackRating.js";
3-
import { withHeygenCanaryRoute } from "./heygenRoute.js";
43

54
// Match the backend DTO caps (HyperframesFeedbackRequest). Truncate here so an
65
// over-long field (e.g. a pasted stack trace) is still forwarded truncated,
@@ -31,9 +30,9 @@ export async function submitFeedback(input: {
3130
cli_version: cap(input.cliVersion, MAX_CLI_VERSION),
3231
env: cap(input.env, MAX_ENV),
3332
}),
34-
headers: withHeygenCanaryRoute({
33+
headers: {
3534
"content-type": "application/json",
36-
}),
35+
},
3736
signal: AbortSignal.timeout(5000),
3837
});
3938
} catch {

0 commit comments

Comments
 (0)