tina4-nodejs 3.13.144 → 3.13.146

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/CLAUDE.md CHANGED
@@ -13,13 +13,13 @@ Even if the skill text is not currently loaded, these are non-negotiable:
13
13
 
14
14
  The full discipline lives in `.claude/skills/tina4-maintainer/SKILL.md`; this block is the always-on floor.
15
15
 
16
- # CLAUDE.md - AI Developer Guide for tina4-nodejs (v3.13.144)
16
+ # CLAUDE.md - AI Developer Guide for tina4-nodejs (v3.13.146)
17
17
 
18
18
  > This file helps AI assistants (Claude, Copilot, Cursor, etc.) understand and work on this codebase effectively.
19
19
 
20
20
  ## What This Project Is
21
21
 
22
- Tina4 for Node.js/TypeScript v3.13.144 - The Intelligent Native Application 4ramework. A convention-over-configuration structural paradigm. The developer writes TypeScript; Tina4 is invisible infrastructure.
22
+ Tina4 for Node.js/TypeScript v3.13.146 - The Intelligent Native Application 4ramework. A convention-over-configuration structural paradigm. The developer writes TypeScript; Tina4 is invisible infrastructure.
23
23
 
24
24
  The philosophy: zero ceremony, batteries included, file system as source of truth.
25
25
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tina4-nodejs",
3
- "version": "3.13.144",
3
+ "version": "3.13.146",
4
4
  "type": "module",
5
5
  "description": "Tina4 for Node.js/TypeScript - native TypeScript conventions and shared Tina4 contracts",
