connectbase-client 5.10.0 → 5.11.0
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/CHANGELOG.md +45 -0
- package/dist/connect-base.umd.js +4 -4
- package/dist/index.d.mts +36 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +86 -6
- package/dist/index.mjs +86 -6
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -264,6 +264,18 @@ declare class HttpClient {
|
|
|
264
264
|
*/
|
|
265
265
|
private bootRestorePromise;
|
|
266
266
|
private bootRestoreAlwaysAwait;
|
|
267
|
+
/**
|
|
268
|
+
* 서버가 `X-CB-Direct-Base` 로 알려준 저지연 원본. 학습 전에는 null 이라 항상 `baseUrl`
|
|
269
|
+
* 을 쓴다. {@link resolveOrigin} 참고.
|
|
270
|
+
*/
|
|
271
|
+
private directBaseUrl;
|
|
272
|
+
/**
|
|
273
|
+
* direct 원본을 이 세션에서 더는 쓰지 않는다는 표시. 한 번이라도 네트워크 레벨에서
|
|
274
|
+
* 실패하면(CSP `connect-src` 차단, 사내 프록시, DNS 미전파, 호스트 회수 등) 즉시 세워
|
|
275
|
+
* 이후 요청은 전부 `baseUrl` 로 간다. direct 는 최적화일 뿐 필수가 아니므로 재시도를
|
|
276
|
+
* 반복하지 않고 한 번에 포기하는 쪽이 안전하다.
|
|
277
|
+
*/
|
|
278
|
+
private directDisabled;
|
|
267
279
|
/**
|
|
268
280
|
* 클라이언트 생성 시 명시된 요청 타임아웃(ms). 미지정이면 `undefined`.
|
|
269
281
|
*
|
|
@@ -406,6 +418,30 @@ declare class HttpClient {
|
|
|
406
418
|
* (platform-issue 019e638d, 2026-05-26). retry 는 1회 한정 — 무한 루프 차단.
|
|
407
419
|
*/
|
|
408
420
|
private doFetch;
|
|
421
|
+
/**
|
|
422
|
+
* 이 요청을 보낼 원본을 고른다.
|
|
423
|
+
*
|
|
424
|
+
* `credentials:'omit'` 인 요청 — 즉 `X-Public-Key` 로만 인증하고 쿠키를 주고받지 않는
|
|
425
|
+
* `/v1/public/*` 데이터 평면 — 만 direct 원본으로 보낸다. 이 조건이 곧 안전 조건이다:
|
|
426
|
+
* 멤버 refresh 쿠키는 **host-only** 로 발급되므로(백엔드 auth_cookie.SetMemberRefreshCookie)
|
|
427
|
+
* 로그인·가입·로그아웃·OAuth·탈퇴를 다른 호스트로 보내면 세션이 조용히 끊긴다.
|
|
428
|
+
* `fetchCredentialsForPath` 가 이미 그 경계를 계산하고 있어, 나중에 쿠키 엔드포인트가
|
|
429
|
+
* 추가돼도 자동으로 제외된다(서버도 같은 경로를 421 로 되돌려보낸다).
|
|
430
|
+
*/
|
|
431
|
+
private resolveOrigin;
|
|
432
|
+
/**
|
|
433
|
+
* 응답에서 저지연 원본 광고를 학습한다.
|
|
434
|
+
*
|
|
435
|
+
* 왜 서버가 정하나: 클라이언트는 자기가 어느 나라에서 접속했는지 신뢰성 있게 모르고,
|
|
436
|
+
* 두 호스트를 재보는 프로브는 요청을 한 번 더 쓴다. Cloudflare 엣지는 `CF-IPCountry` 로
|
|
437
|
+
* 이미 알고 있으므로 서버가 판단해 알려주는 쪽이 정확하고 공짜다. 서버 env 하나로
|
|
438
|
+
* 즉시 회수할 수도 있다.
|
|
439
|
+
*
|
|
440
|
+
* 값은 검증한다 — https 이고 `baseUrl` 과 같은 등록 도메인이어야 한다. 응답은 우리
|
|
441
|
+
* 서버에서 TLS 로 오지만, 설정 실수 하나로 SDK 트래픽 전체가 엉뚱한 호스트로 향하는
|
|
442
|
+
* 일은 없어야 한다.
|
|
443
|
+
*/
|
|
444
|
+
private learnDirectOrigin;
|
|
409
445
|
private tryFetchOnce;
|
|
410
446
|
get<T>(url: string, config?: RequestConfig): Promise<T>;
|
|
411
447
|
post<T>(url: string, data?: unknown, config?: RequestConfig): Promise<T>;
|
package/dist/index.d.ts
CHANGED
|
@@ -264,6 +264,18 @@ declare class HttpClient {
|
|
|
264
264
|
*/
|
|
265
265
|
private bootRestorePromise;
|
|
266
266
|
private bootRestoreAlwaysAwait;
|
|
267
|
+
/**
|
|
268
|
+
* 서버가 `X-CB-Direct-Base` 로 알려준 저지연 원본. 학습 전에는 null 이라 항상 `baseUrl`
|
|
269
|
+
* 을 쓴다. {@link resolveOrigin} 참고.
|
|
270
|
+
*/
|
|
271
|
+
private directBaseUrl;
|
|
272
|
+
/**
|
|
273
|
+
* direct 원본을 이 세션에서 더는 쓰지 않는다는 표시. 한 번이라도 네트워크 레벨에서
|
|
274
|
+
* 실패하면(CSP `connect-src` 차단, 사내 프록시, DNS 미전파, 호스트 회수 등) 즉시 세워
|
|
275
|
+
* 이후 요청은 전부 `baseUrl` 로 간다. direct 는 최적화일 뿐 필수가 아니므로 재시도를
|
|
276
|
+
* 반복하지 않고 한 번에 포기하는 쪽이 안전하다.
|
|
277
|
+
*/
|
|
278
|
+
private directDisabled;
|
|
267
279
|
/**
|
|
268
280
|
* 클라이언트 생성 시 명시된 요청 타임아웃(ms). 미지정이면 `undefined`.
|
|
269
281
|
*
|
|
@@ -406,6 +418,30 @@ declare class HttpClient {
|
|
|
406
418
|
* (platform-issue 019e638d, 2026-05-26). retry 는 1회 한정 — 무한 루프 차단.
|
|
407
419
|
*/
|
|
408
420
|
private doFetch;
|
|
421
|
+
/**
|
|
422
|
+
* 이 요청을 보낼 원본을 고른다.
|
|
423
|
+
*
|
|
424
|
+
* `credentials:'omit'` 인 요청 — 즉 `X-Public-Key` 로만 인증하고 쿠키를 주고받지 않는
|
|
425
|
+
* `/v1/public/*` 데이터 평면 — 만 direct 원본으로 보낸다. 이 조건이 곧 안전 조건이다:
|
|
426
|
+
* 멤버 refresh 쿠키는 **host-only** 로 발급되므로(백엔드 auth_cookie.SetMemberRefreshCookie)
|
|
427
|
+
* 로그인·가입·로그아웃·OAuth·탈퇴를 다른 호스트로 보내면 세션이 조용히 끊긴다.
|
|
428
|
+
* `fetchCredentialsForPath` 가 이미 그 경계를 계산하고 있어, 나중에 쿠키 엔드포인트가
|
|
429
|
+
* 추가돼도 자동으로 제외된다(서버도 같은 경로를 421 로 되돌려보낸다).
|
|
430
|
+
*/
|
|
431
|
+
private resolveOrigin;
|
|
432
|
+
/**
|
|
433
|
+
* 응답에서 저지연 원본 광고를 학습한다.
|
|
434
|
+
*
|
|
435
|
+
* 왜 서버가 정하나: 클라이언트는 자기가 어느 나라에서 접속했는지 신뢰성 있게 모르고,
|
|
436
|
+
* 두 호스트를 재보는 프로브는 요청을 한 번 더 쓴다. Cloudflare 엣지는 `CF-IPCountry` 로
|
|
437
|
+
* 이미 알고 있으므로 서버가 판단해 알려주는 쪽이 정확하고 공짜다. 서버 env 하나로
|
|
438
|
+
* 즉시 회수할 수도 있다.
|
|
439
|
+
*
|
|
440
|
+
* 값은 검증한다 — https 이고 `baseUrl` 과 같은 등록 도메인이어야 한다. 응답은 우리
|
|
441
|
+
* 서버에서 TLS 로 오지만, 설정 실수 하나로 SDK 트래픽 전체가 엉뚱한 호스트로 향하는
|
|
442
|
+
* 일은 없어야 한다.
|
|
443
|
+
*/
|
|
444
|
+
private learnDirectOrigin;
|
|
409
445
|
private tryFetchOnce;
|
|
410
446
|
get<T>(url: string, config?: RequestConfig): Promise<T>;
|
|
411
447
|
post<T>(url: string, data?: unknown, config?: RequestConfig): Promise<T>;
|
package/dist/index.js
CHANGED
|
@@ -11441,6 +11441,9 @@ var COOKIE_BEARING_PUBLIC_PATHS = /* @__PURE__ */ new Set([
|
|
|
11441
11441
|
"/v1/public/app-members/signin",
|
|
11442
11442
|
"/v1/public/app-members/signout"
|
|
11443
11443
|
]);
|
|
11444
|
+
function isAbortError(err) {
|
|
11445
|
+
return typeof err === "object" && err !== null && "name" in err && err.name === "AbortError";
|
|
11446
|
+
}
|
|
11444
11447
|
function fetchCredentialsForPath(url) {
|
|
11445
11448
|
const path = url.split("?")[0];
|
|
11446
11449
|
if (COOKIE_BEARING_PUBLIC_PATHS.has(path)) {
|
|
@@ -11512,6 +11515,18 @@ var HttpClient = class {
|
|
|
11512
11515
|
// OAuth 콜백 부트스트랩처럼 세션 힌트 유무와 무관하게 첫 인증 호출이 반드시 기다려야
|
|
11513
11516
|
// 하는 boot promise 인지 여부 (setBootRestorePromise 의 alwaysAwait 옵션).
|
|
11514
11517
|
this.bootRestoreAlwaysAwait = false;
|
|
11518
|
+
/**
|
|
11519
|
+
* 서버가 `X-CB-Direct-Base` 로 알려준 저지연 원본. 학습 전에는 null 이라 항상 `baseUrl`
|
|
11520
|
+
* 을 쓴다. {@link resolveOrigin} 참고.
|
|
11521
|
+
*/
|
|
11522
|
+
this.directBaseUrl = null;
|
|
11523
|
+
/**
|
|
11524
|
+
* direct 원본을 이 세션에서 더는 쓰지 않는다는 표시. 한 번이라도 네트워크 레벨에서
|
|
11525
|
+
* 실패하면(CSP `connect-src` 차단, 사내 프록시, DNS 미전파, 호스트 회수 등) 즉시 세워
|
|
11526
|
+
* 이후 요청은 전부 `baseUrl` 로 간다. direct 는 최적화일 뿐 필수가 아니므로 재시도를
|
|
11527
|
+
* 반복하지 않고 한 번에 포기하는 쪽이 안전하다.
|
|
11528
|
+
*/
|
|
11529
|
+
this.directDisabled = false;
|
|
11515
11530
|
this.config = { ...config };
|
|
11516
11531
|
this.storageKey = this.buildStorageKey();
|
|
11517
11532
|
this.warnIfUnsafePersistence();
|
|
@@ -12102,18 +12117,73 @@ var HttpClient = class {
|
|
|
12102
12117
|
});
|
|
12103
12118
|
}
|
|
12104
12119
|
}
|
|
12120
|
+
/**
|
|
12121
|
+
* 이 요청을 보낼 원본을 고른다.
|
|
12122
|
+
*
|
|
12123
|
+
* `credentials:'omit'` 인 요청 — 즉 `X-Public-Key` 로만 인증하고 쿠키를 주고받지 않는
|
|
12124
|
+
* `/v1/public/*` 데이터 평면 — 만 direct 원본으로 보낸다. 이 조건이 곧 안전 조건이다:
|
|
12125
|
+
* 멤버 refresh 쿠키는 **host-only** 로 발급되므로(백엔드 auth_cookie.SetMemberRefreshCookie)
|
|
12126
|
+
* 로그인·가입·로그아웃·OAuth·탈퇴를 다른 호스트로 보내면 세션이 조용히 끊긴다.
|
|
12127
|
+
* `fetchCredentialsForPath` 가 이미 그 경계를 계산하고 있어, 나중에 쿠키 엔드포인트가
|
|
12128
|
+
* 추가돼도 자동으로 제외된다(서버도 같은 경로를 421 로 되돌려보낸다).
|
|
12129
|
+
*/
|
|
12130
|
+
resolveOrigin(url) {
|
|
12131
|
+
if (this.directBaseUrl && !this.directDisabled && fetchCredentialsForPath(url) === "omit") {
|
|
12132
|
+
return this.directBaseUrl;
|
|
12133
|
+
}
|
|
12134
|
+
return this.config.baseUrl;
|
|
12135
|
+
}
|
|
12136
|
+
/**
|
|
12137
|
+
* 응답에서 저지연 원본 광고를 학습한다.
|
|
12138
|
+
*
|
|
12139
|
+
* 왜 서버가 정하나: 클라이언트는 자기가 어느 나라에서 접속했는지 신뢰성 있게 모르고,
|
|
12140
|
+
* 두 호스트를 재보는 프로브는 요청을 한 번 더 쓴다. Cloudflare 엣지는 `CF-IPCountry` 로
|
|
12141
|
+
* 이미 알고 있으므로 서버가 판단해 알려주는 쪽이 정확하고 공짜다. 서버 env 하나로
|
|
12142
|
+
* 즉시 회수할 수도 있다.
|
|
12143
|
+
*
|
|
12144
|
+
* 값은 검증한다 — https 이고 `baseUrl` 과 같은 등록 도메인이어야 한다. 응답은 우리
|
|
12145
|
+
* 서버에서 TLS 로 오지만, 설정 실수 하나로 SDK 트래픽 전체가 엉뚱한 호스트로 향하는
|
|
12146
|
+
* 일은 없어야 한다.
|
|
12147
|
+
*/
|
|
12148
|
+
learnDirectOrigin(response) {
|
|
12149
|
+
if (this.directDisabled || this.directBaseUrl) return;
|
|
12150
|
+
const advertised = response.headers?.get("X-CB-Direct-Base");
|
|
12151
|
+
if (!advertised) return;
|
|
12152
|
+
try {
|
|
12153
|
+
const next = new URL(advertised);
|
|
12154
|
+
const base = new URL(this.config.baseUrl);
|
|
12155
|
+
if (next.protocol !== "https:") return;
|
|
12156
|
+
const tail = (h) => h.split(".").slice(-2).join(".");
|
|
12157
|
+
if (tail(next.hostname) !== tail(base.hostname)) return;
|
|
12158
|
+
this.directBaseUrl = next.origin;
|
|
12159
|
+
} catch {
|
|
12160
|
+
}
|
|
12161
|
+
}
|
|
12105
12162
|
async tryFetchOnce(url, init, config) {
|
|
12106
12163
|
const { signal, cleanup } = createTimeoutController({
|
|
12107
12164
|
timeout: config?.timeout ?? this.config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,
|
|
12108
12165
|
signal: config?.signal
|
|
12109
12166
|
});
|
|
12167
|
+
const origin = this.resolveOrigin(url);
|
|
12110
12168
|
try {
|
|
12111
|
-
const response = await fetch(`${
|
|
12169
|
+
const response = await fetch(`${origin}${url}`, {
|
|
12112
12170
|
...init,
|
|
12113
12171
|
credentials: fetchCredentialsForPath(url),
|
|
12114
12172
|
signal
|
|
12115
12173
|
});
|
|
12174
|
+
this.learnDirectOrigin(response);
|
|
12116
12175
|
return { response, ok: response.ok, status: response.status };
|
|
12176
|
+
} catch (err) {
|
|
12177
|
+
if (origin !== this.config.baseUrl && !isAbortError(err)) {
|
|
12178
|
+
this.directDisabled = true;
|
|
12179
|
+
const response = await fetch(`${this.config.baseUrl}${url}`, {
|
|
12180
|
+
...init,
|
|
12181
|
+
credentials: fetchCredentialsForPath(url),
|
|
12182
|
+
signal
|
|
12183
|
+
});
|
|
12184
|
+
return { response, ok: response.ok, status: response.status };
|
|
12185
|
+
}
|
|
12186
|
+
throw err;
|
|
12117
12187
|
} finally {
|
|
12118
12188
|
cleanup();
|
|
12119
12189
|
}
|
|
@@ -12180,11 +12250,21 @@ var HttpClient = class {
|
|
|
12180
12250
|
const extra = new Headers(init.headers);
|
|
12181
12251
|
extra.forEach((value, key) => mergedHeaders.set(key, value));
|
|
12182
12252
|
}
|
|
12183
|
-
|
|
12184
|
-
|
|
12185
|
-
|
|
12186
|
-
|
|
12187
|
-
|
|
12253
|
+
const origin = this.resolveOrigin(url);
|
|
12254
|
+
try {
|
|
12255
|
+
const response = await fetch(`${origin}${url}`, {
|
|
12256
|
+
...init,
|
|
12257
|
+
credentials: fetchCredentialsForPath(url),
|
|
12258
|
+
headers: mergedHeaders
|
|
12259
|
+
});
|
|
12260
|
+
this.learnDirectOrigin(response);
|
|
12261
|
+
return response;
|
|
12262
|
+
} catch (err) {
|
|
12263
|
+
if (origin !== this.config.baseUrl && !isAbortError(err)) {
|
|
12264
|
+
this.directDisabled = true;
|
|
12265
|
+
}
|
|
12266
|
+
throw err;
|
|
12267
|
+
}
|
|
12188
12268
|
}
|
|
12189
12269
|
};
|
|
12190
12270
|
|
package/dist/index.mjs
CHANGED
|
@@ -11392,6 +11392,9 @@ var COOKIE_BEARING_PUBLIC_PATHS = /* @__PURE__ */ new Set([
|
|
|
11392
11392
|
"/v1/public/app-members/signin",
|
|
11393
11393
|
"/v1/public/app-members/signout"
|
|
11394
11394
|
]);
|
|
11395
|
+
function isAbortError(err) {
|
|
11396
|
+
return typeof err === "object" && err !== null && "name" in err && err.name === "AbortError";
|
|
11397
|
+
}
|
|
11395
11398
|
function fetchCredentialsForPath(url) {
|
|
11396
11399
|
const path = url.split("?")[0];
|
|
11397
11400
|
if (COOKIE_BEARING_PUBLIC_PATHS.has(path)) {
|
|
@@ -11463,6 +11466,18 @@ var HttpClient = class {
|
|
|
11463
11466
|
// OAuth 콜백 부트스트랩처럼 세션 힌트 유무와 무관하게 첫 인증 호출이 반드시 기다려야
|
|
11464
11467
|
// 하는 boot promise 인지 여부 (setBootRestorePromise 의 alwaysAwait 옵션).
|
|
11465
11468
|
this.bootRestoreAlwaysAwait = false;
|
|
11469
|
+
/**
|
|
11470
|
+
* 서버가 `X-CB-Direct-Base` 로 알려준 저지연 원본. 학습 전에는 null 이라 항상 `baseUrl`
|
|
11471
|
+
* 을 쓴다. {@link resolveOrigin} 참고.
|
|
11472
|
+
*/
|
|
11473
|
+
this.directBaseUrl = null;
|
|
11474
|
+
/**
|
|
11475
|
+
* direct 원본을 이 세션에서 더는 쓰지 않는다는 표시. 한 번이라도 네트워크 레벨에서
|
|
11476
|
+
* 실패하면(CSP `connect-src` 차단, 사내 프록시, DNS 미전파, 호스트 회수 등) 즉시 세워
|
|
11477
|
+
* 이후 요청은 전부 `baseUrl` 로 간다. direct 는 최적화일 뿐 필수가 아니므로 재시도를
|
|
11478
|
+
* 반복하지 않고 한 번에 포기하는 쪽이 안전하다.
|
|
11479
|
+
*/
|
|
11480
|
+
this.directDisabled = false;
|
|
11466
11481
|
this.config = { ...config };
|
|
11467
11482
|
this.storageKey = this.buildStorageKey();
|
|
11468
11483
|
this.warnIfUnsafePersistence();
|
|
@@ -12053,18 +12068,73 @@ var HttpClient = class {
|
|
|
12053
12068
|
});
|
|
12054
12069
|
}
|
|
12055
12070
|
}
|
|
12071
|
+
/**
|
|
12072
|
+
* 이 요청을 보낼 원본을 고른다.
|
|
12073
|
+
*
|
|
12074
|
+
* `credentials:'omit'` 인 요청 — 즉 `X-Public-Key` 로만 인증하고 쿠키를 주고받지 않는
|
|
12075
|
+
* `/v1/public/*` 데이터 평면 — 만 direct 원본으로 보낸다. 이 조건이 곧 안전 조건이다:
|
|
12076
|
+
* 멤버 refresh 쿠키는 **host-only** 로 발급되므로(백엔드 auth_cookie.SetMemberRefreshCookie)
|
|
12077
|
+
* 로그인·가입·로그아웃·OAuth·탈퇴를 다른 호스트로 보내면 세션이 조용히 끊긴다.
|
|
12078
|
+
* `fetchCredentialsForPath` 가 이미 그 경계를 계산하고 있어, 나중에 쿠키 엔드포인트가
|
|
12079
|
+
* 추가돼도 자동으로 제외된다(서버도 같은 경로를 421 로 되돌려보낸다).
|
|
12080
|
+
*/
|
|
12081
|
+
resolveOrigin(url) {
|
|
12082
|
+
if (this.directBaseUrl && !this.directDisabled && fetchCredentialsForPath(url) === "omit") {
|
|
12083
|
+
return this.directBaseUrl;
|
|
12084
|
+
}
|
|
12085
|
+
return this.config.baseUrl;
|
|
12086
|
+
}
|
|
12087
|
+
/**
|
|
12088
|
+
* 응답에서 저지연 원본 광고를 학습한다.
|
|
12089
|
+
*
|
|
12090
|
+
* 왜 서버가 정하나: 클라이언트는 자기가 어느 나라에서 접속했는지 신뢰성 있게 모르고,
|
|
12091
|
+
* 두 호스트를 재보는 프로브는 요청을 한 번 더 쓴다. Cloudflare 엣지는 `CF-IPCountry` 로
|
|
12092
|
+
* 이미 알고 있으므로 서버가 판단해 알려주는 쪽이 정확하고 공짜다. 서버 env 하나로
|
|
12093
|
+
* 즉시 회수할 수도 있다.
|
|
12094
|
+
*
|
|
12095
|
+
* 값은 검증한다 — https 이고 `baseUrl` 과 같은 등록 도메인이어야 한다. 응답은 우리
|
|
12096
|
+
* 서버에서 TLS 로 오지만, 설정 실수 하나로 SDK 트래픽 전체가 엉뚱한 호스트로 향하는
|
|
12097
|
+
* 일은 없어야 한다.
|
|
12098
|
+
*/
|
|
12099
|
+
learnDirectOrigin(response) {
|
|
12100
|
+
if (this.directDisabled || this.directBaseUrl) return;
|
|
12101
|
+
const advertised = response.headers?.get("X-CB-Direct-Base");
|
|
12102
|
+
if (!advertised) return;
|
|
12103
|
+
try {
|
|
12104
|
+
const next = new URL(advertised);
|
|
12105
|
+
const base = new URL(this.config.baseUrl);
|
|
12106
|
+
if (next.protocol !== "https:") return;
|
|
12107
|
+
const tail = (h) => h.split(".").slice(-2).join(".");
|
|
12108
|
+
if (tail(next.hostname) !== tail(base.hostname)) return;
|
|
12109
|
+
this.directBaseUrl = next.origin;
|
|
12110
|
+
} catch {
|
|
12111
|
+
}
|
|
12112
|
+
}
|
|
12056
12113
|
async tryFetchOnce(url, init, config) {
|
|
12057
12114
|
const { signal, cleanup } = createTimeoutController({
|
|
12058
12115
|
timeout: config?.timeout ?? this.config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,
|
|
12059
12116
|
signal: config?.signal
|
|
12060
12117
|
});
|
|
12118
|
+
const origin = this.resolveOrigin(url);
|
|
12061
12119
|
try {
|
|
12062
|
-
const response = await fetch(`${
|
|
12120
|
+
const response = await fetch(`${origin}${url}`, {
|
|
12063
12121
|
...init,
|
|
12064
12122
|
credentials: fetchCredentialsForPath(url),
|
|
12065
12123
|
signal
|
|
12066
12124
|
});
|
|
12125
|
+
this.learnDirectOrigin(response);
|
|
12067
12126
|
return { response, ok: response.ok, status: response.status };
|
|
12127
|
+
} catch (err) {
|
|
12128
|
+
if (origin !== this.config.baseUrl && !isAbortError(err)) {
|
|
12129
|
+
this.directDisabled = true;
|
|
12130
|
+
const response = await fetch(`${this.config.baseUrl}${url}`, {
|
|
12131
|
+
...init,
|
|
12132
|
+
credentials: fetchCredentialsForPath(url),
|
|
12133
|
+
signal
|
|
12134
|
+
});
|
|
12135
|
+
return { response, ok: response.ok, status: response.status };
|
|
12136
|
+
}
|
|
12137
|
+
throw err;
|
|
12068
12138
|
} finally {
|
|
12069
12139
|
cleanup();
|
|
12070
12140
|
}
|
|
@@ -12131,11 +12201,21 @@ var HttpClient = class {
|
|
|
12131
12201
|
const extra = new Headers(init.headers);
|
|
12132
12202
|
extra.forEach((value, key) => mergedHeaders.set(key, value));
|
|
12133
12203
|
}
|
|
12134
|
-
|
|
12135
|
-
|
|
12136
|
-
|
|
12137
|
-
|
|
12138
|
-
|
|
12204
|
+
const origin = this.resolveOrigin(url);
|
|
12205
|
+
try {
|
|
12206
|
+
const response = await fetch(`${origin}${url}`, {
|
|
12207
|
+
...init,
|
|
12208
|
+
credentials: fetchCredentialsForPath(url),
|
|
12209
|
+
headers: mergedHeaders
|
|
12210
|
+
});
|
|
12211
|
+
this.learnDirectOrigin(response);
|
|
12212
|
+
return response;
|
|
12213
|
+
} catch (err) {
|
|
12214
|
+
if (origin !== this.config.baseUrl && !isAbortError(err)) {
|
|
12215
|
+
this.directDisabled = true;
|
|
12216
|
+
}
|
|
12217
|
+
throw err;
|
|
12218
|
+
}
|
|
12139
12219
|
}
|
|
12140
12220
|
};
|
|
12141
12221
|
|