@shware/http 2.10.3 → 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.
- package/dist/google-one-tap/index.cjs +2 -0
- package/dist/google-one-tap/index.cjs.map +1 -1
- package/dist/google-one-tap/index.d.cts +7 -1
- package/dist/google-one-tap/index.d.ts +7 -1
- package/dist/google-one-tap/index.mjs +2 -0
- package/dist/google-one-tap/index.mjs.map +1 -1
- package/dist/utils/google-tag-gateway.cjs +2 -2
- package/dist/utils/google-tag-gateway.cjs.map +1 -1
- package/dist/utils/google-tag-gateway.mjs +2 -2
- package/dist/utils/google-tag-gateway.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -49,6 +49,7 @@ function loadScript() {
|
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
async function prompt({
|
|
52
|
+
nonce,
|
|
52
53
|
client_id,
|
|
53
54
|
auto_select = false,
|
|
54
55
|
use_fedcm_for_prompt = true,
|
|
@@ -61,6 +62,7 @@ async function prompt({
|
|
|
61
62
|
ux_mode: "popup",
|
|
62
63
|
context: "signin",
|
|
63
64
|
auto_select,
|
|
65
|
+
nonce,
|
|
64
66
|
client_id,
|
|
65
67
|
use_fedcm_for_prompt,
|
|
66
68
|
cancel_on_tap_outside,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/google-one-tap/index.ts"],"sourcesContent":["import type { CredentialResponse, GoogleAccounts, PromptMomentNotification } from './types';\n\ndeclare global {\n interface Window {\n google: {\n accounts: GoogleAccounts;\n };\n }\n}\n\nexport type Props = {\n client_id: string;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n use_fedcm_for_prompt?: boolean;\n};\n\nexport type PromptMoment = {\n skipped: boolean;\n dismissed: boolean;\n momentType: ReturnType<PromptMomentNotification['getMomentType']>;\n dismissedReason: ReturnType<PromptMomentNotification['getDismissedReason']>;\n};\n\nexport type PromptResult =\n | { authorized: true; credential: CredentialResponse }\n | { authorized: false; moment: PromptMoment };\n\nlet script: HTMLScriptElement | null = null;\n\nfunction loadScript(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (script) {\n if (window.google?.accounts?.id) {\n resolve();\n } else {\n script.addEventListener('load', () => resolve());\n script.addEventListener('error', () =>\n reject(new Error('Failed to load Google One Tap script'))\n );\n }\n return;\n }\n\n script = document.createElement('script');\n script.id = 'google-one-tap';\n script.async = true;\n script.defer = true;\n script.src = 'https://accounts.google.com/gsi/client';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load Google One Tap script'));\n\n document.head.appendChild(script);\n });\n}\n\n/** debug: chrome://settings/content/federatedIdentityApi */\nexport async function prompt({\n client_id,\n auto_select = false,\n use_fedcm_for_prompt = true,\n cancel_on_tap_outside = false,\n}: Props): Promise<PromptResult> {\n await loadScript();\n\n return new Promise<PromptResult>((resolve) => {\n let settled = false;\n\n window.google.accounts.id.initialize({\n ux_mode: 'popup',\n context: 'signin',\n auto_select,\n client_id,\n use_fedcm_for_prompt,\n cancel_on_tap_outside,\n callback: (credential) => {\n if (settled) return;\n settled = true;\n resolve({ authorized: true, credential });\n },\n native_callback: (credential) => {\n if (settled) return;\n settled = true;\n resolve({ authorized: true, credential });\n },\n });\n\n window.google.accounts.id.prompt((notification) => {\n if (settled) return;\n\n if (\n notification.isSkippedMoment() ||\n (notification.isDismissedMoment() &&\n notification.getDismissedReason() !== 'credential_returned')\n ) {\n settled = true;\n resolve({\n authorized: false,\n moment: {\n momentType: notification.getMomentType(),\n skipped: notification.isSkippedMoment(),\n dismissed: notification.isDismissedMoment(),\n dismissedReason: notification.getDismissedReason(),\n },\n });\n }\n });\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../../src/google-one-tap/index.ts"],"sourcesContent":["import type { CredentialResponse, GoogleAccounts, PromptMomentNotification } from './types';\n\ndeclare global {\n interface Window {\n google: {\n accounts: GoogleAccounts;\n };\n }\n}\n\nexport type Props = {\n /**\n * Opaque nonce string forwarded as-is to Google. Google echoes it back in\n * the ID Token's `nonce` claim per the OIDC spec; the caller is responsible\n * for any hashing/encoding required by its verifier.\n */\n nonce?: string;\n client_id: string;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n use_fedcm_for_prompt?: boolean;\n};\n\nexport type PromptMoment = {\n skipped: boolean;\n dismissed: boolean;\n momentType: ReturnType<PromptMomentNotification['getMomentType']>;\n dismissedReason: ReturnType<PromptMomentNotification['getDismissedReason']>;\n};\n\nexport type PromptResult =\n | { authorized: true; credential: CredentialResponse }\n | { authorized: false; moment: PromptMoment };\n\nlet script: HTMLScriptElement | null = null;\n\nfunction loadScript(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (script) {\n if (window.google?.accounts?.id) {\n resolve();\n } else {\n script.addEventListener('load', () => resolve());\n script.addEventListener('error', () =>\n reject(new Error('Failed to load Google One Tap script'))\n );\n }\n return;\n }\n\n script = document.createElement('script');\n script.id = 'google-one-tap';\n script.async = true;\n script.defer = true;\n script.src = 'https://accounts.google.com/gsi/client';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load Google One Tap script'));\n\n document.head.appendChild(script);\n });\n}\n\n/** debug: chrome://settings/content/federatedIdentityApi */\nexport async function prompt({\n nonce,\n client_id,\n auto_select = false,\n use_fedcm_for_prompt = true,\n cancel_on_tap_outside = false,\n}: Props): Promise<PromptResult> {\n await loadScript();\n\n return new Promise<PromptResult>((resolve) => {\n let settled = false;\n\n window.google.accounts.id.initialize({\n ux_mode: 'popup',\n context: 'signin',\n auto_select,\n nonce,\n client_id,\n use_fedcm_for_prompt,\n cancel_on_tap_outside,\n callback: (credential) => {\n if (settled) return;\n settled = true;\n resolve({ authorized: true, credential });\n },\n native_callback: (credential) => {\n if (settled) return;\n settled = true;\n resolve({ authorized: true, credential });\n },\n });\n\n window.google.accounts.id.prompt((notification) => {\n if (settled) return;\n\n if (\n notification.isSkippedMoment() ||\n (notification.isDismissedMoment() &&\n notification.getDismissedReason() !== 'credential_returned')\n ) {\n settled = true;\n resolve({\n authorized: false,\n moment: {\n momentType: notification.getMomentType(),\n skipped: notification.isSkippedMoment(),\n dismissed: notification.isDismissedMoment(),\n dismissedReason: notification.getDismissedReason(),\n },\n });\n }\n });\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkCA,IAAI,SAAmC;AAEvC,SAAS,aAA4B;AACnC,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI,QAAQ;AACV,UAAI,OAAO,QAAQ,UAAU,IAAI;AAC/B,gBAAQ;AAAA,MACV,OAAO;AACL,eAAO,iBAAiB,QAAQ,MAAM,QAAQ,CAAC;AAC/C,eAAO;AAAA,UAAiB;AAAA,UAAS,MAC/B,OAAO,IAAI,MAAM,sCAAsC,CAAC;AAAA,QAC1D;AAAA,MACF;AACA;AAAA,IACF;AAEA,aAAS,SAAS,cAAc,QAAQ;AACxC,WAAO,KAAK;AACZ,WAAO,QAAQ;AACf,WAAO,QAAQ;AACf,WAAO,MAAM;AACb,WAAO,SAAS,MAAM,QAAQ;AAC9B,WAAO,UAAU,MAAM,OAAO,IAAI,MAAM,sCAAsC,CAAC;AAE/E,aAAS,KAAK,YAAY,MAAM;AAAA,EAClC,CAAC;AACH;AAGA,eAAsB,OAAO;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,uBAAuB;AAAA,EACvB,wBAAwB;AAC1B,GAAiC;AAC/B,QAAM,WAAW;AAEjB,SAAO,IAAI,QAAsB,CAAC,YAAY;AAC5C,QAAI,UAAU;AAEd,WAAO,OAAO,SAAS,GAAG,WAAW;AAAA,MACnC,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,CAAC,eAAe;AACxB,YAAI,QAAS;AACb,kBAAU;AACV,gBAAQ,EAAE,YAAY,MAAM,WAAW,CAAC;AAAA,MAC1C;AAAA,MACA,iBAAiB,CAAC,eAAe;AAC/B,YAAI,QAAS;AACb,kBAAU;AACV,gBAAQ,EAAE,YAAY,MAAM,WAAW,CAAC;AAAA,MAC1C;AAAA,IACF,CAAC;AAED,WAAO,OAAO,SAAS,GAAG,OAAO,CAAC,iBAAiB;AACjD,UAAI,QAAS;AAEb,UACE,aAAa,gBAAgB,KAC5B,aAAa,kBAAkB,KAC9B,aAAa,mBAAmB,MAAM,uBACxC;AACA,kBAAU;AACV,gBAAQ;AAAA,UACN,YAAY;AAAA,UACZ,QAAQ;AAAA,YACN,YAAY,aAAa,cAAc;AAAA,YACvC,SAAS,aAAa,gBAAgB;AAAA,YACtC,WAAW,aAAa,kBAAkB;AAAA,YAC1C,iBAAiB,aAAa,mBAAmB;AAAA,UACnD;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
|
|
@@ -8,6 +8,12 @@ declare global {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
type Props = {
|
|
11
|
+
/**
|
|
12
|
+
* Opaque nonce string forwarded as-is to Google. Google echoes it back in
|
|
13
|
+
* the ID Token's `nonce` claim per the OIDC spec; the caller is responsible
|
|
14
|
+
* for any hashing/encoding required by its verifier.
|
|
15
|
+
*/
|
|
16
|
+
nonce?: string;
|
|
11
17
|
client_id: string;
|
|
12
18
|
auto_select?: boolean;
|
|
13
19
|
cancel_on_tap_outside?: boolean;
|
|
@@ -27,6 +33,6 @@ type PromptResult = {
|
|
|
27
33
|
moment: PromptMoment;
|
|
28
34
|
};
|
|
29
35
|
/** debug: chrome://settings/content/federatedIdentityApi */
|
|
30
|
-
declare function prompt({ client_id, auto_select, use_fedcm_for_prompt, cancel_on_tap_outside, }: Props): Promise<PromptResult>;
|
|
36
|
+
declare function prompt({ nonce, client_id, auto_select, use_fedcm_for_prompt, cancel_on_tap_outside, }: Props): Promise<PromptResult>;
|
|
31
37
|
|
|
32
38
|
export { type PromptMoment, type PromptResult, type Props, prompt };
|
|
@@ -8,6 +8,12 @@ declare global {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
type Props = {
|
|
11
|
+
/**
|
|
12
|
+
* Opaque nonce string forwarded as-is to Google. Google echoes it back in
|
|
13
|
+
* the ID Token's `nonce` claim per the OIDC spec; the caller is responsible
|
|
14
|
+
* for any hashing/encoding required by its verifier.
|
|
15
|
+
*/
|
|
16
|
+
nonce?: string;
|
|
11
17
|
client_id: string;
|
|
12
18
|
auto_select?: boolean;
|
|
13
19
|
cancel_on_tap_outside?: boolean;
|
|
@@ -27,6 +33,6 @@ type PromptResult = {
|
|
|
27
33
|
moment: PromptMoment;
|
|
28
34
|
};
|
|
29
35
|
/** debug: chrome://settings/content/federatedIdentityApi */
|
|
30
|
-
declare function prompt({ client_id, auto_select, use_fedcm_for_prompt, cancel_on_tap_outside, }: Props): Promise<PromptResult>;
|
|
36
|
+
declare function prompt({ nonce, client_id, auto_select, use_fedcm_for_prompt, cancel_on_tap_outside, }: Props): Promise<PromptResult>;
|
|
31
37
|
|
|
32
38
|
export { type PromptMoment, type PromptResult, type Props, prompt };
|
|
@@ -25,6 +25,7 @@ function loadScript() {
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
async function prompt({
|
|
28
|
+
nonce,
|
|
28
29
|
client_id,
|
|
29
30
|
auto_select = false,
|
|
30
31
|
use_fedcm_for_prompt = true,
|
|
@@ -37,6 +38,7 @@ async function prompt({
|
|
|
37
38
|
ux_mode: "popup",
|
|
38
39
|
context: "signin",
|
|
39
40
|
auto_select,
|
|
41
|
+
nonce,
|
|
40
42
|
client_id,
|
|
41
43
|
use_fedcm_for_prompt,
|
|
42
44
|
cancel_on_tap_outside,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/google-one-tap/index.ts"],"sourcesContent":["import type { CredentialResponse, GoogleAccounts, PromptMomentNotification } from './types';\n\ndeclare global {\n interface Window {\n google: {\n accounts: GoogleAccounts;\n };\n }\n}\n\nexport type Props = {\n client_id: string;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n use_fedcm_for_prompt?: boolean;\n};\n\nexport type PromptMoment = {\n skipped: boolean;\n dismissed: boolean;\n momentType: ReturnType<PromptMomentNotification['getMomentType']>;\n dismissedReason: ReturnType<PromptMomentNotification['getDismissedReason']>;\n};\n\nexport type PromptResult =\n | { authorized: true; credential: CredentialResponse }\n | { authorized: false; moment: PromptMoment };\n\nlet script: HTMLScriptElement | null = null;\n\nfunction loadScript(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (script) {\n if (window.google?.accounts?.id) {\n resolve();\n } else {\n script.addEventListener('load', () => resolve());\n script.addEventListener('error', () =>\n reject(new Error('Failed to load Google One Tap script'))\n );\n }\n return;\n }\n\n script = document.createElement('script');\n script.id = 'google-one-tap';\n script.async = true;\n script.defer = true;\n script.src = 'https://accounts.google.com/gsi/client';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load Google One Tap script'));\n\n document.head.appendChild(script);\n });\n}\n\n/** debug: chrome://settings/content/federatedIdentityApi */\nexport async function prompt({\n client_id,\n auto_select = false,\n use_fedcm_for_prompt = true,\n cancel_on_tap_outside = false,\n}: Props): Promise<PromptResult> {\n await loadScript();\n\n return new Promise<PromptResult>((resolve) => {\n let settled = false;\n\n window.google.accounts.id.initialize({\n ux_mode: 'popup',\n context: 'signin',\n auto_select,\n client_id,\n use_fedcm_for_prompt,\n cancel_on_tap_outside,\n callback: (credential) => {\n if (settled) return;\n settled = true;\n resolve({ authorized: true, credential });\n },\n native_callback: (credential) => {\n if (settled) return;\n settled = true;\n resolve({ authorized: true, credential });\n },\n });\n\n window.google.accounts.id.prompt((notification) => {\n if (settled) return;\n\n if (\n notification.isSkippedMoment() ||\n (notification.isDismissedMoment() &&\n notification.getDismissedReason() !== 'credential_returned')\n ) {\n settled = true;\n resolve({\n authorized: false,\n moment: {\n momentType: notification.getMomentType(),\n skipped: notification.isSkippedMoment(),\n dismissed: notification.isDismissedMoment(),\n dismissedReason: notification.getDismissedReason(),\n },\n });\n }\n });\n });\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../src/google-one-tap/index.ts"],"sourcesContent":["import type { CredentialResponse, GoogleAccounts, PromptMomentNotification } from './types';\n\ndeclare global {\n interface Window {\n google: {\n accounts: GoogleAccounts;\n };\n }\n}\n\nexport type Props = {\n /**\n * Opaque nonce string forwarded as-is to Google. Google echoes it back in\n * the ID Token's `nonce` claim per the OIDC spec; the caller is responsible\n * for any hashing/encoding required by its verifier.\n */\n nonce?: string;\n client_id: string;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n use_fedcm_for_prompt?: boolean;\n};\n\nexport type PromptMoment = {\n skipped: boolean;\n dismissed: boolean;\n momentType: ReturnType<PromptMomentNotification['getMomentType']>;\n dismissedReason: ReturnType<PromptMomentNotification['getDismissedReason']>;\n};\n\nexport type PromptResult =\n | { authorized: true; credential: CredentialResponse }\n | { authorized: false; moment: PromptMoment };\n\nlet script: HTMLScriptElement | null = null;\n\nfunction loadScript(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (script) {\n if (window.google?.accounts?.id) {\n resolve();\n } else {\n script.addEventListener('load', () => resolve());\n script.addEventListener('error', () =>\n reject(new Error('Failed to load Google One Tap script'))\n );\n }\n return;\n }\n\n script = document.createElement('script');\n script.id = 'google-one-tap';\n script.async = true;\n script.defer = true;\n script.src = 'https://accounts.google.com/gsi/client';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load Google One Tap script'));\n\n document.head.appendChild(script);\n });\n}\n\n/** debug: chrome://settings/content/federatedIdentityApi */\nexport async function prompt({\n nonce,\n client_id,\n auto_select = false,\n use_fedcm_for_prompt = true,\n cancel_on_tap_outside = false,\n}: Props): Promise<PromptResult> {\n await loadScript();\n\n return new Promise<PromptResult>((resolve) => {\n let settled = false;\n\n window.google.accounts.id.initialize({\n ux_mode: 'popup',\n context: 'signin',\n auto_select,\n nonce,\n client_id,\n use_fedcm_for_prompt,\n cancel_on_tap_outside,\n callback: (credential) => {\n if (settled) return;\n settled = true;\n resolve({ authorized: true, credential });\n },\n native_callback: (credential) => {\n if (settled) return;\n settled = true;\n resolve({ authorized: true, credential });\n },\n });\n\n window.google.accounts.id.prompt((notification) => {\n if (settled) return;\n\n if (\n notification.isSkippedMoment() ||\n (notification.isDismissedMoment() &&\n notification.getDismissedReason() !== 'credential_returned')\n ) {\n settled = true;\n resolve({\n authorized: false,\n moment: {\n momentType: notification.getMomentType(),\n skipped: notification.isSkippedMoment(),\n dismissed: notification.isDismissedMoment(),\n dismissedReason: notification.getDismissedReason(),\n },\n });\n }\n });\n });\n}\n"],"mappings":";AAkCA,IAAI,SAAmC;AAEvC,SAAS,aAA4B;AACnC,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI,QAAQ;AACV,UAAI,OAAO,QAAQ,UAAU,IAAI;AAC/B,gBAAQ;AAAA,MACV,OAAO;AACL,eAAO,iBAAiB,QAAQ,MAAM,QAAQ,CAAC;AAC/C,eAAO;AAAA,UAAiB;AAAA,UAAS,MAC/B,OAAO,IAAI,MAAM,sCAAsC,CAAC;AAAA,QAC1D;AAAA,MACF;AACA;AAAA,IACF;AAEA,aAAS,SAAS,cAAc,QAAQ;AACxC,WAAO,KAAK;AACZ,WAAO,QAAQ;AACf,WAAO,QAAQ;AACf,WAAO,MAAM;AACb,WAAO,SAAS,MAAM,QAAQ;AAC9B,WAAO,UAAU,MAAM,OAAO,IAAI,MAAM,sCAAsC,CAAC;AAE/E,aAAS,KAAK,YAAY,MAAM;AAAA,EAClC,CAAC;AACH;AAGA,eAAsB,OAAO;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,uBAAuB;AAAA,EACvB,wBAAwB;AAC1B,GAAiC;AAC/B,QAAM,WAAW;AAEjB,SAAO,IAAI,QAAsB,CAAC,YAAY;AAC5C,QAAI,UAAU;AAEd,WAAO,OAAO,SAAS,GAAG,WAAW;AAAA,MACnC,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,CAAC,eAAe;AACxB,YAAI,QAAS;AACb,kBAAU;AACV,gBAAQ,EAAE,YAAY,MAAM,WAAW,CAAC;AAAA,MAC1C;AAAA,MACA,iBAAiB,CAAC,eAAe;AAC/B,YAAI,QAAS;AACb,kBAAU;AACV,gBAAQ,EAAE,YAAY,MAAM,WAAW,CAAC;AAAA,MAC1C;AAAA,IACF,CAAC;AAED,WAAO,OAAO,SAAS,GAAG,OAAO,CAAC,iBAAiB;AACjD,UAAI,QAAS;AAEb,UACE,aAAa,gBAAgB,KAC5B,aAAa,kBAAkB,KAC9B,aAAa,mBAAmB,MAAM,uBACxC;AACA,kBAAU;AACV,gBAAQ;AAAA,UACN,YAAY;AAAA,UACZ,QAAQ;AAAA,YACN,YAAY,aAAa,cAAc;AAAA,YACvC,SAAS,aAAa,gBAAgB;AAAA,YACtC,WAAW,aAAa,kBAAkB;AAAA,YAC1C,iBAAiB,aAAa,mBAAmB;AAAA,UACnD;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
|
|
@@ -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",
|