@agentsean/google 1.0.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.
Files changed (112) hide show
  1. package/LICENSE +661 -0
  2. package/dist/audit-extras.d.ts +21 -0
  3. package/dist/audit-extras.d.ts.map +1 -0
  4. package/dist/audit-extras.js +62 -0
  5. package/dist/audit-extras.js.map +1 -0
  6. package/dist/broker.d.ts +47 -0
  7. package/dist/broker.d.ts.map +1 -0
  8. package/dist/broker.js +146 -0
  9. package/dist/broker.js.map +1 -0
  10. package/dist/causes.d.ts +157 -0
  11. package/dist/causes.d.ts.map +1 -0
  12. package/dist/causes.js +175 -0
  13. package/dist/causes.js.map +1 -0
  14. package/dist/connect-flow.d.ts +63 -0
  15. package/dist/connect-flow.d.ts.map +1 -0
  16. package/dist/connect-flow.js +150 -0
  17. package/dist/connect-flow.js.map +1 -0
  18. package/dist/crux.d.ts +37 -0
  19. package/dist/crux.d.ts.map +1 -0
  20. package/dist/crux.js +112 -0
  21. package/dist/crux.js.map +1 -0
  22. package/dist/data/changepoints.json +174 -0
  23. package/dist/data/quotas.json +17 -0
  24. package/dist/errors.d.ts +46 -0
  25. package/dist/errors.d.ts.map +1 -0
  26. package/dist/errors.js +110 -0
  27. package/dist/errors.js.map +1 -0
  28. package/dist/ga4.d.ts +46 -0
  29. package/dist/ga4.d.ts.map +1 -0
  30. package/dist/ga4.js +126 -0
  31. package/dist/ga4.js.map +1 -0
  32. package/dist/gsc.d.ts +98 -0
  33. package/dist/gsc.d.ts.map +1 -0
  34. package/dist/gsc.js +141 -0
  35. package/dist/gsc.js.map +1 -0
  36. package/dist/http.d.ts +14 -0
  37. package/dist/http.d.ts.map +1 -0
  38. package/dist/http.js +47 -0
  39. package/dist/http.js.map +1 -0
  40. package/dist/incidents.d.ts +51 -0
  41. package/dist/incidents.d.ts.map +1 -0
  42. package/dist/incidents.js +221 -0
  43. package/dist/incidents.js.map +1 -0
  44. package/dist/index.d.ts +27 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +27 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/integrity.d.ts +32 -0
  49. package/dist/integrity.d.ts.map +1 -0
  50. package/dist/integrity.js +52 -0
  51. package/dist/integrity.js.map +1 -0
  52. package/dist/oauth-broker.d.ts +38 -0
  53. package/dist/oauth-broker.d.ts.map +1 -0
  54. package/dist/oauth-broker.js +81 -0
  55. package/dist/oauth-broker.js.map +1 -0
  56. package/dist/oauth-config.d.ts +16 -0
  57. package/dist/oauth-config.d.ts.map +1 -0
  58. package/dist/oauth-config.js +24 -0
  59. package/dist/oauth-config.js.map +1 -0
  60. package/dist/oauth-desktop.d.ts +29 -0
  61. package/dist/oauth-desktop.d.ts.map +1 -0
  62. package/dist/oauth-desktop.js +76 -0
  63. package/dist/oauth-desktop.js.map +1 -0
  64. package/dist/pending.d.ts +18 -0
  65. package/dist/pending.d.ts.map +1 -0
  66. package/dist/pending.js +29 -0
  67. package/dist/pending.js.map +1 -0
  68. package/dist/persist.d.ts +48 -0
  69. package/dist/persist.d.ts.map +1 -0
  70. package/dist/persist.js +298 -0
  71. package/dist/persist.js.map +1 -0
  72. package/dist/pkce.d.ts +9 -0
  73. package/dist/pkce.d.ts.map +1 -0
  74. package/dist/pkce.js +13 -0
  75. package/dist/pkce.js.map +1 -0
  76. package/dist/psi.d.ts +19 -0
  77. package/dist/psi.d.ts.map +1 -0
  78. package/dist/psi.js +47 -0
  79. package/dist/psi.js.map +1 -0
  80. package/dist/quota.d.ts +22 -0
  81. package/dist/quota.d.ts.map +1 -0
  82. package/dist/quota.js +136 -0
  83. package/dist/quota.js.map +1 -0
  84. package/dist/reconcile.d.ts +19 -0
  85. package/dist/reconcile.d.ts.map +1 -0
  86. package/dist/reconcile.js +89 -0
  87. package/dist/reconcile.js.map +1 -0
  88. package/dist/scopes.d.ts +25 -0
  89. package/dist/scopes.d.ts.map +1 -0
  90. package/dist/scopes.js +49 -0
  91. package/dist/scopes.js.map +1 -0
  92. package/dist/seal.d.ts +4 -0
  93. package/dist/seal.d.ts.map +1 -0
  94. package/dist/seal.js +27 -0
  95. package/dist/seal.js.map +1 -0
  96. package/dist/sync.d.ts +29 -0
  97. package/dist/sync.d.ts.map +1 -0
  98. package/dist/sync.js +266 -0
  99. package/dist/sync.js.map +1 -0
  100. package/dist/tokens.d.ts +57 -0
  101. package/dist/tokens.d.ts.map +1 -0
  102. package/dist/tokens.js +122 -0
  103. package/dist/tokens.js.map +1 -0
  104. package/dist/verification.d.ts +17 -0
  105. package/dist/verification.d.ts.map +1 -0
  106. package/dist/verification.js +51 -0
  107. package/dist/verification.js.map +1 -0
  108. package/dist/waterfall.d.ts +39 -0
  109. package/dist/waterfall.d.ts.map +1 -0
  110. package/dist/waterfall.js +167 -0
  111. package/dist/waterfall.js.map +1 -0
  112. package/package.json +52 -0
