sa2kit 1.6.91 → 1.6.96

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.
Files changed (117) hide show
  1. package/dist/client-BlkUL2To.d.ts +26 -0
  2. package/dist/client-DpMIhrlS.d.mts +26 -0
  3. package/dist/huarongdao/index.d.mts +8 -0
  4. package/dist/huarongdao/index.d.ts +8 -0
  5. package/dist/huarongdao/index.js +360 -0
  6. package/dist/huarongdao/index.js.map +1 -0
  7. package/dist/huarongdao/index.mjs +338 -0
  8. package/dist/huarongdao/index.mjs.map +1 -0
  9. package/dist/huarongdao/logic/index.d.mts +11 -0
  10. package/dist/huarongdao/logic/index.d.ts +11 -0
  11. package/dist/huarongdao/logic/index.js +89 -0
  12. package/dist/huarongdao/logic/index.js.map +1 -0
  13. package/dist/huarongdao/logic/index.mjs +81 -0
  14. package/dist/huarongdao/logic/index.mjs.map +1 -0
  15. package/dist/huarongdao/routes/index.d.mts +38 -0
  16. package/dist/huarongdao/routes/index.d.ts +38 -0
  17. package/dist/huarongdao/routes/index.js +114 -0
  18. package/dist/huarongdao/routes/index.js.map +1 -0
  19. package/dist/huarongdao/routes/index.mjs +108 -0
  20. package/dist/huarongdao/routes/index.mjs.map +1 -0
  21. package/dist/huarongdao/server/index.d.mts +14 -0
  22. package/dist/huarongdao/server/index.d.ts +14 -0
  23. package/dist/huarongdao/server/index.js +60 -0
  24. package/dist/huarongdao/server/index.js.map +1 -0
  25. package/dist/huarongdao/server/index.mjs +57 -0
  26. package/dist/huarongdao/server/index.mjs.map +1 -0
  27. package/dist/huarongdao/service/index.d.mts +31 -0
  28. package/dist/huarongdao/service/index.d.ts +31 -0
  29. package/dist/huarongdao/service/index.js +45 -0
  30. package/dist/huarongdao/service/index.js.map +1 -0
  31. package/dist/huarongdao/service/index.mjs +42 -0
  32. package/dist/huarongdao/service/index.mjs.map +1 -0
  33. package/dist/huarongdao/types/index.d.mts +46 -0
  34. package/dist/huarongdao/types/index.d.ts +46 -0
  35. package/dist/huarongdao/types/index.js +4 -0
  36. package/dist/huarongdao/types/index.js.map +1 -0
  37. package/dist/huarongdao/types/index.mjs +3 -0
  38. package/dist/huarongdao/types/index.mjs.map +1 -0
  39. package/dist/huarongdao/ui/web/index.d.mts +3 -0
  40. package/dist/huarongdao/ui/web/index.d.ts +3 -0
  41. package/dist/huarongdao/ui/web/index.js +237 -0
  42. package/dist/huarongdao/ui/web/index.js.map +1 -0
  43. package/dist/huarongdao/ui/web/index.mjs +229 -0
  44. package/dist/huarongdao/ui/web/index.mjs.map +1 -0
  45. package/dist/index-B48rcsqv.d.ts +27 -0
  46. package/dist/index-BNqJdwX4.d.ts +37 -0
  47. package/dist/index-C7yh6b5Q.d.mts +17 -0
  48. package/dist/index-CDapUIT5.d.mts +51 -0
  49. package/dist/index-Cv9jlnNz.d.ts +17 -0
  50. package/dist/index-D3UbkUai.d.ts +51 -0
  51. package/dist/index-DOtQI_mz.d.mts +37 -0
  52. package/dist/index-Da2X78GE.d.mts +27 -0
  53. package/dist/index.d.mts +18 -0
  54. package/dist/index.d.ts +18 -0
  55. package/dist/index.js +1707 -79
  56. package/dist/index.js.map +1 -1
  57. package/dist/index.mjs +1675 -82
  58. package/dist/index.mjs.map +1 -1
  59. package/dist/mikuContest/index.d.mts +13 -0
  60. package/dist/mikuContest/index.d.ts +13 -0
  61. package/dist/mikuContest/index.js +1310 -0
  62. package/dist/mikuContest/index.js.map +1 -0
  63. package/dist/mikuContest/index.mjs +1253 -0
  64. package/dist/mikuContest/index.mjs.map +1 -0
  65. package/dist/mikuContest/logic/index.d.mts +32 -0
  66. package/dist/mikuContest/logic/index.d.ts +32 -0
  67. package/dist/mikuContest/logic/index.js +511 -0
  68. package/dist/mikuContest/logic/index.js.map +1 -0
  69. package/dist/mikuContest/logic/index.mjs +483 -0
  70. package/dist/mikuContest/logic/index.mjs.map +1 -0
  71. package/dist/mikuContest/routes/index.d.mts +80 -0
  72. package/dist/mikuContest/routes/index.d.ts +80 -0
  73. package/dist/mikuContest/routes/index.js +821 -0
  74. package/dist/mikuContest/routes/index.js.map +1 -0
  75. package/dist/mikuContest/routes/index.mjs +791 -0
  76. package/dist/mikuContest/routes/index.mjs.map +1 -0
  77. package/dist/mikuContest/server/index.d.mts +766 -0
  78. package/dist/mikuContest/server/index.d.ts +766 -0
  79. package/dist/mikuContest/server/index.js +705 -0
  80. package/dist/mikuContest/server/index.js.map +1 -0
  81. package/dist/mikuContest/server/index.mjs +672 -0
  82. package/dist/mikuContest/server/index.mjs.map +1 -0
  83. package/dist/mikuContest/service/index.d.mts +30 -0
  84. package/dist/mikuContest/service/index.d.ts +30 -0
  85. package/dist/mikuContest/service/index.js +139 -0
  86. package/dist/mikuContest/service/index.js.map +1 -0
  87. package/dist/mikuContest/service/index.mjs +135 -0
  88. package/dist/mikuContest/service/index.mjs.map +1 -0
  89. package/dist/mikuContest/types/index.d.mts +179 -0
  90. package/dist/mikuContest/types/index.d.ts +179 -0
  91. package/dist/mikuContest/types/index.js +4 -0
  92. package/dist/mikuContest/types/index.js.map +1 -0
  93. package/dist/mikuContest/types/index.mjs +3 -0
  94. package/dist/mikuContest/types/index.mjs.map +1 -0
  95. package/dist/mikuContest/ui/miniapp/index.d.mts +3 -0
  96. package/dist/mikuContest/ui/miniapp/index.d.ts +3 -0
  97. package/dist/mikuContest/ui/miniapp/index.js +566 -0
  98. package/dist/mikuContest/ui/miniapp/index.js.map +1 -0
  99. package/dist/mikuContest/ui/miniapp/index.mjs +540 -0
  100. package/dist/mikuContest/ui/miniapp/index.mjs.map +1 -0
  101. package/dist/mikuContest/ui/web/index.d.mts +4 -0
  102. package/dist/mikuContest/ui/web/index.d.ts +4 -0
  103. package/dist/mikuContest/ui/web/index.js +353 -0
  104. package/dist/mikuContest/ui/web/index.js.map +1 -0
  105. package/dist/mikuContest/ui/web/index.mjs +343 -0
  106. package/dist/mikuContest/ui/web/index.mjs.map +1 -0
  107. package/dist/qqbot/server/index.d.mts +126 -1
  108. package/dist/qqbot/server/index.d.ts +126 -1
  109. package/dist/qqbot/server/index.js +250 -0
  110. package/dist/qqbot/server/index.js.map +1 -1
  111. package/dist/qqbot/server/index.mjs +246 -1
  112. package/dist/qqbot/server/index.mjs.map +1 -1
  113. package/dist/service-D7DM1wW-.d.ts +38 -0
  114. package/dist/service-DPr2rlvH.d.mts +38 -0
  115. package/dist/types-BS7Xz09b.d.mts +14 -0
  116. package/dist/types-k4koMp4m.d.ts +14 -0
  117. package/package.json +76 -1
