@aigne/doc-smith 0.8.12-beta.7 → 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 (284) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/agents/clear/choose-contents.mjs +14 -1
  3. package/agents/clear/clear-media-description.mjs +129 -0
  4. package/agents/clear/index.yaml +3 -1
  5. package/agents/evaluate/code-snippet.mjs +28 -24
  6. package/agents/evaluate/document-structure.yaml +0 -4
  7. package/agents/evaluate/document.yaml +1 -5
  8. package/agents/generate/index.yaml +1 -0
  9. package/agents/init/index.mjs +10 -0
  10. package/agents/media/batch-generate-media-description.yaml +44 -0
  11. package/agents/media/generate-media-description.yaml +47 -0
  12. package/agents/media/load-media-description.mjs +238 -0
  13. package/agents/publish/index.yaml +4 -0
  14. package/agents/publish/publish-docs.mjs +77 -5
  15. package/agents/publish/translate-meta.mjs +103 -0
  16. package/agents/update/generate-document.yaml +30 -28
  17. package/agents/update/index.yaml +1 -0
  18. package/agents/update/update-document-detail.yaml +3 -1
  19. package/agents/utils/load-sources.mjs +103 -53
  20. package/agents/utils/update-branding.mjs +69 -0
  21. package/aigne.yaml +6 -0
  22. package/assets/report-template/report.html +34 -34
  23. package/package.json +17 -2
  24. package/prompts/common/document/role-and-personality.md +3 -1
  25. package/prompts/detail/d2-diagram/guide.md +7 -1
  26. package/prompts/detail/d2-diagram/user-prompt.md +3 -0
  27. package/prompts/detail/generate/system-prompt.md +6 -7
  28. package/prompts/detail/generate/user-prompt.md +12 -3
  29. package/prompts/detail/update/user-prompt.md +0 -2
  30. package/prompts/evaluate/document-structure.md +6 -7
  31. package/prompts/evaluate/document.md +16 -25
  32. package/prompts/media/media-description/system-prompt.md +35 -0
  33. package/prompts/media/media-description/user-prompt.md +8 -0
  34. package/prompts/structure/update/user-prompt.md +0 -4
  35. package/utils/constants/index.mjs +0 -107
  36. package/utils/file-utils.mjs +86 -0
  37. package/utils/markdown-checker.mjs +0 -20
  38. package/utils/request.mjs +7 -0
  39. package/utils/upload-files.mjs +231 -0
  40. package/utils/utils.mjs +11 -1
  41. package/.aigne/doc-smith/config.yaml +0 -77
  42. package/.aigne/doc-smith/history.yaml +0 -37
  43. package/.aigne/doc-smith/output/structure-plan.json +0 -162
  44. package/.aigne/doc-smith/preferences.yml +0 -97
  45. package/.aigne/doc-smith/upload-cache.yaml +0 -1893
  46. package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
  47. package/.github/workflows/ci.yml +0 -54
  48. package/.github/workflows/create-release-pr.yaml +0 -21
  49. package/.github/workflows/publish-docs.yml +0 -65
  50. package/.github/workflows/release.yml +0 -49
  51. package/.github/workflows/reviewer.yml +0 -54
  52. package/.release-please-manifest.json +0 -3
  53. package/RELEASE.md +0 -9
  54. package/assets/screenshots/doc-complete-setup.png +0 -0
  55. package/assets/screenshots/doc-generate-docs.png +0 -0
  56. package/assets/screenshots/doc-generate.png +0 -0
  57. package/assets/screenshots/doc-generated-successfully.png +0 -0
  58. package/assets/screenshots/doc-publish.png +0 -0
  59. package/assets/screenshots/doc-regenerate.png +0 -0
  60. package/assets/screenshots/doc-translate-langs.png +0 -0
  61. package/assets/screenshots/doc-translate.png +0 -0
  62. package/assets/screenshots/doc-update.png +0 -0
  63. package/biome.json +0 -73
  64. package/codecov.yml +0 -15
  65. package/docs/_sidebar.md +0 -15
  66. package/docs/configuration-initial-setup.ja.md +0 -179
  67. package/docs/configuration-initial-setup.md +0 -179
  68. package/docs/configuration-initial-setup.zh-TW.md +0 -179
  69. package/docs/configuration-initial-setup.zh.md +0 -179
  70. package/docs/configuration-managing-preferences.ja.md +0 -100
  71. package/docs/configuration-managing-preferences.md +0 -100
  72. package/docs/configuration-managing-preferences.zh-TW.md +0 -100
  73. package/docs/configuration-managing-preferences.zh.md +0 -100
  74. package/docs/configuration.ja.md +0 -96
  75. package/docs/configuration.md +0 -96
  76. package/docs/configuration.zh-TW.md +0 -96
  77. package/docs/configuration.zh.md +0 -96
  78. package/docs/getting-started.ja.md +0 -88
  79. package/docs/getting-started.md +0 -88
  80. package/docs/getting-started.zh-TW.md +0 -88
  81. package/docs/getting-started.zh.md +0 -88
  82. package/docs/guides-cleaning-up.ja.md +0 -51
  83. package/docs/guides-cleaning-up.md +0 -51
  84. package/docs/guides-cleaning-up.zh-TW.md +0 -51
  85. package/docs/guides-cleaning-up.zh.md +0 -51
  86. package/docs/guides-evaluating-documents.ja.md +0 -66
  87. package/docs/guides-evaluating-documents.md +0 -66
  88. package/docs/guides-evaluating-documents.zh-TW.md +0 -66
  89. package/docs/guides-evaluating-documents.zh.md +0 -66
  90. package/docs/guides-generating-documentation.ja.md +0 -151
  91. package/docs/guides-generating-documentation.md +0 -151
  92. package/docs/guides-generating-documentation.zh-TW.md +0 -151
  93. package/docs/guides-generating-documentation.zh.md +0 -151
  94. package/docs/guides-interactive-chat.ja.md +0 -85
  95. package/docs/guides-interactive-chat.md +0 -85
  96. package/docs/guides-interactive-chat.zh-TW.md +0 -85
  97. package/docs/guides-interactive-chat.zh.md +0 -85
  98. package/docs/guides-managing-history.ja.md +0 -48
  99. package/docs/guides-managing-history.md +0 -48
  100. package/docs/guides-managing-history.zh-TW.md +0 -48
  101. package/docs/guides-managing-history.zh.md +0 -48
  102. package/docs/guides-publishing-your-docs.ja.md +0 -78
  103. package/docs/guides-publishing-your-docs.md +0 -78
  104. package/docs/guides-publishing-your-docs.zh-TW.md +0 -78
  105. package/docs/guides-publishing-your-docs.zh.md +0 -78
  106. package/docs/guides-translating-documentation.ja.md +0 -95
  107. package/docs/guides-translating-documentation.md +0 -95
  108. package/docs/guides-translating-documentation.zh-TW.md +0 -95
  109. package/docs/guides-translating-documentation.zh.md +0 -95
  110. package/docs/guides-updating-documentation.ja.md +0 -77
  111. package/docs/guides-updating-documentation.md +0 -77
  112. package/docs/guides-updating-documentation.zh-TW.md +0 -77
  113. package/docs/guides-updating-documentation.zh.md +0 -77
  114. package/docs/guides.ja.md +0 -32
  115. package/docs/guides.md +0 -32
  116. package/docs/guides.zh-TW.md +0 -32
  117. package/docs/guides.zh.md +0 -32
  118. package/docs/overview.ja.md +0 -61
  119. package/docs/overview.md +0 -61
  120. package/docs/overview.zh-TW.md +0 -61
  121. package/docs/overview.zh.md +0 -61
  122. package/docs/release-notes.ja.md +0 -255
  123. package/docs/release-notes.md +0 -255
  124. package/docs/release-notes.zh-TW.md +0 -255
  125. package/docs/release-notes.zh.md +0 -255
  126. package/media.md +0 -19
  127. package/prompts/common/afs/afs-tools-usage.md +0 -5
  128. package/prompts/common/afs/use-afs-instruction.md +0 -1
  129. package/release-please-config.json +0 -14
  130. package/tests/agents/chat/chat.test.mjs +0 -46
  131. package/tests/agents/clear/choose-contents.test.mjs +0 -284
  132. package/tests/agents/clear/clear-auth-tokens.test.mjs +0 -268
  133. package/tests/agents/clear/clear-document-config.test.mjs +0 -167
  134. package/tests/agents/clear/clear-document-structure.test.mjs +0 -380
  135. package/tests/agents/clear/clear-generated-docs.test.mjs +0 -222
  136. package/tests/agents/evaluate/code-snippet.test.mjs +0 -163
  137. package/tests/agents/evaluate/fixtures/api-services.md +0 -87
  138. package/tests/agents/evaluate/fixtures/js-sdk.md +0 -94
  139. package/tests/agents/evaluate/generate-report.test.mjs +0 -312
  140. package/tests/agents/generate/check-document-structure.test.mjs +0 -45
  141. package/tests/agents/generate/check-need-generate-structure.test.mjs +0 -279
  142. package/tests/agents/generate/document-structure-tools/add-document.test.mjs +0 -449
  143. package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +0 -410
  144. package/tests/agents/generate/document-structure-tools/generate-sub-structure.test.mjs +0 -277
  145. package/tests/agents/generate/document-structure-tools/move-document.test.mjs +0 -476
  146. package/tests/agents/generate/document-structure-tools/update-document.test.mjs +0 -548
  147. package/tests/agents/generate/generate-structure.test.mjs +0 -45
  148. package/tests/agents/generate/user-review-document-structure.test.mjs +0 -319
  149. package/tests/agents/history/view.test.mjs +0 -97
  150. package/tests/agents/init/init.test.mjs +0 -1657
  151. package/tests/agents/prefs/prefs.test.mjs +0 -431
  152. package/tests/agents/publish/publish-docs.test.mjs +0 -787
  153. package/tests/agents/translate/choose-language.test.mjs +0 -311
  154. package/tests/agents/translate/translate-document.test.mjs +0 -51
  155. package/tests/agents/update/check-document.test.mjs +0 -463
  156. package/tests/agents/update/check-update-is-single.test.mjs +0 -300
  157. package/tests/agents/update/document-tools/update-document-content.test.mjs +0 -329
  158. package/tests/agents/update/generate-document.test.mjs +0 -51
  159. package/tests/agents/update/save-and-translate-document.test.mjs +0 -369
  160. package/tests/agents/update/user-review-document.test.mjs +0 -582
  161. package/tests/agents/utils/action-success.test.mjs +0 -54
  162. package/tests/agents/utils/check-detail-result.test.mjs +0 -743
  163. package/tests/agents/utils/check-feedback-refiner.test.mjs +0 -478
  164. package/tests/agents/utils/choose-docs.test.mjs +0 -406
  165. package/tests/agents/utils/exit.test.mjs +0 -70
  166. package/tests/agents/utils/feedback-refiner.test.mjs +0 -51
  167. package/tests/agents/utils/find-item-by-path.test.mjs +0 -517
  168. package/tests/agents/utils/find-user-preferences-by-path.test.mjs +0 -382
  169. package/tests/agents/utils/format-document-structure.test.mjs +0 -364
  170. package/tests/agents/utils/fs.test.mjs +0 -267
  171. package/tests/agents/utils/load-sources.test.mjs +0 -1470
  172. package/tests/agents/utils/save-docs.test.mjs +0 -109
  173. package/tests/agents/utils/save-output.test.mjs +0 -315
  174. package/tests/agents/utils/save-single-doc.test.mjs +0 -364
  175. package/tests/agents/utils/transform-detail-datasources.test.mjs +0 -320
  176. package/tests/utils/auth-utils.test.mjs +0 -596
  177. package/tests/utils/blocklet.test.mjs +0 -336
  178. package/tests/utils/conflict-detector.test.mjs +0 -355
  179. package/tests/utils/constants.test.mjs +0 -295
  180. package/tests/utils/d2-utils.test.mjs +0 -437
  181. package/tests/utils/deploy.test.mjs +0 -399
  182. package/tests/utils/docs-finder-utils.test.mjs +0 -650
  183. package/tests/utils/file-utils.test.mjs +0 -521
  184. package/tests/utils/history-utils.test.mjs +0 -206
  185. package/tests/utils/kroki-utils.test.mjs +0 -646
  186. package/tests/utils/linter/fixtures/css/keyword-error.css +0 -1
  187. package/tests/utils/linter/fixtures/css/missing-semicolon.css +0 -1
  188. package/tests/utils/linter/fixtures/css/syntax-error.css +0 -1
  189. package/tests/utils/linter/fixtures/css/undeclare-variable.css +0 -1
  190. package/tests/utils/linter/fixtures/css/unused-variable.css +0 -2
  191. package/tests/utils/linter/fixtures/css/valid-code.css +0 -1
  192. package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +0 -1
  193. package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +0 -2
  194. package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +0 -2
  195. package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +0 -1
  196. package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +0 -1
  197. package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +0 -2
  198. package/tests/utils/linter/fixtures/go/keyword-error.go +0 -5
  199. package/tests/utils/linter/fixtures/go/missing-semicolon.go +0 -5
  200. package/tests/utils/linter/fixtures/go/syntax-error.go +0 -6
  201. package/tests/utils/linter/fixtures/go/undeclare-variable.go +0 -5
  202. package/tests/utils/linter/fixtures/go/unused-variable.go +0 -5
  203. package/tests/utils/linter/fixtures/go/valid-code.go +0 -7
  204. package/tests/utils/linter/fixtures/js/keyword-error.js +0 -3
  205. package/tests/utils/linter/fixtures/js/missing-semicolon.js +0 -6
  206. package/tests/utils/linter/fixtures/js/syntax-error.js +0 -4
  207. package/tests/utils/linter/fixtures/js/undeclare-variable.js +0 -3
  208. package/tests/utils/linter/fixtures/js/unused-variable.js +0 -7
  209. package/tests/utils/linter/fixtures/js/valid-code.js +0 -15
  210. package/tests/utils/linter/fixtures/json/keyword-error.json +0 -1
  211. package/tests/utils/linter/fixtures/json/missing-semicolon.json +0 -1
  212. package/tests/utils/linter/fixtures/json/syntax-error.json +0 -1
  213. package/tests/utils/linter/fixtures/json/undeclare-variable.json +0 -1
  214. package/tests/utils/linter/fixtures/json/unused-variable.json +0 -1
  215. package/tests/utils/linter/fixtures/json/valid-code.json +0 -1
  216. package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +0 -5
  217. package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +0 -5
  218. package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +0 -5
  219. package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +0 -5
  220. package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +0 -4
  221. package/tests/utils/linter/fixtures/jsx/valid-code.jsx +0 -5
  222. package/tests/utils/linter/fixtures/python/keyword-error.py +0 -3
  223. package/tests/utils/linter/fixtures/python/missing-semicolon.py +0 -2
  224. package/tests/utils/linter/fixtures/python/syntax-error.py +0 -3
  225. package/tests/utils/linter/fixtures/python/undeclare-variable.py +0 -3
  226. package/tests/utils/linter/fixtures/python/unused-variable.py +0 -6
  227. package/tests/utils/linter/fixtures/python/valid-code.py +0 -12
  228. package/tests/utils/linter/fixtures/ruby/keyword-error.rb +0 -2
  229. package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +0 -1
  230. package/tests/utils/linter/fixtures/ruby/syntax-error.rb +0 -2
  231. package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +0 -1
  232. package/tests/utils/linter/fixtures/ruby/unused-variable.rb +0 -2
  233. package/tests/utils/linter/fixtures/ruby/valid-code.rb +0 -1
  234. package/tests/utils/linter/fixtures/sass/keyword-error.sass +0 -2
  235. package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +0 -3
  236. package/tests/utils/linter/fixtures/sass/syntax-error.sass +0 -3
  237. package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +0 -2
  238. package/tests/utils/linter/fixtures/sass/unused-variable.sass +0 -4
  239. package/tests/utils/linter/fixtures/sass/valid-code.sass +0 -2
  240. package/tests/utils/linter/fixtures/scss/keyword-error.scss +0 -1
  241. package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +0 -1
  242. package/tests/utils/linter/fixtures/scss/syntax-error.scss +0 -1
  243. package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +0 -1
  244. package/tests/utils/linter/fixtures/scss/unused-variable.scss +0 -2
  245. package/tests/utils/linter/fixtures/scss/valid-code.scss +0 -1
  246. package/tests/utils/linter/fixtures/shell/keyword-error.sh +0 -5
  247. package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +0 -3
  248. package/tests/utils/linter/fixtures/shell/syntax-error.sh +0 -4
  249. package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +0 -3
  250. package/tests/utils/linter/fixtures/shell/unused-variable.sh +0 -4
  251. package/tests/utils/linter/fixtures/shell/valid-code.sh +0 -3
  252. package/tests/utils/linter/fixtures/ts/keyword-error.ts +0 -1
  253. package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +0 -1
  254. package/tests/utils/linter/fixtures/ts/syntax-error.ts +0 -1
  255. package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +0 -1
  256. package/tests/utils/linter/fixtures/ts/unused-variable.ts +0 -3
  257. package/tests/utils/linter/fixtures/ts/valid-code.ts +0 -3
  258. package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +0 -5
  259. package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +0 -5
  260. package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +0 -5
  261. package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +0 -6
  262. package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +0 -6
  263. package/tests/utils/linter/fixtures/tsx/valid-code.tsx +0 -5
  264. package/tests/utils/linter/fixtures/vue/keyword-error.vue +0 -6
  265. package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +0 -6
  266. package/tests/utils/linter/fixtures/vue/syntax-error.vue +0 -6
  267. package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +0 -6
  268. package/tests/utils/linter/fixtures/vue/unused-variable.vue +0 -7
  269. package/tests/utils/linter/fixtures/vue/valid-code.vue +0 -6
  270. package/tests/utils/linter/fixtures/yaml/keyword-error.yml +0 -1
  271. package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +0 -2
  272. package/tests/utils/linter/fixtures/yaml/syntax-error.yml +0 -1
  273. package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +0 -1
  274. package/tests/utils/linter/fixtures/yaml/unused-variable.yml +0 -2
  275. package/tests/utils/linter/fixtures/yaml/valid-code.yml +0 -3
  276. package/tests/utils/linter/index.test.mjs +0 -440
  277. package/tests/utils/linter/scan-results.mjs +0 -42
  278. package/tests/utils/load-config.test.mjs +0 -141
  279. package/tests/utils/markdown/index.test.mjs +0 -478
  280. package/tests/utils/mermaid-validator.test.mjs +0 -541
  281. package/tests/utils/mock-chat-model.mjs +0 -12
  282. package/tests/utils/preferences-utils.test.mjs +0 -465
  283. package/tests/utils/save-value-to-config.test.mjs +0 -483
  284. package/tests/utils/utils.test.mjs +0 -941
