@ainyc/canonry 4.92.0 → 4.94.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/canonry/references/canonry-cli.md +4 -0
- package/assets/agent-workspace/skills/canonry/references/google-business-profile.md +6 -0
- package/assets/assets/{BacklinksPage-D3JpcWtH.js → BacklinksPage-FeUApIRv.js} +1 -1
- package/assets/assets/{ChartPrimitives-DdwqEX5v.js → ChartPrimitives-DFCM9oRt.js} +1 -1
- package/assets/assets/ProjectPage-Dyx8eZf_.js +6 -0
- package/assets/assets/{RunRow-c_2jd8iz.js → RunRow-CF4jm8w8.js} +1 -1
- package/assets/assets/{RunsPage-D6eM_5tB.js → RunsPage-Dlyl-dmG.js} +1 -1
- package/assets/assets/{SettingsPage-DaMc8nxK.js → SettingsPage-DaQ0YNHz.js} +1 -1
- package/assets/assets/{TrafficPage-Dw16dcSc.js → TrafficPage-38zf4QS8.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-Dy9D80dz.js → TrafficSourceDetailPage-DJY18oUo.js} +1 -1
- package/assets/assets/{arrow-left-D8UaBG9a.js → arrow-left-CRHf1qtt.js} +1 -1
- package/assets/assets/{extract-error-message-CfxCIMNJ.js → extract-error-message-uWeOU6mU.js} +1 -1
- package/assets/assets/{index-BA-lh2pG.js → index-B7ZT1i67.js} +73 -73
- package/assets/assets/{index-fLUYE9Z5.css → index-DiykVUPr.css} +1 -1
- package/assets/assets/{trash-2-j1tX1-Kq.js → trash-2-B1qn8ZLk.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-QYC2N23P.js → chunk-3TTBKG73.js} +69 -5
- package/dist/{chunk-HW4GVIQD.js → chunk-K4QOSPBX.js} +37 -2
- package/dist/{chunk-VJPVFCZW.js → chunk-PV3RAHMK.js} +19 -0
- package/dist/{chunk-IFUHXONX.js → chunk-ZJADMHJ5.js} +207 -63
- package/dist/cli.js +57 -9
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-24HCX4SJ.js → intelligence-service-M33PXIWS.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +9 -9
- package/assets/assets/ProjectPage-BPLf4U3A.js +0 -6
|
@@ -137,6 +137,7 @@ import {
|
|
|
137
137
|
ga4SyncResponseDtoSchema,
|
|
138
138
|
gateHarvestedSearchQueries,
|
|
139
139
|
gbpAccountListResponseSchema,
|
|
140
|
+
gbpAttributesListResponseSchema,
|
|
140
141
|
gbpDailyMetricListResponseSchema,
|
|
141
142
|
gbpDiscoverRequestSchema,
|
|
142
143
|
gbpKeywordImpressionListResponseSchema,
|
|
@@ -258,7 +259,7 @@ import {
|
|
|
258
259
|
wordpressSchemaDeployResultDtoSchema,
|
|
259
260
|
wordpressSchemaStatusResultDtoSchema,
|
|
260
261
|
wordpressStatusDtoSchema
|
|
261
|
-
} from "./chunk-
|
|
262
|
+
} from "./chunk-PV3RAHMK.js";
|
|
262
263
|
|
|
263
264
|
// src/intelligence-service.ts
|
|
264
265
|
import { eq as eq37, desc as desc18, asc as asc5, and as and27, ne as ne5, or as or5, inArray as inArray14, gte as gte7, lte as lte4 } from "drizzle-orm";
|
|
@@ -302,6 +303,7 @@ __export(schema_exports, {
|
|
|
302
303
|
gaTrafficSnapshots: () => gaTrafficSnapshots,
|
|
303
304
|
gaTrafficSummaries: () => gaTrafficSummaries,
|
|
304
305
|
gaTrafficWindowSummaries: () => gaTrafficWindowSummaries,
|
|
306
|
+
gbpAttributesSnapshots: () => gbpAttributesSnapshots,
|
|
305
307
|
gbpDailyMetrics: () => gbpDailyMetrics,
|
|
306
308
|
gbpKeywordImpressions: () => gbpKeywordImpressions,
|
|
307
309
|
gbpKeywordMonthly: () => gbpKeywordMonthly,
|
|
@@ -1276,6 +1278,18 @@ var gbpPlaceDetails = sqliteTable("gbp_place_details", {
|
|
|
1276
1278
|
}, (table) => [
|
|
1277
1279
|
index("idx_gbp_place_details_loc").on(table.projectId, table.locationName, table.syncedAt)
|
|
1278
1280
|
]);
|
|
1281
|
+
var gbpAttributesSnapshots = sqliteTable("gbp_attributes_snapshots", {
|
|
1282
|
+
id: text("id").primaryKey(),
|
|
1283
|
+
projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
1284
|
+
locationName: text("location_name").notNull(),
|
|
1285
|
+
contentHash: text("content_hash").notNull(),
|
|
1286
|
+
attributes: text("attributes", { mode: "json" }).$type().notNull().default([]),
|
|
1287
|
+
attributeCount: integer("attribute_count").notNull().default(0),
|
|
1288
|
+
syncedAt: text("synced_at").notNull(),
|
|
1289
|
+
syncRunId: text("sync_run_id").references(() => runs.id, { onDelete: "set null" })
|
|
1290
|
+
}, (table) => [
|
|
1291
|
+
index("idx_gbp_attributes_loc").on(table.projectId, table.locationName, table.syncedAt)
|
|
1292
|
+
]);
|
|
1279
1293
|
var adsConnections = sqliteTable("ads_connections", {
|
|
1280
1294
|
id: text("id").primaryKey(),
|
|
1281
1295
|
projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
@@ -3166,6 +3180,23 @@ var MIGRATION_VERSIONS = [
|
|
|
3166
3180
|
}
|
|
3167
3181
|
}
|
|
3168
3182
|
}
|
|
3183
|
+
},
|
|
3184
|
+
{
|
|
3185
|
+
version: 82,
|
|
3186
|
+
name: "gbp-attributes-snapshots",
|
|
3187
|
+
statements: [
|
|
3188
|
+
`CREATE TABLE IF NOT EXISTS gbp_attributes_snapshots (
|
|
3189
|
+
id TEXT PRIMARY KEY,
|
|
3190
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
3191
|
+
location_name TEXT NOT NULL,
|
|
3192
|
+
content_hash TEXT NOT NULL,
|
|
3193
|
+
attributes TEXT NOT NULL DEFAULT '[]',
|
|
3194
|
+
attribute_count INTEGER NOT NULL DEFAULT 0,
|
|
3195
|
+
synced_at TEXT NOT NULL,
|
|
3196
|
+
sync_run_id TEXT REFERENCES runs(id) ON DELETE SET NULL
|
|
3197
|
+
)`,
|
|
3198
|
+
`CREATE INDEX IF NOT EXISTS idx_gbp_attributes_loc ON gbp_attributes_snapshots(project_id, location_name, synced_at)`
|
|
3199
|
+
]
|
|
3169
3200
|
}
|
|
3170
3201
|
];
|
|
3171
3202
|
function rebuildBacklinkTableWithSource(tx, table) {
|
|
@@ -8086,7 +8117,15 @@ function buildCategoryCounts(counts2) {
|
|
|
8086
8117
|
}
|
|
8087
8118
|
|
|
8088
8119
|
// ../api-routes/src/intelligence.ts
|
|
8089
|
-
import { eq as eq11, desc as desc4, and as and6, inArray as inArray4 } from "drizzle-orm";
|
|
8120
|
+
import { eq as eq11, desc as desc4, and as and6, inArray as inArray4, like } from "drizzle-orm";
|
|
8121
|
+
var SEVERITY_RANK = { low: 0, medium: 1, high: 2, critical: 3 };
|
|
8122
|
+
function severitiesAtOrAbove(min) {
|
|
8123
|
+
const floor = SEVERITY_RANK[min];
|
|
8124
|
+
if (floor === void 0) {
|
|
8125
|
+
throw validationError(`Invalid severity "${min}". Use one of: low, medium, high, critical.`);
|
|
8126
|
+
}
|
|
8127
|
+
return Object.keys(SEVERITY_RANK).filter((s) => SEVERITY_RANK[s] >= floor);
|
|
8128
|
+
}
|
|
8090
8129
|
function emptyHealthSnapshot(projectId) {
|
|
8091
8130
|
return {
|
|
8092
8131
|
id: `no-data:${projectId}`,
|
|
@@ -8200,9 +8239,28 @@ async function intelligenceRoutes(app) {
|
|
|
8200
8239
|
if (request.query.runId) {
|
|
8201
8240
|
conditions.push(eq11(insights.runId, request.query.runId));
|
|
8202
8241
|
}
|
|
8242
|
+
const typeFilter = request.query.type?.trim();
|
|
8243
|
+
if (typeFilter) {
|
|
8244
|
+
conditions.push(
|
|
8245
|
+
typeFilter.endsWith("*") ? like(insights.type, `${typeFilter.slice(0, -1)}%`) : eq11(insights.type, typeFilter)
|
|
8246
|
+
);
|
|
8247
|
+
}
|
|
8248
|
+
const severityFilter = request.query.severity?.trim();
|
|
8249
|
+
if (severityFilter) {
|
|
8250
|
+
conditions.push(inArray4(insights.severity, severitiesAtOrAbove(severityFilter)));
|
|
8251
|
+
}
|
|
8252
|
+
let limit;
|
|
8253
|
+
if (request.query.limit !== void 0) {
|
|
8254
|
+
const parsed = Number(request.query.limit);
|
|
8255
|
+
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
8256
|
+
throw validationError(`Invalid limit "${request.query.limit}". Use a positive integer.`);
|
|
8257
|
+
}
|
|
8258
|
+
limit = parsed;
|
|
8259
|
+
}
|
|
8203
8260
|
const rows = app.db.select().from(insights).where(conditions.length === 1 ? conditions[0] : and6(...conditions)).orderBy(desc4(insights.createdAt)).all();
|
|
8204
8261
|
const showDismissed = request.query.dismissed === "true";
|
|
8205
|
-
|
|
8262
|
+
let result = rows.filter((r) => showDismissed || !r.dismissed).map(mapInsightRow);
|
|
8263
|
+
if (limit !== void 0) result = result.slice(0, limit);
|
|
8206
8264
|
return reply.send(result);
|
|
8207
8265
|
});
|
|
8208
8266
|
app.get("/projects/:name/insights/:id", async (request, reply) => {
|
|
@@ -13019,7 +13077,7 @@ async function visibilityStatsRoutes(app) {
|
|
|
13019
13077
|
}
|
|
13020
13078
|
|
|
13021
13079
|
// ../api-routes/src/composites.ts
|
|
13022
|
-
import { eq as eq17, and as and12, desc as desc9, sql as sql7, like, or as or4, inArray as inArray9 } from "drizzle-orm";
|
|
13080
|
+
import { eq as eq17, and as and12, desc as desc9, sql as sql7, like as like2, or as or4, inArray as inArray9 } from "drizzle-orm";
|
|
13023
13081
|
var TOP_INSIGHT_LIMIT = 5;
|
|
13024
13082
|
var SEARCH_HIT_HARD_LIMIT = 50;
|
|
13025
13083
|
var SEARCH_SNIPPET_RADIUS = 80;
|
|
@@ -13199,7 +13257,7 @@ async function compositeRoutes(app) {
|
|
|
13199
13257
|
sql7`${querySnapshots.answerText} LIKE ${pattern} ESCAPE '\\'`,
|
|
13200
13258
|
sql7`${querySnapshots.citedDomains} LIKE ${pattern} ESCAPE '\\'`,
|
|
13201
13259
|
sql7`${querySnapshots.rawResponse} LIKE ${pattern} ESCAPE '\\'`,
|
|
13202
|
-
|
|
13260
|
+
like2(queries.query, pattern)
|
|
13203
13261
|
)
|
|
13204
13262
|
)
|
|
13205
13263
|
).orderBy(desc9(querySnapshots.createdAt)).limit(limit + 1).all());
|
|
@@ -13207,8 +13265,8 @@ async function compositeRoutes(app) {
|
|
|
13207
13265
|
and12(
|
|
13208
13266
|
eq17(insights.projectId, project.id),
|
|
13209
13267
|
or4(
|
|
13210
|
-
|
|
13211
|
-
|
|
13268
|
+
like2(insights.title, pattern),
|
|
13269
|
+
like2(insights.query, pattern),
|
|
13212
13270
|
sql7`${insights.recommendation} LIKE ${pattern} ESCAPE '\\'`,
|
|
13213
13271
|
sql7`${insights.cause} LIKE ${pattern} ESCAPE '\\'`
|
|
13214
13272
|
)
|
|
@@ -13778,6 +13836,7 @@ var SCHEMA_TABLE = {
|
|
|
13778
13836
|
GbpLocationDto: gbpLocationDtoSchema,
|
|
13779
13837
|
GbpLocationListResponse: gbpLocationListResponseSchema,
|
|
13780
13838
|
GbpLodgingListResponse: gbpLodgingListResponseSchema,
|
|
13839
|
+
GbpAttributesListResponse: gbpAttributesListResponseSchema,
|
|
13781
13840
|
GbpPlaceActionListResponse: gbpPlaceActionListResponseSchema,
|
|
13782
13841
|
GbpPlaceDetailsListResponse: gbpPlaceDetailsListResponseSchema,
|
|
13783
13842
|
GbpSummaryDto: gbpSummaryDtoSchema,
|
|
@@ -15791,6 +15850,20 @@ var routeCatalog = [
|
|
|
15791
15850
|
404: errorResponse("Project not found.")
|
|
15792
15851
|
}
|
|
15793
15852
|
},
|
|
15853
|
+
{
|
|
15854
|
+
method: "get",
|
|
15855
|
+
path: "/api/v1/projects/{name}/gbp/attributes",
|
|
15856
|
+
summary: "List latest Google Business Profile owner-set attribute snapshots per location",
|
|
15857
|
+
tags: ["gbp"],
|
|
15858
|
+
parameters: [
|
|
15859
|
+
nameParameter,
|
|
15860
|
+
{ in: "query", name: "locationName", required: false, description: "Filter to one location resource name", schema: stringSchema }
|
|
15861
|
+
],
|
|
15862
|
+
responses: {
|
|
15863
|
+
200: jsonResponse("Attribute snapshots returned.", "GbpAttributesListResponse"),
|
|
15864
|
+
404: errorResponse("Project not found.")
|
|
15865
|
+
}
|
|
15866
|
+
},
|
|
15794
15867
|
{
|
|
15795
15868
|
method: "get",
|
|
15796
15869
|
path: "/api/v1/projects/{name}/gbp/places",
|
|
@@ -16719,7 +16792,10 @@ var routeCatalog = [
|
|
|
16719
16792
|
parameters: [
|
|
16720
16793
|
nameParameter,
|
|
16721
16794
|
{ name: "dismissed", in: "query", description: "Include dismissed insights (true/false).", schema: stringSchema },
|
|
16722
|
-
{ name: "runId", in: "query", description: "Filter by run ID.", schema: stringSchema }
|
|
16795
|
+
{ name: "runId", in: "query", description: "Filter by run ID.", schema: stringSchema },
|
|
16796
|
+
{ name: "type", in: "query", description: "Filter by insight type. Exact match, or a trailing `*` for a prefix (e.g. `gbp-*`).", schema: stringSchema },
|
|
16797
|
+
{ name: "severity", in: "query", description: "Minimum severity (low|medium|high|critical); e.g. `high` returns high + critical.", schema: stringSchema },
|
|
16798
|
+
{ name: "limit", in: "query", description: "Cap the number of (newest-first) insights returned.", schema: stringSchema }
|
|
16723
16799
|
],
|
|
16724
16800
|
responses: {
|
|
16725
16801
|
// TODO: Add `InsightDto` Zod schema in contracts.
|
|
@@ -18529,7 +18605,7 @@ function formatNotification(row) {
|
|
|
18529
18605
|
}
|
|
18530
18606
|
|
|
18531
18607
|
// ../api-routes/src/google.ts
|
|
18532
|
-
import
|
|
18608
|
+
import crypto18 from "crypto";
|
|
18533
18609
|
import { eq as eq21, and as and14, desc as desc11, sql as sql8, inArray as inArray10 } from "drizzle-orm";
|
|
18534
18610
|
|
|
18535
18611
|
// ../api-routes/src/gbp-summary.ts
|
|
@@ -20082,6 +20158,47 @@ function stableStringify2(value) {
|
|
|
20082
20158
|
return `{${keys.map((k) => `${JSON.stringify(k)}:${stableStringify2(obj[k])}`).join(",")}}`;
|
|
20083
20159
|
}
|
|
20084
20160
|
|
|
20161
|
+
// ../integration-google-business-profile/src/attributes-client.ts
|
|
20162
|
+
import crypto17 from "crypto";
|
|
20163
|
+
async function getAttributes(accessToken, locationName, opts = {}) {
|
|
20164
|
+
const url = `${GBP_BUSINESS_INFO_BASE}/${locationName}/attributes`;
|
|
20165
|
+
let res;
|
|
20166
|
+
try {
|
|
20167
|
+
res = await gbpFetchGet(url, accessToken, opts);
|
|
20168
|
+
} catch (err) {
|
|
20169
|
+
if (err instanceof GbpApiError && err.status === 404) return [];
|
|
20170
|
+
throw err;
|
|
20171
|
+
}
|
|
20172
|
+
return (res.attributes ?? []).map(normalizeAttribute).filter((a) => a.name.length > 0);
|
|
20173
|
+
}
|
|
20174
|
+
function normalizeAttribute(raw) {
|
|
20175
|
+
const values = [];
|
|
20176
|
+
for (const v of raw.values ?? []) {
|
|
20177
|
+
if (typeof v === "boolean" || typeof v === "string") values.push(v);
|
|
20178
|
+
}
|
|
20179
|
+
for (const s of raw.repeatedEnumValue?.setValues ?? []) values.push(s);
|
|
20180
|
+
const unsetValues = [...raw.repeatedEnumValue?.unsetValues ?? []];
|
|
20181
|
+
const uris = [];
|
|
20182
|
+
for (const u of raw.uriValues ?? []) {
|
|
20183
|
+
if (u.uri) uris.push(u.uri);
|
|
20184
|
+
}
|
|
20185
|
+
return { name: raw.name ?? "", valueType: raw.valueType ?? "", values, unsetValues, uris };
|
|
20186
|
+
}
|
|
20187
|
+
function countAttributes(attrs) {
|
|
20188
|
+
return attrs.length;
|
|
20189
|
+
}
|
|
20190
|
+
function hashAttributes(attrs) {
|
|
20191
|
+
const sorted = [...attrs].sort((a, b) => a.name.localeCompare(b.name));
|
|
20192
|
+
return crypto17.createHash("sha256").update(stableStringify3(sorted)).digest("hex");
|
|
20193
|
+
}
|
|
20194
|
+
function stableStringify3(value) {
|
|
20195
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
20196
|
+
if (Array.isArray(value)) return `[${value.map(stableStringify3).join(",")}]`;
|
|
20197
|
+
const obj = value;
|
|
20198
|
+
const keys = Object.keys(obj).sort();
|
|
20199
|
+
return `{${keys.map((k) => `${JSON.stringify(k)}:${stableStringify3(obj[k])}`).join(",")}}`;
|
|
20200
|
+
}
|
|
20201
|
+
|
|
20085
20202
|
// ../api-routes/src/google.ts
|
|
20086
20203
|
function scopesForConnectionType(type) {
|
|
20087
20204
|
switch (type) {
|
|
@@ -20094,7 +20211,7 @@ function scopesForConnectionType(type) {
|
|
|
20094
20211
|
}
|
|
20095
20212
|
}
|
|
20096
20213
|
function signState(payload, secret) {
|
|
20097
|
-
return
|
|
20214
|
+
return crypto18.createHmac("sha256", secret).update(payload).digest("hex");
|
|
20098
20215
|
}
|
|
20099
20216
|
function buildSignedState(data, secret) {
|
|
20100
20217
|
const payload = JSON.stringify(data);
|
|
@@ -20105,7 +20222,7 @@ function verifySignedState(encoded, secret) {
|
|
|
20105
20222
|
try {
|
|
20106
20223
|
const { payload, sig } = JSON.parse(Buffer.from(encoded, "base64url").toString());
|
|
20107
20224
|
const expected = signState(payload, secret);
|
|
20108
|
-
if (!
|
|
20225
|
+
if (!crypto18.timingSafeEqual(Buffer.from(sig, "hex"), Buffer.from(expected, "hex"))) return null;
|
|
20109
20226
|
return JSON.parse(payload);
|
|
20110
20227
|
} catch {
|
|
20111
20228
|
return null;
|
|
@@ -20441,7 +20558,7 @@ async function googleRoutes(app, opts) {
|
|
|
20441
20558
|
throw validationError('No GSC connection found for this domain. Run "canonry google connect" first.');
|
|
20442
20559
|
}
|
|
20443
20560
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
20444
|
-
const runId =
|
|
20561
|
+
const runId = crypto18.randomUUID();
|
|
20445
20562
|
app.db.insert(runs).values({
|
|
20446
20563
|
id: runId,
|
|
20447
20564
|
projectId: project.id,
|
|
@@ -20539,7 +20656,7 @@ async function googleRoutes(app, opts) {
|
|
|
20539
20656
|
const mob = ir.mobileUsabilityResult;
|
|
20540
20657
|
const rich = ir.richResultsResult;
|
|
20541
20658
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
20542
|
-
const id =
|
|
20659
|
+
const id = crypto18.randomUUID();
|
|
20543
20660
|
app.db.insert(gscUrlInspections).values({
|
|
20544
20661
|
id,
|
|
20545
20662
|
projectId: project.id,
|
|
@@ -20783,7 +20900,7 @@ async function googleRoutes(app, opts) {
|
|
|
20783
20900
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
20784
20901
|
});
|
|
20785
20902
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
20786
|
-
const runId =
|
|
20903
|
+
const runId = crypto18.randomUUID();
|
|
20787
20904
|
app.db.insert(runs).values({
|
|
20788
20905
|
id: runId,
|
|
20789
20906
|
projectId: project.id,
|
|
@@ -20809,7 +20926,7 @@ async function googleRoutes(app, opts) {
|
|
|
20809
20926
|
throw validationError("No GSC property configured for this connection");
|
|
20810
20927
|
}
|
|
20811
20928
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
20812
|
-
const runId =
|
|
20929
|
+
const runId = crypto18.randomUUID();
|
|
20813
20930
|
app.db.insert(runs).values({
|
|
20814
20931
|
id: runId,
|
|
20815
20932
|
projectId: project.id,
|
|
@@ -21090,7 +21207,7 @@ async function googleRoutes(app, opts) {
|
|
|
21090
21207
|
}).where(eq21(gbpLocations.id, existing.id)).run();
|
|
21091
21208
|
} else {
|
|
21092
21209
|
tx.insert(gbpLocations).values({
|
|
21093
|
-
id:
|
|
21210
|
+
id: crypto18.randomUUID(),
|
|
21094
21211
|
projectId: project.id,
|
|
21095
21212
|
accountName,
|
|
21096
21213
|
locationName: remote.name,
|
|
@@ -21214,7 +21331,7 @@ async function googleRoutes(app, opts) {
|
|
|
21214
21331
|
throw validationError(parsed.error.issues[0]?.message ?? "Invalid sync request");
|
|
21215
21332
|
}
|
|
21216
21333
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
21217
|
-
const runId =
|
|
21334
|
+
const runId = crypto18.randomUUID();
|
|
21218
21335
|
app.db.insert(runs).values({
|
|
21219
21336
|
id: runId,
|
|
21220
21337
|
projectId: project.id,
|
|
@@ -21291,6 +21408,26 @@ async function googleRoutes(app, opts) {
|
|
|
21291
21408
|
}));
|
|
21292
21409
|
return { lodging, total: lodging.length };
|
|
21293
21410
|
});
|
|
21411
|
+
app.get("/projects/:name/gbp/attributes", async (request) => {
|
|
21412
|
+
const project = resolveProject(app.db, request.params.name);
|
|
21413
|
+
const conditions = [eq21(gbpAttributesSnapshots.projectId, project.id)];
|
|
21414
|
+
if (request.query.locationName) conditions.push(eq21(gbpAttributesSnapshots.locationName, request.query.locationName));
|
|
21415
|
+
const rows = app.db.select().from(gbpAttributesSnapshots).where(and14(...conditions)).orderBy(desc11(gbpAttributesSnapshots.syncedAt)).all();
|
|
21416
|
+
const latestByLocation = /* @__PURE__ */ new Map();
|
|
21417
|
+
for (const row of rows) {
|
|
21418
|
+
if (!latestByLocation.has(row.locationName)) latestByLocation.set(row.locationName, row);
|
|
21419
|
+
}
|
|
21420
|
+
const attributes = [...latestByLocation.values()].map((r) => ({
|
|
21421
|
+
locationName: r.locationName,
|
|
21422
|
+
attributeCount: r.attributeCount,
|
|
21423
|
+
syncedAt: r.syncedAt,
|
|
21424
|
+
attributes: r.attributes.map((attr) => ({
|
|
21425
|
+
...attr,
|
|
21426
|
+
unsetValues: attr.unsetValues ?? []
|
|
21427
|
+
}))
|
|
21428
|
+
}));
|
|
21429
|
+
return { attributes, total: attributes.length };
|
|
21430
|
+
});
|
|
21294
21431
|
app.get("/projects/:name/gbp/places", async (request) => {
|
|
21295
21432
|
const project = resolveProject(app.db, request.params.name);
|
|
21296
21433
|
const conditions = [eq21(gbpPlaceDetails.projectId, project.id)];
|
|
@@ -21360,7 +21497,7 @@ async function googleRoutes(app, opts) {
|
|
|
21360
21497
|
}
|
|
21361
21498
|
|
|
21362
21499
|
// ../api-routes/src/ads.ts
|
|
21363
|
-
import
|
|
21500
|
+
import crypto19 from "crypto";
|
|
21364
21501
|
import { eq as eq22, and as and15, asc as asc2, gte as gte3, lte as lte2, inArray as inArray11 } from "drizzle-orm";
|
|
21365
21502
|
function statusDto(row) {
|
|
21366
21503
|
if (!row) return { connected: false };
|
|
@@ -21423,7 +21560,7 @@ async function adsRoutes(app, opts) {
|
|
|
21423
21560
|
}).where(eq22(adsConnections.id, existingRow.id)).run();
|
|
21424
21561
|
} else {
|
|
21425
21562
|
tx.insert(adsConnections).values({
|
|
21426
|
-
id:
|
|
21563
|
+
id: crypto19.randomUUID(),
|
|
21427
21564
|
projectId: project.id,
|
|
21428
21565
|
adAccountId: account.id,
|
|
21429
21566
|
displayName: account.name,
|
|
@@ -21485,7 +21622,7 @@ async function adsRoutes(app, opts) {
|
|
|
21485
21622
|
const existing = { runId: inFlight.id, status: inFlight.status };
|
|
21486
21623
|
return existing;
|
|
21487
21624
|
}
|
|
21488
|
-
const runId =
|
|
21625
|
+
const runId = crypto19.randomUUID();
|
|
21489
21626
|
app.db.insert(runs).values({
|
|
21490
21627
|
id: runId,
|
|
21491
21628
|
projectId: project.id,
|
|
@@ -21620,7 +21757,7 @@ async function adsRoutes(app, opts) {
|
|
|
21620
21757
|
}
|
|
21621
21758
|
|
|
21622
21759
|
// ../api-routes/src/bing.ts
|
|
21623
|
-
import
|
|
21760
|
+
import crypto20 from "crypto";
|
|
21624
21761
|
import { eq as eq23, and as and16, desc as desc12 } from "drizzle-orm";
|
|
21625
21762
|
|
|
21626
21763
|
// ../integration-bing/src/constants.ts
|
|
@@ -22052,7 +22189,7 @@ async function bingRoutes(app, opts) {
|
|
|
22052
22189
|
const snapshotDate = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
22053
22190
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
22054
22191
|
app.db.insert(bingCoverageSnapshots).values({
|
|
22055
|
-
id:
|
|
22192
|
+
id: crypto20.randomUUID(),
|
|
22056
22193
|
projectId: project.id,
|
|
22057
22194
|
syncRunId: snapshotRunId,
|
|
22058
22195
|
date: snapshotDate,
|
|
@@ -22123,7 +22260,7 @@ async function bingRoutes(app, opts) {
|
|
|
22123
22260
|
throw validationError("url is required");
|
|
22124
22261
|
}
|
|
22125
22262
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
22126
|
-
const runId =
|
|
22263
|
+
const runId = crypto20.randomUUID();
|
|
22127
22264
|
app.db.insert(runs).values({
|
|
22128
22265
|
id: runId,
|
|
22129
22266
|
projectId: project.id,
|
|
@@ -22144,7 +22281,7 @@ async function bingRoutes(app, opts) {
|
|
|
22144
22281
|
discoveryDate: result.DiscoveryDate ?? null
|
|
22145
22282
|
});
|
|
22146
22283
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
22147
|
-
const id =
|
|
22284
|
+
const id = crypto20.randomUUID();
|
|
22148
22285
|
const httpCode = result.HttpStatus ?? result.HttpCode ?? null;
|
|
22149
22286
|
const lastCrawledDate = parseBingDate(result.LastCrawledDate);
|
|
22150
22287
|
const inIndexDate = parseBingDate(result.InIndexDate);
|
|
@@ -22214,7 +22351,7 @@ async function bingRoutes(app, opts) {
|
|
|
22214
22351
|
throw validationError('No Bing site configured. Run "canonry bing set-site <project> <url>" first.');
|
|
22215
22352
|
}
|
|
22216
22353
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
22217
|
-
const runId =
|
|
22354
|
+
const runId = crypto20.randomUUID();
|
|
22218
22355
|
app.db.insert(runs).values({
|
|
22219
22356
|
id: runId,
|
|
22220
22357
|
projectId: project.id,
|
|
@@ -22498,7 +22635,7 @@ async function cdpRoutes(app, opts) {
|
|
|
22498
22635
|
}
|
|
22499
22636
|
|
|
22500
22637
|
// ../api-routes/src/ga.ts
|
|
22501
|
-
import
|
|
22638
|
+
import crypto21 from "crypto";
|
|
22502
22639
|
import { eq as eq25, desc as desc13, and as and18, sql as sql9 } from "drizzle-orm";
|
|
22503
22640
|
function gaLog(level, action, ctx) {
|
|
22504
22641
|
const entry = { ts: (/* @__PURE__ */ new Date()).toISOString(), level, module: "GA4Routes", action, ...ctx };
|
|
@@ -22754,7 +22891,7 @@ async function ga4Routes(app, opts) {
|
|
|
22754
22891
|
const syncAi = !only || only === "ai";
|
|
22755
22892
|
const syncSocial = !only || only === "social";
|
|
22756
22893
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
22757
|
-
const runId =
|
|
22894
|
+
const runId = crypto21.randomUUID();
|
|
22758
22895
|
app.db.insert(runs).values({
|
|
22759
22896
|
id: runId,
|
|
22760
22897
|
projectId: project.id,
|
|
@@ -22802,7 +22939,7 @@ async function ga4Routes(app, opts) {
|
|
|
22802
22939
|
).run();
|
|
22803
22940
|
for (const row of rows) {
|
|
22804
22941
|
tx.insert(gaTrafficSnapshots).values({
|
|
22805
|
-
id:
|
|
22942
|
+
id: crypto21.randomUUID(),
|
|
22806
22943
|
projectId: project.id,
|
|
22807
22944
|
date: row.date,
|
|
22808
22945
|
landingPage: row.landingPage,
|
|
@@ -22826,7 +22963,7 @@ async function ga4Routes(app, opts) {
|
|
|
22826
22963
|
).run();
|
|
22827
22964
|
for (const row of aiReferrals) {
|
|
22828
22965
|
tx.insert(gaAiReferrals).values({
|
|
22829
|
-
id:
|
|
22966
|
+
id: crypto21.randomUUID(),
|
|
22830
22967
|
projectId: project.id,
|
|
22831
22968
|
date: row.date,
|
|
22832
22969
|
source: row.source,
|
|
@@ -22852,7 +22989,7 @@ async function ga4Routes(app, opts) {
|
|
|
22852
22989
|
).run();
|
|
22853
22990
|
for (const row of socialReferrals) {
|
|
22854
22991
|
tx.insert(gaSocialReferrals).values({
|
|
22855
|
-
id:
|
|
22992
|
+
id: crypto21.randomUUID(),
|
|
22856
22993
|
projectId: project.id,
|
|
22857
22994
|
date: row.date,
|
|
22858
22995
|
source: row.source,
|
|
@@ -22868,7 +23005,7 @@ async function ga4Routes(app, opts) {
|
|
|
22868
23005
|
if (syncSummary) {
|
|
22869
23006
|
tx.delete(gaTrafficSummaries).where(eq25(gaTrafficSummaries.projectId, project.id)).run();
|
|
22870
23007
|
tx.insert(gaTrafficSummaries).values({
|
|
22871
|
-
id:
|
|
23008
|
+
id: crypto21.randomUUID(),
|
|
22872
23009
|
projectId: project.id,
|
|
22873
23010
|
periodStart: summary.periodStart,
|
|
22874
23011
|
periodEnd: summary.periodEnd,
|
|
@@ -22881,7 +23018,7 @@ async function ga4Routes(app, opts) {
|
|
|
22881
23018
|
tx.delete(gaTrafficWindowSummaries).where(eq25(gaTrafficWindowSummaries.projectId, project.id)).run();
|
|
22882
23019
|
for (const ws of windowSummaries) {
|
|
22883
23020
|
tx.insert(gaTrafficWindowSummaries).values({
|
|
22884
|
-
id:
|
|
23021
|
+
id: crypto21.randomUUID(),
|
|
22885
23022
|
projectId: project.id,
|
|
22886
23023
|
windowKey: ws.windowKey,
|
|
22887
23024
|
periodStart: ws.periodStart,
|
|
@@ -23452,7 +23589,7 @@ function parseSchemaPageEntry(entry) {
|
|
|
23452
23589
|
}
|
|
23453
23590
|
|
|
23454
23591
|
// ../integration-wordpress/src/wordpress-client.ts
|
|
23455
|
-
import
|
|
23592
|
+
import crypto22 from "crypto";
|
|
23456
23593
|
function validateUsername(username) {
|
|
23457
23594
|
if (!username || typeof username !== "string" || username.trim().length === 0) {
|
|
23458
23595
|
throw new WordpressApiError("AUTH_INVALID", "Username is required and must be a non-empty string", 400);
|
|
@@ -23665,7 +23802,7 @@ function buildSnippet(content) {
|
|
|
23665
23802
|
return `${text2.slice(0, 157)}...`;
|
|
23666
23803
|
}
|
|
23667
23804
|
function contentHash(content) {
|
|
23668
|
-
return
|
|
23805
|
+
return crypto22.createHash("sha256").update(content).digest("hex");
|
|
23669
23806
|
}
|
|
23670
23807
|
function buildAmbiguousSlugMessage(slug, pages) {
|
|
23671
23808
|
const candidates = pages.map((page) => {
|
|
@@ -24965,7 +25102,7 @@ async function wordpressRoutes(app, opts) {
|
|
|
24965
25102
|
}
|
|
24966
25103
|
|
|
24967
25104
|
// ../api-routes/src/backlinks.ts
|
|
24968
|
-
import
|
|
25105
|
+
import crypto23 from "crypto";
|
|
24969
25106
|
import { and as and20, asc as asc3, desc as desc14, eq as eq26, sql as sql10 } from "drizzle-orm";
|
|
24970
25107
|
|
|
24971
25108
|
// ../integration-commoncrawl/src/constants.ts
|
|
@@ -25603,7 +25740,7 @@ async function backlinksRoutes(app, opts) {
|
|
|
25603
25740
|
const refreshed = app.db.select().from(ccReleaseSyncs).where(eq26(ccReleaseSyncs.id, existing.id)).get();
|
|
25604
25741
|
return reply.status(200).send(mapSyncRow(refreshed));
|
|
25605
25742
|
}
|
|
25606
|
-
const id =
|
|
25743
|
+
const id = crypto23.randomUUID();
|
|
25607
25744
|
app.db.insert(ccReleaseSyncs).values({
|
|
25608
25745
|
id,
|
|
25609
25746
|
release,
|
|
@@ -25660,7 +25797,7 @@ async function backlinksRoutes(app, opts) {
|
|
|
25660
25797
|
throw validationError("Invalid release id");
|
|
25661
25798
|
}
|
|
25662
25799
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
25663
|
-
const runId =
|
|
25800
|
+
const runId = crypto23.randomUUID();
|
|
25664
25801
|
app.db.insert(runs).values({
|
|
25665
25802
|
id: runId,
|
|
25666
25803
|
projectId: project.id,
|
|
@@ -25762,7 +25899,7 @@ async function backlinksRoutes(app, opts) {
|
|
|
25762
25899
|
);
|
|
25763
25900
|
}
|
|
25764
25901
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
25765
|
-
const runId =
|
|
25902
|
+
const runId = crypto23.randomUUID();
|
|
25766
25903
|
app.db.insert(runs).values({
|
|
25767
25904
|
id: runId,
|
|
25768
25905
|
projectId: project.id,
|
|
@@ -25779,12 +25916,12 @@ async function backlinksRoutes(app, opts) {
|
|
|
25779
25916
|
}
|
|
25780
25917
|
|
|
25781
25918
|
// ../api-routes/src/traffic.ts
|
|
25782
|
-
import
|
|
25919
|
+
import crypto25 from "crypto";
|
|
25783
25920
|
import { Agent as UndiciAgent } from "undici";
|
|
25784
25921
|
import { and as and21, desc as desc15, eq as eq27, gte as gte4, lte as lte3, sql as sql11 } from "drizzle-orm";
|
|
25785
25922
|
|
|
25786
25923
|
// ../integration-cloud-run/src/auth.ts
|
|
25787
|
-
import
|
|
25924
|
+
import crypto24 from "crypto";
|
|
25788
25925
|
var GOOGLE_TOKEN_URL3 = "https://oauth2.googleapis.com/token";
|
|
25789
25926
|
var CLOUD_LOGGING_READ_SCOPE = "https://www.googleapis.com/auth/logging.read";
|
|
25790
25927
|
var TOKEN_REQUEST_TIMEOUT_MS = 3e4;
|
|
@@ -25815,7 +25952,7 @@ function createServiceAccountJwt2(clientEmail, privateKey, scope) {
|
|
|
25815
25952
|
const headerB64 = encode(header);
|
|
25816
25953
|
const payloadB64 = encode(payload);
|
|
25817
25954
|
const signingInput = `${headerB64}.${payloadB64}`;
|
|
25818
|
-
const sign =
|
|
25955
|
+
const sign = crypto24.createSign("RSA-SHA256");
|
|
25819
25956
|
sign.update(signingInput);
|
|
25820
25957
|
const signature = sign.sign(privateKey, "base64url");
|
|
25821
25958
|
return `${signingInput}.${signature}`;
|
|
@@ -29723,7 +29860,7 @@ async function runBackfillTask(options) {
|
|
|
29723
29860
|
}
|
|
29724
29861
|
})();
|
|
29725
29862
|
tx.insert(rawEventSamples).values({
|
|
29726
|
-
id:
|
|
29863
|
+
id: crypto25.randomUUID(),
|
|
29727
29864
|
projectId: project.id,
|
|
29728
29865
|
sourceId: sourceRow.id,
|
|
29729
29866
|
ts: sample.observedAt,
|
|
@@ -29849,7 +29986,7 @@ async function trafficRoutes(app, opts) {
|
|
|
29849
29986
|
}).where(eq27(trafficSources.id, activeSource.id)).run();
|
|
29850
29987
|
sourceRow = app.db.select().from(trafficSources).where(eq27(trafficSources.id, activeSource.id)).get();
|
|
29851
29988
|
} else {
|
|
29852
|
-
const newId =
|
|
29989
|
+
const newId = crypto25.randomUUID();
|
|
29853
29990
|
app.db.insert(trafficSources).values({
|
|
29854
29991
|
id: newId,
|
|
29855
29992
|
projectId: project.id,
|
|
@@ -29930,7 +30067,7 @@ async function trafficRoutes(app, opts) {
|
|
|
29930
30067
|
}).where(eq27(trafficSources.id, activeSource.id)).run();
|
|
29931
30068
|
sourceRow = app.db.select().from(trafficSources).where(eq27(trafficSources.id, activeSource.id)).get();
|
|
29932
30069
|
} else {
|
|
29933
|
-
const newId =
|
|
30070
|
+
const newId = crypto25.randomUUID();
|
|
29934
30071
|
app.db.insert(trafficSources).values({
|
|
29935
30072
|
id: newId,
|
|
29936
30073
|
projectId: project.id,
|
|
@@ -30014,7 +30151,7 @@ async function trafficRoutes(app, opts) {
|
|
|
30014
30151
|
}).where(eq27(trafficSources.id, activeSource.id)).run();
|
|
30015
30152
|
row = tx.select().from(trafficSources).where(eq27(trafficSources.id, activeSource.id)).get();
|
|
30016
30153
|
} else {
|
|
30017
|
-
const newId =
|
|
30154
|
+
const newId = crypto25.randomUUID();
|
|
30018
30155
|
tx.insert(trafficSources).values({
|
|
30019
30156
|
id: newId,
|
|
30020
30157
|
projectId: project.id,
|
|
@@ -30048,7 +30185,7 @@ async function trafficRoutes(app, opts) {
|
|
|
30048
30185
|
let created = false;
|
|
30049
30186
|
if (!existingSchedule) {
|
|
30050
30187
|
tx.insert(schedules).values({
|
|
30051
|
-
id:
|
|
30188
|
+
id: crypto25.randomUUID(),
|
|
30052
30189
|
projectId: project.id,
|
|
30053
30190
|
kind: SchedulableRunKinds["traffic-sync"],
|
|
30054
30191
|
cronExpr: DEFAULT_TRAFFIC_SYNC_CRON,
|
|
@@ -30103,7 +30240,7 @@ async function trafficRoutes(app, opts) {
|
|
|
30103
30240
|
const windowEnd = /* @__PURE__ */ new Date();
|
|
30104
30241
|
const startedAt = windowEnd.toISOString();
|
|
30105
30242
|
const syncStartedAtMs = windowEnd.getTime();
|
|
30106
|
-
const runId =
|
|
30243
|
+
const runId = crypto25.randomUUID();
|
|
30107
30244
|
app.db.insert(runs).values({
|
|
30108
30245
|
id: runId,
|
|
30109
30246
|
projectId: project.id,
|
|
@@ -30486,7 +30623,7 @@ async function trafficRoutes(app, opts) {
|
|
|
30486
30623
|
}
|
|
30487
30624
|
})();
|
|
30488
30625
|
tx.insert(rawEventSamples).values({
|
|
30489
|
-
id:
|
|
30626
|
+
id: crypto25.randomUUID(),
|
|
30490
30627
|
projectId: project.id,
|
|
30491
30628
|
sourceId: sourceRow.id,
|
|
30492
30629
|
ts: sample.observedAt,
|
|
@@ -30724,7 +30861,7 @@ async function trafficRoutes(app, opts) {
|
|
|
30724
30861
|
};
|
|
30725
30862
|
}
|
|
30726
30863
|
const startedAt = windowEnd.toISOString();
|
|
30727
|
-
const runId =
|
|
30864
|
+
const runId = crypto25.randomUUID();
|
|
30728
30865
|
app.db.insert(runs).values({
|
|
30729
30866
|
id: runId,
|
|
30730
30867
|
projectId: project.id,
|
|
@@ -31025,7 +31162,7 @@ async function trafficRoutes(app, opts) {
|
|
|
31025
31162
|
}
|
|
31026
31163
|
|
|
31027
31164
|
// ../api-routes/src/doctor/checks/agent.ts
|
|
31028
|
-
import
|
|
31165
|
+
import crypto26 from "crypto";
|
|
31029
31166
|
import fs6 from "fs";
|
|
31030
31167
|
import path7 from "path";
|
|
31031
31168
|
var REQUIRED_SKILLS = ["canonry", "aero"];
|
|
@@ -31178,7 +31315,7 @@ function isInstalled(dir) {
|
|
|
31178
31315
|
}
|
|
31179
31316
|
function hashInstalledFile(filePath) {
|
|
31180
31317
|
try {
|
|
31181
|
-
return
|
|
31318
|
+
return crypto26.createHash("sha256").update(fs6.readFileSync(filePath)).digest("hex");
|
|
31182
31319
|
} catch {
|
|
31183
31320
|
return void 0;
|
|
31184
31321
|
}
|
|
@@ -33080,7 +33217,7 @@ async function doctorRoutes(app, opts) {
|
|
|
33080
33217
|
}
|
|
33081
33218
|
|
|
33082
33219
|
// ../api-routes/src/discovery/routes.ts
|
|
33083
|
-
import
|
|
33220
|
+
import crypto27 from "crypto";
|
|
33084
33221
|
import { and as and25, desc as desc16, eq as eq34, gte as gte6, inArray as inArray12 } from "drizzle-orm";
|
|
33085
33222
|
var MAX_INFLIGHT_DISCOVERY_AGE_MS = 2 * 60 * 60 * 1e3;
|
|
33086
33223
|
async function discoveryRoutes(app, opts) {
|
|
@@ -33126,8 +33263,8 @@ async function discoveryRoutes(app, opts) {
|
|
|
33126
33263
|
if (existing && existing.runId) {
|
|
33127
33264
|
return { reused: true, sessionId: existing.id, runId: existing.runId };
|
|
33128
33265
|
}
|
|
33129
|
-
const sessionId =
|
|
33130
|
-
const runId =
|
|
33266
|
+
const sessionId = crypto27.randomUUID();
|
|
33267
|
+
const runId = crypto27.randomUUID();
|
|
33131
33268
|
tx.insert(discoverySessions).values({
|
|
33132
33269
|
id: sessionId,
|
|
33133
33270
|
projectId: project.id,
|
|
@@ -33375,7 +33512,7 @@ async function discoveryRoutes(app, opts) {
|
|
|
33375
33512
|
app.db.transaction((tx) => {
|
|
33376
33513
|
for (const query of promotedQueries) {
|
|
33377
33514
|
tx.insert(queries).values({
|
|
33378
|
-
id:
|
|
33515
|
+
id: crypto27.randomUUID(),
|
|
33379
33516
|
projectId: project.id,
|
|
33380
33517
|
query,
|
|
33381
33518
|
provenance,
|
|
@@ -33384,7 +33521,7 @@ async function discoveryRoutes(app, opts) {
|
|
|
33384
33521
|
}
|
|
33385
33522
|
for (const domain of promotedCompetitors) {
|
|
33386
33523
|
tx.insert(competitors).values({
|
|
33387
|
-
id:
|
|
33524
|
+
id: crypto27.randomUUID(),
|
|
33388
33525
|
projectId: project.id,
|
|
33389
33526
|
domain,
|
|
33390
33527
|
provenance,
|
|
@@ -33462,7 +33599,7 @@ function selectEligibleCompetitors(competitorMap, competitorTypes) {
|
|
|
33462
33599
|
}
|
|
33463
33600
|
|
|
33464
33601
|
// ../api-routes/src/discovery/orchestrate.ts
|
|
33465
|
-
import
|
|
33602
|
+
import crypto28 from "crypto";
|
|
33466
33603
|
import { eq as eq35 } from "drizzle-orm";
|
|
33467
33604
|
var DEFAULT_MAX_PROBES = 100;
|
|
33468
33605
|
var ABSOLUTE_MAX_PROBES = 500;
|
|
@@ -33556,7 +33693,7 @@ async function executeDiscovery(opts) {
|
|
|
33556
33693
|
probeRows.push({ citedDomains: probe.citedDomains, bucket });
|
|
33557
33694
|
buckets[bucket]++;
|
|
33558
33695
|
opts.db.insert(discoveryProbes).values({
|
|
33559
|
-
id:
|
|
33696
|
+
id: crypto28.randomUUID(),
|
|
33560
33697
|
sessionId: opts.sessionId,
|
|
33561
33698
|
projectId: opts.project.id,
|
|
33562
33699
|
query,
|
|
@@ -33601,7 +33738,7 @@ function upsertDomainClassifications(db, projectId, sessionId, competitorMap) {
|
|
|
33601
33738
|
const domain = normalizeDomain(entry.domain);
|
|
33602
33739
|
if (!domain) continue;
|
|
33603
33740
|
db.insert(domainClassifications).values({
|
|
33604
|
-
id:
|
|
33741
|
+
id: crypto28.randomUUID(),
|
|
33605
33742
|
projectId,
|
|
33606
33743
|
domain,
|
|
33607
33744
|
competitorType: entry.competitorType,
|
|
@@ -33641,7 +33778,7 @@ function dedupeStrings(input) {
|
|
|
33641
33778
|
}
|
|
33642
33779
|
|
|
33643
33780
|
// ../api-routes/src/technical-aeo.ts
|
|
33644
|
-
import
|
|
33781
|
+
import crypto29 from "crypto";
|
|
33645
33782
|
import { and as and26, asc as asc4, count, desc as desc17, eq as eq36, inArray as inArray13 } from "drizzle-orm";
|
|
33646
33783
|
var SURFACEABLE_STATUSES = [RunStatuses.completed, RunStatuses.partial];
|
|
33647
33784
|
function emptyScore(projectName) {
|
|
@@ -33768,7 +33905,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
33768
33905
|
return { runId: existing.id, status: existing.status };
|
|
33769
33906
|
}
|
|
33770
33907
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
33771
|
-
const runId =
|
|
33908
|
+
const runId = crypto29.randomUUID();
|
|
33772
33909
|
app.db.insert(runs).values({
|
|
33773
33910
|
id: runId,
|
|
33774
33911
|
projectId: project.id,
|
|
@@ -34119,7 +34256,7 @@ function buildTrafficSourceValidators(opts) {
|
|
|
34119
34256
|
}
|
|
34120
34257
|
|
|
34121
34258
|
// src/intelligence-service.ts
|
|
34122
|
-
import
|
|
34259
|
+
import crypto30 from "crypto";
|
|
34123
34260
|
|
|
34124
34261
|
// src/logger.ts
|
|
34125
34262
|
var IS_TTY = process.stdout.isTTY === true;
|
|
@@ -34784,7 +34921,7 @@ var IntelligenceService = class {
|
|
|
34784
34921
|
}).run();
|
|
34785
34922
|
}
|
|
34786
34923
|
tx.insert(healthSnapshots).values({
|
|
34787
|
-
id:
|
|
34924
|
+
id: crypto30.randomUUID(),
|
|
34788
34925
|
projectId,
|
|
34789
34926
|
runId,
|
|
34790
34927
|
overallCitedRate: String(result.health.overallCitedRate),
|
|
@@ -34979,6 +35116,7 @@ export {
|
|
|
34979
35116
|
gbpPlaceActions,
|
|
34980
35117
|
gbpLodgingSnapshots,
|
|
34981
35118
|
gbpPlaceDetails,
|
|
35119
|
+
gbpAttributesSnapshots,
|
|
34982
35120
|
adsConnections,
|
|
34983
35121
|
adsCampaigns,
|
|
34984
35122
|
adsAdGroups,
|
|
@@ -35008,12 +35146,18 @@ export {
|
|
|
35008
35146
|
fetchSearchAnalytics,
|
|
35009
35147
|
inspectUrl,
|
|
35010
35148
|
GBP_DAILY_METRICS,
|
|
35149
|
+
listLocations,
|
|
35150
|
+
formatStorefrontAddress,
|
|
35151
|
+
buildLocationProfileFields,
|
|
35011
35152
|
fetchDailyMetrics,
|
|
35012
35153
|
listMonthlyKeywords,
|
|
35013
35154
|
listPlaceActionLinks,
|
|
35014
35155
|
getLodging,
|
|
35015
35156
|
countPopulatedGroups,
|
|
35016
35157
|
hashLodging,
|
|
35158
|
+
getAttributes,
|
|
35159
|
+
countAttributes,
|
|
35160
|
+
hashAttributes,
|
|
35017
35161
|
getUrlInfo,
|
|
35018
35162
|
getCrawlIssues,
|
|
35019
35163
|
getLinkCounts,
|