@shware/http 2.10.4 → 2.10.5
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.
|
@@ -41,11 +41,11 @@ async function forwardToGoogleTagGateway(request, gaId) {
|
|
|
41
41
|
headers.set("x-forwarded-region", region);
|
|
42
42
|
}
|
|
43
43
|
const hasBody = request.method !== "GET" && request.method !== "HEAD";
|
|
44
|
+
const body = hasBody ? await request.arrayBuffer() : void 0;
|
|
44
45
|
const response = await fetch(target, {
|
|
45
46
|
method: request.method,
|
|
46
47
|
headers,
|
|
47
|
-
body
|
|
48
|
-
...hasBody && { duplex: "half" }
|
|
48
|
+
body
|
|
49
49
|
});
|
|
50
50
|
const responseHeaders = new Headers(response.headers);
|
|
51
51
|
responseHeaders.delete("content-encoding");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/google-tag-gateway.ts"],"sourcesContent":["import { getGeolocation } from './geolocation';\n\n/**\n * In a browser, verify the setup by navigating to: https://example.com/metrics/healthy. The page\n * should read ok. Verify that geographical information is being included by navigating to:\n * https://example.com/metrics/?validate_geo=healthy. The page should read ok.\n */\nexport async function forwardToGoogleTagGateway(request: Request, gaId: string) {\n const GATEWAY_HOST = `${gaId}.fps.goog`;\n const { pathname, search } = new URL(request.url);\n\n const target = `https://${GATEWAY_HOST}${pathname}${search}`;\n\n const headers = new Headers();\n headers.set('host', GATEWAY_HOST);\n\n // Forward cookies\n const cookie = request.headers.get('cookie');\n if (cookie) headers.set('cookie', cookie);\n\n // Convert Vercel geo headers to Google Tag Gateway format\n // https://developers.google.com/tag-platform/tag-manager/gateway/setup-guide\n const { country, region } = getGeolocation(request);\n\n if (country && region) {\n headers.set('x-forwarded-countryregion', `${country}-${region}`);\n } else if (country) {\n headers.set('x-forwarded-country', country);\n } else if (region) {\n headers.set('x-forwarded-region', region);\n }\n\n const hasBody = request.method !== 'GET' && request.method !== 'HEAD';\n
|
|
1
|
+
{"version":3,"sources":["../../src/utils/google-tag-gateway.ts"],"sourcesContent":["import { getGeolocation } from './geolocation';\n\n/**\n * In a browser, verify the setup by navigating to: https://example.com/metrics/healthy. The page\n * should read ok. Verify that geographical information is being included by navigating to:\n * https://example.com/metrics/?validate_geo=healthy. The page should read ok.\n */\nexport async function forwardToGoogleTagGateway(request: Request, gaId: string) {\n const GATEWAY_HOST = `${gaId}.fps.goog`;\n const { pathname, search } = new URL(request.url);\n\n const target = `https://${GATEWAY_HOST}${pathname}${search}`;\n\n const headers = new Headers();\n headers.set('host', GATEWAY_HOST);\n\n // Forward cookies\n const cookie = request.headers.get('cookie');\n if (cookie) headers.set('cookie', cookie);\n\n // Convert Vercel geo headers to Google Tag Gateway format\n // https://developers.google.com/tag-platform/tag-manager/gateway/setup-guide\n const { country, region } = getGeolocation(request);\n\n if (country && region) {\n headers.set('x-forwarded-countryregion', `${country}-${region}`);\n } else if (country) {\n headers.set('x-forwarded-country', country);\n } else if (region) {\n headers.set('x-forwarded-region', region);\n }\n\n const hasBody = request.method !== 'GET' && request.method !== 'HEAD';\n\n // Buffer the body instead of streaming it. The conversion endpoint\n // (g/measurement/conversion) answers POSTs with a 302 to www.google.com, and we want\n // to follow that hop on the server so the browser never sees a Google domain (the whole\n // point of the first-party gateway). Following a redirect requires re-issuing the\n // request, which undici cannot do with a one-shot `request.body` stream — it throws\n // \"fetch failed\", surfacing as a 500. A buffered body is replayable, so the redirect\n // is followed transparently here.\n const body = hasBody ? await request.arrayBuffer() : undefined;\n\n const response = await fetch(target, {\n method: request.method,\n headers,\n body,\n });\n\n // Strip content-encoding/content-length because fetch() auto-decompresses\n // but keeps the original headers, causing ERR_CONTENT_DECODING_FAILED\n const responseHeaders = new Headers(response.headers);\n responseHeaders.delete('content-encoding');\n responseHeaders.delete('content-length');\n\n return new Response(response.body, { status: response.status, headers: responseHeaders });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAA+B;AAO/B,eAAsB,0BAA0B,SAAkB,MAAc;AAC9E,QAAM,eAAe,GAAG,IAAI;AAC5B,QAAM,EAAE,UAAU,OAAO,IAAI,IAAI,IAAI,QAAQ,GAAG;AAEhD,QAAM,SAAS,WAAW,YAAY,GAAG,QAAQ,GAAG,MAAM;AAE1D,QAAM,UAAU,IAAI,QAAQ;AAC5B,UAAQ,IAAI,QAAQ,YAAY;AAGhC,QAAM,SAAS,QAAQ,QAAQ,IAAI,QAAQ;AAC3C,MAAI,OAAQ,SAAQ,IAAI,UAAU,MAAM;AAIxC,QAAM,EAAE,SAAS,OAAO,QAAI,mCAAe,OAAO;AAElD,MAAI,WAAW,QAAQ;AACrB,YAAQ,IAAI,6BAA6B,GAAG,OAAO,IAAI,MAAM,EAAE;AAAA,EACjE,WAAW,SAAS;AAClB,YAAQ,IAAI,uBAAuB,OAAO;AAAA,EAC5C,WAAW,QAAQ;AACjB,YAAQ,IAAI,sBAAsB,MAAM;AAAA,EAC1C;AAEA,QAAM,UAAU,QAAQ,WAAW,SAAS,QAAQ,WAAW;AAS/D,QAAM,OAAO,UAAU,MAAM,QAAQ,YAAY,IAAI;AAErD,QAAM,WAAW,MAAM,MAAM,QAAQ;AAAA,IACnC,QAAQ,QAAQ;AAAA,IAChB;AAAA,IACA;AAAA,EACF,CAAC;AAID,QAAM,kBAAkB,IAAI,QAAQ,SAAS,OAAO;AACpD,kBAAgB,OAAO,kBAAkB;AACzC,kBAAgB,OAAO,gBAAgB;AAEvC,SAAO,IAAI,SAAS,SAAS,MAAM,EAAE,QAAQ,SAAS,QAAQ,SAAS,gBAAgB,CAAC;AAC1F;","names":[]}
|
|
@@ -17,11 +17,11 @@ async function forwardToGoogleTagGateway(request, gaId) {
|
|
|
17
17
|
headers.set("x-forwarded-region", region);
|
|
18
18
|
}
|
|
19
19
|
const hasBody = request.method !== "GET" && request.method !== "HEAD";
|
|
20
|
+
const body = hasBody ? await request.arrayBuffer() : void 0;
|
|
20
21
|
const response = await fetch(target, {
|
|
21
22
|
method: request.method,
|
|
22
23
|
headers,
|
|
23
|
-
body
|
|
24
|
-
...hasBody && { duplex: "half" }
|
|
24
|
+
body
|
|
25
25
|
});
|
|
26
26
|
const responseHeaders = new Headers(response.headers);
|
|
27
27
|
responseHeaders.delete("content-encoding");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/google-tag-gateway.ts"],"sourcesContent":["import { getGeolocation } from './geolocation';\n\n/**\n * In a browser, verify the setup by navigating to: https://example.com/metrics/healthy. The page\n * should read ok. Verify that geographical information is being included by navigating to:\n * https://example.com/metrics/?validate_geo=healthy. The page should read ok.\n */\nexport async function forwardToGoogleTagGateway(request: Request, gaId: string) {\n const GATEWAY_HOST = `${gaId}.fps.goog`;\n const { pathname, search } = new URL(request.url);\n\n const target = `https://${GATEWAY_HOST}${pathname}${search}`;\n\n const headers = new Headers();\n headers.set('host', GATEWAY_HOST);\n\n // Forward cookies\n const cookie = request.headers.get('cookie');\n if (cookie) headers.set('cookie', cookie);\n\n // Convert Vercel geo headers to Google Tag Gateway format\n // https://developers.google.com/tag-platform/tag-manager/gateway/setup-guide\n const { country, region } = getGeolocation(request);\n\n if (country && region) {\n headers.set('x-forwarded-countryregion', `${country}-${region}`);\n } else if (country) {\n headers.set('x-forwarded-country', country);\n } else if (region) {\n headers.set('x-forwarded-region', region);\n }\n\n const hasBody = request.method !== 'GET' && request.method !== 'HEAD';\n
|
|
1
|
+
{"version":3,"sources":["../../src/utils/google-tag-gateway.ts"],"sourcesContent":["import { getGeolocation } from './geolocation';\n\n/**\n * In a browser, verify the setup by navigating to: https://example.com/metrics/healthy. The page\n * should read ok. Verify that geographical information is being included by navigating to:\n * https://example.com/metrics/?validate_geo=healthy. The page should read ok.\n */\nexport async function forwardToGoogleTagGateway(request: Request, gaId: string) {\n const GATEWAY_HOST = `${gaId}.fps.goog`;\n const { pathname, search } = new URL(request.url);\n\n const target = `https://${GATEWAY_HOST}${pathname}${search}`;\n\n const headers = new Headers();\n headers.set('host', GATEWAY_HOST);\n\n // Forward cookies\n const cookie = request.headers.get('cookie');\n if (cookie) headers.set('cookie', cookie);\n\n // Convert Vercel geo headers to Google Tag Gateway format\n // https://developers.google.com/tag-platform/tag-manager/gateway/setup-guide\n const { country, region } = getGeolocation(request);\n\n if (country && region) {\n headers.set('x-forwarded-countryregion', `${country}-${region}`);\n } else if (country) {\n headers.set('x-forwarded-country', country);\n } else if (region) {\n headers.set('x-forwarded-region', region);\n }\n\n const hasBody = request.method !== 'GET' && request.method !== 'HEAD';\n\n // Buffer the body instead of streaming it. The conversion endpoint\n // (g/measurement/conversion) answers POSTs with a 302 to www.google.com, and we want\n // to follow that hop on the server so the browser never sees a Google domain (the whole\n // point of the first-party gateway). Following a redirect requires re-issuing the\n // request, which undici cannot do with a one-shot `request.body` stream — it throws\n // \"fetch failed\", surfacing as a 500. A buffered body is replayable, so the redirect\n // is followed transparently here.\n const body = hasBody ? await request.arrayBuffer() : undefined;\n\n const response = await fetch(target, {\n method: request.method,\n headers,\n body,\n });\n\n // Strip content-encoding/content-length because fetch() auto-decompresses\n // but keeps the original headers, causing ERR_CONTENT_DECODING_FAILED\n const responseHeaders = new Headers(response.headers);\n responseHeaders.delete('content-encoding');\n responseHeaders.delete('content-length');\n\n return new Response(response.body, { status: response.status, headers: responseHeaders });\n}\n"],"mappings":";AAAA,SAAS,sBAAsB;AAO/B,eAAsB,0BAA0B,SAAkB,MAAc;AAC9E,QAAM,eAAe,GAAG,IAAI;AAC5B,QAAM,EAAE,UAAU,OAAO,IAAI,IAAI,IAAI,QAAQ,GAAG;AAEhD,QAAM,SAAS,WAAW,YAAY,GAAG,QAAQ,GAAG,MAAM;AAE1D,QAAM,UAAU,IAAI,QAAQ;AAC5B,UAAQ,IAAI,QAAQ,YAAY;AAGhC,QAAM,SAAS,QAAQ,QAAQ,IAAI,QAAQ;AAC3C,MAAI,OAAQ,SAAQ,IAAI,UAAU,MAAM;AAIxC,QAAM,EAAE,SAAS,OAAO,IAAI,eAAe,OAAO;AAElD,MAAI,WAAW,QAAQ;AACrB,YAAQ,IAAI,6BAA6B,GAAG,OAAO,IAAI,MAAM,EAAE;AAAA,EACjE,WAAW,SAAS;AAClB,YAAQ,IAAI,uBAAuB,OAAO;AAAA,EAC5C,WAAW,QAAQ;AACjB,YAAQ,IAAI,sBAAsB,MAAM;AAAA,EAC1C;AAEA,QAAM,UAAU,QAAQ,WAAW,SAAS,QAAQ,WAAW;AAS/D,QAAM,OAAO,UAAU,MAAM,QAAQ,YAAY,IAAI;AAErD,QAAM,WAAW,MAAM,MAAM,QAAQ;AAAA,IACnC,QAAQ,QAAQ;AAAA,IAChB;AAAA,IACA;AAAA,EACF,CAAC;AAID,QAAM,kBAAkB,IAAI,QAAQ,SAAS,OAAO;AACpD,kBAAgB,OAAO,kBAAkB;AACzC,kBAAgB,OAAO,gBAAgB;AAEvC,SAAO,IAAI,SAAS,SAAS,MAAM,EAAE,QAAQ,SAAS,QAAQ,SAAS,gBAAgB,CAAC;AAC1F;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shware/http",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"vitest": "^4.1.5",
|
|
42
42
|
"zod": "^4.4.3",
|
|
43
|
-
"@shware/utils": "^1.4.
|
|
43
|
+
"@shware/utils": "^1.4.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "^25",
|