@zjlab-fe/data-hub-ui 0.21.6 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/dist/types/components/tip-tap/extensions/index.d.ts +1 -1
  2. package/es/assets/cardImg.png.js +3 -0
  3. package/es/assets/closeBtn.png.js +3 -0
  4. package/es/assets/icon-tag-header.png.js +3 -0
  5. package/es/assets/source.png.js +3 -0
  6. package/es/components/FileUploader/FileUploadModal.js +24 -0
  7. package/es/components/FileUploader/FileUploader.js +20 -0
  8. package/es/components/FileUploader/FileUploaderImpl/FileUploader.js +34 -0
  9. package/es/components/FileUploader/FileUploaderImpl/FileUploaderContextProvider.js +46 -0
  10. package/es/components/FileUploader/FileUploaderImpl/FileUploaderFileReceiver.css.js +36 -0
  11. package/es/components/FileUploader/FileUploaderImpl/FileUploaderFileReceiver.js +57 -0
  12. package/es/components/FileUploader/FileUploaderImpl/FileUploaderFileReceiverContainer.js +24 -0
  13. package/es/components/FileUploader/FileUploaderImpl/FileUploaderFileReceiverDesc.js +9 -0
  14. package/es/components/FileUploader/FileUploaderImpl/FileUploaderList.js +46 -0
  15. package/es/components/FileUploader/FileUploaderImpl/FileUploaderListItem.js +46 -0
  16. package/es/components/FileUploader/FileUploaderImpl/FileUploaderListItemFail.js +21 -0
  17. package/es/components/FileUploader/FileUploaderImpl/FileUploaderListItemPaused.js +20 -0
  18. package/es/components/FileUploader/FileUploaderImpl/FileUploaderListItemUploading.js +43 -0
  19. package/es/components/FileUploader/FileUploaderImpl/FileUploaderlListItemFinished.js +32 -0
  20. package/es/components/FileUploader/Locale/translations.js +52 -0
  21. package/es/components/FileUploader/Locale/useTranslate.js +16 -0
  22. package/es/components/FileUploader/UploadStoreProvider/UploadStoreProvider.js +31 -0
  23. package/es/components/FileUploader/UploadStoreProvider/uploadStoreReducer.js +62 -0
  24. package/es/components/FileUploader/UploadStoreProvider/useOnFileAllUploaded.js +31 -0
  25. package/es/components/FileUploader/UploadStoreProvider/useSaveUnfinishedUploads.js +42 -0
  26. package/es/components/FileUploader/UploadStoreProvider/useSetupMergingEvent.js +45 -0
  27. package/es/components/FileUploader/hooks/useCancelUpload.js +40 -0
  28. package/es/components/FileUploader/hooks/useCurrentFile.js +61 -0
  29. package/es/components/FileUploader/hooks/useCurrentFileOnUploading.js +52 -0
  30. package/es/components/FileUploader/hooks/useCurrentFileSetupAndBackUp.js +39 -0
  31. package/es/components/FileUploader/hooks/useFormatFiles.js +64 -0
  32. package/es/components/FileUploader/hooks/useFormatFilesFindDuplicates.js +75 -0
  33. package/es/components/FileUploader/hooks/useFormatFilesRemoveDuplicates.js +21 -0
  34. package/es/components/FileUploader/hooks/useHandleChunkCompletion.js +31 -0
  35. package/es/components/FileUploader/hooks/useOnMounted.js +24 -0
  36. package/es/components/FileUploader/hooks/useOnMountedResumeUnfinished.js +58 -0
  37. package/es/components/FileUploader/hooks/useRetryUpload.js +33 -0
  38. package/es/components/FileUploader/hooks/useUploadChunk.js +46 -0
  39. package/es/components/FileUploader/icons/CloseFilled.js +7 -0
  40. package/es/components/FileUploader/icons/UnkownFileIcon.js +7 -0
  41. package/es/components/FileUploader/icons/UploadIcon.js +7 -0
  42. package/es/components/FileUploader/index.css.js +532 -0
  43. package/es/components/FileUploader/index.js +23 -0
  44. package/es/components/FileUploader/types.js +13 -0
  45. package/es/components/FileUploader/utils/calcDisplaySize.js +20 -0
  46. package/es/components/FileUploader/utils/checkExpiryTime.js +15 -0
  47. package/es/components/FileUploader/utils/createFileToUpload.js +60 -0
  48. package/es/components/FileUploader/utils/fileDB/addFilesToIndexdb.js +14 -0
  49. package/es/components/FileUploader/utils/fileDB/deleteFileInStore.js +18 -0
  50. package/es/components/FileUploader/utils/fileDB/deleteObjectStore.js +25 -0
  51. package/es/components/FileUploader/utils/fileDB/index.js +77 -0
  52. package/es/components/FileUploader/utils/fileDB/openDBAndRetrieveData.js +90 -0
  53. package/es/components/FileUploader/utils/fileDB/retrieveExistingData.js +49 -0
  54. package/es/components/FileUploader/utils/modalConfig.css.js +20 -0
  55. package/es/components/FileUploader/utils/modalConfig.js +32 -0
  56. package/es/components/FileUploader/utils/retrieveAllFiles.js +70 -0
  57. package/es/components/FileUploader/utils/splitFileIntoChunk.js +15 -0
  58. package/es/components/SDK-modal/document-link.js +8 -0
  59. package/es/components/SDK-modal/index.js +25 -0
  60. package/es/components/SDK-modal/index.module.scss.js +49 -0
  61. package/es/components/SDK-modal/inner-modal.js +59 -0
  62. package/es/components/SDK-modal/locale/translations.js +17 -0
  63. package/es/components/apply-perm-modal/index.js +53 -0
  64. package/es/components/apply-perm-modal/index.module.scss.js +96 -0
  65. package/es/components/auth-tag/index.js +23 -0
  66. package/es/components/bench-card/index.js +20 -0
  67. package/es/components/bench-card/index.module.scss.js +48 -0
  68. package/es/components/confirm-again/index.js +15 -0
  69. package/es/components/confirm-again/index.scss.js +37 -0
  70. package/es/components/copy/index.js +41 -0
  71. package/es/components/copy/index.module.scss.js +15 -0
  72. package/es/components/corpus-card/index.js +88 -0
  73. package/es/components/corpus-card/index.module.scss.js +171 -0
  74. package/es/components/feature-card/classNames.js +72 -0
  75. package/es/components/feature-card/components.js +48 -0
  76. package/es/components/feature-card/context.js +13 -0
  77. package/es/components/feature-card/index.css.js +655 -0
  78. package/es/components/feature-card/index.js +48 -0
  79. package/es/components/file-preview/data-table/index.js +94 -0
  80. package/es/components/file-preview/data-table/index.module.scss.js +54 -0
  81. package/es/components/file-preview/excel-preview/index.js +132 -0
  82. package/es/components/file-preview/excel-preview/index.module.scss.js +11 -0
  83. package/es/components/file-preview/excel-preview/utils.js +46 -0
  84. package/es/components/file-preview/img-preview/index.js +18 -0
  85. package/es/components/file-preview/img-preview/index.module.scss.js +17 -0
  86. package/es/components/file-preview/index.js +124 -0
  87. package/es/components/file-preview/index.module.scss.js +32 -0
  88. package/es/components/file-preview/json-preview/index.js +166 -0
  89. package/es/components/file-preview/markdown-preview/index.js +53 -0
  90. package/es/components/file-preview/markdown-preview/index.module.scss.js +1055 -0
  91. package/es/components/file-preview/parquet-preview/index.js +54 -0
  92. package/es/components/file-preview/pdf-preview/index.js +215 -0
  93. package/es/components/file-preview/pdf-preview/index.module.scss.js +16 -0
  94. package/es/components/file-preview/table-preview/index.js +43 -0
  95. package/es/components/file-preview/table-preview/index.module.scss.js +11 -0
  96. package/es/components/file-preview/txt-preview/index.js +24 -0
  97. package/es/components/file-preview/util.js +94 -0
  98. package/es/components/file-uploader/components/circle-progress.css.js +39 -0
  99. package/es/components/file-uploader/components/circle-progress.js +12 -0
  100. package/es/components/file-uploader/components/hooks/use-drop-zone.js +74 -0
  101. package/es/components/file-uploader/components/hooks/use-file-validation.js +52 -0
  102. package/es/components/file-uploader/components/icons.js +19 -0
  103. package/es/components/file-uploader/components/theme.css.js +64 -0
  104. package/es/components/file-uploader/components/uploader-drop-zone.css.js +66 -0
  105. package/es/components/file-uploader/components/uploader-drop-zone.js +74 -0
  106. package/es/components/file-uploader/components/uploader-file-item.css.js +186 -0
  107. package/es/components/file-uploader/components/uploader-file-item.js +63 -0
  108. package/es/components/file-uploader/components/uploader-file-list.css.js +43 -0
  109. package/es/components/file-uploader/components/uploader-file-list.js +27 -0
  110. package/es/components/file-uploader/components/uploader.css.js +20 -0
  111. package/es/components/file-uploader/components/uploader.js +51 -0
  112. package/es/components/file-uploader/components/uploading-status.css.js +52 -0
  113. package/es/components/file-uploader/components/uploading-status.js +54 -0
  114. package/es/components/file-uploader/components/utils/directory-reader.js +65 -0
  115. package/es/components/file-uploader/constants.js +31 -0
  116. package/es/components/file-uploader/context/action-registry.js +69 -0
  117. package/es/components/file-uploader/context/file-state-store.js +83 -0
  118. package/es/components/file-uploader/context/handler-registry.js +119 -0
  119. package/es/components/file-uploader/context/upload-context.js +36 -0
  120. package/es/components/file-uploader/context/upload-provider.js +77 -0
  121. package/es/components/file-uploader/context/upload-reducer.js +21 -0
  122. package/es/components/file-uploader/context/use-upload-engine.js +440 -0
  123. package/es/components/file-uploader/engine/queue-callbacks.js +257 -0
  124. package/es/components/file-uploader/engine/queue-manager.js +195 -0
  125. package/es/components/file-uploader/engine/queue-uploader.js +25 -0
  126. package/es/components/file-uploader/hooks/use-upload.js +327 -0
  127. package/es/components/file-uploader/utils/chunk-handlers.js +66 -0
  128. package/es/components/file-uploader/utils/ensure-handlers.js +53 -0
  129. package/es/components/file-uploader/utils/error-handler.js +84 -0
  130. package/es/components/file-uploader/utils/upload-controllers.js +43 -0
  131. package/es/components/file-uploader/utils/upload-handler.js +68 -0
  132. package/es/components/file-uploader/utils/validate-handlers.js +16 -0
  133. package/es/components/floating-label-input/index.js +46 -0
  134. package/es/components/floating-label-input/index.module.scss.js +30 -0
  135. package/es/components/floating-layer/index.js +15 -0
  136. package/es/components/floating-layer/index.scss.js +31 -0
  137. package/es/components/header/index.js +10 -0
  138. package/es/components/header/index.module.scss.js +16 -0
  139. package/es/components/input-tag/index.js +65 -0
  140. package/es/components/menu/index.js +96 -0
  141. package/es/components/menu/index.module.scss.js +188 -0
  142. package/es/components/model-card/index.js +20 -0
  143. package/es/components/model-card/index.module.scss.js +116 -0
  144. package/es/components/notion-editor/code-block/index.js +18 -0
  145. package/es/components/notion-editor/code-block/languageDetector.js +134 -0
  146. package/es/components/notion-editor/code-block/languages.js +42 -0
  147. package/es/components/notion-editor/index.js +258 -0
  148. package/es/components/notion-editor/index.scss.js +421 -0
  149. package/es/components/notion-editor/parseMarkdown.js +184 -0
  150. package/es/components/operator-chain/components/AddButton.js +20 -0
  151. package/es/components/operator-chain/components/IOCard.js +8 -0
  152. package/es/components/operator-chain/components/SingleCard.js +12 -0
  153. package/es/components/operator-chain/components/VirtualDropdown.js +56 -0
  154. package/es/components/operator-chain/index.js +83 -0
  155. package/es/components/operator-chain/index.module.scss.js +232 -0
  156. package/es/components/permission-editor/index.js +9 -0
  157. package/es/components/permission-editor/permissionEditModal/index.js +37 -0
  158. package/es/components/permission-editor/permissionEditor/index.js +253 -0
  159. package/es/components/permission-editor/permissionEditor/index.module.scss.js +22 -0
  160. package/es/components/permission-editor/permissionViewPopover/index.js +9 -0
  161. package/es/components/popover-select/index.js +42 -0
  162. package/es/components/popover-select/index.module.scss.js +22 -0
  163. package/es/components/radio-card/index.js +24 -0
  164. package/es/components/radio-card/index.scss.js +58 -0
  165. package/es/components/section-heading/classNames.js +22 -0
  166. package/es/components/section-heading/components.js +27 -0
  167. package/es/components/section-heading/context.js +13 -0
  168. package/es/components/section-heading/index.css.js +648 -0
  169. package/es/components/section-heading/index.js +37 -0
  170. package/es/components/status-tag/index.js +31 -0
  171. package/es/components/tag-group-filter/dataSizeFilter.js +100 -0
  172. package/es/components/tag-group-filter/index.js +53 -0
  173. package/es/components/tag-group-filter/index.module.scss.js +134 -0
  174. package/es/components/tag-group-filter/tagFilter.js +19 -0
  175. package/es/components/tag-view/index.js +138 -0
  176. package/es/components/tag-view/index.module.scss.js +56 -0
  177. package/es/components/tag-view/useSize.js +41 -0
  178. package/es/components/tip-tap/bubble-menu.js +47 -0
  179. package/es/components/tip-tap/editor.js +34 -0
  180. package/es/components/tip-tap/extensions/index.js +133 -0
  181. package/es/components/tip-tap/extensions/markdown-paste.js +148 -0
  182. package/es/components/tip-tap/icons/index.js +29 -0
  183. package/es/components/tip-tap/reader.js +15 -0
  184. package/es/components/tip-tap/styles/editor.css.js +863 -0
  185. package/es/components/tip-tap/toolbar/components/color-picker.js +76 -0
  186. package/es/components/tip-tap/toolbar/components/heading-dropdown.js +44 -0
  187. package/es/components/tip-tap/toolbar/components/image-button.js +26 -0
  188. package/es/components/tip-tap/toolbar/components/link-button.js +107 -0
  189. package/es/components/tip-tap/toolbar/components/table-button.js +37 -0
  190. package/es/components/tip-tap/toolbar/components/toolbar-button.js +7 -0
  191. package/es/components/tip-tap/toolbar/index.js +39 -0
  192. package/es/components/uploadDrawer/UploadStoreProvider.js +61 -0
  193. package/es/components/uploadDrawer/fileUploadDrawer.js +66 -0
  194. package/es/components/uploadDrawer/fileUploadDrawerFileDragger.js +71 -0
  195. package/es/components/uploadDrawer/fileUploadDrawerList.js +54 -0
  196. package/es/components/uploadDrawer/fileUploadDrawerListProgressButton.js +54 -0
  197. package/es/components/uploadDrawer/hooks/useCancelUpload.js +37 -0
  198. package/es/components/uploadDrawer/hooks/useFilterFiles.js +107 -0
  199. package/es/components/uploadDrawer/hooks/useFinishUpload.js +33 -0
  200. package/es/components/uploadDrawer/hooks/useFormatFiles.js +54 -0
  201. package/es/components/uploadDrawer/hooks/useProgressButtonRef.js +22 -0
  202. package/es/components/uploadDrawer/hooks/useRemoveFilesInUploadQueue.js +21 -0
  203. package/es/components/uploadDrawer/hooks/useResumeUnfinishedUploads.js +52 -0
  204. package/es/components/uploadDrawer/hooks/useRetryUpload.js +35 -0
  205. package/es/components/uploadDrawer/hooks/useSaveUnfinishedUploads.js +42 -0
  206. package/es/components/uploadDrawer/hooks/useSetupUpload.js +80 -0
  207. package/es/components/uploadDrawer/hooks/useUploadFileToOSS.js +23 -0
  208. package/es/components/uploadDrawer/index.css.js +511 -0
  209. package/es/components/uploadDrawer/index.js +43 -0
  210. package/es/components/uploadDrawer/utils/calcDisplaySize.js +19 -0
  211. package/es/components/uploadDrawer/utils/constant.js +16 -0
  212. package/es/components/uploadDrawer/utils/createFileToUpload.js +51 -0
  213. package/es/components/uploadDrawer/utils/fileDB/deleteFileInStore.js +28 -0
  214. package/es/components/uploadDrawer/utils/fileDB/deleteObjectStore.js +28 -0
  215. package/es/components/uploadDrawer/utils/fileDB/handleAddFilesToDB.js +37 -0
  216. package/es/components/uploadDrawer/utils/fileDB/index.js +9 -0
  217. package/es/components/uploadDrawer/utils/fileDB/openDB.js +111 -0
  218. package/es/components/uploadDrawer/utils/retrieveAllFiles.js +110 -0
  219. package/es/components/uploadDrawer/utils/shouldCreateNewFile.js +13 -0
  220. package/es/components/uploadDrawer/utils/splitFileIntoChunk.js +15 -0
  221. package/es/index.js +42 -1
  222. package/es/lib/utils.js +8 -0
  223. package/lib/index.js +1 -1
  224. package/package.json +164 -154
  225. package/rollup.es.config.mjs +177 -0
  226. package/tsconfig.rollup.json +7 -0