@@ -0,0 +1,51 @@
1
+ import type { SqliteDatabase } from "@agentsean/db";
2
+ export declare const INCIDENTS_JSON = "https://status.search.google.com/incidents.json";
3
+ export declare const INCIDENTS_ATOM = "https://status.search.google.com/en/feed.atom";
4
+ export declare const PRODUCTS_JSON = "https://status.search.google.com/products.json";
5
+ export declare const SERVICE_RANKING = "rGHU1u87FJnkP6W2GwMi";
6
+ export declare const SERVICE_CRAWLING = "QAVfsAEBQ159b2mEWBYF";
7
+ export declare const SERVICE_INDEXING = "DRyTdKyPd41QXD2hnncp";
8
+ export declare const SERVICE_SERVING = "pKUD9XkLn3TBLquSpQMD";
9
+ export type GoogleIncident = {
10
+ id: string;
11
+ number?: string;
12
+ begin: string;
13
+ end?: string | null;
14
+ created?: string;
15
+ modified?: string;
16
+ external_desc: string;
17
+ status_impact?: string;
18
+ severity?: string;
19
+ service_key: string;
20
+ service_name: string;
21
+ uri?: string;
22
+ };
23
+ export declare function parseIncidentsJson(raw: unknown): GoogleIncident[];
24
+ /** Minimal Atom fallback if incidents.json is down. */
25
+ export declare function parseIncidentsAtom(xml: string): GoogleIncident[];
26
+ export declare function fetchIncidents(fetchFn: typeof fetch): Promise<GoogleIncident[]>;
27
+ type CuratedRow = {
28
+ id: string;
29
+ kind: string;
30
+ begin: string;
31
+ end: string | null;
32
+ title: string;
33
+ metricImpact: string[];
34
+ clicksAffected: boolean;
35
+ impressionsAffected: boolean;
36
+ positionAffected: boolean;
37
+ source: string;
38
+ notes?: string;
39
+ };
40
+ export declare function loadCuratedChangepoints(): CuratedRow[];
41
+ export declare function upsertIncidents(db: SqliteDatabase, incidents: GoogleIncident[]): number;
42
+ export declare function seedCuratedChangepoints(db: SqliteDatabase): number;
43
+ export declare function changepointsOverlapping(db: SqliteDatabase, startDate: string, endDate: string): {
44
+ id: string;
45
+ title: string;
46
+ kind: string;
47
+ begin: string;
48
+ end: string | null;
49
+ }[];
50
+ export {};
51
+ //# sourceMappingURL=incidents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incidents.d.ts","sourceRoot":"","sources":["../src/incidents.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,eAAO,MAAM,cAAc,oDAAoD,CAAC;AAChF,eAAO,MAAM,cAAc,kDAAkD,CAAC;AAC9E,eAAO,MAAM,aAAa,mDAAmD,CAAC;AAE9E,eAAO,MAAM,eAAe,yBAAyB,CAAC;AACtD,eAAO,MAAM,gBAAgB,yBAAyB,CAAC;AACvD,eAAO,MAAM,gBAAgB,yBAAyB,CAAC;AACvD,eAAO,MAAM,eAAe,yBAAyB,CAAC;AAEtD,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,EAAE,CA0BjE;AAED,uDAAuD;AACvD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,EAAE,CAkBhE;AAOD,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,KAAK,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAgBrF;AAED,KAAK,UAAU,GAAG;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAOF,wBAAgB,uBAAuB,IAAI,UAAU,EAAE,CAGtD;AAED,wBAAgB,eAAe,CAC7B,EAAE,EAAE,cAAc,EAClB,SAAS,EAAE,cAAc,EAAE,GAC1B,MAAM,CAoDR;AAED,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CAmBlE;AAgDD,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,cAAc,EAClB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,CAiBlF"}
@@ -0,0 +1,221 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { randomUUID } from "node:crypto";
5
+ import { eq } from "drizzle-orm";
6
+ import { googleChangepoints, googleIncidents } from "@agentsean/db";
7
+ export const INCIDENTS_JSON = "https://status.search.google.com/incidents.json";
8
+ export const INCIDENTS_ATOM = "https://status.search.google.com/en/feed.atom";
9
+ export const PRODUCTS_JSON = "https://status.search.google.com/products.json";
10
+ export const SERVICE_RANKING = "rGHU1u87FJnkP6W2GwMi";
11
+ export const SERVICE_CRAWLING = "QAVfsAEBQ159b2mEWBYF";
12
+ export const SERVICE_INDEXING = "DRyTdKyPd41QXD2hnncp";
13
+ export const SERVICE_SERVING = "pKUD9XkLn3TBLquSpQMD";
14
+ export function parseIncidentsJson(raw) {
15
+ if (!Array.isArray(raw))
16
+ return [];
17
+ const out = [];
18
+ for (const row of raw) {
19
+ if (!row || typeof row !== "object")
20
+ continue;
21
+ const r = row;
22
+ if (typeof r.id !== "string" || typeof r.begin !== "string")
23
+ continue;
24
+ if (typeof r.external_desc !== "string" || typeof r.service_key !== "string")
25
+ continue;
26
+ const incident = {
27
+ id: r.id,
28
+ begin: r.begin,
29
+ end: typeof r.end === "string" ? r.end : null,
30
+ external_desc: r.external_desc,
31
+ service_key: r.service_key,
32
+ service_name: typeof r.service_name === "string" ? r.service_name : "unknown",
33
+ };
34
+ if (typeof r.number === "string")
35
+ incident.number = r.number;
36
+ if (typeof r.created === "string")
37
+ incident.created = r.created;
38
+ if (typeof r.modified === "string")
39
+ incident.modified = r.modified;
40
+ if (typeof r.status_impact === "string")
41
+ incident.status_impact = r.status_impact;
42
+ if (typeof r.severity === "string")
43
+ incident.severity = r.severity;
44
+ if (typeof r.uri === "string")
45
+ incident.uri = r.uri;
46
+ out.push(incident);
47
+ }
48
+ return out;
49
+ }
50
+ /** Minimal Atom fallback if incidents.json is down. */
51
+ export function parseIncidentsAtom(xml) {
52
+ const entries = xml.split(/<entry[\s>]/i).slice(1);
53
+ const out = [];
54
+ for (const e of entries) {
55
+ const title = inner(e, "title") ?? "Google Search incident";
56
+ const updated = inner(e, "updated") ?? inner(e, "published") ?? new Date().toISOString();
57
+ const id = inner(e, "id") ?? title;
58
+ out.push({
59
+ id: id.slice(0, 64),
60
+ begin: updated,
61
+ end: null,
62
+ external_desc: title,
63
+ service_key: SERVICE_RANKING,
64
+ service_name: "Ranking",
65
+ });
66
+ }
67
+ return out;
68
+ }
69
+ function inner(xml, tag) {
70
+ const m = xml.match(new RegExp(`<${tag}[^>]*>([\\s\\S]*?)</${tag}>`, "i"));
71
+ return m?.[1]?.replace(/<!\[CDATA\[|\]\]>/g, "").trim() ?? null;
72
+ }
73
+ export async function fetchIncidents(fetchFn) {
74
+ try {
75
+ const res = await fetchFn(INCIDENTS_JSON, {
76
+ headers: { accept: "application/json" },
77
+ });
78
+ if (res.ok) {
79
+ return parseIncidentsJson(await res.json());
80
+ }
81
+ }
82
+ catch {
83
+ // fall through to Atom
84
+ }
85
+ const atom = await fetchFn(INCIDENTS_ATOM, {
86
+ headers: { accept: "application/atom+xml, application/xml, text/xml" },
87
+ });
88
+ if (!atom.ok)
89
+ return [];
90
+ return parseIncidentsAtom(await atom.text());
91
+ }
92
+ function curatedPath() {
93
+ const here = dirname(fileURLToPath(import.meta.url));
94
+ return join(here, "data", "changepoints.json");
95
+ }
96
+ export function loadCuratedChangepoints() {
97
+ const raw = JSON.parse(readFileSync(curatedPath(), "utf8"));
98
+ return raw;
99
+ }
100
+ export function upsertIncidents(db, incidents) {
101
+ const now = new Date().toISOString();
102
+ let n = 0;
103
+ for (const inc of incidents) {
104
+ const existing = db
105
+ .select()
106
+ .from(googleIncidents)
107
+ .where(eq(googleIncidents.id, inc.id))
108
+ .get();
109
+ const values = {
110
+ id: inc.id,
111
+ number: inc.number ?? null,
112
+ begin: inc.begin,
113
+ end: inc.end ?? null,
114
+ created: inc.created ?? null,
115
+ modified: inc.modified ?? null,
116
+ externalDesc: inc.external_desc,
117
+ statusImpact: inc.status_impact ?? null,
118
+ severity: inc.severity ?? null,
119
+ serviceKey: inc.service_key,
120
+ serviceName: inc.service_name,
121
+ uri: inc.uri ?? null,
122
+ raw: JSON.stringify(inc),
123
+ ingestedAt: now,
124
+ };
125
+ if (existing) {
126
+ db.update(googleIncidents)
127
+ .set(values)
128
+ .where(eq(googleIncidents.id, inc.id))
129
+ .run();
130
+ }
131
+ else {
132
+ db.insert(googleIncidents).values(values).run();
133
+ }
134
+ n += 1;
135
+ if (inc.service_key === SERVICE_RANKING) {
136
+ upsertChangepoint(db, {
137
+ kind: "GOOGLE_RANKING_UPDATE",
138
+ begin: inc.begin.slice(0, 10),
139
+ end: inc.end ? inc.end.slice(0, 10) : null,
140
+ title: inc.external_desc,
141
+ metricImpact: ["clicks", "impressions", "position"],
142
+ clicksAffected: 1,
143
+ impressionsAffected: 1,
144
+ positionAffected: 1,
145
+ source: "incidents",
146
+ incidentId: inc.id,
147
+ notes: null,
148
+ });
149
+ }
150
+ }
151
+ return n;
152
+ }
153
+ export function seedCuratedChangepoints(db) {
154
+ let n = 0;
155
+ for (const row of loadCuratedChangepoints()) {
156
+ upsertChangepoint(db, {
157
+ kind: row.kind,
158
+ begin: row.begin,
159
+ end: row.end,
160
+ title: row.title,
161
+ metricImpact: row.metricImpact,
162
+ clicksAffected: row.clicksAffected ? 1 : 0,
163
+ impressionsAffected: row.impressionsAffected ? 1 : 0,
164
+ positionAffected: row.positionAffected ? 1 : 0,
165
+ source: row.source,
166
+ incidentId: null,
167
+ notes: row.notes ?? null,
168
+ });
169
+ n += 1;
170
+ }
171
+ return n;
172
+ }
173
+ function upsertChangepoint(db, row) {
174
+ const existing = db
175
+ .select()
176
+ .from(googleChangepoints)
177
+ .all()
178
+ .find((r) => r.kind === row.kind && r.begin === row.begin && r.title === row.title);
179
+ const values = {
180
+ kind: row.kind,
181
+ begin: row.begin,
182
+ end: row.end,
183
+ title: row.title,
184
+ metricImpact: JSON.stringify(row.metricImpact),
185
+ clicksAffected: row.clicksAffected,
186
+ impressionsAffected: row.impressionsAffected,
187
+ positionAffected: row.positionAffected,
188
+ source: row.source,
189
+ incidentId: row.incidentId,
190
+ notes: row.notes,
191
+ };
192
+ if (existing) {
193
+ db.update(googleChangepoints)
194
+ .set(values)
195
+ .where(eq(googleChangepoints.id, existing.id))
196
+ .run();
197
+ return;
198
+ }
199
+ db.insert(googleChangepoints)
200
+ .values({ id: randomUUID(), ...values })
201
+ .run();
202
+ }
203
+ export function changepointsOverlapping(db, startDate, endDate) {
204
+ return db
205
+ .select()
206
+ .from(googleChangepoints)
207
+ .all()
208
+ .filter((r) => {
209
+ const b = r.begin;
210
+ const e = r.end ?? r.begin;
211
+ return b <= endDate && e >= startDate;
212
+ })
213
+ .map((r) => ({
214
+ id: r.id,
215
+ title: r.title,
216
+ kind: r.kind,
217
+ begin: r.begin,
218
+ end: r.end,
219
+ }));
220
+ }
221
+ //# sourceMappingURL=incidents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incidents.js","sourceRoot":"","sources":["../src/incidents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export { CONNECT_SCOPES, DEFAULT_BROKER_URL, SCOPE, encodeSiteUrl, normalizeGscSiteUrl, } from "./scopes.js";
2
+ export { generatePkce, randomState, randomWrapKey } from "./pkce.js";
3
+ export { seal, unseal } from "./seal.js";
4
+ export { resolveOAuthConfig, parseDesktopClientJson, loopbackRedirectUri, } from "./oauth-config.js";
5
+ export { createPendingStore, type PendingStore, type PendingOauth } from "./pending.js";
6
+ export { startByoAuthorization, exchangeByoCode, buildGoogleAuthUrl, } from "./oauth-desktop.js";
7
+ export { startBrokerAuthorization, grantFromBrokerHandoff, brokerRefreshAccessToken, } from "./oauth-broker.js";
8
+ export { brokerStartUrl, brokerHandleGoogleCallback, brokerHandleRefresh, loadBrokerSecrets, setBrokerRegisteredCallback, sealWithWrapKey, } from "./broker.js";
9
+ export { loadGrant, saveGrant, loadByoClient, saveByoClient, loadApiKey, saveApiKey, grantFromTokenResponse, testingModeFromTokenResponse, refreshAccessToken, validAccessToken, type StoredGoogleGrant, type ByoClient, } from "./tokens.js";
10
+ export { GscApiError, GscTokenError, GscNotConnectedError, Ga4AdminApiError, Ga4DataApiError, Ga4NotConnectedError, QuotaExceededError, } from "./errors.js";
11
+ export { createQuotaManager, LIMITS, type QuotaManager } from "./quota.js";
12
+ export { createGscClient, defaultGscWindow, monthChunks, GSC_ROW_LIMIT_MAX, } from "./gsc.js";
13
+ export { createGa4Client, googleOrganicFilter } from "./ga4.js";
14
+ export { createSiteVerificationClient, metaVerificationTag, fileVerificationPath, } from "./verification.js";
15
+ export { runPsi } from "./psi.js";
16
+ export { queryCruxWithFallback, queryCruxHistory } from "./crux.js";
17
+ export { fetchIncidents, parseIncidentsJson, parseIncidentsAtom, upsertIncidents, seedCuratedChangepoints, changepointsOverlapping, SERVICE_RANKING, } from "./incidents.js";
18
+ export { decideMetric, preferredMetric, impressionsContaminated, num100Straddle, DEFAULT_METRIC, IMPRESSIONS_BUG_BEGIN, IMPRESSIONS_BUG_END, NUM100_BEGIN, NUM100_END, } from "./integrity.js";
19
+ export { computeResidual, reconcileSite } from "./reconcile.js";
20
+ export { DISCREPANCY_CAUSES, GSC_ANONYMIZED_SHARE, EU_GA4_INVISIBLE_LOW, EU_GA4_INVISIBLE_HIGH, isEuTimeZone, type DiscrepancyCause, type DiscrepancyCauseCode, } from "./causes.js";
21
+ export { buildWaterfall, waterfallFromSite, persistWaterfall, type WaterfallInput, type WaterfallResult, type WaterfallStep, } from "./waterfall.js";
22
+ export { syncGoogle, type SyncResult } from "./sync.js";
23
+ export { loadAuditExtras } from "./audit-extras.js";
24
+ export { startConnect, finishConnect, discoverProperties, bindProperties, } from "./connect-flow.js";
25
+ export { upsertGscConnection, upsertGa4Connection, persistVerification, } from "./persist.js";
26
+ export { defaultSleep, type GoogleHttp } from "./http.js";
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ export { CONNECT_SCOPES, DEFAULT_BROKER_URL, SCOPE, encodeSiteUrl, normalizeGscSiteUrl, } from "./scopes.js";
2
+ export { generatePkce, randomState, randomWrapKey } from "./pkce.js";
3
+ export { seal, unseal } from "./seal.js";
4
+ export { resolveOAuthConfig, parseDesktopClientJson, loopbackRedirectUri, } from "./oauth-config.js";
5
+ export { createPendingStore } from "./pending.js";
6
+ export { startByoAuthorization, exchangeByoCode, buildGoogleAuthUrl, } from "./oauth-desktop.js";
7
+ export { startBrokerAuthorization, grantFromBrokerHandoff, brokerRefreshAccessToken, } from "./oauth-broker.js";
8
+ export { brokerStartUrl, brokerHandleGoogleCallback, brokerHandleRefresh, loadBrokerSecrets, setBrokerRegisteredCallback, sealWithWrapKey, } from "./broker.js";
9
+ export { loadGrant, saveGrant, loadByoClient, saveByoClient, loadApiKey, saveApiKey, grantFromTokenResponse, testingModeFromTokenResponse, refreshAccessToken, validAccessToken, } from "./tokens.js";
10
+ export { GscApiError, GscTokenError, GscNotConnectedError, Ga4AdminApiError, Ga4DataApiError, Ga4NotConnectedError, QuotaExceededError, } from "./errors.js";
11
+ export { createQuotaManager, LIMITS } from "./quota.js";
12
+ export { createGscClient, defaultGscWindow, monthChunks, GSC_ROW_LIMIT_MAX, } from "./gsc.js";
13
+ export { createGa4Client, googleOrganicFilter } from "./ga4.js";
14
+ export { createSiteVerificationClient, metaVerificationTag, fileVerificationPath, } from "./verification.js";
15
+ export { runPsi } from "./psi.js";
16
+ export { queryCruxWithFallback, queryCruxHistory } from "./crux.js";
17
+ export { fetchIncidents, parseIncidentsJson, parseIncidentsAtom, upsertIncidents, seedCuratedChangepoints, changepointsOverlapping, SERVICE_RANKING, } from "./incidents.js";
18
+ export { decideMetric, preferredMetric, impressionsContaminated, num100Straddle, DEFAULT_METRIC, IMPRESSIONS_BUG_BEGIN, IMPRESSIONS_BUG_END, NUM100_BEGIN, NUM100_END, } from "./integrity.js";
19
+ export { computeResidual, reconcileSite } from "./reconcile.js";
20
+ export { DISCREPANCY_CAUSES, GSC_ANONYMIZED_SHARE, EU_GA4_INVISIBLE_LOW, EU_GA4_INVISIBLE_HIGH, isEuTimeZone, } from "./causes.js";
21
+ export { buildWaterfall, waterfallFromSite, persistWaterfall, } from "./waterfall.js";
22
+ export { syncGoogle } from "./sync.js";
23
+ export { loadAuditExtras } from "./audit-extras.js";
24
+ export { startConnect, finishConnect, discoverProperties, bindProperties, } from "./connect-flow.js";
25
+ export { upsertGscConnection, upsertGa4Connection, persistVerification, } from "./persist.js";
26
+ export { defaultSleep } from "./http.js";
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAwC,MAAM,cAAc,CAAC;AACxF,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,mBAAmB,EACnB,iBAAiB,EACjB,2BAA2B,EAC3B,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,SAAS,EACT,SAAS,EACT,aAAa,EACb,aAAa,EACb,UAAU,EACV,UAAU,EACV,sBAAsB,EACtB,4BAA4B,EAC5B,kBAAkB,EAClB,gBAAgB,GAGjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAqB,MAAM,YAAY,CAAC;AAC3E,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,uBAAuB,EACvB,uBAAuB,EACvB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,eAAe,EACf,uBAAuB,EACvB,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,EACZ,UAAU,GACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,GAGb,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GAIjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAmB,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,YAAY,EAAmB,MAAM,WAAW,CAAC"}
@@ -0,0 +1,32 @@
1
+ /** Data-integrity landmines that must be encoded now (PLAN.md Phase 2). */
2
+ export declare const IMPRESSIONS_BUG_BEGIN = "2025-05-13";
3
+ export declare const IMPRESSIONS_BUG_END = "2026-04-27";
4
+ export declare const NUM100_BEGIN = "2025-09-10";
5
+ export declare const NUM100_END = "2025-09-14";
6
+ export declare const NUM100_STRADDLE = "2025-09-12";
7
+ export type GscMetric = "clicks" | "impressions" | "ctr" | "position";
8
+ export declare const DEFAULT_METRIC: GscMetric;
9
+ export declare function rangesOverlap(aStart: string, aEnd: string, bStart: string, bEnd: string): boolean;
10
+ export declare function impressionsContaminated(startDate: string, endDate: string): boolean;
11
+ export declare function num100Straddle(startDate: string, endDate: string): boolean;
12
+ export type MetricDecision = {
13
+ metric: GscMetric;
14
+ allowed: boolean;
15
+ reasons: string[];
16
+ };
17
+ /**
18
+ * Default every metric to clicks. Impressions/CTR/position are blocked across
19
+ * the logging-error window and across the &num=100 removal.
20
+ */
21
+ export declare function decideMetric(requested: GscMetric, startDate: string, endDate: string): MetricDecision;
22
+ export declare function preferredMetric(requested: GscMetric | undefined, startDate: string, endDate: string): MetricDecision;
23
+ export declare function annotateSeries<T extends {
24
+ date: string;
25
+ }>(rows: T[], overlapping: {
26
+ begin: string;
27
+ end: string | null;
28
+ title: string;
29
+ }[]): (T & {
30
+ annotations: string[];
31
+ })[];
32
+ //# sourceMappingURL=integrity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrity.d.ts","sourceRoot":"","sources":["../src/integrity.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAE3E,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAClD,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAChD,eAAO,MAAM,YAAY,eAAe,CAAC;AACzC,eAAO,MAAM,UAAU,eAAe,CAAC;AACvC,eAAO,MAAM,eAAe,eAAe,CAAC;AAE5C,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,KAAK,GAAG,UAAU,CAAC;AAEtE,eAAO,MAAM,cAAc,EAAE,SAAoB,CAAC;AAElD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAET;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAEnF;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,cAAc,CAsBhB;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,cAAc,CAEhB;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EACvD,IAAI,EAAE,CAAC,EAAE,EACT,WAAW,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GAClE,CAAC,CAAC,GAAG;IAAE,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,EAAE,CAUnC"}
@@ -0,0 +1,52 @@
1
+ /** Data-integrity landmines that must be encoded now (PLAN.md Phase 2). */
2
+ export const IMPRESSIONS_BUG_BEGIN = "2025-05-13";
3
+ export const IMPRESSIONS_BUG_END = "2026-04-27";
4
+ export const NUM100_BEGIN = "2025-09-10";
5
+ export const NUM100_END = "2025-09-14";
6
+ export const NUM100_STRADDLE = "2025-09-12";
7
+ export const DEFAULT_METRIC = "clicks";
8
+ export function rangesOverlap(aStart, aEnd, bStart, bEnd) {
9
+ return aStart <= bEnd && bStart <= aEnd;
10
+ }
11
+ export function impressionsContaminated(startDate, endDate) {
12
+ return rangesOverlap(startDate, endDate, IMPRESSIONS_BUG_BEGIN, IMPRESSIONS_BUG_END);
13
+ }
14
+ export function num100Straddle(startDate, endDate) {
15
+ return startDate <= NUM100_STRADDLE && endDate >= NUM100_STRADDLE;
16
+ }
17
+ /**
18
+ * Default every metric to clicks. Impressions/CTR/position are blocked across
19
+ * the logging-error window and across the &num=100 removal.
20
+ */
21
+ export function decideMetric(requested, startDate, endDate) {
22
+ const reasons = [];
23
+ if (requested === "clicks") {
24
+ return { metric: "clicks", allowed: true, reasons };
25
+ }
26
+ if (impressionsContaminated(startDate, endDate)) {
27
+ reasons.push(`Impressions logging error ${IMPRESSIONS_BUG_BEGIN} → ${IMPRESSIONS_BUG_END} overlaps this window. Clicks are unaffected; impressions, CTR and average position are not.`);
28
+ }
29
+ if ((requested === "impressions" || requested === "position") &&
30
+ num100Straddle(startDate, endDate)) {
31
+ reasons.push(`&num=100 removal ${NUM100_BEGIN} → ${NUM100_END} straddles this window. Naive year-over-year impression comparison is a false decay alert.`);
32
+ }
33
+ if (reasons.length > 0) {
34
+ return { metric: "clicks", allowed: false, reasons };
35
+ }
36
+ return { metric: requested, allowed: true, reasons };
37
+ }
38
+ export function preferredMetric(requested, startDate, endDate) {
39
+ return decideMetric(requested ?? DEFAULT_METRIC, startDate, endDate);
40
+ }
41
+ export function annotateSeries(rows, overlapping) {
42
+ return rows.map((row) => {
43
+ const annotations = overlapping
44
+ .filter((c) => {
45
+ const e = c.end ?? c.begin;
46
+ return c.begin <= row.date && row.date <= e;
47
+ })
48
+ .map((c) => c.title);
49
+ return { ...row, annotations };
50
+ });
51
+ }
52
+ //# sourceMappingURL=integrity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrity.js","sourceRoot":"","sources":["../src/integrity.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAE3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,YAAY,CAAC;AAClD,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAChD,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAC;AACzC,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC;AACvC,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC;AAI5C,MAAM,CAAC,MAAM,cAAc,GAAc,QAAQ,CAAC;AAElD,MAAM,UAAU,aAAa,CAC3B,MAAc,EACd,IAAY,EACZ,MAAc,EACd,IAAY;IAEZ,OAAO,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,SAAiB,EAAE,OAAe;IACxE,OAAO,aAAa,CAAC,SAAS,EAAE,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,CAAC,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,OAAe;IAC/D,OAAO,SAAS,IAAI,eAAe,IAAI,OAAO,IAAI,eAAe,CAAC;AACpE,CAAC;AAQD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,SAAoB,EACpB,SAAiB,EACjB,OAAe;IAEf,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACtD,CAAC;IACD,IAAI,uBAAuB,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC;QAChD,OAAO,CAAC,IAAI,CACV,6BAA6B,qBAAqB,MAAM,mBAAmB,8FAA8F,CAC1K,CAAC;IACJ,CAAC;IACD,IACE,CAAC,SAAS,KAAK,aAAa,IAAI,SAAS,KAAK,UAAU,CAAC;QACzD,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,EAClC,CAAC;QACD,OAAO,CAAC,IAAI,CACV,oBAAoB,YAAY,MAAM,UAAU,4FAA4F,CAC7I,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACvD,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,SAAgC,EAChC,SAAiB,EACjB,OAAe;IAEf,OAAO,YAAY,CAAC,SAAS,IAAI,cAAc,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,IAAS,EACT,WAAmE;IAEnE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACtB,MAAM,WAAW,GAAG,WAAW;aAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACZ,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC;YAC3B,OAAO,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;QAC9C,CAAC,CAAC;aACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACvB,OAAO,EAAE,GAAG,GAAG,EAAE,WAAW,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { PendingOauth, PendingStore } from "./pending.js";
2
+ import { type StoredGoogleGrant } from "./tokens.js";
3
+ /**
4
+ * Local origin POSTs (or navigates) to the hosted broker. The hosted page never
5
+ * talks to the daemon — Chrome 142+ Local Network Access would prompt and break.
6
+ * Tokens come back on a 302 to http://127.0.0.1:<port>/oauth/callback.
7
+ */
8
+ export declare function startBrokerAuthorization(opts: {
9
+ brokerUrl: string;
10
+ redirectUri: string;
11
+ pending: PendingStore;
12
+ siteId?: string | null | undefined;
13
+ scopes?: readonly string[] | undefined;
14
+ }): {
15
+ authorizationUrl: string;
16
+ state: string;
17
+ wrapKeyB64: string;
18
+ };
19
+ export type BrokerHandoff = {
20
+ access_token: string;
21
+ refresh_token?: string | undefined;
22
+ expires_in?: number | undefined;
23
+ scope?: string | undefined;
24
+ token_type?: string | undefined;
25
+ refresh_token_expires_in?: number | undefined;
26
+ email?: string | undefined;
27
+ sub?: string | undefined;
28
+ };
29
+ export declare function openBrokerHandoff(pending: PendingOauth, payload: string): BrokerHandoff;
30
+ export declare function grantFromBrokerHandoff(pending: PendingOauth, payload: string, prev: StoredGoogleGrant | null): StoredGoogleGrant;
31
+ export declare function brokerRefreshAccessToken(brokerUrl: string, refreshToken: string, wrapKey: Buffer, fetchFn: typeof fetch): Promise<{
32
+ access_token: string;
33
+ expires_in?: number | undefined;
34
+ refresh_token?: string | undefined;
35
+ refresh_token_expires_in?: number | undefined;
36
+ scope?: string | undefined;
37
+ }>;
38
+ //# sourceMappingURL=oauth-broker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-broker.d.ts","sourceRoot":"","sources":["../src/oauth-broker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAA0B,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG7E;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CACxC,GAAG;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CA2BlE;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,MAAM,GACd,aAAa,CAYf;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,iBAAiB,GAAG,IAAI,GAC7B,iBAAiB,CAOnB;AAED,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,KAAK,GACpB,OAAO,CAAC;IACT,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,wBAAwB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,CAAC,CAkBD"}
@@ -0,0 +1,81 @@
1
+ import { CONNECT_SCOPES } from "./scopes.js";
2
+ import { randomState, randomWrapKey } from "./pkce.js";
3
+ import { unseal } from "./seal.js";
4
+ import { grantFromTokenResponse } from "./tokens.js";
5
+ import { GscTokenError } from "./errors.js";
6
+ /**
7
+ * Local origin POSTs (or navigates) to the hosted broker. The hosted page never
8
+ * talks to the daemon — Chrome 142+ Local Network Access would prompt and break.
9
+ * Tokens come back on a 302 to http://127.0.0.1:<port>/oauth/callback.
10
+ */
11
+ export function startBrokerAuthorization(opts) {
12
+ const state = randomState();
13
+ const wrap = randomWrapKey();
14
+ const wrapKeyB64 = wrap.toString("base64url");
15
+ const row = {
16
+ state,
17
+ verifier: null,
18
+ wrapKeyB64,
19
+ mode: "broker",
20
+ createdAt: Date.now(),
21
+ siteId: opts.siteId ?? null,
22
+ redirectUri: opts.redirectUri,
23
+ clientId: null,
24
+ };
25
+ opts.pending.set(row);
26
+ const params = new URLSearchParams({
27
+ redirect_uri: opts.redirectUri,
28
+ state,
29
+ wrap_key: wrapKeyB64,
30
+ scope: (opts.scopes ?? CONNECT_SCOPES).join(" "),
31
+ });
32
+ const base = opts.brokerUrl.replace(/\/$/, "");
33
+ return {
34
+ state,
35
+ wrapKeyB64,
36
+ authorizationUrl: `${base}/google/start?${params.toString()}`,
37
+ };
38
+ }
39
+ export function openBrokerHandoff(pending, payload) {
40
+ const key = Buffer.from(pending.wrapKeyB64, "base64url");
41
+ let parsed;
42
+ try {
43
+ parsed = JSON.parse(unseal(key, payload));
44
+ }
45
+ catch (err) {
46
+ throw new GscTokenError("Could not unseal broker handoff.", err);
47
+ }
48
+ if (!parsed.access_token) {
49
+ throw new GscTokenError("Broker handoff missing access_token.");
50
+ }
51
+ return parsed;
52
+ }
53
+ export function grantFromBrokerHandoff(pending, payload, prev) {
54
+ const handoff = openBrokerHandoff(pending, payload);
55
+ return grantFromTokenResponse(handoff, prev, {
56
+ mode: "broker",
57
+ email: handoff.email ?? null,
58
+ googleSub: handoff.sub ?? null,
59
+ });
60
+ }
61
+ export async function brokerRefreshAccessToken(brokerUrl, refreshToken, wrapKey, fetchFn) {
62
+ const res = await fetchFn(`${brokerUrl.replace(/\/$/, "")}/google/refresh`, {
63
+ method: "POST",
64
+ headers: { "Content-Type": "application/json" },
65
+ body: JSON.stringify({
66
+ refresh_token: refreshToken,
67
+ wrap_key: wrapKey.toString("base64url"),
68
+ }),
69
+ });
70
+ if (!res.ok) {
71
+ throw new GscTokenError(`Broker refresh failed (${res.status}).`);
72
+ }
73
+ const json = (await res.json());
74
+ if (!json.payload)
75
+ throw new GscTokenError("Broker refresh missing payload.");
76
+ const opened = JSON.parse(unseal(wrapKey, json.payload));
77
+ if (!opened.access_token)
78
+ throw new GscTokenError("Broker refresh missing access_token.");
79
+ return opened;
80
+ }
81
+ //# sourceMappingURL=oauth-broker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-broker.js","sourceRoot":"","sources":["../src/oauth-broker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ByoClient } from "./tokens.js";
2
+ export type GoogleOAuthConfig = {
3
+ mode: "broker" | "byo";
4
+ brokerUrl: string;
5
+ byo: ByoClient | null;
6
+ apiKey: string | null;
7
+ };
8
+ export declare function resolveOAuthConfig(env?: NodeJS.ProcessEnv): {
9
+ byo: ByoClient | null;
10
+ brokerUrl: string;
11
+ apiKey: string | null;
12
+ };
13
+ export declare function parseDesktopClientJson(raw: string): ByoClient;
14
+ /** RFC 8252: IP literal, not localhost. Desktop clients accept any port. */
15
+ export declare function loopbackRedirectUri(port: number): string;
16
+ //# sourceMappingURL=oauth-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-config.d.ts","sourceRoot":"","sources":["../src/oauth-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,QAAQ,GAAG,KAAK,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG;IACxE,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAYA;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAgB7D;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD"}
@@ -0,0 +1,24 @@
1
+ import { DEFAULT_BROKER_URL } from "./scopes.js";
2
+ export function resolveOAuthConfig(env = process.env) {
3
+ const clientId = env["GOOGLE_CLIENT_ID"]?.trim() || env["SEAN_GOOGLE_CLIENT_ID"]?.trim();
4
+ const clientSecret = env["GOOGLE_CLIENT_SECRET"]?.trim() || env["SEAN_GOOGLE_CLIENT_SECRET"]?.trim();
5
+ const byo = clientId && clientSecret ? { clientId, clientSecret } : null;
6
+ const brokerUrl = (env["SEAN_OAUTH_BROKER_URL"]?.trim() || DEFAULT_BROKER_URL).replace(/\/$/, "");
7
+ const apiKey = env["GOOGLE_API_KEY"]?.trim() || env["SEAN_GOOGLE_API_KEY"]?.trim() || null;
8
+ return { byo, brokerUrl, apiKey };
9
+ }
10
+ export function parseDesktopClientJson(raw) {
11
+ const parsed = JSON.parse(raw);
12
+ const installed = parsed.installed ?? parsed.web;
13
+ const clientId = parsed.client_id ?? installed?.client_id;
14
+ const clientSecret = parsed.client_secret ?? installed?.client_secret;
15
+ if (!clientId || !clientSecret) {
16
+ throw new Error("client_secret.json is missing client_id/client_secret. Create a Desktop app OAuth client.");
17
+ }
18
+ return { clientId, clientSecret };
19
+ }
20
+ /** RFC 8252: IP literal, not localhost. Desktop clients accept any port. */
21
+ export function loopbackRedirectUri(port) {
22
+ return `http://127.0.0.1:${port}/oauth/callback`;
23
+ }
24
+ //# sourceMappingURL=oauth-config.js.map