@@ -1,4 +1,6 @@
1
1
  import { NextResponse } from 'next/server';
2
+ import { readFile, mkdir, writeFile } from 'fs/promises';
3
+ import { dirname } from 'path';
2
4
 
3
5
  // src/qqbot/server/client.ts
4
6
  var NapCatClient = class {
@@ -135,6 +137,249 @@ function createNextNapCatRouteHandler(config) {
135
137
  };
136
138
  }
137
139
 
138
- export { NapCatClient, createNapCatWebApi, createNextNapCatRouteHandler };
140
+ // src/qqbot/server/xhsMonitor/notifier.ts
141
+ function defaultMessageTemplate(payload) {
142
+ return [
143
+ `\u3010\u5C0F\u7EA2\u4E66\u65B0\u5E16\u63D0\u9192\u3011${payload.accountLabel}`,
144
+ payload.post.title ? `\u6807\u9898\uFF1A${payload.post.title}` : void 0,
145
+ `\u94FE\u63A5\uFF1A${payload.post.url}`,
146
+ `\u68C0\u6D4B\u65F6\u95F4\uFF1A${payload.detectedAt}`
147
+ ].filter(Boolean).join("\n");
148
+ }
149
+ var XhsQqNotifier = class {
150
+ constructor(options) {
151
+ this.client = options.client;
152
+ this.target = options.target;
153
+ this.messageTemplate = options.messageTemplate ?? defaultMessageTemplate;
154
+ }
155
+ async notify(payload) {
156
+ const message = this.messageTemplate(payload);
157
+ const response = this.target.type === "group" ? await this.client.sendGroupMessage({
158
+ group_id: this.target.groupId,
159
+ message
160
+ }) : await this.client.sendPrivateMessage({
161
+ user_id: this.target.userId,
162
+ message
163
+ });
164
+ if (response.status !== "ok") {
165
+ throw new Error(`Failed to send QQ message: ${response.message ?? "Unknown error"}`);
166
+ }
167
+ }
168
+ };
169
+
170
+ // src/qqbot/server/xhsMonitor/source.ts
171
+ function decodeHtmlEntities(input) {
172
+ return input.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">").replace(/\\u0026/g, "&").replace(/\\"/g, '"').replace(/\\n/g, " ").trim();
173
+ }
174
+ function normalizeTitle(title) {
175
+ return decodeHtmlEntities(title).replace(/\s+/g, " ").trim();
176
+ }
177
+ var XhsProfileHtmlSource = class {
178
+ constructor(options) {
179
+ this.profileUrl = options.profileUrl;
180
+ this.timeoutMs = options.timeoutMs ?? 12e3;
181
+ this.userAgent = options.userAgent ?? "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0 Safari/537.36";
182
+ }
183
+ async fetchLatestPosts(limit = 20) {
184
+ const controller = new AbortController();
185
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
186
+ try {
187
+ const response = await fetch(this.profileUrl, {
188
+ method: "GET",
189
+ headers: {
190
+ "User-Agent": this.userAgent,
191
+ Accept: "text/html,application/xhtml+xml"
192
+ },
193
+ signal: controller.signal
194
+ });
195
+ if (!response.ok) {
196
+ throw new Error(`Failed to fetch profile page: HTTP ${response.status}`);
197
+ }
198
+ const html = await response.text();
199
+ return this.parsePostsFromHtml(html, limit);
200
+ } finally {
201
+ clearTimeout(timer);
202
+ }
203
+ }
204
+ parsePostsFromHtml(html, limit) {
205
+ const idMatches = [...html.matchAll(/(?:\/explore\/|\"noteId\"\s*:\s*\")([a-zA-Z0-9_-]{8,32})/g)];
206
+ const titleMatches = [...html.matchAll(/\"displayTitle\"\s*:\s*\"([^"]{1,120})\"/g)];
207
+ const uniqueIds = [];
208
+ const seen = /* @__PURE__ */ new Set();
209
+ for (const match of idMatches) {
210
+ const id = match[1];
211
+ if (!id || seen.has(id)) {
212
+ continue;
213
+ }
214
+ seen.add(id);
215
+ uniqueIds.push(id);
216
+ if (uniqueIds.length >= limit) {
217
+ break;
218
+ }
219
+ }
220
+ const titles = titleMatches.map((match) => normalizeTitle(match[1] ?? "")).filter(Boolean);
221
+ return uniqueIds.map((id, index) => ({
222
+ id,
223
+ url: `https://www.xiaohongshu.com/explore/${id}`,
224
+ title: titles[index]
225
+ }));
226
+ }
227
+ };
228
+ var DEFAULT_STATE = {
229
+ seenPostIds: [],
230
+ updatedAt: (/* @__PURE__ */ new Date(0)).toISOString()
231
+ };
232
+ var FileXhsMonitorStateStore = class {
233
+ constructor(options) {
234
+ this.filePath = options.filePath;
235
+ this.maxSeenPostIds = Math.max(10, options.maxSeenPostIds ?? 500);
236
+ }
237
+ async read() {
238
+ try {
239
+ const text = await readFile(this.filePath, "utf8");
240
+ const parsed = JSON.parse(text);
241
+ const seenPostIds = Array.isArray(parsed.seenPostIds) ? parsed.seenPostIds.filter((item) => typeof item === "string") : [];
242
+ const updatedAt = typeof parsed.updatedAt === "string" ? parsed.updatedAt : (/* @__PURE__ */ new Date()).toISOString();
243
+ return {
244
+ seenPostIds: seenPostIds.slice(0, this.maxSeenPostIds),
245
+ updatedAt
246
+ };
247
+ } catch {
248
+ return DEFAULT_STATE;
249
+ }
250
+ }
251
+ async write(state) {
252
+ await mkdir(dirname(this.filePath), { recursive: true });
253
+ const compactState = {
254
+ seenPostIds: state.seenPostIds.slice(0, this.maxSeenPostIds),
255
+ updatedAt: state.updatedAt
256
+ };
257
+ await writeFile(this.filePath, JSON.stringify(compactState, null, 2), "utf8");
258
+ }
259
+ };
260
+
261
+ // src/qqbot/server/xhsMonitor/service.ts
262
+ function sortPostsByPublishedAt(posts) {
263
+ return [...posts].sort((a, b) => {
264
+ const ta = a.publishedAt ? Date.parse(a.publishedAt) : Number.NaN;
265
+ const tb = b.publishedAt ? Date.parse(b.publishedAt) : Number.NaN;
266
+ if (Number.isNaN(ta) || Number.isNaN(tb)) {
267
+ return 0;
268
+ }
269
+ return ta - tb;
270
+ });
271
+ }
272
+ var XhsMonitorService = class {
273
+ constructor(options) {
274
+ this.timer = null;
275
+ this.initialized = false;
276
+ this.running = false;
277
+ this.accountLabel = options.accountLabel;
278
+ this.source = options.source;
279
+ this.notifier = options.notifier;
280
+ this.stateStore = options.stateStore;
281
+ this.pollIntervalMs = Math.max(5e3, options.pollIntervalMs);
282
+ this.skipInitialSnapshot = options.skipInitialSnapshot ?? true;
283
+ this.postLimit = options.postLimit ?? 20;
284
+ this.now = options.now ?? (() => /* @__PURE__ */ new Date());
285
+ }
286
+ async checkOnce() {
287
+ if (this.running) {
288
+ return { notifiedCount: 0, fetchedCount: 0 };
289
+ }
290
+ this.running = true;
291
+ try {
292
+ const state = await this.stateStore.read();
293
+ const seen = new Set(state.seenPostIds);
294
+ const posts = await this.source.fetchLatestPosts(this.postLimit);
295
+ const orderedPosts = sortPostsByPublishedAt(posts);
296
+ const newlyDetected = orderedPosts.filter((post) => !seen.has(post.id));
297
+ if (!this.initialized && this.skipInitialSnapshot) {
298
+ for (const post of orderedPosts) {
299
+ seen.add(post.id);
300
+ }
301
+ await this.persistSeenIds(seen);
302
+ this.initialized = true;
303
+ return { notifiedCount: 0, fetchedCount: posts.length };
304
+ }
305
+ let notifiedCount = 0;
306
+ for (const post of newlyDetected) {
307
+ await this.notifier.notify({
308
+ accountLabel: this.accountLabel,
309
+ post,
310
+ detectedAt: this.now().toISOString()
311
+ });
312
+ notifiedCount += 1;
313
+ seen.add(post.id);
314
+ }
315
+ if (newlyDetected.length > 0 || !this.initialized) {
316
+ for (const post of orderedPosts) {
317
+ seen.add(post.id);
318
+ }
319
+ await this.persistSeenIds(seen);
320
+ }
321
+ this.initialized = true;
322
+ return { notifiedCount, fetchedCount: posts.length };
323
+ } finally {
324
+ this.running = false;
325
+ }
326
+ }
327
+ start(immediate = true) {
328
+ if (this.timer) {
329
+ return;
330
+ }
331
+ const run = async () => {
332
+ try {
333
+ await this.checkOnce();
334
+ } catch (error) {
335
+ console.error("[XhsMonitorService] check failed", error);
336
+ }
337
+ };
338
+ if (immediate) {
339
+ void run();
340
+ }
341
+ this.timer = setInterval(() => {
342
+ void run();
343
+ }, this.pollIntervalMs);
344
+ }
345
+ stop() {
346
+ if (this.timer) {
347
+ clearInterval(this.timer);
348
+ this.timer = null;
349
+ }
350
+ }
351
+ async persistSeenIds(seenIds) {
352
+ await this.stateStore.write({
353
+ seenPostIds: Array.from(seenIds).slice(-500),
354
+ updatedAt: this.now().toISOString()
355
+ });
356
+ }
357
+ };
358
+
359
+ // src/qqbot/server/xhsMonitor/app.ts
360
+ function createXhsMonitorApp(options) {
361
+ const client = new NapCatClient(options.napCat);
362
+ const source = new XhsProfileHtmlSource({
363
+ profileUrl: options.profileUrl
364
+ });
365
+ const stateStore = new FileXhsMonitorStateStore({
366
+ filePath: options.stateFilePath
367
+ });
368
+ const notifier = new XhsQqNotifier({
369
+ client,
370
+ target: options.target
371
+ });
372
+ return new XhsMonitorService({
373
+ accountLabel: options.accountLabel,
374
+ source,
375
+ notifier,
376
+ stateStore,
377
+ pollIntervalMs: options.pollIntervalMs,
378
+ skipInitialSnapshot: options.skipInitialSnapshot,
379
+ postLimit: options.postLimit
380
+ });
381
+ }
382
+
383
+ export { FileXhsMonitorStateStore, NapCatClient, XhsMonitorService, XhsProfileHtmlSource, XhsQqNotifier, createNapCatWebApi, createNextNapCatRouteHandler, createXhsMonitorApp };
139
384
  //# sourceMappingURL=index.mjs.map
140
385
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/qqbot/server/client.ts","../../../src/qqbot/server/webApi.ts","../../../src/qqbot/server/nextRouteAdapter.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import {\n NapCatConfig,\n OneBotActionResponse,\n OneBotFriendInfo,\n OneBotGroupInfo,\n SendGroupMessagePayload,\n SendPrivateMessagePayload,\n} from '../types';\n\nexport class NapCatClient {\n private readonly baseUrl: string;\n private readonly accessToken?: string;\n private readonly timeoutMs: number;\n\n constructor(config: NapCatConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.accessToken = config.accessToken;\n this.timeoutMs = config.timeoutMs ?? 12000;\n }\n\n async callApi<TData = unknown>(action: string, params?: Record<string, unknown>): Promise<OneBotActionResponse<TData>> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const response = await fetch(`${this.baseUrl}/${action}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}),\n },\n body: JSON.stringify(params ?? {}),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n return {\n status: 'failed',\n retcode: response.status,\n message: `NapCat HTTP ${response.status}`,\n };\n }\n\n const payload = (await response.json()) as OneBotActionResponse<TData>;\n return payload;\n } catch (error) {\n return {\n status: 'failed',\n retcode: -1,\n message: error instanceof Error ? error.message : 'Unknown NapCat request error',\n };\n } finally {\n clearTimeout(timeout);\n }\n }\n\n async sendGroupMessage(payload: SendGroupMessagePayload) {\n return this.callApi<{ message_id: number }>('send_group_msg', payload as unknown as Record<string, unknown>);\n }\n\n async sendPrivateMessage(payload: SendPrivateMessagePayload) {\n return this.callApi<{ message_id: number }>('send_private_msg', payload as unknown as Record<string, unknown>);\n }\n\n async getGroupList() {\n return this.callApi<OneBotGroupInfo[]>('get_group_list');\n }\n\n async getFriendList() {\n return this.callApi<OneBotFriendInfo[]>('get_friend_list');\n }\n}\n","import { NapCatWebhookEvent, NapCatWebApiResponse } from '../types';\nimport { NapCatClient } from './client';\n\nexport interface HttpLikeRequest {\n method: string;\n path: string;\n body?: unknown;\n}\n\nexport interface HttpLikeResponse {\n status: number;\n headers?: Record<string, string>;\n body: NapCatWebApiResponse<unknown>;\n}\n\nexport interface NapCatWebApiOptions {\n onWebhookEvent?: (event: NapCatWebhookEvent) => Promise<void> | void;\n}\n\nfunction json(status: number, body: NapCatWebApiResponse<unknown>): HttpLikeResponse {\n return {\n status,\n headers: { 'Content-Type': 'application/json' },\n body,\n };\n}\n\nexport function createNapCatWebApi(client: NapCatClient, options: NapCatWebApiOptions = {}) {\n return async function handle(request: HttpLikeRequest): Promise<HttpLikeResponse> {\n const method = request.method.toUpperCase();\n\n if (method === 'GET' && request.path === '/health') {\n return json(200, { ok: true, data: { service: 'qqbot-napcat-bridge' } });\n }\n\n if (method === 'POST' && request.path === '/send/group') {\n const result = await client.sendGroupMessage((request.body ?? {}) as any);\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/send/private') {\n const result = await client.sendPrivateMessage((request.body ?? {}) as any);\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/groups') {\n const result = await client.getGroupList();\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/friends') {\n const result = await client.getFriendList();\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path.startsWith('/action/')) {\n const action = request.path.replace('/action/', '');\n const result = await client.callApi(action, (request.body ?? {}) as Record<string, unknown>);\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/webhook/event') {\n const event = (request.body ?? {}) as NapCatWebhookEvent;\n await options.onWebhookEvent?.(event);\n return json(200, { ok: true });\n }\n\n return json(404, { ok: false, error: `Route not found: ${method} ${request.path}` });\n };\n}\n","import { NextRequest, NextResponse } from 'next/server';\nimport { HttpLikeRequest, createNapCatWebApi } from './webApi';\nimport { NapCatClient } from './client';\n\nexport interface NextNapCatRouteConfig {\n client: NapCatClient;\n basePath?: string;\n onWebhookEvent?: (event: Record<string, unknown>) => Promise<void> | void;\n}\n\nexport function createNextNapCatRouteHandler(config: NextNapCatRouteConfig) {\n const basePath = config.basePath ?? '/api/qqbot';\n const handle = createNapCatWebApi(config.client, {\n onWebhookEvent: config.onWebhookEvent,\n });\n\n return async function handler(request: NextRequest) {\n const url = new URL(request.url);\n const path = url.pathname.startsWith(basePath) ? url.pathname.slice(basePath.length) || '/' : url.pathname;\n\n const body = request.method.toUpperCase() === 'GET' ? undefined : await request.json().catch(() => undefined);\n\n const payload: HttpLikeRequest = {\n method: request.method,\n path,\n body,\n };\n\n const result = await handle(payload);\n return NextResponse.json(result.body, { status: result.status, headers: result.headers });\n };\n}\n"]}
1
+ {"version":3,"sources":["../../../src/qqbot/server/client.ts","../../../src/qqbot/server/webApi.ts","../../../src/qqbot/server/nextRouteAdapter.ts","../../../src/qqbot/server/xhsMonitor/notifier.ts","../../../src/qqbot/server/xhsMonitor/source.ts","../../../src/qqbot/server/xhsMonitor/stateStore.ts","../../../src/qqbot/server/xhsMonitor/service.ts","../../../src/qqbot/server/xhsMonitor/app.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import {\n NapCatConfig,\n OneBotActionResponse,\n OneBotFriendInfo,\n OneBotGroupInfo,\n SendGroupMessagePayload,\n SendPrivateMessagePayload,\n} from '../types';\n\nexport class NapCatClient {\n private readonly baseUrl: string;\n private readonly accessToken?: string;\n private readonly timeoutMs: number;\n\n constructor(config: NapCatConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.accessToken = config.accessToken;\n this.timeoutMs = config.timeoutMs ?? 12000;\n }\n\n async callApi<TData = unknown>(action: string, params?: Record<string, unknown>): Promise<OneBotActionResponse<TData>> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const response = await fetch(`${this.baseUrl}/${action}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}),\n },\n body: JSON.stringify(params ?? {}),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n return {\n status: 'failed',\n retcode: response.status,\n message: `NapCat HTTP ${response.status}`,\n };\n }\n\n const payload = (await response.json()) as OneBotActionResponse<TData>;\n return payload;\n } catch (error) {\n return {\n status: 'failed',\n retcode: -1,\n message: error instanceof Error ? error.message : 'Unknown NapCat request error',\n };\n } finally {\n clearTimeout(timeout);\n }\n }\n\n async sendGroupMessage(payload: SendGroupMessagePayload) {\n return this.callApi<{ message_id: number }>('send_group_msg', payload as unknown as Record<string, unknown>);\n }\n\n async sendPrivateMessage(payload: SendPrivateMessagePayload) {\n return this.callApi<{ message_id: number }>('send_private_msg', payload as unknown as Record<string, unknown>);\n }\n\n async getGroupList() {\n return this.callApi<OneBotGroupInfo[]>('get_group_list');\n }\n\n async getFriendList() {\n return this.callApi<OneBotFriendInfo[]>('get_friend_list');\n }\n}\n","import { NapCatWebhookEvent, NapCatWebApiResponse } from '../types';\nimport { NapCatClient } from './client';\n\nexport interface HttpLikeRequest {\n method: string;\n path: string;\n body?: unknown;\n}\n\nexport interface HttpLikeResponse {\n status: number;\n headers?: Record<string, string>;\n body: NapCatWebApiResponse<unknown>;\n}\n\nexport interface NapCatWebApiOptions {\n onWebhookEvent?: (event: NapCatWebhookEvent) => Promise<void> | void;\n}\n\nfunction json(status: number, body: NapCatWebApiResponse<unknown>): HttpLikeResponse {\n return {\n status,\n headers: { 'Content-Type': 'application/json' },\n body,\n };\n}\n\nexport function createNapCatWebApi(client: NapCatClient, options: NapCatWebApiOptions = {}) {\n return async function handle(request: HttpLikeRequest): Promise<HttpLikeResponse> {\n const method = request.method.toUpperCase();\n\n if (method === 'GET' && request.path === '/health') {\n return json(200, { ok: true, data: { service: 'qqbot-napcat-bridge' } });\n }\n\n if (method === 'POST' && request.path === '/send/group') {\n const result = await client.sendGroupMessage((request.body ?? {}) as any);\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/send/private') {\n const result = await client.sendPrivateMessage((request.body ?? {}) as any);\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/groups') {\n const result = await client.getGroupList();\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/friends') {\n const result = await client.getFriendList();\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path.startsWith('/action/')) {\n const action = request.path.replace('/action/', '');\n const result = await client.callApi(action, (request.body ?? {}) as Record<string, unknown>);\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/webhook/event') {\n const event = (request.body ?? {}) as NapCatWebhookEvent;\n await options.onWebhookEvent?.(event);\n return json(200, { ok: true });\n }\n\n return json(404, { ok: false, error: `Route not found: ${method} ${request.path}` });\n };\n}\n","import { NextRequest, NextResponse } from 'next/server';\nimport { HttpLikeRequest, createNapCatWebApi } from './webApi';\nimport { NapCatClient } from './client';\n\nexport interface NextNapCatRouteConfig {\n client: NapCatClient;\n basePath?: string;\n onWebhookEvent?: (event: Record<string, unknown>) => Promise<void> | void;\n}\n\nexport function createNextNapCatRouteHandler(config: NextNapCatRouteConfig) {\n const basePath = config.basePath ?? '/api/qqbot';\n const handle = createNapCatWebApi(config.client, {\n onWebhookEvent: config.onWebhookEvent,\n });\n\n return async function handler(request: NextRequest) {\n const url = new URL(request.url);\n const path = url.pathname.startsWith(basePath) ? url.pathname.slice(basePath.length) || '/' : url.pathname;\n\n const body = request.method.toUpperCase() === 'GET' ? undefined : await request.json().catch(() => undefined);\n\n const payload: HttpLikeRequest = {\n method: request.method,\n path,\n body,\n };\n\n const result = await handle(payload);\n return NextResponse.json(result.body, { status: result.status, headers: result.headers });\n };\n}\n","import { NapCatClient } from '../client';\nimport { XhsNotificationPayload, XhsNotifier } from './types';\n\nexport interface XhsQqNotifierOptions {\n client: NapCatClient;\n target: { type: 'group'; groupId: number } | { type: 'private'; userId: number };\n messageTemplate?: (payload: XhsNotificationPayload) => string;\n}\n\nfunction defaultMessageTemplate(payload: XhsNotificationPayload): string {\n return [\n `【小红书新帖提醒】${payload.accountLabel}`,\n payload.post.title ? `标题:${payload.post.title}` : undefined,\n `链接:${payload.post.url}`,\n `检测时间:${payload.detectedAt}`,\n ]\n .filter(Boolean)\n .join('\\n');\n}\n\nexport class XhsQqNotifier implements XhsNotifier {\n private readonly client: NapCatClient;\n private readonly target: XhsQqNotifierOptions['target'];\n private readonly messageTemplate: (payload: XhsNotificationPayload) => string;\n\n constructor(options: XhsQqNotifierOptions) {\n this.client = options.client;\n this.target = options.target;\n this.messageTemplate = options.messageTemplate ?? defaultMessageTemplate;\n }\n\n async notify(payload: XhsNotificationPayload): Promise<void> {\n const message = this.messageTemplate(payload);\n const response =\n this.target.type === 'group'\n ? await this.client.sendGroupMessage({\n group_id: this.target.groupId,\n message,\n })\n : await this.client.sendPrivateMessage({\n user_id: this.target.userId,\n message,\n });\n\n if (response.status !== 'ok') {\n throw new Error(`Failed to send QQ message: ${response.message ?? 'Unknown error'}`);\n }\n }\n}\n","import { XhsPost, XhsSource } from './types';\n\nexport interface XhsProfileHtmlSourceOptions {\n profileUrl: string;\n timeoutMs?: number;\n userAgent?: string;\n}\n\nfunction decodeHtmlEntities(input: string): string {\n return input\n .replace(/\\\\u003c/g, '<')\n .replace(/\\\\u003e/g, '>')\n .replace(/\\\\u0026/g, '&')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\n/g, ' ')\n .trim();\n}\n\nfunction normalizeTitle(title: string): string {\n return decodeHtmlEntities(title).replace(/\\s+/g, ' ').trim();\n}\n\nexport class XhsProfileHtmlSource implements XhsSource {\n private readonly profileUrl: string;\n private readonly timeoutMs: number;\n private readonly userAgent: string;\n\n constructor(options: XhsProfileHtmlSourceOptions) {\n this.profileUrl = options.profileUrl;\n this.timeoutMs = options.timeoutMs ?? 12000;\n this.userAgent =\n options.userAgent ??\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0 Safari/537.36';\n }\n\n async fetchLatestPosts(limit = 20): Promise<XhsPost[]> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const response = await fetch(this.profileUrl, {\n method: 'GET',\n headers: {\n 'User-Agent': this.userAgent,\n Accept: 'text/html,application/xhtml+xml',\n },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch profile page: HTTP ${response.status}`);\n }\n\n const html = await response.text();\n return this.parsePostsFromHtml(html, limit);\n } finally {\n clearTimeout(timer);\n }\n }\n\n private parsePostsFromHtml(html: string, limit: number): XhsPost[] {\n const idMatches = [...html.matchAll(/(?:\\/explore\\/|\\\"noteId\\\"\\s*:\\s*\\\")([a-zA-Z0-9_-]{8,32})/g)];\n const titleMatches = [...html.matchAll(/\\\"displayTitle\\\"\\s*:\\s*\\\"([^\"]{1,120})\\\"/g)];\n\n const uniqueIds: string[] = [];\n const seen = new Set<string>();\n for (const match of idMatches) {\n const id = match[1];\n if (!id || seen.has(id)) {\n continue;\n }\n seen.add(id);\n uniqueIds.push(id);\n if (uniqueIds.length >= limit) {\n break;\n }\n }\n\n const titles = titleMatches.map((match) => normalizeTitle(match[1] ?? '')).filter(Boolean);\n\n return uniqueIds.map((id, index) => ({\n id,\n url: `https://www.xiaohongshu.com/explore/${id}`,\n title: titles[index],\n }));\n }\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { XhsMonitorState, XhsMonitorStateStore } from './types';\n\nconst DEFAULT_STATE: XhsMonitorState = {\n seenPostIds: [],\n updatedAt: new Date(0).toISOString(),\n};\n\nexport interface FileXhsMonitorStateStoreOptions {\n filePath: string;\n maxSeenPostIds?: number;\n}\n\nexport class FileXhsMonitorStateStore implements XhsMonitorStateStore {\n private readonly filePath: string;\n private readonly maxSeenPostIds: number;\n\n constructor(options: FileXhsMonitorStateStoreOptions) {\n this.filePath = options.filePath;\n this.maxSeenPostIds = Math.max(10, options.maxSeenPostIds ?? 500);\n }\n\n async read(): Promise<XhsMonitorState> {\n try {\n const text = await readFile(this.filePath, 'utf8');\n const parsed = JSON.parse(text) as Partial<XhsMonitorState>;\n const seenPostIds = Array.isArray(parsed.seenPostIds)\n ? parsed.seenPostIds.filter((item): item is string => typeof item === 'string')\n : [];\n const updatedAt = typeof parsed.updatedAt === 'string' ? parsed.updatedAt : new Date().toISOString();\n return {\n seenPostIds: seenPostIds.slice(0, this.maxSeenPostIds),\n updatedAt,\n };\n } catch {\n return DEFAULT_STATE;\n }\n }\n\n async write(state: XhsMonitorState): Promise<void> {\n await mkdir(dirname(this.filePath), { recursive: true });\n const compactState: XhsMonitorState = {\n seenPostIds: state.seenPostIds.slice(0, this.maxSeenPostIds),\n updatedAt: state.updatedAt,\n };\n await writeFile(this.filePath, JSON.stringify(compactState, null, 2), 'utf8');\n }\n}\n","import { XhsMonitorStateStore, XhsNotifier, XhsPost, XhsSource } from './types';\n\nexport interface XhsMonitorServiceOptions {\n accountLabel: string;\n source: XhsSource;\n notifier: XhsNotifier;\n stateStore: XhsMonitorStateStore;\n pollIntervalMs: number;\n skipInitialSnapshot?: boolean;\n postLimit?: number;\n now?: () => Date;\n}\n\nfunction sortPostsByPublishedAt(posts: XhsPost[]): XhsPost[] {\n return [...posts].sort((a, b) => {\n const ta = a.publishedAt ? Date.parse(a.publishedAt) : Number.NaN;\n const tb = b.publishedAt ? Date.parse(b.publishedAt) : Number.NaN;\n if (Number.isNaN(ta) || Number.isNaN(tb)) {\n return 0;\n }\n return ta - tb;\n });\n}\n\nexport class XhsMonitorService {\n private readonly accountLabel: string;\n private readonly source: XhsSource;\n private readonly notifier: XhsNotifier;\n private readonly stateStore: XhsMonitorStateStore;\n private readonly pollIntervalMs: number;\n private readonly skipInitialSnapshot: boolean;\n private readonly postLimit: number;\n private readonly now: () => Date;\n private timer: NodeJS.Timeout | null = null;\n private initialized = false;\n private running = false;\n\n constructor(options: XhsMonitorServiceOptions) {\n this.accountLabel = options.accountLabel;\n this.source = options.source;\n this.notifier = options.notifier;\n this.stateStore = options.stateStore;\n this.pollIntervalMs = Math.max(5000, options.pollIntervalMs);\n this.skipInitialSnapshot = options.skipInitialSnapshot ?? true;\n this.postLimit = options.postLimit ?? 20;\n this.now = options.now ?? (() => new Date());\n }\n\n async checkOnce(): Promise<{ notifiedCount: number; fetchedCount: number }> {\n if (this.running) {\n return { notifiedCount: 0, fetchedCount: 0 };\n }\n\n this.running = true;\n try {\n const state = await this.stateStore.read();\n const seen = new Set(state.seenPostIds);\n const posts = await this.source.fetchLatestPosts(this.postLimit);\n const orderedPosts = sortPostsByPublishedAt(posts);\n const newlyDetected = orderedPosts.filter((post) => !seen.has(post.id));\n\n if (!this.initialized && this.skipInitialSnapshot) {\n for (const post of orderedPosts) {\n seen.add(post.id);\n }\n await this.persistSeenIds(seen);\n this.initialized = true;\n return { notifiedCount: 0, fetchedCount: posts.length };\n }\n\n let notifiedCount = 0;\n for (const post of newlyDetected) {\n await this.notifier.notify({\n accountLabel: this.accountLabel,\n post,\n detectedAt: this.now().toISOString(),\n });\n notifiedCount += 1;\n seen.add(post.id);\n }\n\n if (newlyDetected.length > 0 || !this.initialized) {\n for (const post of orderedPosts) {\n seen.add(post.id);\n }\n await this.persistSeenIds(seen);\n }\n\n this.initialized = true;\n return { notifiedCount, fetchedCount: posts.length };\n } finally {\n this.running = false;\n }\n }\n\n start(immediate = true): void {\n if (this.timer) {\n return;\n }\n\n const run = async () => {\n try {\n await this.checkOnce();\n } catch (error) {\n console.error('[XhsMonitorService] check failed', error);\n }\n };\n\n if (immediate) {\n void run();\n }\n\n this.timer = setInterval(() => {\n void run();\n }, this.pollIntervalMs);\n }\n\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n\n private async persistSeenIds(seenIds: Set<string>): Promise<void> {\n await this.stateStore.write({\n seenPostIds: Array.from(seenIds).slice(-500),\n updatedAt: this.now().toISOString(),\n });\n }\n}\n","import { NapCatClient } from '../client';\nimport { XhsQqNotifier } from './notifier';\nimport { XhsProfileHtmlSource } from './source';\nimport { FileXhsMonitorStateStore } from './stateStore';\nimport { XhsMonitorService } from './service';\n\nexport interface CreateXhsMonitorAppOptions {\n accountLabel: string;\n profileUrl: string;\n pollIntervalMs: number;\n stateFilePath: string;\n napCat: {\n baseUrl: string;\n accessToken?: string;\n timeoutMs?: number;\n };\n target: { type: 'group'; groupId: number } | { type: 'private'; userId: number };\n skipInitialSnapshot?: boolean;\n postLimit?: number;\n}\n\nexport function createXhsMonitorApp(options: CreateXhsMonitorAppOptions): XhsMonitorService {\n const client = new NapCatClient(options.napCat);\n const source = new XhsProfileHtmlSource({\n profileUrl: options.profileUrl,\n });\n const stateStore = new FileXhsMonitorStateStore({\n filePath: options.stateFilePath,\n });\n const notifier = new XhsQqNotifier({\n client,\n target: options.target,\n });\n\n return new XhsMonitorService({\n accountLabel: options.accountLabel,\n source,\n notifier,\n stateStore,\n pollIntervalMs: options.pollIntervalMs,\n skipInitialSnapshot: options.skipInitialSnapshot,\n postLimit: options.postLimit,\n });\n}\n"]}
@@ -0,0 +1,38 @@
1
+ import { MikuContestConfig, CreateMikuSubmissionInput, MikuSubmission, MikuSubmissionFilter, ReviewMikuSubmissionInput, VoteMikuSubmissionInput, MikuVoterRestriction, SetMikuVoterRestrictionInput, ResetMikuVotesInput, MikuAnnouncement, CreateMikuAnnouncementInput, MikuLeaderboardItem, MikuContestStateSnapshot, MikuSubmissionExportRow, MikuContestPersistedState } from './mikuContest/types/index.js';
2
+
3
+ interface MikuContestServiceOptions {
4
+ contestConfig?: Partial<MikuContestConfig>;
5
+ }
6
+ declare class MikuContestService {
7
+ private contest;
8
+ private readonly submissions;
9
+ private readonly votes;
10
+ private readonly announcements;
11
+ private readonly voterRestrictions;
12
+ constructor(options?: MikuContestServiceOptions);
13
+ getContestConfig(): MikuContestConfig;
14
+ updateContestConfig(patch: Partial<MikuContestConfig>): MikuContestConfig;
15
+ createSubmission(input: CreateMikuSubmissionInput, mode?: 'web' | 'miniapp'): MikuSubmission;
16
+ listSubmissions(filter?: MikuSubmissionFilter): MikuSubmission[];
17
+ getSubmission(submissionId: string): MikuSubmission | null;
18
+ reviewSubmission(input: ReviewMikuSubmissionInput): MikuSubmission;
19
+ vote(input: VoteMikuSubmissionInput): MikuSubmission;
20
+ getVoterRestriction(voterId: string): MikuVoterRestriction | null;
21
+ setVoterRestriction(input: SetMikuVoterRestrictionInput): MikuVoterRestriction;
22
+ resetVotes(input: ResetMikuVotesInput): {
23
+ removedVotes: number;
24
+ affectedSubmissions: string[];
25
+ };
26
+ listAnnouncements(contestId?: string): MikuAnnouncement[];
27
+ publishAnnouncement(input: CreateMikuAnnouncementInput): MikuAnnouncement;
28
+ getLeaderboard(limit?: number): MikuLeaderboardItem[];
29
+ getSnapshot(): MikuContestStateSnapshot;
30
+ getSubmissionExportRows(filter?: MikuSubmissionFilter): MikuSubmissionExportRow[];
31
+ exportSubmissionExcel(filter?: MikuSubmissionFilter): Uint8Array;
32
+ private recalculateVoteCounts;
33
+ exportPersistenceState(): MikuContestPersistedState;
34
+ importPersistenceState(state: MikuContestPersistedState): void;
35
+ }
36
+ declare const createMikuContestService: (options?: MikuContestServiceOptions) => MikuContestService;
37
+
38
+ export { type MikuContestServiceOptions as M, MikuContestService as a, createMikuContestService as c };
@@ -0,0 +1,38 @@
1
+ import { MikuContestConfig, CreateMikuSubmissionInput, MikuSubmission, MikuSubmissionFilter, ReviewMikuSubmissionInput, VoteMikuSubmissionInput, MikuVoterRestriction, SetMikuVoterRestrictionInput, ResetMikuVotesInput, MikuAnnouncement, CreateMikuAnnouncementInput, MikuLeaderboardItem, MikuContestStateSnapshot, MikuSubmissionExportRow, MikuContestPersistedState } from './mikuContest/types/index.mjs';
2
+
3
+ interface MikuContestServiceOptions {
4
+ contestConfig?: Partial<MikuContestConfig>;
5
+ }
6
+ declare class MikuContestService {
7
+ private contest;
8
+ private readonly submissions;
9
+ private readonly votes;
10
+ private readonly announcements;
11
+ private readonly voterRestrictions;
12
+ constructor(options?: MikuContestServiceOptions);
13
+ getContestConfig(): MikuContestConfig;
14
+ updateContestConfig(patch: Partial<MikuContestConfig>): MikuContestConfig;
15
+ createSubmission(input: CreateMikuSubmissionInput, mode?: 'web' | 'miniapp'): MikuSubmission;
16
+ listSubmissions(filter?: MikuSubmissionFilter): MikuSubmission[];
17
+ getSubmission(submissionId: string): MikuSubmission | null;
18
+ reviewSubmission(input: ReviewMikuSubmissionInput): MikuSubmission;
19
+ vote(input: VoteMikuSubmissionInput): MikuSubmission;
20
+ getVoterRestriction(voterId: string): MikuVoterRestriction | null;
21
+ setVoterRestriction(input: SetMikuVoterRestrictionInput): MikuVoterRestriction;
22
+ resetVotes(input: ResetMikuVotesInput): {
23
+ removedVotes: number;
24
+ affectedSubmissions: string[];
25
+ };
26
+ listAnnouncements(contestId?: string): MikuAnnouncement[];
27
+ publishAnnouncement(input: CreateMikuAnnouncementInput): MikuAnnouncement;
28
+ getLeaderboard(limit?: number): MikuLeaderboardItem[];
29
+ getSnapshot(): MikuContestStateSnapshot;
30
+ getSubmissionExportRows(filter?: MikuSubmissionFilter): MikuSubmissionExportRow[];
31
+ exportSubmissionExcel(filter?: MikuSubmissionFilter): Uint8Array;
32
+ private recalculateVoteCounts;
33
+ exportPersistenceState(): MikuContestPersistedState;
34
+ importPersistenceState(state: MikuContestPersistedState): void;
35
+ }
36
+ declare const createMikuContestService: (options?: MikuContestServiceOptions) => MikuContestService;
37
+
38
+ export { type MikuContestServiceOptions as M, MikuContestService as a, createMikuContestService as c };
@@ -0,0 +1,14 @@
1
+ import { MikuContestPersistedState } from './mikuContest/types/index.mjs';
2
+
3
+ interface MikuContestPersistenceAdapter {
4
+ loadState(contestId: string): Promise<MikuContestPersistedState | null>;
5
+ saveState(state: MikuContestPersistedState): Promise<void>;
6
+ }
7
+ type DrizzleLikeDb = {
8
+ select: (...args: any[]) => any;
9
+ insert: (...args: any[]) => any;
10
+ update: (...args: any[]) => any;
11
+ delete: (...args: any[]) => any;
12
+ };
13
+
14
+ export type { DrizzleLikeDb as D, MikuContestPersistenceAdapter as M };
@@ -0,0 +1,14 @@
1
+ import { MikuContestPersistedState } from './mikuContest/types/index.js';
2
+
3
+ interface MikuContestPersistenceAdapter {
4
+ loadState(contestId: string): Promise<MikuContestPersistedState | null>;
5
+ saveState(state: MikuContestPersistedState): Promise<void>;
6
+ }
7
+ type DrizzleLikeDb = {
8
+ select: (...args: any[]) => any;
9
+ insert: (...args: any[]) => any;
10
+ update: (...args: any[]) => any;
11
+ delete: (...args: any[]) => any;
12
+ };
13
+
14
+ export type { DrizzleLikeDb as D, MikuContestPersistenceAdapter as M };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sa2kit",
3
- "version": "1.6.91",
3
+ "version": "1.6.96",
4
4
  "description": "A modern, type-safe React utility library with cross-platform support and platform adapters",
5
5
  "keywords": [
6
6
  "react",
@@ -398,6 +398,81 @@
398
398
  "import": "./dist/vocaloidBooth/server/index.mjs",
399
399
  "require": "./dist/vocaloidBooth/server/index.js"
400
400
  },
401
+ "./mikuContest": {
402
+ "types": "./dist/mikuContest/index.d.ts",
403
+ "import": "./dist/mikuContest/index.mjs",
404
+ "require": "./dist/mikuContest/index.js"
405
+ },
406
+ "./mikuContest/types": {
407
+ "types": "./dist/mikuContest/types/index.d.ts",
408
+ "import": "./dist/mikuContest/types/index.mjs",
409
+ "require": "./dist/mikuContest/types/index.js"
410
+ },
411
+ "./mikuContest/logic": {
412
+ "types": "./dist/mikuContest/logic/index.d.ts",
413
+ "import": "./dist/mikuContest/logic/index.mjs",
414
+ "require": "./dist/mikuContest/logic/index.js"
415
+ },
416
+ "./mikuContest/service": {
417
+ "types": "./dist/mikuContest/service/index.d.ts",
418
+ "import": "./dist/mikuContest/service/index.mjs",
419
+ "require": "./dist/mikuContest/service/index.js"
420
+ },
421
+ "./mikuContest/ui/web": {
422
+ "types": "./dist/mikuContest/ui/web/index.d.ts",
423
+ "import": "./dist/mikuContest/ui/web/index.mjs",
424
+ "require": "./dist/mikuContest/ui/web/index.js"
425
+ },
426
+ "./mikuContest/ui/miniapp": {
427
+ "types": "./dist/mikuContest/ui/miniapp/index.d.ts",
428
+ "import": "./dist/mikuContest/ui/miniapp/index.mjs",
429
+ "require": "./dist/mikuContest/ui/miniapp/index.js"
430
+ },
431
+ "./mikuContest/server": {
432
+ "types": "./dist/mikuContest/server/index.d.ts",
433
+ "import": "./dist/mikuContest/server/index.mjs",
434
+ "require": "./dist/mikuContest/server/index.js"
435
+ },
436
+ "./mikuContest/routes": {
437
+ "types": "./dist/mikuContest/routes/index.d.ts",
438
+ "import": "./dist/mikuContest/routes/index.mjs",
439
+ "require": "./dist/mikuContest/routes/index.js"
440
+ },
441
+ "./huarongdao": {
442
+ "types": "./dist/huarongdao/index.d.ts",
443
+ "import": "./dist/huarongdao/index.mjs",
444
+ "require": "./dist/huarongdao/index.js"
445
+ },
446
+ "./huarongdao/types": {
447
+ "types": "./dist/huarongdao/types/index.d.ts",
448
+ "import": "./dist/huarongdao/types/index.mjs",
449
+ "require": "./dist/huarongdao/types/index.js"
450
+ },
451
+ "./huarongdao/logic": {
452
+ "types": "./dist/huarongdao/logic/index.d.ts",
453
+ "import": "./dist/huarongdao/logic/index.mjs",
454
+ "require": "./dist/huarongdao/logic/index.js"
455
+ },
456
+ "./huarongdao/service": {
457
+ "types": "./dist/huarongdao/service/index.d.ts",
458
+ "import": "./dist/huarongdao/service/index.mjs",
459
+ "require": "./dist/huarongdao/service/index.js"
460
+ },
461
+ "./huarongdao/ui/web": {
462
+ "types": "./dist/huarongdao/ui/web/index.d.ts",
463
+ "import": "./dist/huarongdao/ui/web/index.mjs",
464
+ "require": "./dist/huarongdao/ui/web/index.js"
465
+ },
466
+ "./huarongdao/server": {
467
+ "types": "./dist/huarongdao/server/index.d.ts",
468
+ "import": "./dist/huarongdao/server/index.mjs",
469
+ "require": "./dist/huarongdao/server/index.js"
470
+ },
471
+ "./huarongdao/routes": {
472
+ "types": "./dist/huarongdao/routes/index.d.ts",
473
+ "import": "./dist/huarongdao/routes/index.mjs",
474
+ "require": "./dist/huarongdao/routes/index.js"
475
+ },
401
476
  "./components": {
402
477
  "types": "./dist/components/index.d.ts",
403
478
  "import": "./dist/components/index.mjs",