@bunizao/contracts 0.6.1 → 0.7.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/dist/admin.d.ts +96 -7
- package/dist/comments.d.ts +27 -0
- package/dist/index.js +0 -6
- package/package.json +1 -1
package/dist/admin.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClientFingerprint, CommentStatus, Interaction } from './comments';
|
|
1
|
+
import type { ClientFingerprint, CommentAuthAtWrite, CommentClaimMethod, CommentStatus, Interaction } from './comments';
|
|
2
2
|
import type { DeliveryMode, NotifyAuditEventType, NotifyChannel, SubscriberRecord, SubscriberStatus } from './notify';
|
|
3
3
|
export interface SubscriberChannelCount {
|
|
4
4
|
total: number;
|
|
@@ -211,6 +211,10 @@ export interface AdminClusterCount {
|
|
|
211
211
|
and no body hash. */
|
|
212
212
|
export interface AdminCommentActor {
|
|
213
213
|
readerId: string | null;
|
|
214
|
+
/** Missing on older responses means unknown, not authenticated. */
|
|
215
|
+
authAtWrite?: CommentAuthAtWrite;
|
|
216
|
+
claimedAt?: string | null;
|
|
217
|
+
claimMethod?: CommentClaimMethod | null;
|
|
214
218
|
/** Plaintext while the row still holds it (verified: with the row;
|
|
215
219
|
unverified: seven days). */
|
|
216
220
|
email: string | null;
|
|
@@ -297,6 +301,47 @@ export interface AdminBanResult {
|
|
|
297
301
|
comments: number;
|
|
298
302
|
reactions: number;
|
|
299
303
|
};
|
|
304
|
+
operation?: AdminBanOperation | null;
|
|
305
|
+
}
|
|
306
|
+
export interface AdminBanPreview {
|
|
307
|
+
accounts: number;
|
|
308
|
+
sessions: number;
|
|
309
|
+
comments: Record<AdminCommentStatus | 'total', number>;
|
|
310
|
+
reactions: number;
|
|
311
|
+
purge: {
|
|
312
|
+
comments: number;
|
|
313
|
+
reactions: number;
|
|
314
|
+
};
|
|
315
|
+
windowDays: 90;
|
|
316
|
+
purgeLimit: number;
|
|
317
|
+
purgeAllowed: boolean;
|
|
318
|
+
}
|
|
319
|
+
export interface AdminBanOperation {
|
|
320
|
+
id: string;
|
|
321
|
+
createdAt: string;
|
|
322
|
+
source: AdminBanSource;
|
|
323
|
+
keys: AdminBanInput['keys'];
|
|
324
|
+
note: string | null;
|
|
325
|
+
purged: {
|
|
326
|
+
comments: number;
|
|
327
|
+
reactions: number;
|
|
328
|
+
};
|
|
329
|
+
restoredAt: string | null;
|
|
330
|
+
restorableUntil: string;
|
|
331
|
+
restored: {
|
|
332
|
+
comments: number;
|
|
333
|
+
reactions: number;
|
|
334
|
+
};
|
|
335
|
+
skipped: {
|
|
336
|
+
comments: number;
|
|
337
|
+
reactions: number;
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
export interface AdminBanOperationListResult {
|
|
341
|
+
operations: AdminBanOperation[];
|
|
342
|
+
}
|
|
343
|
+
export interface AdminBanRestoreResult {
|
|
344
|
+
operation: AdminBanOperation;
|
|
300
345
|
}
|
|
301
346
|
export interface AdminBanListResult {
|
|
302
347
|
bans: AdminBan[];
|
|
@@ -308,6 +353,13 @@ export interface AdminSourceProfile {
|
|
|
308
353
|
type: AdminSourceKeyType;
|
|
309
354
|
value: string;
|
|
310
355
|
};
|
|
356
|
+
identitySummary?: {
|
|
357
|
+
verifiedAccounts: number;
|
|
358
|
+
anonymousSessions: number;
|
|
359
|
+
claimedComments: number;
|
|
360
|
+
sharedStorage: boolean;
|
|
361
|
+
sharedFingerprint: boolean;
|
|
362
|
+
};
|
|
311
363
|
firstSeenAt: string | null;
|
|
312
364
|
lastSeenAt: string | null;
|
|
313
365
|
comments: {
|
|
@@ -327,9 +379,7 @@ export interface AdminSourceProfile {
|
|
|
327
379
|
/** Newest 50. */
|
|
328
380
|
rows: AdminReactionRecord[];
|
|
329
381
|
};
|
|
330
|
-
/** Distinct values
|
|
331
|
-
the churn: one fingerprint over 40 sessions and 12 IPs is a bot; one
|
|
332
|
-
session over 3 IPs is a phone that changed networks. */
|
|
382
|
+
/** Distinct observed values. Shared environments do not establish a person. */
|
|
333
383
|
spread: Record<'session' | 'ip' | 'ip24' | 'fp' | 'clientFp' | 'clientFpStable' | 'storageId' | 'email' | 'asn' | 'ua', number>;
|
|
334
384
|
/** Every bot and vpn hint this source has tripped, with how often. */
|
|
335
385
|
hints: Array<{
|
|
@@ -337,9 +387,8 @@ export interface AdminSourceProfile {
|
|
|
337
387
|
kind: 'bot' | 'vpn';
|
|
338
388
|
count: number;
|
|
339
389
|
}>;
|
|
340
|
-
/**
|
|
341
|
-
|
|
342
|
-
carried. Never `ip24`, `asn` or `ua` as a hop. */
|
|
390
|
+
/** Links describe verified-at-write account evidence or shared storage.
|
|
391
|
+
clientFpStable remains zero for compatibility; it never creates links. */
|
|
343
392
|
linked: {
|
|
344
393
|
sessions: number;
|
|
345
394
|
via: Record<'email' | 'clientFpStable' | 'storageId', number>;
|
|
@@ -374,12 +423,52 @@ export interface AdminInsightRow {
|
|
|
374
423
|
}
|
|
375
424
|
export type AdminCommentInsightsWindow = '7d' | '30d' | '90d';
|
|
376
425
|
export type AdminReactionInsightsWindow = '48h' | '7d';
|
|
426
|
+
export interface AdminCommentQuality {
|
|
427
|
+
since: string;
|
|
428
|
+
collectedSince: string | null;
|
|
429
|
+
available: {
|
|
430
|
+
moderation: boolean;
|
|
431
|
+
requests: boolean;
|
|
432
|
+
clientReports: boolean;
|
|
433
|
+
};
|
|
434
|
+
/** A cohort of automatically held comments and the first later owner decision. */
|
|
435
|
+
moderation: {
|
|
436
|
+
held: number;
|
|
437
|
+
reviewed: number;
|
|
438
|
+
released: number;
|
|
439
|
+
releasedShare: number | null;
|
|
440
|
+
};
|
|
441
|
+
/** Request outcomes include retries. Authenticated does not mean known benign. */
|
|
442
|
+
requests: {
|
|
443
|
+
attempts: number;
|
|
444
|
+
failures: number;
|
|
445
|
+
failureShare: number | null;
|
|
446
|
+
authenticatedAttempts: number;
|
|
447
|
+
authenticatedFailures: number;
|
|
448
|
+
authenticatedFailureShare: number | null;
|
|
449
|
+
outcomes: Array<{
|
|
450
|
+
kind: 'comment' | 'reaction';
|
|
451
|
+
outcome: string;
|
|
452
|
+
count: number;
|
|
453
|
+
}>;
|
|
454
|
+
};
|
|
455
|
+
/** Self-reported and incomplete when the browser cannot deliver telemetry. */
|
|
456
|
+
clientReports: {
|
|
457
|
+
reports: number;
|
|
458
|
+
failures: number;
|
|
459
|
+
networkFailures: number;
|
|
460
|
+
challengedAttempts: number;
|
|
461
|
+
repeatedChallenges: number;
|
|
462
|
+
untrusted: true;
|
|
463
|
+
};
|
|
464
|
+
}
|
|
377
465
|
/** `GET /admin/comments/insights?window=`. Every table carries a held rate,
|
|
378
466
|
because a source is only interesting relative to how the automatic pass
|
|
379
467
|
treats it. NULL groups show as their own row, never dropped. */
|
|
380
468
|
export interface AdminCommentInsights {
|
|
381
469
|
window: AdminCommentInsightsWindow;
|
|
382
470
|
since: string;
|
|
471
|
+
quality?: AdminCommentQuality;
|
|
383
472
|
networks: Array<AdminInsightRow & {
|
|
384
473
|
asn: number | null;
|
|
385
474
|
asOrg: string | null;
|
package/dist/comments.d.ts
CHANGED
|
@@ -491,3 +491,30 @@ export declare function commentPolicyFromTags(tags: readonly CommentPolicyTagLik
|
|
|
491
491
|
`readonly` and `off` answer no; the difference between them is drawn, not
|
|
492
492
|
enforced. */
|
|
493
493
|
export declare const acceptsComments: (policy: CommentPolicy) => boolean;
|
|
494
|
+
/** Evidence recorded when the comment was written, never upgraded by claiming. */
|
|
495
|
+
export type CommentAuthAtWrite = 'unknown' | 'anonymous' | 'verified';
|
|
496
|
+
export type CommentClaimMethod = 'session' | 'confirmed';
|
|
497
|
+
export interface ReaderClaimCandidate {
|
|
498
|
+
id: string;
|
|
499
|
+
surface: CommentSurface;
|
|
500
|
+
postId: string;
|
|
501
|
+
body: string;
|
|
502
|
+
createdAt: string;
|
|
503
|
+
authorName: string;
|
|
504
|
+
}
|
|
505
|
+
export interface ReaderClaimsResult {
|
|
506
|
+
comments: ReaderClaimCandidate[];
|
|
507
|
+
hasMore: boolean;
|
|
508
|
+
}
|
|
509
|
+
export interface ReaderClaimsInput {
|
|
510
|
+
commentIds: string[];
|
|
511
|
+
}
|
|
512
|
+
export interface ReaderClaimResult {
|
|
513
|
+
claimedIds: string[];
|
|
514
|
+
}
|
|
515
|
+
/** Optional client reports are operational observations, never identity evidence. */
|
|
516
|
+
export interface CommentTelemetryInput {
|
|
517
|
+
kind: 'comment' | 'reaction';
|
|
518
|
+
outcome: 'accepted' | 'http_error' | 'network_error' | 'challenge_failed';
|
|
519
|
+
challenges: number;
|
|
520
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,6 @@ var BLOG_ANALYTICS_EVENTS_DEFAULT_LIMIT = 50;
|
|
|
10
10
|
var BLOG_ANALYTICS_READ_THRESHOLD_MS = 5000;
|
|
11
11
|
var BLOG_ANALYTICS_COMPLETION_SCROLL_DEPTH = 0.9;
|
|
12
12
|
var BLOG_ANALYTICS_RANGE_OPTIONS = [7, 30, 90];
|
|
13
|
-
|
|
14
13
|
// src/comments.ts
|
|
15
14
|
var READER_PROVIDERS = ["email", "github", "google"];
|
|
16
15
|
var COMMENT_LOCALES = ["zh", "en"];
|
|
@@ -73,7 +72,6 @@ function commentPolicyFromTags(tags, base = DEFAULT_COMMENT_POLICY) {
|
|
|
73
72
|
return policy;
|
|
74
73
|
}
|
|
75
74
|
var acceptsComments = (policy) => policy.mode === "open";
|
|
76
|
-
|
|
77
75
|
// src/content.ts
|
|
78
76
|
var CONTENT_DOCUMENT_SOURCES = ["mood", "post"];
|
|
79
77
|
var POST_LOCALE_RE = /^[a-z]{2,8}(?:-[a-z0-9]{1,8})*$/;
|
|
@@ -99,15 +97,12 @@ var MESSAGE_MIN_BODY_LENGTH = 2;
|
|
|
99
97
|
var MESSAGE_MAX_BODY_LENGTH = 4000;
|
|
100
98
|
var MESSAGE_MAX_NAME_LENGTH = 32;
|
|
101
99
|
var MESSAGE_STATES = ["new", "read", "replied", "archived", "spam"];
|
|
102
|
-
|
|
103
100
|
// src/mood.ts
|
|
104
101
|
var MOOD_SENTIMENT_LABELS = ["joy", "calm", "melancholy", "anger", "anxiety", "neutral"];
|
|
105
102
|
var MOOD_AI_MODELS = ["gpt-5.5", "gpt-5", "claude-sonnet-4.6"];
|
|
106
103
|
var MOOD_COMMENT_ORIGINS = ["telegram", "web"];
|
|
107
|
-
|
|
108
104
|
// src/notify.ts
|
|
109
105
|
var NOTIFY_CHANNELS = ["mood", "blog", "privacy", "announcement"];
|
|
110
|
-
|
|
111
106
|
// src/routes.ts
|
|
112
107
|
var API_PREFIX = "/api";
|
|
113
108
|
var HEALTH_PATH = "/health";
|
|
@@ -147,7 +142,6 @@ var LEGACY_NOTIFY_BASE_PATH = "/v2/notify";
|
|
|
147
142
|
var LEGACY_GHOST_WEBHOOK_PATH = "/v2/ghost/webhook";
|
|
148
143
|
var LEGACY_MUSICKIT_TOKEN_PATH = "/v2/musickit/token";
|
|
149
144
|
var LEGACY_HEALTH_PATH = "/v2/health";
|
|
150
|
-
|
|
151
145
|
// src/telegram-ops.ts
|
|
152
146
|
var TELEGRAM_OPS_WEBHOOK_PATH = "/webhooks/telegram-ops";
|
|
153
147
|
var TELEGRAM_OPS_COMMENT_CALLBACK_PREFIXES = {
|