6
6
  "keywords": [
@@ -43003,6 +43003,13 @@ import { randomBytes as randomBytes11 } from "node:crypto";
43003
43003
  import { promises as fsp, createWriteStream } from "node:fs";
43004
43004
  import { basename as basename7 } from "node:path";
43005
43005
  import { pipeline } from "node:stream/promises";
43006
+ function keepCrossOriginHeaders(headers) {
43007
+ const out = {};
43008
+ for (const [key, value] of Object.entries(headers)) {
43009
+ if (KEEP_ON_CROSS_ORIGIN.has(key.toLowerCase())) out[key] = value;
43010
+ }
43011
+ return out;
43012
+ }
43006
43013
  function sameOrigin(urlA, urlB) {
43007
43014
  try {
43008
43015
  const a = new URL2(urlA);
@@ -43146,7 +43153,7 @@ async function* parseSseStream(lines) {
43146
43153
  const trailing = emit();
43147
43154
  if (trailing) yield trailing;
43148
43155
  }
43149
- var ApiStreamError, RETRY_STATUSES, DOWNLOAD_CHUNK_SIZE, MAX_REDIRECTS, STRIP_ON_CROSS_ORIGIN, MIME_BY_EXT, Api;
43156
+ var ApiStreamError, RETRY_STATUSES, DOWNLOAD_CHUNK_SIZE, MAX_REDIRECTS, STRIP_ON_CROSS_ORIGIN, KEEP_ON_CROSS_ORIGIN, MIME_BY_EXT, Api;
43150
43157
  var init_api = __esm({
43151
43158
  "../core/src/api.ts"() {
43152
43159
  "use strict";
@@ -43164,6 +43171,14 @@ var init_api = __esm({
43164
43171
  DOWNLOAD_CHUNK_SIZE = 64 * 1024;
43165
43172
  MAX_REDIRECTS = 10;
43166
43173
  STRIP_ON_CROSS_ORIGIN = /* @__PURE__ */ new Set(["authorization", "cookie"]);
43174
+ KEEP_ON_CROSS_ORIGIN = /* @__PURE__ */ new Set([
43175
+ "user-agent",
43176
+ "accept",
43177
+ "accept-encoding",
43178
+ "accept-language",
43179
+ "content-type",
43180
+ "content-length"
43181
+ ]);
43167
43182
  MIME_BY_EXT = {
43168
43183
  txt: "text/plain",
43169
43184
  html: "text/html",
@@ -43619,6 +43634,18 @@ var init_api = __esm({
43619
43634
  }
43620
43635
  return `${this.baseUrl}/${path10.replace(/^\/+/, "")}`;
43621
43636
  }
43637
+ /**
43638
+ * The headers configured on the client, as they may go to `targetUrl`.
43639
+ *
43640
+ * They belong to the base origin, like the token: an absolute target on
43641
+ * another origin gets only the cross-origin-safe ones. A client with no
43642
+ * base has no origin to bind them to, and sends them to the URL each call
43643
+ * names.
43644
+ */
43645
+ configuredHeadersFor(targetUrl) {
43646
+ const offOrigin = targetUrl !== void 0 && this.baseUrl !== "" && !sameOrigin(targetUrl, this.baseUrl);
43647
+ return offOrigin ? keepCrossOriginHeaders(this.headers) : this.headers;
43648
+ }
43622
43649
  /**
43623
43650
  * Build the request headers (default User-Agent + auth + cookie jar +
43624
43651
  * extras) and serialize the body to a Buffer. Shared by every verb,
@@ -43633,7 +43660,7 @@ var init_api = __esm({
43633
43660
  * clobber.
43634
43661
  */
43635
43662
  buildRequest(method, contentType, body, extraHeaders, targetUrl) {
43636
- const headers = { "User-Agent": `Tina4/${TINA4_VERSION}`, ...this.headers };
43663
+ const headers = { "User-Agent": `Tina4/${TINA4_VERSION}`, ...this.configuredHeadersFor(targetUrl) };
43637
43664
  const sameOriginAsBase = targetUrl === void 0 || sameOrigin(targetUrl, this.baseUrl);
43638
43665
  if (this.authHeader && sameOriginAsBase) {
43639
43666
  headers["Authorization"] = this.authHeader;
@@ -43735,9 +43762,9 @@ var init_api = __esm({
43735
43762
  * Location, this drains the intermediate response and re-issues to the new
43736
43763
  * URL: 301/302/303 on a non-GET/HEAD become GET (body dropped, urllib
43737
43764
  * behaviour); 307/308 preserve method + body. When the redirect target is a
43738
- * DIFFERENT origin, the Authorization and Cookie headers are stripped so a
43739
- * bearer token / session cookie never leaks to a host you didn't
43740
- * authenticate to.
43765
+ * DIFFERENT origin, only KEEP_ON_CROSS_ORIGIN headers are carried, so a
43766
+ * bearer token, session cookie or any caller-set credential header never
43767
+ * leaks to a host you didn't authenticate to.
43741
43768
  */
43742
43769
  async performRequest(method, url, headers, data, redirectsLeft) {
43743
43770
  try {
@@ -43781,18 +43808,13 @@ var init_api = __esm({
43781
43808
  const crossOrigin = !sameOrigin(url, nextUrl);
43782
43809
  let nextMethod = method;
43783
43810
  let nextData = data;
43784
- const nextHeaders = { ...headers };
43811
+ const nextHeaders = crossOrigin ? keepCrossOriginHeaders(headers) : { ...headers };
43785
43812
  if ((status2 === 301 || status2 === 302 || status2 === 303) && method !== "GET" && method !== "HEAD") {
43786
43813
  nextMethod = "GET";
43787
43814
  nextData = void 0;
43788
43815
  deleteHeaderCaseInsensitive(nextHeaders, "content-type");
43789
43816
  deleteHeaderCaseInsensitive(nextHeaders, "content-length");
43790
43817
  }
43791
- if (crossOrigin) {
43792
- for (const name of STRIP_ON_CROSS_ORIGIN) {
43793
- deleteHeaderCaseInsensitive(nextHeaders, name);
43794
- }
43795
- }
43796
43818
  this.performRequest(nextMethod, nextUrl, nextHeaders, nextData, redirectsLeft - 1).then(resolve29);
43797
43819
  return;
43798
43820
  }
@@ -42959,6 +42959,13 @@ import { randomBytes as randomBytes11 } from "node:crypto";
42959
42959
  import { promises as fsp, createWriteStream } from "node:fs";
42960
42960
  import { basename as basename6 } from "node:path";
42961
42961
  import { pipeline } from "node:stream/promises";
42962
+ function keepCrossOriginHeaders(headers) {
42963
+ const out = {};
42964
+ for (const [key, value] of Object.entries(headers)) {
42965
+ if (KEEP_ON_CROSS_ORIGIN.has(key.toLowerCase())) out[key] = value;
42966
+ }
42967
+ return out;
42968
+ }
42962
42969
  function sameOrigin(urlA, urlB) {
42963
42970
  try {
42964
42971
  const a = new URL2(urlA);
@@ -43102,7 +43109,7 @@ async function* parseSseStream(lines) {
43102
43109
  const trailing = emit();
43103
43110
  if (trailing) yield trailing;
43104
43111
  }
43105
- var ApiStreamError, RETRY_STATUSES, DOWNLOAD_CHUNK_SIZE, MAX_REDIRECTS, STRIP_ON_CROSS_ORIGIN, MIME_BY_EXT, Api;
43112
+ var ApiStreamError, RETRY_STATUSES, DOWNLOAD_CHUNK_SIZE, MAX_REDIRECTS, STRIP_ON_CROSS_ORIGIN, KEEP_ON_CROSS_ORIGIN, MIME_BY_EXT, Api;
43106
43113
  var init_api = __esm({
43107
43114
  "src/api.ts"() {
43108
43115
  "use strict";
@@ -43120,6 +43127,14 @@ var init_api = __esm({
43120
43127
  DOWNLOAD_CHUNK_SIZE = 64 * 1024;
43121
43128
  MAX_REDIRECTS = 10;
43122
43129
  STRIP_ON_CROSS_ORIGIN = /* @__PURE__ */ new Set(["authorization", "cookie"]);
43130
+ KEEP_ON_CROSS_ORIGIN = /* @__PURE__ */ new Set([
43131
+ "user-agent",
43132
+ "accept",
43133
+ "accept-encoding",
43134
+ "accept-language",
43135
+ "content-type",
43136
+ "content-length"
43137
+ ]);
43123
43138
  MIME_BY_EXT = {
43124
43139
  txt: "text/plain",
43125
43140
  html: "text/html",
@@ -43575,6 +43590,18 @@ var init_api = __esm({
43575
43590
  }
43576
43591
  return `${this.baseUrl}/${path10.replace(/^\/+/, "")}`;
43577
43592
  }
43593
+ /**
43594
+ * The headers configured on the client, as they may go to `targetUrl`.
43595
+ *
43596
+ * They belong to the base origin, like the token: an absolute target on
43597
+ * another origin gets only the cross-origin-safe ones. A client with no
43598
+ * base has no origin to bind them to, and sends them to the URL each call
43599
+ * names.
43600
+ */
43601
+ configuredHeadersFor(targetUrl) {
43602
+ const offOrigin = targetUrl !== void 0 && this.baseUrl !== "" && !sameOrigin(targetUrl, this.baseUrl);
43603
+ return offOrigin ? keepCrossOriginHeaders(this.headers) : this.headers;
43604
+ }
43578
43605
  /**
43579
43606
  * Build the request headers (default User-Agent + auth + cookie jar +
43580
43607
  * extras) and serialize the body to a Buffer. Shared by every verb,
@@ -43589,7 +43616,7 @@ var init_api = __esm({
43589
43616
  * clobber.
43590
43617
  */
43591
43618
  buildRequest(method, contentType, body, extraHeaders, targetUrl) {
43592
- const headers = { "User-Agent": `Tina4/${TINA4_VERSION}`, ...this.headers };
43619
+ const headers = { "User-Agent": `Tina4/${TINA4_VERSION}`, ...this.configuredHeadersFor(targetUrl) };
43593
43620
  const sameOriginAsBase = targetUrl === void 0 || sameOrigin(targetUrl, this.baseUrl);
43594
43621
  if (this.authHeader && sameOriginAsBase) {
43595
43622
  headers["Authorization"] = this.authHeader;
@@ -43691,9 +43718,9 @@ var init_api = __esm({
43691
43718
  * Location, this drains the intermediate response and re-issues to the new
43692
43719
  * URL: 301/302/303 on a non-GET/HEAD become GET (body dropped, urllib
43693
43720
  * behaviour); 307/308 preserve method + body. When the redirect target is a
43694
- * DIFFERENT origin, the Authorization and Cookie headers are stripped so a
43695
- * bearer token / session cookie never leaks to a host you didn't
43696
- * authenticate to.
43721
+ * DIFFERENT origin, only KEEP_ON_CROSS_ORIGIN headers are carried, so a
43722
+ * bearer token, session cookie or any caller-set credential header never
43723
+ * leaks to a host you didn't authenticate to.
43697
43724
  */
43698
43725
  async performRequest(method, url, headers, data, redirectsLeft) {
43699
43726
  try {
@@ -43737,18 +43764,13 @@ var init_api = __esm({
43737
43764
  const crossOrigin = !sameOrigin(url, nextUrl);
43738
43765
  let nextMethod = method;
43739
43766
  let nextData = data;
43740
- const nextHeaders = { ...headers };
43767
+ const nextHeaders = crossOrigin ? keepCrossOriginHeaders(headers) : { ...headers };
43741
43768
  if ((status2 === 301 || status2 === 302 || status2 === 303) && method !== "GET" && method !== "HEAD") {
43742
43769
  nextMethod = "GET";
43743
43770
  nextData = void 0;
43744
43771
  deleteHeaderCaseInsensitive(nextHeaders, "content-type");
43745
43772
  deleteHeaderCaseInsensitive(nextHeaders, "content-length");
43746
43773
  }
43747
- if (crossOrigin) {
43748
- for (const name of STRIP_ON_CROSS_ORIGIN) {
43749
- deleteHeaderCaseInsensitive(nextHeaders, name);
43750
- }
43751
- }
43752
43774
  this.performRequest(nextMethod, nextUrl, nextHeaders, nextData, redirectsLeft - 1).then(resolve21);
43753
43775
  return;
43754
43776
  }
@@ -153,6 +153,26 @@ const MAX_REDIRECTS = 10;
153
153
  */
154
154
  const STRIP_ON_CROSS_ORIGIN: ReadonlySet<string> = new Set(["authorization", "cookie"]);
155
155
 
156
+ /**
157
+ * The only headers carried onto a different origin. A caller-set header can
158
+ * hold a credential under any name (X-Api-Key, X-Auth-Token, ...), so a
159
+ * denylist cannot contain it: the headers configured on the client (and any
160
+ * per-call header, on a redirect) are bound to the origin they were meant for,
161
+ * and only these content-negotiation headers cross. Lower-case.
162
+ */
163
+ const KEEP_ON_CROSS_ORIGIN: ReadonlySet<string> = new Set([
164
+ "user-agent", "accept", "accept-encoding", "accept-language", "content-type", "content-length",
165
+ ]);
166
+
167
+ /** Only the headers allowed onto a different origin (KEEP_ON_CROSS_ORIGIN). */
168
+ function keepCrossOriginHeaders(headers: Record<string, string>): Record<string, string> {
169
+ const out: Record<string, string> = {};
170
+ for (const [key, value] of Object.entries(headers)) {
171
+ if (KEEP_ON_CROSS_ORIGIN.has(key.toLowerCase())) out[key] = value;
172
+ }
173
+ return out;
174
+ }
175
+
156
176
  /**
157
177
  * Minimal extension → MIME map for guessing a multipart part's Content-Type.
158
178
  * Kept in-repo so the client stays zero-dependency (Node has no stdlib
@@ -909,6 +929,19 @@ export class Api {
909
929
  return `${this.baseUrl}/${path.replace(/^\/+/, "")}`;
910
930
  }
911
931
 
932
+ /**
933
+ * The headers configured on the client, as they may go to `targetUrl`.
934
+ *
935
+ * They belong to the base origin, like the token: an absolute target on
936
+ * another origin gets only the cross-origin-safe ones. A client with no
937
+ * base has no origin to bind them to, and sends them to the URL each call
938
+ * names.
939
+ */
940
+ private configuredHeadersFor(targetUrl?: string): Record<string, string> {
941
+ const offOrigin = targetUrl !== undefined && this.baseUrl !== "" && !sameOrigin(targetUrl, this.baseUrl);
942
+ return offOrigin ? keepCrossOriginHeaders(this.headers) : this.headers;
943
+ }
944
+
912
945
  /**
913
946
  * Build the request headers (default User-Agent + auth + cookie jar +
914
947
  * extras) and serialize the body to a Buffer. Shared by every verb,
@@ -929,7 +962,7 @@ export class Api {
929
962
  extraHeaders?: Record<string, string>,
930
963
  targetUrl?: string,
931
964
  ): { headers: Record<string, string>; data: Buffer | undefined } {
932
- const headers: Record<string, string> = { "User-Agent": `Tina4/${TINA4_VERSION}`, ...this.headers };
965
+ const headers: Record<string, string> = { "User-Agent": `Tina4/${TINA4_VERSION}`, ...this.configuredHeadersFor(targetUrl) };
933
966
  // Attach the configured Authorization / Cookie ONLY when the request
934
967
  // target is same-origin as the configured base. A path that is itself
935
968
  // an absolute off-origin URL (e.g. get("http://evil/x")) otherwise
@@ -1066,9 +1099,9 @@ export class Api {
1066
1099
  * Location, this drains the intermediate response and re-issues to the new
1067
1100
  * URL: 301/302/303 on a non-GET/HEAD become GET (body dropped, urllib
1068
1101
  * behaviour); 307/308 preserve method + body. When the redirect target is a
1069
- * DIFFERENT origin, the Authorization and Cookie headers are stripped so a
1070
- * bearer token / session cookie never leaks to a host you didn't
1071
- * authenticate to.
1102
+ * DIFFERENT origin, only KEEP_ON_CROSS_ORIGIN headers are carried, so a
1103
+ * bearer token, session cookie or any caller-set credential header never
1104
+ * leaks to a host you didn't authenticate to.
1072
1105
  */
1073
1106
  private async performRequest(
1074
1107
  method: string,
@@ -1128,7 +1161,7 @@ export class Api {
1128
1161
  const crossOrigin = !sameOrigin(url, nextUrl);
1129
1162
  let nextMethod = method;
1130
1163
  let nextData = data;
1131
- const nextHeaders: Record<string, string> = { ...headers };
1164
+ const nextHeaders: Record<string, string> = crossOrigin ? keepCrossOriginHeaders(headers) : { ...headers };
1132
1165
 
1133
1166
  // 301/302/303 on a body-bearing method → GET, drop the body
1134
1167
  // (matches urllib's HTTPRedirectHandler); 307/308 preserve.
@@ -1143,12 +1176,6 @@ export class Api {
1143
1176
  deleteHeaderCaseInsensitive(nextHeaders, "content-length");
1144
1177
  }
1145
1178
 
1146
- if (crossOrigin) {
1147
- for (const name of STRIP_ON_CROSS_ORIGIN) {
1148
- deleteHeaderCaseInsensitive(nextHeaders, name);
1149
- }
1150
- }
1151
-
1152
1179
  this.performRequest(nextMethod, nextUrl, nextHeaders, nextData, redirectsLeft - 1).then(resolve);
1153
1180
  return;
1154
1181
  }
@@ -31466,6 +31466,13 @@ import { randomBytes as randomBytes9 } from "node:crypto";
31466
31466
  import { promises as fsp, createWriteStream } from "node:fs";
31467
31467
  import { basename as basename6 } from "node:path";
31468
31468
  import { pipeline } from "node:stream/promises";
31469
+ function keepCrossOriginHeaders(headers) {
31470
+ const out = {};
31471
+ for (const [key, value] of Object.entries(headers)) {
31472
+ if (KEEP_ON_CROSS_ORIGIN.has(key.toLowerCase())) out[key] = value;
31473
+ }
31474
+ return out;
31475
+ }
31469
31476
  function sameOrigin(urlA, urlB) {
31470
31477
  try {
31471
31478
  const a = new URL2(urlA);
@@ -31609,7 +31616,7 @@ async function* parseSseStream(lines) {
31609
31616
  const trailing = emit();
31610
31617
  if (trailing) yield trailing;
31611
31618
  }
31612
- var ApiStreamError, RETRY_STATUSES, DOWNLOAD_CHUNK_SIZE, MAX_REDIRECTS, STRIP_ON_CROSS_ORIGIN, MIME_BY_EXT, Api;
31619
+ var ApiStreamError, RETRY_STATUSES, DOWNLOAD_CHUNK_SIZE, MAX_REDIRECTS, STRIP_ON_CROSS_ORIGIN, KEEP_ON_CROSS_ORIGIN, MIME_BY_EXT, Api;
31613
31620
  var init_api = __esm({
31614
31621
  "../core/src/api.ts"() {
31615
31622
  "use strict";
@@ -31627,6 +31634,14 @@ var init_api = __esm({
31627
31634
  DOWNLOAD_CHUNK_SIZE = 64 * 1024;
31628
31635
  MAX_REDIRECTS = 10;
31629
31636
  STRIP_ON_CROSS_ORIGIN = /* @__PURE__ */ new Set(["authorization", "cookie"]);
31637
+ KEEP_ON_CROSS_ORIGIN = /* @__PURE__ */ new Set([
31638
+ "user-agent",
31639
+ "accept",
31640
+ "accept-encoding",
31641
+ "accept-language",
31642
+ "content-type",
31643
+ "content-length"
31644
+ ]);
31630
31645
  MIME_BY_EXT = {
31631
31646
  txt: "text/plain",
31632
31647
  html: "text/html",
@@ -32082,6 +32097,18 @@ var init_api = __esm({
32082
32097
  }
32083
32098
  return `${this.baseUrl}/${path10.replace(/^\/+/, "")}`;
32084
32099
  }
32100
+ /**
32101
+ * The headers configured on the client, as they may go to `targetUrl`.
32102
+ *
32103
+ * They belong to the base origin, like the token: an absolute target on
32104
+ * another origin gets only the cross-origin-safe ones. A client with no
32105
+ * base has no origin to bind them to, and sends them to the URL each call
32106
+ * names.
32107
+ */
32108
+ configuredHeadersFor(targetUrl) {
32109
+ const offOrigin = targetUrl !== void 0 && this.baseUrl !== "" && !sameOrigin(targetUrl, this.baseUrl);
32110
+ return offOrigin ? keepCrossOriginHeaders(this.headers) : this.headers;
32111
+ }
32085
32112
  /**
32086
32113
  * Build the request headers (default User-Agent + auth + cookie jar +
32087
32114
  * extras) and serialize the body to a Buffer. Shared by every verb,
@@ -32096,7 +32123,7 @@ var init_api = __esm({
32096
32123
  * clobber.
32097
32124
  */
32098
32125
  buildRequest(method, contentType, body, extraHeaders, targetUrl) {
32099
- const headers = { "User-Agent": `Tina4/${TINA4_VERSION}`, ...this.headers };
32126
+ const headers = { "User-Agent": `Tina4/${TINA4_VERSION}`, ...this.configuredHeadersFor(targetUrl) };
32100
32127
  const sameOriginAsBase = targetUrl === void 0 || sameOrigin(targetUrl, this.baseUrl);
32101
32128
  if (this.authHeader && sameOriginAsBase) {
32102
32129
  headers["Authorization"] = this.authHeader;
@@ -32198,9 +32225,9 @@ var init_api = __esm({
32198
32225
  * Location, this drains the intermediate response and re-issues to the new
32199
32226
  * URL: 301/302/303 on a non-GET/HEAD become GET (body dropped, urllib
32200
32227
  * behaviour); 307/308 preserve method + body. When the redirect target is a
32201
- * DIFFERENT origin, the Authorization and Cookie headers are stripped so a
32202
- * bearer token / session cookie never leaks to a host you didn't
32203
- * authenticate to.
32228
+ * DIFFERENT origin, only KEEP_ON_CROSS_ORIGIN headers are carried, so a
32229
+ * bearer token, session cookie or any caller-set credential header never
32230
+ * leaks to a host you didn't authenticate to.
32204
32231
  */
32205
32232
  async performRequest(method, url, headers, data, redirectsLeft) {
32206
32233
  try {
@@ -32244,18 +32271,13 @@ var init_api = __esm({
32244
32271
  const crossOrigin = !sameOrigin(url, nextUrl);
32245
32272
  let nextMethod = method;
32246
32273
  let nextData = data;
32247
- const nextHeaders = { ...headers };
32274
+ const nextHeaders = crossOrigin ? keepCrossOriginHeaders(headers) : { ...headers };
32248
32275
  if ((status2 === 301 || status2 === 302 || status2 === 303) && method !== "GET" && method !== "HEAD") {
32249
32276
  nextMethod = "GET";
32250
32277
  nextData = void 0;
32251
32278
  deleteHeaderCaseInsensitive(nextHeaders, "content-type");
32252
32279
  deleteHeaderCaseInsensitive(nextHeaders, "content-length");
32253
32280
  }
32254
- if (crossOrigin) {
32255
- for (const name of STRIP_ON_CROSS_ORIGIN) {
32256
- deleteHeaderCaseInsensitive(nextHeaders, name);
32257
- }
32258
- }
32259
32281
  this.performRequest(nextMethod, nextUrl, nextHeaders, nextData, redirectsLeft - 1).then(resolve21);
32260
32282
  return;
32261
32283
  }
@@ -318,6 +318,15 @@ export declare class Api {
318
318
  */
319
319
  private openStreamRequest;
320
320
  private buildUrl;
321
+ /**
322
+ * The headers configured on the client, as they may go to `targetUrl`.
323
+ *
324
+ * They belong to the base origin, like the token: an absolute target on
325
+ * another origin gets only the cross-origin-safe ones. A client with no
326
+ * base has no origin to bind them to, and sends them to the URL each call
327
+ * names.
328
+ */
329
+ private configuredHeadersFor;
321
330
  /**
322
331
  * Build the request headers (default User-Agent + auth + cookie jar +
323
332
  * extras) and serialize the body to a Buffer. Shared by every verb,
@@ -357,9 +366,9 @@ export declare class Api {
357
366
  * Location, this drains the intermediate response and re-issues to the new
358
367
  * URL: 301/302/303 on a non-GET/HEAD become GET (body dropped, urllib
359
368
  * behaviour); 307/308 preserve method + body. When the redirect target is a
360
- * DIFFERENT origin, the Authorization and Cookie headers are stripped so a
361
- * bearer token / session cookie never leaks to a host you didn't
362
- * authenticate to.
369
+ * DIFFERENT origin, only KEEP_ON_CROSS_ORIGIN headers are carried, so a
370
+ * bearer token, session cookie or any caller-set credential header never
371
+ * leaks to a host you didn't authenticate to.
363
372
  */
364
373
  private performRequest;
365
374
  /** Buffer a response body, parse JSON if possible, and store cookies. */