@@ -1,109 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test } from "bun:test";
2
- import { mkdir, readdir, rm, writeFile } from "node:fs/promises";
3
- import { dirname, join } from "node:path";
4
- import { fileURLToPath } from "node:url";
5
- import saveDocs from "../../../agents/utils/save-docs.mjs";
6
-
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
-
9
- describe("save-docs", () => {
10
- let testDir;
11
-
12
- beforeEach(async () => {
13
- // Set test environment variable to prevent actual config file modification
14
- process.env.NODE_ENV = "test";
15
-
16
- // Create a temporary test directory
17
- testDir = join(__dirname, "test-docs");
18
- await mkdir(testDir, { recursive: true });
19
-
20
- // Create some test files
21
- const testFiles = [
22
- "overview.md",
23
- "getting-started.md",
24
- "getting-started.zh.md",
25
- "getting-started.en.md",
26
- "old-file.md", // This should be deleted
27
- "another-old-file.md", // This should be deleted
28
- "old-translation.zh.md", // This should be deleted
29
- "_sidebar.md", // This should be preserved
30
- ];
31
-
32
- for (const file of testFiles) {
33
- await writeFile(join(testDir, file), `# Test content for ${file}`);
34
- }
35
- });
36
-
37
- afterEach(async () => {
38
- // Clean up environment variable
39
- delete process.env.NODE_ENV;
40
-
41
- // Clean up test directory
42
- try {
43
- await rm(testDir, { recursive: true, force: true });
44
- } catch {
45
- // Ignore cleanup errors since they don't affect test results
46
- }
47
- });
48
-
49
- test("should clean up invalid files and maintain valid ones", async () => {
50
- const initialFiles = await readdir(testDir);
51
- expect(initialFiles).toContain("overview.md");
52
- expect(initialFiles).toContain("getting-started.md");
53
- expect(initialFiles).toContain("old-file.md");
54
-
55
- // Test documentation structure
56
- const documentStructure = [
57
- {
58
- path: "/overview",
59
- title: "Overview",
60
- description: "Overview page",
61
- },
62
- {
63
- path: "/getting-started",
64
- title: "Getting Started",
65
- description: "Getting started guide",
66
- },
67
- ];
68
-
69
- // Test with translation languages
70
- const translateLanguages = ["zh", "en"];
71
-
72
- const result = await saveDocs({
73
- documentExecutionStructure: documentStructure,
74
- docsDir: testDir,
75
- translateLanguages,
76
- });
77
-
78
- expect(result).toBeDefined();
79
-
80
- const remainingFiles = await readdir(testDir);
81
-
82
- // Expected files after cleanup:
83
- // - overview.md (existing)
84
- // - getting-started.md (existing)
85
- // - getting-started.zh.md (existing)
86
- // - _sidebar.md (generated)
87
- // Note: getting-started.en.md may be cleaned up if not needed
88
- // Note: overview.zh.md and overview.en.md are not created by saveDocs,
89
- // they would be created by saveDocWithTranslations when content is generated
90
- const expectedFiles = [
91
- "overview.md",
92
- "getting-started.md",
93
- "getting-started.zh.md",
94
- "_sidebar.md",
95
- ];
96
-
97
- const missingFiles = expectedFiles.filter((file) => !remainingFiles.includes(file));
98
- const extraFiles = remainingFiles.filter((file) => !expectedFiles.includes(file));
99
-
100
- expect(missingFiles).toHaveLength(0);
101
- expect(extraFiles).toHaveLength(0);
102
-
103
- // Verify that invalid files were deleted
104
- const deletedFiles = ["old-file.md", "another-old-file.md", "old-translation.zh.md"];
105
- const stillExist = deletedFiles.filter((file) => remainingFiles.includes(file));
106
-
107
- expect(stillExist).toHaveLength(0);
108
- });
109
- });
@@ -1,315 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test";
2
- import fs from "node:fs";
3
- import * as path from "node:path";
4
- import saveOutput from "../../../agents/utils/save-output.mjs";
5
-
6
- describe("saveOutput utility", () => {
7
- let mkdirSpy;
8
- let writeFileSpy;
9
- let joinSpy;
10
- let consoleWarnSpy;
11
-
12
- beforeEach(() => {
13
- // Spy on fs.promises methods
14
- mkdirSpy = spyOn(fs.promises, "mkdir").mockResolvedValue();
15
- writeFileSpy = spyOn(fs.promises, "writeFile").mockResolvedValue();
16
-
17
- // Spy on path methods
18
- joinSpy = spyOn(path, "join").mockImplementation((...paths) => paths.join("/"));
19
-
20
- // Spy on console.warn
21
- consoleWarnSpy = spyOn(console, "warn").mockImplementation(() => {});
22
- });
23
-
24
- afterEach(() => {
25
- // Restore all spies
26
- mkdirSpy?.mockRestore();
27
- writeFileSpy?.mockRestore();
28
- joinSpy?.mockRestore();
29
- consoleWarnSpy?.mockRestore();
30
- });
31
-
32
- // SUCCESSFUL SAVE TESTS
33
- test("should save string content successfully", async () => {
34
- const result = await saveOutput({
35
- savePath: "/output/dir",
36
- fileName: "result.txt",
37
- saveKey: "textContent",
38
- textContent: "Hello, World!",
39
- });
40
-
41
- expect(mkdirSpy).toHaveBeenCalledWith("/output/dir", { recursive: true });
42
- expect(joinSpy).toHaveBeenCalledWith("/output/dir", "result.txt");
43
- expect(writeFileSpy).toHaveBeenCalledWith("/output/dir/result.txt", "Hello, World!", "utf8");
44
- expect(result).toEqual({
45
- saveOutputStatus: true,
46
- saveOutputPath: "/output/dir/result.txt",
47
- });
48
- });
49
-
50
- test("should save object content as formatted JSON", async () => {
51
- const objectData = {
52
- title: "Test Document",
53
- tags: ["test", "sample"],
54
- metadata: { version: 1 },
55
- };
56
-
57
- const result = await saveOutput({
58
- savePath: "/data",
59
- fileName: "config.json",
60
- saveKey: "configData",
61
- configData: objectData,
62
- });
63
-
64
- const expectedContent = JSON.stringify(objectData, null, 2);
65
- expect(writeFileSpy).toHaveBeenCalledWith("/data/config.json", expectedContent, "utf8");
66
- expect(result.saveOutputStatus).toBe(true);
67
- expect(result.saveOutputPath).toBe("/data/config.json");
68
- });
69
-
70
- test("should save number content as string", async () => {
71
- const result = await saveOutput({
72
- savePath: "/numbers",
73
- fileName: "count.txt",
74
- saveKey: "count",
75
- count: 42,
76
- });
77
-
78
- expect(writeFileSpy).toHaveBeenCalledWith("/numbers/count.txt", "42", "utf8");
79
- expect(result.saveOutputStatus).toBe(true);
80
- });
81
-
82
- test("should save boolean content as string", async () => {
83
- const result = await saveOutput({
84
- savePath: "/flags",
85
- fileName: "flag.txt",
86
- saveKey: "isEnabled",
87
- isEnabled: true,
88
- });
89
-
90
- expect(writeFileSpy).toHaveBeenCalledWith("/flags/flag.txt", "true", "utf8");
91
- expect(result.saveOutputStatus).toBe(true);
92
- });
93
-
94
- test("should save array content as formatted JSON", async () => {
95
- const arrayData = ["item1", "item2", { nested: "object" }];
96
-
97
- const result = await saveOutput({
98
- savePath: "/arrays",
99
- fileName: "list.json",
100
- saveKey: "items",
101
- items: arrayData,
102
- });
103
-
104
- const expectedContent = JSON.stringify(arrayData, null, 2);
105
- expect(writeFileSpy).toHaveBeenCalledWith("/arrays/list.json", expectedContent, "utf8");
106
- expect(result.saveOutputStatus).toBe(true);
107
- });
108
-
109
- // NULL AND UNDEFINED HANDLING
110
- test("should handle null values by converting to JSON string", async () => {
111
- const result = await saveOutput({
112
- savePath: "/null-test",
113
- fileName: "null.json",
114
- saveKey: "nullValue",
115
- nullValue: null,
116
- });
117
-
118
- expect(writeFileSpy).toHaveBeenCalledWith("/null-test/null.json", "null", "utf8");
119
- expect(result.saveOutputStatus).toBe(true);
120
- });
121
-
122
- test("should handle undefined values by converting to string", async () => {
123
- const result = await saveOutput({
124
- savePath: "/undefined-test",
125
- fileName: "undefined.txt",
126
- saveKey: "undefinedValue",
127
- undefinedValue: undefined,
128
- });
129
-
130
- expect(writeFileSpy).toHaveBeenCalledWith("/undefined-test/undefined.txt", "undefined", "utf8");
131
- expect(result.saveOutputStatus).toBe(true);
132
- });
133
-
134
- // MISSING SAVE KEY TESTS
135
- test("should warn and return false when saveKey is not found", async () => {
136
- const result = await saveOutput({
137
- savePath: "/output",
138
- fileName: "missing.txt",
139
- saveKey: "nonExistentKey",
140
- existingKey: "some value",
141
- });
142
-
143
- expect(consoleWarnSpy).toHaveBeenCalledWith(
144
- 'saveKey "nonExistentKey" not found in input, skip saving.',
145
- );
146
- expect(result).toEqual({
147
- saveOutputStatus: false,
148
- saveOutputPath: null,
149
- });
150
- expect(mkdirSpy).not.toHaveBeenCalled();
151
- expect(writeFileSpy).not.toHaveBeenCalled();
152
- });
153
-
154
- test("should not save when saveKey exists but is undefined", async () => {
155
- const result = await saveOutput({
156
- savePath: "/output",
157
- fileName: "test.txt",
158
- saveKey: "undefinedKey",
159
- // undefinedKey is not provided, so it will be undefined
160
- });
161
-
162
- expect(consoleWarnSpy).toHaveBeenCalledWith(
163
- 'saveKey "undefinedKey" not found in input, skip saving.',
164
- );
165
- expect(result.saveOutputStatus).toBe(false);
166
- });
167
-
168
- // COMPLEX PATH HANDLING
169
- test("should handle nested directory paths", async () => {
170
- await saveOutput({
171
- savePath: "/deep/nested/directory/structure",
172
- fileName: "file.txt",
173
- saveKey: "content",
174
- content: "test content",
175
- });
176
-
177
- expect(mkdirSpy).toHaveBeenCalledWith("/deep/nested/directory/structure", {
178
- recursive: true,
179
- });
180
- expect(joinSpy).toHaveBeenCalledWith("/deep/nested/directory/structure", "file.txt");
181
- });
182
-
183
- test("should handle paths with special characters", async () => {
184
- await saveOutput({
185
- savePath: "/path with spaces/特殊字符/symbols!@#",
186
- fileName: "file-name_with-symbols.json",
187
- saveKey: "data",
188
- data: { test: "value" },
189
- });
190
-
191
- expect(mkdirSpy).toHaveBeenCalledWith("/path with spaces/特殊字符/symbols!@#", {
192
- recursive: true,
193
- });
194
- expect(joinSpy).toHaveBeenCalledWith(
195
- "/path with spaces/特殊字符/symbols!@#",
196
- "file-name_with-symbols.json",
197
- );
198
- });
199
-
200
- // EMPTY AND EDGE CASES
201
- test("should save empty string content", async () => {
202
- const result = await saveOutput({
203
- savePath: "/empty",
204
- fileName: "empty.txt",
205
- saveKey: "emptyString",
206
- emptyString: "",
207
- });
208
-
209
- expect(writeFileSpy).toHaveBeenCalledWith("/empty/empty.txt", "", "utf8");
210
- expect(result.saveOutputStatus).toBe(true);
211
- });
212
-
213
- test("should save empty object as formatted JSON", async () => {
214
- const result = await saveOutput({
215
- savePath: "/empty",
216
- fileName: "empty.json",
217
- saveKey: "emptyObject",
218
- emptyObject: {},
219
- });
220
-
221
- expect(writeFileSpy).toHaveBeenCalledWith("/empty/empty.json", "{}", "utf8");
222
- expect(result.saveOutputStatus).toBe(true);
223
- });
224
-
225
- test("should save empty array as formatted JSON", async () => {
226
- const result = await saveOutput({
227
- savePath: "/empty",
228
- fileName: "empty-array.json",
229
- saveKey: "emptyArray",
230
- emptyArray: [],
231
- });
232
-
233
- expect(writeFileSpy).toHaveBeenCalledWith("/empty/empty-array.json", "[]", "utf8");
234
- expect(result.saveOutputStatus).toBe(true);
235
- });
236
-
237
- // COMPLEX OBJECT SERIALIZATION
238
- test("should handle complex nested objects", async () => {
239
- const complexObject = {
240
- users: [
241
- { id: 1, name: "Alice", settings: { theme: "dark", notifications: true } },
242
- { id: 2, name: "Bob", settings: { theme: "light", notifications: false } },
243
- ],
244
- metadata: {
245
- version: "1.0.0",
246
- created: "2024-01-01",
247
- features: ["auth", "api", "ui"],
248
- },
249
- };
250
-
251
- const result = await saveOutput({
252
- savePath: "/complex",
253
- fileName: "data.json",
254
- saveKey: "complexData",
255
- complexData: complexObject,
256
- });
257
-
258
- const expectedContent = JSON.stringify(complexObject, null, 2);
259
- expect(writeFileSpy).toHaveBeenCalledWith("/complex/data.json", expectedContent, "utf8");
260
- expect(result.saveOutputStatus).toBe(true);
261
- });
262
-
263
- // MULTIPLE KEYS IN INPUT
264
- test("should only save the specified saveKey among multiple keys", async () => {
265
- const result = await saveOutput({
266
- savePath: "/selective",
267
- fileName: "selected.txt",
268
- saveKey: "targetKey",
269
- targetKey: "This should be saved",
270
- otherKey: "This should be ignored",
271
- anotherKey: { ignored: "data" },
272
- });
273
-
274
- expect(writeFileSpy).toHaveBeenCalledWith(
275
- "/selective/selected.txt",
276
- "This should be saved",
277
- "utf8",
278
- );
279
- expect(result.saveOutputStatus).toBe(true);
280
- });
281
-
282
- // FUNCTION CONTENT HANDLING
283
- test("should convert function to string", async () => {
284
- const testFunction = function testFn() {
285
- return "hello";
286
- };
287
-
288
- const result = await saveOutput({
289
- savePath: "/functions",
290
- fileName: "function.txt",
291
- saveKey: "fn",
292
- fn: testFunction,
293
- });
294
-
295
- expect(writeFileSpy).toHaveBeenCalledWith(
296
- "/functions/function.txt",
297
- testFunction.toString(),
298
- "utf8",
299
- );
300
- expect(result.saveOutputStatus).toBe(true);
301
- });
302
-
303
- // ZERO VALUES
304
- test("should save zero values correctly", async () => {
305
- const result = await saveOutput({
306
- savePath: "/zeros",
307
- fileName: "zero.txt",
308
- saveKey: "zeroValue",
309
- zeroValue: 0,
310
- });
311
-
312
- expect(writeFileSpy).toHaveBeenCalledWith("/zeros/zero.txt", "0", "utf8");
313
- expect(result.saveOutputStatus).toBe(true);
314
- });
315
- });