@senguoyun/dsh-arkme 0.1.67 → 0.1.68
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/docs/chat-add-long-article.md +39 -0
- package/docs/desktop-direct-recording.md +40 -0
- package/docs/desktop-membership-handoff.md +36 -0
- package/docs/desktop-regression-2026-09-19.md +77 -0
- package/docs/desktop-screenshot.md +59 -0
- package/docs/private-interaction-directory-handoff.md +95 -0
- package/docs/recording-calendar-coverage.md +41 -0
- package/docs/recording-presence-handoff.md +155 -0
- package/lib/client.js +49834 -45144
- package/lib/client.js.map +1 -1
- package/lib/harness-model-client.js +8 -0
- package/lib/harness-native-selection-client.js +72 -5
- package/lib/harness-sidebar-client.js +46 -2
- package/lib/index.js +27 -3
- package/lib/persistent-extension.js +1 -1
- package/lib/{persistent-runtime-C_Geaa4B.js → persistent-runtime-DlJzDZlE.js} +816 -94
- package/lib/sdk.js +8 -0
- package/lib/types/arkme-service.d.ts +18 -1
- package/lib/types/arkme-service.d.ts.map +1 -1
- package/lib/types/call-record-presentation.d.ts +2 -0
- package/lib/types/call-record-presentation.d.ts.map +1 -1
- package/lib/types/client/ArkmeArticlePicker.d.ts +10 -0
- package/lib/types/client/ArkmeArticlePicker.d.ts.map +1 -0
- package/lib/types/client/ArkmeCallDetailContent.d.ts.map +1 -1
- package/lib/types/client/ArkmeCallRecordContent.d.ts.map +1 -1
- package/lib/types/client/ArkmeCallSurface.d.ts +3 -1
- package/lib/types/client/ArkmeCallSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeChatMemberActions.d.ts +2 -0
- package/lib/types/client/ArkmeChatMemberActions.d.ts.map +1 -1
- package/lib/types/client/ArkmeComposerScreenshotButton.d.ts +13 -0
- package/lib/types/client/ArkmeComposerScreenshotButton.d.ts.map +1 -0
- package/lib/types/client/ArkmeComposerSendButton.d.ts.map +1 -1
- package/lib/types/client/ArkmeDetailShell.d.ts +2 -1
- package/lib/types/client/ArkmeDetailShell.d.ts.map +1 -1
- package/lib/types/client/ArkmeDshMenu.d.ts +2 -0
- package/lib/types/client/ArkmeDshMenu.d.ts.map +1 -1
- package/lib/types/client/ArkmeEmojiPicker.d.ts.map +1 -1
- package/lib/types/client/ArkmeFileViewer.d.ts.map +1 -1
- package/lib/types/client/ArkmeGroupChatControls.d.ts +32 -0
- package/lib/types/client/ArkmeGroupChatControls.d.ts.map +1 -1
- package/lib/types/client/ArkmeLinkQuickView.d.ts +8 -0
- package/lib/types/client/ArkmeLinkQuickView.d.ts.map +1 -0
- package/lib/types/client/ArkmeLongArticleDialog.d.ts +6 -3
- package/lib/types/client/ArkmeLongArticleDialog.d.ts.map +1 -1
- package/lib/types/client/ArkmeLongArticleQuickView.d.ts +6 -0
- package/lib/types/client/ArkmeLongArticleQuickView.d.ts.map +1 -0
- package/lib/types/client/ArkmeMarkdownBody.d.ts +4 -1
- package/lib/types/client/ArkmeMarkdownBody.d.ts.map +1 -1
- package/lib/types/client/ArkmeMembershipDialog.d.ts +14 -0
- package/lib/types/client/ArkmeMembershipDialog.d.ts.map +1 -0
- package/lib/types/client/ArkmeMessageReadReceipt.d.ts.map +1 -1
- package/lib/types/client/ArkmeNoteDetails.d.ts +1 -1
- package/lib/types/client/ArkmeNoteDetails.d.ts.map +1 -1
- package/lib/types/client/ArkmeProductNavigation.d.ts.map +1 -1
- package/lib/types/client/ArkmeQuickAdd.d.ts +2 -1
- package/lib/types/client/ArkmeQuickAdd.d.ts.map +1 -1
- package/lib/types/client/ArkmeReadReceiptIcon.d.ts +7 -0
- package/lib/types/client/ArkmeReadReceiptIcon.d.ts.map +1 -0
- package/lib/types/client/ArkmeRecordingSurface.d.ts +3 -1
- package/lib/types/client/ArkmeRecordingSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeRichContent.d.ts.map +1 -1
- package/lib/types/client/ArkmeRichText.d.ts +6 -2
- package/lib/types/client/ArkmeRichText.d.ts.map +1 -1
- package/lib/types/client/ArkmeRightPanelHeader.d.ts +3 -1
- package/lib/types/client/ArkmeRightPanelHeader.d.ts.map +1 -1
- package/lib/types/client/ArkmeScreenshotCropDialog.d.ts +9 -0
- package/lib/types/client/ArkmeScreenshotCropDialog.d.ts.map +1 -0
- package/lib/types/client/ArkmeSearchSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeSidebar.d.ts +9 -0
- package/lib/types/client/ArkmeSidebar.d.ts.map +1 -1
- package/lib/types/client/ArkmeSourceBreadcrumb.d.ts.map +1 -1
- package/lib/types/client/ArkmeVoiceprintSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeWideConversation.d.ts.map +1 -1
- package/lib/types/client/api.d.ts +1 -1
- package/lib/types/client/api.d.ts.map +1 -1
- package/lib/types/client/arkme-membership.d.ts +15 -0
- package/lib/types/client/arkme-membership.d.ts.map +1 -0
- package/lib/types/client/browser-screenshot.d.ts +27 -0
- package/lib/types/client/browser-screenshot.d.ts.map +1 -0
- package/lib/types/client/chat-directory-store.d.ts.map +1 -1
- package/lib/types/client/composer-article-store.d.ts +35 -0
- package/lib/types/client/composer-article-store.d.ts.map +1 -0
- package/lib/types/client/composer-paste-focus.d.ts +21 -0
- package/lib/types/client/composer-paste-focus.d.ts.map +1 -0
- package/lib/types/client/composer-selection-request.d.ts +2 -0
- package/lib/types/client/composer-selection-request.d.ts.map +1 -1
- package/lib/types/client/conversation-menu-layer.d.ts +9 -2
- package/lib/types/client/conversation-menu-layer.d.ts.map +1 -1
- package/lib/types/client/conversation-selector-style.d.ts +2 -2
- package/lib/types/client/conversation-selector-style.d.ts.map +1 -1
- package/lib/types/client/directory-search-layout.d.ts +1 -1
- package/lib/types/client/directory-search-layout.d.ts.map +1 -1
- package/lib/types/client/file-send-tasks.d.ts +1 -1
- package/lib/types/client/file-send-tasks.d.ts.map +1 -1
- package/lib/types/client/harness-session-hover.d.ts.map +1 -1
- package/lib/types/client/mention-read-status.d.ts +10 -0
- package/lib/types/client/mention-read-status.d.ts.map +1 -0
- package/lib/types/client/menu-hover-region.d.ts +5 -0
- package/lib/types/client/menu-hover-region.d.ts.map +1 -0
- package/lib/types/client/recordings/ArkmeDirectRecording.d.ts +10 -0
- package/lib/types/client/recordings/ArkmeDirectRecording.d.ts.map +1 -0
- package/lib/types/client/recordings/ArkmeRecordingNavigationHint.d.ts +9 -0
- package/lib/types/client/recordings/ArkmeRecordingNavigationHint.d.ts.map +1 -0
- package/lib/types/client/recordings/ArkmeRecordingTimeline.d.ts +4 -2
- package/lib/types/client/recordings/ArkmeRecordingTimeline.d.ts.map +1 -1
- package/lib/types/client/recordings/direct-recording-capture.d.ts +14 -0
- package/lib/types/client/recordings/direct-recording-capture.d.ts.map +1 -0
- package/lib/types/client/recordings/direct-recording-journal.d.ts +33 -0
- package/lib/types/client/recordings/direct-recording-journal.d.ts.map +1 -0
- package/lib/types/client/recordings/direct-recording-store.d.ts +68 -0
- package/lib/types/client/recordings/direct-recording-store.d.ts.map +1 -0
- package/lib/types/client/recordings/recording-breath.d.ts +6 -0
- package/lib/types/client/recordings/recording-breath.d.ts.map +1 -0
- package/lib/types/client/recordings/recording-coverage.d.ts +6 -0
- package/lib/types/client/recordings/recording-coverage.d.ts.map +1 -0
- package/lib/types/client/redesign/styles.d.ts.map +1 -1
- package/lib/types/client/search-source-rows.d.ts +9 -0
- package/lib/types/client/search-source-rows.d.ts.map +1 -0
- package/lib/types/client/self-topic-menu-bridge.d.ts +2 -6
- package/lib/types/client/self-topic-menu-bridge.d.ts.map +1 -1
- package/lib/types/client/self-topic-menu-hover.d.ts.map +1 -1
- package/lib/types/client/text-link-parser.d.ts +1 -9
- package/lib/types/client/text-link-parser.d.ts.map +1 -1
- package/lib/types/client/text-link-tlds.d.ts +1 -1
- package/lib/types/client/text-link-tlds.d.ts.map +1 -1
- package/lib/types/client/use-conversation-name-search.d.ts +9 -0
- package/lib/types/client/use-conversation-name-search.d.ts.map +1 -0
- package/lib/types/client/use-resizable-note-detail.d.ts +3 -3
- package/lib/types/client/use-resizable-note-detail.d.ts.map +1 -1
- package/lib/types/desktop-screenshot-contract.d.ts +14 -0
- package/lib/types/desktop-screenshot-contract.d.ts.map +1 -0
- package/lib/types/desktop-screenshot.d.ts +22 -0
- package/lib/types/desktop-screenshot.d.ts.map +1 -0
- package/lib/types/host-api.d.ts.map +1 -1
- package/lib/types/markdown.d.ts +6 -1
- package/lib/types/markdown.d.ts.map +1 -1
- package/lib/types/recording-coverage.d.ts +12 -0
- package/lib/types/recording-coverage.d.ts.map +1 -0
- package/lib/types/sdk/index.d.ts +6 -0
- package/lib/types/sdk/index.d.ts.map +1 -1
- package/lib/types/search-record-links.d.ts +3 -0
- package/lib/types/search-record-links.d.ts.map +1 -0
- package/lib/types/services/background-sound-membership-service.d.ts +5 -0
- package/lib/types/services/background-sound-membership-service.d.ts.map +1 -1
- package/lib/types/services/call-history-service.d.ts +1 -1
- package/lib/types/services/call-history-service.d.ts.map +1 -1
- package/lib/types/services/chat-service.d.ts +8 -1
- package/lib/types/services/chat-service.d.ts.map +1 -1
- package/lib/types/services/membership-service.d.ts +13 -0
- package/lib/types/services/membership-service.d.ts.map +1 -0
- package/lib/types/services/record-service.d.ts +1 -1
- package/lib/types/services/record-service.d.ts.map +1 -1
- package/lib/types/services/recording-service.d.ts.map +1 -1
- package/lib/types/services/search-service.d.ts.map +1 -1
- package/lib/types/services/service.d.ts +1 -1
- package/lib/types/services/service.d.ts.map +1 -1
- package/lib/types/services/source-service.d.ts +7 -1
- package/lib/types/services/source-service.d.ts.map +1 -1
- package/lib/types/state-store.d.ts +1 -1
- package/lib/types/state-store.d.ts.map +1 -1
- package/lib/types/text-link-parser.d.ts +10 -0
- package/lib/types/text-link-parser.d.ts.map +1 -0
- package/lib/types/text-link-tlds.d.ts +2 -0
- package/lib/types/text-link-tlds.d.ts.map +1 -0
- package/lib/types/types.d.ts +53 -3
- package/lib/types/types.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -2,12 +2,13 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
3
3
|
import { chmodSync, constants, createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { createCipheriv, createDecipheriv, createHash, createHmac, createPublicKey, randomBytes, randomUUID, timingSafeEqual, verify } from "node:crypto";
|
|
5
|
-
import { chmod as chmod$1, copyFile, lstat, mkdir, open, opendir, readFile, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
5
|
+
import { access, chmod as chmod$1, copyFile, lstat, mkdir, mkdtemp, open, opendir, readFile, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
6
|
+
import { execFile } from "node:child_process";
|
|
6
7
|
import minpath, { basename, dirname, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
|
|
7
8
|
import { fileURLToPath, fileURLToPath as urlToPath } from "node:url";
|
|
8
9
|
import { gunzipSync, gzipSync } from "node:zlib";
|
|
9
10
|
import { request } from "node:http";
|
|
10
|
-
import { homedir } from "node:os";
|
|
11
|
+
import { homedir, tmpdir } from "node:os";
|
|
11
12
|
import { request as request$1 } from "node:https";
|
|
12
13
|
import { Readable } from "node:stream";
|
|
13
14
|
import { BlockList, isIP } from "node:net";
|
|
@@ -1936,8 +1937,137 @@ var ServiceRuntime = class {
|
|
|
1936
1937
|
}
|
|
1937
1938
|
};
|
|
1938
1939
|
//#endregion
|
|
1940
|
+
//#region src/desktop-screenshot.ts
|
|
1941
|
+
const executable = "/usr/sbin/screencapture";
|
|
1942
|
+
const pngSignature = Buffer.from([
|
|
1943
|
+
137,
|
|
1944
|
+
80,
|
|
1945
|
+
78,
|
|
1946
|
+
71,
|
|
1947
|
+
13,
|
|
1948
|
+
10,
|
|
1949
|
+
26,
|
|
1950
|
+
10
|
|
1951
|
+
]);
|
|
1952
|
+
/** Always interactive: no full-screen capture, shell, caller paths or clipboard mutation. */
|
|
1953
|
+
const captureProcess = (path, signal) => new Promise((resolve, reject) => {
|
|
1954
|
+
execFile(executable, [
|
|
1955
|
+
"-i",
|
|
1956
|
+
"-s",
|
|
1957
|
+
"-x",
|
|
1958
|
+
"-t",
|
|
1959
|
+
"png",
|
|
1960
|
+
path
|
|
1961
|
+
], {
|
|
1962
|
+
signal,
|
|
1963
|
+
maxBuffer: 64 * 1024
|
|
1964
|
+
}, (error, _stdout, stderr) => {
|
|
1965
|
+
if (signal.aborted) {
|
|
1966
|
+
reject(signal.reason);
|
|
1967
|
+
return;
|
|
1968
|
+
}
|
|
1969
|
+
if (error !== null && typeof error.code !== "number") {
|
|
1970
|
+
reject(error);
|
|
1971
|
+
return;
|
|
1972
|
+
}
|
|
1973
|
+
resolve({
|
|
1974
|
+
code: typeof error?.code === "number" ? error.code : 0,
|
|
1975
|
+
stderr
|
|
1976
|
+
});
|
|
1977
|
+
});
|
|
1978
|
+
});
|
|
1979
|
+
var ArkmeDesktopScreenshot = class {
|
|
1980
|
+
options;
|
|
1981
|
+
active;
|
|
1982
|
+
constructor(options) {
|
|
1983
|
+
this.options = options;
|
|
1984
|
+
}
|
|
1985
|
+
async capability() {
|
|
1986
|
+
if ((this.options.platform ?? process.platform) !== "darwin") return {
|
|
1987
|
+
available: false,
|
|
1988
|
+
reason: "截屏暂仅支持 macOS,可使用系统截屏后粘贴图片"
|
|
1989
|
+
};
|
|
1990
|
+
return await (this.options.executableAvailable ?? (async () => {
|
|
1991
|
+
try {
|
|
1992
|
+
await access(executable, constants.X_OK);
|
|
1993
|
+
return true;
|
|
1994
|
+
} catch {
|
|
1995
|
+
return false;
|
|
1996
|
+
}
|
|
1997
|
+
}))() ? { available: true } : {
|
|
1998
|
+
available: false,
|
|
1999
|
+
reason: "系统截屏暂不可用,可使用系统截屏后粘贴图片"
|
|
2000
|
+
};
|
|
2001
|
+
}
|
|
2002
|
+
cancel() {
|
|
2003
|
+
this.active?.abort();
|
|
2004
|
+
}
|
|
2005
|
+
async capture(expectedUserId, requestSignal) {
|
|
2006
|
+
if (!Number.isSafeInteger(expectedUserId) || expectedUserId <= 0) throw new ArkmePluginError("screenshot-account-required", "请先登录后再截屏", false, 400);
|
|
2007
|
+
if (this.active !== void 0) throw new ArkmePluginError("screenshot-busy", "正在截屏,请先完成或按 Esc 取消", false, 409);
|
|
2008
|
+
const controller = new AbortController();
|
|
2009
|
+
this.active = controller;
|
|
2010
|
+
const abort = () => controller.abort();
|
|
2011
|
+
requestSignal?.addEventListener("abort", abort, { once: true });
|
|
2012
|
+
if (requestSignal?.aborted) abort();
|
|
2013
|
+
let timedOut = false;
|
|
2014
|
+
const timer = setTimeout(() => {
|
|
2015
|
+
timedOut = true;
|
|
2016
|
+
abort();
|
|
2017
|
+
}, this.options.timeoutMs ?? 12e4);
|
|
2018
|
+
let directory;
|
|
2019
|
+
const check = async () => {
|
|
2020
|
+
controller.signal.throwIfAborted();
|
|
2021
|
+
if (await this.options.currentUser() !== expectedUserId) throw new ArkmePluginError("screenshot-account-changed", "账号已切换,请重新截屏", false, 409);
|
|
2022
|
+
controller.signal.throwIfAborted();
|
|
2023
|
+
};
|
|
2024
|
+
try {
|
|
2025
|
+
await check();
|
|
2026
|
+
const capability = await this.capability();
|
|
2027
|
+
if (!capability.available) throw new ArkmePluginError("screenshot-unavailable", capability.reason, false, 501);
|
|
2028
|
+
directory = await mkdtemp(join(tmpdir(), "arkme-screenshot-"));
|
|
2029
|
+
const path = join(directory, "capture.png");
|
|
2030
|
+
controller.signal.throwIfAborted();
|
|
2031
|
+
const result = await (this.options.capture ?? captureProcess)(path, controller.signal);
|
|
2032
|
+
await check();
|
|
2033
|
+
const info = await stat(path).catch((error) => {
|
|
2034
|
+
if (error.code === "ENOENT") return void 0;
|
|
2035
|
+
throw error;
|
|
2036
|
+
});
|
|
2037
|
+
if (info === void 0 && (result.code === 0 || result.code === 1) && result.stderr.trim() === "") return { status: "cancelled" };
|
|
2038
|
+
if (result.code !== 0 || info === void 0) throw new ArkmePluginError("screenshot-permission", "无法截屏。请在系统设置 → 隐私与安全性 → 屏幕录制中允许当前运行环境,然后重试", false, 403);
|
|
2039
|
+
if (!info.isFile() || info.size > this.options.maxImageBytes()) throw new ArkmePluginError("screenshot-too-large", "截图过大,请缩小框选区域后重试", false, 413);
|
|
2040
|
+
const bytes = await readFile(path);
|
|
2041
|
+
if (!bytes.subarray(0, 8).equals(pngSignature)) throw new ArkmePluginError("screenshot-invalid", "未能生成有效截图,请重试", true, 502);
|
|
2042
|
+
await check();
|
|
2043
|
+
return {
|
|
2044
|
+
status: "captured",
|
|
2045
|
+
fileName: `截图-${Date.now()}.png`,
|
|
2046
|
+
mimeType: "image/png",
|
|
2047
|
+
contentBase64: bytes.toString("base64")
|
|
2048
|
+
};
|
|
2049
|
+
} catch (error) {
|
|
2050
|
+
if (timedOut) throw new ArkmePluginError("screenshot-timeout", "截屏已超时,请重新点击截屏", true, 408);
|
|
2051
|
+
if (controller.signal.aborted) return { status: "cancelled" };
|
|
2052
|
+
if (error instanceof ArkmePluginError) throw error;
|
|
2053
|
+
throw new ArkmePluginError("screenshot-failed", "截屏失败,请检查系统屏幕录制权限后重试", true, 502);
|
|
2054
|
+
} finally {
|
|
2055
|
+
clearTimeout(timer);
|
|
2056
|
+
requestSignal?.removeEventListener("abort", abort);
|
|
2057
|
+
try {
|
|
2058
|
+
if (directory !== void 0) await rm(directory, {
|
|
2059
|
+
recursive: true,
|
|
2060
|
+
force: true
|
|
2061
|
+
});
|
|
2062
|
+
} finally {
|
|
2063
|
+
if (this.active === controller) this.active = void 0;
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
};
|
|
2068
|
+
//#endregion
|
|
1939
2069
|
//#region src/services/record-edit-history-service.ts
|
|
1940
|
-
function invalid$
|
|
2070
|
+
function invalid$5() {
|
|
1941
2071
|
throw new ArkmePluginError("record-edit-history-invalid", "编辑记录暂不可用,请刷新后重试", true, 502);
|
|
1942
2072
|
}
|
|
1943
2073
|
var RecordEditHistoryService = class {
|
|
@@ -1948,9 +2078,9 @@ var RecordEditHistoryService = class {
|
|
|
1948
2078
|
this.projector = projector;
|
|
1949
2079
|
}
|
|
1950
2080
|
async page(target, cursorEditAt = 0, signal) {
|
|
1951
|
-
if (!Number.isSafeInteger(cursorEditAt) || cursorEditAt < 0 || target.recordUid.trim() === "") invalid$
|
|
2081
|
+
if (!Number.isSafeInteger(cursorEditAt) || cursorEditAt < 0 || target.recordUid.trim() === "") invalid$5();
|
|
1952
2082
|
const session = await this.runtime.requireSession();
|
|
1953
|
-
if (session.userId !== target.viewerUserId) invalid$
|
|
2083
|
+
if (session.userId !== target.viewerUserId) invalid$5();
|
|
1954
2084
|
const window = {
|
|
1955
2085
|
limit: 50,
|
|
1956
2086
|
...cursorEditAt === 0 ? {} : { cursor_edit_at: cursorEditAt }
|
|
@@ -1963,22 +2093,22 @@ var RecordEditHistoryService = class {
|
|
|
1963
2093
|
rel_uid: target.relationUid,
|
|
1964
2094
|
...window
|
|
1965
2095
|
}, session, signal));
|
|
1966
|
-
if (signal?.aborted || (await this.runtime.requireSession()).userId !== session.userId) invalid$
|
|
1967
|
-
if (!Array.isArray(data.items) || typeof data.has_more !== "boolean") invalid$
|
|
2096
|
+
if (signal?.aborted || (await this.runtime.requireSession()).userId !== session.userId) invalid$5();
|
|
2097
|
+
if (!Array.isArray(data.items) || typeof data.has_more !== "boolean") invalid$5();
|
|
1968
2098
|
const next = data.next_cursor_edit_at;
|
|
1969
|
-
if (data.has_more && (typeof next !== "number" || !Number.isSafeInteger(next) || next <= 0 || cursorEditAt > 0 && next >= cursorEditAt)) invalid$
|
|
2099
|
+
if (data.has_more && (typeof next !== "number" || !Number.isSafeInteger(next) || next <= 0 || cursorEditAt > 0 && next >= cursorEditAt)) invalid$5();
|
|
1970
2100
|
const seen = /* @__PURE__ */ new Set();
|
|
1971
2101
|
const snapshots = data.items.flatMap((raw) => {
|
|
1972
2102
|
const revision = objectValue$2(raw);
|
|
1973
|
-
if (revision.record_uid !== target.recordUid || typeof revision.revision_uid !== "string" || revision.revision_uid.trim() === "") invalid$
|
|
2103
|
+
if (revision.record_uid !== target.recordUid || typeof revision.revision_uid !== "string" || revision.revision_uid.trim() === "") invalid$5();
|
|
1974
2104
|
if (revision.revision_type !== 1 && revision.revision_type !== 5) return [];
|
|
1975
|
-
if (typeof revision.edit_at !== "number" || !Number.isSafeInteger(revision.edit_at) || revision.edit_at <= 0 || !Number.isFinite(new Date(revision.edit_at).getTime()) || typeof revision.text_content !== "string") invalid$
|
|
2105
|
+
if (typeof revision.edit_at !== "number" || !Number.isSafeInteger(revision.edit_at) || revision.edit_at <= 0 || !Number.isFinite(new Date(revision.edit_at).getTime()) || typeof revision.text_content !== "string") invalid$5();
|
|
1976
2106
|
if (seen.has(revision.revision_uid)) return [];
|
|
1977
2107
|
seen.add(revision.revision_uid);
|
|
1978
2108
|
return [revision];
|
|
1979
2109
|
});
|
|
1980
2110
|
const contents = snapshots.length === 0 ? [] : await this.projector.projectPage(snapshots, target, signal);
|
|
1981
|
-
if (signal?.aborted || (await this.runtime.requireSession()).userId !== session.userId || contents.length !== snapshots.length) invalid$
|
|
2111
|
+
if (signal?.aborted || (await this.runtime.requireSession()).userId !== session.userId || contents.length !== snapshots.length) invalid$5();
|
|
1982
2112
|
const items = snapshots.map((revision, index) => ({
|
|
1983
2113
|
revisionUid: revision.revision_uid,
|
|
1984
2114
|
kind: revision.revision_type === 5 ? "original" : "manual",
|
|
@@ -12498,7 +12628,7 @@ function tokenizeThematicBreak(effects, ok, nok) {
|
|
|
12498
12628
|
* } from 'micromark-util-types'
|
|
12499
12629
|
*/
|
|
12500
12630
|
/** @type {Construct} */
|
|
12501
|
-
const list$
|
|
12631
|
+
const list$3 = {
|
|
12502
12632
|
continuation: { tokenize: tokenizeListContinuation },
|
|
12503
12633
|
exit: tokenizeListEnd,
|
|
12504
12634
|
name: "list",
|
|
@@ -12618,7 +12748,7 @@ function tokenizeListContinuation(effects, ok, nok) {
|
|
|
12618
12748
|
function notInCurrentItem(code) {
|
|
12619
12749
|
self.containerState._closeFlow = true;
|
|
12620
12750
|
self.interrupt = void 0;
|
|
12621
|
-
return factorySpace(effects, effects.attempt(list$
|
|
12751
|
+
return factorySpace(effects, effects.attempt(list$3, ok, nok), "linePrefix", self.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4)(code);
|
|
12622
12752
|
}
|
|
12623
12753
|
}
|
|
12624
12754
|
/**
|
|
@@ -13051,19 +13181,19 @@ var constructs_exports = /* @__PURE__ */ __exportAll({
|
|
|
13051
13181
|
});
|
|
13052
13182
|
/** @satisfies {Extension['document']} */
|
|
13053
13183
|
const document$1 = {
|
|
13054
|
-
[42]: list$
|
|
13055
|
-
[43]: list$
|
|
13056
|
-
[45]: list$
|
|
13057
|
-
[48]: list$
|
|
13058
|
-
[49]: list$
|
|
13059
|
-
[50]: list$
|
|
13060
|
-
[51]: list$
|
|
13061
|
-
[52]: list$
|
|
13062
|
-
[53]: list$
|
|
13063
|
-
[54]: list$
|
|
13064
|
-
[55]: list$
|
|
13065
|
-
[56]: list$
|
|
13066
|
-
[57]: list$
|
|
13184
|
+
[42]: list$3,
|
|
13185
|
+
[43]: list$3,
|
|
13186
|
+
[45]: list$3,
|
|
13187
|
+
[48]: list$3,
|
|
13188
|
+
[49]: list$3,
|
|
13189
|
+
[50]: list$3,
|
|
13190
|
+
[51]: list$3,
|
|
13191
|
+
[52]: list$3,
|
|
13192
|
+
[53]: list$3,
|
|
13193
|
+
[54]: list$3,
|
|
13194
|
+
[55]: list$3,
|
|
13195
|
+
[56]: list$3,
|
|
13196
|
+
[57]: list$3,
|
|
13067
13197
|
[62]: blockQuote
|
|
13068
13198
|
};
|
|
13069
13199
|
/** @satisfies {Extension['contentInitial']} */
|
|
@@ -17401,7 +17531,7 @@ function checkRule(state) {
|
|
|
17401
17531
|
* @param {Info} info
|
|
17402
17532
|
* @returns {string}
|
|
17403
17533
|
*/
|
|
17404
|
-
function list$
|
|
17534
|
+
function list$2(node, parent, state, info) {
|
|
17405
17535
|
const exit = state.enter("list");
|
|
17406
17536
|
const bulletCurrent = state.bulletCurrent;
|
|
17407
17537
|
/** @type {string} */
|
|
@@ -17676,7 +17806,7 @@ const handle = {
|
|
|
17676
17806
|
inlineCode,
|
|
17677
17807
|
link,
|
|
17678
17808
|
linkReference,
|
|
17679
|
-
list: list$
|
|
17809
|
+
list: list$2,
|
|
17680
17810
|
listItem,
|
|
17681
17811
|
paragraph,
|
|
17682
17812
|
root,
|
|
@@ -20532,23 +20662,23 @@ function arkmeArticleImageReference(value) {
|
|
|
20532
20662
|
//#endregion
|
|
20533
20663
|
//#region src/record-deletion-ref.ts
|
|
20534
20664
|
const prefix$1 = "arkme-record-delete-v1";
|
|
20535
|
-
const invalid$
|
|
20665
|
+
const invalid$4 = () => new ArkmePluginError("record-delete-reference-invalid", "删除引用已失效,请刷新后重新选择", false, 409);
|
|
20536
20666
|
function sealRecordDeletionRef(ref, key) {
|
|
20537
20667
|
const payload = Buffer.from(JSON.stringify(ref)).toString("base64url");
|
|
20538
20668
|
return `${prefix$1}.${payload}.${createHmac("sha256", key).update(`${prefix$1}.${payload}`).digest("base64url")}`;
|
|
20539
20669
|
}
|
|
20540
20670
|
function openRecordDeletionRef(value, key) {
|
|
20541
|
-
if (typeof value !== "string" || value.length > 2048) throw invalid$
|
|
20671
|
+
if (typeof value !== "string" || value.length > 2048) throw invalid$4();
|
|
20542
20672
|
const [kind, payload, signature, extra] = value.split(".");
|
|
20543
|
-
if (kind !== prefix$1 || !payload || !signature || extra !== void 0) throw invalid$
|
|
20673
|
+
if (kind !== prefix$1 || !payload || !signature || extra !== void 0) throw invalid$4();
|
|
20544
20674
|
const actual = Buffer.from(signature, "base64url");
|
|
20545
20675
|
const expected = createHmac("sha256", key).update(`${prefix$1}.${payload}`).digest();
|
|
20546
|
-
if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) throw invalid$
|
|
20676
|
+
if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) throw invalid$4();
|
|
20547
20677
|
let ref;
|
|
20548
20678
|
try {
|
|
20549
20679
|
ref = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
|
20550
20680
|
} catch {
|
|
20551
|
-
throw invalid$
|
|
20681
|
+
throw invalid$4();
|
|
20552
20682
|
}
|
|
20553
20683
|
if (!ref || !Number.isSafeInteger(ref.userId) || ref.userId <= 0 || !Number.isSafeInteger(ref.recordVersion) || ref.recordVersion <= 0 || ![
|
|
20554
20684
|
"private_chat",
|
|
@@ -20556,7 +20686,7 @@ function openRecordDeletionRef(value, key) {
|
|
|
20556
20686
|
"send_to_self",
|
|
20557
20687
|
"default_category",
|
|
20558
20688
|
"topic"
|
|
20559
|
-
].includes(ref.sourceKind) || typeof ref.sourceOwnerRef !== "string" || !ref.sourceOwnerRef.trim() || typeof ref.recordUid !== "string" || !ref.recordUid.trim()) throw invalid$
|
|
20689
|
+
].includes(ref.sourceKind) || typeof ref.sourceOwnerRef !== "string" || !ref.sourceOwnerRef.trim() || typeof ref.recordUid !== "string" || !ref.recordUid.trim()) throw invalid$4();
|
|
20560
20690
|
return ref;
|
|
20561
20691
|
}
|
|
20562
20692
|
/** Only authoritative Record snapshots can grant deletion; missing versions never fall back to a relation version. */
|
|
@@ -20669,31 +20799,31 @@ var RecordDeletionService = class {
|
|
|
20669
20799
|
};
|
|
20670
20800
|
//#endregion
|
|
20671
20801
|
//#region src/record-topic-assignment-ref.ts
|
|
20672
|
-
const invalid$
|
|
20802
|
+
const invalid$3 = () => new ArkmePluginError("record-topic-reference-invalid", "快记归属引用已失效,请刷新后重新选择", false, 409);
|
|
20673
20803
|
const prefix = "arkme-record-topic-v1";
|
|
20674
20804
|
function sealRecordTopicAssignmentRef(reference, key) {
|
|
20675
20805
|
const payload = Buffer.from(JSON.stringify(reference)).toString("base64url");
|
|
20676
20806
|
return `${prefix}.${payload}.${createHmac("sha256", key).update(`${prefix}.${payload}`).digest("base64url")}`;
|
|
20677
20807
|
}
|
|
20678
20808
|
function openRecordTopicAssignmentRef(value, key) {
|
|
20679
|
-
if (typeof value !== "string" || value.length > 2048) throw invalid$
|
|
20809
|
+
if (typeof value !== "string" || value.length > 2048) throw invalid$3();
|
|
20680
20810
|
const parts = value.split(".");
|
|
20681
|
-
if (parts.length !== 3 || parts[0] !== prefix) throw invalid$
|
|
20811
|
+
if (parts.length !== 3 || parts[0] !== prefix) throw invalid$3();
|
|
20682
20812
|
const payload = parts[1];
|
|
20683
20813
|
const signature = Buffer.from(parts[2], "base64url");
|
|
20684
20814
|
const expected = createHmac("sha256", key).update(`${prefix}.${payload}`).digest();
|
|
20685
|
-
if (signature.length !== expected.length || !timingSafeEqual(signature, expected)) throw invalid$
|
|
20815
|
+
if (signature.length !== expected.length || !timingSafeEqual(signature, expected)) throw invalid$3();
|
|
20686
20816
|
let parsed;
|
|
20687
20817
|
try {
|
|
20688
20818
|
parsed = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
|
20689
20819
|
} catch {
|
|
20690
|
-
throw invalid$
|
|
20820
|
+
throw invalid$3();
|
|
20691
20821
|
}
|
|
20692
20822
|
if (!parsed || !Number.isSafeInteger(parsed.userId) || parsed.userId <= 0 || ![
|
|
20693
20823
|
"send_to_self",
|
|
20694
20824
|
"default_category",
|
|
20695
20825
|
"topic"
|
|
20696
|
-
].includes(parsed.sourceKind) || typeof parsed.sourceOwnerRef !== "string" || parsed.sourceOwnerRef.trim() === "" || typeof parsed.recordUid !== "string" || parsed.recordUid.trim() === "" || typeof parsed.sourceTopicUid !== "string") throw invalid$
|
|
20826
|
+
].includes(parsed.sourceKind) || typeof parsed.sourceOwnerRef !== "string" || parsed.sourceOwnerRef.trim() === "" || typeof parsed.recordUid !== "string" || parsed.recordUid.trim() === "" || typeof parsed.sourceTopicUid !== "string") throw invalid$3();
|
|
20697
20827
|
return parsed;
|
|
20698
20828
|
}
|
|
20699
20829
|
//#endregion
|
|
@@ -34752,6 +34882,16 @@ var BackgroundSoundMembershipService = class {
|
|
|
34752
34882
|
this.runtime = runtime;
|
|
34753
34883
|
}
|
|
34754
34884
|
async current(options = {}) {
|
|
34885
|
+
const { raw, userId } = await this.readCurrent(options);
|
|
34886
|
+
const memberType = memberTypeFromResponse(raw);
|
|
34887
|
+
return {
|
|
34888
|
+
userId,
|
|
34889
|
+
memberType,
|
|
34890
|
+
eligible: memberType > 0
|
|
34891
|
+
};
|
|
34892
|
+
}
|
|
34893
|
+
/** Shared account-bound read for the membership UI and background-sound eligibility. */
|
|
34894
|
+
async readCurrent(options = {}) {
|
|
34755
34895
|
const expectedUserId = options.expectedUserId;
|
|
34756
34896
|
if (expectedUserId !== void 0 && (!Number.isSafeInteger(expectedUserId) || expectedUserId <= 0)) throw new ArkmePluginError("background-sound-membership-expected-user-invalid", "背景音会员资格的预期账号无效", false, 400);
|
|
34757
34897
|
const session = await this.runtime.requireSession();
|
|
@@ -34759,11 +34899,87 @@ var BackgroundSoundMembershipService = class {
|
|
|
34759
34899
|
const raw = await this.runtime.authenticatedAuthReadPost("/api/v1/premium/get/member", {}, session, options.signal);
|
|
34760
34900
|
const currentSession = await this.runtime.requireSession();
|
|
34761
34901
|
if (currentSession.userId !== session.userId || expectedUserId !== void 0 && currentSession.userId !== expectedUserId) throw new ArkmePluginError("background-sound-membership-account-changed", "账号已切换,本次会员资格查询结果已丢弃", false, 409);
|
|
34762
|
-
|
|
34902
|
+
memberTypeFromResponse(raw);
|
|
34763
34903
|
return {
|
|
34764
|
-
|
|
34904
|
+
raw,
|
|
34905
|
+
userId: session.userId
|
|
34906
|
+
};
|
|
34907
|
+
}
|
|
34908
|
+
};
|
|
34909
|
+
//#endregion
|
|
34910
|
+
//#region src/services/membership-service.ts
|
|
34911
|
+
function invalid$2() {
|
|
34912
|
+
throw new ArkmePluginError("membership-contract-invalid", "会员信息暂时无法确认,请稍后重试", true, 502);
|
|
34913
|
+
}
|
|
34914
|
+
function integer$1(value) {
|
|
34915
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) return invalid$2();
|
|
34916
|
+
return value;
|
|
34917
|
+
}
|
|
34918
|
+
function timestamp(value) {
|
|
34919
|
+
if (value === void 0 || value === null || value === 0) return null;
|
|
34920
|
+
const micros = integer$1(value);
|
|
34921
|
+
const millis = Math.floor(micros / 1e3);
|
|
34922
|
+
if (millis < Date.UTC(2e3, 0) || millis > Date.UTC(3e3, 0)) return invalid$2();
|
|
34923
|
+
return millis;
|
|
34924
|
+
}
|
|
34925
|
+
function parseMembership(raw, userId, now = Date.now()) {
|
|
34926
|
+
const memberType = integer$1(raw.member_type);
|
|
34927
|
+
if (memberType > 2) return invalid$2();
|
|
34928
|
+
const expireAtMillis = timestamp(raw.expire_at);
|
|
34929
|
+
return {
|
|
34930
|
+
userId,
|
|
34931
|
+
memberType,
|
|
34932
|
+
expireAtMillis,
|
|
34933
|
+
gifted: raw.is_gifted === 1,
|
|
34934
|
+
lifetime: memberType === 2 && expireAtMillis !== null && expireAtMillis > now + 100 * 365.25 * 864e5
|
|
34935
|
+
};
|
|
34936
|
+
}
|
|
34937
|
+
function parseMembershipProducts(raw) {
|
|
34938
|
+
if (!Array.isArray(raw.data_ls)) return invalid$2();
|
|
34939
|
+
const products = raw.data_ls.map((entry) => {
|
|
34940
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return invalid$2();
|
|
34941
|
+
const row = entry;
|
|
34942
|
+
const memberType = integer$1(row.spu_code);
|
|
34943
|
+
if (memberType !== 1 && memberType !== 2) return invalid$2();
|
|
34944
|
+
if (typeof row.name !== "string" || !row.name.trim() || typeof row.is_period !== "boolean") return invalid$2();
|
|
34945
|
+
const alipayId = integer$1(row.alipay_product_id);
|
|
34946
|
+
const wechatId = integer$1(row.wechat_product_id);
|
|
34947
|
+
if (alipayId === 0 && wechatId === 0) return invalid$2();
|
|
34948
|
+
return {
|
|
34949
|
+
id: `${memberType}:${alipayId}:${wechatId}:${row.is_period ? "recurring" : "once"}`,
|
|
34765
34950
|
memberType,
|
|
34766
|
-
|
|
34951
|
+
name: row.name.trim(),
|
|
34952
|
+
priceMinor: integer$1(row.money),
|
|
34953
|
+
currency: "CNY",
|
|
34954
|
+
recurring: row.is_period,
|
|
34955
|
+
monthCount: integer$1(row.month_count)
|
|
34956
|
+
};
|
|
34957
|
+
});
|
|
34958
|
+
if (new Set(products.map((p) => p.id)).size !== products.length) return invalid$2();
|
|
34959
|
+
return products.sort((a, b) => a.memberType - b.memberType || a.monthCount - b.monthCount || a.priceMinor - b.priceMinor);
|
|
34960
|
+
}
|
|
34961
|
+
/** Membership is distinct from managed-AI balance billing. Only read endpoints are exposed. */
|
|
34962
|
+
var MembershipService = class {
|
|
34963
|
+
runtime;
|
|
34964
|
+
membership;
|
|
34965
|
+
constructor(runtime) {
|
|
34966
|
+
this.runtime = runtime;
|
|
34967
|
+
this.membership = new BackgroundSoundMembershipService(runtime);
|
|
34968
|
+
}
|
|
34969
|
+
async current(expectedUserId) {
|
|
34970
|
+
const { raw, userId } = await this.membership.readCurrent({ expectedUserId });
|
|
34971
|
+
return parseMembership(raw, userId);
|
|
34972
|
+
}
|
|
34973
|
+
async catalog(expectedUserId) {
|
|
34974
|
+
if (!Number.isSafeInteger(expectedUserId) || expectedUserId <= 0) return invalid$2();
|
|
34975
|
+
const session = await this.runtime.requireSession();
|
|
34976
|
+
if (session.userId !== expectedUserId) throw new ArkmePluginError("membership-account-changed", "账号已切换,请重新打开会员页面", false, 409);
|
|
34977
|
+
const raw = await this.runtime.authenticatedAuthReadPost("/api/v1/payment/get/sale-product", {}, session);
|
|
34978
|
+
if ((await this.runtime.requireSession()).userId !== session.userId) throw new ArkmePluginError("membership-account-changed", "账号已切换,已丢弃套餐结果", false, 409);
|
|
34979
|
+
return {
|
|
34980
|
+
userId: session.userId,
|
|
34981
|
+
products: parseMembershipProducts(raw),
|
|
34982
|
+
checkout: "mobile-app-only"
|
|
34767
34983
|
};
|
|
34768
34984
|
}
|
|
34769
34985
|
};
|
|
@@ -35677,9 +35893,9 @@ function arkmePickedFileKind(mimeType, fileName = "") {
|
|
|
35677
35893
|
}
|
|
35678
35894
|
//#endregion
|
|
35679
35895
|
//#region src/call-record-presentation.ts
|
|
35680
|
-
function object$
|
|
35896
|
+
function object$2(value) {
|
|
35681
35897
|
if (typeof value === "string") try {
|
|
35682
|
-
return object$
|
|
35898
|
+
return object$2(JSON.parse(value));
|
|
35683
35899
|
} catch {
|
|
35684
35900
|
return {};
|
|
35685
35901
|
}
|
|
@@ -35688,6 +35904,27 @@ function object$1(value) {
|
|
|
35688
35904
|
function first$1(source, keys) {
|
|
35689
35905
|
return keys.map((key) => source[key]).find((value) => value !== void 0 && value !== null && value !== "");
|
|
35690
35906
|
}
|
|
35907
|
+
/** Only explicit template identities, never names inferred from summary prose. */
|
|
35908
|
+
function callSummaryUserIds(source) {
|
|
35909
|
+
const template = String(first$1(source, [
|
|
35910
|
+
"smt",
|
|
35911
|
+
"call_summary_template",
|
|
35912
|
+
"callSummaryTemplate",
|
|
35913
|
+
"summary_template",
|
|
35914
|
+
"summaryTemplate"
|
|
35915
|
+
]) ?? "");
|
|
35916
|
+
const users = object$2(first$1(source, [
|
|
35917
|
+
"ssu",
|
|
35918
|
+
"summary_speaker_user_ids",
|
|
35919
|
+
"call_summary_speaker_user_ids"
|
|
35920
|
+
]));
|
|
35921
|
+
const ids = /* @__PURE__ */ new Set();
|
|
35922
|
+
for (const match of template.matchAll(/\{\{(user|speaker):([^{}]+)\}\}/g)) {
|
|
35923
|
+
const userId = Number(match[1] === "user" ? match[2] : users[match[0]] ?? users[match[2]]);
|
|
35924
|
+
if (Number.isSafeInteger(userId) && userId > 0) ids.add(userId);
|
|
35925
|
+
}
|
|
35926
|
+
return [...ids];
|
|
35927
|
+
}
|
|
35691
35928
|
/** Flutter-compatible summary templates, resolved on the host before projection. */
|
|
35692
35929
|
function renderCallRecordSummary(source, viewerUserId, displayNames = /* @__PURE__ */ new Map()) {
|
|
35693
35930
|
const fallback = String(first$1(source, [
|
|
@@ -35705,12 +35942,12 @@ function renderCallRecordSummary(source, viewerUserId, displayNames = /* @__PURE
|
|
|
35705
35942
|
"summary_template",
|
|
35706
35943
|
"summaryTemplate"
|
|
35707
35944
|
]) ?? "").trim();
|
|
35708
|
-
const labels = object$
|
|
35945
|
+
const labels = object$2(first$1(source, [
|
|
35709
35946
|
"ssl",
|
|
35710
35947
|
"summary_speaker_labels",
|
|
35711
35948
|
"call_summary_speaker_labels"
|
|
35712
35949
|
]));
|
|
35713
|
-
const users = object$
|
|
35950
|
+
const users = object$2(first$1(source, [
|
|
35714
35951
|
"ssu",
|
|
35715
35952
|
"summary_speaker_user_ids",
|
|
35716
35953
|
"call_summary_speaker_user_ids"
|
|
@@ -35727,10 +35964,10 @@ function renderCallRecordSummary(source, viewerUserId, displayNames = /* @__PURE
|
|
|
35727
35964
|
return text.includes("{{") ? "" : text;
|
|
35728
35965
|
}
|
|
35729
35966
|
function callRecordCandidates(raw) {
|
|
35730
|
-
const root = object$
|
|
35731
|
-
const record = object$
|
|
35732
|
-
const core = object$
|
|
35733
|
-
const payload = object$
|
|
35967
|
+
const root = object$2(raw);
|
|
35968
|
+
const record = object$2(root.record);
|
|
35969
|
+
const core = object$2(root.record_core);
|
|
35970
|
+
const payload = object$2(record.payload ?? root.payload);
|
|
35734
35971
|
const candidates = [];
|
|
35735
35972
|
const seen = /* @__PURE__ */ new Set();
|
|
35736
35973
|
const visit = (value, depth) => {
|
|
@@ -35745,7 +35982,7 @@ function callRecordCandidates(raw) {
|
|
|
35745
35982
|
"payload",
|
|
35746
35983
|
"record",
|
|
35747
35984
|
"record_core"
|
|
35748
|
-
]) if (value[key] != null) visit(object$
|
|
35985
|
+
]) if (value[key] != null) visit(object$2(value[key]), depth + 1);
|
|
35749
35986
|
};
|
|
35750
35987
|
for (const value of [
|
|
35751
35988
|
payload,
|
|
@@ -35768,10 +36005,10 @@ function callRecordSource(raw) {
|
|
|
35768
36005
|
"call_detail",
|
|
35769
36006
|
"callDetail"
|
|
35770
36007
|
]) {
|
|
35771
|
-
const nested = object$
|
|
36008
|
+
const nested = object$2(value[key]);
|
|
35772
36009
|
if (Object.keys(nested).length > 0) return nested;
|
|
35773
36010
|
}
|
|
35774
|
-
const extra = value.extra == null ? void 0 : details(object$
|
|
36011
|
+
const extra = value.extra == null ? void 0 : details(object$2(value.extra), depth + 1);
|
|
35775
36012
|
if (extra) return extra;
|
|
35776
36013
|
if (first$1(value, [
|
|
35777
36014
|
"mt",
|
|
@@ -35801,7 +36038,7 @@ function callRecordRoomId(raw) {
|
|
|
35801
36038
|
]);
|
|
35802
36039
|
if (typeof room === "string" && room.trim()) return room.trim();
|
|
35803
36040
|
for (const candidate of callRecordCandidates(raw)) {
|
|
35804
|
-
const anchor = object$
|
|
36041
|
+
const anchor = object$2(candidate.structured_anchor ?? candidate.structuredAnchor ?? candidate);
|
|
35805
36042
|
if (Number(anchor.anchor_kind ?? anchor.anchorKind) !== 2) continue;
|
|
35806
36043
|
const uid = anchor.anchor_uid ?? anchor.anchorUid;
|
|
35807
36044
|
if (typeof uid === "string" && uid.trim()) return uid.trim();
|
|
@@ -35858,7 +36095,7 @@ function callRecordConversationPreview(raw, viewerUserId = 0) {
|
|
|
35858
36095
|
"payload_kind",
|
|
35859
36096
|
"payloadKind"
|
|
35860
36097
|
]));
|
|
35861
|
-
const anchor = object$
|
|
36098
|
+
const anchor = object$2(value.structured_anchor ?? value.structuredAnchor ?? value);
|
|
35862
36099
|
return template === 9 || (!Number.isFinite(template) || template === 5) && Number(anchor.anchor_kind ?? anchor.anchorKind) === 2;
|
|
35863
36100
|
}))) return void 0;
|
|
35864
36101
|
if (!source) return "[通话]";
|
|
@@ -36397,6 +36634,46 @@ var SourceService = class {
|
|
|
36397
36634
|
if (sourceKind !== 3) return void 0;
|
|
36398
36635
|
return (await this.chatSourcesBySessionUids([ownerRef], signal)).get(ownerRef);
|
|
36399
36636
|
}
|
|
36637
|
+
/** Search one canonical directory page, including names with no matching messages. */
|
|
36638
|
+
async searchConversationNames(options) {
|
|
36639
|
+
const keyword = options.query.trim().normalize("NFKC").toLocaleLowerCase();
|
|
36640
|
+
if (keyword === "") throw new ArkmePluginError("conversation-query-empty", "搜索关键词不能为空", false);
|
|
36641
|
+
const session = await this.runtime.requireSession();
|
|
36642
|
+
const page = await this.listSources("root", {
|
|
36643
|
+
limit: 50,
|
|
36644
|
+
firstPaint: true,
|
|
36645
|
+
...options.cursor === void 0 ? {} : { cursor: options.cursor },
|
|
36646
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
36647
|
+
});
|
|
36648
|
+
options.signal?.throwIfAborted();
|
|
36649
|
+
if (page.hasMore && (!page.nextCursor || page.nextCursor === options.cursor)) throw new ArkmePluginError("conversation-search-incomplete", "会话名称查找未完成,请重试", true);
|
|
36650
|
+
const peerIds = page.items.flatMap((item) => item.kind === "private_chat" && item.peerUserId !== void 0 ? [item.peerUserId] : []);
|
|
36651
|
+
const profiles = peerIds.length === 0 ? /* @__PURE__ */ new Map() : await this.profile.publicProfileSummariesByUserIds(peerIds, session, options.signal);
|
|
36652
|
+
const items = [];
|
|
36653
|
+
for (const directorySource of page.items) {
|
|
36654
|
+
const nickname = profiles.get(directorySource.peerUserId ?? 0)?.nickname.trim() || directorySource.privateNickname;
|
|
36655
|
+
const targetSource = nickname ? {
|
|
36656
|
+
...directorySource,
|
|
36657
|
+
privateNickname: nickname
|
|
36658
|
+
} : directorySource;
|
|
36659
|
+
if (targetSource.kind !== "private_chat" && targetSource.kind !== "group_chat") continue;
|
|
36660
|
+
if (![targetSource.displayName, targetSource.privateNickname ?? ""].some((name) => name.normalize("NFKC").toLocaleLowerCase().includes(keyword))) continue;
|
|
36661
|
+
const ref = await this.openSourceRef(targetSource.sourceRef, session.userId);
|
|
36662
|
+
items.push({
|
|
36663
|
+
sourceKind: 3,
|
|
36664
|
+
sourceUid: ref.ownerRef,
|
|
36665
|
+
title: targetSource.displayName,
|
|
36666
|
+
targetSource,
|
|
36667
|
+
...targetSource.privateNickname ? { nickname: targetSource.privateNickname } : {}
|
|
36668
|
+
});
|
|
36669
|
+
}
|
|
36670
|
+
options.signal?.throwIfAborted();
|
|
36671
|
+
return {
|
|
36672
|
+
items,
|
|
36673
|
+
hasMore: page.hasMore,
|
|
36674
|
+
...page.nextCursor === void 0 ? {} : { nextCursor: page.nextCursor }
|
|
36675
|
+
};
|
|
36676
|
+
}
|
|
36400
36677
|
/** Resolve a bounded set in one directory walk, reusing viewer-scoped source projections. */
|
|
36401
36678
|
async chatSourcesBySessionUids(uids, signal) {
|
|
36402
36679
|
const session = await this.runtime.requireSession();
|
|
@@ -37310,7 +37587,8 @@ var SourceService = class {
|
|
|
37310
37587
|
const sessionKind = numberValue$26(chatSession.session_kind);
|
|
37311
37588
|
const kind = sessionKind === 2 ? "group_chat" : sessionKind === 1 || sessionKind === 3 ? "private_chat" : void 0;
|
|
37312
37589
|
if (uid === "" || kind === void 0) continue;
|
|
37313
|
-
const
|
|
37590
|
+
const privateNickname = stringValue$2(supplement.counterpart_name_snapshot).trim() || stringValue$2(counterpart.display_name_snapshot).trim();
|
|
37591
|
+
const displayName = (kind === "private_chat" ? stringValue$2(supplement.remark).trim() || privateNickname || stringValue$2(supplement.pending_name).trim() || stringValue$2(counterpart.visible_phone).trim() : stringValue$2(chatSession.title)).trim() || "未命名会话";
|
|
37314
37592
|
const preview = arkmeChatConversationPreview(latestRecord, session.userId);
|
|
37315
37593
|
const unreadCount = attention.unreadCount;
|
|
37316
37594
|
const latestRelation = objectValue$2(latestPreview.relation);
|
|
@@ -37329,6 +37607,7 @@ var SourceService = class {
|
|
|
37329
37607
|
kind,
|
|
37330
37608
|
directMessageAdmissionApplicable: sessionKind === 1 && numberValue$26(counterpart.user_id) > 0,
|
|
37331
37609
|
displayName,
|
|
37610
|
+
...kind === "private_chat" && privateNickname !== "" ? { privateNickname } : {},
|
|
37332
37611
|
...kind === "private_chat" && cached?.avatarRef !== void 0 ? { avatarRef: cached.avatarRef } : {},
|
|
37333
37612
|
...kind === "group_chat" && cached?.avatarRefs !== void 0 ? { avatarRefs: [...cached.avatarRefs] } : {},
|
|
37334
37613
|
...kind === "group_chat" && cached?.groupAvatar !== void 0 ? { groupAvatar: cloneSourceItem(cached).groupAvatar } : {},
|
|
@@ -37484,6 +37763,8 @@ var SourceService = class {
|
|
|
37484
37763
|
for (const [index, targetUserId] of privateUserIdByIndex) {
|
|
37485
37764
|
const item = items[index];
|
|
37486
37765
|
if (item === void 0) continue;
|
|
37766
|
+
const nickname = profiles.get(targetUserId)?.nickname?.trim();
|
|
37767
|
+
if (nickname) item.privateNickname = nickname;
|
|
37487
37768
|
if (profiles.get(targetUserId)?.avatarUrl === void 0) {
|
|
37488
37769
|
delete item.avatarRef;
|
|
37489
37770
|
continue;
|
|
@@ -37627,7 +37908,8 @@ var SourceService = class {
|
|
|
37627
37908
|
const peerUserId = numberValue$26(counterpart.user_id);
|
|
37628
37909
|
const kind = sessionKind === 2 ? "group_chat" : sessionKind === 1 || sessionKind === 3 ? "private_chat" : void 0;
|
|
37629
37910
|
if (uid === "" || kind === void 0) throw new Error("invalid chat display snapshot");
|
|
37630
|
-
const
|
|
37911
|
+
const privateNickname = stringValue$2(supplement.counterpart_name_snapshot).trim() || stringValue$2(counterpart.display_name_snapshot).trim();
|
|
37912
|
+
const displayName = (kind === "private_chat" ? stringValue$2(supplement.remark).trim() || privateNickname || stringValue$2(supplement.pending_name).trim() || stringValue$2(counterpart.visible_phone).trim() : stringValue$2(chatSession.title)).trim() || cached?.displayName || "未命名会话";
|
|
37631
37913
|
const latestItem = [...timelineItems].sort((left, right) => (right.sequence ?? 0) - (left.sequence ?? 0))[0];
|
|
37632
37914
|
const latestPreview = latestItem === void 0 ? cached?.latestPreview : latestItem.forwardRecords === void 0 ? arkmeTimelineConversationPreview(latestItem) : `[转发] ${latestItem.forwardRecords.title}`;
|
|
37633
37915
|
const latestSequence = Math.max(numberValue$26(unread.session_last_seq ?? chatSession.last_seq), latestItem?.sequence ?? 0, cached?.latestSequence ?? 0);
|
|
@@ -37646,6 +37928,7 @@ var SourceService = class {
|
|
|
37646
37928
|
kind,
|
|
37647
37929
|
directMessageAdmissionApplicable: sessionKind === 1 && numberValue$26(counterpart.user_id) > 0,
|
|
37648
37930
|
displayName,
|
|
37931
|
+
...kind === "private_chat" && privateNickname !== "" ? { privateNickname } : {},
|
|
37649
37932
|
...kind === "private_chat" && Number.isSafeInteger(peerUserId) && peerUserId > 0 ? { peerUserId } : {},
|
|
37650
37933
|
...kind === "private_chat" && Number.isSafeInteger(peerUserId) && peerUserId > 0 ? { peerMemberType: arkmePeerMemberType(counterpart.member_type) } : {},
|
|
37651
37934
|
...cached?.avatarRef === void 0 ? {} : { avatarRef: cached.avatarRef },
|
|
@@ -39998,8 +40281,15 @@ var CallHistoryService = class {
|
|
|
39998
40281
|
displayName: userId === session.userId ? "我" : "通话参与者",
|
|
39999
40282
|
...userId === session.userId ? { isCurrentUser: true } : {}
|
|
40000
40283
|
});
|
|
40001
|
-
const
|
|
40002
|
-
const
|
|
40284
|
+
const seeds = participantSeeds.slice(0, 50);
|
|
40285
|
+
const summarySeeds = callSummaryUserIds(raw).filter((id) => !seeds.some((participant) => participant.userId === id)).slice(0, 50).map((userId) => ({
|
|
40286
|
+
userId,
|
|
40287
|
+
displayName: ""
|
|
40288
|
+
}));
|
|
40289
|
+
const presentations = await this.attachParticipantPresentation([...seeds, ...summarySeeds], session, signal);
|
|
40290
|
+
const participants = presentations.slice(0, seeds.length);
|
|
40291
|
+
const summaryNames = new Map(presentations.flatMap((participant) => participant.userId && participant.displayName.trim() && !/^(Arkme 用户 \d+|通话参与者)$/.test(participant.displayName.trim()) ? [[participant.userId, participant.displayName]] : []));
|
|
40292
|
+
const summaryText = safeSummary(renderCallRecordSummary(raw, session.userId, summaryNames));
|
|
40003
40293
|
const hangupParticipant = participants.find((participant) => participant.userId === numberValue$22(hangupUserId));
|
|
40004
40294
|
return {
|
|
40005
40295
|
callRef: await this.sealCallRef({
|
|
@@ -40042,17 +40332,18 @@ var CallHistoryService = class {
|
|
|
40042
40332
|
...hangupParticipant ? { hangupParticipant } : {}
|
|
40043
40333
|
};
|
|
40044
40334
|
}
|
|
40045
|
-
async
|
|
40335
|
+
async attachParticipantPresentation(participants, session, signal) {
|
|
40046
40336
|
const ids = [...new Set(participants.flatMap((participant) => participant.userId === void 0 ? [] : [participant.userId]))];
|
|
40047
40337
|
if (ids.length === 0) return participants;
|
|
40048
|
-
const profiles = await this.profile.publicProfileSummariesByUserIds(ids, session, signal).catch(() => /* @__PURE__ */ new Map());
|
|
40338
|
+
const [profiles, remarks] = await Promise.all([this.profile.publicProfileSummariesByUserIds(ids, session, signal).catch(() => /* @__PURE__ */ new Map()), this.source?.privateRemarksByUserIds(ids, signal === void 0 ? {} : { signal }).catch(() => /* @__PURE__ */ new Map()) ?? Promise.resolve(/* @__PURE__ */ new Map())]);
|
|
40049
40339
|
return await Promise.all(participants.map(async (participant) => {
|
|
40050
40340
|
const userId = participant.userId;
|
|
40051
40341
|
if (userId === void 0) return participant;
|
|
40052
40342
|
const profile = profiles.get(userId);
|
|
40343
|
+
const remark = userId === session.userId ? "" : remarks.get(userId)?.trim();
|
|
40053
40344
|
return {
|
|
40054
40345
|
...participant,
|
|
40055
|
-
displayName: profile?.displayName || participant.displayName,
|
|
40346
|
+
displayName: remark || profile?.displayName || participant.displayName,
|
|
40056
40347
|
...profile?.avatarUrl === void 0 ? {} : { avatarRef: await this.profile.sealProfileImageRef(session.userId, userId) }
|
|
40057
40348
|
};
|
|
40058
40349
|
}));
|
|
@@ -42119,7 +42410,7 @@ function botDisplayName(profiles, uid) {
|
|
|
42119
42410
|
}
|
|
42120
42411
|
//#endregion
|
|
42121
42412
|
//#region src/services/chat-sender-display-reader.ts
|
|
42122
|
-
const list = (value) => Array.isArray(value) ? value : [];
|
|
42413
|
+
const list$1 = (value) => Array.isArray(value) ? value : [];
|
|
42123
42414
|
const text$1 = (value) => stringValue$2(value).trim();
|
|
42124
42415
|
const first = (raw, keys) => keys.map((key) => text$1(raw[key])).find(Boolean) ?? "";
|
|
42125
42416
|
/** Normalize wire data once. Neither raw participants nor their extra fields escape this adapter. */
|
|
@@ -42129,7 +42420,7 @@ function botDisplaySnapshot(bundle) {
|
|
|
42129
42420
|
const extra = objectValue$2(session.extra);
|
|
42130
42421
|
const groupTarget = arkmeGroupBotBindingTargetFromBundle(bundle) ?? arkmeGroupBotBindingTargetFromBundle({ rm_subject_id: extra.subject_id ?? extra.legacy_subject_id });
|
|
42131
42422
|
const profiles = /* @__PURE__ */ new Map();
|
|
42132
|
-
for (const value of list(bundle.bot_participants)) {
|
|
42423
|
+
for (const value of list$1(bundle.bot_participants)) {
|
|
42133
42424
|
const participant = objectValue$2(value);
|
|
42134
42425
|
const uid = text$1(participant.bot_uid);
|
|
42135
42426
|
if (uid === "" || text$1(participant.chat_session_uid) !== chatSessionUid) continue;
|
|
@@ -42175,7 +42466,7 @@ var RuntimeBotDisplayProfilesReader = class {
|
|
|
42175
42466
|
let snapshot = input.snapshot;
|
|
42176
42467
|
if (snapshot === void 0) try {
|
|
42177
42468
|
const data = await this.runtime.authenticatedChatPost("/api/v1/chats/display-snapshots", { chat_session_uids: [input.chatSessionUid] }, session, identitySignal, { refreshOnUnauthorized: false });
|
|
42178
|
-
snapshot = list(data.items).map((value) => botDisplaySnapshot(objectValue$2(value))).find((item) => item.chatSessionUid === input.chatSessionUid);
|
|
42469
|
+
snapshot = list$1(data.items).map((value) => botDisplaySnapshot(objectValue$2(value))).find((item) => item.chatSessionUid === input.chatSessionUid);
|
|
42179
42470
|
} catch (error) {
|
|
42180
42471
|
optionalFailure(error);
|
|
42181
42472
|
}
|
|
@@ -42206,7 +42497,7 @@ var RuntimeBotDisplayProfilesReader = class {
|
|
|
42206
42497
|
cancelWhenUnobserved: true
|
|
42207
42498
|
});
|
|
42208
42499
|
const profiles = /* @__PURE__ */ new Map();
|
|
42209
|
-
for (const value of list(data.bots)) {
|
|
42500
|
+
for (const value of list$1(data.bots)) {
|
|
42210
42501
|
const raw = objectValue$2(value);
|
|
42211
42502
|
if (raw.installed === true && text$1(raw.bot_id) !== "" && text$1(raw.name) !== "") profiles.set(text$1(raw.bot_id), {
|
|
42212
42503
|
displayName: text$1(raw.name),
|
|
@@ -42674,7 +42965,7 @@ async function recordReeditMentionMetadata(text, prepared, resolve) {
|
|
|
42674
42965
|
}
|
|
42675
42966
|
//#endregion
|
|
42676
42967
|
//#region src/record-sender-snapshot.ts
|
|
42677
|
-
function object(value) {
|
|
42968
|
+
function object$1(value) {
|
|
42678
42969
|
return value !== null && typeof value === "object" ? value : {};
|
|
42679
42970
|
}
|
|
42680
42971
|
function text(...values) {
|
|
@@ -42682,10 +42973,10 @@ function text(...values) {
|
|
|
42682
42973
|
}
|
|
42683
42974
|
/** Keep the recorded actor, never resolve a historical record through today's profile. */
|
|
42684
42975
|
function recordSenderSnapshot(raw) {
|
|
42685
|
-
const item = object(raw);
|
|
42686
|
-
const core = object(item.record_core);
|
|
42687
|
-
const snapshot = object(core.sender_snapshot ?? item.sender_snapshot);
|
|
42688
|
-
const extra = object(core.extra ?? item.extra);
|
|
42976
|
+
const item = object$1(raw);
|
|
42977
|
+
const core = object$1(item.record_core);
|
|
42978
|
+
const snapshot = object$1(core.sender_snapshot ?? item.sender_snapshot);
|
|
42979
|
+
const extra = object$1(core.extra ?? item.extra);
|
|
42689
42980
|
const avatar = text(snapshot.avatar, core.avatar, item.avatar, extra.sender_avatar_ref);
|
|
42690
42981
|
return {
|
|
42691
42982
|
avatarSnapshot: true,
|
|
@@ -43784,10 +44075,15 @@ var RecordService = class {
|
|
|
43784
44075
|
this.assertReeditActive();
|
|
43785
44076
|
await this.runtime.stateStore.removeLongArticleDraft(session.userId, draft.sourceRef, itemUid);
|
|
43786
44077
|
}
|
|
43787
|
-
async removeLongArticleDraft(sourceRef, itemUid) {
|
|
44078
|
+
async removeLongArticleDraft(sourceRef, itemUid, expectedRecordUid) {
|
|
43788
44079
|
const session = await this.runtime.requireSession();
|
|
43789
44080
|
const source = await this.source.openSourceRef(sourceRef, session.userId);
|
|
43790
44081
|
const uid = itemUid?.trim() || void 0;
|
|
44082
|
+
if (expectedRecordUid !== void 0) {
|
|
44083
|
+
if (uid !== void 0 || expectedRecordUid.trim() === "") throw new ArkmePluginError("long-article-draft-invalid", "长文草稿标识无效", false);
|
|
44084
|
+
await this.runtime.stateStore.removeLongArticleDraft(session.userId, sourceRef, void 0, expectedRecordUid);
|
|
44085
|
+
return;
|
|
44086
|
+
}
|
|
43791
44087
|
if (uid !== void 0) {
|
|
43792
44088
|
const sourceIdentityKey = await this.recordReeditSourceIdentityKey(source);
|
|
43793
44089
|
const current = await this.runtime.stateStore.getRecordReeditDraft(session.userId, sourceIdentityKey, uid);
|
|
@@ -47542,6 +47838,8 @@ var ChatService = class {
|
|
|
47542
47838
|
}
|
|
47543
47839
|
async forwardSourceMessages(sourceRef, actionRefs, options = {}) {
|
|
47544
47840
|
const session = await this.runtime.requireSession();
|
|
47841
|
+
if (options.expectedUserId !== void 0 && options.expectedUserId !== session.userId) throw new ArkmePluginError("file-account-changed", "账号已切换", false, 403);
|
|
47842
|
+
if (options.sendAtMillis !== void 0 && (!Number.isSafeInteger(options.sendAtMillis) || options.sendAtMillis <= 0)) throw new ArkmePluginError("message-actions-time-invalid", "发送时间无效", false);
|
|
47545
47843
|
const source = await this.source.openSourceRef(sourceRef, session.userId);
|
|
47546
47844
|
const targetSourceRef = options.targetSourceRef?.trim() || sourceRef;
|
|
47547
47845
|
const targetSource = targetSourceRef === sourceRef ? source : await this.source.openSourceRef(targetSourceRef, session.userId);
|
|
@@ -47581,7 +47879,7 @@ var ChatService = class {
|
|
|
47581
47879
|
}
|
|
47582
47880
|
};
|
|
47583
47881
|
if (targetSource.kind === "private_chat" || targetSource.kind === "group_chat") {
|
|
47584
|
-
const sendAtMillis = Date.now();
|
|
47882
|
+
const sendAtMillis = options.sendAtMillis ?? Date.now();
|
|
47585
47883
|
const clientRequestId = this.forwardClientRequestId(targetSource.ownerRef, references, sendAtMillis);
|
|
47586
47884
|
const sourceRecordUids = references.some((reference) => reference.sourceKind === "chat_relation") ? [] : references.map((reference) => reference.recordUid).filter((recordUid) => recordUid.trim() !== "");
|
|
47587
47885
|
const data = await postChatMessageCreation(this.runtime, "/api/v1/chats/records/forward", {
|
|
@@ -48297,6 +48595,29 @@ var ChatService = class {
|
|
|
48297
48595
|
editable: numberValue$19(core.owner_user_id) === session.userId && numberValue$19(core.creator_user_id) === session.userId
|
|
48298
48596
|
};
|
|
48299
48597
|
}
|
|
48598
|
+
/** Resolve a complete, owned article, never trust a search excerpt as send content. */
|
|
48599
|
+
async ownLongArticle(itemUid, expectedUserId, signal) {
|
|
48600
|
+
const session = await this.runtime.requireSession();
|
|
48601
|
+
if (session.userId !== expectedUserId) throw new ArkmePluginError("file-account-changed", "账号已切换", false, 403);
|
|
48602
|
+
const target = await this.source.selfTarget(signal);
|
|
48603
|
+
const source = await this.source.openSourceRef(target.sourceRef, session.userId);
|
|
48604
|
+
const detail = await this.record.longArticleDetail(target.sourceRef, itemUid, signal);
|
|
48605
|
+
if (!detail.editable) throw new ArkmePluginError("long-article-not-owned", "只能添加自己创建的长文", false, 403);
|
|
48606
|
+
if ((await this.runtime.requireSession()).userId !== session.userId) throw new ArkmePluginError("file-account-changed", "账号已切换", false, 403);
|
|
48607
|
+
const item = this.withRecordMessageActionRef(source, {
|
|
48608
|
+
...detail,
|
|
48609
|
+
isMe: true,
|
|
48610
|
+
senderName: "我",
|
|
48611
|
+
status: 1,
|
|
48612
|
+
templateKind: 8,
|
|
48613
|
+
displayKind: 1
|
|
48614
|
+
}, session.userId, await this.runtime.stateStore.uniqueCode());
|
|
48615
|
+
if (!item.messageActionRef) throw new ArkmePluginError("long-article-ref-invalid", "长文暂不可添加,请重试", true);
|
|
48616
|
+
return {
|
|
48617
|
+
detail,
|
|
48618
|
+
messageActionRef: item.messageActionRef
|
|
48619
|
+
};
|
|
48620
|
+
}
|
|
48300
48621
|
async updateLongArticle(sourceRef, itemUid, input) {
|
|
48301
48622
|
return await this.record.updateLongArticle(sourceRef, itemUid, input);
|
|
48302
48623
|
}
|
|
@@ -48306,8 +48627,8 @@ var ChatService = class {
|
|
|
48306
48627
|
async putLongArticleDraft(draft) {
|
|
48307
48628
|
return await this.record.putLongArticleDraft(draft);
|
|
48308
48629
|
}
|
|
48309
|
-
async removeLongArticleDraft(sourceRef, itemUid) {
|
|
48310
|
-
return await this.record.removeLongArticleDraft(sourceRef, itemUid);
|
|
48630
|
+
async removeLongArticleDraft(sourceRef, itemUid, expectedRecordUid) {
|
|
48631
|
+
return await this.record.removeLongArticleDraft(sourceRef, itemUid, expectedRecordUid);
|
|
48311
48632
|
}
|
|
48312
48633
|
async uploadLocalFile(filePath, metadata, options = {}) {
|
|
48313
48634
|
return await this.media.uploadLocalFile(filePath, metadata, options);
|
|
@@ -84832,6 +85153,81 @@ function projectRecordingVersions(response, kind) {
|
|
|
84832
85153
|
return versions.sort((left, right) => right.generatedAtMillis - left.generatedAtMillis || left.sourceIndex - right.sourceIndex).map(({ sourceIndex: _sourceIndex, ...version }) => version);
|
|
84833
85154
|
}
|
|
84834
85155
|
//#endregion
|
|
85156
|
+
//#region src/recording-coverage.ts
|
|
85157
|
+
const object = (value) => value !== null && typeof value === "object" ? value : {};
|
|
85158
|
+
const list = (value) => Array.isArray(value) ? value : [];
|
|
85159
|
+
const number = (value) => typeof value === "number" && Number.isFinite(value) ? value : NaN;
|
|
85160
|
+
/** Upload ownership and speaker identity are not the recording's explicit memory attribution. */
|
|
85161
|
+
function recordingBelongsToViewer(session, viewerUserId) {
|
|
85162
|
+
return Number.isSafeInteger(viewerUserId) && viewerUserId > 0 && number(object(session).belong_usr) === viewerUserId;
|
|
85163
|
+
}
|
|
85164
|
+
function clipRecordingCoverage(interval, start, end) {
|
|
85165
|
+
const from = Math.max(start, interval.startAtMillis);
|
|
85166
|
+
const to = Math.min(end, interval.endAtMillis);
|
|
85167
|
+
return Number.isFinite(from) && Number.isFinite(to) && from >= 0 && to > from ? {
|
|
85168
|
+
...interval,
|
|
85169
|
+
startAtMillis: from,
|
|
85170
|
+
endAtMillis: to
|
|
85171
|
+
} : void 0;
|
|
85172
|
+
}
|
|
85173
|
+
/** Use physical audio children, never first/last speech or a session envelope spanning gaps. */
|
|
85174
|
+
function projectRecordingCoverage(response, dayStart, dayEnd, viewerUserId) {
|
|
85175
|
+
const data = object(response);
|
|
85176
|
+
const rawSessions = data.session_ls ?? data.sessions;
|
|
85177
|
+
const rawChildren = data.child_ls ?? data.children;
|
|
85178
|
+
const sessions = new Map(list(rawSessions).map((value) => {
|
|
85179
|
+
const session = object(value);
|
|
85180
|
+
return [String(session.id ?? session.session_id ?? ""), session];
|
|
85181
|
+
}));
|
|
85182
|
+
let incomplete = !Array.isArray(rawSessions) || !Array.isArray(rawChildren) || !Number.isSafeInteger(viewerUserId) || viewerUserId <= 0 || [...sessions.values()].some((session) => !Number.isSafeInteger(session.belong_usr) || number(session.belong_usr) < 0);
|
|
85183
|
+
const childrenBySession = /* @__PURE__ */ new Set();
|
|
85184
|
+
const intervals = [];
|
|
85185
|
+
const add = (interval) => {
|
|
85186
|
+
const clipped = clipRecordingCoverage(interval, dayStart, dayEnd);
|
|
85187
|
+
if (clipped) intervals.push(clipped);
|
|
85188
|
+
};
|
|
85189
|
+
for (const raw of list(rawChildren)) {
|
|
85190
|
+
const child = object(raw);
|
|
85191
|
+
const id = String(child.session_id ?? "");
|
|
85192
|
+
childrenBySession.add(id);
|
|
85193
|
+
const session = sessions.get(id);
|
|
85194
|
+
if (session === void 0) {
|
|
85195
|
+
incomplete = true;
|
|
85196
|
+
continue;
|
|
85197
|
+
}
|
|
85198
|
+
if (!recordingBelongsToViewer(session, viewerUserId)) continue;
|
|
85199
|
+
const start = number(child.start_at);
|
|
85200
|
+
const absoluteStart = start >= 1e11 ? start : number(session?.start_at) + start;
|
|
85201
|
+
const duration = number(child.duration);
|
|
85202
|
+
if (!Number.isFinite(absoluteStart) || absoluteStart < 0 || !(duration > 0)) {
|
|
85203
|
+
incomplete = true;
|
|
85204
|
+
continue;
|
|
85205
|
+
}
|
|
85206
|
+
add({
|
|
85207
|
+
startAtMillis: absoluteStart,
|
|
85208
|
+
endAtMillis: absoluteStart + duration,
|
|
85209
|
+
sourceLabel: typeof session?.orig_name === "string" && session.orig_name.trim() ? session.orig_name : "已同步录音",
|
|
85210
|
+
status: child.has_asr === false ? "processing" : "saved"
|
|
85211
|
+
});
|
|
85212
|
+
}
|
|
85213
|
+
for (const [id, session] of sessions) {
|
|
85214
|
+
if (!recordingBelongsToViewer(session, viewerUserId)) continue;
|
|
85215
|
+
if (childrenBySession.has(id)) continue;
|
|
85216
|
+
const start = number(session.start_at), end = number(session.end_at), duration = number(session.duration);
|
|
85217
|
+
if (session.has_finish_spk === true && duration > 0 && end > start && Math.abs(end - start - duration) < 1) add({
|
|
85218
|
+
startAtMillis: start,
|
|
85219
|
+
endAtMillis: end,
|
|
85220
|
+
sourceLabel: typeof session.orig_name === "string" && session.orig_name ? session.orig_name : "已同步录音",
|
|
85221
|
+
status: "saved"
|
|
85222
|
+
});
|
|
85223
|
+
else incomplete = true;
|
|
85224
|
+
}
|
|
85225
|
+
return {
|
|
85226
|
+
state: incomplete ? "partial" : "ready",
|
|
85227
|
+
intervals: intervals.sort((a, b) => a.startAtMillis - b.startAtMillis)
|
|
85228
|
+
};
|
|
85229
|
+
}
|
|
85230
|
+
//#endregion
|
|
84835
85231
|
//#region src/services/recording-service.ts
|
|
84836
85232
|
function numberValue$5(value) {
|
|
84837
85233
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
@@ -85734,6 +86130,8 @@ var RecordingService = class {
|
|
|
85734
86130
|
dayEndMillis: dayEnd.getTime()
|
|
85735
86131
|
};
|
|
85736
86132
|
const response = transcriptResult.value;
|
|
86133
|
+
const coverage = projectRecordingCoverage(response, date, dayEnd.getTime(), session.userId);
|
|
86134
|
+
const ownSessionIds = new Set(listValue$5(response.session_ls ?? response.sessions).filter((raw) => recordingBelongsToViewer(raw, session.userId)).map((raw) => stringValue$2(objectValue$2(raw).id ?? objectValue$2(raw).session_id).trim()).filter((id) => id !== ""));
|
|
85737
86135
|
const { processingCount: pendingDoubao, candidateCount, failedCount, silentCount } = recordingDoubaoProgress(response, options);
|
|
85738
86136
|
const section = (transcriptSource) => {
|
|
85739
86137
|
const items = projectRecordingTranscripts(response, speakerData, profilesByUserId, {
|
|
@@ -85744,7 +86142,7 @@ var RecordingService = class {
|
|
|
85744
86142
|
return {
|
|
85745
86143
|
state: items.length > 0 ? "ready" : processingCount > 0 ? "processing" : transcriptSource === "doubao" && failedCount > 0 ? "error" : "empty",
|
|
85746
86144
|
items,
|
|
85747
|
-
message: items.length > 0 ? "" : processingCount > 0 ? "音频文字正在导入&转写中" : transcriptSource === "doubao" && failedCount > 0 ? "豆包转写失败,请稍后重试" : transcriptSource === "system" ? "当天无录音" : "暂无豆包转写内容",
|
|
86145
|
+
message: items.length > 0 ? "" : processingCount > 0 ? "音频文字正在导入&转写中" : transcriptSource === "doubao" && failedCount > 0 ? "豆包转写失败,请稍后重试" : transcriptSource === "system" ? coverage.intervals.length > 0 ? "已有录音,暂无转写内容" : "当天无录音" : "暂无豆包转写内容",
|
|
85748
86146
|
identityCoverage: speakerResult.status === "fulfilled" ? "complete" : "partial",
|
|
85749
86147
|
totalDurationMillis,
|
|
85750
86148
|
processingCount
|
|
@@ -85754,7 +86152,9 @@ var RecordingService = class {
|
|
|
85754
86152
|
section,
|
|
85755
86153
|
candidateCount,
|
|
85756
86154
|
failedCount,
|
|
85757
|
-
silentCount
|
|
86155
|
+
silentCount,
|
|
86156
|
+
coverage,
|
|
86157
|
+
ownSessionIds
|
|
85758
86158
|
};
|
|
85759
86159
|
}
|
|
85760
86160
|
async recordingComparison(dateStamp, signal) {
|
|
@@ -85877,13 +86277,14 @@ var RecordingService = class {
|
|
|
85877
86277
|
async recordingDayWithSession(dateStamp, session, signal) {
|
|
85878
86278
|
const date = this.recordingDayStart(dateStamp).getTime();
|
|
85879
86279
|
const [transcriptResult, summaryResult, timelineResult] = await Promise.allSettled([
|
|
85880
|
-
this.
|
|
86280
|
+
this.readRecordingTranscripts(date, session, signal),
|
|
85881
86281
|
this.recordingProjectionWithSession(date, "summary", session, signal),
|
|
85882
86282
|
this.recordingProjectionWithSession(date, "timeline", session, signal)
|
|
85883
86283
|
]);
|
|
85884
86284
|
let transcript;
|
|
85885
86285
|
if (transcriptResult.status === "fulfilled") {
|
|
85886
|
-
const
|
|
86286
|
+
const section = transcriptResult.value.section("system");
|
|
86287
|
+
const items = section.items;
|
|
85887
86288
|
const counts = /* @__PURE__ */ new Map();
|
|
85888
86289
|
for (const item of items) {
|
|
85889
86290
|
const key = this.recordingSpeakerMutationKey(item);
|
|
@@ -85892,8 +86293,11 @@ var RecordingService = class {
|
|
|
85892
86293
|
const recordingItemRefKey = await this.recordingRefKey("arkme-recording-item-v1");
|
|
85893
86294
|
const speakerRefKey = await this.recordingRefKey("arkme-recording-speaker-v1");
|
|
85894
86295
|
transcript = {
|
|
85895
|
-
...
|
|
85896
|
-
items: items.map((item) =>
|
|
86296
|
+
...section,
|
|
86297
|
+
items: items.map((item) => ({
|
|
86298
|
+
...this.workbenchItem(date, item, counts.get(this.recordingSpeakerMutationKey(item)) ?? 1, session.userId, recordingItemRefKey, speakerRefKey),
|
|
86299
|
+
recordingBelongsToViewer: transcriptResult.value.ownSessionIds.has(item.sessionId)
|
|
86300
|
+
}))
|
|
85897
86301
|
};
|
|
85898
86302
|
} else transcript = {
|
|
85899
86303
|
state: "error",
|
|
@@ -85904,7 +86308,11 @@ var RecordingService = class {
|
|
|
85904
86308
|
};
|
|
85905
86309
|
return {
|
|
85906
86310
|
dateStamp: date,
|
|
85907
|
-
|
|
86311
|
+
coverage: transcriptResult.status === "fulfilled" ? transcriptResult.value.coverage : {
|
|
86312
|
+
state: "error",
|
|
86313
|
+
intervals: []
|
|
86314
|
+
},
|
|
86315
|
+
totalDurationMillis: transcriptResult.status === "fulfilled" ? transcript.totalDurationMillis : 0,
|
|
85908
86316
|
transcript,
|
|
85909
86317
|
summary: summaryResult.status === "fulfilled" ? summaryResult.value : {
|
|
85910
86318
|
state: "error",
|
|
@@ -86970,6 +87378,257 @@ async function resolveDshSearchOrigins(provider, items, signal) {
|
|
|
86970
87378
|
} : item);
|
|
86971
87379
|
}
|
|
86972
87380
|
//#endregion
|
|
87381
|
+
//#region src/text-link-tlds.ts
|
|
87382
|
+
const validLinkTlds = new Set(`
|
|
87383
|
+
aarp abb abbott abbvie abc able abogado abudhabi ac academy accenture accountant accountants aco actor ad
|
|
87384
|
+
ads adult ae aeg aero aetna af afl africa ag agakhan agency ai aig airbus airforce
|
|
87385
|
+
airtel akdn al alibaba alipay allfinanz allstate ally alsace alstom am amazon americanexpress americanfamily amex amfam
|
|
87386
|
+
amica amsterdam analytics android anquan anz ao aol apartments app apple aq aquarelle ar arab aramco
|
|
87387
|
+
archi army arpa art arte as asda asia associates at athleta attorney au auction audi audible
|
|
87388
|
+
audio auspost author auto autos aw aws ax axa az azure ba baby baidu banamex band
|
|
87389
|
+
bank bar barcelona barclaycard barclays barefoot bargains baseball basketball bauhaus bayern bb bbc bbt bbva bcg
|
|
87390
|
+
bcn bd be beats beauty beer berlin best bestbuy bet bf bg bh bharti bi bible
|
|
87391
|
+
bid bike bing bingo bio biz bj black blackfriday blockbuster blog bloomberg blue bm bms bmw
|
|
87392
|
+
bn bnpparibas bo boats boehringer bofa bom bond boo book booking bosch bostik boston bot boutique
|
|
87393
|
+
box br bradesco bridgestone broadway broker brother brussels bs bt build builders business buy buzz bv
|
|
87394
|
+
bw by bz bzh ca cab cafe cal call calvinklein cam camera camp canon capetown capital
|
|
87395
|
+
capitalone car caravan cards care career careers cars casa case cash casino cat catering catholic cba
|
|
87396
|
+
cbn cbre cc cd center ceo cern cf cfa cfd cg ch chanel channel charity chase
|
|
87397
|
+
chat cheap chintai christmas chrome church ci cipriani circle cisco citadel citi citic city ck cl
|
|
87398
|
+
claims cleaning click clinic clinique clothing cloud club clubmed cm cn co coach codes coffee college
|
|
87399
|
+
cologne com commbank community company compare computer comsec condos construction consulting contact contractors cooking cool coop
|
|
87400
|
+
corsica country coupon coupons courses cpa cr credit creditcard creditunion cricket crown crs cruise cruises cu
|
|
87401
|
+
cuisinella cv cw cx cy cymru cyou cz dad dance data date dating datsun day dclk
|
|
87402
|
+
dds de deal dealer deals degree delivery dell deloitte delta democrat dental dentist desi design dev
|
|
87403
|
+
dhl diamonds diet digital direct directory discount discover dish diy dj dk dm dnp do docs
|
|
87404
|
+
doctor dog domains dot download drive dtv dubai dunlop dupont durban dvag dvr dz earth eat
|
|
87405
|
+
ec eco edeka edu education ee eg email emerck energy engineer engineering enterprises epson equipment er
|
|
87406
|
+
ericsson erni es esq estate et eu eurovision eus events exchange expert exposed express extraspace fage
|
|
87407
|
+
fail fairwinds faith family fan fans farm farmers fashion fast fedex feedback ferrari ferrero fi fidelity
|
|
87408
|
+
fido film final finance financial fire firestone firmdale fish fishing fit fitness fj fk flickr flights
|
|
87409
|
+
flir florist flowers fly fm fo foo food football ford forex forsale forum foundation fox fr
|
|
87410
|
+
free fresenius frl frogans frontier ftr fujitsu fun fund furniture futbol fyi ga gal gallery gallo
|
|
87411
|
+
gallup game games gap garden gay gb gbiz gd gdn ge gea gent genting george gf
|
|
87412
|
+
gg ggee gh gi gift gifts gives giving gl glass gle global globo gm gmail gmbh
|
|
87413
|
+
gmo gmx gn godaddy gold goldpoint golf goo goodyear goog google gop got gov gp gq
|
|
87414
|
+
gr grainger graphics gratis green gripe grocery group gs gt gu gucci guge guide guitars guru
|
|
87415
|
+
gw gy hair hamburg hangout haus hbo hdfc hdfcbank health healthcare help helsinki here hermes hiphop
|
|
87416
|
+
hisamitsu hitachi hiv hk hkt hm hn hockey holdings holiday homedepot homegoods homes homesense honda horse
|
|
87417
|
+
hospital host hosting hot hotels hotmail house how hr hsbc ht hu hughes hyatt hyundai ibm
|
|
87418
|
+
icbc ice icu id ie ieee ifm ikano il im imamat imdb immo immobilien in inc
|
|
87419
|
+
industries infiniti info ing ink institute insurance insure int international intuit investments io ipiranga iq ir
|
|
87420
|
+
irish is ismaili ist istanbul it itau itv jaguar java jcb je jeep jetzt jewelry jio
|
|
87421
|
+
jll jm jmp jnj jo jobs joburg jot joy jp jpmorgan jprs juegos juniper kaufen kddi
|
|
87422
|
+
ke kerryhotels kerryproperties kfh kg kh ki kia kids kim kindle kitchen kiwi km kn koeln
|
|
87423
|
+
komatsu kosher kp kpmg kpn kr krd kred kuokgroup kw ky kyoto kz la lacaixa lamborghini
|
|
87424
|
+
lamer land landrover lanxess lasalle lat latino latrobe law lawyer lb lc lds lease leclerc lefrak
|
|
87425
|
+
legal lego lexus lgbt li lidl life lifeinsurance lifestyle lighting like lilly limited limo lincoln link
|
|
87426
|
+
live living lk llc llp loan loans locker locus lol london lotte lotto love lpl lplfinancial
|
|
87427
|
+
lr ls lt ltd ltda lu lundbeck luxe luxury lv ly ma madrid maif maison makeup
|
|
87428
|
+
man management mango map market marketing markets marriott marshalls mattel mba mc mckinsey md me med
|
|
87429
|
+
media meet melbourne meme memorial men menu merckmsd mg mh miami microsoft mil mini mint mit
|
|
87430
|
+
mitsubishi mk ml mlb mls mm mma mn mo mobi mobile moda moe moi mom monash
|
|
87431
|
+
money monster mormon mortgage moscow moto motorcycles mov movie mp mq mr ms msd mt mtn
|
|
87432
|
+
mtr mu museum music mv mw mx my mz na nab nagoya name navy nba nc
|
|
87433
|
+
ne nec net netbank netflix network neustar new news next nextdirect nexus nf nfl ng ngo
|
|
87434
|
+
nhk ni nico nike nikon ninja nissan nissay nl no nokia norton now nowruz nowtv np
|
|
87435
|
+
nr nra nrw ntt nu nyc nz obi observer office okinawa olayan olayangroup ollo om omega
|
|
87436
|
+
one ong onl online ooo open oracle orange org organic origins osaka otsuka ott ovh pa
|
|
87437
|
+
page panasonic paris pars partners parts party pay pccw pe pet pf pfizer pg ph pharmacy
|
|
87438
|
+
phd philips phone photo photography photos physio pics pictet pictures pid pin ping pink pioneer pizza
|
|
87439
|
+
pk pl place play playstation plumbing plus pm pn pnc pohl poker politie porn post pr
|
|
87440
|
+
praxi press prime pro prod productions prof progressive promo properties property protection pru prudential ps pt
|
|
87441
|
+
pub pw pwc py qa qpon quebec quest racing radio re read realestate realtor realty recipes
|
|
87442
|
+
red redstone redumbrella rehab reise reisen reit reliance ren rent rentals repair report republican rest restaurant
|
|
87443
|
+
review reviews rexroth rich richardli ricoh ril rio rip ro rocks rodeo rogers room rs rsvp
|
|
87444
|
+
ru rugby ruhr run rw rwe ryukyu sa saarland safe safety sakura sale salon samsclub samsung
|
|
87445
|
+
sandvik sandvikcoromant sanofi sap sarl sas save saxo sb sbi sbs sc scb schaeffler schmidt scholarships
|
|
87446
|
+
school schule schwarz science scot sd se search seat secure security seek select sener services seven
|
|
87447
|
+
sew sex sexy sfr sg sh shangrila sharp shell shia shiksha shoes shop shopping shouji show
|
|
87448
|
+
si silk sina singles site sj sk ski skin sky skype sl sling sm smart smile
|
|
87449
|
+
sn sncf so soccer social softbank software sohu solar solutions song sony soy spa space sport
|
|
87450
|
+
spot sr srl ss st stada staples star statebank statefarm stc stcgroup stockholm storage store stream
|
|
87451
|
+
studio study style su sucks supplies supply support surf surgery suzuki sv swatch swiss sx sy
|
|
87452
|
+
sydney systems sz tab taipei talk taobao target tatamotors tatar tattoo tax taxi tc tci td
|
|
87453
|
+
tdk team tech technology tel temasek tennis teva tf tg th thd theater theatre tiaa tickets
|
|
87454
|
+
tienda tips tires tirol tj tjmaxx tjx tk tkmaxx tl tm tmall tn to today tokyo
|
|
87455
|
+
tools top toray toshiba total tours town toyota toys tr trade trading training travel travelers travelersinsurance
|
|
87456
|
+
trust trv tt tube tui tunes tushu tv tvs tw tz ua ubank ubs ug uk
|
|
87457
|
+
unicom university uno uol ups us uy uz va vacations vana vanguard vc ve vegas ventures
|
|
87458
|
+
verisign versicherung vet vg vi viajes video vig viking villas vin vip virgin visa vision viva
|
|
87459
|
+
vivo vlaanderen vn vodka volvo vote voting voto voyage vu wales walmart walter wang wanggou watch
|
|
87460
|
+
watches weather weatherchannel webcam weber website wed wedding weibo weir wf whoswho wien wiki williamhill win
|
|
87461
|
+
windows wine winners wme wolterskluwer woodside work works world wow ws wtc wtf xbox xerox xihuan
|
|
87462
|
+
xin xn--11b4c3d xn--1ck2e1b xn--1qqw23a xn--2scrj9c xn--30rr7y xn--3bst00m xn--3ds443g xn--3e0b707e xn--3hcrj9c xn--3pxu8k xn--42c2d9a xn--45br5cyl xn--45brj9c xn--45q11c xn--4dbrk0ce
|
|
87463
|
+
xn--4gbrim xn--54b7fta0cc xn--55qw42g xn--55qx5d xn--5su34j936bgsg xn--5tzm5g xn--6frz82g xn--6qq986b3xl xn--80adxhks xn--80ao21a xn--80aqecdr1a xn--80asehdb xn--80aswg xn--8y0a063a xn--90a3ac xn--90ae
|
|
87464
|
+
xn--90ais xn--9dbq2a xn--9et52u xn--9krt00a xn--b4w605ferd xn--bck1b9a5dre4c xn--c1avg xn--c2br7g xn--cck2b3b xn--cckwcxetd xn--cg4bki xn--clchc0ea0b2g2a9gcd xn--czr694b xn--czrs0t xn--czru2d xn--d1acj3b
|
|
87465
|
+
xn--d1alf xn--e1a4c xn--eckvdtc9d xn--efvy88h xn--fct429k xn--fhbei xn--fiq228c5hs xn--fiq64b xn--fiqs8s xn--fiqz9s xn--fjq720a xn--flw351e xn--fpcrj9c3d xn--fzc2c9e2c xn--fzys8d69uvgm xn--g2xx48c
|
|
87466
|
+
xn--gckr3f0f xn--gecrj9c xn--gk3at1e xn--h2breg3eve xn--h2brj9c xn--h2brj9c8c xn--hxt814e xn--i1b6b1a6a2e xn--imr513n xn--io0a7i xn--j1aef xn--j1amh xn--j6w193g xn--jlq480n2rg xn--jvr189m xn--kcrx77d1x4a
|
|
87467
|
+
xn--kprw13d xn--kpry57d xn--kput3i xn--l1acc xn--lgbbat1ad8j xn--mgb9awbf xn--mgba3a3ejt xn--mgba3a4f16a xn--mgba7c0bbn0a xn--mgbaam7a8h xn--mgbab2bd xn--mgbah1a3hjkrd xn--mgbai9azgqp6j xn--mgbayh7gpa xn--mgbbh1a xn--mgbbh1a71e
|
|
87468
|
+
xn--mgbc0a9azcg xn--mgbca7dzdo xn--mgbcpq6gpa1a xn--mgberp4a5d4ar xn--mgbgu82a xn--mgbi4ecexp xn--mgbpl2fh xn--mgbt3dhd xn--mgbtx2b xn--mgbx4cd0ab xn--mix891f xn--mk1bu44c xn--mxtq1m xn--ngbc5azd xn--ngbe9e0a xn--ngbrx
|
|
87469
|
+
xn--node xn--nqv7f xn--nqv7fs00ema xn--nyqy26a xn--o3cw4h xn--ogbpf8fl xn--otu796d xn--p1acf xn--p1ai xn--pgbs0dh xn--pssy2u xn--q7ce6a xn--q9jyb4c xn--qcka1pmc xn--qxa6a xn--qxam
|
|
87470
|
+
xn--rhqv96g xn--rovu88b xn--rvc1e0am3e xn--s9brj9c xn--ses554g xn--t60b56a xn--tckwe xn--tiq49xqyj xn--unup4y xn--vermgensberater-ctb xn--vermgensberatung-pwb xn--vhquv xn--vuq861b xn--w4r85el8fhu5dnra xn--w4rs40l xn--wgbh1c
|
|
87471
|
+
xn--wgbl6a xn--xhq521b xn--xkc2al3hye2a xn--xkc2dl3a5ee0h xn--y9a3aq xn--yfro4i67o xn--ygbi2ammx xn--zfr164b xxx xyz yachts yahoo yamaxun yandex ye yodobashi
|
|
87472
|
+
yoga yokohama you youtube yt yun za zappos zara zero zip zm zone zuerich zw
|
|
87473
|
+
`.trim().split(/\s+/u));
|
|
87474
|
+
function isValidLinkTld(value) {
|
|
87475
|
+
return validLinkTlds.has(value.toLowerCase());
|
|
87476
|
+
}
|
|
87477
|
+
//#endregion
|
|
87478
|
+
//#region src/text-link-parser.ts
|
|
87479
|
+
const urlCandidatePattern = /(?<![a-z0-9_-])(?:[a-z][a-z0-9+.-]*:\/\/[-a-z0-9._~%!$&'*+,;=:@\\]+(?:[/?#][^\s<>{}()()【】,。!?;、“”‘’]*)?|(?:javascript|data):[^\s<>{}()()【】,。!?;、“”‘’]*|(?:www\.)?(?=[a-z0-9.-]*\.)[a-z0-9][a-z0-9.-]*(?::[a-z0-9_+-]*)?(?:[/?#\\][^\s<>{}()()【】,。!?;:、“”‘’]*)?)/giu;
|
|
87480
|
+
const explicitSchemePattern = /^[a-z][a-z0-9+.-]*:\/\//iu;
|
|
87481
|
+
const trailingPunctuationPattern = /[.,!?;:,。!?;:、'"“”‘’]+$/u;
|
|
87482
|
+
const asciiContinuationPattern = /[a-z0-9_-]/iu;
|
|
87483
|
+
const ipv4Pattern = /^(?:\d{1,3}\.){3}\d{1,3}$/u;
|
|
87484
|
+
const domainLabelPattern = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/iu;
|
|
87485
|
+
const riskyBareFileLikeTlds = /* @__PURE__ */ new Set([
|
|
87486
|
+
"apk",
|
|
87487
|
+
"avi",
|
|
87488
|
+
"conf",
|
|
87489
|
+
"csv",
|
|
87490
|
+
"doc",
|
|
87491
|
+
"docs",
|
|
87492
|
+
"docx",
|
|
87493
|
+
"dmg",
|
|
87494
|
+
"exe",
|
|
87495
|
+
"gif",
|
|
87496
|
+
"gz",
|
|
87497
|
+
"ini",
|
|
87498
|
+
"ipa",
|
|
87499
|
+
"jpeg",
|
|
87500
|
+
"jpg",
|
|
87501
|
+
"json",
|
|
87502
|
+
"log",
|
|
87503
|
+
"md",
|
|
87504
|
+
"mkv",
|
|
87505
|
+
"mov",
|
|
87506
|
+
"mp3",
|
|
87507
|
+
"mp4",
|
|
87508
|
+
"msi",
|
|
87509
|
+
"pdf",
|
|
87510
|
+
"png",
|
|
87511
|
+
"rar",
|
|
87512
|
+
"svg",
|
|
87513
|
+
"tar",
|
|
87514
|
+
"txt",
|
|
87515
|
+
"webp",
|
|
87516
|
+
"xml",
|
|
87517
|
+
"yaml",
|
|
87518
|
+
"yml",
|
|
87519
|
+
"zip"
|
|
87520
|
+
]);
|
|
87521
|
+
function isExplicitUrl(text) {
|
|
87522
|
+
return explicitSchemePattern.test(text);
|
|
87523
|
+
}
|
|
87524
|
+
function trimTrailingPunctuation(text) {
|
|
87525
|
+
let candidate = text.replace(trailingPunctuationPattern, "");
|
|
87526
|
+
let squareBracketBalance = 0;
|
|
87527
|
+
for (const character of candidate) if (character === "[") squareBracketBalance += 1;
|
|
87528
|
+
else if (character === "]") squareBracketBalance -= 1;
|
|
87529
|
+
while (candidate.endsWith("]") && squareBracketBalance < 0) {
|
|
87530
|
+
candidate = candidate.slice(0, -1);
|
|
87531
|
+
squareBracketBalance += 1;
|
|
87532
|
+
}
|
|
87533
|
+
return candidate;
|
|
87534
|
+
}
|
|
87535
|
+
function isValidIpv4(host) {
|
|
87536
|
+
if (!ipv4Pattern.test(host) || host === "0.0.0.0") return false;
|
|
87537
|
+
return host.split(".").every((part) => {
|
|
87538
|
+
const value = Number(part);
|
|
87539
|
+
return Number.isInteger(value) && value >= 0 && value <= 255;
|
|
87540
|
+
});
|
|
87541
|
+
}
|
|
87542
|
+
function isValidDomain(host) {
|
|
87543
|
+
if (host.length > 253) return false;
|
|
87544
|
+
const labels = host.split(".");
|
|
87545
|
+
if (labels.length < 2 || labels.some((label) => !domainLabelPattern.test(label))) return false;
|
|
87546
|
+
const tld = labels.at(-1)?.toLowerCase();
|
|
87547
|
+
return tld !== void 0 && isValidLinkTld(tld);
|
|
87548
|
+
}
|
|
87549
|
+
function isValidHost(host) {
|
|
87550
|
+
if (host === "localhost") return true;
|
|
87551
|
+
return ipv4Pattern.test(host) ? isValidIpv4(host) : isValidDomain(host);
|
|
87552
|
+
}
|
|
87553
|
+
function isLikelyNumericShortBareDomain(text, host) {
|
|
87554
|
+
if (isExplicitUrl(text) || /^www\./iu.test(text) || ipv4Pattern.test(host)) return false;
|
|
87555
|
+
const labels = host.split(".");
|
|
87556
|
+
return labels.length === 2 && /^\d$/u.test(labels[0] ?? "");
|
|
87557
|
+
}
|
|
87558
|
+
function isLikelyFileLikeBareDomain(text, host) {
|
|
87559
|
+
if (isExplicitUrl(text) || /^www\./iu.test(text) || ipv4Pattern.test(host)) return false;
|
|
87560
|
+
const labels = host.split(".");
|
|
87561
|
+
return labels.length === 2 && riskyBareFileLikeTlds.has(labels.at(-1)?.toLowerCase() ?? "");
|
|
87562
|
+
}
|
|
87563
|
+
function rawHost(text) {
|
|
87564
|
+
const authorityStart = isExplicitUrl(text) ? text.indexOf("://") + 3 : 0;
|
|
87565
|
+
const host = (text.slice(authorityStart).split(/[/?#\\]/u, 1)[0] ?? "").replace(/:\d{1,5}$/u, "").toLowerCase();
|
|
87566
|
+
return host === "" ? void 0 : host;
|
|
87567
|
+
}
|
|
87568
|
+
function normalizedHref(text) {
|
|
87569
|
+
if (text.includes("\\")) return void 0;
|
|
87570
|
+
const sourceHost = rawHost(text);
|
|
87571
|
+
if (sourceHost === void 0 || !isValidHost(sourceHost)) return void 0;
|
|
87572
|
+
if (sourceHost === "localhost" && !isExplicitUrl(text)) return void 0;
|
|
87573
|
+
const href = isExplicitUrl(text) ? text : `https://${text}`;
|
|
87574
|
+
try {
|
|
87575
|
+
const url = new URL(href);
|
|
87576
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return void 0;
|
|
87577
|
+
if (url.username !== "" || url.password !== "" || !isValidHost(url.hostname)) return void 0;
|
|
87578
|
+
if (url.pathname.includes("\\") || url.search.includes("\\") || url.hash.includes("\\")) return void 0;
|
|
87579
|
+
if (url.search.toLowerCase().includes("javascript:") || url.hash.includes("##")) return void 0;
|
|
87580
|
+
if (isLikelyNumericShortBareDomain(text, sourceHost)) return void 0;
|
|
87581
|
+
if (isLikelyFileLikeBareDomain(text, sourceHost)) return void 0;
|
|
87582
|
+
return href;
|
|
87583
|
+
} catch {
|
|
87584
|
+
return;
|
|
87585
|
+
}
|
|
87586
|
+
}
|
|
87587
|
+
function pushText(runs, text) {
|
|
87588
|
+
if (text === "") return;
|
|
87589
|
+
const previous = runs.at(-1);
|
|
87590
|
+
if (previous?.kind === "text") {
|
|
87591
|
+
runs[runs.length - 1] = {
|
|
87592
|
+
kind: "text",
|
|
87593
|
+
text: previous.text + text
|
|
87594
|
+
};
|
|
87595
|
+
return;
|
|
87596
|
+
}
|
|
87597
|
+
runs.push({
|
|
87598
|
+
kind: "text",
|
|
87599
|
+
text
|
|
87600
|
+
});
|
|
87601
|
+
}
|
|
87602
|
+
function textLinkRuns(text) {
|
|
87603
|
+
const runs = [];
|
|
87604
|
+
let cursor = 0;
|
|
87605
|
+
for (const match of text.matchAll(urlCandidatePattern)) {
|
|
87606
|
+
const candidate = trimTrailingPunctuation(match[0]);
|
|
87607
|
+
if (candidate === "") continue;
|
|
87608
|
+
const start = match.index;
|
|
87609
|
+
const end = start + candidate.length;
|
|
87610
|
+
const href = normalizedHref(candidate);
|
|
87611
|
+
const hasEmailBoundary = start > 0 && text[start - 1] === "@";
|
|
87612
|
+
const hasSuspiciousRightBoundary = !isExplicitUrl(candidate) && !/^www\./iu.test(candidate) && end < text.length && asciiContinuationPattern.test(text[end] ?? "");
|
|
87613
|
+
if (href === void 0 || hasEmailBoundary || hasSuspiciousRightBoundary) continue;
|
|
87614
|
+
pushText(runs, text.slice(cursor, start));
|
|
87615
|
+
runs.push({
|
|
87616
|
+
kind: "link",
|
|
87617
|
+
text: candidate,
|
|
87618
|
+
href
|
|
87619
|
+
});
|
|
87620
|
+
cursor = end;
|
|
87621
|
+
}
|
|
87622
|
+
pushText(runs, text.slice(cursor));
|
|
87623
|
+
return runs;
|
|
87624
|
+
}
|
|
87625
|
+
//#endregion
|
|
87626
|
+
//#region src/search-record-links.ts
|
|
87627
|
+
/** Extract before the search excerpt is clipped, using the same safe URLs as chat rendering. */
|
|
87628
|
+
function arkmeSearchRecordLinks(text) {
|
|
87629
|
+
return [...new Set(textLinkRuns(text).flatMap((run) => run.kind === "link" ? [run.href] : []))];
|
|
87630
|
+
}
|
|
87631
|
+
//#endregion
|
|
86973
87632
|
//#region src/services/search-service.ts
|
|
86974
87633
|
function numberValue$2(value) {
|
|
86975
87634
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
@@ -87201,7 +87860,7 @@ var SearchService = class {
|
|
|
87201
87860
|
};
|
|
87202
87861
|
}
|
|
87203
87862
|
async withNavigationTargets(result, signal, sourceRef) {
|
|
87204
|
-
if (this.source === void 0 || result.items.length === 0) return result;
|
|
87863
|
+
if (this.source === void 0 || result.items.length === 0 && result.sourceAggregates.length === 0) return result;
|
|
87205
87864
|
if (sourceRef !== void 0) {
|
|
87206
87865
|
const session = await this.runtime.requireSession();
|
|
87207
87866
|
const source = await this.source.openSourceRef(sourceRef, session.userId);
|
|
@@ -87210,7 +87869,8 @@ var SearchService = class {
|
|
|
87210
87869
|
...result,
|
|
87211
87870
|
items: result.items.map((item) => item.sourceKind === 3 && (item.sourceUid ?? item.routeTargetUid) === source.ownerRef ? {
|
|
87212
87871
|
...item,
|
|
87213
|
-
targetSource
|
|
87872
|
+
targetSource,
|
|
87873
|
+
sourceTitle: targetSource.displayName
|
|
87214
87874
|
} : item)
|
|
87215
87875
|
};
|
|
87216
87876
|
}
|
|
@@ -87218,14 +87878,33 @@ var SearchService = class {
|
|
|
87218
87878
|
const aggregateTitleByKey = new Map(result.sourceAggregates.map((item) => [`${String(item.sourceKind)}:${item.sourceUid}`, item.title]));
|
|
87219
87879
|
for (const item of result.items) {
|
|
87220
87880
|
const sourceUid = item.sourceUid ?? item.routeTargetUid ?? "";
|
|
87221
|
-
|
|
87881
|
+
const key = `${String(item.sourceKind)}:${sourceUid}`;
|
|
87882
|
+
targets.set(key, {
|
|
87883
|
+
sourceKind: item.sourceKind,
|
|
87884
|
+
sourceUid,
|
|
87885
|
+
title: item.sourceTitle ?? aggregateTitleByKey.get(key) ?? ""
|
|
87886
|
+
});
|
|
87887
|
+
}
|
|
87888
|
+
for (const item of result.sourceAggregates) {
|
|
87889
|
+
const key = `${String(item.sourceKind)}:${item.sourceUid}`;
|
|
87890
|
+
if (!targets.has(key)) targets.set(key, item);
|
|
87222
87891
|
}
|
|
87223
87892
|
const sourceByKey = /* @__PURE__ */ new Map();
|
|
87224
|
-
|
|
87225
|
-
|
|
87893
|
+
const chatUids = [...targets.values()].filter((item) => item.sourceKind === 3).map((item) => item.sourceUid);
|
|
87894
|
+
if (chatUids.length > 0) try {
|
|
87895
|
+
const chats = await this.source.chatSourcesBySessionUids(chatUids, signal);
|
|
87896
|
+
for (const [uid, source] of chats) sourceByKey.set(`3:${uid}`, source);
|
|
87226
87897
|
} catch (error) {
|
|
87227
87898
|
if (signal?.aborted) throw error;
|
|
87228
|
-
|
|
87899
|
+
}
|
|
87900
|
+
for (const [key, item] of targets) {
|
|
87901
|
+
if (item.sourceKind === 3) continue;
|
|
87902
|
+
try {
|
|
87903
|
+
sourceByKey.set(key, await this.source.searchTargetSource(item.sourceKind, item.sourceUid, item.title, signal));
|
|
87904
|
+
} catch (error) {
|
|
87905
|
+
if (signal?.aborted) throw error;
|
|
87906
|
+
sourceByKey.set(key, void 0);
|
|
87907
|
+
}
|
|
87229
87908
|
}
|
|
87230
87909
|
return {
|
|
87231
87910
|
...result,
|
|
@@ -87234,7 +87913,17 @@ var SearchService = class {
|
|
|
87234
87913
|
const targetSource = sourceByKey.get(`${String(item.sourceKind)}:${sourceUid}`);
|
|
87235
87914
|
return targetSource === void 0 ? item : {
|
|
87236
87915
|
...item,
|
|
87237
|
-
targetSource
|
|
87916
|
+
targetSource,
|
|
87917
|
+
sourceTitle: targetSource.displayName
|
|
87918
|
+
};
|
|
87919
|
+
}),
|
|
87920
|
+
sourceAggregates: result.sourceAggregates.map((item) => {
|
|
87921
|
+
const targetSource = sourceByKey.get(`${String(item.sourceKind)}:${item.sourceUid}`);
|
|
87922
|
+
return targetSource === void 0 ? item : {
|
|
87923
|
+
...item,
|
|
87924
|
+
title: targetSource.displayName,
|
|
87925
|
+
targetSource,
|
|
87926
|
+
...targetSource.privateNickname ? { nickname: targetSource.privateNickname } : {}
|
|
87238
87927
|
};
|
|
87239
87928
|
})
|
|
87240
87929
|
};
|
|
@@ -87391,13 +88080,14 @@ var SearchService = class {
|
|
|
87391
88080
|
const files = listValue$3(item.file_ls).map(assetItem).filter((value) => value !== void 0);
|
|
87392
88081
|
const voice = assetItem(payload.voice);
|
|
87393
88082
|
const textContent = clippedText(core.text_content, 2e3);
|
|
87394
|
-
const
|
|
88083
|
+
const linkUrls = arkmeSearchRecordLinks(stringValue$2(core.text_content));
|
|
87395
88084
|
const sourceTitle = stringValue$2(topic.title ?? chat.title).trim();
|
|
87396
88085
|
const creationSource = Math.trunc(numberValue$2(core.creation_source ?? item.creation_source));
|
|
87397
88086
|
const recordOwnerUserId = recordOwnerId(core.owner_user_id);
|
|
87398
88087
|
return {
|
|
87399
88088
|
recordUid,
|
|
87400
88089
|
...recordOwnerUserId !== 0 ? { recordOwnerUserId } : {},
|
|
88090
|
+
...recordOwnerId(core.creator_user_id) !== 0 ? { recordCreatorUserId: recordOwnerId(core.creator_user_id) } : {},
|
|
87401
88091
|
sourceKind: Math.trunc(numberValue$2(item.source_kind)),
|
|
87402
88092
|
...stringValue$2(item.source_uid).trim() === "" ? {} : { sourceUid: stringValue$2(item.source_uid).trim() },
|
|
87403
88093
|
routeTargetKind: stringValue$2(item.route_target_kind).trim(),
|
|
@@ -87414,7 +88104,10 @@ var SearchService = class {
|
|
|
87414
88104
|
media,
|
|
87415
88105
|
files,
|
|
87416
88106
|
...voice === void 0 ? {} : { voice },
|
|
87417
|
-
...
|
|
88107
|
+
...linkUrls.length === 0 ? {} : {
|
|
88108
|
+
linkUrl: linkUrls[0],
|
|
88109
|
+
linkUrls
|
|
88110
|
+
},
|
|
87418
88111
|
...numberValue$2(core.duration_millis ?? core.record_duration_millis) <= 0 ? {} : { recordDurationMillis: numberValue$2(core.duration_millis ?? core.record_duration_millis) },
|
|
87419
88112
|
...numberValue$2(item.scene_item_count) <= 0 ? {} : { sceneItemCount: numberValue$2(item.scene_item_count) },
|
|
87420
88113
|
...numberValue$2(item.scene_item_size) <= 0 ? {} : { sceneItemSize: numberValue$2(item.scene_item_size) }
|
|
@@ -91135,7 +91828,9 @@ var ArkmeService = class {
|
|
|
91135
91828
|
userBan;
|
|
91136
91829
|
directMessageAdmissionOwner;
|
|
91137
91830
|
backgroundSoundPreferenceOwner;
|
|
91831
|
+
membershipOwner;
|
|
91138
91832
|
fileTransfers;
|
|
91833
|
+
desktopScreenshot;
|
|
91139
91834
|
localFileOpener;
|
|
91140
91835
|
worldVoiceprintInviteVariantIndex = 0;
|
|
91141
91836
|
constructor(config, sessionStore, stateStore, fetchImpl = fetch, pendingSessionStore, outgoingCallBroker = new ArkmeOutgoingCallBroker(), billingGateway, linkDocumentReader, localDshQuery) {
|
|
@@ -91257,6 +91952,11 @@ var ArkmeService = class {
|
|
|
91257
91952
|
}
|
|
91258
91953
|
});
|
|
91259
91954
|
this.backgroundSoundPreferenceOwner = new BackgroundSoundPreferenceService(this.runtime, new BackgroundSoundMembershipService(this.runtime));
|
|
91955
|
+
this.membershipOwner = new MembershipService(this.runtime);
|
|
91956
|
+
this.desktopScreenshot = new ArkmeDesktopScreenshot({
|
|
91957
|
+
currentUser: async () => (await this.runtime.requireSession()).userId,
|
|
91958
|
+
maxImageBytes: () => this.filesOwner().capabilities().maxImageBytes
|
|
91959
|
+
});
|
|
91260
91960
|
this.fileTransfers = createArkmeFileTransfers({
|
|
91261
91961
|
directory: config.fileStateDirectory,
|
|
91262
91962
|
maxUploadBytes: config.maxUploadBytes,
|
|
@@ -91277,6 +91977,13 @@ var ArkmeService = class {
|
|
|
91277
91977
|
fileCapabilities() {
|
|
91278
91978
|
return this.filesOwner().capabilities();
|
|
91279
91979
|
}
|
|
91980
|
+
async screenshotCapability() {
|
|
91981
|
+
await this.runtime.requireSession();
|
|
91982
|
+
return await this.desktopScreenshot.capability();
|
|
91983
|
+
}
|
|
91984
|
+
async captureScreenshot(expectedUserId, signal) {
|
|
91985
|
+
return await this.desktopScreenshot.capture(expectedUserId, signal);
|
|
91986
|
+
}
|
|
91280
91987
|
async fileSearch(options) {
|
|
91281
91988
|
return await this.search.searchFiles(options);
|
|
91282
91989
|
}
|
|
@@ -91331,6 +92038,12 @@ var ArkmeService = class {
|
|
|
91331
92038
|
async fileReceive(mediaRef, start = false) {
|
|
91332
92039
|
return await this.filesOwner().reception(mediaRef, start);
|
|
91333
92040
|
}
|
|
92041
|
+
async membershipCurrent(expectedUserId) {
|
|
92042
|
+
return await this.membershipOwner.current(expectedUserId);
|
|
92043
|
+
}
|
|
92044
|
+
async membershipCatalog(expectedUserId) {
|
|
92045
|
+
return await this.membershipOwner.catalog(expectedUserId);
|
|
92046
|
+
}
|
|
91334
92047
|
async backgroundSoundPreference(signal) {
|
|
91335
92048
|
return await this.backgroundSoundPreferenceOwner.preference(signal);
|
|
91336
92049
|
}
|
|
@@ -91338,6 +92051,7 @@ var ArkmeService = class {
|
|
|
91338
92051
|
return await this.backgroundSoundPreferenceOwner.update(enabled, signal, expectedUserId);
|
|
91339
92052
|
}
|
|
91340
92053
|
clearAccountState(userIds) {
|
|
92054
|
+
this.desktopScreenshot.cancel();
|
|
91341
92055
|
this.calendar.dispose();
|
|
91342
92056
|
this.directory.reset();
|
|
91343
92057
|
this.realtime.resetAttentionSummary();
|
|
@@ -91625,6 +92339,7 @@ var ArkmeService = class {
|
|
|
91625
92339
|
return await this.callHistory.retryCallSummary(callRef, signal);
|
|
91626
92340
|
}
|
|
91627
92341
|
dispose() {
|
|
92342
|
+
this.desktopScreenshot.cancel();
|
|
91628
92343
|
this.directory.reset();
|
|
91629
92344
|
this.record.dispose();
|
|
91630
92345
|
this.realtime.resetAttentionSummary();
|
|
@@ -92229,6 +92944,9 @@ var ArkmeService = class {
|
|
|
92229
92944
|
async forwardSourceMessages(sourceRef, actionRefs, options = {}) {
|
|
92230
92945
|
return await this.chat.forwardSourceMessages(sourceRef, actionRefs, options);
|
|
92231
92946
|
}
|
|
92947
|
+
async ownLongArticle(itemUid, expectedUserId, signal) {
|
|
92948
|
+
return await this.chat.ownLongArticle(itemUid, expectedUserId, signal);
|
|
92949
|
+
}
|
|
92232
92950
|
async forwardMessageActions(conversationRef, actionRefs, options) {
|
|
92233
92951
|
return await this.messageActions.forward(conversationRef, actionRefs, options);
|
|
92234
92952
|
}
|
|
@@ -92316,6 +93034,7 @@ var ArkmeService = class {
|
|
|
92316
93034
|
async publishLongArticle(sourceRef, input, signal) {
|
|
92317
93035
|
if (!/^[A-Za-z0-9._:-]{8,256}$/.test(input.recordUid) || !/^[A-Za-z0-9._:-]{8,256}$/.test(input.relationUid)) throw new ArkmePluginError("long-article-id-invalid", "长文提交标识无效", false);
|
|
92318
93036
|
const userId = (await this.runtime.requireSession()).userId;
|
|
93037
|
+
if (input.expectedUserId !== void 0 && input.expectedUserId !== userId) throw new ArkmePluginError("file-account-changed", "账号已切换", false, 403);
|
|
92319
93038
|
let previous;
|
|
92320
93039
|
try {
|
|
92321
93040
|
previous = await this.chat.longArticleDetail(sourceRef, input.recordUid, signal);
|
|
@@ -92381,8 +93100,8 @@ var ArkmeService = class {
|
|
|
92381
93100
|
async putLongArticleDraft(draft) {
|
|
92382
93101
|
return await this.chat.putLongArticleDraft(draft);
|
|
92383
93102
|
}
|
|
92384
|
-
async removeLongArticleDraft(sourceRef, itemUid) {
|
|
92385
|
-
return await this.chat.removeLongArticleDraft(sourceRef, itemUid);
|
|
93103
|
+
async removeLongArticleDraft(sourceRef, itemUid, expectedRecordUid) {
|
|
93104
|
+
return await this.chat.removeLongArticleDraft(sourceRef, itemUid, expectedRecordUid);
|
|
92386
93105
|
}
|
|
92387
93106
|
async prepareRecordReedit(input, options = {}) {
|
|
92388
93107
|
return await this.record.prepareRecordReedit(input, options);
|
|
@@ -92505,6 +93224,9 @@ var ArkmeService = class {
|
|
|
92505
93224
|
async searchRemote(options) {
|
|
92506
93225
|
return await this.search.searchRemote(options);
|
|
92507
93226
|
}
|
|
93227
|
+
async searchConversationNames(options) {
|
|
93228
|
+
return await this.source.searchConversationNames(options);
|
|
93229
|
+
}
|
|
92508
93230
|
async searchTagRecords(options) {
|
|
92509
93231
|
return await this.search.searchTagRecords(options);
|
|
92510
93232
|
}
|