@aigne/doc-smith 0.8.12-beta.8 → 0.8.12-beta.9

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 (264) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/agents/publish/index.yaml +4 -0
  3. package/agents/publish/publish-docs.mjs +77 -5
  4. package/agents/publish/translate-meta.mjs +103 -0
  5. package/agents/update/generate-document.yaml +30 -28
  6. package/agents/update/update-document-detail.yaml +3 -1
  7. package/agents/utils/update-branding.mjs +69 -0
  8. package/package.json +16 -2
  9. package/prompts/common/document/role-and-personality.md +3 -1
  10. package/prompts/detail/d2-diagram/guide.md +7 -1
  11. package/prompts/detail/d2-diagram/user-prompt.md +3 -0
  12. package/prompts/detail/generate/system-prompt.md +6 -7
  13. package/prompts/detail/generate/user-prompt.md +12 -3
  14. package/prompts/detail/update/user-prompt.md +0 -2
  15. package/prompts/structure/update/user-prompt.md +0 -4
  16. package/utils/file-utils.mjs +69 -24
  17. package/utils/markdown-checker.mjs +0 -20
  18. package/utils/request.mjs +7 -0
  19. package/utils/upload-files.mjs +231 -0
  20. package/utils/utils.mjs +11 -1
  21. package/.aigne/doc-smith/config.yaml +0 -77
  22. package/.aigne/doc-smith/history.yaml +0 -37
  23. package/.aigne/doc-smith/media-description.yaml +0 -91
  24. package/.aigne/doc-smith/output/structure-plan.json +0 -162
  25. package/.aigne/doc-smith/preferences.yml +0 -97
  26. package/.aigne/doc-smith/upload-cache.yaml +0 -1830
  27. package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
  28. package/.github/workflows/ci.yml +0 -54
  29. package/.github/workflows/create-release-pr.yaml +0 -21
  30. package/.github/workflows/publish-docs.yml +0 -65
  31. package/.github/workflows/release.yml +0 -49
  32. package/.github/workflows/reviewer.yml +0 -54
  33. package/.release-please-manifest.json +0 -3
  34. package/RELEASE.md +0 -9
  35. package/assets/screenshots/doc-complete-setup.png +0 -0
  36. package/assets/screenshots/doc-generate-docs.png +0 -0
  37. package/assets/screenshots/doc-generate.png +0 -0
  38. package/assets/screenshots/doc-generated-successfully.png +0 -0
  39. package/assets/screenshots/doc-publish.png +0 -0
  40. package/assets/screenshots/doc-regenerate.png +0 -0
  41. package/assets/screenshots/doc-translate-langs.png +0 -0
  42. package/assets/screenshots/doc-translate.png +0 -0
  43. package/assets/screenshots/doc-update.png +0 -0
  44. package/biome.json +0 -73
  45. package/codecov.yml +0 -15
  46. package/docs/_sidebar.md +0 -15
  47. package/docs/configuration-initial-setup.ja.md +0 -179
  48. package/docs/configuration-initial-setup.md +0 -198
  49. package/docs/configuration-initial-setup.zh-TW.md +0 -179
  50. package/docs/configuration-initial-setup.zh.md +0 -179
  51. package/docs/configuration-managing-preferences.ja.md +0 -100
  52. package/docs/configuration-managing-preferences.md +0 -100
  53. package/docs/configuration-managing-preferences.zh-TW.md +0 -100
  54. package/docs/configuration-managing-preferences.zh.md +0 -100
  55. package/docs/configuration.ja.md +0 -69
  56. package/docs/configuration.md +0 -69
  57. package/docs/configuration.zh-TW.md +0 -69
  58. package/docs/configuration.zh.md +0 -69
  59. package/docs/getting-started.ja.md +0 -107
  60. package/docs/getting-started.md +0 -107
  61. package/docs/getting-started.zh-TW.md +0 -107
  62. package/docs/getting-started.zh.md +0 -107
  63. package/docs/guides-cleaning-up.ja.md +0 -51
  64. package/docs/guides-cleaning-up.md +0 -52
  65. package/docs/guides-cleaning-up.zh-TW.md +0 -51
  66. package/docs/guides-cleaning-up.zh.md +0 -51
  67. package/docs/guides-evaluating-documents.ja.md +0 -66
  68. package/docs/guides-evaluating-documents.md +0 -107
  69. package/docs/guides-evaluating-documents.zh-TW.md +0 -66
  70. package/docs/guides-evaluating-documents.zh.md +0 -66
  71. package/docs/guides-generating-documentation.ja.md +0 -151
  72. package/docs/guides-generating-documentation.md +0 -89
  73. package/docs/guides-generating-documentation.zh-TW.md +0 -151
  74. package/docs/guides-generating-documentation.zh.md +0 -151
  75. package/docs/guides-interactive-chat.ja.md +0 -85
  76. package/docs/guides-interactive-chat.md +0 -93
  77. package/docs/guides-interactive-chat.zh-TW.md +0 -85
  78. package/docs/guides-interactive-chat.zh.md +0 -85
  79. package/docs/guides-managing-history.ja.md +0 -48
  80. package/docs/guides-managing-history.md +0 -53
  81. package/docs/guides-managing-history.zh-TW.md +0 -48
  82. package/docs/guides-managing-history.zh.md +0 -48
  83. package/docs/guides-publishing-your-docs.ja.md +0 -78
  84. package/docs/guides-publishing-your-docs.md +0 -83
  85. package/docs/guides-publishing-your-docs.zh-TW.md +0 -78
  86. package/docs/guides-publishing-your-docs.zh.md +0 -78
  87. package/docs/guides-translating-documentation.ja.md +0 -95
  88. package/docs/guides-translating-documentation.md +0 -100
  89. package/docs/guides-translating-documentation.zh-TW.md +0 -95
  90. package/docs/guides-translating-documentation.zh.md +0 -95
  91. package/docs/guides-updating-documentation.ja.md +0 -77
  92. package/docs/guides-updating-documentation.md +0 -79
  93. package/docs/guides-updating-documentation.zh-TW.md +0 -77
  94. package/docs/guides-updating-documentation.zh.md +0 -77
  95. package/docs/guides.ja.md +0 -32
  96. package/docs/guides.md +0 -32
  97. package/docs/guides.zh-TW.md +0 -32
  98. package/docs/guides.zh.md +0 -32
  99. package/docs/overview.ja.md +0 -61
  100. package/docs/overview.md +0 -61
  101. package/docs/overview.zh-TW.md +0 -61
  102. package/docs/overview.zh.md +0 -61
  103. package/docs/release-notes.ja.md +0 -255
  104. package/docs/release-notes.md +0 -288
  105. package/docs/release-notes.zh-TW.md +0 -255
  106. package/docs/release-notes.zh.md +0 -255
  107. package/prompts/common/afs/afs-tools-usage.md +0 -5
  108. package/prompts/common/afs/use-afs-instruction.md +0 -1
  109. package/release-please-config.json +0 -14
  110. package/tests/agents/chat/chat.test.mjs +0 -46
  111. package/tests/agents/clear/choose-contents.test.mjs +0 -284
  112. package/tests/agents/clear/clear-auth-tokens.test.mjs +0 -268
  113. package/tests/agents/clear/clear-document-config.test.mjs +0 -167
  114. package/tests/agents/clear/clear-document-structure.test.mjs +0 -380
  115. package/tests/agents/clear/clear-generated-docs.test.mjs +0 -222
  116. package/tests/agents/evaluate/code-snippet.test.mjs +0 -163
  117. package/tests/agents/evaluate/fixtures/api-services.md +0 -87
  118. package/tests/agents/evaluate/fixtures/js-sdk.md +0 -94
  119. package/tests/agents/evaluate/generate-report.test.mjs +0 -312
  120. package/tests/agents/generate/check-document-structure.test.mjs +0 -45
  121. package/tests/agents/generate/check-need-generate-structure.test.mjs +0 -279
  122. package/tests/agents/generate/document-structure-tools/add-document.test.mjs +0 -449
  123. package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +0 -410
  124. package/tests/agents/generate/document-structure-tools/generate-sub-structure.test.mjs +0 -277
  125. package/tests/agents/generate/document-structure-tools/move-document.test.mjs +0 -476
  126. package/tests/agents/generate/document-structure-tools/update-document.test.mjs +0 -548
  127. package/tests/agents/generate/generate-structure.test.mjs +0 -45
  128. package/tests/agents/generate/user-review-document-structure.test.mjs +0 -319
  129. package/tests/agents/history/view.test.mjs +0 -97
  130. package/tests/agents/init/init.test.mjs +0 -1657
  131. package/tests/agents/prefs/prefs.test.mjs +0 -431
  132. package/tests/agents/publish/publish-docs.test.mjs +0 -787
  133. package/tests/agents/translate/choose-language.test.mjs +0 -311
  134. package/tests/agents/translate/translate-document.test.mjs +0 -51
  135. package/tests/agents/update/check-document.test.mjs +0 -463
  136. package/tests/agents/update/check-update-is-single.test.mjs +0 -300
  137. package/tests/agents/update/document-tools/update-document-content.test.mjs +0 -329
  138. package/tests/agents/update/generate-document.test.mjs +0 -51
  139. package/tests/agents/update/save-and-translate-document.test.mjs +0 -369
  140. package/tests/agents/update/user-review-document.test.mjs +0 -582
  141. package/tests/agents/utils/action-success.test.mjs +0 -54
  142. package/tests/agents/utils/check-detail-result.test.mjs +0 -743
  143. package/tests/agents/utils/check-feedback-refiner.test.mjs +0 -478
  144. package/tests/agents/utils/choose-docs.test.mjs +0 -406
  145. package/tests/agents/utils/exit.test.mjs +0 -70
  146. package/tests/agents/utils/feedback-refiner.test.mjs +0 -51
  147. package/tests/agents/utils/find-item-by-path.test.mjs +0 -517
  148. package/tests/agents/utils/find-user-preferences-by-path.test.mjs +0 -382
  149. package/tests/agents/utils/format-document-structure.test.mjs +0 -364
  150. package/tests/agents/utils/fs.test.mjs +0 -267
  151. package/tests/agents/utils/load-sources.test.mjs +0 -1470
  152. package/tests/agents/utils/save-docs.test.mjs +0 -109
  153. package/tests/agents/utils/save-output.test.mjs +0 -315
  154. package/tests/agents/utils/save-single-doc.test.mjs +0 -364
  155. package/tests/agents/utils/transform-detail-datasources.test.mjs +0 -320
  156. package/tests/utils/auth-utils.test.mjs +0 -596
  157. package/tests/utils/blocklet.test.mjs +0 -336
  158. package/tests/utils/conflict-detector.test.mjs +0 -355
  159. package/tests/utils/constants.test.mjs +0 -295
  160. package/tests/utils/d2-utils.test.mjs +0 -437
  161. package/tests/utils/deploy.test.mjs +0 -399
  162. package/tests/utils/docs-finder-utils.test.mjs +0 -650
  163. package/tests/utils/file-utils.test.mjs +0 -521
  164. package/tests/utils/history-utils.test.mjs +0 -206
  165. package/tests/utils/kroki-utils.test.mjs +0 -646
  166. package/tests/utils/linter/fixtures/css/keyword-error.css +0 -1
  167. package/tests/utils/linter/fixtures/css/missing-semicolon.css +0 -1
  168. package/tests/utils/linter/fixtures/css/syntax-error.css +0 -1
  169. package/tests/utils/linter/fixtures/css/undeclare-variable.css +0 -1
  170. package/tests/utils/linter/fixtures/css/unused-variable.css +0 -2
  171. package/tests/utils/linter/fixtures/css/valid-code.css +0 -1
  172. package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +0 -1
  173. package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +0 -2
  174. package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +0 -2
  175. package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +0 -1
  176. package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +0 -1
  177. package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +0 -2
  178. package/tests/utils/linter/fixtures/go/keyword-error.go +0 -5
  179. package/tests/utils/linter/fixtures/go/missing-semicolon.go +0 -5
  180. package/tests/utils/linter/fixtures/go/syntax-error.go +0 -6
  181. package/tests/utils/linter/fixtures/go/undeclare-variable.go +0 -5
  182. package/tests/utils/linter/fixtures/go/unused-variable.go +0 -5
  183. package/tests/utils/linter/fixtures/go/valid-code.go +0 -7
  184. package/tests/utils/linter/fixtures/js/keyword-error.js +0 -3
  185. package/tests/utils/linter/fixtures/js/missing-semicolon.js +0 -6
  186. package/tests/utils/linter/fixtures/js/syntax-error.js +0 -4
  187. package/tests/utils/linter/fixtures/js/undeclare-variable.js +0 -3
  188. package/tests/utils/linter/fixtures/js/unused-variable.js +0 -7
  189. package/tests/utils/linter/fixtures/js/valid-code.js +0 -15
  190. package/tests/utils/linter/fixtures/json/keyword-error.json +0 -1
  191. package/tests/utils/linter/fixtures/json/missing-semicolon.json +0 -1
  192. package/tests/utils/linter/fixtures/json/syntax-error.json +0 -1
  193. package/tests/utils/linter/fixtures/json/undeclare-variable.json +0 -1
  194. package/tests/utils/linter/fixtures/json/unused-variable.json +0 -1
  195. package/tests/utils/linter/fixtures/json/valid-code.json +0 -1
  196. package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +0 -5
  197. package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +0 -5
  198. package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +0 -5
  199. package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +0 -5
  200. package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +0 -4
  201. package/tests/utils/linter/fixtures/jsx/valid-code.jsx +0 -5
  202. package/tests/utils/linter/fixtures/python/keyword-error.py +0 -3
  203. package/tests/utils/linter/fixtures/python/missing-semicolon.py +0 -2
  204. package/tests/utils/linter/fixtures/python/syntax-error.py +0 -3
  205. package/tests/utils/linter/fixtures/python/undeclare-variable.py +0 -3
  206. package/tests/utils/linter/fixtures/python/unused-variable.py +0 -6
  207. package/tests/utils/linter/fixtures/python/valid-code.py +0 -12
  208. package/tests/utils/linter/fixtures/ruby/keyword-error.rb +0 -2
  209. package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +0 -1
  210. package/tests/utils/linter/fixtures/ruby/syntax-error.rb +0 -2
  211. package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +0 -1
  212. package/tests/utils/linter/fixtures/ruby/unused-variable.rb +0 -2
  213. package/tests/utils/linter/fixtures/ruby/valid-code.rb +0 -1
  214. package/tests/utils/linter/fixtures/sass/keyword-error.sass +0 -2
  215. package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +0 -3
  216. package/tests/utils/linter/fixtures/sass/syntax-error.sass +0 -3
  217. package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +0 -2
  218. package/tests/utils/linter/fixtures/sass/unused-variable.sass +0 -4
  219. package/tests/utils/linter/fixtures/sass/valid-code.sass +0 -2
  220. package/tests/utils/linter/fixtures/scss/keyword-error.scss +0 -1
  221. package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +0 -1
  222. package/tests/utils/linter/fixtures/scss/syntax-error.scss +0 -1
  223. package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +0 -1
  224. package/tests/utils/linter/fixtures/scss/unused-variable.scss +0 -2
  225. package/tests/utils/linter/fixtures/scss/valid-code.scss +0 -1
  226. package/tests/utils/linter/fixtures/shell/keyword-error.sh +0 -5
  227. package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +0 -3
  228. package/tests/utils/linter/fixtures/shell/syntax-error.sh +0 -4
  229. package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +0 -3
  230. package/tests/utils/linter/fixtures/shell/unused-variable.sh +0 -4
  231. package/tests/utils/linter/fixtures/shell/valid-code.sh +0 -3
  232. package/tests/utils/linter/fixtures/ts/keyword-error.ts +0 -1
  233. package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +0 -1
  234. package/tests/utils/linter/fixtures/ts/syntax-error.ts +0 -1
  235. package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +0 -1
  236. package/tests/utils/linter/fixtures/ts/unused-variable.ts +0 -3
  237. package/tests/utils/linter/fixtures/ts/valid-code.ts +0 -3
  238. package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +0 -5
  239. package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +0 -5
  240. package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +0 -5
  241. package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +0 -6
  242. package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +0 -6
  243. package/tests/utils/linter/fixtures/tsx/valid-code.tsx +0 -5
  244. package/tests/utils/linter/fixtures/vue/keyword-error.vue +0 -6
  245. package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +0 -6
  246. package/tests/utils/linter/fixtures/vue/syntax-error.vue +0 -6
  247. package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +0 -6
  248. package/tests/utils/linter/fixtures/vue/unused-variable.vue +0 -7
  249. package/tests/utils/linter/fixtures/vue/valid-code.vue +0 -6
  250. package/tests/utils/linter/fixtures/yaml/keyword-error.yml +0 -1
  251. package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +0 -2
  252. package/tests/utils/linter/fixtures/yaml/syntax-error.yml +0 -1
  253. package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +0 -1
  254. package/tests/utils/linter/fixtures/yaml/unused-variable.yml +0 -2
  255. package/tests/utils/linter/fixtures/yaml/valid-code.yml +0 -3
  256. package/tests/utils/linter/index.test.mjs +0 -440
  257. package/tests/utils/linter/scan-results.mjs +0 -42
  258. package/tests/utils/load-config.test.mjs +0 -141
  259. package/tests/utils/markdown/index.test.mjs +0 -478
  260. package/tests/utils/mermaid-validator.test.mjs +0 -541
  261. package/tests/utils/mock-chat-model.mjs +0 -12
  262. package/tests/utils/preferences-utils.test.mjs +0 -465
  263. package/tests/utils/save-value-to-config.test.mjs +0 -483
  264. package/tests/utils/utils.test.mjs +0 -941
