@bunizao/contracts 0.20.0 → 0.22.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/analytics.d.ts +1 -1
- package/dist/analytics.js +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +35 -23
- package/dist/mood.d.ts +176 -0
- package/dist/mood.js +35 -1
- package/dist/routes.d.ts +0 -7
- package/dist/routes.js +1 -13
- package/package.json +1 -6
- package/dist/desk.d.ts +0 -78
- package/dist/desk.js +0 -13
package/dist/analytics.d.ts
CHANGED
|
@@ -210,7 +210,7 @@ export declare const SITE_ANALYTICS_COLLECT_ENDPOINT: '/api/analytics/collect';
|
|
|
210
210
|
export declare const SITE_ANALYTICS_REPORT_ENDPOINT: '/api/analytics/site';
|
|
211
211
|
export declare const SITE_ANALYTICS_ENGAGED_DWELL_MS = 10000;
|
|
212
212
|
export declare const SITE_ANALYTICS_SESSION_IDLE_MS: number;
|
|
213
|
-
export declare const SITE_ANALYTICS_SURFACES: readonly ['home', 'legacy', 'not_found', 'blog_index', 'blog_tags', 'blog_tag', 'blog_post', 'mood_feed', 'mood_post', 'mood_embed', 'projects', 'message', 'privacy', 'subscribe_manage', 'reader', 'docs', 'components', 'other'];
|
|
213
|
+
export declare const SITE_ANALYTICS_SURFACES: readonly ['home', 'legacy', 'not_found', 'blog_index', 'blog_tags', 'blog_tag', 'blog_post', 'mood_feed', 'mood_post', 'mood_embed', 'mood_year', 'projects', 'message', 'privacy', 'subscribe_manage', 'reader', 'docs', 'components', 'other'];
|
|
214
214
|
export type SiteAnalyticsSurface = typeof SITE_ANALYTICS_SURFACES[number];
|
|
215
215
|
export type SiteAnalyticsClickKind = 'link_internal' | 'link_outbound' | 'button' | 'panel';
|
|
216
216
|
export type SiteAnalyticsTrafficClass = 'human' | 'bot' | 'owner';
|
package/dist/analytics.js
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ var SITE_ANALYTICS_SURFACES = [
|
|
|
25
25
|
"mood_feed",
|
|
26
26
|
"mood_post",
|
|
27
27
|
"mood_embed",
|
|
28
|
+
"mood_year",
|
|
28
29
|
"projects",
|
|
29
30
|
"message",
|
|
30
31
|
"privacy",
|
|
@@ -144,12 +145,6 @@ function parsePostLocaleTag(tagName) {
|
|
|
144
145
|
}
|
|
145
146
|
return canonicalSlug ? { locale, canonicalSlug } : { locale };
|
|
146
147
|
}
|
|
147
|
-
// src/desk.ts
|
|
148
|
-
var DESK_MAC_STATES = ["on", "locked", "sleeping", "paused"];
|
|
149
|
-
var DESK_REPORT_VERSION = 1;
|
|
150
|
-
var DESK_PRESENCE_STATES = ["awake", "idle", "asleep", "offline"];
|
|
151
|
-
var DESK_SKIES = ["clear", "cloudy", "fog", "drizzle", "rain", "snow", "storm"];
|
|
152
|
-
var DESK_LIVE_FULL_CLOSE_CODE = 1013;
|
|
153
148
|
// src/messages.ts
|
|
154
149
|
var MESSAGE_LOCALES = ["zh", "en"];
|
|
155
150
|
var MESSAGE_MIN_BODY_LENGTH = 2;
|
|
@@ -159,6 +154,38 @@ var MESSAGE_STATES = ["new", "read", "replied", "archived", "spam"];
|
|
|
159
154
|
// src/mood.ts
|
|
160
155
|
var MOOD_SENTIMENT_LABELS = ["joy", "calm", "melancholy", "anger", "anxiety", "neutral"];
|
|
161
156
|
var MOOD_AI_MODELS = ["gpt-5.5", "gpt-5", "claude-sonnet-4.6"];
|
|
157
|
+
var MOOD_TOPICS = [
|
|
158
|
+
{ id: "food-drink", zh: "饮食", en: "Food & Drink" },
|
|
159
|
+
{ id: "shopping-style", zh: "消费穿搭", en: "Shopping & Style" },
|
|
160
|
+
{ id: "money-finance", zh: "金融理财", en: "Money & Finance" },
|
|
161
|
+
{ id: "study-school", zh: "学业", en: "Study & School" },
|
|
162
|
+
{ id: "devices", zh: "数码设备", en: "Devices" },
|
|
163
|
+
{ id: "apps-services", zh: "软件服务", en: "Apps & Services" },
|
|
164
|
+
{ id: "ai", zh: "人工智能", en: "AI" },
|
|
165
|
+
{ id: "coding", zh: "编程开发", en: "Coding & Dev" },
|
|
166
|
+
{ id: "music", zh: "音乐", en: "Music" },
|
|
167
|
+
{ id: "media-entertainment", zh: "影视游戏", en: "Media & Games" },
|
|
168
|
+
{ id: "internet-culture", zh: "网络文化", en: "Internet Culture" },
|
|
169
|
+
{ id: "friends", zh: "朋友社交", en: "Friends & Social" },
|
|
170
|
+
{ id: "romance", zh: "恋爱情感", en: "Romance" },
|
|
171
|
+
{ id: "self-feelings", zh: "自我心境", en: "Self & Feelings" },
|
|
172
|
+
{ id: "reflections", zh: "感悟观点", en: "Reflections & Views" },
|
|
173
|
+
{ id: "health-sleep", zh: "健康睡眠", en: "Health & Sleep" },
|
|
174
|
+
{ id: "travel", zh: "出行旅行", en: "Travel & Transport" },
|
|
175
|
+
{ id: "daily-life", zh: "日常生活", en: "Daily Life" }
|
|
176
|
+
];
|
|
177
|
+
var MOOD_TOPIC_GROUPS = [
|
|
178
|
+
{ id: "ai", zh: "AI", en: "AI", topics: ["ai"] },
|
|
179
|
+
{ id: "tech", zh: "数码与折腾", en: "Tech & Tinkering", topics: ["devices", "apps-services", "coding"] },
|
|
180
|
+
{ id: "study", zh: "学习", en: "Study", topics: ["study-school"] },
|
|
181
|
+
{ id: "food", zh: "吃喝", en: "Food & Drink", topics: ["food-drink"] },
|
|
182
|
+
{ id: "money", zh: "钱与消费", en: "Money & Shopping", topics: ["money-finance", "shopping-style"] },
|
|
183
|
+
{ id: "people", zh: "朋友与感情", en: "Friends & Love", topics: ["friends", "romance"] },
|
|
184
|
+
{ id: "feelings", zh: "心情与想法", en: "Feelings & Thoughts", topics: ["self-feelings", "reflections"] },
|
|
185
|
+
{ id: "health", zh: "身体与睡眠", en: "Health & Sleep", topics: ["health-sleep"] },
|
|
186
|
+
{ id: "media", zh: "音乐与娱乐", en: "Music & Media", topics: ["music", "media-entertainment", "internet-culture"] },
|
|
187
|
+
{ id: "life", zh: "生活与出行", en: "Daily Life & Travel", topics: ["daily-life", "travel"] }
|
|
188
|
+
];
|
|
162
189
|
var MOOD_COMMENT_ORIGINS = ["telegram", "web"];
|
|
163
190
|
// src/notify.ts
|
|
164
191
|
var NOTIFY_CHANNELS = ["mood", "blog", "privacy", "announcement"];
|
|
@@ -178,13 +205,6 @@ var MOOD_SEARCH_PATH = "/v2/mood/search";
|
|
|
178
205
|
var MOOD_IMAGE_PROXY_BASE_PATH = "/v2/images";
|
|
179
206
|
var MOOD_MEDIA_PROXY_BASE_PATH = "/v2/media";
|
|
180
207
|
var LISTENING_PATH = "/v2/listening";
|
|
181
|
-
var DESK_PATH = "/v2/desk";
|
|
182
|
-
var DESK_LIVE_PATH = "/v2/desk/live";
|
|
183
|
-
var DESK_REPORT_PATH = "/v2/desk/report";
|
|
184
|
-
var DESK_ICONS_PATH = "/v2/desk/icons";
|
|
185
|
-
function deskIconPath(hash) {
|
|
186
|
-
return `${DESK_ICONS_PATH}/${hash}`;
|
|
187
|
-
}
|
|
188
208
|
var INSTAGRAM_PROFILE_PATH = "/v2/instagram";
|
|
189
209
|
var INSTAGRAM_AVATAR_PATH = "/v2/instagram/avatar";
|
|
190
210
|
var COMMENTS_PATH = "/v2/comments";
|
|
@@ -297,15 +317,6 @@ export {
|
|
|
297
317
|
CONTENT_DOCUMENT_SOURCES,
|
|
298
318
|
DEFAULT_COMMENT_POLICY,
|
|
299
319
|
DEFAULT_REACTION_EMOJI,
|
|
300
|
-
DESK_ICONS_PATH,
|
|
301
|
-
DESK_LIVE_FULL_CLOSE_CODE,
|
|
302
|
-
DESK_LIVE_PATH,
|
|
303
|
-
DESK_MAC_STATES,
|
|
304
|
-
DESK_PATH,
|
|
305
|
-
DESK_PRESENCE_STATES,
|
|
306
|
-
DESK_REPORT_PATH,
|
|
307
|
-
DESK_REPORT_VERSION,
|
|
308
|
-
DESK_SKIES,
|
|
309
320
|
EVENT_STATUSES,
|
|
310
321
|
GHOST_WEBHOOK_PATH,
|
|
311
322
|
HEALTH_PATH,
|
|
@@ -339,6 +350,8 @@ export {
|
|
|
339
350
|
MOOD_PUBLIC_FEED_PATH,
|
|
340
351
|
MOOD_SEARCH_PATH,
|
|
341
352
|
MOOD_SENTIMENT_LABELS,
|
|
353
|
+
MOOD_TOPICS,
|
|
354
|
+
MOOD_TOPIC_GROUPS,
|
|
342
355
|
MUSICKIT_TOKEN_PATH,
|
|
343
356
|
NEWSLETTER_ANALYTICS_CLICK_ENDPOINT,
|
|
344
357
|
NEWSLETTER_ANALYTICS_OPEN_ENDPOINT,
|
|
@@ -394,7 +407,6 @@ export {
|
|
|
394
407
|
avatarClass,
|
|
395
408
|
commentAnchorToken,
|
|
396
409
|
commentPolicyFromTags,
|
|
397
|
-
deskIconPath,
|
|
398
410
|
isAvatarSeed,
|
|
399
411
|
parsePostLocaleTag,
|
|
400
412
|
seedInClass,
|
package/dist/mood.d.ts
CHANGED
|
@@ -12,6 +12,137 @@ export declare const MOOD_SENTIMENT_LABELS: readonly ['joy', 'calm', 'melancholy
|
|
|
12
12
|
export declare const MOOD_AI_MODELS: readonly ['gpt-5.5', 'gpt-5', 'claude-sonnet-4.6'];
|
|
13
13
|
export type MoodSentimentLabel = (typeof MOOD_SENTIMENT_LABELS)[number];
|
|
14
14
|
export type MoodAiModel = string;
|
|
15
|
+
/** The fixed topic list of the per-post AI pass, with display labels. An id
|
|
16
|
+
is stable: renaming one splits its yearly history. */
|
|
17
|
+
export declare const MOOD_TOPICS: readonly [{
|
|
18
|
+
readonly id: 'food-drink';
|
|
19
|
+
readonly zh: '饮食';
|
|
20
|
+
readonly en: 'Food & Drink';
|
|
21
|
+
}, {
|
|
22
|
+
readonly id: 'shopping-style';
|
|
23
|
+
readonly zh: '消费穿搭';
|
|
24
|
+
readonly en: 'Shopping & Style';
|
|
25
|
+
}, {
|
|
26
|
+
readonly id: 'money-finance';
|
|
27
|
+
readonly zh: '金融理财';
|
|
28
|
+
readonly en: 'Money & Finance';
|
|
29
|
+
}, {
|
|
30
|
+
readonly id: 'study-school';
|
|
31
|
+
readonly zh: '学业';
|
|
32
|
+
readonly en: 'Study & School';
|
|
33
|
+
}, {
|
|
34
|
+
readonly id: 'devices';
|
|
35
|
+
readonly zh: '数码设备';
|
|
36
|
+
readonly en: 'Devices';
|
|
37
|
+
}, {
|
|
38
|
+
readonly id: 'apps-services';
|
|
39
|
+
readonly zh: '软件服务';
|
|
40
|
+
readonly en: 'Apps & Services';
|
|
41
|
+
}, {
|
|
42
|
+
readonly id: 'ai';
|
|
43
|
+
readonly zh: '人工智能';
|
|
44
|
+
readonly en: 'AI';
|
|
45
|
+
}, {
|
|
46
|
+
readonly id: 'coding';
|
|
47
|
+
readonly zh: '编程开发';
|
|
48
|
+
readonly en: 'Coding & Dev';
|
|
49
|
+
}, {
|
|
50
|
+
readonly id: 'music';
|
|
51
|
+
readonly zh: '音乐';
|
|
52
|
+
readonly en: 'Music';
|
|
53
|
+
}, {
|
|
54
|
+
readonly id: 'media-entertainment';
|
|
55
|
+
readonly zh: '影视游戏';
|
|
56
|
+
readonly en: 'Media & Games';
|
|
57
|
+
}, {
|
|
58
|
+
readonly id: 'internet-culture';
|
|
59
|
+
readonly zh: '网络文化';
|
|
60
|
+
readonly en: 'Internet Culture';
|
|
61
|
+
}, {
|
|
62
|
+
readonly id: 'friends';
|
|
63
|
+
readonly zh: '朋友社交';
|
|
64
|
+
readonly en: 'Friends & Social';
|
|
65
|
+
}, {
|
|
66
|
+
readonly id: 'romance';
|
|
67
|
+
readonly zh: '恋爱情感';
|
|
68
|
+
readonly en: 'Romance';
|
|
69
|
+
}, {
|
|
70
|
+
readonly id: 'self-feelings';
|
|
71
|
+
readonly zh: '自我心境';
|
|
72
|
+
readonly en: 'Self & Feelings';
|
|
73
|
+
}, {
|
|
74
|
+
readonly id: 'reflections';
|
|
75
|
+
readonly zh: '感悟观点';
|
|
76
|
+
readonly en: 'Reflections & Views';
|
|
77
|
+
}, {
|
|
78
|
+
readonly id: 'health-sleep';
|
|
79
|
+
readonly zh: '健康睡眠';
|
|
80
|
+
readonly en: 'Health & Sleep';
|
|
81
|
+
}, {
|
|
82
|
+
readonly id: 'travel';
|
|
83
|
+
readonly zh: '出行旅行';
|
|
84
|
+
readonly en: 'Travel & Transport';
|
|
85
|
+
}, {
|
|
86
|
+
readonly id: 'daily-life';
|
|
87
|
+
readonly zh: '日常生活';
|
|
88
|
+
readonly en: 'Daily Life';
|
|
89
|
+
}];
|
|
90
|
+
export type MoodTopicId = (typeof MOOD_TOPICS)[number]['id'];
|
|
91
|
+
/** How the yearly view counts topics: eighteen bars are too fine to read a
|
|
92
|
+
year by, so it shows these ten. Posts keep their MOOD_TOPICS ids; every id
|
|
93
|
+
sits in exactly one group. */
|
|
94
|
+
export declare const MOOD_TOPIC_GROUPS: readonly [{
|
|
95
|
+
readonly id: 'ai';
|
|
96
|
+
readonly zh: 'AI';
|
|
97
|
+
readonly en: 'AI';
|
|
98
|
+
readonly topics: readonly ["ai"];
|
|
99
|
+
}, {
|
|
100
|
+
readonly id: 'tech';
|
|
101
|
+
readonly zh: '数码与折腾';
|
|
102
|
+
readonly en: 'Tech & Tinkering';
|
|
103
|
+
readonly topics: readonly ["devices", "apps-services", "coding"];
|
|
104
|
+
}, {
|
|
105
|
+
readonly id: 'study';
|
|
106
|
+
readonly zh: '学习';
|
|
107
|
+
readonly en: 'Study';
|
|
108
|
+
readonly topics: readonly ["study-school"];
|
|
109
|
+
}, {
|
|
110
|
+
readonly id: 'food';
|
|
111
|
+
readonly zh: '吃喝';
|
|
112
|
+
readonly en: 'Food & Drink';
|
|
113
|
+
readonly topics: readonly ["food-drink"];
|
|
114
|
+
}, {
|
|
115
|
+
readonly id: 'money';
|
|
116
|
+
readonly zh: '钱与消费';
|
|
117
|
+
readonly en: 'Money & Shopping';
|
|
118
|
+
readonly topics: readonly ["money-finance", "shopping-style"];
|
|
119
|
+
}, {
|
|
120
|
+
readonly id: 'people';
|
|
121
|
+
readonly zh: '朋友与感情';
|
|
122
|
+
readonly en: 'Friends & Love';
|
|
123
|
+
readonly topics: readonly ["friends", "romance"];
|
|
124
|
+
}, {
|
|
125
|
+
readonly id: 'feelings';
|
|
126
|
+
readonly zh: '心情与想法';
|
|
127
|
+
readonly en: 'Feelings & Thoughts';
|
|
128
|
+
readonly topics: readonly ["self-feelings", "reflections"];
|
|
129
|
+
}, {
|
|
130
|
+
readonly id: 'health';
|
|
131
|
+
readonly zh: '身体与睡眠';
|
|
132
|
+
readonly en: 'Health & Sleep';
|
|
133
|
+
readonly topics: readonly ["health-sleep"];
|
|
134
|
+
}, {
|
|
135
|
+
readonly id: 'media';
|
|
136
|
+
readonly zh: '音乐与娱乐';
|
|
137
|
+
readonly en: 'Music & Media';
|
|
138
|
+
readonly topics: readonly ["music", "media-entertainment", "internet-culture"];
|
|
139
|
+
}, {
|
|
140
|
+
readonly id: 'life';
|
|
141
|
+
readonly zh: '生活与出行';
|
|
142
|
+
readonly en: 'Daily Life & Travel';
|
|
143
|
+
readonly topics: readonly ["daily-life", "travel"];
|
|
144
|
+
}];
|
|
145
|
+
export type MoodTopicGroupId = (typeof MOOD_TOPIC_GROUPS)[number]['id'];
|
|
15
146
|
export interface MoodSentiment {
|
|
16
147
|
label: MoodSentimentLabel;
|
|
17
148
|
score: number;
|
|
@@ -42,6 +173,49 @@ export interface MoodStatsSnapshot {
|
|
|
42
173
|
};
|
|
43
174
|
generatedAt: string;
|
|
44
175
|
}
|
|
176
|
+
/** One local day (the owner's Melbourne clock) of the owner's own posts. */
|
|
177
|
+
export interface MoodYearDay {
|
|
178
|
+
/** YYYY-MM-DD. */
|
|
179
|
+
date: string;
|
|
180
|
+
posts: number;
|
|
181
|
+
/** Mean sentiment score of the day's analysed posts that carry a feeling
|
|
182
|
+
(score not 0), -1 (cold) to 1 (warm), two decimals; null when none does. */
|
|
183
|
+
temperature: number | null;
|
|
184
|
+
}
|
|
185
|
+
export interface MoodYearTopic {
|
|
186
|
+
/** A MoodTopicGroupId, kept as string: a snapshot can outlive a vocabulary change. */
|
|
187
|
+
group: string;
|
|
188
|
+
/** Analysed posts with at least one topic in the group. */
|
|
189
|
+
count: number;
|
|
190
|
+
}
|
|
191
|
+
export interface MoodYearWord {
|
|
192
|
+
/** The spelling the year used most. */
|
|
193
|
+
word: string;
|
|
194
|
+
/** Posts that name it. */
|
|
195
|
+
count: number;
|
|
196
|
+
/** Message ids of the newest posts that name it, newest first, at most
|
|
197
|
+
five: where the word came from. */
|
|
198
|
+
posts: number[];
|
|
199
|
+
}
|
|
200
|
+
/** One calendar year of the owner's own words. Forwards are left out: they
|
|
201
|
+
are someone else's mood. Built once a day into KV, never per request. */
|
|
202
|
+
export interface MoodYear {
|
|
203
|
+
year: number;
|
|
204
|
+
/** Every year with posts, ascending. */
|
|
205
|
+
years: number[];
|
|
206
|
+
posts: number;
|
|
207
|
+
/** Posts the AI pass has read; sentiment, topics and words cover only these. */
|
|
208
|
+
analyzed: number;
|
|
209
|
+
/** Days with at least one post, ascending; empty days are absent. */
|
|
210
|
+
days: MoodYearDay[];
|
|
211
|
+
sentiment: Record<MoodSentimentLabel, number>;
|
|
212
|
+
/** Topic groups, most frequent first. */
|
|
213
|
+
topics: MoodYearTopic[];
|
|
214
|
+
/** Word-cloud keywords used on at least two days, most distinctive first,
|
|
215
|
+
at most 120. */
|
|
216
|
+
words: MoodYearWord[];
|
|
217
|
+
generatedAt: string;
|
|
218
|
+
}
|
|
45
219
|
export interface MoodAiConfig {
|
|
46
220
|
primary: MoodAiModel;
|
|
47
221
|
fallback: MoodAiModel;
|
|
@@ -68,6 +242,7 @@ export interface MoodIngestHealth {
|
|
|
68
242
|
coverage: {
|
|
69
243
|
sentiment: MoodCoverageSummary;
|
|
70
244
|
tags: MoodCoverageSummary;
|
|
245
|
+
topics: MoodCoverageSummary;
|
|
71
246
|
};
|
|
72
247
|
replyIntegrity: {
|
|
73
248
|
edges: number;
|
|
@@ -83,6 +258,7 @@ export interface MoodSearchResult {
|
|
|
83
258
|
datetime: string;
|
|
84
259
|
snippet: string;
|
|
85
260
|
tags: string[];
|
|
261
|
+
topics: string[];
|
|
86
262
|
sentiment_label: MoodSentimentLabel | null;
|
|
87
263
|
}
|
|
88
264
|
export interface MoodSearchResponse {
|
package/dist/mood.js
CHANGED
|
@@ -1,9 +1,43 @@
|
|
|
1
1
|
// src/mood.ts
|
|
2
2
|
var MOOD_SENTIMENT_LABELS = ["joy", "calm", "melancholy", "anger", "anxiety", "neutral"];
|
|
3
3
|
var MOOD_AI_MODELS = ["gpt-5.5", "gpt-5", "claude-sonnet-4.6"];
|
|
4
|
+
var MOOD_TOPICS = [
|
|
5
|
+
{ id: "food-drink", zh: "饮食", en: "Food & Drink" },
|
|
6
|
+
{ id: "shopping-style", zh: "消费穿搭", en: "Shopping & Style" },
|
|
7
|
+
{ id: "money-finance", zh: "金融理财", en: "Money & Finance" },
|
|
8
|
+
{ id: "study-school", zh: "学业", en: "Study & School" },
|
|
9
|
+
{ id: "devices", zh: "数码设备", en: "Devices" },
|
|
10
|
+
{ id: "apps-services", zh: "软件服务", en: "Apps & Services" },
|
|
11
|
+
{ id: "ai", zh: "人工智能", en: "AI" },
|
|
12
|
+
{ id: "coding", zh: "编程开发", en: "Coding & Dev" },
|
|
13
|
+
{ id: "music", zh: "音乐", en: "Music" },
|
|
14
|
+
{ id: "media-entertainment", zh: "影视游戏", en: "Media & Games" },
|
|
15
|
+
{ id: "internet-culture", zh: "网络文化", en: "Internet Culture" },
|
|
16
|
+
{ id: "friends", zh: "朋友社交", en: "Friends & Social" },
|
|
17
|
+
{ id: "romance", zh: "恋爱情感", en: "Romance" },
|
|
18
|
+
{ id: "self-feelings", zh: "自我心境", en: "Self & Feelings" },
|
|
19
|
+
{ id: "reflections", zh: "感悟观点", en: "Reflections & Views" },
|
|
20
|
+
{ id: "health-sleep", zh: "健康睡眠", en: "Health & Sleep" },
|
|
21
|
+
{ id: "travel", zh: "出行旅行", en: "Travel & Transport" },
|
|
22
|
+
{ id: "daily-life", zh: "日常生活", en: "Daily Life" }
|
|
23
|
+
];
|
|
24
|
+
var MOOD_TOPIC_GROUPS = [
|
|
25
|
+
{ id: "ai", zh: "AI", en: "AI", topics: ["ai"] },
|
|
26
|
+
{ id: "tech", zh: "数码与折腾", en: "Tech & Tinkering", topics: ["devices", "apps-services", "coding"] },
|
|
27
|
+
{ id: "study", zh: "学习", en: "Study", topics: ["study-school"] },
|
|
28
|
+
{ id: "food", zh: "吃喝", en: "Food & Drink", topics: ["food-drink"] },
|
|
29
|
+
{ id: "money", zh: "钱与消费", en: "Money & Shopping", topics: ["money-finance", "shopping-style"] },
|
|
30
|
+
{ id: "people", zh: "朋友与感情", en: "Friends & Love", topics: ["friends", "romance"] },
|
|
31
|
+
{ id: "feelings", zh: "心情与想法", en: "Feelings & Thoughts", topics: ["self-feelings", "reflections"] },
|
|
32
|
+
{ id: "health", zh: "身体与睡眠", en: "Health & Sleep", topics: ["health-sleep"] },
|
|
33
|
+
{ id: "media", zh: "音乐与娱乐", en: "Music & Media", topics: ["music", "media-entertainment", "internet-culture"] },
|
|
34
|
+
{ id: "life", zh: "生活与出行", en: "Daily Life & Travel", topics: ["daily-life", "travel"] }
|
|
35
|
+
];
|
|
4
36
|
var MOOD_COMMENT_ORIGINS = ["telegram", "web"];
|
|
5
37
|
export {
|
|
6
38
|
MOOD_AI_MODELS,
|
|
7
39
|
MOOD_COMMENT_ORIGINS,
|
|
8
|
-
MOOD_SENTIMENT_LABELS
|
|
40
|
+
MOOD_SENTIMENT_LABELS,
|
|
41
|
+
MOOD_TOPICS,
|
|
42
|
+
MOOD_TOPIC_GROUPS
|
|
9
43
|
};
|
package/dist/routes.d.ts
CHANGED
|
@@ -12,13 +12,6 @@ export declare const MOOD_SEARCH_PATH: '/v2/mood/search';
|
|
|
12
12
|
export declare const MOOD_IMAGE_PROXY_BASE_PATH: '/v2/images';
|
|
13
13
|
export declare const MOOD_MEDIA_PROXY_BASE_PATH: '/v2/media';
|
|
14
14
|
export declare const LISTENING_PATH: '/v2/listening';
|
|
15
|
-
export declare const DESK_PATH: '/v2/desk';
|
|
16
|
-
/** WebSocket upgrade; the server pushes DeskLive messages. */
|
|
17
|
-
export declare const DESK_LIVE_PATH: '/v2/desk/live';
|
|
18
|
-
export declare const DESK_REPORT_PATH: '/v2/desk/report';
|
|
19
|
-
/** PUT (owner-signed) and GET an app icon PNG by its sha256: `${DESK_ICONS_PATH}/<hash>`. */
|
|
20
|
-
export declare const DESK_ICONS_PATH: '/v2/desk/icons';
|
|
21
|
-
export declare function deskIconPath(hash: string): string;
|
|
22
15
|
export declare const INSTAGRAM_PROFILE_PATH: '/v2/instagram';
|
|
23
16
|
export declare const INSTAGRAM_AVATAR_PATH: '/v2/instagram/avatar';
|
|
24
17
|
export declare const COMMENTS_PATH: '/v2/comments';
|
package/dist/routes.js
CHANGED
|
@@ -13,13 +13,6 @@ var MOOD_SEARCH_PATH = "/v2/mood/search";
|
|
|
13
13
|
var MOOD_IMAGE_PROXY_BASE_PATH = "/v2/images";
|
|
14
14
|
var MOOD_MEDIA_PROXY_BASE_PATH = "/v2/media";
|
|
15
15
|
var LISTENING_PATH = "/v2/listening";
|
|
16
|
-
var DESK_PATH = "/v2/desk";
|
|
17
|
-
var DESK_LIVE_PATH = "/v2/desk/live";
|
|
18
|
-
var DESK_REPORT_PATH = "/v2/desk/report";
|
|
19
|
-
var DESK_ICONS_PATH = "/v2/desk/icons";
|
|
20
|
-
function deskIconPath(hash) {
|
|
21
|
-
return `${DESK_ICONS_PATH}/${hash}`;
|
|
22
|
-
}
|
|
23
16
|
var INSTAGRAM_PROFILE_PATH = "/v2/instagram";
|
|
24
17
|
var INSTAGRAM_AVATAR_PATH = "/v2/instagram/avatar";
|
|
25
18
|
var COMMENTS_PATH = "/v2/comments";
|
|
@@ -52,10 +45,6 @@ export {
|
|
|
52
45
|
API_PREFIX,
|
|
53
46
|
COMMENTS_PATH,
|
|
54
47
|
COMMENT_PATH_PREFIX,
|
|
55
|
-
DESK_ICONS_PATH,
|
|
56
|
-
DESK_LIVE_PATH,
|
|
57
|
-
DESK_PATH,
|
|
58
|
-
DESK_REPORT_PATH,
|
|
59
48
|
GHOST_WEBHOOK_PATH,
|
|
60
49
|
HEALTH_PATH,
|
|
61
50
|
INSTAGRAM_AVATAR_PATH,
|
|
@@ -92,6 +81,5 @@ export {
|
|
|
92
81
|
READER_PREFERENCES_PATH,
|
|
93
82
|
READER_RESEND_PATH,
|
|
94
83
|
READER_VERIFY_PATH,
|
|
95
|
-
TELEGRAM_WEBHOOK_PATH
|
|
96
|
-
deskIconPath
|
|
84
|
+
TELEGRAM_WEBHOOK_PATH
|
|
97
85
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bunizao/contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Shared TypeScript contracts for buxx.me services and clients.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -48,11 +48,6 @@
|
|
|
48
48
|
"import": "./dist/content.js",
|
|
49
49
|
"default": "./dist/content.js"
|
|
50
50
|
},
|
|
51
|
-
"./desk": {
|
|
52
|
-
"types": "./dist/desk.d.ts",
|
|
53
|
-
"import": "./dist/desk.js",
|
|
54
|
-
"default": "./dist/desk.js"
|
|
55
|
-
},
|
|
56
51
|
"./instagram": {
|
|
57
52
|
"types": "./dist/instagram.d.ts",
|
|
58
53
|
"import": "./dist/instagram.js",
|
package/dist/desk.d.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/** Mac power state as the reporter sees it. */
|
|
2
|
-
export declare const DESK_MAC_STATES: readonly ['on', 'locked', 'sleeping', 'paused'];
|
|
3
|
-
export type DeskMacState = (typeof DESK_MAC_STATES)[number];
|
|
4
|
-
/**
|
|
5
|
-
* An app on the desk. `label` is at most 24 letters, digits, spaces and dots;
|
|
6
|
-
* site-api turns anything else into "something else". `icon` is the
|
|
7
|
-
* lowercase hex sha256 of a PNG (at most 128 px a side) already uploaded to
|
|
8
|
-
* deskIconPath(icon), or null.
|
|
9
|
-
*/
|
|
10
|
-
export interface DeskApp {
|
|
11
|
-
label: string;
|
|
12
|
-
icon: string | null;
|
|
13
|
-
}
|
|
14
|
-
/** Report body version the reporter sends; site-api rejects any other. */
|
|
15
|
-
export declare const DESK_REPORT_VERSION = 1;
|
|
16
|
-
/**
|
|
17
|
-
* Body of the owner-only, HMAC-signed POST to DESK_REPORT_PATH. The server
|
|
18
|
-
* ignores a report whose sentAt is not newer than the stored one, and
|
|
19
|
-
* computes expiry from its own clock plus ttl.
|
|
20
|
-
*/
|
|
21
|
-
export interface DeskReport {
|
|
22
|
-
v: typeof DESK_REPORT_VERSION;
|
|
23
|
-
/** Reporter clock, epoch milliseconds. Only used for ordering. */
|
|
24
|
-
sentAt: number;
|
|
25
|
-
mac: DeskMacState;
|
|
26
|
-
/** Seconds since the last keyboard or pointer input. */
|
|
27
|
-
idleSeconds: number;
|
|
28
|
-
/** True while an app holds a display-sleep assertion (video, a call). */
|
|
29
|
-
screenHeld: boolean;
|
|
30
|
-
/** Apps in use, most active first; `other` for an unlisted one. Never window titles or bundle ids. */
|
|
31
|
-
apps: DeskApp[];
|
|
32
|
-
/** IANA zone of the Mac, e.g. Australia/Melbourne. */
|
|
33
|
-
timeZone: string;
|
|
34
|
-
/** Seconds this report stays valid without a successor. */
|
|
35
|
-
ttl: number;
|
|
36
|
-
}
|
|
37
|
-
export declare const DESK_PRESENCE_STATES: readonly ['awake', 'idle', 'asleep', 'offline'];
|
|
38
|
-
export type DeskPresenceState = (typeof DESK_PRESENCE_STATES)[number];
|
|
39
|
-
export declare const DESK_SKIES: readonly ['clear', 'cloudy', 'fog', 'drizzle', 'rain', 'snow', 'storm'];
|
|
40
|
-
export type Sky = (typeof DESK_SKIES)[number];
|
|
41
|
-
export interface DeskPresence {
|
|
42
|
-
state: DeskPresenceState;
|
|
43
|
-
/** Empty unless awake or idle; an unlisted app reads "something else" with no icon. */
|
|
44
|
-
apps: DeskApp[];
|
|
45
|
-
/** Seconds of lease left when computed; null when offline or asleep. */
|
|
46
|
-
validFor: number | null;
|
|
47
|
-
}
|
|
48
|
-
export interface DeskPlace {
|
|
49
|
-
/** IANA zone the clock shows; the last pushed zone, or the default. */
|
|
50
|
-
timeZone: string;
|
|
51
|
-
/** City named by the zone; null when the zone names none (e.g. UTC). */
|
|
52
|
-
city: string | null;
|
|
53
|
-
}
|
|
54
|
-
export interface DeskWeather {
|
|
55
|
-
/** Degrees Celsius, rounded. */
|
|
56
|
-
temperature: number;
|
|
57
|
-
sky: Sky;
|
|
58
|
-
/** Daylight at the place right now. */
|
|
59
|
-
day: boolean;
|
|
60
|
-
}
|
|
61
|
-
/** Response of GET DESK_PATH. Fields are only ever added. */
|
|
62
|
-
export interface DeskNow {
|
|
63
|
-
presence: DeskPresence;
|
|
64
|
-
place: DeskPlace;
|
|
65
|
-
/** Null when the weather source is unavailable. */
|
|
66
|
-
weather: DeskWeather | null;
|
|
67
|
-
}
|
|
68
|
-
/** Close code the live socket uses when it is full; poll instead. */
|
|
69
|
-
export declare const DESK_LIVE_FULL_CLOSE_CODE = 1013;
|
|
70
|
-
/**
|
|
71
|
-
* Message the live socket at DESK_LIVE_PATH sends on connect and whenever
|
|
72
|
-
* presence or place changes. Weather is not pushed; read it from DESK_PATH.
|
|
73
|
-
* The socket answers the text `ping` with `pong`. Fields are only ever added.
|
|
74
|
-
*/
|
|
75
|
-
export interface DeskLive {
|
|
76
|
-
presence: DeskPresence;
|
|
77
|
-
place: DeskPlace;
|
|
78
|
-
}
|
package/dist/desk.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// src/desk.ts
|
|
2
|
-
var DESK_MAC_STATES = ["on", "locked", "sleeping", "paused"];
|
|
3
|
-
var DESK_REPORT_VERSION = 1;
|
|
4
|
-
var DESK_PRESENCE_STATES = ["awake", "idle", "asleep", "offline"];
|
|
5
|
-
var DESK_SKIES = ["clear", "cloudy", "fog", "drizzle", "rain", "snow", "storm"];
|
|
6
|
-
var DESK_LIVE_FULL_CLOSE_CODE = 1013;
|
|
7
|
-
export {
|
|
8
|
-
DESK_LIVE_FULL_CLOSE_CODE,
|
|
9
|
-
DESK_MAC_STATES,
|
|
10
|
-
DESK_PRESENCE_STATES,
|
|
11
|
-
DESK_REPORT_VERSION,
|
|
12
|
-
DESK_SKIES
|
|
13
|
-
};
|