@lobehub/chat 1.81.3 → 1.81.5
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/.eslintrc.js +1 -0
- package/.github/workflows/release.yml +5 -0
- package/.github/workflows/test.yml +5 -0
- package/CHANGELOG.md +58 -0
- package/changelog/v1.json +21 -0
- package/locales/ar/common.json +2 -0
- package/locales/ar/electron.json +32 -0
- package/locales/ar/models.json +129 -3
- package/locales/ar/plugin.json +1 -0
- package/locales/ar/tool.json +25 -0
- package/locales/bg-BG/common.json +2 -0
- package/locales/bg-BG/electron.json +32 -0
- package/locales/bg-BG/models.json +129 -3
- package/locales/bg-BG/plugin.json +1 -0
- package/locales/bg-BG/tool.json +25 -0
- package/locales/de-DE/common.json +2 -0
- package/locales/de-DE/electron.json +32 -0
- package/locales/de-DE/models.json +129 -3
- package/locales/de-DE/plugin.json +1 -0
- package/locales/de-DE/tool.json +25 -0
- package/locales/en-US/common.json +2 -0
- package/locales/en-US/electron.json +32 -0
- package/locales/en-US/models.json +129 -3
- package/locales/en-US/plugin.json +1 -0
- package/locales/en-US/tool.json +25 -0
- package/locales/es-ES/common.json +2 -0
- package/locales/es-ES/electron.json +32 -0
- package/locales/es-ES/models.json +129 -3
- package/locales/es-ES/plugin.json +1 -0
- package/locales/es-ES/tool.json +25 -0
- package/locales/fa-IR/common.json +2 -0
- package/locales/fa-IR/electron.json +32 -0
- package/locales/fa-IR/models.json +129 -3
- package/locales/fa-IR/plugin.json +1 -0
- package/locales/fa-IR/tool.json +25 -0
- package/locales/fr-FR/common.json +2 -0
- package/locales/fr-FR/electron.json +32 -0
- package/locales/fr-FR/models.json +129 -3
- package/locales/fr-FR/plugin.json +1 -0
- package/locales/fr-FR/tool.json +25 -0
- package/locales/it-IT/common.json +2 -0
- package/locales/it-IT/electron.json +32 -0
- package/locales/it-IT/models.json +129 -3
- package/locales/it-IT/plugin.json +1 -0
- package/locales/it-IT/tool.json +25 -0
- package/locales/ja-JP/common.json +2 -0
- package/locales/ja-JP/electron.json +32 -0
- package/locales/ja-JP/models.json +129 -3
- package/locales/ja-JP/plugin.json +1 -0
- package/locales/ja-JP/tool.json +25 -0
- package/locales/ko-KR/common.json +2 -0
- package/locales/ko-KR/electron.json +32 -0
- package/locales/ko-KR/models.json +129 -3
- package/locales/ko-KR/plugin.json +1 -0
- package/locales/ko-KR/tool.json +25 -0
- package/locales/nl-NL/common.json +2 -0
- package/locales/nl-NL/electron.json +32 -0
- package/locales/nl-NL/models.json +129 -3
- package/locales/nl-NL/plugin.json +1 -0
- package/locales/nl-NL/tool.json +25 -0
- package/locales/pl-PL/common.json +2 -0
- package/locales/pl-PL/electron.json +32 -0
- package/locales/pl-PL/models.json +129 -3
- package/locales/pl-PL/plugin.json +1 -0
- package/locales/pl-PL/tool.json +25 -0
- package/locales/pt-BR/common.json +2 -0
- package/locales/pt-BR/electron.json +32 -0
- package/locales/pt-BR/models.json +129 -3
- package/locales/pt-BR/plugin.json +1 -0
- package/locales/pt-BR/tool.json +25 -0
- package/locales/ru-RU/common.json +2 -0
- package/locales/ru-RU/electron.json +32 -0
- package/locales/ru-RU/models.json +129 -3
- package/locales/ru-RU/plugin.json +1 -0
- package/locales/ru-RU/tool.json +25 -0
- package/locales/tr-TR/common.json +2 -0
- package/locales/tr-TR/electron.json +32 -0
- package/locales/tr-TR/models.json +129 -3
- package/locales/tr-TR/plugin.json +1 -0
- package/locales/tr-TR/tool.json +25 -0
- package/locales/vi-VN/common.json +2 -0
- package/locales/vi-VN/electron.json +32 -0
- package/locales/vi-VN/models.json +129 -3
- package/locales/vi-VN/plugin.json +1 -0
- package/locales/vi-VN/tool.json +25 -0
- package/locales/zh-CN/common.json +2 -0
- package/locales/zh-CN/electron.json +32 -0
- package/locales/zh-CN/models.json +134 -8
- package/locales/zh-CN/plugin.json +1 -0
- package/locales/zh-CN/tool.json +25 -0
- package/locales/zh-TW/common.json +2 -0
- package/locales/zh-TW/electron.json +32 -0
- package/locales/zh-TW/models.json +129 -3
- package/locales/zh-TW/plugin.json +1 -0
- package/locales/zh-TW/tool.json +25 -0
- package/package.json +4 -3
- package/packages/electron-client-ipc/src/events/index.ts +5 -5
- package/packages/electron-client-ipc/src/events/localFile.ts +22 -0
- package/packages/electron-client-ipc/src/events/{file.ts → upload.ts} +1 -1
- package/packages/electron-client-ipc/src/types/index.ts +2 -1
- package/packages/electron-client-ipc/src/types/localFile.ts +52 -0
- package/packages/file-loaders/README.md +63 -0
- package/packages/file-loaders/package.json +42 -0
- package/packages/file-loaders/src/index.ts +2 -0
- package/packages/file-loaders/src/loadFile.ts +206 -0
- package/packages/file-loaders/src/loaders/docx/__snapshots__/index.test.ts.snap +74 -0
- package/packages/file-loaders/src/loaders/docx/fixtures/test.docx +0 -0
- package/packages/file-loaders/src/loaders/docx/index.test.ts +41 -0
- package/packages/file-loaders/src/loaders/docx/index.ts +73 -0
- package/packages/file-loaders/src/loaders/excel/__snapshots__/index.test.ts.snap +58 -0
- package/packages/file-loaders/src/loaders/excel/fixtures/test.xlsx +0 -0
- package/packages/file-loaders/src/loaders/excel/index.test.ts +47 -0
- package/packages/file-loaders/src/loaders/excel/index.ts +121 -0
- package/packages/file-loaders/src/loaders/index.ts +19 -0
- package/packages/file-loaders/src/loaders/pdf/__snapshots__/index.test.ts.snap +98 -0
- package/packages/file-loaders/src/loaders/pdf/index.test.ts +49 -0
- package/packages/file-loaders/src/loaders/pdf/index.ts +133 -0
- package/packages/file-loaders/src/loaders/pptx/__snapshots__/index.test.ts.snap +40 -0
- package/packages/file-loaders/src/loaders/pptx/fixtures/test.pptx +0 -0
- package/packages/file-loaders/src/loaders/pptx/index.test.ts +47 -0
- package/packages/file-loaders/src/loaders/pptx/index.ts +186 -0
- package/packages/file-loaders/src/loaders/text/__snapshots__/index.test.ts.snap +15 -0
- package/packages/file-loaders/src/loaders/text/fixtures/test.txt +2 -0
- package/packages/file-loaders/src/loaders/text/index.test.ts +38 -0
- package/packages/file-loaders/src/loaders/text/index.ts +53 -0
- package/packages/file-loaders/src/types.ts +200 -0
- package/packages/file-loaders/src/utils/isTextReadableFile.ts +68 -0
- package/packages/file-loaders/src/utils/parser-utils.ts +112 -0
- package/packages/file-loaders/test/__snapshots__/loaders.test.ts.snap +93 -0
- package/packages/file-loaders/test/fixtures/test.csv +4 -0
- package/packages/file-loaders/test/fixtures/test.docx +0 -0
- package/packages/file-loaders/test/fixtures/test.epub +0 -0
- package/packages/file-loaders/test/fixtures/test.md +3 -0
- package/packages/file-loaders/test/fixtures/test.pptx +0 -0
- package/packages/file-loaders/test/fixtures/test.txt +3 -0
- package/packages/file-loaders/test/loaders.test.ts +39 -0
- package/scripts/prebuild.mts +5 -1
- package/src/app/(backend)/trpc/desktop/[trpc]/route.ts +26 -0
- package/src/features/Conversation/Messages/Assistant/Tool/Render/Arguments/ObjectEntity.tsx +81 -0
- package/src/features/Conversation/Messages/Assistant/Tool/Render/Arguments/ValueCell.tsx +43 -0
- package/src/features/Conversation/Messages/Assistant/Tool/Render/Arguments/index.tsx +120 -0
- package/src/features/Conversation/Messages/Assistant/Tool/Render/CustomRender.tsx +75 -2
- package/src/features/Conversation/Messages/Assistant/Tool/Render/KeyValueEditor.tsx +214 -0
- package/src/features/User/UserPanel/useMenu.tsx +8 -1
- package/src/libs/agent-runtime/google/index.ts +3 -0
- package/src/libs/trpc/client/desktop.ts +14 -0
- package/src/locales/default/common.ts +2 -0
- package/src/locales/default/electron.ts +34 -0
- package/src/locales/default/index.ts +2 -0
- package/src/locales/default/tool.ts +25 -0
- package/src/server/routers/desktop/index.ts +9 -0
- package/src/server/routers/desktop/pgTable.ts +43 -0
- package/src/services/electron/autoUpdate.ts +17 -0
- package/src/services/electron/file.ts +31 -0
- package/src/services/electron/localFileService.ts +39 -0
- package/src/services/electron/remoteServer.ts +40 -0
- package/src/store/chat/index.ts +1 -1
- package/src/store/chat/slices/builtinTool/actions/index.ts +3 -1
- package/src/store/chat/slices/builtinTool/actions/localFile.ts +129 -0
- package/src/store/chat/slices/builtinTool/initialState.ts +2 -0
- package/src/store/chat/slices/builtinTool/selectors.ts +2 -0
- package/src/store/chat/slices/plugin/action.ts +3 -3
- package/src/store/chat/store.ts +2 -0
- package/src/store/electron/actions/sync.ts +117 -0
- package/src/store/electron/index.ts +1 -0
- package/src/store/electron/initialState.ts +18 -0
- package/src/store/electron/selectors/index.ts +1 -0
- package/src/store/electron/selectors/sync.ts +9 -0
- package/src/store/electron/store.ts +29 -0
- package/src/tools/index.ts +8 -0
- package/src/tools/local-files/Render/ListFiles/Result.tsx +42 -0
- package/src/tools/local-files/Render/ListFiles/index.tsx +68 -0
- package/src/tools/local-files/Render/ReadLocalFile/ReadFileSkeleton.tsx +50 -0
- package/src/tools/local-files/Render/ReadLocalFile/ReadFileView.tsx +197 -0
- package/src/tools/local-files/Render/ReadLocalFile/index.tsx +31 -0
- package/src/tools/local-files/Render/ReadLocalFile/style.ts +37 -0
- package/src/tools/local-files/Render/SearchFiles/Result.tsx +42 -0
- package/src/tools/local-files/Render/SearchFiles/SearchQuery/SearchView.tsx +77 -0
- package/src/tools/local-files/Render/SearchFiles/SearchQuery/index.tsx +72 -0
- package/src/tools/local-files/Render/SearchFiles/index.tsx +32 -0
- package/src/tools/local-files/Render/index.tsx +36 -0
- package/src/tools/local-files/components/FileItem.tsx +117 -0
- package/src/tools/local-files/index.ts +149 -0
- package/src/tools/local-files/systemRole.ts +46 -0
- package/src/tools/local-files/type.ts +33 -0
- package/src/tools/renders.ts +3 -0
- package/packages/electron-client-ipc/src/events/search.ts +0 -4
- package/src/features/Conversation/Messages/Assistant/Tool/Render/Arguments.tsx +0 -165
- /package/packages/electron-client-ipc/src/types/{file.ts → upload.ts} +0 -0
@@ -0,0 +1,200 @@
|
|
1
|
+
// Define supported file types - consider using an enum or const assertion
|
2
|
+
export type SupportedFileType = 'pdf' | 'docx' | 'txt' | 'excel' | 'pptx'; // | 'pptx' | 'latex' | 'epub' | 'code' | 'markdown';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* 代表一个完整的已加载文件,包含文件级信息和其所有页面/块。
|
6
|
+
*/
|
7
|
+
export interface FileDocument {
|
8
|
+
/**
|
9
|
+
* 文件内容
|
10
|
+
*/
|
11
|
+
content: string;
|
12
|
+
|
13
|
+
/**
|
14
|
+
* 文件创建时间戳。
|
15
|
+
*/
|
16
|
+
createdTime: Date;
|
17
|
+
|
18
|
+
/**
|
19
|
+
* 文件类型或扩展名。
|
20
|
+
*/
|
21
|
+
fileType: string;
|
22
|
+
|
23
|
+
/**
|
24
|
+
* 原始文件名。
|
25
|
+
*/
|
26
|
+
filename: string;
|
27
|
+
|
28
|
+
/**
|
29
|
+
* 文件级别的元数据。
|
30
|
+
* 例如从文件属性中提取的标题、作者,或整个文件加载失败时的错误。
|
31
|
+
*/
|
32
|
+
metadata: {
|
33
|
+
/**
|
34
|
+
* 允许添加其他文件级别的元数据。
|
35
|
+
*/
|
36
|
+
[key: string]: any;
|
37
|
+
/**
|
38
|
+
* 文档作者 (如果可用)。
|
39
|
+
*/
|
40
|
+
author?: string;
|
41
|
+
/**
|
42
|
+
* 如果整个文件加载失败,记录错误信息。
|
43
|
+
*/
|
44
|
+
error?: string;
|
45
|
+
/**
|
46
|
+
* 文档标题 (如果可用)。
|
47
|
+
*/
|
48
|
+
title?: string;
|
49
|
+
};
|
50
|
+
|
51
|
+
/**
|
52
|
+
* 文件最后修改时间戳。
|
53
|
+
*/
|
54
|
+
modifiedTime: Date;
|
55
|
+
|
56
|
+
/**
|
57
|
+
* 包含文档中所有逻辑页面/块的数组。
|
58
|
+
* 顺序通常对应文件中的自然顺序。
|
59
|
+
*/
|
60
|
+
pages?: DocumentPage[];
|
61
|
+
|
62
|
+
/**
|
63
|
+
* 原始文件的完整路径。
|
64
|
+
*/
|
65
|
+
source: string;
|
66
|
+
|
67
|
+
/**
|
68
|
+
* 整个文档的总字符数 (所有 Page 的 charCount 之和)。
|
69
|
+
* 需要在所有 Page 加载和计算后得出。
|
70
|
+
*/
|
71
|
+
totalCharCount: number;
|
72
|
+
|
73
|
+
/**
|
74
|
+
* 整个文档的总行数 (所有 Page 的 lineCount 之和)。
|
75
|
+
* 需要在所有 Page 加载和计算后得出。
|
76
|
+
*/
|
77
|
+
totalLineCount: number;
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* 代表文件中的一个逻辑单元/页面/块。
|
82
|
+
*/
|
83
|
+
export interface DocumentPage {
|
84
|
+
/**
|
85
|
+
* 此页/块内容的字符数。
|
86
|
+
*/
|
87
|
+
charCount: number;
|
88
|
+
|
89
|
+
/**
|
90
|
+
* 此页/块内容的行数。
|
91
|
+
*/
|
92
|
+
lineCount: number;
|
93
|
+
|
94
|
+
/**
|
95
|
+
* 与此页/块相关的元数据。
|
96
|
+
*/
|
97
|
+
metadata: {
|
98
|
+
/**
|
99
|
+
* 允许添加其他特定于页/块的元数据。
|
100
|
+
*/
|
101
|
+
[key: string]: any;
|
102
|
+
|
103
|
+
/**
|
104
|
+
* 如果原始文件单元被进一步分割成块,这是当前块的索引。
|
105
|
+
*/
|
106
|
+
chunkIndex?: number;
|
107
|
+
|
108
|
+
/**
|
109
|
+
* 处理此页/块时发生的错误。
|
110
|
+
*/
|
111
|
+
error?: string;
|
112
|
+
|
113
|
+
/**
|
114
|
+
* 此页/块在原始文件中的结束行号。
|
115
|
+
*/
|
116
|
+
lineNumberEnd?: number;
|
117
|
+
|
118
|
+
/**
|
119
|
+
* 此页/块在原始文件中的起始行号。
|
120
|
+
*/
|
121
|
+
lineNumberStart?: number;
|
122
|
+
|
123
|
+
/**
|
124
|
+
* 页码 (适用于 PDF, DOCX)。
|
125
|
+
*/
|
126
|
+
pageNumber?: number;
|
127
|
+
|
128
|
+
/**
|
129
|
+
* 与此页/块相关的章节标题。
|
130
|
+
*/
|
131
|
+
sectionTitle?: string;
|
132
|
+
|
133
|
+
/**
|
134
|
+
* 工作表名称 (适用于 XLSX)。
|
135
|
+
*/
|
136
|
+
sheetName?: string;
|
137
|
+
|
138
|
+
/**
|
139
|
+
* 幻灯片编号 (适用于 PPTX)。
|
140
|
+
*/
|
141
|
+
slideNumber?: number;
|
142
|
+
|
143
|
+
/**
|
144
|
+
* 如果原始文件单元被进一步分割成块,这是该单元的总块数。
|
145
|
+
*/
|
146
|
+
totalChunks?: number;
|
147
|
+
};
|
148
|
+
|
149
|
+
/**
|
150
|
+
* 此页/块的核心文本内容。
|
151
|
+
*/
|
152
|
+
pageContent: string;
|
153
|
+
}
|
154
|
+
|
155
|
+
/**
|
156
|
+
* 可选的文件元数据,用于覆盖从文件系统读取的信息。
|
157
|
+
*/
|
158
|
+
export interface FileMetadata {
|
159
|
+
/**
|
160
|
+
* 文件创建时间戳。
|
161
|
+
*/
|
162
|
+
createdTime?: Date;
|
163
|
+
/**
|
164
|
+
* 文件类型或扩展名。
|
165
|
+
*/
|
166
|
+
fileType?: string;
|
167
|
+
/**
|
168
|
+
* 文件名。
|
169
|
+
*/
|
170
|
+
filename?: string;
|
171
|
+
/**
|
172
|
+
* 文件最后修改时间戳。
|
173
|
+
*/
|
174
|
+
modifiedTime?: Date;
|
175
|
+
/**
|
176
|
+
* 文件来源标识 (例如 S3 URL 或原始路径)。
|
177
|
+
*/
|
178
|
+
source?: string;
|
179
|
+
}
|
180
|
+
|
181
|
+
/**
|
182
|
+
* 定义所有文件加载器类必须实现的接口。
|
183
|
+
*/
|
184
|
+
export interface FileLoaderInterface {
|
185
|
+
/**
|
186
|
+
* 将从 loadPages 获取的页面内容聚合成单一的字符串。
|
187
|
+
* @param pages DocumentPage 对象的数组。
|
188
|
+
* @returns 返回聚合后的文本内容的 Promise。
|
189
|
+
*/
|
190
|
+
aggregateContent(pages: DocumentPage[]): Promise<string>;
|
191
|
+
|
192
|
+
attachDocumentMetadata?(filePath: string): Promise<Record<string, any>>;
|
193
|
+
|
194
|
+
/**
|
195
|
+
* 根据文件路径加载文件内容,并将其分割为逻辑页面/块。
|
196
|
+
* @param filePath 文件的完整路径。
|
197
|
+
* @returns 返回包含 DocumentPage 对象的数组的 Promise。
|
198
|
+
*/
|
199
|
+
loadPages(filePath: string): Promise<DocumentPage[]>;
|
200
|
+
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
export const TEXT_READABLE_FILE_TYPES = [
|
2
|
+
// Plain Text & Markup
|
3
|
+
'txt',
|
4
|
+
'md',
|
5
|
+
'markdown',
|
6
|
+
'mdx',
|
7
|
+
|
8
|
+
// Configuration & Data
|
9
|
+
'json',
|
10
|
+
'xml',
|
11
|
+
'yaml',
|
12
|
+
'yml',
|
13
|
+
'toml',
|
14
|
+
'ini',
|
15
|
+
'cfg',
|
16
|
+
'conf',
|
17
|
+
'csv',
|
18
|
+
|
19
|
+
// Web Development
|
20
|
+
'html',
|
21
|
+
'htm',
|
22
|
+
'css',
|
23
|
+
'scss',
|
24
|
+
'less',
|
25
|
+
'js',
|
26
|
+
'jsx',
|
27
|
+
'ts',
|
28
|
+
'tsx',
|
29
|
+
'mjs',
|
30
|
+
'vue',
|
31
|
+
'svelte',
|
32
|
+
'svg',
|
33
|
+
|
34
|
+
// Scripting & Programming
|
35
|
+
'php',
|
36
|
+
'py',
|
37
|
+
'rb',
|
38
|
+
'java',
|
39
|
+
'c',
|
40
|
+
'cpp',
|
41
|
+
'h',
|
42
|
+
'hpp',
|
43
|
+
'cs',
|
44
|
+
'go',
|
45
|
+
'rs',
|
46
|
+
'swift',
|
47
|
+
'kt',
|
48
|
+
'sh',
|
49
|
+
'bash',
|
50
|
+
'bat',
|
51
|
+
'ps1',
|
52
|
+
|
53
|
+
// Other
|
54
|
+
'log',
|
55
|
+
'sql',
|
56
|
+
'patch',
|
57
|
+
'diff',
|
58
|
+
'db', // Often text-based, like SQLite journals
|
59
|
+
];
|
60
|
+
|
61
|
+
/**
|
62
|
+
* Determine if a file can be read as text based on its extension.
|
63
|
+
* @param fileType File extension (without the leading dot)
|
64
|
+
* @returns Whether the file is likely text-readable
|
65
|
+
*/
|
66
|
+
export function isTextReadableFile(fileType: string): boolean {
|
67
|
+
return TEXT_READABLE_FILE_TYPES.includes(fileType.toLowerCase());
|
68
|
+
}
|
@@ -0,0 +1,112 @@
|
|
1
|
+
import { DOMParser } from '@xmldom/xmldom';
|
2
|
+
import concat from 'concat-stream';
|
3
|
+
import { Buffer } from 'node:buffer';
|
4
|
+
import yauzl from 'yauzl';
|
5
|
+
|
6
|
+
// Define basic error messages
|
7
|
+
const ERRORMSG = {
|
8
|
+
fileCorrupted: (filepath: string | Buffer) =>
|
9
|
+
`[OfficeParser]: Your file ${typeof filepath === 'string' ? filepath : 'Buffer'} seems to be corrupted. If you are sure it is fine, please create a ticket.`,
|
10
|
+
invalidInput: `[OfficeParser]: Invalid input type: Expected a Buffer or a valid file path`,
|
11
|
+
};
|
12
|
+
|
13
|
+
/** Returns parsed xml document for a given xml text.
|
14
|
+
* @param {string} xml The xml string from the doc file
|
15
|
+
* @returns {XMLDocument}
|
16
|
+
*/
|
17
|
+
export const parseString = (xml: string) => {
|
18
|
+
const parser = new DOMParser();
|
19
|
+
return parser.parseFromString(xml, 'text/xml') as unknown as XMLDocument;
|
20
|
+
};
|
21
|
+
|
22
|
+
export interface ExtractedFile {
|
23
|
+
content: string;
|
24
|
+
path: string;
|
25
|
+
}
|
26
|
+
|
27
|
+
/** Extract specific files from either a ZIP file buffer or file path based on a filter function.
|
28
|
+
* @param {Buffer|string} zipInput ZIP file input, either a Buffer or a file path (string).
|
29
|
+
* @param {(fileName: string) => boolean} filterFn A function that receives the entry file name and returns true if the file should be extracted.
|
30
|
+
* @returns {Promise<ExtractedFile[]>} Resolves to an array of object containing file path and content.
|
31
|
+
*/
|
32
|
+
export function extractFiles(
|
33
|
+
zipInput: Buffer | string,
|
34
|
+
filterFn: (fileName: string) => boolean,
|
35
|
+
): Promise<ExtractedFile[]> {
|
36
|
+
return new Promise((resolve, reject) => {
|
37
|
+
/** Processes zip file and resolves with the path of file and their content.
|
38
|
+
* @param {yauzl.ZipFile} zipfile
|
39
|
+
*/
|
40
|
+
const processZipfile = (zipfile: yauzl.ZipFile) => {
|
41
|
+
const extractedFiles: ExtractedFile[] = [];
|
42
|
+
zipfile.readEntry(); // Start reading entries
|
43
|
+
|
44
|
+
zipfile.on('entry', (entry: yauzl.Entry) => {
|
45
|
+
// Directory entries end with a forward slash
|
46
|
+
if (entry.fileName.endsWith('/')) {
|
47
|
+
zipfile.readEntry(); // Skip directories
|
48
|
+
return;
|
49
|
+
}
|
50
|
+
|
51
|
+
// Use the filter function to determine if the file should be extracted
|
52
|
+
if (filterFn(entry.fileName)) {
|
53
|
+
zipfile.openReadStream(entry, (err, readStream) => {
|
54
|
+
if (err) {
|
55
|
+
zipfile.close(); // Ensure zipfile is closed on error
|
56
|
+
return reject(err);
|
57
|
+
}
|
58
|
+
if (!readStream) {
|
59
|
+
zipfile.close();
|
60
|
+
return reject(new Error(`Could not open read stream for ${entry.fileName}`));
|
61
|
+
}
|
62
|
+
|
63
|
+
// Use concat-stream to collect the data into a single Buffer
|
64
|
+
readStream.pipe(
|
65
|
+
concat((data) => {
|
66
|
+
extractedFiles.push({
|
67
|
+
content: data.toString('utf8'),
|
68
|
+
path: entry.fileName, // Specify encoding
|
69
|
+
});
|
70
|
+
zipfile.readEntry(); // Continue reading entries
|
71
|
+
}),
|
72
|
+
);
|
73
|
+
readStream.on('error', (streamErr) => {
|
74
|
+
zipfile.close();
|
75
|
+
reject(streamErr);
|
76
|
+
});
|
77
|
+
});
|
78
|
+
} else {
|
79
|
+
zipfile.readEntry(); // Skip entries that don't match the filter
|
80
|
+
}
|
81
|
+
});
|
82
|
+
|
83
|
+
zipfile.on('end', () => {
|
84
|
+
resolve(extractedFiles);
|
85
|
+
zipfile.close(); // Close the zipfile when done reading entries
|
86
|
+
});
|
87
|
+
|
88
|
+
zipfile.on('error', (err) => {
|
89
|
+
zipfile.close();
|
90
|
+
reject(err);
|
91
|
+
});
|
92
|
+
};
|
93
|
+
|
94
|
+
// Determine whether the input is a buffer or file path
|
95
|
+
if (Buffer.isBuffer(zipInput)) {
|
96
|
+
// Process ZIP from Buffer
|
97
|
+
yauzl.fromBuffer(zipInput, { lazyEntries: true }, (err, zipfile) => {
|
98
|
+
if (err || !zipfile) return reject(err || new Error('Failed to open zip from buffer'));
|
99
|
+
processZipfile(zipfile);
|
100
|
+
});
|
101
|
+
} else if (typeof zipInput === 'string') {
|
102
|
+
// Process ZIP from File Path
|
103
|
+
yauzl.open(zipInput, { lazyEntries: true }, (err, zipfile) => {
|
104
|
+
if (err || !zipfile)
|
105
|
+
return reject(err || new Error(`Failed to open zip file: ${zipInput}`));
|
106
|
+
processZipfile(zipfile);
|
107
|
+
});
|
108
|
+
} else {
|
109
|
+
reject(new Error(ERRORMSG.invalidInput));
|
110
|
+
}
|
111
|
+
});
|
112
|
+
}
|
@@ -0,0 +1,93 @@
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
2
|
+
|
3
|
+
exports[`loadFile Integration Tests > Text Handling (.txt, .csv, .md, etc.) > should load content from a test.csv file using filePath 1`] = `
|
4
|
+
{
|
5
|
+
"content": "ID,Name,Value
|
6
|
+
1,Alpha,100
|
7
|
+
2,Beta,200
|
8
|
+
3,Gamma,300
|
9
|
+
",
|
10
|
+
"fileType": "csv",
|
11
|
+
"filename": "test.csv",
|
12
|
+
"metadata": {
|
13
|
+
"loaderSpecific": undefined,
|
14
|
+
},
|
15
|
+
"pages": [
|
16
|
+
{
|
17
|
+
"charCount": 49,
|
18
|
+
"lineCount": 5,
|
19
|
+
"metadata": {
|
20
|
+
"lineNumberEnd": 5,
|
21
|
+
"lineNumberStart": 1,
|
22
|
+
},
|
23
|
+
"pageContent": "ID,Name,Value
|
24
|
+
1,Alpha,100
|
25
|
+
2,Beta,200
|
26
|
+
3,Gamma,300
|
27
|
+
",
|
28
|
+
},
|
29
|
+
],
|
30
|
+
"totalCharCount": 49,
|
31
|
+
"totalLineCount": 5,
|
32
|
+
}
|
33
|
+
`;
|
34
|
+
|
35
|
+
exports[`loadFile Integration Tests > Text Handling (.txt, .csv, .md, etc.) > should load content from a test.md file using filePath 1`] = `
|
36
|
+
{
|
37
|
+
"content": "# Markdown Test
|
38
|
+
|
39
|
+
This is a test.
|
40
|
+
",
|
41
|
+
"fileType": "md",
|
42
|
+
"filename": "test.md",
|
43
|
+
"metadata": {
|
44
|
+
"loaderSpecific": undefined,
|
45
|
+
},
|
46
|
+
"pages": [
|
47
|
+
{
|
48
|
+
"charCount": 33,
|
49
|
+
"lineCount": 4,
|
50
|
+
"metadata": {
|
51
|
+
"lineNumberEnd": 4,
|
52
|
+
"lineNumberStart": 1,
|
53
|
+
},
|
54
|
+
"pageContent": "# Markdown Test
|
55
|
+
|
56
|
+
This is a test.
|
57
|
+
",
|
58
|
+
},
|
59
|
+
],
|
60
|
+
"totalCharCount": 33,
|
61
|
+
"totalLineCount": 4,
|
62
|
+
}
|
63
|
+
`;
|
64
|
+
|
65
|
+
exports[`loadFile Integration Tests > Text Handling (.txt, .csv, .md, etc.) > should load content from a test.txt file using filePath 1`] = `
|
66
|
+
{
|
67
|
+
"content": "This is line 1.
|
68
|
+
This is line 2.
|
69
|
+
End of text file.
|
70
|
+
",
|
71
|
+
"fileType": "txt",
|
72
|
+
"filename": "test.txt",
|
73
|
+
"metadata": {
|
74
|
+
"loaderSpecific": undefined,
|
75
|
+
},
|
76
|
+
"pages": [
|
77
|
+
{
|
78
|
+
"charCount": 50,
|
79
|
+
"lineCount": 4,
|
80
|
+
"metadata": {
|
81
|
+
"lineNumberEnd": 4,
|
82
|
+
"lineNumberStart": 1,
|
83
|
+
},
|
84
|
+
"pageContent": "This is line 1.
|
85
|
+
This is line 2.
|
86
|
+
End of text file.
|
87
|
+
",
|
88
|
+
},
|
89
|
+
],
|
90
|
+
"totalCharCount": 50,
|
91
|
+
"totalLineCount": 4,
|
92
|
+
}
|
93
|
+
`;
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,39 @@
|
|
1
|
+
// @vitest-environment node
|
2
|
+
import fs from 'node:fs';
|
3
|
+
import path from 'node:path';
|
4
|
+
import { describe, expect, it } from 'vitest';
|
5
|
+
|
6
|
+
import { loadFile } from '../src';
|
7
|
+
|
8
|
+
const getFixturePath = (filename: string) => path.join(__dirname, 'fixtures', filename);
|
9
|
+
|
10
|
+
const TEXT_FILES = ['test.txt', 'test.csv', 'test.md'];
|
11
|
+
|
12
|
+
describe('loadFile Integration Tests', () => {
|
13
|
+
describe('Text Handling (.txt, .csv, .md, etc.)', () => {
|
14
|
+
const testPureTextFile = (fileName: string) => {
|
15
|
+
it(`should load content from a ${fileName} file using filePath`, async () => {
|
16
|
+
const filePath = getFixturePath(fileName);
|
17
|
+
const expectedContent = fs.readFileSync(filePath, 'utf-8');
|
18
|
+
|
19
|
+
// Pass filePath directly to loadFile
|
20
|
+
const docs = await loadFile(filePath);
|
21
|
+
|
22
|
+
expect(docs.content).toEqual(expectedContent);
|
23
|
+
expect(docs.source).toEqual(filePath);
|
24
|
+
|
25
|
+
// @ts-expect-error
|
26
|
+
delete docs.source;
|
27
|
+
// @ts-expect-error
|
28
|
+
delete docs.createdTime;
|
29
|
+
// @ts-expect-error
|
30
|
+
delete docs.modifiedTime;
|
31
|
+
expect(docs).toMatchSnapshot();
|
32
|
+
});
|
33
|
+
};
|
34
|
+
|
35
|
+
TEXT_FILES.forEach((file) => {
|
36
|
+
testPureTextFile(file);
|
37
|
+
});
|
38
|
+
});
|
39
|
+
});
|
package/scripts/prebuild.mts
CHANGED
@@ -25,12 +25,16 @@ const partialBuildPages = [
|
|
25
25
|
disabled: isDesktop,
|
26
26
|
paths: ['src/app/[variants]/(main)/(mobile)'],
|
27
27
|
},
|
28
|
+
{
|
29
|
+
name: 'oauth',
|
30
|
+
disabled: isDesktop,
|
31
|
+
paths: ['src/app/[variants]/oauth', 'src/app/(backend)/oidc'],
|
32
|
+
},
|
28
33
|
{
|
29
34
|
name: 'api-webhooks',
|
30
35
|
disabled: isDesktop,
|
31
36
|
paths: ['src/app/(backend)/api/webhooks'],
|
32
37
|
},
|
33
|
-
|
34
38
|
// no need for web
|
35
39
|
{
|
36
40
|
name: 'desktop-devtools',
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
|
2
|
+
import type { NextRequest } from 'next/server';
|
3
|
+
|
4
|
+
import { pino } from '@/libs/logger';
|
5
|
+
import { createLambdaContext } from '@/libs/trpc/lambda/context';
|
6
|
+
import { desktopRouter } from '@/server/routers/desktop';
|
7
|
+
|
8
|
+
const handler = (req: NextRequest) =>
|
9
|
+
fetchRequestHandler({
|
10
|
+
/**
|
11
|
+
* @link https://trpc.io/docs/v11/context
|
12
|
+
*/
|
13
|
+
createContext: () => createLambdaContext(req),
|
14
|
+
|
15
|
+
endpoint: '/trpc/desktop',
|
16
|
+
|
17
|
+
onError: ({ error, path, type }) => {
|
18
|
+
pino.info(`Error in tRPC handler (tools) on path: ${path}, type: ${type}`);
|
19
|
+
console.error(error);
|
20
|
+
},
|
21
|
+
|
22
|
+
req,
|
23
|
+
router: desktopRouter,
|
24
|
+
});
|
25
|
+
|
26
|
+
export { handler as GET, handler as POST };
|
@@ -0,0 +1,81 @@
|
|
1
|
+
import { createStyles } from 'antd-style';
|
2
|
+
import { memo } from 'react';
|
3
|
+
|
4
|
+
import { useIsMobile } from '@/hooks/useIsMobile';
|
5
|
+
import { shinyTextStylish } from '@/styles/loading';
|
6
|
+
|
7
|
+
import ValueCell from './ValueCell';
|
8
|
+
|
9
|
+
const useStyles = createStyles(({ css, token }) => ({
|
10
|
+
arrayRow: css`
|
11
|
+
&:not(:first-child) {
|
12
|
+
border-block-start: 1px dotted ${token.colorBorderSecondary};
|
13
|
+
}
|
14
|
+
`,
|
15
|
+
colon: css`
|
16
|
+
color: ${token.colorTextTertiary};
|
17
|
+
`,
|
18
|
+
key: css`
|
19
|
+
color: ${token.colorTextTertiary};
|
20
|
+
`,
|
21
|
+
row: css`
|
22
|
+
display: flex;
|
23
|
+
align-items: baseline;
|
24
|
+
|
25
|
+
&:not(:first-child) {
|
26
|
+
border-block-start: 1px dotted ${token.colorBorderSecondary};
|
27
|
+
}
|
28
|
+
`,
|
29
|
+
shineText: shinyTextStylish(token),
|
30
|
+
value: css`
|
31
|
+
color: ${token.colorTextSecondary};
|
32
|
+
`,
|
33
|
+
}));
|
34
|
+
|
35
|
+
const formatValue = (value: any): string | string[] => {
|
36
|
+
if (Array.isArray(value)) {
|
37
|
+
return value.map((v) => (typeof v === 'object' ? JSON.stringify(v) : v));
|
38
|
+
}
|
39
|
+
|
40
|
+
if (typeof value === 'object' && value !== null) {
|
41
|
+
return Object.entries(value)
|
42
|
+
.map(([k, v]) => `${k}: ${typeof v === 'object' ? JSON.stringify(v) : v}`)
|
43
|
+
.join(', ');
|
44
|
+
}
|
45
|
+
return String(value);
|
46
|
+
};
|
47
|
+
|
48
|
+
interface ObjectEntityProps {
|
49
|
+
editable?: boolean;
|
50
|
+
hasMinWidth: boolean;
|
51
|
+
objectKey: string;
|
52
|
+
shine?: boolean;
|
53
|
+
value: any;
|
54
|
+
}
|
55
|
+
|
56
|
+
const ObjectEntity = memo<ObjectEntityProps>(({ hasMinWidth, shine, value, objectKey }) => {
|
57
|
+
const { styles, cx } = useStyles();
|
58
|
+
const isMobile = useIsMobile();
|
59
|
+
const formatedValue = formatValue(value);
|
60
|
+
|
61
|
+
return (
|
62
|
+
<div className={styles.row}>
|
63
|
+
<span
|
64
|
+
className={styles.key}
|
65
|
+
style={{ minWidth: hasMinWidth ? (isMobile ? 60 : 140) : undefined }}
|
66
|
+
>
|
67
|
+
{objectKey}
|
68
|
+
</span>
|
69
|
+
<span className={styles.colon}>:</span>
|
70
|
+
<div className={cx(shine ? styles.shineText : styles.value)} style={{ width: '100%' }}>
|
71
|
+
{typeof formatedValue === 'string' ? (
|
72
|
+
<ValueCell value={formatedValue} />
|
73
|
+
) : (
|
74
|
+
formatedValue.map((v, i) => <ValueCell key={i + v} value={v} />)
|
75
|
+
)}
|
76
|
+
</div>
|
77
|
+
</div>
|
78
|
+
);
|
79
|
+
});
|
80
|
+
|
81
|
+
export default ObjectEntity;
|