@@ -1,541 +0,0 @@
1
- import { afterAll, beforeAll, describe, expect, test } from "bun:test";
2
- import { dirname } from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import {
5
- getValidationStats,
6
- shutdownValidation,
7
- validateBasicMermaidSyntax,
8
- validateMermaidSyntax,
9
- } from "../../utils/mermaid-validator.mjs";
10
- import {
11
- getMermaidWorkerPool,
12
- SimpleMermaidWorkerPool,
13
- shutdownMermaidWorkerPool,
14
- } from "../../utils/mermaid-worker-pool.mjs";
15
-
16
- const __filename = fileURLToPath(import.meta.url);
17
- const __dirname = dirname(__filename);
18
-
19
- describe.skip("Mermaid Worker Pool", () => {
20
- let workerPool;
21
-
22
- beforeAll(() => {
23
- // Ensure clean state
24
- workerPool = new SimpleMermaidWorkerPool({ poolSize: 2, timeout: 5000 });
25
- });
26
-
27
- afterAll(async () => {
28
- if (workerPool) {
29
- await workerPool.shutdown();
30
- }
31
- await shutdownMermaidWorkerPool();
32
- });
33
-
34
- describe("SimpleMermaidWorkerPool", () => {
35
- test("should initialize with default options", () => {
36
- const pool = new SimpleMermaidWorkerPool();
37
- expect(pool.poolSize).toBe(3);
38
- expect(pool.timeout).toBe(15000);
39
- expect(pool.workers).toEqual([]);
40
- expect(pool.availableWorkers).toEqual([]);
41
- expect(pool.requestQueue).toEqual([]);
42
- expect(pool.isShuttingDown).toBe(false);
43
- });
44
-
45
- test("should initialize with custom options", () => {
46
- const pool = new SimpleMermaidWorkerPool({ poolSize: 5, timeout: 10000 });
47
- expect(pool.poolSize).toBe(5);
48
- expect(pool.timeout).toBe(10000);
49
- });
50
-
51
- test("should initialize workers", async () => {
52
- const pool = new SimpleMermaidWorkerPool({ poolSize: 2, timeout: 5000 });
53
-
54
- await pool.initialize();
55
-
56
- expect(pool.workers.length).toBe(2);
57
- expect(pool.availableWorkers.length).toBe(2);
58
-
59
- await pool.shutdown();
60
- });
61
-
62
- test("should not reinitialize if already initialized", async () => {
63
- const pool = new SimpleMermaidWorkerPool({ poolSize: 2, timeout: 5000 });
64
-
65
- await pool.initialize();
66
- const initialWorkers = pool.workers.length;
67
-
68
- await pool.initialize();
69
- expect(pool.workers.length).toBe(initialWorkers);
70
-
71
- await pool.shutdown();
72
- });
73
-
74
- test("should validate valid mermaid content", async () => {
75
- const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 10000 });
76
-
77
- const validContent = `
78
- flowchart TD
79
- A[Start] --> B[Process]
80
- B --> C[End]
81
- `;
82
-
83
- const result = await pool.validate(validContent);
84
- expect(result).toBe(true);
85
-
86
- await pool.shutdown();
87
- });
88
-
89
- test("should reject invalid mermaid content", async () => {
90
- const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 10000 });
91
-
92
- const invalidContent = `
93
- flowchart TD
94
- A[Start] --> B[Process
95
- B --> C[End]
96
- `;
97
-
98
- await expect(pool.validate(invalidContent)).rejects.toThrow();
99
-
100
- await pool.shutdown();
101
- });
102
-
103
- test("should handle concurrent validation requests", async () => {
104
- const pool = new SimpleMermaidWorkerPool({ poolSize: 2, timeout: 10000 });
105
-
106
- const validContent1 = `
107
- flowchart TD
108
- A[Start] --> B[Process]
109
- `;
110
-
111
- const validContent2 = `
112
- graph LR
113
- X --> Y --> Z
114
- `;
115
-
116
- const validContent3 = `
117
- sequenceDiagram
118
- Alice->>Bob: Hello
119
- `;
120
-
121
- const promises = [
122
- pool.validate(validContent1),
123
- pool.validate(validContent2),
124
- pool.validate(validContent3),
125
- ];
126
-
127
- const results = await Promise.all(promises);
128
- expect(results).toEqual([true, true, true]);
129
-
130
- await pool.shutdown();
131
- });
132
-
133
- test("should handle validation timeout", async () => {
134
- const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 100 });
135
-
136
- // Create content that might cause processing delay
137
- const complexContent = `
138
- flowchart TD
139
- ${"A --> B\n".repeat(1000)}
140
- `;
141
-
142
- await expect(pool.validate(complexContent)).rejects.toThrow(/timeout/);
143
-
144
- await pool.shutdown();
145
- });
146
-
147
- test("should queue requests when all workers are busy", async () => {
148
- const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 5000 });
149
-
150
- const validContent = `
151
- flowchart TD
152
- A --> B
153
- `;
154
-
155
- // Start multiple validations simultaneously
156
- const promise1 = pool.validate(validContent);
157
- const promise2 = pool.validate(validContent);
158
- const promise3 = pool.validate(validContent);
159
-
160
- const results = await Promise.all([promise1, promise2, promise3]);
161
- expect(results).toEqual([true, true, true]);
162
-
163
- await pool.shutdown();
164
- });
165
-
166
- test("should reject requests when shutting down", async () => {
167
- const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 5000 });
168
-
169
- await pool.initialize();
170
- await pool.shutdown();
171
-
172
- await expect(pool.validate("flowchart TD\nA --> B")).rejects.toThrow(
173
- "Worker pool is shutting down",
174
- );
175
- });
176
-
177
- test("should provide accurate statistics", async () => {
178
- const pool = new SimpleMermaidWorkerPool({ poolSize: 3, timeout: 5000 });
179
- await pool.initialize();
180
-
181
- const stats = pool.getStats();
182
- expect(stats.poolSize).toBe(3);
183
- expect(stats.totalWorkers).toBe(3);
184
- expect(stats.availableWorkers).toBe(3);
185
- expect(stats.busyWorkers).toBe(0);
186
- expect(stats.queuedRequests).toBe(0);
187
- expect(stats.isShuttingDown).toBe(false);
188
-
189
- await pool.shutdown();
190
- });
191
-
192
- test("should handle worker errors gracefully", async () => {
193
- const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 5000 });
194
-
195
- // Try to validate empty content which should cause an error
196
- await expect(pool.validate("")).rejects.toThrow();
197
-
198
- // Pool should still be functional after error
199
- const validContent = "flowchart TD\nA --> B";
200
- const result = await pool.validate(validContent);
201
- expect(result).toBe(true);
202
-
203
- await pool.shutdown();
204
- });
205
-
206
- test("should shutdown gracefully", async () => {
207
- const pool = new SimpleMermaidWorkerPool({ poolSize: 2, timeout: 5000 });
208
- await pool.initialize();
209
-
210
- expect(pool.workers.length).toBe(2);
211
- expect(pool.isShuttingDown).toBe(false);
212
-
213
- await pool.shutdown();
214
-
215
- expect(pool.workers.length).toBe(0);
216
- expect(pool.availableWorkers.length).toBe(0);
217
- expect(pool.isShuttingDown).toBe(true);
218
- });
219
-
220
- test("should reject queued requests during shutdown", async () => {
221
- const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 5000 });
222
- await pool.initialize();
223
-
224
- // Add requests to queue
225
- const validContent = "flowchart TD\nA --> B";
226
- const promise1 = pool.validate(validContent);
227
- const promise2 = pool.validate(validContent);
228
-
229
- // Start shutdown while requests are queued
230
- setTimeout(() => pool.shutdown(), 10);
231
-
232
- // At least one request should be rejected due to shutdown
233
- const results = await Promise.allSettled([promise1, promise2]);
234
- const rejectedCount = results.filter((r) => r.status === "rejected").length;
235
- expect(rejectedCount).toBeGreaterThan(0);
236
- });
237
- });
238
-
239
- describe("Global Worker Pool Functions", () => {
240
- afterAll(async () => {
241
- await shutdownMermaidWorkerPool();
242
- });
243
-
244
- test("should get global worker pool instance", () => {
245
- const pool1 = getMermaidWorkerPool();
246
- const pool2 = getMermaidWorkerPool();
247
- expect(pool1).toBe(pool2); // Should return same instance
248
- });
249
-
250
- test("should get global worker pool with options", () => {
251
- // Note: Global pool ignores options if already created
252
- // This test verifies that the function returns a pool instance
253
- const pool = getMermaidWorkerPool({ poolSize: 4, timeout: 8000 });
254
- expect(pool).toBeInstanceOf(SimpleMermaidWorkerPool);
255
- expect(typeof pool.poolSize).toBe("number");
256
- expect(typeof pool.timeout).toBe("number");
257
- });
258
-
259
- test("should shutdown global worker pool", async () => {
260
- const pool = getMermaidWorkerPool();
261
- await pool.initialize();
262
- expect(pool.workers.length).toBeGreaterThan(0);
263
-
264
- await shutdownMermaidWorkerPool();
265
- expect(pool.workers.length).toBe(0);
266
- });
267
- });
268
- });
269
-
270
- describe.skip("Mermaid Validator", () => {
271
- afterAll(async () => {
272
- await shutdownValidation();
273
- });
274
-
275
- describe("validateBasicMermaidSyntax", () => {
276
- test("should validate basic flowchart syntax", () => {
277
- const content = "flowchart TD\nA --> B";
278
- expect(validateBasicMermaidSyntax(content)).toBe(true);
279
- });
280
-
281
- test("should validate graph syntax", () => {
282
- const content = "graph LR\nA --> B";
283
- expect(validateBasicMermaidSyntax(content)).toBe(true);
284
- });
285
-
286
- test("should validate sequence diagram syntax", () => {
287
- const content = "sequenceDiagram\nAlice->>Bob: Hello";
288
- expect(validateBasicMermaidSyntax(content)).toBe(true);
289
- });
290
-
291
- test("should validate class diagram syntax", () => {
292
- const content = "classDiagram\nclass Animal";
293
- expect(validateBasicMermaidSyntax(content)).toBe(true);
294
- });
295
-
296
- test("should validate state diagram syntax", () => {
297
- const content = "stateDiagram\n[*] --> Still";
298
- expect(validateBasicMermaidSyntax(content)).toBe(true);
299
- });
300
-
301
- test("should validate ER diagram syntax", () => {
302
- const content = "erDiagram\nCUSTOMER {}";
303
- expect(validateBasicMermaidSyntax(content)).toBe(true);
304
- });
305
-
306
- test("should validate journey diagram syntax", () => {
307
- const content = "journey\ntitle My working day";
308
- expect(validateBasicMermaidSyntax(content)).toBe(true);
309
- });
310
-
311
- test("should validate gantt chart syntax", () => {
312
- const content = "gantt\ntitle A Gantt Diagram";
313
- expect(validateBasicMermaidSyntax(content)).toBe(true);
314
- });
315
-
316
- test("should validate pie chart syntax", () => {
317
- const content = "pie title Pets adopted by volunteers";
318
- expect(validateBasicMermaidSyntax(content)).toBe(true);
319
- });
320
-
321
- test("should reject empty content", () => {
322
- expect(() => validateBasicMermaidSyntax("")).toThrow("Empty mermaid diagram");
323
- expect(() => validateBasicMermaidSyntax(" ")).toThrow("Empty mermaid diagram");
324
- });
325
-
326
- test("should reject invalid diagram type", () => {
327
- expect(() => validateBasicMermaidSyntax("invalid\nA --> B")).toThrow(
328
- "Invalid or missing diagram type",
329
- );
330
- });
331
-
332
- test("should detect unmatched brackets", () => {
333
- expect(() => validateBasicMermaidSyntax("flowchart TD\nA[Start --> B[End]")).toThrow(
334
- "Unmatched brackets in diagram",
335
- );
336
- });
337
-
338
- test("should detect unmatched single quotes", () => {
339
- // Test with properly matched brackets but unmatched quotes
340
- expect(() =>
341
- validateBasicMermaidSyntax("flowchart TD\nA --> B\nNote: 'Unmatched quote"),
342
- ).toThrow("Unmatched single quotes in diagram");
343
- });
344
-
345
- test("should detect unmatched double quotes", () => {
346
- // Test with properly matched brackets but unmatched quotes
347
- expect(() =>
348
- validateBasicMermaidSyntax('flowchart TD\nA --> B\nNote: "Unmatched quote'),
349
- ).toThrow("Unmatched double quotes in diagram");
350
- });
351
-
352
- test("should allow matched quotes", () => {
353
- const content = "flowchart TD\nA[\"Start\"] --> B['End']";
354
- expect(validateBasicMermaidSyntax(content)).toBe(true);
355
- });
356
-
357
- test("should allow complex bracket combinations", () => {
358
- const content = "flowchart TD\nA[Start] --> B{Decision} --> C((Circle))";
359
- expect(validateBasicMermaidSyntax(content)).toBe(true);
360
- });
361
- });
362
-
363
- describe("validateMermaidSyntax", () => {
364
- test("should validate simple flowchart", async () => {
365
- const content = "flowchart TD\nA[Start] --> B[End]";
366
- const result = await validateMermaidSyntax(content);
367
- expect(result).toBe(true);
368
- });
369
-
370
- test("should validate complex flowchart", async () => {
371
- const content = `
372
- flowchart TD
373
- A[Start] --> B{Is it working?}
374
- B -->|Yes| C[Great!]
375
- B -->|No| D[Fix it]
376
- D --> B
377
- C --> E[End]
378
- `;
379
- const result = await validateMermaidSyntax(content);
380
- expect(result).toBe(true);
381
- });
382
-
383
- test("should validate sequence diagram", async () => {
384
- const content = `
385
- sequenceDiagram
386
- participant Alice
387
- participant Bob
388
- Alice->>Bob: Hello Bob, how are you?
389
- Bob-->>Alice: Great!
390
- `;
391
- const result = await validateMermaidSyntax(content);
392
- expect(result).toBe(true);
393
- });
394
-
395
- test("should reject invalid syntax", async () => {
396
- const content = "flowchart TD\nA[Start --> B[End"; // Missing closing bracket
397
- await expect(validateMermaidSyntax(content)).rejects.toThrow();
398
- });
399
-
400
- test("should reject empty content", async () => {
401
- await expect(validateMermaidSyntax("")).rejects.toThrow("Empty mermaid diagram");
402
- await expect(validateMermaidSyntax(" ")).rejects.toThrow("Empty mermaid diagram");
403
- });
404
-
405
- test("should handle worker pool fallback gracefully", async () => {
406
- // This test checks that the function can fall back to basic validation
407
- // if worker validation fails due to environment issues
408
- const content = "flowchart TD\nA --> B";
409
- const result = await validateMermaidSyntax(content);
410
- expect(result).toBe(true);
411
- });
412
-
413
- test("should validate different diagram types", async () => {
414
- const testCases = [
415
- "graph LR\nA --> B",
416
- "sequenceDiagram\nAlice->>Bob: Hello",
417
- "classDiagram\nclass Animal",
418
- "stateDiagram\n[*] --> Still",
419
- "erDiagram\nCUSTOMER {}",
420
- "journey\ntitle My day",
421
- "gantt\ntitle Project",
422
- "pie title Data",
423
- ];
424
-
425
- for (const content of testCases) {
426
- const result = await validateMermaidSyntax(content);
427
- expect(result).toBe(true);
428
- }
429
- });
430
- });
431
-
432
- describe("Utility Functions", () => {
433
- test("should get validation statistics", () => {
434
- const stats = getValidationStats();
435
- expect(typeof stats).toBe("object");
436
-
437
- if (stats.error) {
438
- expect(typeof stats.error).toBe("string");
439
- } else {
440
- expect(typeof stats.poolSize).toBe("number");
441
- expect(typeof stats.totalWorkers).toBe("number");
442
- expect(typeof stats.availableWorkers).toBe("number");
443
- expect(typeof stats.busyWorkers).toBe("number");
444
- expect(typeof stats.queuedRequests).toBe("number");
445
- expect(typeof stats.isShuttingDown).toBe("boolean");
446
- }
447
- });
448
-
449
- test("should shutdown validation properly", async () => {
450
- // Should not throw
451
- await expect(shutdownValidation()).resolves.toBeUndefined();
452
- });
453
- });
454
-
455
- describe("Error Handling and Edge Cases", () => {
456
- test("should handle very large diagrams", async () => {
457
- const largeContent = `
458
- flowchart TD
459
- ${Array.from({ length: 50 }, (_, i) => `A${i} --> A${i + 1}`).join("\n ")}
460
- `;
461
-
462
- // Should either succeed or fail with a clear error
463
- try {
464
- const result = await validateMermaidSyntax(largeContent);
465
- expect(result).toBe(true);
466
- } catch (error) {
467
- expect(error.message).toBeTruthy();
468
- }
469
- });
470
-
471
- test("should handle special characters in content", async () => {
472
- const content = `
473
- flowchart TD
474
- A["Node with special chars: @#$%"] --> B["Another node: &*()"]
475
- `;
476
-
477
- const result = await validateMermaidSyntax(content);
478
- expect(result).toBe(true);
479
- });
480
-
481
- test("should handle unicode characters", async () => {
482
- const content = `
483
- flowchart TD
484
- A["开始"] --> B["处理"]
485
- B --> C["结束"]
486
- `;
487
-
488
- const result = await validateMermaidSyntax(content);
489
- expect(result).toBe(true);
490
- });
491
-
492
- test("should handle multiline node labels", async () => {
493
- const content = `
494
- flowchart TD
495
- A["Multi<br/>Line<br/>Label"] --> B["Another<br/>Multi<br/>Line"]
496
- `;
497
-
498
- const result = await validateMermaidSyntax(content);
499
- expect(result).toBe(true);
500
- });
501
-
502
- test("should handle comments in diagrams", async () => {
503
- const content = `
504
- flowchart TD
505
- %% This is a comment
506
- A[Start] --> B[End]
507
- %% Another comment
508
- `;
509
-
510
- const result = await validateMermaidSyntax(content);
511
- expect(result).toBe(true);
512
- });
513
- });
514
-
515
- describe("Concurrency and Performance", () => {
516
- test("should handle multiple concurrent validations", async () => {
517
- const validations = Array.from({ length: 10 }, (_, i) =>
518
- validateMermaidSyntax(`flowchart TD\nA${i} --> B${i}`),
519
- );
520
-
521
- const results = await Promise.all(validations);
522
- expect(results.every((r) => r === true)).toBe(true);
523
- });
524
-
525
- test("should handle mixed valid and invalid validations", async () => {
526
- const validations = [
527
- validateMermaidSyntax("flowchart TD\nA --> B"),
528
- validateMermaidSyntax("invalid content"),
529
- validateMermaidSyntax("graph LR\nX --> Y"),
530
- validateMermaidSyntax("another invalid"),
531
- ];
532
-
533
- const results = await Promise.allSettled(validations);
534
-
535
- expect(results[0].status).toBe("fulfilled");
536
- expect(results[1].status).toBe("rejected");
537
- expect(results[2].status).toBe("fulfilled");
538
- expect(results[3].status).toBe("rejected");
539
- });
540
- });
541
- });
@@ -1,12 +0,0 @@
1
- // Mock ChatModel for testing
2
- export class MockChatModel {
3
- constructor(options = {}) {
4
- this.options = options;
5
- }
6
-
7
- process() {
8
- throw new Error("Method not implemented in test mock");
9
- }
10
- }
11
-
12
- export const loadModel = () => new MockChatModel();