@gscdump/sdk 0.17.0 → 0.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +125 -85
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -166,6 +166,89 @@ function createAnalyticsClient(options = {}) {
|
|
|
166
166
|
}
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
|
+
function normalizeLifecycleUrl(url) {
|
|
170
|
+
return (url || "").replace(/^sc-domain:/, "").replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/$/, "").toLowerCase();
|
|
171
|
+
}
|
|
172
|
+
function normalizeGscPropertyKey(url) {
|
|
173
|
+
const value = url || "";
|
|
174
|
+
if (!value) return "";
|
|
175
|
+
if (value.startsWith("sc-domain:")) return `domain:${normalizeLifecycleUrl(value)}`;
|
|
176
|
+
if (!/^https?:\/\//.test(value)) return "";
|
|
177
|
+
return `url:${normalizeLifecycleUrl(value)}`;
|
|
178
|
+
}
|
|
179
|
+
function analyticsStatusToSyncStatus(status) {
|
|
180
|
+
switch (status) {
|
|
181
|
+
case "ready":
|
|
182
|
+
case "queryable_live":
|
|
183
|
+
case "queryable_partial": return "synced";
|
|
184
|
+
case "syncing":
|
|
185
|
+
case "preparing": return "syncing";
|
|
186
|
+
case "failed": return "error";
|
|
187
|
+
default: return "pending";
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function lifecycleSiteToUserSite(site) {
|
|
191
|
+
const syncStatus = analyticsStatusToSyncStatus(site.analytics.status);
|
|
192
|
+
return {
|
|
193
|
+
siteId: site.siteId,
|
|
194
|
+
siteUrl: site.gscPropertyUrl || site.requestedUrl,
|
|
195
|
+
analyticsSyncStatus: syncStatus,
|
|
196
|
+
analyticsSyncProgress: site.analytics.progress,
|
|
197
|
+
syncStatus,
|
|
198
|
+
syncProgress: site.analytics.progress,
|
|
199
|
+
indexingEligible: site.indexing.eligible,
|
|
200
|
+
indexingIneligibleReason: site.indexing.reason,
|
|
201
|
+
indexingPermissionLevel: site.permissionLevel,
|
|
202
|
+
indexingStatus: site.indexing.status === "ready" ? "complete" : site.indexing.status === "not_requested" ? "not_started" : "indexing",
|
|
203
|
+
indexingProgress: site.indexing.progress,
|
|
204
|
+
lastSyncAt: site.updatedAt ? Date.parse(site.updatedAt) : null,
|
|
205
|
+
newestDateSynced: site.analytics.syncedRange.newest,
|
|
206
|
+
oldestDateSynced: site.analytics.syncedRange.oldest
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function lifecycleSiteToSyncStatus(site) {
|
|
210
|
+
const syncStatus = analyticsStatusToSyncStatus(site.analytics.status);
|
|
211
|
+
const completed = site.analytics.progress.completed;
|
|
212
|
+
const failed = site.analytics.progress.failed;
|
|
213
|
+
const total = site.analytics.progress.total;
|
|
214
|
+
const queued = Math.max(total - completed - failed, 0);
|
|
215
|
+
return {
|
|
216
|
+
siteUrl: site.gscPropertyUrl || site.requestedUrl,
|
|
217
|
+
syncStatus,
|
|
218
|
+
oldestDateAvailable: site.analytics.syncedRange.oldest,
|
|
219
|
+
oldestDateSynced: site.analytics.syncedRange.oldest,
|
|
220
|
+
newestDateSynced: site.analytics.syncedRange.newest,
|
|
221
|
+
lastSyncAt: site.updatedAt ? Date.parse(site.updatedAt) : null,
|
|
222
|
+
lastError: site.latestError?.message ?? null,
|
|
223
|
+
jobs: {
|
|
224
|
+
queued,
|
|
225
|
+
processing: [
|
|
226
|
+
"queued",
|
|
227
|
+
"preparing",
|
|
228
|
+
"syncing"
|
|
229
|
+
].includes(site.analytics.status) ? 1 : 0,
|
|
230
|
+
completed,
|
|
231
|
+
failed
|
|
232
|
+
},
|
|
233
|
+
progress: site.analytics.progress.percent,
|
|
234
|
+
jobProgress: site.analytics.progress.percent,
|
|
235
|
+
daysSynced: completed,
|
|
236
|
+
daysAvailable: total,
|
|
237
|
+
isSyncing: [
|
|
238
|
+
"queued",
|
|
239
|
+
"preparing",
|
|
240
|
+
"syncing"
|
|
241
|
+
].includes(site.analytics.status),
|
|
242
|
+
hasData: site.analytics.queryable,
|
|
243
|
+
isComplete: site.analytics.queryable && site.analytics.status === "ready",
|
|
244
|
+
tables: {}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function findLifecycleSite(lifecycle, siteIdOrPropertyUrl) {
|
|
248
|
+
const normalized = normalizeLifecycleUrl(siteIdOrPropertyUrl);
|
|
249
|
+
const propertyKey = normalizeGscPropertyKey(siteIdOrPropertyUrl);
|
|
250
|
+
return lifecycle.sites.find((site) => site.siteId === siteIdOrPropertyUrl || site.externalSiteId === siteIdOrPropertyUrl || !!propertyKey && normalizeGscPropertyKey(site.gscPropertyUrl) === propertyKey || !site.gscPropertyUrl && normalizeLifecycleUrl(site.requestedUrl) === normalized || !propertyKey && normalizeLifecycleUrl(site.requestedUrl) === normalized) ?? null;
|
|
251
|
+
}
|
|
169
252
|
const TRAILING_SLASH_RE$1 = /\/+$/;
|
|
170
253
|
const LEADING_SLASH_RE = /^\/+/;
|
|
171
254
|
function trimApiBase(apiBase) {
|
|
@@ -303,6 +386,35 @@ function createPartnerClient(options = {}) {
|
|
|
303
386
|
err.data = latest;
|
|
304
387
|
throw err;
|
|
305
388
|
},
|
|
389
|
+
async waitForUserLifecycleReady(userId, waitOptions = {}) {
|
|
390
|
+
const attempts = waitOptions.attempts ?? 12;
|
|
391
|
+
const intervalMs = waitOptions.intervalMs ?? 1e3;
|
|
392
|
+
let latest = null;
|
|
393
|
+
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
394
|
+
latest = await request(partnerRoutes.users.lifecycle(userId));
|
|
395
|
+
const status = latest.account.status;
|
|
396
|
+
if (status === "ready") return latest;
|
|
397
|
+
if (status === "refresh_missing" || status === "scope_missing" || status === "reauth_required") throw new PartnerApiError({
|
|
398
|
+
kind: "auth",
|
|
399
|
+
statusCode: 401,
|
|
400
|
+
message: "Google Search Console authorization must be refreshed",
|
|
401
|
+
data: latest.account
|
|
402
|
+
});
|
|
403
|
+
if (status === "disconnected" || status === "oauth_received") throw new PartnerApiError({
|
|
404
|
+
kind: "provisioning",
|
|
405
|
+
statusCode: 409,
|
|
406
|
+
message: "gscdump user is not fully connected",
|
|
407
|
+
data: latest.account
|
|
408
|
+
});
|
|
409
|
+
if (attempt < attempts - 1) await sleep(intervalMs);
|
|
410
|
+
}
|
|
411
|
+
throw new PartnerApiError({
|
|
412
|
+
kind: "provisioning",
|
|
413
|
+
statusCode: 409,
|
|
414
|
+
message: "gscdump user database is still provisioning",
|
|
415
|
+
data: latest
|
|
416
|
+
});
|
|
417
|
+
},
|
|
306
418
|
getUserSites(userId) {
|
|
307
419
|
return request(partnerRoutes.users.sites(userId), {}, partnerEndpointSchemas.getUserSites.response);
|
|
308
420
|
},
|
|
@@ -332,8 +444,19 @@ function createPartnerClient(options = {}) {
|
|
|
332
444
|
getAnalysisSources(siteId, tables) {
|
|
333
445
|
return request(partnerRoutes.sites.analysisSources(siteId), { query: tablesQuery(tables) }, partnerEndpointSchemas.getAnalysisSources.response);
|
|
334
446
|
},
|
|
335
|
-
getSiteSyncStatus(siteId) {
|
|
336
|
-
return request(partnerRoutes.sites.syncStatus(siteId));
|
|
447
|
+
async getSiteSyncStatus(siteId, userId) {
|
|
448
|
+
if (!userId) return request(partnerRoutes.sites.syncStatus(siteId));
|
|
449
|
+
const site = findLifecycleSite(await request(partnerRoutes.users.lifecycle(userId)), siteId);
|
|
450
|
+
if (!site) throw new PartnerApiError({
|
|
451
|
+
kind: "not-found",
|
|
452
|
+
statusCode: 404,
|
|
453
|
+
message: "gscdump lifecycle site not found",
|
|
454
|
+
data: {
|
|
455
|
+
siteId,
|
|
456
|
+
userId
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
return lifecycleSiteToSyncStatus(site);
|
|
337
460
|
},
|
|
338
461
|
getData(siteId, state, queryOptions) {
|
|
339
462
|
if (shouldValidate(options, "request")) {
|
|
@@ -495,89 +618,6 @@ function createPartnerClient(options = {}) {
|
|
|
495
618
|
};
|
|
496
619
|
}
|
|
497
620
|
const createGscdumpClient = createPartnerClient;
|
|
498
|
-
function normalizeLifecycleUrl(url) {
|
|
499
|
-
return (url || "").replace(/^sc-domain:/, "").replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/$/, "").toLowerCase();
|
|
500
|
-
}
|
|
501
|
-
function normalizeGscPropertyKey(url) {
|
|
502
|
-
const value = url || "";
|
|
503
|
-
if (!value) return "";
|
|
504
|
-
if (value.startsWith("sc-domain:")) return `domain:${normalizeLifecycleUrl(value)}`;
|
|
505
|
-
if (!/^https?:\/\//.test(value)) return "";
|
|
506
|
-
return `url:${normalizeLifecycleUrl(value)}`;
|
|
507
|
-
}
|
|
508
|
-
function analyticsStatusToSyncStatus(status) {
|
|
509
|
-
switch (status) {
|
|
510
|
-
case "ready":
|
|
511
|
-
case "queryable_live":
|
|
512
|
-
case "queryable_partial": return "synced";
|
|
513
|
-
case "syncing":
|
|
514
|
-
case "preparing": return "syncing";
|
|
515
|
-
case "failed": return "error";
|
|
516
|
-
default: return "pending";
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
function lifecycleSiteToUserSite(site) {
|
|
520
|
-
const syncStatus = analyticsStatusToSyncStatus(site.analytics.status);
|
|
521
|
-
return {
|
|
522
|
-
siteId: site.siteId,
|
|
523
|
-
siteUrl: site.gscPropertyUrl || site.requestedUrl,
|
|
524
|
-
analyticsSyncStatus: syncStatus,
|
|
525
|
-
analyticsSyncProgress: site.analytics.progress,
|
|
526
|
-
syncStatus,
|
|
527
|
-
syncProgress: site.analytics.progress,
|
|
528
|
-
indexingEligible: site.indexing.eligible,
|
|
529
|
-
indexingIneligibleReason: site.indexing.reason,
|
|
530
|
-
indexingPermissionLevel: site.permissionLevel,
|
|
531
|
-
indexingStatus: site.indexing.status === "ready" ? "complete" : site.indexing.status === "not_requested" ? "not_started" : "indexing",
|
|
532
|
-
indexingProgress: site.indexing.progress,
|
|
533
|
-
lastSyncAt: site.updatedAt ? Date.parse(site.updatedAt) : null,
|
|
534
|
-
newestDateSynced: site.analytics.syncedRange.newest,
|
|
535
|
-
oldestDateSynced: site.analytics.syncedRange.oldest
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
function lifecycleSiteToSyncStatus(site) {
|
|
539
|
-
const syncStatus = analyticsStatusToSyncStatus(site.analytics.status);
|
|
540
|
-
const completed = site.analytics.progress.completed;
|
|
541
|
-
const failed = site.analytics.progress.failed;
|
|
542
|
-
const total = site.analytics.progress.total;
|
|
543
|
-
const queued = Math.max(total - completed - failed, 0);
|
|
544
|
-
return {
|
|
545
|
-
siteUrl: site.gscPropertyUrl || site.requestedUrl,
|
|
546
|
-
syncStatus,
|
|
547
|
-
oldestDateAvailable: site.analytics.syncedRange.oldest,
|
|
548
|
-
oldestDateSynced: site.analytics.syncedRange.oldest,
|
|
549
|
-
newestDateSynced: site.analytics.syncedRange.newest,
|
|
550
|
-
lastSyncAt: site.updatedAt ? Date.parse(site.updatedAt) : null,
|
|
551
|
-
lastError: site.latestError?.message ?? null,
|
|
552
|
-
jobs: {
|
|
553
|
-
queued,
|
|
554
|
-
processing: [
|
|
555
|
-
"queued",
|
|
556
|
-
"preparing",
|
|
557
|
-
"syncing"
|
|
558
|
-
].includes(site.analytics.status) ? 1 : 0,
|
|
559
|
-
completed,
|
|
560
|
-
failed
|
|
561
|
-
},
|
|
562
|
-
progress: site.analytics.progress.percent,
|
|
563
|
-
jobProgress: site.analytics.progress.percent,
|
|
564
|
-
daysSynced: completed,
|
|
565
|
-
daysAvailable: total,
|
|
566
|
-
isSyncing: [
|
|
567
|
-
"queued",
|
|
568
|
-
"preparing",
|
|
569
|
-
"syncing"
|
|
570
|
-
].includes(site.analytics.status),
|
|
571
|
-
hasData: site.analytics.queryable,
|
|
572
|
-
isComplete: site.analytics.queryable && site.analytics.status === "ready",
|
|
573
|
-
tables: {}
|
|
574
|
-
};
|
|
575
|
-
}
|
|
576
|
-
function findLifecycleSite(lifecycle, siteIdOrPropertyUrl) {
|
|
577
|
-
const normalized = normalizeLifecycleUrl(siteIdOrPropertyUrl);
|
|
578
|
-
const propertyKey = normalizeGscPropertyKey(siteIdOrPropertyUrl);
|
|
579
|
-
return lifecycle.sites.find((site) => site.siteId === siteIdOrPropertyUrl || site.externalSiteId === siteIdOrPropertyUrl || !!propertyKey && normalizeGscPropertyKey(site.gscPropertyUrl) === propertyKey || !site.gscPropertyUrl && normalizeLifecycleUrl(site.requestedUrl) === normalized || !propertyKey && normalizeLifecycleUrl(site.requestedUrl) === normalized) ?? null;
|
|
580
|
-
}
|
|
581
621
|
const HTTP_PROTOCOL_RE = /^http/i;
|
|
582
622
|
const API_SUFFIX_RE = /\/api\/?$/;
|
|
583
623
|
const TRAILING_SLASH_RE = /\/+$/;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/sdk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.17.
|
|
4
|
+
"version": "0.17.2",
|
|
5
5
|
"description": "Consumer SDK for hosted gscdump.com integrations.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"node": ">=18"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"gscdump": "0.17.
|
|
44
|
+
"gscdump": "0.17.2"
|
|
45
45
|
},
|
|
46
46
|
"peerDependenciesMeta": {
|
|
47
47
|
"gscdump": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"ofetch": "^1.5.1",
|
|
53
53
|
"zod": "^4.4.3",
|
|
54
|
-
"@gscdump/contracts": "0.17.
|
|
54
|
+
"@gscdump/contracts": "0.17.2"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"typescript": "^6.0.3",
|