@@ -0,0 +1,134 @@
1
+ /** 根据代码内容特征自动识别语言 */
2
+ const LANGUAGE_PATTERNS = [
3
+ // TypeScript — 优先于 JS/JSX 判断
4
+ [
5
+ 'interface\\s+\\w+\\s*\\{|^type\\s+\\w+\\s*=|:\\s*(string|number|boolean|void|any)\\b(?!\\s*[:=])',
6
+ 'typescript',
7
+ ],
8
+ ['\\.tsx?["\']|tsconfig|@types/', 'typescript'],
9
+ // TSX
10
+ ['as\\s+\\w+(?:\\[\\])?\\s*[,)}\\]>]', 'tsx'],
11
+ // JSX
12
+ [
13
+ '<[A-Z]\\w*(?:\\s+[\\w-]+(?:\\s*=\\s*["\'{[(][^"\'\\]})]*["\'})\\]])?\\s*>[\\s\\S]*?<\\/[A-Z]\\w+\\s*>|className=|onClick=|onChange=|return\\s*\\(',
14
+ 'jsx',
15
+ ],
16
+ // JavaScript
17
+ [
18
+ 'import\\s+.*\\s+from\\s+["\']|export\\s+(default|const|function)|const\\s+\\w+\\s*=\\s*(require|\\(|async)|module\\.exports|console\\.(log|error|warn)',
19
+ 'javascript',
20
+ ],
21
+ ['function\\s*\\*|async\\s+function|=>\\s*[{ (]|let\\s+\\w+\\s*[=;]', 'javascript'],
22
+ // HTML — 优先于 XML
23
+ ['<!DOCTYPE\\s+html|<html[\\s>]|<head[\\s>]|<body[\\s>]|<div[\\s>]|<span[\\s>]', 'html'],
24
+ // CSS
25
+ ['[.#][\\w-]+\\s*\\{[^}]*[a-z-]+\\s*:\\s*[^;]+;', 'css'],
26
+ // SCSS
27
+ ['@mixin\\s+\\w|@include\\s+\\w|\\$\\w+:\\s*[^;]+;|&\\s*__', 'scss'],
28
+ // JSON
29
+ ['^\\s*[{[]\\s*[\\s\\S]*?"[\\w$]+"\\s*:', 'json'],
30
+ // C# — 放在 Java 前面,避免 C# 的 @Override 等注解被 Java 误匹配
31
+ ['using\\s+System[.;]|namespace\\s+\\w+|Console\\.(Write|Read|Line)', 'csharp'],
32
+ // Java — 放在 Python 前面,避免 Java 的 import 误匹配
33
+ [
34
+ '(?:public\\s+|protected\\s+|private\\s+)?(?:abstract\\s+)?(?:class|interface|enum)\\s+\\w+|System\\.(out|err|in)\\.|static\\s+void\\s+main|^import\\s+\\w+\\.\\w+',
35
+ 'java',
36
+ ],
37
+ // Python
38
+ [
39
+ '^from\\s+\\w+\\s+import|^import\\s+(os|sys|re|json|datetime|math|collections|typing|pathlib|random)|^def\\s+\\w+\\s*\\(|^class\\s+\\w+\\s*[:\\(]|if\\s+__name__\\s*==\\s*["\']__main__["\']|print\\s*\\(|#.*coding|elif\\s|else\\s*:|except\\s|try\\s*:',
40
+ 'python',
41
+ ],
42
+ // C
43
+ ['^#include\\s+<[^>]+\\.h>|printf\\s*\\(|scanf\\s*\\(|int\\s+main\\s*\\(', 'c'],
44
+ // C++
45
+ [
46
+ '^#include\\s+<(iostream|vector|string|map|algorithm)>|std::|cout\\s*<<|cin\\s*>>|template\\s*<|class\\s+\\w+\\s*[{:]',
47
+ 'cpp',
48
+ ],
49
+ // Go
50
+ [
51
+ '^func\\s+\\w+|^package\\s+\\w+|^import\\s+[("]|fmt\\.(Print|Sprintf|Errorf)|:=|defer\\s+\\w|go\\s+func',
52
+ 'go',
53
+ ],
54
+ // Rust
55
+ [
56
+ '^fn\\s+\\w+|let\\s+mut|match\\s+\\w+\\s*\\{|^impl\\s+\\w+|^pub\\s+(fn|struct|enum|trait)|^use\\s+\\w+|println!|vec!|unsafe\\s*\\{',
57
+ 'rust',
58
+ ],
59
+ // Kotlin
60
+ [
61
+ '^fun\\s+\\w+\\s*\\(|^val\\s+\\w+|^var\\s+\\w+|^import\\s+\\w+\\.|^class\\s+\\w+\\s*[:(]|println\\s*\\(',
62
+ 'kotlin',
63
+ ],
64
+ // Swift
65
+ [
66
+ '^func\\s+\\w+|^var\\s+\\w+|^let\\s+\\w+|^import\\s+(UIKit|Foundation|SwiftUI)|print\\s*\\(|guard\\s+let|#available',
67
+ 'swift',
68
+ ],
69
+ // Dart
70
+ ['^void\\s+main|^import\\s+["\']package:|^class\\s+\\w+\\s*\\{|@override', 'dart'],
71
+ // PHP
72
+ ['^<\\?php|function\\s+\\w+\\s*\\(.*\\).*\\{|\\$\\w+|echo\\s+["\']', 'php'],
73
+ // Ruby
74
+ [
75
+ '^def\\s+\\w+|^end$|^require\\s+["\'][\\w\\/]+["\']|attr_(accessor|reader|writer)|^class\\s+\\w+\\s*[<$]',
76
+ 'ruby',
77
+ ],
78
+ // Lua
79
+ ['^function\\s+\\w+|^local\\s+\\w+\\s*=|^end$|--\\[\\[', 'lua'],
80
+ // R
81
+ ['^library\\(|<- |data\\.frame\\(|ggplot\\(|^function\\(', 'r'],
82
+ // SQL
83
+ ['^(SELECT|FROM|WHERE|INSERT\\s+INTO|CREATE\\s+TABLE|UPDATE|DELETE\\s+FROM|JOIN|ALTER\\s+TABLE)\\b', 'sql'],
84
+ // Bash
85
+ ['^#!\\/|^echo\\s+|^export\\s+\\w+=|^source\\s+|^if\\s+\\[|^for\\s+\\w+\\s+in|^while\\s+read', 'bash'],
86
+ // PowerShell
87
+ ['Write-Host|Get-Item|Foreach-Object|\\$_|^param\\(', 'powershell'],
88
+ // Markdown — 放在 YAML 前面,避免 Markdown 列表项被误判为 YAML
89
+ ['^#{1,6}\\s|^\\[.*\\]\\(.*\\)|^-\\s+\\[[ x]\\]|^-\\s+\\w|^\\d+\\.\\s+\\w|^\\|.*\\|', 'markdown'],
90
+ // XML (非 HTML)
91
+ ['^<\\?xml\\s|<[A-Za-z]+\\s+[^>]*\\/>|<[A-Za-z]+[^>]*>[\\s\\S]*?<\\/[A-Za-z]+>', 'xml'],
92
+ // YAML
93
+ ['^---\\s*$|^[\\w.-]+:\\s+(?!\\s)|^\\s+-\\s+\\w+', 'yaml'],
94
+ // GraphQL
95
+ ['^type\\s+\\w+\\s*\\{|^query\\s+\\w+|^mutation\\s+\\w+|^schema\\s*\\{', 'graphql'],
96
+ // Diff
97
+ ['^---\\s+\\S+$|^\\+\\+\\+\\s+\\S+$|^@@\\s+-\\d+,\\d+\\s+\\+\\d+,\\d+\\s+@@', 'diff'],
98
+ // HTTP — 必须有请求行(GET/POST ... HTTP/)才能判定
99
+ ['^(GET|POST|PUT|DELETE|PATCH)\\s+\\S+\\s+HTTP\\/', 'http'],
100
+ // Makefile
101
+ ['^[A-Z_]+\\s*[:+]?=\\s*\\S+|^\\.PHONY:|^all:|^install:|^clean:', 'makefile'],
102
+ // Dockerfile
103
+ ['^FROM\\s+\\w+|^RUN\\s+|^CMD\\s+\\[|^COPY\\s+|^WORKDIR\\s+|^ENV\\s+', 'dockerfile'],
104
+ // Nginx
105
+ ['^server\\s*\\{|^location\\s+\\S+|proxy_pass|server_name', 'nginx'],
106
+ ];
107
+ /**
108
+ * 检测代码内容对应的编程语言
109
+ * @param code 要检测的代码文本
110
+ * @returns 匹配的语言 key,未匹配则返回 'text'
111
+ */
112
+ function detectLanguage(code) {
113
+ var _a;
114
+ if (!code) {
115
+ return 'text';
116
+ }
117
+ const firstLine = (_a = code.split('\n', 1)[0]) !== null && _a !== void 0 ? _a : '';
118
+ const sampleLines = code.split('\n').slice(0, 30);
119
+ const sampleText = sampleLines.join('\n');
120
+ for (const [pattern, lang] of LANGUAGE_PATTERNS) {
121
+ try {
122
+ const regex = new RegExp(pattern);
123
+ if (regex.test(sampleText) || regex.test(firstLine)) {
124
+ return lang;
125
+ }
126
+ }
127
+ catch (_b) {
128
+ // 正则异常时跳过
129
+ }
130
+ }
131
+ return 'text';
132
+ }
133
+
134
+ export { detectLanguage };
@@ -0,0 +1,42 @@
1
+ const LANGUAGES = {
2
+ // plain: { name: 'text', aliases: ['text', 'txt'] },
3
+ nginx: { name: 'Nginx' },
4
+ text: { name: '纯文本', aliases: ['plaintext', 'txt'] },
5
+ javascript: { name: 'JavaScript', aliases: ['js'] },
6
+ typescript: { name: 'TypeScript', aliases: ['ts'] },
7
+ jsx: { name: 'JSX' },
8
+ tsx: { name: 'TSX' },
9
+ html: { name: 'HTML' },
10
+ css: { name: 'CSS' },
11
+ scss: { name: 'SCSS', aliases: ['sass'] },
12
+ json: { name: 'JSON' },
13
+ python: { name: 'Python', aliases: ['py'] },
14
+ java: { name: 'Java' },
15
+ c: { name: 'C' },
16
+ cpp: { name: 'C++', aliases: ['cxx', 'cc'] },
17
+ csharp: { name: 'C#', aliases: ['cs', 'dotnet'] },
18
+ go: { name: 'Go', aliases: ['golang'] },
19
+ rust: { name: 'Rust', aliases: ['rs'] },
20
+ sql: { name: 'SQL' },
21
+ bash: { name: 'Bash', aliases: ['sh', 'shell', 'zsh'] },
22
+ powershell: { name: 'PowerShell', aliases: ['ps', 'ps1'] },
23
+ yaml: { name: 'YAML', aliases: ['yml'] },
24
+ xml: { name: 'XML' },
25
+ markdown: { name: 'Markdown', aliases: ['md'] },
26
+ php: { name: 'PHP' },
27
+ ruby: { name: 'Ruby', aliases: ['rb'] },
28
+ swift: { name: 'Swift' },
29
+ kotlin: { name: 'Kotlin', aliases: ['kt'] },
30
+ dart: { name: 'Dart' },
31
+ lua: { name: 'Lua' },
32
+ r: { name: 'R' },
33
+ dockerfile: { name: 'Dockerfile', aliases: ['docker'] },
34
+ graphql: { name: 'GraphQL', aliases: ['gql'] },
35
+ diff: { name: 'Diff' },
36
+ http: { name: 'HTTP' },
37
+ makefile: { name: 'Makefile', aliases: ['make'] },
38
+ };
39
+ /** Shiki 需要预加载的语言列表(排除纯文本) */
40
+ const HIGHLIGHT_LANGS = Object.keys(LANGUAGES).filter((l) => l !== 'text');
41
+
42
+ export { HIGHLIGHT_LANGS, LANGUAGES as default };
@@ -0,0 +1,258 @@
1
+ import { __awaiter } from 'tslib';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { forwardRef, useRef, useState, useCallback, useEffect, useMemo, useImperativeHandle } from 'react';
4
+ import { createReactBlockSpec, useCreateBlockNote, FormattingToolbarController, FormattingToolbar, getFormattingToolbarItems, BasicTextStyleButton } from '@blocknote/react';
5
+ import { Extension } from '@tiptap/core';
6
+ import { TextSelection } from 'prosemirror-state';
7
+ import { BlockNoteSchema, defaultStyleSpecs, defaultInlineContentSpecs, defaultBlockSpecs } from '@blocknote/core';
8
+ import { BlockNoteView } from '@blocknote/mantine';
9
+ import { zh } from '@blocknote/core/locales';
10
+ import '@blocknote/core/fonts/inter.css';
11
+ import '@blocknote/mantine/style.css';
12
+ import './index.scss.js';
13
+ import { CustomCodeBlock } from './code-block/index.js';
14
+ import { detectLanguage } from './code-block/languageDetector.js';
15
+ import { parsePastedMarkdown } from './parseMarkdown.js';
16
+
17
+ // 自定义文件块,替换默认的文件块
18
+ const CustomFileBlock = createReactBlockSpec({
19
+ type: 'file',
20
+ propSchema: {
21
+ name: { default: '' },
22
+ url: { default: '' },
23
+ caption: { default: '' },
24
+ backgroundColor: { default: 'default' },
25
+ },
26
+ content: 'none',
27
+ }, {
28
+ render: ({ block }) => (jsxs("div", { className: "data-hub-ui-custom-file-block", onClick: () => window.open(block.props.url, '_blank'), children: [jsx("div", { className: "data-hub-ui-custom-file-block__icon", children: "\uD83D\uDCC4" }), jsx("div", { className: "data-hub-ui-custom-file-block__info", children: jsx("div", { className: "data-hub-ui-custom-file-block__name", children: block.props.name || '未命名文件' }) })] })),
29
+ });
30
+ // 创建自定义 Schema,替换默认 file 和 codeBlock 块
31
+ const schema = BlockNoteSchema.create({
32
+ blockSpecs: Object.assign(Object.assign({}, defaultBlockSpecs), { codeBlock: CustomCodeBlock, file: CustomFileBlock() }),
33
+ inlineContentSpecs: defaultInlineContentSpecs,
34
+ styleSpecs: defaultStyleSpecs,
35
+ });
36
+ const ATTACHMENT_URL_REGEXP = /(\/api\/fes\/docs\/resource\/attachment\/)([^/?#]+)(\/[^/?#]+)/;
37
+ const isCopyPastePayload = (value) => value.action === 'copy' && Array.isArray(value.data);
38
+ const replaceAttachmentDocId = (url, docId) => url.replace(ATTACHMENT_URL_REGEXP, (_match, prefix, _oldId, suffix) => {
39
+ return `${prefix}${docId}${suffix}`;
40
+ });
41
+ const rewriteAttachmentUrls = (blocks, docId) => {
42
+ blocks.forEach((block) => {
43
+ if ((block.type === 'image' || block.type === 'file') && block.props) {
44
+ const url = block.props.url;
45
+ if (typeof url === 'string') {
46
+ block.props.url = replaceAttachmentDocId(url, docId);
47
+ }
48
+ }
49
+ if (Array.isArray(block.children)) {
50
+ rewriteAttachmentUrls(block.children, docId);
51
+ }
52
+ });
53
+ };
54
+ const isEmptyBlockContent = (block) => {
55
+ const blockContent = block.content;
56
+ return !blockContent || (Array.isArray(blockContent) && blockContent.length === 0);
57
+ };
58
+ const getInlineText = (content) => {
59
+ if (!Array.isArray(content)) {
60
+ return '';
61
+ }
62
+ return content
63
+ .map((item) => {
64
+ if ('text' in item && typeof item.text === 'string') {
65
+ return item.text;
66
+ }
67
+ return '';
68
+ })
69
+ .join('')
70
+ .trim();
71
+ };
72
+ const getHeadingTocItems = (blocks) => {
73
+ const tocItems = [];
74
+ const walkBlocks = (items) => {
75
+ items.forEach((block) => {
76
+ if (block.type === 'heading') {
77
+ const level = Number(block.props.level) || 1;
78
+ tocItems.push({
79
+ id: block.id,
80
+ level: Math.min(Math.max(level, 1), 6),
81
+ title: getInlineText(block.content) || '未命名标题',
82
+ });
83
+ }
84
+ if (Array.isArray(block.children) && block.children.length > 0) {
85
+ walkBlocks(block.children);
86
+ }
87
+ });
88
+ };
89
+ walkBlocks(blocks);
90
+ return tocItems;
91
+ };
92
+ const parseCopyPasteBlocks = (plainText, docId) => {
93
+ if (!docId) {
94
+ return null;
95
+ }
96
+ try {
97
+ const parsed = JSON.parse(plainText);
98
+ if (!isCopyPastePayload(parsed)) {
99
+ return null;
100
+ }
101
+ const blocks = JSON.parse(JSON.stringify(parsed.data));
102
+ rewriteAttachmentUrls(blocks, docId);
103
+ return blocks;
104
+ }
105
+ catch (_a) {
106
+ return null;
107
+ }
108
+ };
109
+ const NotionEditor = forwardRef(({ initContent, editable = false, className = '', docId, onChange, onImageUpload, onFileUpload, onImageUploadByUrl, }, ref) => {
110
+ const placeholder = '输入 "/" 快速插入内容';
111
+ const docIdRef = useRef(docId);
112
+ const [tocCollapsed, setTocCollapsed] = useState(false);
113
+ const [tocItems, setTocItems] = useState([]);
114
+ docIdRef.current = docId;
115
+ const uploadFile = useCallback((file) => __awaiter(void 0, void 0, void 0, function* () {
116
+ const isImage = file.type.startsWith('image/');
117
+ if (isImage && onImageUpload) {
118
+ return onImageUpload(file);
119
+ }
120
+ if (!isImage && onFileUpload) {
121
+ // const result = await onFileUpload(file);
122
+ // return result.url;
123
+ return onFileUpload(file);
124
+ }
125
+ return URL.createObjectURL(file);
126
+ }), [onImageUpload, onFileUpload]);
127
+ const editor = useCreateBlockNote({
128
+ dictionary: Object.assign(Object.assign({}, zh), { placeholders: Object.assign(Object.assign({}, zh.placeholders), { default: placeholder, emptyDocument: placeholder }) }),
129
+ initialContent: Array.isArray(initContent) && initContent.length > 0 ? initContent : undefined,
130
+ schema: schema,
131
+ setIdAttribute: true,
132
+ uploadFile,
133
+ tables: {
134
+ splitCells: true,
135
+ },
136
+ _tiptapOptions: {
137
+ extensions: [
138
+ Extension.create({
139
+ name: 'codeBlockSelectAll',
140
+ addKeyboardShortcuts() {
141
+ return {
142
+ 'Mod-a': () => {
143
+ const { state, view } = this.editor;
144
+ const { selection, doc } = state;
145
+ const { $from } = selection;
146
+ const parent = $from.parent;
147
+ // 仅在 codeBlock 内拦截 Ctrl+A
148
+ if (parent.type.name === 'codeBlock') {
149
+ const start = $from.start();
150
+ const end = $from.end();
151
+ const tr = state.tr.setSelection(TextSelection.create(doc, start, end));
152
+ view.dispatch(tr);
153
+ return true; // 阻止默认全选
154
+ }
155
+ return false; // 其他 block 走默认行为
156
+ },
157
+ };
158
+ },
159
+ }),
160
+ ],
161
+ },
162
+ pasteHandler: ({ event, editor: ed, defaultPasteHandler }) => {
163
+ var _a, _b, _c, _d, _e;
164
+ // return defaultPasteHandler();
165
+ // 在代码块内粘贴时不拦截,保持纯文本
166
+ const pos = ed.getTextCursorPosition();
167
+ if (pos.block.type === 'codeBlock') {
168
+ // 粘贴后自动识别语言并设置
169
+ const plainText = (_b = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text/plain')) === null || _b === void 0 ? void 0 : _b.trim();
170
+ console.log('+++ plainText', plainText);
171
+ defaultPasteHandler();
172
+ if (plainText) {
173
+ const lang = detectLanguage(plainText);
174
+ if (lang !== 'text') {
175
+ ed.updateBlock(pos.block, { props: { language: lang } });
176
+ }
177
+ }
178
+ return true;
179
+ }
180
+ // 有纯文本且包含 Markdown 标记字符时,手动解析
181
+ if ((_c = event.clipboardData) === null || _c === void 0 ? void 0 : _c.types.includes('text/plain')) {
182
+ const plainText = (_d = event.clipboardData.getData('text/plain')) === null || _d === void 0 ? void 0 : _d.trim();
183
+ const copyPasteBlocks = plainText ? parseCopyPasteBlocks(plainText, docIdRef.current) : null;
184
+ if (copyPasteBlocks) {
185
+ if (copyPasteBlocks.length > 0) {
186
+ const cursorBlock = ed.getTextCursorPosition().block;
187
+ const isEmpty = isEmptyBlockContent(cursorBlock);
188
+ const refBlock = isEmpty ? ((_e = ed.getParentBlock(cursorBlock)) !== null && _e !== void 0 ? _e : cursorBlock) : cursorBlock;
189
+ ed.insertBlocks(copyPasteBlocks, refBlock, 'after');
190
+ }
191
+ return true;
192
+ }
193
+ const hasHtmlImage = /<img\b[^>]*\bsrc=(["']).*?\1[^>]*\/?>/i.test(plainText);
194
+ if (plainText && (/[#*`\-[>|]/.test(plainText) || hasHtmlImage)) {
195
+ // 以 < 开头像 HTML 代码 → 按 HTML 粘贴,包含 img 标签时走自定义上传逻辑
196
+ if (/^\s*</.test(plainText) && !hasHtmlImage) {
197
+ return defaultPasteHandler();
198
+ }
199
+ // 使用自定义解析:先提取 ```代码块```,剩余部分走标准 Markdown
200
+ (() => __awaiter(void 0, void 0, void 0, function* () {
201
+ var _a;
202
+ const cursorBlock = ed.getTextCursorPosition().block;
203
+ const blocks = yield parsePastedMarkdown(plainText, (md) => ed.tryParseMarkdownToBlocks(md), onImageUploadByUrl);
204
+ if (blocks.length > 0) {
205
+ // 光标所在 block 如果内容为空则先移除
206
+ const isEmpty = isEmptyBlockContent(cursorBlock);
207
+ // 在光标 block 位置或其后插入
208
+ const refBlock = isEmpty ? ((_a = ed.getParentBlock(cursorBlock)) !== null && _a !== void 0 ? _a : cursorBlock) : cursorBlock;
209
+ ed.insertBlocks(blocks, refBlock, 'after');
210
+ }
211
+ }))();
212
+ return true;
213
+ }
214
+ }
215
+ return defaultPasteHandler();
216
+ },
217
+ });
218
+ // Sync editable prop
219
+ useEffect(() => {
220
+ if (editor) {
221
+ editor.isEditable = editable;
222
+ }
223
+ }, [editor, editable]);
224
+ const handleChange = useCallback(() => {
225
+ if (editor) {
226
+ const blocks = editor.document;
227
+ setTocItems(getHeadingTocItems(blocks));
228
+ onChange === null || onChange === void 0 ? void 0 : onChange(blocks);
229
+ }
230
+ }, [editor, onChange]);
231
+ useEffect(() => {
232
+ if (editor) {
233
+ setTocItems(getHeadingTocItems(editor.document));
234
+ }
235
+ }, [editor]);
236
+ const showToc = tocItems.length > 0;
237
+ const tocTitle = useMemo(() => (tocCollapsed ? '展开目录' : '收起目录'), [tocCollapsed]);
238
+ const handleTocItemClick = useCallback((blockId) => {
239
+ const target = document.querySelector(`.data-hub-ui-blocknote-editor [data-id="${CSS.escape(blockId)}"]`);
240
+ target === null || target === void 0 ? void 0 : target.scrollIntoView({ behavior: 'smooth', block: 'start' });
241
+ }, []);
242
+ useImperativeHandle(ref, () => ({
243
+ getContent: () => editor.document,
244
+ // getJSON: () => (editor?.document ?? []) as unknown as Record<string, unknown>,
245
+ setContent: (content) => __awaiter(void 0, void 0, void 0, function* () {
246
+ if (editor) {
247
+ // @ts-expect-error - Block[] 与 PartialBlock[] 类型参数不匹配,但运行时安全
248
+ editor.replaceBlocks(editor.document, content);
249
+ }
250
+ }),
251
+ focus: () => editor === null || editor === void 0 ? void 0 : editor.focus(),
252
+ isEmpty: () => { var _a; return (_a = editor === null || editor === void 0 ? void 0 : editor.isEmpty) !== null && _a !== void 0 ? _a : true; },
253
+ }));
254
+ return (jsxs("div", { className: `data-hub-ui-blocknote-editor-wrapper ${tocCollapsed ? 'is-toc-collapsed' : ''} ${className}`, children: [jsx(BlockNoteView, { editor: editor, formattingToolbar: false, onChange: handleChange, theme: "light", className: "data-hub-ui-blocknote-editor", children: jsx(FormattingToolbarController, { formattingToolbar: () => (jsxs(FormattingToolbar, { children: [getFormattingToolbarItems(), jsx(BasicTextStyleButton, { basicTextStyle: "code" })] })) }) }), showToc && (jsxs("aside", { className: `data-hub-ui-blocknote-toc ${tocCollapsed ? 'is-collapsed' : ''}`, children: [jsxs("button", { type: "button", className: "data-hub-ui-blocknote-toc__toggle", "aria-label": tocTitle, "aria-expanded": !tocCollapsed, onClick: () => setTocCollapsed((value) => !value), children: [jsx("span", { children: "\u76EE\u5F55" }), jsx("span", { className: "data-hub-ui-blocknote-toc__toggle-icon", children: tocCollapsed ? '‹' : '›' })] }), !tocCollapsed && (jsx("nav", { className: "data-hub-ui-blocknote-toc__list", "aria-label": "\u6587\u6863\u76EE\u5F55", children: tocItems.map((item) => (jsx("button", { type: "button", className: "data-hub-ui-blocknote-toc__item", style: { '--toc-level': item.level }, title: item.title, onClick: () => handleTocItemClick(item.id), children: item.title }, item.id))) }))] }))] }));
255
+ });
256
+ NotionEditor.displayName = 'NotionEditor';
257
+
258
+ export { NotionEditor as default };