@canonry/canonry 7.58.3 → 7.58.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +21 -13
- package/assets/assets/{AgentSetupPage-CRvCLiCD.js → AgentSetupPage-CoD9a386.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-B3qnQtNg.js → MeasurementPropertyPage-BZmvjMiS.js} +1 -1
- package/assets/assets/{ProjectPage-j9V9UFfY.js → ProjectPage-DMIoYBCF.js} +2 -2
- package/assets/assets/{RunsPage-CvqCrsiH.js → RunsPage-DtvesLu2.js} +1 -1
- package/assets/assets/{SettingsPage-CX5Rzsm3.js → SettingsPage-BjE3d5Ae.js} +1 -1
- package/assets/assets/{SiteHealthSection-CYKyJBaJ.js → SiteHealthSection-D6RLbM2o.js} +2 -2
- package/assets/assets/{TrafficPage-DNC0DP-U.js → TrafficPage-CHZlfMgd.js} +1 -1
- package/assets/assets/{index-CQwjYVPD.js → index-CgAMnZFS.js} +5 -5
- package/assets/assets/index-DElT2Fss.css +1 -0
- package/assets/assets/{react-sigma_core.esm.min-BNkIcXRz.js → react-sigma_core.esm.min-TGwpCHs4.js} +1 -1
- package/assets/assets/{service-CWdIU_mf.js → service-CUJkePNp.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{backfill-JAHDHVXJ.js → backfill-SINDWLD3.js} +2 -2
- package/dist/{chunk-2DZYA62C.js → chunk-5D4RL23M.js} +1 -1
- package/dist/{chunk-NMLVLFF7.js → chunk-65YQFVJM.js} +1 -1
- package/dist/{chunk-QFO7JHX2.js → chunk-A5F5E4DL.js} +1 -1
- package/dist/{chunk-BDUHO7KK.js → chunk-AP7YSOFC.js} +14 -14
- package/dist/{chunk-SXGLLWS4.js → chunk-CYVQW32W.js} +7 -5
- package/dist/{chunk-JDRKZOUP.js → chunk-NWYNTYPD.js} +1 -1
- package/dist/{chunk-RXMGU7AF.js → chunk-O6TF6TPM.js} +2 -2
- package/dist/{chunk-NWQQYLZV.js → chunk-QEJBAPDP.js} +195 -100
- package/dist/{cli-commands-3HTHHRXT.js → cli-commands-ZPW3OST3.js} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{dashboard-2P3TEH6S.js → dashboard-VT3GQRW4.js} +1 -1
- package/dist/{demo-TPOKI7ZM.js → demo-ZBNVULOO.js} +1 -1
- package/dist/{demo-server-ZBNKYYM2.js → demo-server-QUW4TDJL.js} +153 -7
- package/dist/index.js +5 -5
- package/dist/{init-4IKMMWAD.js → init-C2DLDK6T.js} +1 -1
- package/dist/{intelligence-service-4PHEK5F4.js → intelligence-service-R5BRSQKI.js} +2 -2
- package/dist/{serve-2AOLGG3F.js → serve-ME2KJ6BG.js} +6 -6
- package/dist/{session-VTFLD3C5.js → session-R3PRJ3RB.js} +3 -3
- package/dist/{tools-LRHO7QOT.js → tools-VZVQ2CTU.js} +2 -2
- package/package.json +1 -1
- package/assets/assets/index-B662I7kR.css +0 -1
|
@@ -59714,7 +59714,7 @@ async function backlinksRoutes(app, opts) {
|
|
|
59714
59714
|
import crypto51 from "crypto";
|
|
59715
59715
|
import { isIP } from "net";
|
|
59716
59716
|
import { isDeepStrictEqual } from "util";
|
|
59717
|
-
import { and as and68, desc as desc38, eq as eq79, gte as gte18, inArray as inArray33, lte as lte19, sql as sql29 } from "drizzle-orm";
|
|
59717
|
+
import { and as and68, desc as desc38, eq as eq79, gt as gt6, gte as gte18, inArray as inArray33, lt as lt12, lte as lte19, sql as sql29 } from "drizzle-orm";
|
|
59718
59718
|
|
|
59719
59719
|
// ../api-routes/src/cloudflare-worker-version.ts
|
|
59720
59720
|
var CURRENT_CLOUDFLARE_WORKER_VERSION = "1.0.1";
|
|
@@ -59723,8 +59723,9 @@ var CURRENT_CLOUDFLARE_WORKER_VERSION = "1.0.1";
|
|
|
59723
59723
|
var VERCEL_MAX_SYNC_WINDOW_MS = 24 * 60 * 6e4;
|
|
59724
59724
|
var DEFAULT_VERCEL_SYNC_DEADLINE_MS = 4 * 6e4;
|
|
59725
59725
|
var CLOUDFLARE_QUEUE_BATCH_SIZE = 100;
|
|
59726
|
-
var
|
|
59727
|
-
var
|
|
59726
|
+
var DEFAULT_CLOUDFLARE_QUEUE_SYNC_DEADLINE_MS = 4 * 6e4;
|
|
59727
|
+
var DEFAULT_CLOUDFLARE_QUEUE_MAX_BATCHES = 300;
|
|
59728
|
+
var CLOUDFLARE_QUEUE_RESIDUAL_WARN_COUNT = 1e3;
|
|
59728
59729
|
var MIN_VERCEL_SYNC_DEADLINE_MS = 3e4;
|
|
59729
59730
|
var MAX_VERCEL_SYNC_DEADLINE_MS = 15 * 6e4;
|
|
59730
59731
|
var TRAFFIC_SOURCE_MAX_CATCHUP_MS = {
|
|
@@ -59737,6 +59738,13 @@ function resolveVercelSyncDeadlineMs(env = process.env) {
|
|
|
59737
59738
|
if (!Number.isFinite(parsed) || parsed <= 0) return void 0;
|
|
59738
59739
|
return Math.min(MAX_VERCEL_SYNC_DEADLINE_MS, Math.max(MIN_VERCEL_SYNC_DEADLINE_MS, Math.trunc(parsed)));
|
|
59739
59740
|
}
|
|
59741
|
+
function resolveCloudflareQueueSyncDeadlineMs(env = process.env) {
|
|
59742
|
+
const raw = env.CANONRY_CLOUDFLARE_QUEUE_SYNC_DEADLINE_MS;
|
|
59743
|
+
if (raw === void 0 || raw.trim() === "") return void 0;
|
|
59744
|
+
const parsed = Number(raw);
|
|
59745
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return void 0;
|
|
59746
|
+
return Math.min(MAX_VERCEL_SYNC_DEADLINE_MS, Math.max(MIN_VERCEL_SYNC_DEADLINE_MS, Math.trunc(parsed)));
|
|
59747
|
+
}
|
|
59740
59748
|
|
|
59741
59749
|
// ../integration-cloud-run/src/auth.ts
|
|
59742
59750
|
import crypto49 from "crypto";
|
|
@@ -60723,8 +60731,11 @@ function resolveOptions(options) {
|
|
|
60723
60731
|
sleep: options.sleep
|
|
60724
60732
|
};
|
|
60725
60733
|
}
|
|
60734
|
+
function queueUrl(options) {
|
|
60735
|
+
return `${options.apiBaseUrl}/accounts/${encodeURIComponent(options.accountId)}/queues/${encodeURIComponent(options.queueId)}`;
|
|
60736
|
+
}
|
|
60726
60737
|
function queueMessagesUrl(options, action) {
|
|
60727
|
-
return `${
|
|
60738
|
+
return `${queueUrl(options)}/messages/${action}`;
|
|
60728
60739
|
}
|
|
60729
60740
|
function requestSignal(timeoutMs, signal) {
|
|
60730
60741
|
const timeout = AbortSignal.timeout(timeoutMs);
|
|
@@ -60768,16 +60779,20 @@ async function withQueueRetry(attempt, options) {
|
|
|
60768
60779
|
throw lastError;
|
|
60769
60780
|
}
|
|
60770
60781
|
async function postJson(options, action, body, signal) {
|
|
60782
|
+
return requestJson(options, { method: "POST", url: queueMessagesUrl(options, action), label: action, body }, signal);
|
|
60783
|
+
}
|
|
60784
|
+
async function requestJson(options, request, signal) {
|
|
60785
|
+
const { label: action } = request;
|
|
60771
60786
|
return withQueueRetry(async () => {
|
|
60772
60787
|
let response;
|
|
60773
60788
|
try {
|
|
60774
|
-
response = await options.fetchImpl(
|
|
60775
|
-
method:
|
|
60789
|
+
response = await options.fetchImpl(request.url, {
|
|
60790
|
+
method: request.method,
|
|
60776
60791
|
headers: {
|
|
60777
60792
|
Authorization: `Bearer ${options.apiToken}`,
|
|
60778
|
-
"Content-Type": "application/json"
|
|
60793
|
+
...request.body ? { "Content-Type": "application/json" } : {}
|
|
60779
60794
|
},
|
|
60780
|
-
body: JSON.stringify(body),
|
|
60795
|
+
...request.body ? { body: JSON.stringify(request.body) } : {},
|
|
60781
60796
|
signal: requestSignal(options.timeoutMs, signal)
|
|
60782
60797
|
});
|
|
60783
60798
|
} catch (error) {
|
|
@@ -60795,7 +60810,10 @@ async function postJson(options, action, body, signal) {
|
|
|
60795
60810
|
}
|
|
60796
60811
|
try {
|
|
60797
60812
|
return await response.json();
|
|
60798
|
-
} catch {
|
|
60813
|
+
} catch (error) {
|
|
60814
|
+
if (isAbortError(error)) {
|
|
60815
|
+
throw new CloudflareQueueApiError("Cloudflare Queue request timed out or was aborted", 408);
|
|
60816
|
+
}
|
|
60799
60817
|
throw new CloudflareQueueApiError(`Cloudflare Queue ${action} returned invalid JSON`, 502);
|
|
60800
60818
|
}
|
|
60801
60819
|
}, {
|
|
@@ -60996,6 +61014,19 @@ function normalizeRetries(retries) {
|
|
|
60996
61014
|
return { leaseId, ...retry.delaySeconds === void 0 ? {} : { delaySeconds: retry.delaySeconds } };
|
|
60997
61015
|
});
|
|
60998
61016
|
}
|
|
61017
|
+
var CLOUDFLARE_QUEUE_MAX_RETENTION_SECONDS = 14 * 24 * 60 * 60;
|
|
61018
|
+
var MIN_RETENTION_SECONDS = 60;
|
|
61019
|
+
var SANITY_MAX_RETENTION_SECONDS = 10 * 365 * 24 * 60 * 60;
|
|
61020
|
+
function recordOrNull(value) {
|
|
61021
|
+
return value != null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
61022
|
+
}
|
|
61023
|
+
async function getCloudflareQueueRetentionSeconds(client, signal) {
|
|
61024
|
+
const resolved = resolveOptions(client);
|
|
61025
|
+
const envelope = recordOrNull(await requestJson(resolved, { method: "GET", url: queueUrl(resolved), label: "read" }, signal));
|
|
61026
|
+
if (envelope?.success !== true) return null;
|
|
61027
|
+
const seconds = recordOrNull(recordOrNull(envelope.result)?.settings)?.message_retention_period;
|
|
61028
|
+
return typeof seconds === "number" && Number.isInteger(seconds) && seconds >= MIN_RETENTION_SECONDS && seconds <= SANITY_MAX_RETENTION_SECONDS ? seconds : null;
|
|
61029
|
+
}
|
|
60999
61030
|
async function pullCloudflareQueueMessages(client, options = {}) {
|
|
61000
61031
|
const resolved = resolveOptions(client);
|
|
61001
61032
|
const body = {};
|
|
@@ -61421,7 +61452,10 @@ var MAX_BACKFILL_DAYS = 90;
|
|
|
61421
61452
|
var BACKFILL_MAX_PAGES = 1e3;
|
|
61422
61453
|
var BACKFILL_SAMPLE_LIMIT = 500;
|
|
61423
61454
|
var CLOUDFLARE_INGEST_BODY_LIMIT = 256 * 1024;
|
|
61424
|
-
var
|
|
61455
|
+
var CLOUDFLARE_QUEUE_RECEIPT_REPLAY_MARGIN_MS = 10 * 6e4;
|
|
61456
|
+
var CLOUDFLARE_QUEUE_RECEIPT_TTL_MS = CLOUDFLARE_QUEUE_MAX_RETENTION_SECONDS * 1e3 + CLOUDFLARE_QUEUE_RECEIPT_REPLAY_MARGIN_MS;
|
|
61457
|
+
var DAY_MS2 = 24 * 60 * 6e4;
|
|
61458
|
+
var CLOUDFLARE_QUEUE_RETENTION_READ_TIMEOUT_MS = 1e4;
|
|
61425
61459
|
var CLOUDFLARE_QUEUE_VISIBILITY_TIMEOUT_MS = 5 * 6e4;
|
|
61426
61460
|
var CLOUDFLARE_QUEUE_SYNC_LEASE_TTL_MS = 5 * 6e4;
|
|
61427
61461
|
var WORDPRESS_SYNC_LEASE_TTL_MS = 5 * 6e4;
|
|
@@ -61440,6 +61474,35 @@ function timingSafeEqualHex(a, b) {
|
|
|
61440
61474
|
const right = Buffer.from(b, "hex");
|
|
61441
61475
|
return left.length === right.length && crypto51.timingSafeEqual(left, right);
|
|
61442
61476
|
}
|
|
61477
|
+
async function loadQueueReceiptPolicy(db, sourceId, readRetentionSeconds, warn2) {
|
|
61478
|
+
let liveTtlMs = null;
|
|
61479
|
+
try {
|
|
61480
|
+
const seconds = await readRetentionSeconds();
|
|
61481
|
+
if (seconds === null) {
|
|
61482
|
+
warn2({}, "Cloudflare reported no usable Queue retention; keeping dedupe receipts for the maximum retention");
|
|
61483
|
+
} else {
|
|
61484
|
+
liveTtlMs = seconds * 1e3 + CLOUDFLARE_QUEUE_RECEIPT_REPLAY_MARGIN_MS;
|
|
61485
|
+
}
|
|
61486
|
+
} catch (error) {
|
|
61487
|
+
warn2(
|
|
61488
|
+
error instanceof CloudflareQueueApiError ? { status: error.status, error: error.message } : { error: "unexpected error" },
|
|
61489
|
+
"Could not read Cloudflare Queue retention; keeping dedupe receipts for the maximum retention"
|
|
61490
|
+
);
|
|
61491
|
+
}
|
|
61492
|
+
if (liveTtlMs === null) return { ttlMsAt: () => CLOUDFLARE_QUEUE_RECEIPT_TTL_MS };
|
|
61493
|
+
const ttlMs = liveTtlMs;
|
|
61494
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
61495
|
+
const alive = and68(eq79(trafficEventReceipts.sourceId, sourceId), gt6(trafficEventReceipts.expiresAt, now));
|
|
61496
|
+
const lifetimeMs = sql29`(julianday(${trafficEventReceipts.expiresAt}) - julianday(${trafficEventReceipts.receivedAt})) * ${DAY_MS2}`;
|
|
61497
|
+
const shortest = db.select({ ms: sql29`min(${lifetimeMs})` }).from(trafficEventReceipts).where(alive).get()?.ms ?? null;
|
|
61498
|
+
if (shortest !== null && shortest < ttlMs - 1e3) {
|
|
61499
|
+
const extended = sql29`strftime('%Y-%m-%dT%H:%M:%fZ', julianday(${trafficEventReceipts.receivedAt}) + ${ttlMs / DAY_MS2})`;
|
|
61500
|
+
db.update(trafficEventReceipts).set({ expiresAt: extended }).where(and68(alive, lt12(trafficEventReceipts.expiresAt, extended))).run();
|
|
61501
|
+
}
|
|
61502
|
+
const floorExpiry = db.select({ at: sql29`max(${trafficEventReceipts.expiresAt})` }).from(trafficEventReceipts).where(and68(alive, sql29`${lifetimeMs} < ${CLOUDFLARE_QUEUE_RECEIPT_TTL_MS - 1e3}`)).get()?.at ?? null;
|
|
61503
|
+
const floorMs = floorExpiry ? Date.parse(floorExpiry) : 0;
|
|
61504
|
+
return { ttlMsAt: (receivedAt) => Math.max(ttlMs, floorMs - Date.parse(receivedAt)) };
|
|
61505
|
+
}
|
|
61443
61506
|
function parseDirectPushCloudflareSourceConfig(config) {
|
|
61444
61507
|
const parsed = cloudflareTrafficSourceConfigSchema.safeParse(config);
|
|
61445
61508
|
return parsed.success && parsed.data.deliveryMode === CloudflareTrafficDeliveryModes["direct-push"] ? parsed.data : null;
|
|
@@ -62139,9 +62202,11 @@ async function trafficRoutes(app, opts) {
|
|
|
62139
62202
|
const pullVercelEvents = opts.pullVercelTrafficEvents ?? listVercelTrafficEvents;
|
|
62140
62203
|
const pullQueueMessages = opts.pullCloudflareQueueMessages ?? pullCloudflareQueueMessages;
|
|
62141
62204
|
const ackQueueMessages = opts.ackCloudflareQueueMessages ?? ackCloudflareQueueMessages;
|
|
62205
|
+
const readQueueRetentionSeconds = opts.getCloudflareQueueRetentionSeconds ?? getCloudflareQueueRetentionSeconds;
|
|
62142
62206
|
const cloudflareQueueMaxBatches = opts.cloudflareQueueMaxBatches ?? DEFAULT_CLOUDFLARE_QUEUE_MAX_BATCHES;
|
|
62143
|
-
|
|
62144
|
-
|
|
62207
|
+
const cloudflareQueueSyncDeadlineMs = opts.cloudflareQueueSyncDeadlineMs ?? DEFAULT_CLOUDFLARE_QUEUE_SYNC_DEADLINE_MS;
|
|
62208
|
+
if (!Number.isInteger(cloudflareQueueMaxBatches) || cloudflareQueueMaxBatches < 1 || cloudflareQueueMaxBatches > 1e3) {
|
|
62209
|
+
throw new RangeError("cloudflareQueueMaxBatches must be an integer from 1 to 1000");
|
|
62145
62210
|
}
|
|
62146
62211
|
const allowLoopback = opts.allowLoopbackWebhooks === true;
|
|
62147
62212
|
let rawSampleRetentionTimer;
|
|
@@ -63054,6 +63119,61 @@ async function trafficRoutes(app, opts) {
|
|
|
63054
63119
|
const runId = crypto51.randomUUID();
|
|
63055
63120
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
63056
63121
|
const startedMs = Date.now();
|
|
63122
|
+
let acceptedEvents = 0;
|
|
63123
|
+
let selfTrafficExcluded = 0;
|
|
63124
|
+
let crawlerHits = 0;
|
|
63125
|
+
let aiUserFetchHits = 0;
|
|
63126
|
+
let aiReferralHits = 0;
|
|
63127
|
+
let unknownHits = 0;
|
|
63128
|
+
let crawlerBucketRows = 0;
|
|
63129
|
+
let aiUserFetchBucketRows = 0;
|
|
63130
|
+
let aiReferralBucketRows = 0;
|
|
63131
|
+
let sampleRows = 0;
|
|
63132
|
+
let committedAt = startedAt;
|
|
63133
|
+
let remainingBacklogCount = 0;
|
|
63134
|
+
let completedBatches = 0;
|
|
63135
|
+
const finishSync = (status, error) => {
|
|
63136
|
+
app.db.update(runs).set({ status, finishedAt: committedAt, ...error ? { error } : {} }).where(eq79(runs.id, runId)).run();
|
|
63137
|
+
writeAuditLog(app.db, {
|
|
63138
|
+
projectId: project.id,
|
|
63139
|
+
actor: "api",
|
|
63140
|
+
action: "traffic.cloudflare.queue-synced",
|
|
63141
|
+
entityType: "traffic_source",
|
|
63142
|
+
entityId: sourceRow2.id
|
|
63143
|
+
});
|
|
63144
|
+
try {
|
|
63145
|
+
opts.onTrafficSynced?.({
|
|
63146
|
+
status: "completed",
|
|
63147
|
+
sourceType: sourceRow2.sourceType,
|
|
63148
|
+
sourceId: sourceRow2.id,
|
|
63149
|
+
pulledEvents: acceptedEvents,
|
|
63150
|
+
selfTrafficExcluded,
|
|
63151
|
+
crawlerHits,
|
|
63152
|
+
aiUserFetchHits,
|
|
63153
|
+
aiReferralHits,
|
|
63154
|
+
durationMs: Date.now() - startedMs
|
|
63155
|
+
});
|
|
63156
|
+
} catch {
|
|
63157
|
+
}
|
|
63158
|
+
return {
|
|
63159
|
+
sourceId: sourceRow2.id,
|
|
63160
|
+
runId,
|
|
63161
|
+
syncedAt: committedAt,
|
|
63162
|
+
pulledEvents: acceptedEvents,
|
|
63163
|
+
selfTrafficExcluded,
|
|
63164
|
+
crawlerHits,
|
|
63165
|
+
aiUserFetchHits,
|
|
63166
|
+
aiReferralHits,
|
|
63167
|
+
unknownHits,
|
|
63168
|
+
crawlerBucketRows,
|
|
63169
|
+
aiUserFetchBucketRows,
|
|
63170
|
+
aiReferralBucketRows,
|
|
63171
|
+
sampleRows,
|
|
63172
|
+
remainingBacklogCount,
|
|
63173
|
+
windowStart: startedAt,
|
|
63174
|
+
windowEnd: committedAt
|
|
63175
|
+
};
|
|
63176
|
+
};
|
|
63057
63177
|
try {
|
|
63058
63178
|
app.db.insert(runs).values({
|
|
63059
63179
|
id: runId,
|
|
@@ -63065,20 +63185,17 @@ async function trafficRoutes(app, opts) {
|
|
|
63065
63185
|
startedAt,
|
|
63066
63186
|
createdAt: startedAt
|
|
63067
63187
|
}).run();
|
|
63068
|
-
let acceptedEvents = 0;
|
|
63069
|
-
let selfTrafficExcluded = 0;
|
|
63070
|
-
let crawlerHits = 0;
|
|
63071
|
-
let aiUserFetchHits = 0;
|
|
63072
|
-
let aiReferralHits = 0;
|
|
63073
|
-
let unknownHits = 0;
|
|
63074
|
-
let crawlerBucketRows = 0;
|
|
63075
|
-
let aiUserFetchBucketRows = 0;
|
|
63076
|
-
let aiReferralBucketRows = 0;
|
|
63077
|
-
let sampleRows = 0;
|
|
63078
|
-
let committedAt = startedAt;
|
|
63079
|
-
let remainingBacklogCount = 0;
|
|
63080
63188
|
const canonicalHost = resolveCloudflareWorkerRouteHost(project.canonicalDomain);
|
|
63081
|
-
|
|
63189
|
+
const drainDeadlineMs = startedMs + cloudflareQueueSyncDeadlineMs;
|
|
63190
|
+
let consecutiveEmptyPulls = 0;
|
|
63191
|
+
let receiptPolicy = null;
|
|
63192
|
+
const resolveReceiptPolicy = () => receiptPolicy ??= loadQueueReceiptPolicy(
|
|
63193
|
+
app.db,
|
|
63194
|
+
sourceRow2.id,
|
|
63195
|
+
() => readQueueRetentionSeconds({ ...queueClient, maxRetries: 0, timeoutMs: CLOUDFLARE_QUEUE_RETENTION_READ_TIMEOUT_MS }),
|
|
63196
|
+
(fields, message) => request.log.warn({ sourceId: sourceRow2.id, ...fields }, message)
|
|
63197
|
+
);
|
|
63198
|
+
for (let batch = 0; batch < cloudflareQueueMaxBatches && (batch === 0 || Date.now() < drainDeadlineMs); batch += 1) {
|
|
63082
63199
|
if (!tryClaimTrafficSyncLease({
|
|
63083
63200
|
db: app.db,
|
|
63084
63201
|
sourceId: sourceRow2.id,
|
|
@@ -63144,6 +63261,7 @@ async function trafficRoutes(app, opts) {
|
|
|
63144
63261
|
}
|
|
63145
63262
|
validLeases.push(message.leaseId);
|
|
63146
63263
|
}
|
|
63264
|
+
const policy = normalized.length > 0 ? await resolveReceiptPolicy() : null;
|
|
63147
63265
|
committedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
63148
63266
|
const writeResult = writeTrafficEventBatch({
|
|
63149
63267
|
db: app.db,
|
|
@@ -63151,7 +63269,7 @@ async function trafficRoutes(app, opts) {
|
|
|
63151
63269
|
sourceId: sourceRow2.id,
|
|
63152
63270
|
events: normalized,
|
|
63153
63271
|
receivedAt: committedAt,
|
|
63154
|
-
receiptTtlMs: CLOUDFLARE_QUEUE_RECEIPT_TTL_MS,
|
|
63272
|
+
receiptTtlMs: policy ? policy.ttlMsAt(committedAt) : CLOUDFLARE_QUEUE_RECEIPT_TTL_MS,
|
|
63155
63273
|
sampleLimit,
|
|
63156
63274
|
validateSource: (latest) => {
|
|
63157
63275
|
if (!latest || latest.projectId !== project.id || latest.status !== TrafficSourceStatuses.connected || latest.syncLeaseOwner !== leaseOwner || !isDeepStrictEqual(latest.configJson, sourceRow2.configJson)) {
|
|
@@ -63198,53 +63316,27 @@ async function trafficRoutes(app, opts) {
|
|
|
63198
63316
|
aiUserFetchBucketRows += writeResult.aiUserFetchBucketRows;
|
|
63199
63317
|
aiReferralBucketRows += writeResult.aiReferralBucketRows;
|
|
63200
63318
|
sampleRows += writeResult.sampleRows;
|
|
63201
|
-
|
|
63202
|
-
if (
|
|
63203
|
-
|
|
63204
|
-
|
|
63205
|
-
|
|
63206
|
-
|
|
63207
|
-
|
|
63208
|
-
|
|
63209
|
-
|
|
63210
|
-
entityId: sourceRow2.id
|
|
63211
|
-
});
|
|
63212
|
-
try {
|
|
63213
|
-
opts.onTrafficSynced?.({
|
|
63214
|
-
status: "completed",
|
|
63215
|
-
sourceType: sourceRow2.sourceType,
|
|
63216
|
-
sourceId: sourceRow2.id,
|
|
63217
|
-
pulledEvents: acceptedEvents,
|
|
63218
|
-
selfTrafficExcluded,
|
|
63219
|
-
crawlerHits,
|
|
63220
|
-
aiUserFetchHits,
|
|
63221
|
-
aiReferralHits,
|
|
63222
|
-
durationMs: Date.now() - startedMs
|
|
63223
|
-
});
|
|
63224
|
-
} catch {
|
|
63319
|
+
completedBatches += 1;
|
|
63320
|
+
if (remainingBacklogCount === 0) break;
|
|
63321
|
+
if (pulled.messages.length === 0) {
|
|
63322
|
+
if (pulled.skippedUnleasedMessageCount > 0 && pulled.skippedUnleasedMessageCount < CLOUDFLARE_QUEUE_BATCH_SIZE) break;
|
|
63323
|
+
consecutiveEmptyPulls = pulled.skippedUnleasedMessageCount === 0 ? consecutiveEmptyPulls + 1 : 0;
|
|
63324
|
+
if (consecutiveEmptyPulls >= 2) break;
|
|
63325
|
+
} else {
|
|
63326
|
+
consecutiveEmptyPulls = 0;
|
|
63327
|
+
}
|
|
63225
63328
|
}
|
|
63226
|
-
|
|
63227
|
-
sourceId: sourceRow2.id,
|
|
63228
|
-
runId,
|
|
63229
|
-
syncedAt: committedAt,
|
|
63230
|
-
pulledEvents: acceptedEvents,
|
|
63231
|
-
selfTrafficExcluded,
|
|
63232
|
-
crawlerHits,
|
|
63233
|
-
aiUserFetchHits,
|
|
63234
|
-
aiReferralHits,
|
|
63235
|
-
unknownHits,
|
|
63236
|
-
crawlerBucketRows,
|
|
63237
|
-
aiUserFetchBucketRows,
|
|
63238
|
-
aiReferralBucketRows,
|
|
63239
|
-
sampleRows,
|
|
63240
|
-
remainingBacklogCount,
|
|
63241
|
-
windowStart: startedAt,
|
|
63242
|
-
windowEnd: committedAt
|
|
63243
|
-
};
|
|
63244
|
-
return response;
|
|
63329
|
+
return finishSync(RunStatuses.completed, null);
|
|
63245
63330
|
} catch (error) {
|
|
63246
63331
|
const failedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
63247
63332
|
const safeError = error instanceof CloudflareQueueApiError ? error.message : "Cloudflare Queue sync failed; retry the active source.";
|
|
63333
|
+
if (completedBatches > 0) {
|
|
63334
|
+
request.log.warn(
|
|
63335
|
+
{ sourceId: sourceRow2.id, completedBatches, error: safeError },
|
|
63336
|
+
"Cloudflare Queue sync stopped after saving some batches"
|
|
63337
|
+
);
|
|
63338
|
+
return finishSync(RunStatuses.partial, safeError);
|
|
63339
|
+
}
|
|
63248
63340
|
try {
|
|
63249
63341
|
opts.onTrafficSynced?.({
|
|
63250
63342
|
status: "failed",
|
|
@@ -65907,7 +65999,7 @@ var GSC_DATA_STALE_DAYS = 7;
|
|
|
65907
65999
|
var SYNC_IDLE_DAYS = 3;
|
|
65908
66000
|
var NOT_SYNCING_URGENT_DAYS = 8;
|
|
65909
66001
|
var GSC_REPORTING_TIME_ZONE2 = "America/Los_Angeles";
|
|
65910
|
-
var
|
|
66002
|
+
var DAY_MS3 = 24 * 60 * 60 * 1e3;
|
|
65911
66003
|
var ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
65912
66004
|
function utcFromIsoDate(date) {
|
|
65913
66005
|
const match = ISO_DATE.exec(date);
|
|
@@ -65918,7 +66010,7 @@ function daysBetweenIsoDates(from, to) {
|
|
|
65918
66010
|
const start = utcFromIsoDate(from);
|
|
65919
66011
|
const end = utcFromIsoDate(to);
|
|
65920
66012
|
if (start === null || end === null) return null;
|
|
65921
|
-
return Math.floor((end - start) /
|
|
66013
|
+
return Math.floor((end - start) / DAY_MS3);
|
|
65922
66014
|
}
|
|
65923
66015
|
function daysSinceDate(date, now = /* @__PURE__ */ new Date(), timeZone) {
|
|
65924
66016
|
const today = timeZone ? formatIsoDateInTimeZone(now.toISOString(), timeZone) : `${now.getUTCFullYear()}-${String(now.getUTCMonth() + 1).padStart(2, "0")}-${String(now.getUTCDate()).padStart(2, "0")}`;
|
|
@@ -65930,7 +66022,7 @@ function skipped(code, summary3) {
|
|
|
65930
66022
|
function lastSyncAgeDays(ctx, kinds) {
|
|
65931
66023
|
const row = ctx.db.select({ createdAt: runs.createdAt }).from(runs).where(and73(eq87(runs.projectId, ctx.project.id), inArray36(runs.kind, kinds), eq87(runs.status, "completed"))).orderBy(desc40(runs.createdAt)).limit(1).get();
|
|
65932
66024
|
if (!row?.createdAt) return null;
|
|
65933
|
-
const age = Math.floor((Date.now() - Date.parse(row.createdAt)) /
|
|
66025
|
+
const age = Math.floor((Date.now() - Date.parse(row.createdAt)) / DAY_MS3);
|
|
65934
66026
|
return Number.isFinite(age) ? age : null;
|
|
65935
66027
|
}
|
|
65936
66028
|
function grade(ctx, spec, newestDate) {
|
|
@@ -66423,7 +66515,7 @@ async function probeApiHost(host, options = {}) {
|
|
|
66423
66515
|
}
|
|
66424
66516
|
|
|
66425
66517
|
// ../api-routes/src/doctor/checks/integration-sync.ts
|
|
66426
|
-
import { and as and74, count as count6, desc as desc41, eq as eq88, gte as gte21, gt as
|
|
66518
|
+
import { and as and74, count as count6, desc as desc41, eq as eq88, gte as gte21, gt as gt7, inArray as inArray37, isNull as isNull14, notInArray as notInArray3, or as or19 } from "drizzle-orm";
|
|
66427
66519
|
var SYNC_FAILURE_WINDOW = 3;
|
|
66428
66520
|
var SUMMARY_ERROR_LIMIT = 300;
|
|
66429
66521
|
var FINISHED_STATUSES = [RunStatuses.completed, RunStatuses.partial, RunStatuses.failed];
|
|
@@ -66518,7 +66610,7 @@ function readSyncRunState(db, projectId, kind, options = {}) {
|
|
|
66518
66610
|
const graded = options.since ? and74(scope, gte21(runs.createdAt, options.since)) : scope;
|
|
66519
66611
|
const recent = db.select({ id: runs.id, status: runs.status, trigger: runs.trigger, error: runs.error, createdAt: runs.createdAt }).from(runs).where(and74(graded, inArray37(runs.status, FINISHED_STATUSES))).orderBy(desc41(runs.createdAt)).limit(SYNC_FAILURE_WINDOW).all();
|
|
66520
66612
|
const lastSuccess = db.select({ createdAt: runs.createdAt, finishedAt: runs.finishedAt }).from(runs).where(and74(graded, inArray37(runs.status, SUCCESS_STATUSES))).orderBy(desc41(runs.createdAt)).limit(1).get();
|
|
66521
|
-
const failureCount = db.select({ count: count6() }).from(runs).where(and74(lastSuccess ? and74(graded,
|
|
66613
|
+
const failureCount = db.select({ count: count6() }).from(runs).where(and74(lastSuccess ? and74(graded, gt7(runs.createdAt, lastSuccess.createdAt)) : graded, eq88(runs.status, RunStatuses.failed))).get();
|
|
66522
66614
|
const failuresSinceSuccess = Number(failureCount?.count ?? 0);
|
|
66523
66615
|
const latest = recent[0];
|
|
66524
66616
|
return {
|
|
@@ -68353,12 +68445,12 @@ var queueBacklogCheck = {
|
|
|
68353
68445
|
}
|
|
68354
68446
|
const remaining = measured.filter((source) => (source.queueBacklogCount ?? 0) > 0);
|
|
68355
68447
|
const total = remaining.reduce((sum, source) => sum + source.queueBacklogCount, 0);
|
|
68356
|
-
if (total >
|
|
68448
|
+
if (total > CLOUDFLARE_QUEUE_RESIDUAL_WARN_COUNT) {
|
|
68357
68449
|
return {
|
|
68358
68450
|
status: CheckStatuses.warn,
|
|
68359
68451
|
code: "traffic.queue-backlog.remaining",
|
|
68360
|
-
summary: `${total.toLocaleString("en-US")} message(s) remained across ${remaining.length} Cloudflare Queue source(s) after the last
|
|
68361
|
-
remediation: "
|
|
68452
|
+
summary: `${total.toLocaleString("en-US")} message(s) remained across ${remaining.length} Cloudflare Queue source(s) after the last sync, more than the ${CLOUDFLARE_QUEUE_RESIDUAL_WARN_COUNT.toLocaleString("en-US")} that can arrive while a drain runs. The drain stopped at its time limit or pull cap before the Queue was empty.`,
|
|
68453
|
+
remediation: "If the backlog keeps growing, messages will pass the Queue's retention and be dropped. Shorten the traffic-sync schedule interval, or raise `CANONRY_CLOUDFLARE_QUEUE_SYNC_DEADLINE_MS` (default 4 minutes per sync).",
|
|
68362
68454
|
details
|
|
68363
68455
|
};
|
|
68364
68456
|
}
|
|
@@ -68366,8 +68458,8 @@ var queueBacklogCheck = {
|
|
|
68366
68458
|
return {
|
|
68367
68459
|
status: CheckStatuses.ok,
|
|
68368
68460
|
code: "traffic.queue-backlog.within-drain-budget",
|
|
68369
|
-
summary: `${total.toLocaleString("en-US")} message(s) remained after the last
|
|
68370
|
-
remediation: "
|
|
68461
|
+
summary: `${total.toLocaleString("en-US")} message(s) remained after the last sync, within the ${CLOUDFLARE_QUEUE_RESIDUAL_WARN_COUNT.toLocaleString("en-US")} that can arrive while a drain runs.`,
|
|
68462
|
+
remediation: "The next scheduled sync drains these. Run `canonry traffic sync <project> --source <id>` to drain them sooner.",
|
|
68371
68463
|
details
|
|
68372
68464
|
};
|
|
68373
68465
|
}
|
|
@@ -68529,7 +68621,7 @@ var GTM_REQUIRED_OAUTH_SCOPES = [
|
|
|
68529
68621
|
];
|
|
68530
68622
|
var FRESH_SNAPSHOT_WARN_DAYS = 7;
|
|
68531
68623
|
var FRESH_SNAPSHOT_FAIL_DAYS = 30;
|
|
68532
|
-
var
|
|
68624
|
+
var DAY_MS4 = 24 * 60 * 60 * 1e3;
|
|
68533
68625
|
function unavailableStatus() {
|
|
68534
68626
|
return {
|
|
68535
68627
|
status: CheckStatuses.skipped,
|
|
@@ -68616,7 +68708,7 @@ function snapshotOutput(provider, latestSnapshotAt, now) {
|
|
|
68616
68708
|
details: { latestSnapshotAt }
|
|
68617
68709
|
};
|
|
68618
68710
|
}
|
|
68619
|
-
const ageDays2 = (now.getTime() - snapshotMs) /
|
|
68711
|
+
const ageDays2 = (now.getTime() - snapshotMs) / DAY_MS4;
|
|
68620
68712
|
const details = { latestSnapshotAt, ageDays: Math.max(0, Math.round(ageDays2)) };
|
|
68621
68713
|
if (ageDays2 < 0) {
|
|
68622
68714
|
return {
|
|
@@ -69925,12 +70017,12 @@ function dedupeStrings(input) {
|
|
|
69925
70017
|
|
|
69926
70018
|
// ../api-routes/src/technical-aeo.ts
|
|
69927
70019
|
import crypto55 from "crypto";
|
|
69928
|
-
import { and as and81, asc as asc20, count as count7, desc as desc45, eq as eq98, gte as gte25, inArray as inArray41, isNotNull as isNotNull9, isNull as isNull17, lt as
|
|
70020
|
+
import { and as and81, asc as asc20, count as count7, desc as desc45, eq as eq98, gte as gte25, inArray as inArray41, isNotNull as isNotNull9, isNull as isNull17, lt as lt13, or as or21, sql as sql33 } from "drizzle-orm";
|
|
69929
70021
|
import { alias } from "drizzle-orm/sqlite-core";
|
|
69930
70022
|
|
|
69931
70023
|
// ../api-routes/src/technical-aeo-issues.ts
|
|
69932
70024
|
import { createHash as createHash10 } from "crypto";
|
|
69933
|
-
import { and as and80, asc as asc19, eq as eq97, gt as
|
|
70025
|
+
import { and as and80, asc as asc19, eq as eq97, gt as gt8, sql as sql32 } from "drizzle-orm";
|
|
69934
70026
|
var ADVISORY_CODES = /* @__PURE__ */ new Set([
|
|
69935
70027
|
"entity-consistency.title.short",
|
|
69936
70028
|
"site.duplicate-title",
|
|
@@ -70091,7 +70183,7 @@ function readSiteAuditIssues(input) {
|
|
|
70091
70183
|
url: siteCrawlPages.url,
|
|
70092
70184
|
auditScore: siteCrawlPages.auditScore,
|
|
70093
70185
|
auditFields: siteCrawlPages.auditFields
|
|
70094
|
-
}).from(siteCrawlPages).where(and80(scope, after === void 0 ? void 0 :
|
|
70186
|
+
}).from(siteCrawlPages).where(and80(scope, after === void 0 ? void 0 : gt8(siteCrawlPages.nodeKey, after))).orderBy(asc19(siteCrawlPages.nodeKey)).limit(200).all();
|
|
70095
70187
|
for (const page3 of pages) {
|
|
70096
70188
|
evidenceHash.update(JSON.stringify(page3));
|
|
70097
70189
|
const fields = record(page3.auditFields);
|
|
@@ -70581,11 +70673,11 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
70581
70673
|
};
|
|
70582
70674
|
const resolveCrawl = (projectId, runId, requestedDate, scope = {}) => {
|
|
70583
70675
|
const filters = visibleCrawlFilters(projectId);
|
|
70584
|
-
if (scope.recordedBefore) filters.push(
|
|
70676
|
+
if (scope.recordedBefore) filters.push(lt13(siteCrawlSnapshots.createdAt, scope.recordedBefore));
|
|
70585
70677
|
if (requestedDate) {
|
|
70586
70678
|
const nextDate2 = /* @__PURE__ */ new Date(`${requestedDate}T00:00:00.000Z`);
|
|
70587
70679
|
nextDate2.setUTCDate(nextDate2.getUTCDate() + 1);
|
|
70588
|
-
filters.push(gte25(siteCrawlSnapshots.createdAt, requestedDate),
|
|
70680
|
+
filters.push(gte25(siteCrawlSnapshots.createdAt, requestedDate), lt13(siteCrawlSnapshots.createdAt, nextDate2.toISOString()));
|
|
70589
70681
|
}
|
|
70590
70682
|
const selectionFilters = scope.scoredOnly ? [...filters, sql33`exists (select 1 from ${siteAuditSnapshots} where ${siteAuditSnapshots.projectId} = ${siteCrawlSnapshots.projectId} and ${siteAuditSnapshots.runId} = ${siteCrawlSnapshots.runId})`] : filters;
|
|
70591
70683
|
const selected = app.db.select({ snapshot: siteCrawlSnapshots, runStatus: runs.status }).from(siteCrawlSnapshots).innerJoin(runs, eq98(siteCrawlSnapshots.runId, runs.id)).where(and81(...selectionFilters, runId ? eq98(siteCrawlSnapshots.runId, runId) : void 0)).orderBy(
|
|
@@ -70602,7 +70694,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
70602
70694
|
const sameDate = and81(
|
|
70603
70695
|
...filters,
|
|
70604
70696
|
gte25(siteCrawlSnapshots.createdAt, date),
|
|
70605
|
-
|
|
70697
|
+
lt13(siteCrawlSnapshots.createdAt, nextDate.toISOString())
|
|
70606
70698
|
);
|
|
70607
70699
|
const sameDateRunCount = app.db.select({ value: count7() }).from(siteCrawlSnapshots).innerJoin(runs, eq98(siteCrawlSnapshots.runId, runs.id)).where(sameDate).get()?.value ?? 0;
|
|
70608
70700
|
const candidates = app.db.select({
|
|
@@ -70633,7 +70725,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
70633
70725
|
eq98(runs.kind, RunKinds["site-audit"]),
|
|
70634
70726
|
inArray41(runs.status, SURFACEABLE_STATUSES),
|
|
70635
70727
|
notProbeRun(),
|
|
70636
|
-
...recordedBefore ? [
|
|
70728
|
+
...recordedBefore ? [lt13(siteAuditSnapshots.createdAt, recordedBefore)] : []
|
|
70637
70729
|
];
|
|
70638
70730
|
const complete = sql33`case when ${runs.status} = ${RunStatuses.completed} then 1 else 0 end`;
|
|
70639
70731
|
const selectAudit = (pinnedRunId) => app.db.select({ snap: siteAuditSnapshots, runStatus: runs.status }).from(siteAuditSnapshots).innerJoin(runs, eq98(siteAuditSnapshots.runId, runs.id)).where(and81(...filters, pinnedRunId ? eq98(siteAuditSnapshots.runId, pinnedRunId) : void 0)).orderBy(
|
|
@@ -70660,7 +70752,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
70660
70752
|
const sameDate = and81(
|
|
70661
70753
|
...filters,
|
|
70662
70754
|
gte25(siteAuditSnapshots.createdAt, date),
|
|
70663
|
-
|
|
70755
|
+
lt13(siteAuditSnapshots.createdAt, nextDate.toISOString())
|
|
70664
70756
|
);
|
|
70665
70757
|
const sameDateRunCount = app.db.select({ value: count7() }).from(siteAuditSnapshots).innerJoin(runs, eq98(siteAuditSnapshots.runId, runs.id)).where(sameDate).get()?.value ?? 0;
|
|
70666
70758
|
const candidates = app.db.select({
|
|
@@ -71099,7 +71191,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
71099
71191
|
eq98(siteCrawlPages.runId, siteCrawlGraphNodes.runId),
|
|
71100
71192
|
eq98(siteCrawlPages.attemptId, siteCrawlGraphNodes.attemptId),
|
|
71101
71193
|
eq98(siteCrawlPages.nodeKey, siteCrawlGraphNodes.nodeKey)
|
|
71102
|
-
)).where(and81(...graphScope,
|
|
71194
|
+
)).where(and81(...graphScope, lt13(siteCrawlGraphNodes.sampleRank, maxNodes))).orderBy(asc20(siteCrawlGraphNodes.sampleRank)).all();
|
|
71103
71195
|
const nodes = nodeRows.map(({ indexabilityReasons, canonicalNodeKey, ...row }) => ({
|
|
71104
71196
|
...row,
|
|
71105
71197
|
healthState: deriveSiteHealthState({ ...row, indexabilityReasons, canonicalNodeKey }),
|
|
@@ -71118,18 +71210,18 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
71118
71210
|
eq98(graphSourceNode.runId, siteCrawlGraphEdges.runId),
|
|
71119
71211
|
eq98(graphSourceNode.attemptId, siteCrawlGraphEdges.attemptId),
|
|
71120
71212
|
eq98(graphSourceNode.nodeKey, siteCrawlGraphEdges.sourceNodeKey),
|
|
71121
|
-
|
|
71213
|
+
lt13(graphSourceNode.sampleRank, maxNodes)
|
|
71122
71214
|
)).innerJoin(graphTargetNode, and81(
|
|
71123
71215
|
eq98(graphTargetNode.projectId, siteCrawlGraphEdges.projectId),
|
|
71124
71216
|
eq98(graphTargetNode.runId, siteCrawlGraphEdges.runId),
|
|
71125
71217
|
eq98(graphTargetNode.attemptId, siteCrawlGraphEdges.attemptId),
|
|
71126
71218
|
eq98(graphTargetNode.nodeKey, siteCrawlGraphEdges.targetNodeKey),
|
|
71127
|
-
|
|
71219
|
+
lt13(graphTargetNode.sampleRank, maxNodes)
|
|
71128
71220
|
)).where(and81(
|
|
71129
71221
|
eq98(siteCrawlGraphEdges.projectId, project.id),
|
|
71130
71222
|
eq98(siteCrawlGraphEdges.runId, snapshot.runId),
|
|
71131
71223
|
eq98(siteCrawlGraphEdges.attemptId, snapshot.attemptId),
|
|
71132
|
-
|
|
71224
|
+
lt13(siteCrawlGraphEdges.sampleRank, maxEdges),
|
|
71133
71225
|
graphLinkKindFilter
|
|
71134
71226
|
)).orderBy(asc20(siteCrawlGraphEdges.sampleRank)).all();
|
|
71135
71227
|
const totalNodes = persistedLayout.totalNodes;
|
|
@@ -71473,10 +71565,10 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
71473
71565
|
const beforeTarget = request.query.fromRunId ? resolveCrawl(project.id, request.query.fromRunId) : afterTarget ? app.db.select({ snapshot: siteCrawlSnapshots, runStatus: runs.status }).from(siteCrawlSnapshots).innerJoin(runs, eq98(siteCrawlSnapshots.runId, runs.id)).where(and81(
|
|
71474
71566
|
...completeSnapshotFilters,
|
|
71475
71567
|
or21(
|
|
71476
|
-
|
|
71568
|
+
lt13(siteCrawlSnapshots.createdAt, afterTarget.snapshot.createdAt),
|
|
71477
71569
|
and81(
|
|
71478
71570
|
eq98(siteCrawlSnapshots.createdAt, afterTarget.snapshot.createdAt),
|
|
71479
|
-
|
|
71571
|
+
lt13(siteCrawlSnapshots.runId, afterTarget.snapshot.runId)
|
|
71480
71572
|
)
|
|
71481
71573
|
)
|
|
71482
71574
|
)).orderBy(desc45(siteCrawlSnapshots.createdAt), desc45(siteCrawlSnapshots.runId)).limit(1).get() : void 0;
|
|
@@ -72361,7 +72453,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
72361
72453
|
}).from(siteCrawlPages).where(and81(
|
|
72362
72454
|
auditedWhere,
|
|
72363
72455
|
isNotNull9(siteCrawlPages.auditScore),
|
|
72364
|
-
|
|
72456
|
+
lt13(siteCrawlPages.auditScore, 70)
|
|
72365
72457
|
)).orderBy(asc20(siteCrawlPages.auditScore), asc20(siteCrawlPages.nodeKey)).limit(LIVE_PAGE_HEALTH_CANDIDATE_LIMIT).all();
|
|
72366
72458
|
const examples = candidates.flatMap((candidate) => {
|
|
72367
72459
|
if (candidate.auditScore == null) return [];
|
|
@@ -72456,7 +72548,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
72456
72548
|
// ../api-routes/src/research.ts
|
|
72457
72549
|
import crypto56 from "crypto";
|
|
72458
72550
|
import { z as z6 } from "zod";
|
|
72459
|
-
import { and as and82, count as count8, desc as desc46, eq as eq99, gte as gte26, lt as
|
|
72551
|
+
import { and as and82, count as count8, desc as desc46, eq as eq99, gte as gte26, lt as lt14, or as or22, sql as sql34 } from "drizzle-orm";
|
|
72460
72552
|
var sameLocation = (a, b) => a.label === b.label && a.city === b.city && a.region === b.region && a.country === b.country && a.timezone === b.timezone;
|
|
72461
72553
|
var BATCH_RECEIPT_PREFIX = "__canonry_research_batch__:";
|
|
72462
72554
|
async function researchRoutes(app, opts) {
|
|
@@ -72521,7 +72613,7 @@ async function researchRoutes(app, opts) {
|
|
|
72521
72613
|
const used = tx.select({ value: count8() }).from(researchRuns).where(and82(
|
|
72522
72614
|
eq99(researchRuns.projectId, project.id),
|
|
72523
72615
|
gte26(researchRuns.createdAt, start),
|
|
72524
|
-
|
|
72616
|
+
lt14(researchRuns.createdAt, end),
|
|
72525
72617
|
sql34`(json_extract(${researchRuns.initiatedBy}, '$.role') = ${UserRoles.viewer} OR json_extract(${researchRuns.initiatedBy}, '$.limited') = 1)`
|
|
72526
72618
|
)).get()?.value ?? 0;
|
|
72527
72619
|
if (used >= viewerDailyRunLimit) {
|
|
@@ -72577,7 +72669,7 @@ async function researchRoutes(app, opts) {
|
|
|
72577
72669
|
const used = tx.select({ value: count8() }).from(researchRuns).where(and82(
|
|
72578
72670
|
eq99(researchRuns.projectId, project.id),
|
|
72579
72671
|
gte26(researchRuns.createdAt, start),
|
|
72580
|
-
|
|
72672
|
+
lt14(researchRuns.createdAt, end),
|
|
72581
72673
|
sql34`(json_extract(${researchRuns.initiatedBy}, '$.role') = ${UserRoles.viewer} OR json_extract(${researchRuns.initiatedBy}, '$.limited') = 1)`
|
|
72582
72674
|
)).get()?.value ?? 0;
|
|
72583
72675
|
if (used + prepared.length > viewerDailyRunLimit) throw researchDailyLimitExceeded(project.name, viewerDailyRunLimit, date);
|
|
@@ -72631,7 +72723,7 @@ async function researchRoutes(app, opts) {
|
|
|
72631
72723
|
const cursor = request.query.cursor ? parseResearchCursor(request.query.cursor, project.id) : null;
|
|
72632
72724
|
const rows = app.db.select().from(researchRuns).where(and82(
|
|
72633
72725
|
eq99(researchRuns.projectId, project.id),
|
|
72634
|
-
cursor ? or22(
|
|
72726
|
+
cursor ? or22(lt14(researchRuns.createdAt, cursor.createdAt), and82(eq99(researchRuns.createdAt, cursor.createdAt), lt14(researchRuns.id, cursor.id))) : void 0
|
|
72635
72727
|
)).orderBy(desc46(researchRuns.createdAt), desc46(researchRuns.id)).limit(limit + 1).all();
|
|
72636
72728
|
const runs2 = rows.slice(0, limit).map(serializeRun);
|
|
72637
72729
|
const last = runs2.at(-1);
|
|
@@ -73260,7 +73352,9 @@ async function apiRoutes(app, opts) {
|
|
|
73260
73352
|
cloudflareTrafficCredentialStore: opts.cloudflareTrafficCredentialStore,
|
|
73261
73353
|
pullCloudflareQueueMessages: opts.pullCloudflareQueueMessages,
|
|
73262
73354
|
ackCloudflareQueueMessages: opts.ackCloudflareQueueMessages,
|
|
73355
|
+
getCloudflareQueueRetentionSeconds: opts.getCloudflareQueueRetentionSeconds,
|
|
73263
73356
|
cloudflareQueueMaxBatches: opts.cloudflareQueueMaxBatches,
|
|
73357
|
+
cloudflareQueueSyncDeadlineMs: opts.cloudflareQueueSyncDeadlineMs,
|
|
73264
73358
|
cloudflareTrafficIngestUrl: opts.cloudflareTrafficIngestUrl,
|
|
73265
73359
|
cloudflareIngestRateLimitMax: opts.cloudflareIngestRateLimitMax,
|
|
73266
73360
|
cloudflareIngestIpRateLimitMax: opts.cloudflareIngestIpRateLimitMax,
|
|
@@ -73676,6 +73770,7 @@ export {
|
|
|
73676
73770
|
listCachedReleases,
|
|
73677
73771
|
pruneCachedRelease,
|
|
73678
73772
|
resolveVercelSyncDeadlineMs,
|
|
73773
|
+
resolveCloudflareQueueSyncDeadlineMs,
|
|
73679
73774
|
SITE_REACHABILITY_CHECK_ID,
|
|
73680
73775
|
SITE_REACHABILITY_CHECKS,
|
|
73681
73776
|
scheduledHealthCheckIds,
|
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node --import tsx
|
|
2
2
|
import {
|
|
3
3
|
REGISTERED_CLI_COMMANDS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AP7YSOFC.js";
|
|
5
5
|
import "./chunk-6GO5VVAC.js";
|
|
6
6
|
import {
|
|
7
7
|
buildSetupState,
|
|
8
8
|
runPendingServeHandoff
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-NWYNTYPD.js";
|
|
10
10
|
import "./chunk-WLIGKWVB.js";
|
|
11
11
|
import "./chunk-VJWDBFSL.js";
|
|
12
12
|
import "./chunk-TSENU4GG.js";
|
|
@@ -40,7 +40,7 @@ function parseDemoTrustedProxies(values) {
|
|
|
40
40
|
async function demoCommand(options) {
|
|
41
41
|
const { host, port } = parseDemoListenOptions(options);
|
|
42
42
|
const trustProxy = parseDemoTrustedProxies(options.trustProxy);
|
|
43
|
-
const { createDemoServer } = await import("./demo-server-
|
|
43
|
+
const { createDemoServer } = await import("./demo-server-QUW4TDJL.js");
|
|
44
44
|
const app = await createDemoServer({ trustProxy });
|
|
45
45
|
let stopping = false;
|
|
46
46
|
const stop = () => {
|