@canonry/canonry 7.93.0 → 7.95.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/agent-workspace/skills/aero/references/ai-traffic-tracking.md +7 -1
- package/assets/agent-workspace/skills/canonry/references/ai-traffic-tracking.md +7 -1
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +6 -4
- package/assets/assets/{AgentSetupPage-D53_2n_4.js → AgentSetupPage-BV0TvyWO.js} +4 -4
- package/assets/assets/{AuditHistoryPanel-BFRuRv_c.js → AuditHistoryPanel-CTVhEVjr.js} +1 -1
- package/assets/assets/{BacklinksPage-DpSbhjVf.js → BacklinksPage-CE1Bfpf6.js} +1 -1
- package/assets/assets/{HistoryPage-1z0GDe6W.js → HistoryPage-BhqA-Udl.js} +1 -1
- package/assets/assets/MeasurementPropertyPage-BiJ06H7w.js +4 -0
- package/assets/assets/ProjectPage-BqS0rfDT.js +11 -0
- package/assets/assets/{RunsPage-DpsqauyB.js → RunsPage-BII3_JsE.js} +1 -1
- package/assets/assets/{SettingsPage-ChIbt7x6.js → SettingsPage-DS4ivpsX.js} +1 -1
- package/assets/assets/SiteHealthSection-IywsGGIA.js +2 -0
- package/assets/assets/ToneBadge-CTZ_JZLD.js +60 -0
- package/assets/assets/{TrafficPage-yoq0n5vi.js → TrafficPage-Bg9JrnxC.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-eCf7k39J.js → TrafficSourceDetailPage-BuD8BlaT.js} +1 -1
- package/assets/assets/{account-context-vYgW6LGe.js → account-context-ylqeghOr.js} +1 -1
- package/assets/assets/{agent-trust-copy-CJ7pZlY5.js → agent-trust-copy-DxpavxIA.js} +1 -1
- package/assets/assets/{card-CArOADSj.js → card-rZ7BA4sl.js} +1 -1
- package/assets/assets/{format-helpers-kCHfk00b.js → format-helpers-PdOXn5Yf.js} +1 -1
- package/assets/assets/index-CU7tAhKY.js +60 -0
- package/assets/assets/{query-client-DWFpwopf.js → query-client-Cq4kP41m.js} +1 -1
- package/assets/assets/react-query-DVctucqC.js +1 -0
- package/assets/assets/{react-sigma_core.esm.min-CaW_CBlP.js → react-sigma_core.esm.min-DYhAEr2t.js} +1 -1
- package/assets/assets/{server-traffic-B1Fb2oFZ.js → server-traffic-Owp6jMwT.js} +1 -1
- package/assets/assets/{service-Cu6wI40I.js → service-y3nQY3Ue.js} +1 -1
- package/assets/index.html +7 -7
- package/dist/{ads-X3VXFPB7.js → ads-GN7QSEUV.js} +3 -3
- package/dist/{agent-VVPPGM2P.js → agent-J46OIQHH.js} +7 -7
- package/dist/{agent-ask-FJVCKO3R.js → agent-ask-755DZ4YB.js} +3 -3
- package/dist/{agent-conversations-5YXYDZEK.js → agent-conversations-QO7C6F6L.js} +3 -3
- package/dist/{agent-journeys-DBMYKLJX.js → agent-journeys-SVI6LWKM.js} +3 -3
- package/dist/{agent-memory-7HOF4LNF.js → agent-memory-V3ZJZT5W.js} +3 -3
- package/dist/{agent-providers-AO25NSCX.js → agent-providers-QIHZ222U.js} +3 -3
- package/dist/{agent-transcript-IRZ2QDU7.js → agent-transcript-6TS3ZOCA.js} +3 -3
- package/dist/{analytics-RH5NXDQX.js → analytics-LFT5OAOR.js} +3 -3
- package/dist/{apply-XNTW4GYA.js → apply-3XXMVLBK.js} +3 -3
- package/dist/{backfill-O6BON2NA.js → backfill-F62Y47XV.js} +10 -10
- package/dist/{backlinks-VHK5TJU4.js → backlinks-AOA5KHHB.js} +3 -3
- package/dist/{bing-A4SQ5MIN.js → bing-75F4W4E2.js} +3 -3
- package/dist/{bootstrap-I2NLTHBM.js → bootstrap-CDGVAICZ.js} +10 -10
- package/dist/{cdp-LAD7DM6U.js → cdp-YBCWRWY4.js} +7 -7
- package/dist/{chunk-U3KBGIJ6.js → chunk-46YXUJSW.js} +2 -2
- package/dist/{chunk-5LLEZ6YL.js → chunk-5TPLZD4I.js} +1 -1
- package/dist/{chunk-4CPCYR5M.js → chunk-6RDBULDN.js} +1 -1
- package/dist/{chunk-ON4G7RCY.js → chunk-6S6XEEGX.js} +35 -22
- package/dist/{chunk-4UA2Y24K.js → chunk-73AUPWSG.js} +6 -6
- package/dist/{chunk-LWVLQCQH.js → chunk-7PUUMJXY.js} +2973 -2639
- package/dist/{chunk-QXT6QVBE.js → chunk-A6O6X6FU.js} +1 -1
- package/dist/{chunk-7RWVMCMK.js → chunk-BUZBBVDZ.js} +1 -1
- package/dist/{chunk-SOJIEKH6.js → chunk-C6UU2PDJ.js} +21 -21
- package/dist/{chunk-GO5OUMY5.js → chunk-CVCUADCM.js} +669 -635
- package/dist/{chunk-J6QOUWDQ.js → chunk-EWSVH5TU.js} +1 -1
- package/dist/{chunk-VYZIXIDN.js → chunk-FESPLVBO.js} +6 -6
- package/dist/{chunk-CWEEHODU.js → chunk-FWY5HUSB.js} +2 -2
- package/dist/{chunk-SNQVHD2O.js → chunk-GUVN5OSX.js} +3 -3
- package/dist/{chunk-YUHP5IUB.js → chunk-IATTIKXF.js} +3 -3
- package/dist/{chunk-HE4ZCVSF.js → chunk-J3NS6NGM.js} +146 -3
- package/dist/{chunk-CM3BXAMM.js → chunk-JVOOKVCW.js} +2 -2
- package/dist/{chunk-3SVI6OY3.js → chunk-KK7NWOGH.js} +7 -7
- package/dist/{chunk-67WZEUEE.js → chunk-KMT7I5KZ.js} +5 -5
- package/dist/{chunk-N6CIAFEO.js → chunk-L7W72K4X.js} +367 -367
- package/dist/{chunk-OLEMJTEJ.js → chunk-LHU3KIKG.js} +2 -2
- package/dist/{chunk-GS3KXIFK.js → chunk-MKLAX5KY.js} +2 -1
- package/dist/{chunk-VNPYFXO5.js → chunk-NJG6WFRK.js} +1 -1
- package/dist/{chunk-7BEQY4YS.js → chunk-NMUL63XG.js} +2 -2
- package/dist/{chunk-QBMMHMDZ.js → chunk-NVWTGVZ4.js} +3 -3
- package/dist/{chunk-WCUXKDJZ.js → chunk-PHOMW3R4.js} +4 -4
- package/dist/{chunk-5X6CWQ6P.js → chunk-Q6WHXY7D.js} +1 -1
- package/dist/{chunk-VFYZVQVX.js → chunk-RPPB4H4D.js} +1 -1
- package/dist/{chunk-BOUEM6D6.js → chunk-T3FYWUQL.js} +2 -2
- package/dist/{chunk-IFVVXGLK.js → chunk-TG5D4E2Y.js} +1 -1
- package/dist/{chunk-2ORBI7PS.js → chunk-TS5Q63NE.js} +3 -3
- package/dist/{chunk-U3DFWCTU.js → chunk-TXW2FPNJ.js} +4 -4
- package/dist/{chunk-UPUJSQ2U.js → chunk-VOP74COR.js} +2 -2
- package/dist/{chunk-2OJJPSFS.js → chunk-WK6IPTTM.js} +4 -4
- package/dist/{chunk-AAUJZ43Q.js → chunk-YTRXALSU.js} +1 -1
- package/dist/{citations-D2ZLKEAZ.js → citations-SQYZTJQ6.js} +3 -3
- package/dist/{cli-catalog-ZJX65B35.js → cli-catalog-N3JLEU77.js} +3 -3
- package/dist/{cli-commands-BSX2GGJL.js → cli-commands-QOJJMX2X.js} +7 -7
- package/dist/cli.js +13 -13
- package/dist/{competitor-GMBE6HDJ.js → competitor-C5JAHHR7.js} +3 -3
- package/dist/{content-V7VKNFRA.js → content-RVPODQI6.js} +3 -3
- package/dist/{dashboard-DOIM7F3F.js → dashboard-3NAY2SX6.js} +6 -6
- package/dist/{demo-TKNEM6WC.js → demo-OSYK452E.js} +1 -1
- package/dist/{demo-server-K6LAEKGV.js → demo-server-GO4V5UXK.js} +14 -14
- package/dist/{discover-TALBBFX7.js → discover-U2DNK2TO.js} +3 -3
- package/dist/{discover-eval-2R3F3C7O.js → discover-eval-ESLS56AH.js} +3 -3
- package/dist/{doctor-UW7QBZR3.js → doctor-SBF54WXE.js} +3 -3
- package/dist/{evidence-CMXDXINS.js → evidence-WHDCM7Z5.js} +3 -3
- package/dist/{export-cmd-HO6K6ZDO.js → export-cmd-7CHS6K3S.js} +3 -3
- package/dist/{ga-VSS5Z44P.js → ga-XRASDAVX.js} +4 -4
- package/dist/{gbp-RYMAOVON.js → gbp-FEOFMTBH.js} +3 -3
- package/dist/{google-RZQSM3VZ.js → google-MWJ4HAUB.js} +4 -4
- package/dist/{google-marketing-ULMGHDFF.js → google-marketing-GELTQ32D.js} +1 -1
- package/dist/{health-cmd-5AJLSCWH.js → health-cmd-IO7YMTRQ.js} +3 -3
- package/dist/{history-ZEWDWGKK.js → history-I74D3NTT.js} +3 -3
- package/dist/index.d.ts +261 -64
- package/dist/index.js +25 -25
- package/dist/{init-NAMFIDDT.js → init-ZLJMCJ3Q.js} +12 -12
- package/dist/{insights-F747HGKV.js → insights-EAMVEB5Y.js} +3 -3
- package/dist/intelligence-service-GSQ7YAYU.js +16 -0
- package/dist/{journeys-IN6PKYC6.js → journeys-E373TZZS.js} +3 -3
- package/dist/{keys-JPOCEVCO.js → keys-27JRRWKZ.js} +3 -3
- package/dist/{keyword-P6EYHLKS.js → keyword-45H2TBRG.js} +3 -3
- package/dist/{logs-3WC6OWDD.js → logs-K4K4OJDY.js} +3 -3
- package/dist/{mcp-LU6BKIGI.js → mcp-734WXNIA.js} +4 -4
- package/dist/mcp.js +9 -9
- package/dist/{measurement-plan-G4E42X4M.js → measurement-plan-XZXK3YLO.js} +5 -5
- package/dist/{notify-ADPO6H5M.js → notify-ZGLVTSVC.js} +3 -3
- package/dist/{organic-evidence-6C4ADEAQ.js → organic-evidence-CRTYFYAN.js} +3 -3
- package/dist/{overview-NLKLGTIL.js → overview-5URBJKI4.js} +4 -4
- package/dist/{project-4QVFGUPT.js → project-R5W4Y4L4.js} +3 -3
- package/dist/{query-6JVOPG7E.js → query-LPGNI3ZR.js} +3 -3
- package/dist/{research-NG2HHDTB.js → research-GTVKPIO2.js} +3 -3
- package/dist/{results-export-RUBBBAKB.js → results-export-UNQQHELR.js} +3 -3
- package/dist/{run-4ZM7F4T4.js → run-DLAFXVF4.js} +4 -4
- package/dist/{schedule-NYJD7QNS.js → schedule-7I5VIJFS.js} +3 -3
- package/dist/{search-Z5TMFDQD.js → search-MUS7FSOJ.js} +3 -3
- package/dist/{serve-ZHUBM33Q.js → serve-5TV26VAH.js} +26 -26
- package/dist/{session-VNIHR75J.js → session-FWALDL3F.js} +13 -13
- package/dist/{settings-2YWI2XEK.js → settings-EB433IDI.js} +3 -3
- package/dist/{sitemaps-PPRANFJS.js → sitemaps-5EVGGGQ5.js} +3 -3
- package/dist/{skills-WKAHQ42S.js → skills-2HS4MYNT.js} +2 -2
- package/dist/{snapshot-J2RMG6IC.js → snapshot-4DMW7AK2.js} +3 -3
- package/dist/{src-ZNFSBJSC.js → src-OYMKXD6L.js} +4 -2
- package/dist/{status-S7WMZ437.js → status-2CRLY5B6.js} +4 -4
- package/dist/{technical-aeo-NKCIAWHJ.js → technical-aeo-HIQJCEML.js} +3 -3
- package/dist/{telemetry-DT4BLD5L.js → telemetry-H3SGPKZC.js} +4 -4
- package/dist/{tools-22WRA2TI.js → tools-PHYD6WYF.js} +11 -11
- package/dist/{traffic-HTBFYDKA.js → traffic-47L2EV6Q.js} +8 -5
- package/dist/{trends-SHT3BBXE.js → trends-CCWE7MF6.js} +3 -3
- package/dist/{users-BV6QFK4Q.js → users-BGIGSKB2.js} +3 -3
- package/dist/{visibility-stats-TGCKVC7I.js → visibility-stats-XVF64BMX.js} +3 -3
- package/dist/{wordpress-LYXQ3AWR.js → wordpress-DQ6DAQPS.js} +3 -3
- package/package.json +1 -1
- package/assets/assets/MeasurementPropertyPage-Dzjx179C.js +0 -4
- package/assets/assets/ProjectPage-BgPs3YQG.js +0 -11
- package/assets/assets/SiteHealthSection-B-79VmOp.js +0 -2
- package/assets/assets/ToneBadge-Cx8uzsd6.js +0 -60
- package/assets/assets/index-9HU3ZsRh.js +0 -60
- package/assets/assets/react-query-DdeD3n1W.js +0 -1
- package/dist/intelligence-service-7FVMY2WA.js +0 -16
|
@@ -3704,8 +3704,9 @@ function percentOf(part, whole) {
|
|
|
3704
3704
|
var WINDOW_SETS = {
|
|
3705
3705
|
metrics: ["7d", "30d", "90d", "all"],
|
|
3706
3706
|
gaMeasurementAnalysis: ["30d", "60d", "90d"],
|
|
3707
|
-
gaOverview: ["7d", "30d", "90d"],
|
|
3708
|
-
|
|
3707
|
+
gaOverview: ["7d", "30d", "90d", "180d"],
|
|
3708
|
+
gaTraffic: ["7d", "30d", "90d", "180d", "all"],
|
|
3709
|
+
gaSearchLanding: ["7d", "28d", "90d", "180d"],
|
|
3709
3710
|
googleAdsMetrics: ["7d", "14d", "30d"],
|
|
3710
3711
|
trafficAnalytics: ["7d", "14d", "30d", "90d"],
|
|
3711
3712
|
organicEvidence: ["60d", "90d"]
|
|
@@ -11671,8 +11672,8 @@ function parseBoundaryDate(value, field) {
|
|
|
11671
11672
|
if (Number.isNaN(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== trimmed) throw invalid();
|
|
11672
11673
|
return trimmed;
|
|
11673
11674
|
}
|
|
11674
|
-
function resolveDateRange(input) {
|
|
11675
|
-
const window =
|
|
11675
|
+
function resolveDateRange(input, windows = WINDOW_SETS.metrics) {
|
|
11676
|
+
const window = parseWindowIn(input.window, windows, { fallback: "all" });
|
|
11676
11677
|
const startDate = parseBoundaryDate(input.startDate, "startDate");
|
|
11677
11678
|
const endDate = parseBoundaryDate(input.endDate, "endDate");
|
|
11678
11679
|
if (startDate && endDate && startDate > endDate) {
|
|
@@ -17165,7 +17166,7 @@ var resultsClearResponseSchema = z47.object({
|
|
|
17165
17166
|
});
|
|
17166
17167
|
|
|
17167
17168
|
// ../contracts/src/ga.ts
|
|
17168
|
-
import { z as
|
|
17169
|
+
import { z as z52 } from "zod";
|
|
17169
17170
|
|
|
17170
17171
|
// ../contracts/src/traffic-class.ts
|
|
17171
17172
|
import { z as z48 } from "zod";
|
|
@@ -17370,29 +17371,131 @@ function buildStackedDailySeries(points, options) {
|
|
|
17370
17371
|
return { series, otherCount: folded.length, days };
|
|
17371
17372
|
}
|
|
17372
17373
|
|
|
17374
|
+
// ../contracts/src/statistics.ts
|
|
17375
|
+
import { z as z51 } from "zod";
|
|
17376
|
+
function round(value, dp = 4) {
|
|
17377
|
+
const f = 10 ** dp;
|
|
17378
|
+
return (Math.round(value * f) + 0) / f;
|
|
17379
|
+
}
|
|
17380
|
+
function roundSignificant(value, sig = 6) {
|
|
17381
|
+
if (!Number.isFinite(value) || value === 0) return 0;
|
|
17382
|
+
const magnitude = Math.ceil(Math.log10(Math.abs(value)));
|
|
17383
|
+
const factor = 10 ** (sig - magnitude);
|
|
17384
|
+
return (Math.round(value * factor) + 0) / factor;
|
|
17385
|
+
}
|
|
17386
|
+
function shareOf(part, total) {
|
|
17387
|
+
if (!Number.isFinite(part) || !Number.isFinite(total)) return null;
|
|
17388
|
+
if (part <= 0) return 0;
|
|
17389
|
+
return total > 0 ? part / total : null;
|
|
17390
|
+
}
|
|
17391
|
+
function breakdownShares(parts) {
|
|
17392
|
+
const total = parts.reduce((sum, part) => sum + Math.max(0, part), 0);
|
|
17393
|
+
return parts.map((part) => shareOf(part, total) ?? 0);
|
|
17394
|
+
}
|
|
17395
|
+
function median(values) {
|
|
17396
|
+
const sorted = values.filter((value) => Number.isFinite(value)).sort((left, right) => left - right);
|
|
17397
|
+
if (sorted.length === 0) return null;
|
|
17398
|
+
const middle = Math.floor(sorted.length / 2);
|
|
17399
|
+
return sorted.length % 2 === 1 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;
|
|
17400
|
+
}
|
|
17401
|
+
function wilsonInterval(successes, n, z97 = 1.96) {
|
|
17402
|
+
if (!Number.isFinite(n) || n <= 0) return null;
|
|
17403
|
+
const s = Math.max(0, Math.min(successes, n));
|
|
17404
|
+
const p = s / n;
|
|
17405
|
+
const z210 = z97 * z97;
|
|
17406
|
+
const denom = 1 + z210 / n;
|
|
17407
|
+
const center = (p + z210 / (2 * n)) / denom;
|
|
17408
|
+
const margin = z97 / denom * Math.sqrt(p * (1 - p) / n + z210 / (4 * n * n));
|
|
17409
|
+
return {
|
|
17410
|
+
low: round(Math.max(0, center - margin)),
|
|
17411
|
+
high: round(Math.min(1, center + margin))
|
|
17412
|
+
};
|
|
17413
|
+
}
|
|
17414
|
+
var linearTrendSchema = z51.object({
|
|
17415
|
+
/** Change in the fitted value per one-index step. */
|
|
17416
|
+
slope: z51.number(),
|
|
17417
|
+
/** Fitted value at index 0. */
|
|
17418
|
+
intercept: z51.number(),
|
|
17419
|
+
/** Coefficient of determination in [0, 1]. `1` for a series with no variance. */
|
|
17420
|
+
r2: z51.number(),
|
|
17421
|
+
/** Fitted value at the first index. */
|
|
17422
|
+
start: z51.number(),
|
|
17423
|
+
/** Fitted value at the last index. */
|
|
17424
|
+
end: z51.number(),
|
|
17425
|
+
/** Count of finite observations the fit used (not the series length). */
|
|
17426
|
+
n: z51.number(),
|
|
17427
|
+
/**
|
|
17428
|
+
* Index of the first observation the fit used, and of the last.
|
|
17429
|
+
*
|
|
17430
|
+
* `start` / `end` are evaluated AT these indices, not at the series' own ends.
|
|
17431
|
+
* A caller drawing the line must span exactly this range: extending it across
|
|
17432
|
+
* leading or trailing indices the metric has no data for draws a fitted claim
|
|
17433
|
+
* over dates that were never measured.
|
|
17434
|
+
*/
|
|
17435
|
+
startIndex: z51.number(),
|
|
17436
|
+
endIndex: z51.number()
|
|
17437
|
+
});
|
|
17438
|
+
function linearTrend(values) {
|
|
17439
|
+
const points = [];
|
|
17440
|
+
for (const [index, value] of values.entries()) {
|
|
17441
|
+
if (typeof value === "number" && Number.isFinite(value)) points.push({ x: index, y: value });
|
|
17442
|
+
}
|
|
17443
|
+
const n = points.length;
|
|
17444
|
+
if (n < 2) return null;
|
|
17445
|
+
const meanX = points.reduce((sum, p) => sum + p.x, 0) / n;
|
|
17446
|
+
const meanY = points.reduce((sum, p) => sum + p.y, 0) / n;
|
|
17447
|
+
let sxx = 0;
|
|
17448
|
+
let sxy = 0;
|
|
17449
|
+
for (const p of points) {
|
|
17450
|
+
sxx += (p.x - meanX) ** 2;
|
|
17451
|
+
sxy += (p.x - meanX) * (p.y - meanY);
|
|
17452
|
+
}
|
|
17453
|
+
const slope = sxy / sxx;
|
|
17454
|
+
const intercept = meanY - slope * meanX;
|
|
17455
|
+
let ssRes = 0;
|
|
17456
|
+
let ssTot = 0;
|
|
17457
|
+
for (const p of points) {
|
|
17458
|
+
ssRes += (p.y - (slope * p.x + intercept)) ** 2;
|
|
17459
|
+
ssTot += (p.y - meanY) ** 2;
|
|
17460
|
+
}
|
|
17461
|
+
const r2 = ssTot === 0 ? 1 : Math.min(1, Math.max(0, 1 - ssRes / ssTot));
|
|
17462
|
+
const firstX = points[0].x;
|
|
17463
|
+
const lastX = points[n - 1].x;
|
|
17464
|
+
return {
|
|
17465
|
+
slope: roundSignificant(slope),
|
|
17466
|
+
intercept: roundSignificant(intercept),
|
|
17467
|
+
r2: round(r2),
|
|
17468
|
+
start: roundSignificant(slope * firstX + intercept),
|
|
17469
|
+
end: roundSignificant(slope * lastX + intercept),
|
|
17470
|
+
n,
|
|
17471
|
+
startIndex: firstX,
|
|
17472
|
+
endIndex: lastX
|
|
17473
|
+
};
|
|
17474
|
+
}
|
|
17475
|
+
|
|
17373
17476
|
// ../contracts/src/ga.ts
|
|
17374
|
-
var ga4ConnectionDtoSchema =
|
|
17375
|
-
id:
|
|
17376
|
-
projectId:
|
|
17377
|
-
propertyId:
|
|
17378
|
-
clientEmail:
|
|
17379
|
-
connected:
|
|
17380
|
-
createdAt:
|
|
17381
|
-
updatedAt:
|
|
17382
|
-
});
|
|
17383
|
-
var ga4TrafficSnapshotDtoSchema =
|
|
17384
|
-
date:
|
|
17385
|
-
landingPage:
|
|
17386
|
-
sessions:
|
|
17387
|
-
organicSessions:
|
|
17388
|
-
users:
|
|
17389
|
-
});
|
|
17390
|
-
var ga4SourceDimensionSchema =
|
|
17391
|
-
var ga4AiReferralDtoSchema =
|
|
17392
|
-
source:
|
|
17393
|
-
medium:
|
|
17477
|
+
var ga4ConnectionDtoSchema = z52.object({
|
|
17478
|
+
id: z52.string(),
|
|
17479
|
+
projectId: z52.string(),
|
|
17480
|
+
propertyId: z52.string(),
|
|
17481
|
+
clientEmail: z52.string(),
|
|
17482
|
+
connected: z52.boolean(),
|
|
17483
|
+
createdAt: z52.string(),
|
|
17484
|
+
updatedAt: z52.string()
|
|
17485
|
+
});
|
|
17486
|
+
var ga4TrafficSnapshotDtoSchema = z52.object({
|
|
17487
|
+
date: z52.string(),
|
|
17488
|
+
landingPage: z52.string(),
|
|
17489
|
+
sessions: z52.number(),
|
|
17490
|
+
organicSessions: z52.number(),
|
|
17491
|
+
users: z52.number()
|
|
17492
|
+
});
|
|
17493
|
+
var ga4SourceDimensionSchema = z52.enum(["session", "first_user", "manual_utm"]);
|
|
17494
|
+
var ga4AiReferralDtoSchema = z52.object({
|
|
17495
|
+
source: z52.string(),
|
|
17496
|
+
medium: z52.string(),
|
|
17394
17497
|
trafficClass: aiReferralTrafficClassSchema,
|
|
17395
|
-
sessions:
|
|
17498
|
+
sessions: z52.number(),
|
|
17396
17499
|
/**
|
|
17397
17500
|
* @deprecated Never emitted since 4.135.0. Removed in the next major.
|
|
17398
17501
|
*
|
|
@@ -17407,7 +17510,7 @@ var ga4AiReferralDtoSchema = z51.object({
|
|
|
17407
17510
|
* number. Sessions are unaffected: GA4 attributes exactly one landing page
|
|
17408
17511
|
* per session, so the landing-page rows partition the day and do sum.
|
|
17409
17512
|
*/
|
|
17410
|
-
users:
|
|
17513
|
+
users: z52.number().optional(),
|
|
17411
17514
|
/**
|
|
17412
17515
|
* The winning attribution dimension for this (source, medium) tuple — the
|
|
17413
17516
|
* one with the highest session count. GA4 emits one row per dimension
|
|
@@ -17425,33 +17528,33 @@ var ga4AiReferralDtoSchema = z51.object({
|
|
|
17425
17528
|
*/
|
|
17426
17529
|
share: fraction()
|
|
17427
17530
|
});
|
|
17428
|
-
var ga4AiReferralLandingPageDtoSchema =
|
|
17429
|
-
source:
|
|
17430
|
-
medium:
|
|
17531
|
+
var ga4AiReferralLandingPageDtoSchema = z52.object({
|
|
17532
|
+
source: z52.string(),
|
|
17533
|
+
medium: z52.string(),
|
|
17431
17534
|
trafficClass: aiReferralTrafficClassSchema,
|
|
17432
17535
|
/**
|
|
17433
17536
|
* The winning attribution dimension for this (source, medium, landingPage)
|
|
17434
17537
|
* tuple — the one with the highest session count.
|
|
17435
17538
|
*/
|
|
17436
17539
|
sourceDimension: ga4SourceDimensionSchema,
|
|
17437
|
-
landingPage:
|
|
17438
|
-
sessions:
|
|
17540
|
+
landingPage: z52.string(),
|
|
17541
|
+
sessions: z52.number(),
|
|
17439
17542
|
/** @deprecated See `GA4AiReferralDto.users`. Never emitted since 4.135.0. */
|
|
17440
|
-
users:
|
|
17543
|
+
users: z52.number().optional()
|
|
17441
17544
|
});
|
|
17442
|
-
var ga4SocialReferralDtoSchema =
|
|
17443
|
-
source:
|
|
17444
|
-
medium:
|
|
17445
|
-
sessions:
|
|
17545
|
+
var ga4SocialReferralDtoSchema = z52.object({
|
|
17546
|
+
source: z52.string(),
|
|
17547
|
+
medium: z52.string(),
|
|
17548
|
+
sessions: z52.number(),
|
|
17446
17549
|
/**
|
|
17447
17550
|
* @deprecated Never emitted by `/ga/traffic`. ga_social_referrals stores
|
|
17448
17551
|
* users as GA's COUNT DISTINCT at (date, source, medium, channel group), so
|
|
17449
17552
|
* summing it across the window counts a returning visitor once per day.
|
|
17450
17553
|
* Optional so existing consumers keep parsing.
|
|
17451
17554
|
*/
|
|
17452
|
-
users:
|
|
17555
|
+
users: z52.number().optional(),
|
|
17453
17556
|
/** GA4 default channel group (e.g. 'Organic Social', 'Paid Social') */
|
|
17454
|
-
channelGroup:
|
|
17557
|
+
channelGroup: z52.string(),
|
|
17455
17558
|
/**
|
|
17456
17559
|
* This row's sessions as a 0..1 share of the window's social sessions
|
|
17457
17560
|
* (`socialSessions`, which is the sum of these rows), so the rows' shares add
|
|
@@ -17459,51 +17562,51 @@ var ga4SocialReferralDtoSchema = z51.object({
|
|
|
17459
17562
|
*/
|
|
17460
17563
|
share: fraction()
|
|
17461
17564
|
});
|
|
17462
|
-
var ga4SocialPlatformDtoSchema =
|
|
17565
|
+
var ga4SocialPlatformDtoSchema = z52.object({
|
|
17463
17566
|
/** Platform id from `socialPlatformForReferralSource`; null for a source no platform matches. */
|
|
17464
17567
|
platform: socialPlatformSchema.nullable(),
|
|
17465
17568
|
/** The platform's name, or the raw source when `platform` is null. */
|
|
17466
|
-
label:
|
|
17467
|
-
sessions:
|
|
17569
|
+
label: z52.string(),
|
|
17570
|
+
sessions: z52.number(),
|
|
17468
17571
|
/** Sessions outside GA4's Paid Social channel group. */
|
|
17469
|
-
organicSessions:
|
|
17572
|
+
organicSessions: z52.number(),
|
|
17470
17573
|
/** Sessions in GA4's Paid Social channel group. */
|
|
17471
|
-
paidSessions:
|
|
17574
|
+
paidSessions: z52.number(),
|
|
17472
17575
|
/** 0..1 share of `socialSessions`; the groups' shares add up to 1. */
|
|
17473
17576
|
share: fraction(),
|
|
17474
17577
|
/** The grouped `socialReferrals` rows, sessions descending. */
|
|
17475
|
-
sources:
|
|
17578
|
+
sources: z52.array(ga4SocialReferralDtoSchema)
|
|
17476
17579
|
});
|
|
17477
|
-
var ga4AiEngineReferralDtoSchema =
|
|
17580
|
+
var ga4AiEngineReferralDtoSchema = z52.object({
|
|
17478
17581
|
/** Engine id from `aiEngineForReferralSource`; null for the unattributed group. */
|
|
17479
17582
|
engine: aiReferralEngineSchema.nullable(),
|
|
17480
17583
|
/** The engine's name, or `Unattributed AI`. */
|
|
17481
|
-
label:
|
|
17482
|
-
sessions:
|
|
17483
|
-
organicSessions:
|
|
17484
|
-
paidSessions:
|
|
17584
|
+
label: z52.string(),
|
|
17585
|
+
sessions: z52.number(),
|
|
17586
|
+
organicSessions: z52.number(),
|
|
17587
|
+
paidSessions: z52.number(),
|
|
17485
17588
|
/** 0..1 share of the `aiReferrals` rows' sessions, the same base as each row's `share`. */
|
|
17486
17589
|
share: fraction(),
|
|
17487
17590
|
/** The grouped `aiReferrals` rows, sessions descending. */
|
|
17488
|
-
sources:
|
|
17591
|
+
sources: z52.array(ga4AiReferralDtoSchema)
|
|
17489
17592
|
});
|
|
17490
|
-
var ga4ChannelBucketDtoSchema =
|
|
17491
|
-
sessions:
|
|
17593
|
+
var ga4ChannelBucketDtoSchema = z52.object({
|
|
17594
|
+
sessions: z52.number(),
|
|
17492
17595
|
sharePct: percent(),
|
|
17493
|
-
sharePctDisplay:
|
|
17596
|
+
sharePctDisplay: z52.string()
|
|
17494
17597
|
});
|
|
17495
|
-
var ga4ChannelBreakdownDtoSchema =
|
|
17598
|
+
var ga4ChannelBreakdownDtoSchema = z52.object({
|
|
17496
17599
|
organic: ga4ChannelBucketDtoSchema,
|
|
17497
17600
|
social: ga4ChannelBucketDtoSchema,
|
|
17498
17601
|
direct: ga4ChannelBucketDtoSchema,
|
|
17499
17602
|
ai: ga4ChannelBucketDtoSchema,
|
|
17500
17603
|
other: ga4ChannelBucketDtoSchema
|
|
17501
17604
|
});
|
|
17502
|
-
var ga4TrafficSummaryDtoSchema =
|
|
17503
|
-
totalSessions:
|
|
17504
|
-
totalOrganicSessions:
|
|
17605
|
+
var ga4TrafficSummaryDtoSchema = z52.object({
|
|
17606
|
+
totalSessions: z52.number(),
|
|
17607
|
+
totalOrganicSessions: z52.number(),
|
|
17505
17608
|
/** Direct-channel sessions (sessions with no source — bookmarks, typed URLs, AI-driven traffic with stripped referrer). 0 for legacy rows from before the column was added. */
|
|
17506
|
-
totalDirectSessions:
|
|
17609
|
+
totalDirectSessions: z52.number(),
|
|
17507
17610
|
/**
|
|
17508
17611
|
* Null when the range has no un-dimensioned aggregate behind it.
|
|
17509
17612
|
*
|
|
@@ -17512,14 +17615,14 @@ var ga4TrafficSummaryDtoSchema = z51.object({
|
|
|
17512
17615
|
* windows have a precomputed deduplicated row; an explicit calendar range does
|
|
17513
17616
|
* not, and reports the figure as unavailable rather than as an inflated sum.
|
|
17514
17617
|
*/
|
|
17515
|
-
totalUsers:
|
|
17516
|
-
topPages:
|
|
17517
|
-
landingPage:
|
|
17518
|
-
sessions:
|
|
17519
|
-
organicSessions:
|
|
17618
|
+
totalUsers: z52.number().nullable(),
|
|
17619
|
+
topPages: z52.array(z52.object({
|
|
17620
|
+
landingPage: z52.string(),
|
|
17621
|
+
sessions: z52.number(),
|
|
17622
|
+
organicSessions: z52.number(),
|
|
17520
17623
|
/** Per-page Direct-channel sessions. 0 for legacy rows. */
|
|
17521
|
-
directSessions:
|
|
17522
|
-
users:
|
|
17624
|
+
directSessions: z52.number(),
|
|
17625
|
+
users: z52.number(),
|
|
17523
17626
|
/**
|
|
17524
17627
|
* Organic search sessions as a 0..1 share of this page's sessions. 0 when
|
|
17525
17628
|
* the page has no organic sessions; null when organic sessions exist with
|
|
@@ -17527,49 +17630,49 @@ var ga4TrafficSummaryDtoSchema = z51.object({
|
|
|
17527
17630
|
*/
|
|
17528
17631
|
organicShare: fraction().nullable()
|
|
17529
17632
|
})),
|
|
17530
|
-
aiReferrals:
|
|
17531
|
-
aiReferralLandingPages:
|
|
17633
|
+
aiReferrals: z52.array(ga4AiReferralDtoSchema),
|
|
17634
|
+
aiReferralLandingPages: z52.array(ga4AiReferralLandingPageDtoSchema),
|
|
17532
17635
|
/** Deduped AI session total: MAX(sessions) per date+source across attribution dimensions, then summed. Cross-cutting: can overlap with Direct/Organic/Social via firstUserSource. */
|
|
17533
|
-
aiSessionsDeduped:
|
|
17636
|
+
aiSessionsDeduped: z52.number(),
|
|
17534
17637
|
/** @deprecated See `GA4AiReferralDto.users`. Never emitted since 4.135.0. */
|
|
17535
|
-
aiUsersDeduped:
|
|
17638
|
+
aiUsersDeduped: z52.number().optional(),
|
|
17536
17639
|
/** Deduped AI sessions whose attribution carries paid intent. */
|
|
17537
|
-
paidAiSessionsDeduped:
|
|
17640
|
+
paidAiSessionsDeduped: z52.number(),
|
|
17538
17641
|
/** @deprecated See `GA4AiReferralDto.users`. Never emitted since 4.135.0. */
|
|
17539
|
-
paidAiUsersDeduped:
|
|
17642
|
+
paidAiUsersDeduped: z52.number().optional(),
|
|
17540
17643
|
/** Deduped AI sessions without paid intent evidence. */
|
|
17541
|
-
organicAiSessionsDeduped:
|
|
17644
|
+
organicAiSessionsDeduped: z52.number(),
|
|
17542
17645
|
/** @deprecated See `GA4AiReferralDto.users`. Never emitted since 4.135.0. */
|
|
17543
|
-
organicAiUsersDeduped:
|
|
17646
|
+
organicAiUsersDeduped: z52.number().optional(),
|
|
17544
17647
|
/** AI sessions whose CURRENT sessionSource matched an AI engine. Can overlap with raw Organic/Social/Direct totals; `channelBreakdown` removes those overlaps for display. */
|
|
17545
|
-
aiSessionsBySession:
|
|
17648
|
+
aiSessionsBySession: z52.number(),
|
|
17546
17649
|
/** @deprecated See `GA4AiReferralDto.users`. Never emitted since 4.135.0. */
|
|
17547
|
-
aiUsersBySession:
|
|
17650
|
+
aiUsersBySession: z52.number().optional(),
|
|
17548
17651
|
/** Session-source-only paid AI sessions. */
|
|
17549
|
-
paidAiSessionsBySession:
|
|
17652
|
+
paidAiSessionsBySession: z52.number(),
|
|
17550
17653
|
/** @deprecated See `GA4AiReferralDto.users`. Never emitted since 4.135.0. */
|
|
17551
|
-
paidAiUsersBySession:
|
|
17654
|
+
paidAiUsersBySession: z52.number().optional(),
|
|
17552
17655
|
/** Session-source-only organic/non-paid AI sessions. */
|
|
17553
|
-
organicAiSessionsBySession:
|
|
17656
|
+
organicAiSessionsBySession: z52.number(),
|
|
17554
17657
|
/** @deprecated See `GA4AiReferralDto.users`. Never emitted since 4.135.0. */
|
|
17555
|
-
organicAiUsersBySession:
|
|
17658
|
+
organicAiUsersBySession: z52.number().optional(),
|
|
17556
17659
|
/**
|
|
17557
17660
|
* `aiReferrals` grouped by engine, sessions descending, with the unattributed
|
|
17558
17661
|
* group last. The groups' sessions add up to the rows' sessions.
|
|
17559
17662
|
*/
|
|
17560
|
-
aiEngines:
|
|
17561
|
-
socialReferrals:
|
|
17663
|
+
aiEngines: z52.array(ga4AiEngineReferralDtoSchema),
|
|
17664
|
+
socialReferrals: z52.array(ga4SocialReferralDtoSchema),
|
|
17562
17665
|
/** `socialReferrals` grouped by platform, sessions descending; the groups' sessions add up to `socialSessions`. */
|
|
17563
|
-
socialPlatforms:
|
|
17666
|
+
socialPlatforms: z52.array(ga4SocialPlatformDtoSchema),
|
|
17564
17667
|
/**
|
|
17565
17668
|
* Daily social sessions by platform over the same window as every other
|
|
17566
17669
|
* figure here: the five largest platforms, then the rest as `other`.
|
|
17567
17670
|
*/
|
|
17568
17671
|
socialPlatformDaily: stackedDailySeriesSchema,
|
|
17569
17672
|
/** Total social sessions (session-scoped, no cross-dimension dedup needed). */
|
|
17570
|
-
socialSessions:
|
|
17673
|
+
socialSessions: z52.number(),
|
|
17571
17674
|
/** Social sessions in GA4's Paid Social channel group. */
|
|
17572
|
-
paidSocialSessions:
|
|
17675
|
+
paidSocialSessions: z52.number(),
|
|
17573
17676
|
/** `paidSocialSessions` as a 0..1 share of `socialSessions`; 0 with no social sessions. */
|
|
17574
17677
|
paidSocialShare: fraction(),
|
|
17575
17678
|
/** Total social users (session-scoped, no cross-dimension dedup needed). */
|
|
@@ -17578,7 +17681,7 @@ var ga4TrafficSummaryDtoSchema = z51.object({
|
|
|
17578
17681
|
* COUNT DISTINCT at (date, source, medium, channel group), so summing it
|
|
17579
17682
|
* across the window counts a returning visitor once per day.
|
|
17580
17683
|
*/
|
|
17581
|
-
socialUsers:
|
|
17684
|
+
socialUsers: z52.number().optional(),
|
|
17582
17685
|
/** Five disjoint buckets used for the channel breakdown. Known AI session-source matches are removed from their native GA4 bucket before shares are computed. */
|
|
17583
17686
|
channelBreakdown: ga4ChannelBreakdownDtoSchema,
|
|
17584
17687
|
/** Organic sessions as a percentage of total sessions (0–100, at wire precision). */
|
|
@@ -17600,55 +17703,56 @@ var ga4TrafficSummaryDtoSchema = z51.object({
|
|
|
17600
17703
|
/** Social sessions as a percentage of total sessions (0–100, at wire precision). */
|
|
17601
17704
|
socialSharePct: percent(),
|
|
17602
17705
|
/** Display string for organicSharePct: the unrounded share through formatPercent ('12.5%', '<0.1%' for a non-zero share below one decimal), '0%' with no sessions, or '—' when sessions exist but total is unknown (partial sync). */
|
|
17603
|
-
organicSharePctDisplay:
|
|
17706
|
+
organicSharePctDisplay: z52.string(),
|
|
17604
17707
|
/** Display string for aiSharePct: the unrounded share through formatPercent ('12.5%', '<0.1%' for a non-zero share below one decimal), '0%' with no sessions, or '—' when sessions exist but total is unknown (partial sync). */
|
|
17605
|
-
aiSharePctDisplay:
|
|
17708
|
+
aiSharePctDisplay: z52.string(),
|
|
17606
17709
|
/** Display string for aiSharePctBySession: the unrounded share through formatPercent ('12.5%', '<0.1%' for a non-zero share below one decimal), '0%' with no sessions, or '—' when sessions exist but total is unknown (partial sync). */
|
|
17607
|
-
aiSharePctBySessionDisplay:
|
|
17710
|
+
aiSharePctBySessionDisplay: z52.string(),
|
|
17608
17711
|
/** Display string for paidAiSharePct. */
|
|
17609
|
-
paidAiSharePctDisplay:
|
|
17712
|
+
paidAiSharePctDisplay: z52.string(),
|
|
17610
17713
|
/** Display string for paidAiSharePctBySession. */
|
|
17611
|
-
paidAiSharePctBySessionDisplay:
|
|
17714
|
+
paidAiSharePctBySessionDisplay: z52.string(),
|
|
17612
17715
|
/** Display string for organicAiSharePct. */
|
|
17613
|
-
organicAiSharePctDisplay:
|
|
17716
|
+
organicAiSharePctDisplay: z52.string(),
|
|
17614
17717
|
/** Display string for organicAiSharePctBySession. */
|
|
17615
|
-
organicAiSharePctBySessionDisplay:
|
|
17718
|
+
organicAiSharePctBySessionDisplay: z52.string(),
|
|
17616
17719
|
/** Display string for directSharePct: the unrounded share through formatPercent ('12.5%', '<0.1%' for a non-zero share below one decimal), '0%' with no sessions, or '—' when sessions exist but total is unknown (partial sync). */
|
|
17617
|
-
directSharePctDisplay:
|
|
17720
|
+
directSharePctDisplay: z52.string(),
|
|
17618
17721
|
/** Display string for socialSharePct: the unrounded share through formatPercent ('12.5%', '<0.1%' for a non-zero share below one decimal), '0%' with no sessions, or '—' when sessions exist but total is unknown (partial sync). */
|
|
17619
|
-
socialSharePctDisplay:
|
|
17722
|
+
socialSharePctDisplay: z52.string(),
|
|
17620
17723
|
/** Sessions not covered by Organic, Social, Direct, or AI (session) channels — e.g. Referral, Email, Paid Search, Display. Always non-negative; clamped to 0 when the four disjoint channels sum above total (rounding edge). */
|
|
17621
|
-
otherSessions:
|
|
17724
|
+
otherSessions: z52.number(),
|
|
17622
17725
|
/** Other sessions as a percentage of total sessions (0–100, at wire precision). */
|
|
17623
17726
|
otherSharePct: percent(),
|
|
17624
17727
|
/** Display string for otherSharePct: the unrounded share through formatPercent ('12.5%', '<0.1%' for a non-zero share below one decimal), '0%' with no sessions, or '—' when sessions exist but total is unknown (partial sync). */
|
|
17625
|
-
otherSharePctDisplay:
|
|
17626
|
-
lastSyncedAt:
|
|
17627
|
-
});
|
|
17628
|
-
var ga4StatusDtoSchema =
|
|
17629
|
-
connected:
|
|
17630
|
-
propertyId:
|
|
17631
|
-
clientEmail:
|
|
17632
|
-
authMethod:
|
|
17633
|
-
lastSyncedAt:
|
|
17634
|
-
createdAt:
|
|
17635
|
-
updatedAt:
|
|
17636
|
-
});
|
|
17637
|
-
var ga4PropertySummaryDtoSchema =
|
|
17638
|
-
propertyId:
|
|
17639
|
-
displayName:
|
|
17728
|
+
otherSharePctDisplay: z52.string(),
|
|
17729
|
+
lastSyncedAt: z52.string().nullable()
|
|
17730
|
+
});
|
|
17731
|
+
var ga4StatusDtoSchema = z52.object({
|
|
17732
|
+
connected: z52.boolean(),
|
|
17733
|
+
propertyId: z52.string().nullable(),
|
|
17734
|
+
clientEmail: z52.string().nullable(),
|
|
17735
|
+
authMethod: z52.enum(["service-account", "oauth"]).nullable(),
|
|
17736
|
+
lastSyncedAt: z52.string().nullable(),
|
|
17737
|
+
createdAt: z52.string().nullable().optional(),
|
|
17738
|
+
updatedAt: z52.string().nullable().optional()
|
|
17739
|
+
});
|
|
17740
|
+
var ga4PropertySummaryDtoSchema = z52.object({
|
|
17741
|
+
propertyId: z52.string(),
|
|
17742
|
+
displayName: z52.string(),
|
|
17640
17743
|
/** GA4 account that owns the property. Two accounts can hold like-named properties. */
|
|
17641
|
-
accountName:
|
|
17744
|
+
accountName: z52.string()
|
|
17642
17745
|
});
|
|
17643
|
-
var ga4PropertiesDtoSchema =
|
|
17644
|
-
properties:
|
|
17746
|
+
var ga4PropertiesDtoSchema = z52.object({
|
|
17747
|
+
properties: z52.array(ga4PropertySummaryDtoSchema)
|
|
17645
17748
|
});
|
|
17646
|
-
var gaSearchLandingWindowSchema =
|
|
17749
|
+
var gaSearchLandingWindowSchema = z52.enum(WINDOW_SETS.gaSearchLanding);
|
|
17647
17750
|
var GA_SEARCH_LANDING_WINDOWS = gaSearchLandingWindowSchema.options;
|
|
17648
17751
|
var GA_SEARCH_LANDING_WINDOW_DAYS = {
|
|
17649
17752
|
"7d": 7,
|
|
17650
17753
|
"28d": 28,
|
|
17651
|
-
"90d": 90
|
|
17754
|
+
"90d": 90,
|
|
17755
|
+
"180d": 180
|
|
17652
17756
|
};
|
|
17653
17757
|
var GA_SEARCH_LANDING_DEFAULT_WINDOW = "28d";
|
|
17654
17758
|
var GA_SEARCH_LANDING_DEFAULT_LIMIT = 50;
|
|
@@ -17657,124 +17761,124 @@ function gaSearchLandingPageLabel(landingPage) {
|
|
|
17657
17761
|
return landingPage === "" ? GA_SEARCH_LANDING_EMPTY_PAGE_LABEL : landingPage;
|
|
17658
17762
|
}
|
|
17659
17763
|
var GA_SEARCH_LANDING_MAX_LIMIT = 1e3;
|
|
17660
|
-
var gaSearchLandingStatusSchema =
|
|
17661
|
-
var gaSearchLandingMetricsSchema =
|
|
17662
|
-
organicGoogleSearchClicks:
|
|
17663
|
-
organicGoogleSearchImpressions:
|
|
17764
|
+
var gaSearchLandingStatusSchema = z52.enum(["never-synced", "ready", "unavailable", "error"]);
|
|
17765
|
+
var gaSearchLandingMetricsSchema = z52.object({
|
|
17766
|
+
organicGoogleSearchClicks: z52.number().int().nonnegative(),
|
|
17767
|
+
organicGoogleSearchImpressions: z52.number().int().nonnegative(),
|
|
17664
17768
|
/** GA4's own click-through rate (0..1). Null when there were no impressions. */
|
|
17665
|
-
organicGoogleSearchClickThroughRate: fraction(
|
|
17769
|
+
organicGoogleSearchClickThroughRate: fraction(z52.number().min(0).max(1)).nullable(),
|
|
17666
17770
|
/** GA4's own average position. Null when there were no impressions. */
|
|
17667
|
-
organicGoogleSearchAveragePosition:
|
|
17771
|
+
organicGoogleSearchAveragePosition: z52.number().nonnegative().nullable(),
|
|
17668
17772
|
/**
|
|
17669
17773
|
* GA4's plain `activeUsers` from the same request, which is what GA4's own
|
|
17670
17774
|
* report shows in this column (verified against the GA4 UI). Not limited to
|
|
17671
17775
|
* Google organic sessions.
|
|
17672
17776
|
*/
|
|
17673
|
-
activeUsers:
|
|
17777
|
+
activeUsers: z52.number().int().nonnegative()
|
|
17674
17778
|
});
|
|
17675
17779
|
var gaSearchLandingPageRowSchema = gaSearchLandingMetricsSchema.extend({
|
|
17676
17780
|
/** GA4's `landingPagePlusQueryString`, exactly as reported (never normalized). */
|
|
17677
|
-
landingPage:
|
|
17781
|
+
landingPage: z52.string()
|
|
17678
17782
|
});
|
|
17679
|
-
var gaSearchConsoleLinkStateSchema =
|
|
17680
|
-
var gaSearchLandingPagesResponseSchema =
|
|
17681
|
-
source:
|
|
17783
|
+
var gaSearchConsoleLinkStateSchema = z52.enum(["has-data", "not-linked", "no-search-data", "unknown"]);
|
|
17784
|
+
var gaSearchLandingPagesResponseSchema = z52.object({
|
|
17785
|
+
source: z52.literal("ga4-search-console-link"),
|
|
17682
17786
|
status: gaSearchLandingStatusSchema,
|
|
17683
17787
|
/** The last failed attempt's message (Google's own text for `unavailable`). */
|
|
17684
|
-
error:
|
|
17788
|
+
error: z52.string().nullable(),
|
|
17685
17789
|
/** When the stored snapshot was written. Null when none exists. */
|
|
17686
|
-
syncedAt:
|
|
17790
|
+
syncedAt: z52.string().datetime().nullable(),
|
|
17687
17791
|
/** When a sync last tried to refresh the snapshot, successful or not. */
|
|
17688
|
-
attemptedAt:
|
|
17792
|
+
attemptedAt: z52.string().datetime().nullable(),
|
|
17689
17793
|
window: gaSearchLandingWindowSchema,
|
|
17690
17794
|
/** Inclusive first day of the stored window, in the property's time zone. */
|
|
17691
|
-
windowStart:
|
|
17795
|
+
windowStart: z52.iso.date().nullable(),
|
|
17692
17796
|
/** Inclusive last day of the stored window (yesterday at sync time). */
|
|
17693
|
-
windowEnd:
|
|
17694
|
-
windowDays:
|
|
17797
|
+
windowEnd: z52.iso.date().nullable(),
|
|
17798
|
+
windowDays: z52.number().int().positive().nullable(),
|
|
17695
17799
|
/** GA4 property reporting time zone the window dates are in. */
|
|
17696
|
-
timeZone:
|
|
17697
|
-
subjectToThresholding:
|
|
17698
|
-
dataLossFromOtherRow:
|
|
17800
|
+
timeZone: z52.string().nullable(),
|
|
17801
|
+
subjectToThresholding: z52.boolean(),
|
|
17802
|
+
dataLossFromOtherRow: z52.boolean(),
|
|
17699
17803
|
/** GA4's own TOTAL row for the window. Never a sum of `rows`. Null when no snapshot exists. */
|
|
17700
17804
|
total: gaSearchLandingMetricsSchema.nullable(),
|
|
17701
17805
|
/** Rows GA4 reported for the window. Can exceed `totalRows` when `rowsCapped`. */
|
|
17702
|
-
reportRowCount:
|
|
17806
|
+
reportRowCount: z52.number().int().nonnegative().nullable(),
|
|
17703
17807
|
/** True when GA4 reported more rows than were stored (the per-window row cap). */
|
|
17704
|
-
rowsCapped:
|
|
17808
|
+
rowsCapped: z52.boolean(),
|
|
17705
17809
|
/** Stored rows for the window, the population `limit` / `offset` page over. */
|
|
17706
|
-
totalRows:
|
|
17707
|
-
limit:
|
|
17708
|
-
offset:
|
|
17810
|
+
totalRows: z52.number().int().nonnegative(),
|
|
17811
|
+
limit: z52.number().int().positive(),
|
|
17812
|
+
offset: z52.number().int().nonnegative(),
|
|
17709
17813
|
/** Ordered by clicks, then impressions (both descending), then landing page. */
|
|
17710
|
-
rows:
|
|
17814
|
+
rows: z52.array(gaSearchLandingPageRowSchema),
|
|
17711
17815
|
/**
|
|
17712
17816
|
* Whether the window's GA4 report has Search Console data, compared with
|
|
17713
17817
|
* Canonry's own Search Console data for the same days. Null when no window
|
|
17714
17818
|
* is stored.
|
|
17715
17819
|
*/
|
|
17716
|
-
searchConsoleLink:
|
|
17820
|
+
searchConsoleLink: z52.object({
|
|
17717
17821
|
state: gaSearchConsoleLinkStateSchema,
|
|
17718
17822
|
/** Search Console impressions Canonry stores for the window's days; null when it has none for them. */
|
|
17719
|
-
searchConsoleImpressions:
|
|
17823
|
+
searchConsoleImpressions: z52.number().int().nonnegative().nullable()
|
|
17720
17824
|
}).nullable()
|
|
17721
17825
|
});
|
|
17722
17826
|
function gaSearchLandingHasSearchData(total) {
|
|
17723
17827
|
return total.organicGoogleSearchClicks > 0 || total.organicGoogleSearchImpressions > 0;
|
|
17724
17828
|
}
|
|
17725
|
-
var gaSearchLandingSyncResultSchema =
|
|
17726
|
-
status:
|
|
17829
|
+
var gaSearchLandingSyncResultSchema = z52.object({
|
|
17830
|
+
status: z52.enum(["ready", "unavailable", "error"]),
|
|
17727
17831
|
/** Windows written by this sync, empty unless `ready`. */
|
|
17728
|
-
windows:
|
|
17832
|
+
windows: z52.array(z52.object({
|
|
17729
17833
|
window: gaSearchLandingWindowSchema,
|
|
17730
|
-
rowCount:
|
|
17731
|
-
reportRowCount:
|
|
17732
|
-
rowsCapped:
|
|
17834
|
+
rowCount: z52.number().int().nonnegative(),
|
|
17835
|
+
reportRowCount: z52.number().int().nonnegative(),
|
|
17836
|
+
rowsCapped: z52.boolean()
|
|
17733
17837
|
})),
|
|
17734
17838
|
/** Landing-page rows written across every window. */
|
|
17735
|
-
rowCount:
|
|
17736
|
-
error:
|
|
17737
|
-
});
|
|
17738
|
-
var gaSyncOnlySchema =
|
|
17739
|
-
var ga4SyncResponseDtoSchema =
|
|
17740
|
-
synced:
|
|
17741
|
-
rowCount:
|
|
17742
|
-
aiReferralCount:
|
|
17743
|
-
socialReferralCount:
|
|
17744
|
-
/**
|
|
17745
|
-
* The
|
|
17746
|
-
* `days` bounded to GA4's supported sync range (1–
|
|
17839
|
+
rowCount: z52.number().int().nonnegative(),
|
|
17840
|
+
error: z52.string().optional()
|
|
17841
|
+
});
|
|
17842
|
+
var gaSyncOnlySchema = z52.enum(["traffic", "ai", "social", "search-landing"]);
|
|
17843
|
+
var ga4SyncResponseDtoSchema = z52.object({
|
|
17844
|
+
synced: z52.boolean(),
|
|
17845
|
+
rowCount: z52.number().int().nonnegative(),
|
|
17846
|
+
aiReferralCount: z52.number().int().nonnegative(),
|
|
17847
|
+
socialReferralCount: z52.number().int().nonnegative(),
|
|
17848
|
+
/**
|
|
17849
|
+
* The requested coverage window, in days — reused mature days plus fetched gaps. The request's
|
|
17850
|
+
* `days` is bounded to GA4's supported sync range (1–180). Read this, not
|
|
17747
17851
|
* `requestedDays`, when reporting or reasoning about coverage: a
|
|
17748
|
-
* `--days 500` sync
|
|
17852
|
+
* `--days 500` sync covers 180 days, and this field says 180.
|
|
17749
17853
|
*/
|
|
17750
|
-
days:
|
|
17854
|
+
days: z52.number().int().nonnegative(),
|
|
17751
17855
|
/** The window the caller asked for, before bounding. Equals `days` unless `clamped`. */
|
|
17752
|
-
requestedDays:
|
|
17856
|
+
requestedDays: z52.number().int().nonnegative(),
|
|
17753
17857
|
/**
|
|
17754
17858
|
* True when `requestedDays` fell outside GA4's supported range and `days`
|
|
17755
17859
|
* differs from it — i.e. the synced history is not the range requested.
|
|
17756
17860
|
*/
|
|
17757
|
-
clamped:
|
|
17758
|
-
syncedAt:
|
|
17759
|
-
measurement:
|
|
17760
|
-
acquisition:
|
|
17761
|
-
leads:
|
|
17762
|
-
days:
|
|
17763
|
-
status:
|
|
17764
|
-
rowCount:
|
|
17765
|
-
attributionScope:
|
|
17766
|
-
error:
|
|
17861
|
+
clamped: z52.boolean(),
|
|
17862
|
+
syncedAt: z52.string(),
|
|
17863
|
+
measurement: z52.object({
|
|
17864
|
+
acquisition: z52.object({ days: z52.number().int().nonnegative(), status: z52.enum(["ready", "error"]), rowCount: z52.number().int().nonnegative(), error: z52.string().optional() }),
|
|
17865
|
+
leads: z52.object({
|
|
17866
|
+
days: z52.number().int().nonnegative(),
|
|
17867
|
+
status: z52.enum(["ready", "error", "not-configured"]),
|
|
17868
|
+
rowCount: z52.number().int().nonnegative(),
|
|
17869
|
+
attributionScope: z52.enum(["landing-page", "channel"]).optional(),
|
|
17870
|
+
error: z52.string().optional(),
|
|
17767
17871
|
/** The GA4 events this sync counted: the configured lead events plus the property's key events. */
|
|
17768
|
-
eventNames:
|
|
17872
|
+
eventNames: z52.array(z52.string()).optional(),
|
|
17769
17873
|
/**
|
|
17770
17874
|
* The property's key-event read. `read` lists them; `error` keeps the
|
|
17771
17875
|
* previous successful list and names the failure; `disabled` means the
|
|
17772
17876
|
* project counts only its configured lead events.
|
|
17773
17877
|
*/
|
|
17774
|
-
keyEvents:
|
|
17775
|
-
status:
|
|
17776
|
-
names:
|
|
17777
|
-
error:
|
|
17878
|
+
keyEvents: z52.object({
|
|
17879
|
+
status: z52.enum(["read", "error", "disabled"]),
|
|
17880
|
+
names: z52.array(z52.string()),
|
|
17881
|
+
error: z52.string().optional()
|
|
17778
17882
|
}).optional()
|
|
17779
17883
|
}),
|
|
17780
17884
|
/**
|
|
@@ -17792,18 +17896,18 @@ var ga4SyncResponseDtoSchema = z51.object({
|
|
|
17792
17896
|
* or `unavailable` attempt is left out and reported in
|
|
17793
17897
|
* `measurement.searchLandingPages`.
|
|
17794
17898
|
*/
|
|
17795
|
-
syncedComponents:
|
|
17899
|
+
syncedComponents: z52.array(z52.string()).optional()
|
|
17796
17900
|
});
|
|
17797
|
-
var gaMoverChangeBasisSchema =
|
|
17901
|
+
var gaMoverChangeBasisSchema = z52.enum(["new", "small-base", "percent"]);
|
|
17798
17902
|
var GaMoverChangeBases = gaMoverChangeBasisSchema.enum;
|
|
17799
|
-
var gaSourceMoverSchema =
|
|
17800
|
-
source:
|
|
17903
|
+
var gaSourceMoverSchema = z52.object({
|
|
17904
|
+
source: z52.string(),
|
|
17801
17905
|
/** Sessions from this source in the last 7 days. */
|
|
17802
|
-
sessions7d:
|
|
17906
|
+
sessions7d: z52.number(),
|
|
17803
17907
|
/** Sessions from this source in the 7 days before that. */
|
|
17804
|
-
sessionsPrev7d:
|
|
17908
|
+
sessionsPrev7d: z52.number(),
|
|
17805
17909
|
/** Signed session change, `sessions7d - sessionsPrev7d`. The mover is the source whose change is largest in size. */
|
|
17806
|
-
changeSessions:
|
|
17910
|
+
changeSessions: z52.number(),
|
|
17807
17911
|
/**
|
|
17808
17912
|
* Signed whole-percent change against the prior 7 days (`150` = +150%, `-100`
|
|
17809
17913
|
* = the source stopped sending sessions). Null when the prior 7 days had no
|
|
@@ -17812,29 +17916,29 @@ var gaSourceMoverSchema = z51.object({
|
|
|
17812
17916
|
changePct: percent().nullable(),
|
|
17813
17917
|
changeBasis: gaMoverChangeBasisSchema
|
|
17814
17918
|
});
|
|
17815
|
-
var gaSocialReferralTrendResponseSchema =
|
|
17816
|
-
socialSessions7d:
|
|
17817
|
-
socialSessionsPrev7d:
|
|
17919
|
+
var gaSocialReferralTrendResponseSchema = z52.object({
|
|
17920
|
+
socialSessions7d: z52.number(),
|
|
17921
|
+
socialSessionsPrev7d: z52.number(),
|
|
17818
17922
|
/** Signed whole-percent change of the last 7 days against the 7 before. Null when the prior 7 days had no sessions. */
|
|
17819
17923
|
trend7dPct: percent().nullable(),
|
|
17820
|
-
socialSessions30d:
|
|
17821
|
-
socialSessionsPrev30d:
|
|
17924
|
+
socialSessions30d: z52.number(),
|
|
17925
|
+
socialSessionsPrev30d: z52.number(),
|
|
17822
17926
|
/** Signed whole-percent change of the last 30 days against the 30 before. Null when the prior 30 days had no sessions. */
|
|
17823
17927
|
trend30dPct: percent().nullable(),
|
|
17824
17928
|
/** Social source with the largest session change in the last 7 days against the 7 before. Null when no source moved. */
|
|
17825
17929
|
biggestMover: gaSourceMoverSchema.nullable()
|
|
17826
17930
|
});
|
|
17827
|
-
var gaChannelTrendSchema =
|
|
17828
|
-
sessions7d:
|
|
17829
|
-
sessionsPrev7d:
|
|
17931
|
+
var gaChannelTrendSchema = z52.object({
|
|
17932
|
+
sessions7d: z52.number(),
|
|
17933
|
+
sessionsPrev7d: z52.number(),
|
|
17830
17934
|
/** Signed whole-percent change of the last 7 days against the 7 before. Null when the prior 7 days had no sessions. */
|
|
17831
17935
|
trend7dPct: percent().nullable(),
|
|
17832
|
-
sessions30d:
|
|
17833
|
-
sessionsPrev30d:
|
|
17936
|
+
sessions30d: z52.number(),
|
|
17937
|
+
sessionsPrev30d: z52.number(),
|
|
17834
17938
|
/** Signed whole-percent change of the last 30 days against the 30 before. Null when the prior 30 days had no sessions. */
|
|
17835
17939
|
trend30dPct: percent().nullable()
|
|
17836
17940
|
});
|
|
17837
|
-
var gaAttributionTrendResponseSchema =
|
|
17941
|
+
var gaAttributionTrendResponseSchema = z52.object({
|
|
17838
17942
|
organic: gaChannelTrendSchema,
|
|
17839
17943
|
/** AI session trend, scoped to sessionSource-only matches so it lines up with the disjoint AI cell in the channel breakdown. */
|
|
17840
17944
|
ai: gaChannelTrendSchema,
|
|
@@ -17846,23 +17950,23 @@ var gaAttributionTrendResponseSchema = z51.object({
|
|
|
17846
17950
|
/** Social source with the largest session change in the last 7 days against the 7 before. Null when no source moved. */
|
|
17847
17951
|
socialBiggestMover: gaSourceMoverSchema.nullable()
|
|
17848
17952
|
});
|
|
17849
|
-
var gaOverviewValuesSchema =
|
|
17850
|
-
activeUsers:
|
|
17851
|
-
newUsers:
|
|
17852
|
-
totalUsers:
|
|
17853
|
-
sessions:
|
|
17854
|
-
organicSessions:
|
|
17855
|
-
views:
|
|
17856
|
-
eventCount:
|
|
17953
|
+
var gaOverviewValuesSchema = z52.object({
|
|
17954
|
+
activeUsers: z52.number().int().nonnegative().nullable(),
|
|
17955
|
+
newUsers: z52.number().int().nonnegative().nullable(),
|
|
17956
|
+
totalUsers: z52.number().int().nonnegative().nullable(),
|
|
17957
|
+
sessions: z52.number().int().nonnegative().nullable(),
|
|
17958
|
+
organicSessions: z52.number().int().nonnegative().nullable(),
|
|
17959
|
+
views: z52.number().int().nonnegative().nullable(),
|
|
17960
|
+
eventCount: z52.number().int().nonnegative().nullable(),
|
|
17857
17961
|
/** GA4 counts a key event once per session when the property says so, so this can be a decimal. */
|
|
17858
|
-
keyEvents:
|
|
17962
|
+
keyEvents: z52.number().nonnegative().nullable(),
|
|
17859
17963
|
engagementRate: fraction().nullable(),
|
|
17860
17964
|
bounceRate: fraction().nullable(),
|
|
17861
|
-
averageEngagementTimeSeconds:
|
|
17965
|
+
averageEngagementTimeSeconds: z52.number().nonnegative().nullable()
|
|
17862
17966
|
});
|
|
17863
17967
|
var gaOverviewMetricKeySchema = gaOverviewValuesSchema.keyof();
|
|
17864
17968
|
var GaOverviewMetricKeys = gaOverviewMetricKeySchema.enum;
|
|
17865
|
-
var gaOverviewChangeSchema =
|
|
17969
|
+
var gaOverviewChangeSchema = z52.object({
|
|
17866
17970
|
activeUsers: percent().nullable(),
|
|
17867
17971
|
newUsers: percent().nullable(),
|
|
17868
17972
|
totalUsers: percent().nullable(),
|
|
@@ -17875,12 +17979,12 @@ var gaOverviewChangeSchema = z51.object({
|
|
|
17875
17979
|
bounceRate: percent().nullable(),
|
|
17876
17980
|
averageEngagementTimeSeconds: percent().nullable()
|
|
17877
17981
|
});
|
|
17878
|
-
var GA_OVERVIEW_WINDOW_DAYS = { "7d": 7, "30d": 30, "90d": 90 };
|
|
17982
|
+
var GA_OVERVIEW_WINDOW_DAYS = { "7d": 7, "30d": 30, "90d": 90, "180d": 180 };
|
|
17879
17983
|
var GA_OVERVIEW_WINDOWS = WINDOW_SETS.gaOverview;
|
|
17880
17984
|
function isGaOverviewWindow(value) {
|
|
17881
17985
|
return GA_OVERVIEW_WINDOWS.some((window) => window === value);
|
|
17882
17986
|
}
|
|
17883
|
-
var GA_OVERVIEW_HISTORY_DAYS = 2 * GA_OVERVIEW_WINDOW_DAYS["
|
|
17987
|
+
var GA_OVERVIEW_HISTORY_DAYS = 2 * GA_OVERVIEW_WINDOW_DAYS["180d"];
|
|
17884
17988
|
function gaOverviewComparisonDaysAgo(window) {
|
|
17885
17989
|
const days = GA_OVERVIEW_WINDOW_DAYS[window];
|
|
17886
17990
|
return {
|
|
@@ -17897,20 +18001,20 @@ function gaOverviewComparisonRanges(window, now = /* @__PURE__ */ new Date(), ti
|
|
|
17897
18001
|
};
|
|
17898
18002
|
}
|
|
17899
18003
|
var GaOverviewPeriods = { current: "current", previous: "previous" };
|
|
17900
|
-
var gaOverviewPeriodSchema =
|
|
18004
|
+
var gaOverviewPeriodSchema = z52.object({
|
|
17901
18005
|
/** Inclusive. Null when the window has never been synced with the overview metrics. */
|
|
17902
|
-
startDate:
|
|
17903
|
-
endDate:
|
|
18006
|
+
startDate: z52.string().nullable(),
|
|
18007
|
+
endDate: z52.string().nullable()
|
|
17904
18008
|
});
|
|
17905
|
-
var gaOverviewDaySchema =
|
|
17906
|
-
date:
|
|
18009
|
+
var gaOverviewDaySchema = z52.object({
|
|
18010
|
+
date: z52.string(),
|
|
17907
18011
|
/** The day of the previous period in the same position: the window's first day lines up with its first. */
|
|
17908
|
-
previousDate:
|
|
18012
|
+
previousDate: z52.string(),
|
|
17909
18013
|
values: gaOverviewValuesSchema,
|
|
17910
18014
|
previousValues: gaOverviewValuesSchema
|
|
17911
18015
|
});
|
|
17912
|
-
var gaOverviewResponseSchema =
|
|
17913
|
-
window:
|
|
18016
|
+
var gaOverviewResponseSchema = z52.object({
|
|
18017
|
+
window: z52.enum(WINDOW_SETS.gaTraffic),
|
|
17914
18018
|
current: gaOverviewPeriodSchema,
|
|
17915
18019
|
/** The period just before `current`, of the same length. */
|
|
17916
18020
|
previous: gaOverviewPeriodSchema,
|
|
@@ -17923,9 +18027,9 @@ var gaOverviewResponseSchema = z51.object({
|
|
|
17923
18027
|
*/
|
|
17924
18028
|
changePct: gaOverviewChangeSchema,
|
|
17925
18029
|
/** One entry per day of `current`, oldest first. */
|
|
17926
|
-
days:
|
|
18030
|
+
days: z52.array(gaOverviewDaySchema),
|
|
17927
18031
|
/** When GA4 last reported this window's totals. Null when it never has. */
|
|
17928
|
-
syncedAt:
|
|
18032
|
+
syncedAt: z52.string().nullable()
|
|
17929
18033
|
});
|
|
17930
18034
|
var GaOverviewUnits = { count: "count", fraction: "fraction", seconds: "seconds" };
|
|
17931
18035
|
var GaOverviewBetter = { higher: "higher", lower: "lower" };
|
|
@@ -17964,128 +18068,141 @@ var gaTrafficResponseSchema = ga4TrafficSummaryDtoSchema.extend({
|
|
|
17964
18068
|
* Read every share against this window. The share fields divide a channel
|
|
17965
18069
|
* count by `totalSessions`; both come from these dates and only these dates.
|
|
17966
18070
|
*/
|
|
17967
|
-
windowStart:
|
|
18071
|
+
windowStart: z52.string().nullable(),
|
|
17968
18072
|
/** Inclusive end (YYYY-MM-DD) of the measured window. `null` when open-ended. */
|
|
17969
|
-
windowEnd:
|
|
18073
|
+
windowEnd: z52.string().nullable(),
|
|
17970
18074
|
/**
|
|
17971
18075
|
* Calendar days the measured window covers, counting both ends. `null` when
|
|
17972
18076
|
* either bound is open — an unknown span is reported as unknown rather than
|
|
17973
18077
|
* guessed.
|
|
17974
18078
|
*/
|
|
17975
|
-
windowDays:
|
|
18079
|
+
windowDays: z52.number().nullable(),
|
|
17976
18080
|
/** Alias of `windowStart`, retained for callers that predate it. */
|
|
17977
|
-
periodStart:
|
|
18081
|
+
periodStart: z52.string().nullable(),
|
|
17978
18082
|
/** Alias of `windowEnd`, retained for callers that predate it. */
|
|
17979
|
-
periodEnd:
|
|
18083
|
+
periodEnd: z52.string().nullable()
|
|
17980
18084
|
});
|
|
17981
|
-
var ga4AiReferralHistoryEntrySchema =
|
|
17982
|
-
date:
|
|
17983
|
-
source:
|
|
17984
|
-
medium:
|
|
18085
|
+
var ga4AiReferralHistoryEntrySchema = z52.object({
|
|
18086
|
+
date: z52.string(),
|
|
18087
|
+
source: z52.string(),
|
|
18088
|
+
medium: z52.string(),
|
|
17985
18089
|
trafficClass: aiReferralTrafficClassSchema,
|
|
17986
|
-
landingPage:
|
|
17987
|
-
sessions:
|
|
18090
|
+
landingPage: z52.string(),
|
|
18091
|
+
sessions: z52.number(),
|
|
17988
18092
|
/** @deprecated See `GA4AiReferralDto.users`. Never emitted since 4.180.6. */
|
|
17989
|
-
users:
|
|
18093
|
+
users: z52.number().optional(),
|
|
17990
18094
|
/** Which GA4 dimension this row came from: session (sessionSource), first_user (firstUserSource), or manual_utm (utm_source parameter) */
|
|
17991
18095
|
sourceDimension: ga4SourceDimensionSchema
|
|
17992
18096
|
});
|
|
17993
|
-
var ga4AiReferralDailySourceSchema =
|
|
17994
|
-
source:
|
|
17995
|
-
sessions:
|
|
17996
|
-
paidSessions:
|
|
17997
|
-
organicSessions:
|
|
17998
|
-
});
|
|
17999
|
-
var ga4AiReferralDailyEntrySchema =
|
|
18000
|
-
date:
|
|
18001
|
-
sessions:
|
|
18002
|
-
paidSessions:
|
|
18003
|
-
organicSessions:
|
|
18097
|
+
var ga4AiReferralDailySourceSchema = z52.object({
|
|
18098
|
+
source: z52.string(),
|
|
18099
|
+
sessions: z52.number(),
|
|
18100
|
+
paidSessions: z52.number(),
|
|
18101
|
+
organicSessions: z52.number()
|
|
18102
|
+
});
|
|
18103
|
+
var ga4AiReferralDailyEntrySchema = z52.object({
|
|
18104
|
+
date: z52.string(),
|
|
18105
|
+
sessions: z52.number(),
|
|
18106
|
+
paidSessions: z52.number(),
|
|
18107
|
+
organicSessions: z52.number(),
|
|
18004
18108
|
/** Per-source split of the day. `sessions` is the sum of these. */
|
|
18005
|
-
bySource:
|
|
18109
|
+
bySource: z52.array(ga4AiReferralDailySourceSchema)
|
|
18006
18110
|
});
|
|
18007
|
-
var
|
|
18111
|
+
var ga4AiReferralDailyTrendSchema = linearTrendSchema.extend({
|
|
18112
|
+
startDate: z52.string(),
|
|
18113
|
+
endDate: z52.string()
|
|
18114
|
+
});
|
|
18115
|
+
var ga4AiReferralDailyDtoSchema = z52.object({
|
|
18008
18116
|
/** Ascending by date. Dates with no AI referrals are absent, not zero-filled. */
|
|
18009
|
-
days:
|
|
18117
|
+
days: z52.array(ga4AiReferralDailyEntrySchema),
|
|
18010
18118
|
/** Sources present in the window, ordered by total sessions descending. */
|
|
18011
|
-
sources:
|
|
18012
|
-
totalSessions:
|
|
18013
|
-
totalPaidSessions:
|
|
18014
|
-
totalOrganicSessions:
|
|
18119
|
+
sources: z52.array(z52.string()),
|
|
18120
|
+
totalSessions: z52.number(),
|
|
18121
|
+
totalPaidSessions: z52.number(),
|
|
18122
|
+
totalOrganicSessions: z52.number(),
|
|
18015
18123
|
/**
|
|
18016
18124
|
* The same days by AI engine: the five largest engines (the unattributed
|
|
18017
18125
|
* group counts as one), then the rest as `other`. Folded from the same
|
|
18018
18126
|
* winner set as `days`, so each day's values add up to that day's sessions.
|
|
18019
18127
|
*/
|
|
18020
|
-
byEngine: stackedDailySeriesSchema
|
|
18021
|
-
|
|
18022
|
-
|
|
18023
|
-
|
|
18024
|
-
|
|
18025
|
-
|
|
18026
|
-
|
|
18027
|
-
|
|
18128
|
+
byEngine: stackedDailySeriesSchema,
|
|
18129
|
+
/**
|
|
18130
|
+
* Fitted over the window's complete GA4 days, server side so every consumer
|
|
18131
|
+
* draws the same line. A day counts once GA4 reported the site's daily total
|
|
18132
|
+
* for it, so a date with no AI row is a measured zero; days before the
|
|
18133
|
+
* project's first stored AI row, and the last two UTC days (still filling),
|
|
18134
|
+
* are left out. Null with fewer than two such days. Optional so a newer
|
|
18135
|
+
* client reads an older API.
|
|
18136
|
+
*/
|
|
18137
|
+
trend: ga4AiReferralDailyTrendSchema.nullable().optional()
|
|
18138
|
+
});
|
|
18139
|
+
var ga4SocialReferralHistoryEntrySchema = z52.object({
|
|
18140
|
+
date: z52.string(),
|
|
18141
|
+
source: z52.string(),
|
|
18142
|
+
medium: z52.string(),
|
|
18143
|
+
sessions: z52.number(),
|
|
18144
|
+
users: z52.number(),
|
|
18028
18145
|
/** GA4 default channel group (e.g. 'Organic Social', 'Paid Social') */
|
|
18029
|
-
channelGroup:
|
|
18146
|
+
channelGroup: z52.string()
|
|
18030
18147
|
});
|
|
18031
|
-
var ga4SessionHistoryEntrySchema =
|
|
18032
|
-
date:
|
|
18033
|
-
sessions:
|
|
18034
|
-
organicSessions:
|
|
18148
|
+
var ga4SessionHistoryEntrySchema = z52.object({
|
|
18149
|
+
date: z52.string(),
|
|
18150
|
+
sessions: z52.number(),
|
|
18151
|
+
organicSessions: z52.number(),
|
|
18035
18152
|
/**
|
|
18036
18153
|
* Unique visitors for the day. Deduplicated by GA when `usersSource` is
|
|
18037
18154
|
* `deduplicated`; a landing-page sum (which overcounts multi-page visitors)
|
|
18038
18155
|
* for days synced before per-day totals were captured.
|
|
18039
18156
|
*/
|
|
18040
|
-
users:
|
|
18157
|
+
users: z52.number(),
|
|
18041
18158
|
/**
|
|
18042
18159
|
* How `users` was derived. `deduplicated` matches the GA UI's active users;
|
|
18043
18160
|
* `landing-page-sum` is the legacy overcount kept so historical days still
|
|
18044
18161
|
* render. Never compare the two across a series without saying which is which.
|
|
18045
18162
|
*/
|
|
18046
|
-
usersSource:
|
|
18163
|
+
usersSource: z52.enum(["deduplicated", "landing-page-sum"])
|
|
18047
18164
|
});
|
|
18048
|
-
var gaAcquisitionDimensionSchema =
|
|
18165
|
+
var gaAcquisitionDimensionSchema = z52.enum(["date", "channelGroup", "source", "medium", "hostName", "landingPage"]);
|
|
18049
18166
|
var GaAcquisitionDimensions = gaAcquisitionDimensionSchema.enum;
|
|
18050
|
-
var gaAcquisitionQuerySchema =
|
|
18167
|
+
var gaAcquisitionQuerySchema = z52.object({
|
|
18051
18168
|
window: metricsWindowSchema.optional(),
|
|
18052
|
-
startDate:
|
|
18053
|
-
endDate:
|
|
18054
|
-
channel:
|
|
18055
|
-
source:
|
|
18056
|
-
medium:
|
|
18057
|
-
hostName:
|
|
18058
|
-
landingPage:
|
|
18059
|
-
pathPrefix:
|
|
18060
|
-
groupBy:
|
|
18061
|
-
limit:
|
|
18062
|
-
offset:
|
|
18063
|
-
}).strict();
|
|
18064
|
-
var gaAcquisitionRowSchema =
|
|
18065
|
-
date:
|
|
18066
|
-
channelGroup:
|
|
18067
|
-
source:
|
|
18068
|
-
medium:
|
|
18069
|
-
hostName:
|
|
18070
|
-
landingPage:
|
|
18071
|
-
sessions:
|
|
18072
|
-
});
|
|
18073
|
-
var gaAcquisitionResponseSchema =
|
|
18074
|
-
source:
|
|
18169
|
+
startDate: z52.iso.date().optional(),
|
|
18170
|
+
endDate: z52.iso.date().optional(),
|
|
18171
|
+
channel: z52.string().optional(),
|
|
18172
|
+
source: z52.string().optional(),
|
|
18173
|
+
medium: z52.string().optional(),
|
|
18174
|
+
hostName: z52.string().optional(),
|
|
18175
|
+
landingPage: z52.string().optional(),
|
|
18176
|
+
pathPrefix: z52.string().optional(),
|
|
18177
|
+
groupBy: z52.string().refine((value) => value.split(",").every((key) => gaAcquisitionDimensionSchema.safeParse(key.trim()).success), `groupBy must contain: ${gaAcquisitionDimensionSchema.options.join(", ")}`).optional(),
|
|
18178
|
+
limit: z52.number().int().min(1).max(1e3).optional(),
|
|
18179
|
+
offset: z52.number().int().nonnegative().optional()
|
|
18180
|
+
}).strict();
|
|
18181
|
+
var gaAcquisitionRowSchema = z52.object({
|
|
18182
|
+
date: z52.string().optional(),
|
|
18183
|
+
channelGroup: z52.string().optional(),
|
|
18184
|
+
source: z52.string().optional(),
|
|
18185
|
+
medium: z52.string().optional(),
|
|
18186
|
+
hostName: z52.string().optional(),
|
|
18187
|
+
landingPage: z52.string().optional(),
|
|
18188
|
+
sessions: z52.number().int().nonnegative()
|
|
18189
|
+
});
|
|
18190
|
+
var gaAcquisitionResponseSchema = z52.object({
|
|
18191
|
+
source: z52.literal("ga4-acquisition"),
|
|
18075
18192
|
status: gaMeasurementComponentStatusSchema,
|
|
18076
|
-
error:
|
|
18077
|
-
syncedAt:
|
|
18078
|
-
scope:
|
|
18079
|
-
window:
|
|
18080
|
-
coverage:
|
|
18081
|
-
filters:
|
|
18082
|
-
groupBy:
|
|
18083
|
-
channelGroups:
|
|
18084
|
-
totalSessions:
|
|
18085
|
-
totalRows:
|
|
18086
|
-
limit:
|
|
18087
|
-
offset:
|
|
18088
|
-
rows:
|
|
18193
|
+
error: z52.string().nullable(),
|
|
18194
|
+
syncedAt: z52.string().nullable(),
|
|
18195
|
+
scope: z52.object({ project: z52.string(), attribution: z52.literal("project-only"), unavailableDimensions: z52.array(z52.enum(["property", "target", "market"])) }),
|
|
18196
|
+
window: z52.object({ startDate: z52.string().nullable(), endDate: z52.string().nullable(), window: metricsWindowSchema }),
|
|
18197
|
+
coverage: z52.object({ earliestDate: z52.string().nullable(), latestDate: z52.string().nullable() }),
|
|
18198
|
+
filters: z52.object({ channel: z52.string().nullable(), source: z52.string().nullable(), medium: z52.string().nullable(), hostName: z52.string().nullable(), landingPage: z52.string().nullable(), pathPrefix: z52.string().nullable() }),
|
|
18199
|
+
groupBy: z52.array(gaAcquisitionDimensionSchema),
|
|
18200
|
+
channelGroups: z52.array(z52.string()),
|
|
18201
|
+
totalSessions: z52.number().int().nonnegative(),
|
|
18202
|
+
totalRows: z52.number().int().nonnegative(),
|
|
18203
|
+
limit: z52.number().int(),
|
|
18204
|
+
offset: z52.number().int(),
|
|
18205
|
+
rows: z52.array(gaAcquisitionRowSchema)
|
|
18089
18206
|
});
|
|
18090
18207
|
function formatGaOverviewValue(key, value, options = {}) {
|
|
18091
18208
|
if (value === null) return "\u2014";
|
|
@@ -18168,8 +18285,8 @@ function collectBrandAliasesFromDomain(domain) {
|
|
|
18168
18285
|
}
|
|
18169
18286
|
|
|
18170
18287
|
// ../contracts/src/backlinks.ts
|
|
18171
|
-
import { z as
|
|
18172
|
-
var backlinkSourceSchema =
|
|
18288
|
+
import { z as z53 } from "zod";
|
|
18289
|
+
var backlinkSourceSchema = z53.enum(["commoncrawl", "bing-webmaster"]);
|
|
18173
18290
|
var BacklinkSources = backlinkSourceSchema.enum;
|
|
18174
18291
|
function computeBacklinkSummaryMetrics(rows) {
|
|
18175
18292
|
if (rows.length === 0) {
|
|
@@ -18185,108 +18302,108 @@ function computeBacklinkSummaryMetrics(rows) {
|
|
|
18185
18302
|
top10HostsShare: share.toFixed(6)
|
|
18186
18303
|
};
|
|
18187
18304
|
}
|
|
18188
|
-
var ccReleaseSyncStatusSchema =
|
|
18305
|
+
var ccReleaseSyncStatusSchema = z53.enum(["queued", "downloading", "querying", "ready", "failed"]);
|
|
18189
18306
|
var CcReleaseSyncStatuses = ccReleaseSyncStatusSchema.enum;
|
|
18190
|
-
var ccReleaseSyncDtoSchema =
|
|
18191
|
-
id:
|
|
18192
|
-
release:
|
|
18307
|
+
var ccReleaseSyncDtoSchema = z53.object({
|
|
18308
|
+
id: z53.string(),
|
|
18309
|
+
release: z53.string(),
|
|
18193
18310
|
status: ccReleaseSyncStatusSchema,
|
|
18194
|
-
phaseDetail:
|
|
18195
|
-
vertexPath:
|
|
18196
|
-
edgesPath:
|
|
18197
|
-
vertexSha256:
|
|
18198
|
-
edgesSha256:
|
|
18199
|
-
vertexBytes:
|
|
18200
|
-
edgesBytes:
|
|
18201
|
-
projectsProcessed:
|
|
18202
|
-
domainsDiscovered:
|
|
18203
|
-
downloadStartedAt:
|
|
18204
|
-
downloadFinishedAt:
|
|
18205
|
-
queryStartedAt:
|
|
18206
|
-
queryFinishedAt:
|
|
18207
|
-
error:
|
|
18208
|
-
createdAt:
|
|
18209
|
-
updatedAt:
|
|
18311
|
+
phaseDetail: z53.string().nullable().optional(),
|
|
18312
|
+
vertexPath: z53.string().nullable().optional(),
|
|
18313
|
+
edgesPath: z53.string().nullable().optional(),
|
|
18314
|
+
vertexSha256: z53.string().nullable().optional(),
|
|
18315
|
+
edgesSha256: z53.string().nullable().optional(),
|
|
18316
|
+
vertexBytes: z53.number().int().nullable().optional(),
|
|
18317
|
+
edgesBytes: z53.number().int().nullable().optional(),
|
|
18318
|
+
projectsProcessed: z53.number().int().nullable().optional(),
|
|
18319
|
+
domainsDiscovered: z53.number().int().nullable().optional(),
|
|
18320
|
+
downloadStartedAt: z53.string().nullable().optional(),
|
|
18321
|
+
downloadFinishedAt: z53.string().nullable().optional(),
|
|
18322
|
+
queryStartedAt: z53.string().nullable().optional(),
|
|
18323
|
+
queryFinishedAt: z53.string().nullable().optional(),
|
|
18324
|
+
error: z53.string().nullable().optional(),
|
|
18325
|
+
createdAt: z53.string(),
|
|
18326
|
+
updatedAt: z53.string()
|
|
18210
18327
|
});
|
|
18211
|
-
var backlinkDomainDtoSchema =
|
|
18212
|
-
linkingDomain:
|
|
18213
|
-
numHosts:
|
|
18328
|
+
var backlinkDomainDtoSchema = z53.object({
|
|
18329
|
+
linkingDomain: z53.string(),
|
|
18330
|
+
numHosts: z53.number().int(),
|
|
18214
18331
|
source: backlinkSourceSchema
|
|
18215
18332
|
});
|
|
18216
|
-
var backlinkSummaryDtoSchema =
|
|
18217
|
-
projectId:
|
|
18218
|
-
release:
|
|
18219
|
-
targetDomain:
|
|
18220
|
-
totalLinkingDomains:
|
|
18221
|
-
totalHosts:
|
|
18222
|
-
top10HostsShare:
|
|
18223
|
-
queriedAt:
|
|
18333
|
+
var backlinkSummaryDtoSchema = z53.object({
|
|
18334
|
+
projectId: z53.string(),
|
|
18335
|
+
release: z53.string(),
|
|
18336
|
+
targetDomain: z53.string(),
|
|
18337
|
+
totalLinkingDomains: z53.number().int(),
|
|
18338
|
+
totalHosts: z53.number().int(),
|
|
18339
|
+
top10HostsShare: z53.string(),
|
|
18340
|
+
queriedAt: z53.string(),
|
|
18224
18341
|
source: backlinkSourceSchema,
|
|
18225
18342
|
// Populated when the response is filtered (e.g. ?excludeCrawlers=1).
|
|
18226
18343
|
// Counts the rows omitted from totalLinkingDomains/totalHosts so callers
|
|
18227
18344
|
// can show "N hidden" hints without re-deriving them.
|
|
18228
|
-
excludedLinkingDomains:
|
|
18229
|
-
excludedHosts:
|
|
18345
|
+
excludedLinkingDomains: z53.number().int().optional(),
|
|
18346
|
+
excludedHosts: z53.number().int().optional()
|
|
18230
18347
|
});
|
|
18231
|
-
var backlinkListResponseSchema =
|
|
18348
|
+
var backlinkListResponseSchema = z53.object({
|
|
18232
18349
|
source: backlinkSourceSchema,
|
|
18233
18350
|
summary: backlinkSummaryDtoSchema.nullable(),
|
|
18234
|
-
total:
|
|
18235
|
-
rows:
|
|
18236
|
-
});
|
|
18237
|
-
var backlinkHistoryEntrySchema =
|
|
18238
|
-
release:
|
|
18239
|
-
totalLinkingDomains:
|
|
18240
|
-
totalHosts:
|
|
18241
|
-
top10HostsShare:
|
|
18242
|
-
queriedAt:
|
|
18351
|
+
total: z53.number().int(),
|
|
18352
|
+
rows: z53.array(backlinkDomainDtoSchema)
|
|
18353
|
+
});
|
|
18354
|
+
var backlinkHistoryEntrySchema = z53.object({
|
|
18355
|
+
release: z53.string(),
|
|
18356
|
+
totalLinkingDomains: z53.number().int(),
|
|
18357
|
+
totalHosts: z53.number().int(),
|
|
18358
|
+
top10HostsShare: z53.string(),
|
|
18359
|
+
queriedAt: z53.string(),
|
|
18243
18360
|
source: backlinkSourceSchema
|
|
18244
18361
|
});
|
|
18245
|
-
var backlinkSourceAvailabilityDtoSchema =
|
|
18362
|
+
var backlinkSourceAvailabilityDtoSchema = z53.object({
|
|
18246
18363
|
source: backlinkSourceSchema,
|
|
18247
|
-
connected:
|
|
18248
|
-
hasData:
|
|
18249
|
-
latestRelease:
|
|
18250
|
-
totalLinkingDomains:
|
|
18251
|
-
lastSyncedAt:
|
|
18252
|
-
});
|
|
18253
|
-
var backlinkSourcesResponseSchema =
|
|
18254
|
-
projectId:
|
|
18255
|
-
targetDomain:
|
|
18256
|
-
sources:
|
|
18257
|
-
anyConnected:
|
|
18258
|
-
anyData:
|
|
18259
|
-
});
|
|
18260
|
-
var backlinksInstallStatusDtoSchema =
|
|
18261
|
-
duckdbInstalled:
|
|
18262
|
-
duckdbVersion:
|
|
18263
|
-
duckdbSpec:
|
|
18264
|
-
pluginDir:
|
|
18265
|
-
});
|
|
18266
|
-
var backlinksInstallResultDtoSchema =
|
|
18267
|
-
installed:
|
|
18268
|
-
version:
|
|
18269
|
-
path:
|
|
18270
|
-
alreadyPresent:
|
|
18271
|
-
});
|
|
18272
|
-
var ccAvailableReleaseSchema =
|
|
18273
|
-
release:
|
|
18274
|
-
vertexUrl:
|
|
18275
|
-
edgesUrl:
|
|
18276
|
-
vertexBytes:
|
|
18277
|
-
edgesBytes:
|
|
18278
|
-
lastModified:
|
|
18279
|
-
});
|
|
18280
|
-
var ccCachedReleaseSchema =
|
|
18281
|
-
release:
|
|
18364
|
+
connected: z53.boolean(),
|
|
18365
|
+
hasData: z53.boolean(),
|
|
18366
|
+
latestRelease: z53.string().nullable(),
|
|
18367
|
+
totalLinkingDomains: z53.number().int(),
|
|
18368
|
+
lastSyncedAt: z53.string().nullable()
|
|
18369
|
+
});
|
|
18370
|
+
var backlinkSourcesResponseSchema = z53.object({
|
|
18371
|
+
projectId: z53.string(),
|
|
18372
|
+
targetDomain: z53.string(),
|
|
18373
|
+
sources: z53.array(backlinkSourceAvailabilityDtoSchema),
|
|
18374
|
+
anyConnected: z53.boolean(),
|
|
18375
|
+
anyData: z53.boolean()
|
|
18376
|
+
});
|
|
18377
|
+
var backlinksInstallStatusDtoSchema = z53.object({
|
|
18378
|
+
duckdbInstalled: z53.boolean(),
|
|
18379
|
+
duckdbVersion: z53.string().nullable().optional(),
|
|
18380
|
+
duckdbSpec: z53.string(),
|
|
18381
|
+
pluginDir: z53.string()
|
|
18382
|
+
});
|
|
18383
|
+
var backlinksInstallResultDtoSchema = z53.object({
|
|
18384
|
+
installed: z53.boolean(),
|
|
18385
|
+
version: z53.string(),
|
|
18386
|
+
path: z53.string(),
|
|
18387
|
+
alreadyPresent: z53.boolean()
|
|
18388
|
+
});
|
|
18389
|
+
var ccAvailableReleaseSchema = z53.object({
|
|
18390
|
+
release: z53.string(),
|
|
18391
|
+
vertexUrl: z53.string(),
|
|
18392
|
+
edgesUrl: z53.string(),
|
|
18393
|
+
vertexBytes: z53.number().int().nullable(),
|
|
18394
|
+
edgesBytes: z53.number().int().nullable(),
|
|
18395
|
+
lastModified: z53.string().nullable()
|
|
18396
|
+
});
|
|
18397
|
+
var ccCachedReleaseSchema = z53.object({
|
|
18398
|
+
release: z53.string(),
|
|
18282
18399
|
syncStatus: ccReleaseSyncStatusSchema.nullable(),
|
|
18283
|
-
bytes:
|
|
18284
|
-
lastUsedAt:
|
|
18400
|
+
bytes: z53.number().int(),
|
|
18401
|
+
lastUsedAt: z53.string().nullable()
|
|
18285
18402
|
});
|
|
18286
18403
|
|
|
18287
18404
|
// ../contracts/src/content.ts
|
|
18288
|
-
import { z as
|
|
18289
|
-
var contentActionSchema =
|
|
18405
|
+
import { z as z54 } from "zod";
|
|
18406
|
+
var contentActionSchema = z54.enum(["create", "expand", "refresh", "add-schema"]);
|
|
18290
18407
|
var ContentActions = contentActionSchema.enum;
|
|
18291
18408
|
function contentActionLabel(action) {
|
|
18292
18409
|
switch (action) {
|
|
@@ -18300,9 +18417,9 @@ function contentActionLabel(action) {
|
|
|
18300
18417
|
return "Add schema";
|
|
18301
18418
|
}
|
|
18302
18419
|
}
|
|
18303
|
-
var demandSourceSchema =
|
|
18420
|
+
var demandSourceSchema = z54.enum(["gsc", "competitor-evidence", "both"]);
|
|
18304
18421
|
var DemandSources = demandSourceSchema.enum;
|
|
18305
|
-
var actionConfidenceSchema =
|
|
18422
|
+
var actionConfidenceSchema = z54.enum(["high", "medium", "low"]);
|
|
18306
18423
|
var ActionConfidences = actionConfidenceSchema.enum;
|
|
18307
18424
|
function actionConfidenceLabel(confidence) {
|
|
18308
18425
|
switch (confidence) {
|
|
@@ -18314,7 +18431,7 @@ function actionConfidenceLabel(confidence) {
|
|
|
18314
18431
|
return "Low";
|
|
18315
18432
|
}
|
|
18316
18433
|
}
|
|
18317
|
-
var pageTypeSchema =
|
|
18434
|
+
var pageTypeSchema = z54.enum([
|
|
18318
18435
|
"blog-post",
|
|
18319
18436
|
"comparison",
|
|
18320
18437
|
"listicle",
|
|
@@ -18323,7 +18440,7 @@ var pageTypeSchema = z53.enum([
|
|
|
18323
18440
|
"glossary"
|
|
18324
18441
|
]);
|
|
18325
18442
|
var PageTypes = pageTypeSchema.enum;
|
|
18326
|
-
var contentActionStateSchema =
|
|
18443
|
+
var contentActionStateSchema = z54.enum([
|
|
18327
18444
|
"proposed",
|
|
18328
18445
|
"briefed",
|
|
18329
18446
|
"payload-generated",
|
|
@@ -18333,7 +18450,7 @@ var contentActionStateSchema = z53.enum([
|
|
|
18333
18450
|
"dismissed"
|
|
18334
18451
|
]);
|
|
18335
18452
|
var ContentActionStates = contentActionStateSchema.enum;
|
|
18336
|
-
var winnabilityClassSchema =
|
|
18453
|
+
var winnabilityClassSchema = z54.enum(["ownable", "ceded"]);
|
|
18337
18454
|
var WinnabilityClasses = winnabilityClassSchema.enum;
|
|
18338
18455
|
function winnabilityClassLabel(winnabilityClass) {
|
|
18339
18456
|
switch (winnabilityClass) {
|
|
@@ -18368,40 +18485,40 @@ function deriveWinnabilityClass(citedSurfaceDomains, surfaceClasses, threshold =
|
|
|
18368
18485
|
winnability
|
|
18369
18486
|
};
|
|
18370
18487
|
}
|
|
18371
|
-
var ourBestPageSchema =
|
|
18372
|
-
url:
|
|
18373
|
-
gscImpressions:
|
|
18374
|
-
gscClicks:
|
|
18488
|
+
var ourBestPageSchema = z54.object({
|
|
18489
|
+
url: z54.string(),
|
|
18490
|
+
gscImpressions: z54.number().nonnegative(),
|
|
18491
|
+
gscClicks: z54.number().nonnegative(),
|
|
18375
18492
|
// Null when the page came from the inventory fallback (no GSC ranking data).
|
|
18376
|
-
gscAvgPosition:
|
|
18377
|
-
organicSessions:
|
|
18378
|
-
});
|
|
18379
|
-
var winningCompetitorSchema =
|
|
18380
|
-
domain:
|
|
18381
|
-
url:
|
|
18382
|
-
title:
|
|
18383
|
-
citationCount:
|
|
18384
|
-
});
|
|
18385
|
-
var scoreBreakdownSchema =
|
|
18386
|
-
demand:
|
|
18387
|
-
competitor:
|
|
18388
|
-
absence:
|
|
18389
|
-
gapSeverity:
|
|
18390
|
-
});
|
|
18391
|
-
var existingActionRefSchema =
|
|
18392
|
-
actionId:
|
|
18493
|
+
gscAvgPosition: z54.number().nonnegative().nullable(),
|
|
18494
|
+
organicSessions: z54.number().nonnegative()
|
|
18495
|
+
});
|
|
18496
|
+
var winningCompetitorSchema = z54.object({
|
|
18497
|
+
domain: z54.string(),
|
|
18498
|
+
url: z54.string(),
|
|
18499
|
+
title: z54.string(),
|
|
18500
|
+
citationCount: z54.number().int().nonnegative()
|
|
18501
|
+
});
|
|
18502
|
+
var scoreBreakdownSchema = z54.object({
|
|
18503
|
+
demand: z54.number(),
|
|
18504
|
+
competitor: z54.number(),
|
|
18505
|
+
absence: z54.number(),
|
|
18506
|
+
gapSeverity: z54.number()
|
|
18507
|
+
});
|
|
18508
|
+
var existingActionRefSchema = z54.object({
|
|
18509
|
+
actionId: z54.string(),
|
|
18393
18510
|
state: contentActionStateSchema,
|
|
18394
|
-
lastUpdated:
|
|
18511
|
+
lastUpdated: z54.string()
|
|
18395
18512
|
});
|
|
18396
|
-
var contentTargetRowDtoSchema =
|
|
18397
|
-
targetRef:
|
|
18398
|
-
query:
|
|
18513
|
+
var contentTargetRowDtoSchema = z54.object({
|
|
18514
|
+
targetRef: z54.string(),
|
|
18515
|
+
query: z54.string(),
|
|
18399
18516
|
action: contentActionSchema,
|
|
18400
18517
|
ourBestPage: ourBestPageSchema.nullable(),
|
|
18401
18518
|
winningCompetitor: winningCompetitorSchema.nullable(),
|
|
18402
|
-
score:
|
|
18519
|
+
score: z54.number(),
|
|
18403
18520
|
scoreBreakdown: scoreBreakdownSchema,
|
|
18404
|
-
drivers:
|
|
18521
|
+
drivers: z54.array(z54.string()),
|
|
18405
18522
|
demandSource: demandSourceSchema,
|
|
18406
18523
|
actionConfidence: actionConfidenceSchema,
|
|
18407
18524
|
existingAction: existingActionRefSchema.nullable(),
|
|
@@ -18416,134 +18533,134 @@ var contentTargetRowDtoSchema = z53.object({
|
|
|
18416
18533
|
* `[0, 1]`. `null` when the gate failed open (no classification coverage for
|
|
18417
18534
|
* the cited surface) — distinct from a computed `1.0`.
|
|
18418
18535
|
*/
|
|
18419
|
-
winnability: fraction(
|
|
18420
|
-
});
|
|
18421
|
-
var contentTargetsResponseDtoSchema =
|
|
18422
|
-
targets:
|
|
18423
|
-
contextMetrics:
|
|
18424
|
-
totalAiReferralSessions:
|
|
18425
|
-
latestRunId:
|
|
18426
|
-
runTimestamp:
|
|
18536
|
+
winnability: fraction(z54.number().min(0).max(1)).nullable()
|
|
18537
|
+
});
|
|
18538
|
+
var contentTargetsResponseDtoSchema = z54.object({
|
|
18539
|
+
targets: z54.array(contentTargetRowDtoSchema),
|
|
18540
|
+
contextMetrics: z54.object({
|
|
18541
|
+
totalAiReferralSessions: z54.number().int().nonnegative(),
|
|
18542
|
+
latestRunId: z54.string(),
|
|
18543
|
+
runTimestamp: z54.string()
|
|
18427
18544
|
})
|
|
18428
18545
|
});
|
|
18429
|
-
var contentTargetDismissalDtoSchema =
|
|
18430
|
-
targetRef:
|
|
18431
|
-
addressedUrl:
|
|
18432
|
-
note:
|
|
18433
|
-
dismissedAt:
|
|
18546
|
+
var contentTargetDismissalDtoSchema = z54.object({
|
|
18547
|
+
targetRef: z54.string(),
|
|
18548
|
+
addressedUrl: z54.string().nullable(),
|
|
18549
|
+
note: z54.string().nullable(),
|
|
18550
|
+
dismissedAt: z54.string()
|
|
18434
18551
|
});
|
|
18435
|
-
var contentTargetDismissalsResponseDtoSchema =
|
|
18436
|
-
dismissals:
|
|
18552
|
+
var contentTargetDismissalsResponseDtoSchema = z54.object({
|
|
18553
|
+
dismissals: z54.array(contentTargetDismissalDtoSchema)
|
|
18437
18554
|
});
|
|
18438
|
-
var contentTargetDismissRequestSchema =
|
|
18439
|
-
targetRef:
|
|
18555
|
+
var contentTargetDismissRequestSchema = z54.object({
|
|
18556
|
+
targetRef: z54.string().min(1),
|
|
18440
18557
|
/** URL of the page the user wrote that addresses this recommendation. Stored verbatim for the audit trail; not currently used to suppress the slug-token matcher. */
|
|
18441
|
-
addressedUrl:
|
|
18558
|
+
addressedUrl: z54.string().url().optional(),
|
|
18442
18559
|
/** Free-form note (e.g. "covered in our Q1 content sprint"). 500 char cap is the API surface limit; the DB column is unbounded. */
|
|
18443
|
-
note:
|
|
18560
|
+
note: z54.string().max(500).optional()
|
|
18444
18561
|
});
|
|
18445
|
-
var recommendationExplanationDtoSchema =
|
|
18446
|
-
targetRef:
|
|
18562
|
+
var recommendationExplanationDtoSchema = z54.object({
|
|
18563
|
+
targetRef: z54.string(),
|
|
18447
18564
|
/** Version of the prompt template used. Bumping the version invalidates the cache forward without touching the table. */
|
|
18448
|
-
promptVersion:
|
|
18565
|
+
promptVersion: z54.string(),
|
|
18449
18566
|
/** Provider that produced the explanation (e.g. "claude", "gemini"). */
|
|
18450
|
-
provider:
|
|
18567
|
+
provider: z54.string(),
|
|
18451
18568
|
/** Model id within that provider (e.g. "claude-sonnet-4-6"). */
|
|
18452
|
-
model:
|
|
18569
|
+
model: z54.string(),
|
|
18453
18570
|
/** Markdown-formatted rationale + recommended next steps. */
|
|
18454
|
-
responseText:
|
|
18571
|
+
responseText: z54.string(),
|
|
18455
18572
|
/** Estimated cost in millicents (1/100 of a cent). 0 when unknown. */
|
|
18456
|
-
costMillicents:
|
|
18457
|
-
generatedAt:
|
|
18573
|
+
costMillicents: z54.number().int().nonnegative(),
|
|
18574
|
+
generatedAt: z54.string()
|
|
18458
18575
|
});
|
|
18459
|
-
var recommendationExplainRequestSchema =
|
|
18576
|
+
var recommendationExplainRequestSchema = z54.object({
|
|
18460
18577
|
/**
|
|
18461
18578
|
* Optional provider override (e.g. "claude" to force Claude even if
|
|
18462
18579
|
* the project's default is Gemini). Falls through to project default
|
|
18463
18580
|
* → auto-detect when omitted.
|
|
18464
18581
|
*/
|
|
18465
|
-
provider:
|
|
18582
|
+
provider: z54.string().optional(),
|
|
18466
18583
|
/**
|
|
18467
18584
|
* Optional model override within the chosen provider. Falls through to
|
|
18468
18585
|
* the `analyze`-tier default model when omitted.
|
|
18469
18586
|
*/
|
|
18470
|
-
model:
|
|
18587
|
+
model: z54.string().optional(),
|
|
18471
18588
|
/**
|
|
18472
18589
|
* Force a fresh LLM call even if a cached explanation exists for the
|
|
18473
18590
|
* current prompt version. Use sparingly — defeats the cache.
|
|
18474
18591
|
*/
|
|
18475
|
-
forceRefresh:
|
|
18592
|
+
forceRefresh: z54.boolean().optional()
|
|
18476
18593
|
});
|
|
18477
|
-
var contentBriefDtoSchema =
|
|
18594
|
+
var contentBriefDtoSchema = z54.object({
|
|
18478
18595
|
/** The query the brief is for (echoed from the recommendation). */
|
|
18479
|
-
targetQuery:
|
|
18596
|
+
targetQuery: z54.string().trim().min(1),
|
|
18480
18597
|
/** Always `ownable` in practice — the gate rejects `ceded` before synthesis. */
|
|
18481
18598
|
winnabilityClass: winnabilityClassSchema,
|
|
18482
18599
|
/** The differentiated content angle to take. */
|
|
18483
|
-
angle:
|
|
18600
|
+
angle: z54.string().trim().min(1),
|
|
18484
18601
|
/** Why this query is winnable, citing the cited-surface signal. */
|
|
18485
|
-
whyWinnable:
|
|
18602
|
+
whyWinnable: z54.string().trim().min(1),
|
|
18486
18603
|
/** The schema.org type or markup to add or extend. */
|
|
18487
|
-
schemaHookup:
|
|
18604
|
+
schemaHookup: z54.string().trim().min(1),
|
|
18488
18605
|
/** Why the cited surface is controllable (the ownable-vs-ceded reasoning). */
|
|
18489
|
-
controllableSurfaceRationale:
|
|
18606
|
+
controllableSurfaceRationale: z54.string().trim().min(1)
|
|
18490
18607
|
});
|
|
18491
|
-
var recommendationBriefDtoSchema =
|
|
18492
|
-
targetRef:
|
|
18608
|
+
var recommendationBriefDtoSchema = z54.object({
|
|
18609
|
+
targetRef: z54.string(),
|
|
18493
18610
|
/** Version of the brief prompt template; bumping invalidates the cache forward. */
|
|
18494
|
-
promptVersion:
|
|
18495
|
-
provider:
|
|
18496
|
-
model:
|
|
18611
|
+
promptVersion: z54.string(),
|
|
18612
|
+
provider: z54.string(),
|
|
18613
|
+
model: z54.string(),
|
|
18497
18614
|
brief: contentBriefDtoSchema,
|
|
18498
18615
|
/** Estimated cost in millicents (1/100 of a cent). 0 when unknown. */
|
|
18499
|
-
costMillicents:
|
|
18500
|
-
generatedAt:
|
|
18616
|
+
costMillicents: z54.number().int().nonnegative(),
|
|
18617
|
+
generatedAt: z54.string()
|
|
18501
18618
|
});
|
|
18502
|
-
var domainClassificationDtoSchema =
|
|
18503
|
-
domain:
|
|
18619
|
+
var domainClassificationDtoSchema = z54.object({
|
|
18620
|
+
domain: z54.string(),
|
|
18504
18621
|
competitorType: discoveryCompetitorTypeSchema,
|
|
18505
|
-
hits:
|
|
18506
|
-
updatedAt:
|
|
18622
|
+
hits: z54.number().int().nonnegative(),
|
|
18623
|
+
updatedAt: z54.string()
|
|
18507
18624
|
});
|
|
18508
|
-
var domainClassificationsResponseDtoSchema =
|
|
18509
|
-
classifications:
|
|
18510
|
-
});
|
|
18511
|
-
var contentGroundingSourceSchema =
|
|
18512
|
-
uri:
|
|
18513
|
-
title:
|
|
18514
|
-
domain:
|
|
18515
|
-
isOurDomain:
|
|
18516
|
-
isCompetitor:
|
|
18517
|
-
citationCount:
|
|
18518
|
-
providers:
|
|
18519
|
-
});
|
|
18520
|
-
var contentSourceRowDtoSchema =
|
|
18521
|
-
query:
|
|
18522
|
-
groundingSources:
|
|
18523
|
-
});
|
|
18524
|
-
var contentSourcesResponseDtoSchema =
|
|
18525
|
-
sources:
|
|
18526
|
-
latestRunId:
|
|
18527
|
-
});
|
|
18528
|
-
var contentGapRowDtoSchema =
|
|
18529
|
-
query:
|
|
18530
|
-
competitorDomains:
|
|
18531
|
-
competitorCount:
|
|
18532
|
-
missRate: fraction(
|
|
18533
|
-
lastSeenInRunId:
|
|
18534
|
-
});
|
|
18535
|
-
var contentGapsResponseDtoSchema =
|
|
18536
|
-
gaps:
|
|
18537
|
-
latestRunId:
|
|
18625
|
+
var domainClassificationsResponseDtoSchema = z54.object({
|
|
18626
|
+
classifications: z54.array(domainClassificationDtoSchema)
|
|
18627
|
+
});
|
|
18628
|
+
var contentGroundingSourceSchema = z54.object({
|
|
18629
|
+
uri: z54.string(),
|
|
18630
|
+
title: z54.string(),
|
|
18631
|
+
domain: z54.string(),
|
|
18632
|
+
isOurDomain: z54.boolean(),
|
|
18633
|
+
isCompetitor: z54.boolean(),
|
|
18634
|
+
citationCount: z54.number().int().nonnegative(),
|
|
18635
|
+
providers: z54.array(providerNameSchema)
|
|
18636
|
+
});
|
|
18637
|
+
var contentSourceRowDtoSchema = z54.object({
|
|
18638
|
+
query: z54.string(),
|
|
18639
|
+
groundingSources: z54.array(contentGroundingSourceSchema)
|
|
18640
|
+
});
|
|
18641
|
+
var contentSourcesResponseDtoSchema = z54.object({
|
|
18642
|
+
sources: z54.array(contentSourceRowDtoSchema),
|
|
18643
|
+
latestRunId: z54.string()
|
|
18644
|
+
});
|
|
18645
|
+
var contentGapRowDtoSchema = z54.object({
|
|
18646
|
+
query: z54.string(),
|
|
18647
|
+
competitorDomains: z54.array(z54.string()),
|
|
18648
|
+
competitorCount: z54.number().int().nonnegative(),
|
|
18649
|
+
missRate: fraction(z54.number().min(0).max(1)),
|
|
18650
|
+
lastSeenInRunId: z54.string()
|
|
18651
|
+
});
|
|
18652
|
+
var contentGapsResponseDtoSchema = z54.object({
|
|
18653
|
+
gaps: z54.array(contentGapRowDtoSchema),
|
|
18654
|
+
latestRunId: z54.string()
|
|
18538
18655
|
});
|
|
18539
18656
|
|
|
18540
18657
|
// ../contracts/src/doctor.ts
|
|
18541
|
-
import { z as
|
|
18542
|
-
var checkStatusSchema =
|
|
18658
|
+
import { z as z55 } from "zod";
|
|
18659
|
+
var checkStatusSchema = z55.enum(["ok", "warn", "fail", "skipped"]);
|
|
18543
18660
|
var CheckStatuses = checkStatusSchema.enum;
|
|
18544
|
-
var checkScopeSchema =
|
|
18661
|
+
var checkScopeSchema = z55.enum(["global", "project"]);
|
|
18545
18662
|
var CheckScopes = checkScopeSchema.enum;
|
|
18546
|
-
var checkCategorySchema =
|
|
18663
|
+
var checkCategorySchema = z55.enum([
|
|
18547
18664
|
"auth",
|
|
18548
18665
|
"config",
|
|
18549
18666
|
"providers",
|
|
@@ -18555,9 +18672,9 @@ var checkCategorySchema = z54.enum([
|
|
|
18555
18672
|
]);
|
|
18556
18673
|
var CheckCategories = checkCategorySchema.enum;
|
|
18557
18674
|
var CHECK_RUNTIME_ERROR_SUFFIX = ".runtime-error";
|
|
18558
|
-
var checkNotificationPolicySchema =
|
|
18675
|
+
var checkNotificationPolicySchema = z55.enum(["health", "silent"]);
|
|
18559
18676
|
var CheckNotificationPolicies = checkNotificationPolicySchema.enum;
|
|
18560
|
-
var reportMonthSchema =
|
|
18677
|
+
var reportMonthSchema = z55.string().regex(/^[1-9]\d{3}-(0[1-9]|1[0-2])$/, "Expected YYYY-MM");
|
|
18561
18678
|
function reportMonthsForDoctor(reportMonth, now = /* @__PURE__ */ new Date()) {
|
|
18562
18679
|
if (reportMonth !== void 0) return [reportMonthSchema.parse(reportMonth)];
|
|
18563
18680
|
const current = now.toISOString().slice(0, 7);
|
|
@@ -18569,40 +18686,40 @@ function gradedReportMonths(months, now = /* @__PURE__ */ new Date()) {
|
|
|
18569
18686
|
const current = now.toISOString().slice(0, 7);
|
|
18570
18687
|
return new Set(months.length > 1 ? months.filter((month) => month !== current) : months);
|
|
18571
18688
|
}
|
|
18572
|
-
var healthAlertCopySchema =
|
|
18573
|
-
label:
|
|
18574
|
-
line:
|
|
18575
|
-
next:
|
|
18689
|
+
var healthAlertCopySchema = z55.object({
|
|
18690
|
+
label: z55.string().describe(`The problem in a few words, e.g. "Can't reach Google".`),
|
|
18691
|
+
line: z55.string().describe("What happened, in one plain sentence."),
|
|
18692
|
+
next: z55.string().nullable().describe("What to do, in one plain sentence; null when nothing needs doing yet.")
|
|
18576
18693
|
});
|
|
18577
|
-
var checkResultSchema =
|
|
18578
|
-
id:
|
|
18694
|
+
var checkResultSchema = z55.object({
|
|
18695
|
+
id: z55.string(),
|
|
18579
18696
|
category: checkCategorySchema,
|
|
18580
18697
|
scope: checkScopeSchema,
|
|
18581
|
-
title:
|
|
18698
|
+
title: z55.string(),
|
|
18582
18699
|
status: checkStatusSchema,
|
|
18583
18700
|
notificationPolicy: checkNotificationPolicySchema.optional().describe("Health checks page by default. Silent checks (report advisories and standing advisories) remain visible but never affect health alert state."),
|
|
18584
|
-
code:
|
|
18585
|
-
urgent:
|
|
18586
|
-
summary:
|
|
18587
|
-
remediation:
|
|
18588
|
-
details:
|
|
18701
|
+
code: z55.string().describe('Stable machine-readable code (e.g. "google.token.refresh-failed"). Use this for filtering and remediation logic.'),
|
|
18702
|
+
urgent: z55.boolean().optional().describe('True when this result is a problem a person has to act on now (the website is down, daily data stopped arriving, a sync keeps failing). Urgent results are what the health.urgent notification event reports. A result set aside under its failing cause (status "skipped", code "<id>.superseded") keeps the flag: the problem is still open.'),
|
|
18703
|
+
summary: z55.string(),
|
|
18704
|
+
remediation: z55.string().nullable().optional().describe('Operator-facing next step. Null when status is "ok" or no specific remediation applies.'),
|
|
18705
|
+
details: z55.record(z55.string(), z55.unknown()).optional().describe("Structured context \u2014 principal email, redirect URI, missing scopes, etc. Stable per check id."),
|
|
18589
18706
|
alert: healthAlertCopySchema.optional().describe("Plain words a health alert shows for this result. Absent when the check has none; alerts then fall back to the summary."),
|
|
18590
|
-
durationMs:
|
|
18707
|
+
durationMs: z55.number().int().nonnegative().describe("How long the check took to execute.")
|
|
18591
18708
|
});
|
|
18592
|
-
var doctorReportSchema =
|
|
18709
|
+
var doctorReportSchema = z55.object({
|
|
18593
18710
|
scope: checkScopeSchema,
|
|
18594
|
-
project:
|
|
18595
|
-
reportMonths:
|
|
18596
|
-
generatedAt:
|
|
18597
|
-
durationMs:
|
|
18598
|
-
summary:
|
|
18599
|
-
total:
|
|
18600
|
-
ok:
|
|
18601
|
-
warn:
|
|
18602
|
-
fail:
|
|
18603
|
-
skipped:
|
|
18711
|
+
project: z55.string().nullable().describe('Project name when scope is "project", null otherwise.'),
|
|
18712
|
+
reportMonths: z55.array(reportMonthSchema).optional().describe("Calendar months evaluated by project report readiness checks."),
|
|
18713
|
+
generatedAt: z55.string().describe("ISO-8601 timestamp when this doctor run started."),
|
|
18714
|
+
durationMs: z55.number().int().nonnegative(),
|
|
18715
|
+
summary: z55.object({
|
|
18716
|
+
total: z55.number().int().nonnegative(),
|
|
18717
|
+
ok: z55.number().int().nonnegative(),
|
|
18718
|
+
warn: z55.number().int().nonnegative(),
|
|
18719
|
+
fail: z55.number().int().nonnegative(),
|
|
18720
|
+
skipped: z55.number().int().nonnegative()
|
|
18604
18721
|
}),
|
|
18605
|
-
checks:
|
|
18722
|
+
checks: z55.array(checkResultSchema)
|
|
18606
18723
|
});
|
|
18607
18724
|
function summarizeCheckResults(results) {
|
|
18608
18725
|
const summary = { total: results.length, ok: 0, warn: 0, fail: 0, skipped: 0 };
|
|
@@ -18635,8 +18752,8 @@ function groupIsoDateRanges(dates) {
|
|
|
18635
18752
|
}
|
|
18636
18753
|
|
|
18637
18754
|
// ../contracts/src/skills.ts
|
|
18638
|
-
import { z as
|
|
18639
|
-
var codingAgentSchema =
|
|
18755
|
+
import { z as z56 } from "zod";
|
|
18756
|
+
var codingAgentSchema = z56.enum(["claude", "codex"]);
|
|
18640
18757
|
var CodingAgents = codingAgentSchema.enum;
|
|
18641
18758
|
function agentPluginClientLabel(client) {
|
|
18642
18759
|
return client === "claude-code" ? "Claude Code" : "Codex";
|
|
@@ -18660,7 +18777,7 @@ function formatCanonryPluginUpdateHint(clients) {
|
|
|
18660
18777
|
if (names.length === 1) return `Update or reinstall \`canonry@canonry\` in ${names[0]}.`;
|
|
18661
18778
|
return `Update or reinstall \`canonry@canonry\` in ${joinPluginSubjects(names)}.`;
|
|
18662
18779
|
}
|
|
18663
|
-
var skillsClientSchema =
|
|
18780
|
+
var skillsClientSchema = z56.enum(["claude", "codex", "all"]);
|
|
18664
18781
|
var SkillsClients = skillsClientSchema.enum;
|
|
18665
18782
|
var SKILL_MANIFEST_FILENAME = ".canonry-skill-manifest.json";
|
|
18666
18783
|
function classifySkillFile(params) {
|
|
@@ -18677,108 +18794,6 @@ function coerceSkillManifest(parsed) {
|
|
|
18677
18794
|
return null;
|
|
18678
18795
|
}
|
|
18679
18796
|
|
|
18680
|
-
// ../contracts/src/statistics.ts
|
|
18681
|
-
import { z as z56 } from "zod";
|
|
18682
|
-
function round(value, dp = 4) {
|
|
18683
|
-
const f = 10 ** dp;
|
|
18684
|
-
return (Math.round(value * f) + 0) / f;
|
|
18685
|
-
}
|
|
18686
|
-
function roundSignificant(value, sig = 6) {
|
|
18687
|
-
if (!Number.isFinite(value) || value === 0) return 0;
|
|
18688
|
-
const magnitude = Math.ceil(Math.log10(Math.abs(value)));
|
|
18689
|
-
const factor = 10 ** (sig - magnitude);
|
|
18690
|
-
return (Math.round(value * factor) + 0) / factor;
|
|
18691
|
-
}
|
|
18692
|
-
function shareOf(part, total) {
|
|
18693
|
-
if (!Number.isFinite(part) || !Number.isFinite(total)) return null;
|
|
18694
|
-
if (part <= 0) return 0;
|
|
18695
|
-
return total > 0 ? part / total : null;
|
|
18696
|
-
}
|
|
18697
|
-
function breakdownShares(parts) {
|
|
18698
|
-
const total = parts.reduce((sum, part) => sum + Math.max(0, part), 0);
|
|
18699
|
-
return parts.map((part) => shareOf(part, total) ?? 0);
|
|
18700
|
-
}
|
|
18701
|
-
function median(values) {
|
|
18702
|
-
const sorted = values.filter((value) => Number.isFinite(value)).sort((left, right) => left - right);
|
|
18703
|
-
if (sorted.length === 0) return null;
|
|
18704
|
-
const middle = Math.floor(sorted.length / 2);
|
|
18705
|
-
return sorted.length % 2 === 1 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;
|
|
18706
|
-
}
|
|
18707
|
-
function wilsonInterval(successes, n, z97 = 1.96) {
|
|
18708
|
-
if (!Number.isFinite(n) || n <= 0) return null;
|
|
18709
|
-
const s = Math.max(0, Math.min(successes, n));
|
|
18710
|
-
const p = s / n;
|
|
18711
|
-
const z210 = z97 * z97;
|
|
18712
|
-
const denom = 1 + z210 / n;
|
|
18713
|
-
const center = (p + z210 / (2 * n)) / denom;
|
|
18714
|
-
const margin = z97 / denom * Math.sqrt(p * (1 - p) / n + z210 / (4 * n * n));
|
|
18715
|
-
return {
|
|
18716
|
-
low: round(Math.max(0, center - margin)),
|
|
18717
|
-
high: round(Math.min(1, center + margin))
|
|
18718
|
-
};
|
|
18719
|
-
}
|
|
18720
|
-
var linearTrendSchema = z56.object({
|
|
18721
|
-
/** Change in the fitted value per one-index step. */
|
|
18722
|
-
slope: z56.number(),
|
|
18723
|
-
/** Fitted value at index 0. */
|
|
18724
|
-
intercept: z56.number(),
|
|
18725
|
-
/** Coefficient of determination in [0, 1]. `1` for a series with no variance. */
|
|
18726
|
-
r2: z56.number(),
|
|
18727
|
-
/** Fitted value at the first index. */
|
|
18728
|
-
start: z56.number(),
|
|
18729
|
-
/** Fitted value at the last index. */
|
|
18730
|
-
end: z56.number(),
|
|
18731
|
-
/** Count of finite observations the fit used (not the series length). */
|
|
18732
|
-
n: z56.number(),
|
|
18733
|
-
/**
|
|
18734
|
-
* Index of the first observation the fit used, and of the last.
|
|
18735
|
-
*
|
|
18736
|
-
* `start` / `end` are evaluated AT these indices, not at the series' own ends.
|
|
18737
|
-
* A caller drawing the line must span exactly this range: extending it across
|
|
18738
|
-
* leading or trailing indices the metric has no data for draws a fitted claim
|
|
18739
|
-
* over dates that were never measured.
|
|
18740
|
-
*/
|
|
18741
|
-
startIndex: z56.number(),
|
|
18742
|
-
endIndex: z56.number()
|
|
18743
|
-
});
|
|
18744
|
-
function linearTrend(values) {
|
|
18745
|
-
const points = [];
|
|
18746
|
-
for (const [index, value] of values.entries()) {
|
|
18747
|
-
if (typeof value === "number" && Number.isFinite(value)) points.push({ x: index, y: value });
|
|
18748
|
-
}
|
|
18749
|
-
const n = points.length;
|
|
18750
|
-
if (n < 2) return null;
|
|
18751
|
-
const meanX = points.reduce((sum, p) => sum + p.x, 0) / n;
|
|
18752
|
-
const meanY = points.reduce((sum, p) => sum + p.y, 0) / n;
|
|
18753
|
-
let sxx = 0;
|
|
18754
|
-
let sxy = 0;
|
|
18755
|
-
for (const p of points) {
|
|
18756
|
-
sxx += (p.x - meanX) ** 2;
|
|
18757
|
-
sxy += (p.x - meanX) * (p.y - meanY);
|
|
18758
|
-
}
|
|
18759
|
-
const slope = sxy / sxx;
|
|
18760
|
-
const intercept = meanY - slope * meanX;
|
|
18761
|
-
let ssRes = 0;
|
|
18762
|
-
let ssTot = 0;
|
|
18763
|
-
for (const p of points) {
|
|
18764
|
-
ssRes += (p.y - (slope * p.x + intercept)) ** 2;
|
|
18765
|
-
ssTot += (p.y - meanY) ** 2;
|
|
18766
|
-
}
|
|
18767
|
-
const r2 = ssTot === 0 ? 1 : Math.min(1, Math.max(0, 1 - ssRes / ssTot));
|
|
18768
|
-
const firstX = points[0].x;
|
|
18769
|
-
const lastX = points[n - 1].x;
|
|
18770
|
-
return {
|
|
18771
|
-
slope: roundSignificant(slope),
|
|
18772
|
-
intercept: roundSignificant(intercept),
|
|
18773
|
-
r2: round(r2),
|
|
18774
|
-
start: roundSignificant(slope * firstX + intercept),
|
|
18775
|
-
end: roundSignificant(slope * lastX + intercept),
|
|
18776
|
-
n,
|
|
18777
|
-
startIndex: firstX,
|
|
18778
|
-
endIndex: lastX
|
|
18779
|
-
};
|
|
18780
|
-
}
|
|
18781
|
-
|
|
18782
18797
|
// ../contracts/src/traffic.ts
|
|
18783
18798
|
import { z as z57 } from "zod";
|
|
18784
18799
|
var trafficCrawlerSegmentsSchema = z57.object({
|
|
@@ -19332,6 +19347,16 @@ var trafficEventsResponseSchema = z57.object({
|
|
|
19332
19347
|
* early gap, which is the better error than marking real data unmeasured.
|
|
19333
19348
|
*/
|
|
19334
19349
|
coverageStart: z57.string().nullable(),
|
|
19350
|
+
/**
|
|
19351
|
+
* When the selected sources began counting AI-referral arrivals once per
|
|
19352
|
+
* visit, or null when none holds hours counted by the older rule. Hours
|
|
19353
|
+
* before it also counted a visitor's later pages, assets and API calls as
|
|
19354
|
+
* arrivals and read high; stored hourly rows keep no visitor, so they
|
|
19355
|
+
* cannot be recounted. Like `coverageStart`, not bound to the window.
|
|
19356
|
+
* `trends.aiReferralLandedHits` is fitted only over buckets that begin at
|
|
19357
|
+
* or after it. Optional so a newer client reads an older API.
|
|
19358
|
+
*/
|
|
19359
|
+
aiReferralCountingChangedAt: z57.string().nullable().optional(),
|
|
19335
19360
|
/**
|
|
19336
19361
|
* Least-squares fit per charted metric, over the densified points.
|
|
19337
19362
|
*
|
|
@@ -21446,6 +21471,14 @@ var trafficActivitySummarySchema = z66.object({
|
|
|
21446
21471
|
coverageStart: z66.string().nullable(),
|
|
21447
21472
|
/** Recording began on or before the prior window start. This does not establish uninterrupted ingestion. */
|
|
21448
21473
|
priorWindowComplete: z66.boolean(),
|
|
21474
|
+
/**
|
|
21475
|
+
* When the project's sources began counting AI-referral arrivals once per
|
|
21476
|
+
* visit, or null when none holds hours counted by the older rule. Earlier hours
|
|
21477
|
+
* also counted a visitor's later requests and read high, and cannot be
|
|
21478
|
+
* recounted, so referral deltas are null while the prior window starts
|
|
21479
|
+
* before it. Not window-bound. Optional so a newer client reads an older API.
|
|
21480
|
+
*/
|
|
21481
|
+
aiReferralCountingChangedAt: z66.string().nullable().optional(),
|
|
21449
21482
|
hasData: z66.boolean().describe("True when the selected or prior window has stored crawler, user-fetch, countable referral or operator evidence, or the selected window has referral redirects. False means no qualifying stored evidence; it can occur with no, paused, errored or never-synced ingestion and out-of-window observations. It does not establish measured zero traffic or source health."),
|
|
21450
21483
|
/** Verified crawler hits during the selected period and the equal preceding period. */
|
|
21451
21484
|
verifiedCrawlerHits: trafficActivityCountSchema,
|
|
@@ -28311,6 +28344,7 @@ export {
|
|
|
28311
28344
|
GaMoverChangeBases,
|
|
28312
28345
|
gaSocialReferralTrendResponseSchema,
|
|
28313
28346
|
gaAttributionTrendResponseSchema,
|
|
28347
|
+
GA_OVERVIEW_WINDOW_DAYS,
|
|
28314
28348
|
GA_OVERVIEW_WINDOWS,
|
|
28315
28349
|
isGaOverviewWindow,
|
|
28316
28350
|
GA_OVERVIEW_HISTORY_DAYS,
|