testeranto 0.134.0 → 0.140.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 (221) hide show
  1. package/.aider.chat.history.md +14577 -0
  2. package/.aider.input.history +566 -0
  3. package/.aider.tags.cache.v3/{8d/fa/12860238755bcfab9af8a93c52ab.val → bd/91/b71f967fd074cf4b757081b429b7.val} +0 -0
  4. package/.aider.tags.cache.v3/cache.db +0 -0
  5. package/.aider.tags.cache.v3/{18/8b/7dfca822129dad10b5cacadf7728.val → fb/96/b0f91c7e75e08fc5a6907633cf99.val} +0 -0
  6. package/README.md +29 -423
  7. package/bundle.js +1 -1
  8. package/dist/common/src/CoreTypes.js +2 -0
  9. package/dist/common/src/Init.js +4 -1
  10. package/dist/common/src/Node.js +1 -1
  11. package/dist/common/src/PM/PM_WithEslintAndTsc.js +10 -8
  12. package/dist/common/src/PM/__tests__/nodeSidecar.testeranto.js +2 -2
  13. package/dist/common/src/PM/main.js +12 -7
  14. package/dist/common/src/PM/node.js +10 -3
  15. package/dist/common/src/Web.js +2 -2
  16. package/dist/common/src/build.js +7 -72
  17. package/dist/common/src/defaultConfig.js +0 -1
  18. package/dist/common/src/esbuildConfigs/eslint-formatter-testeranto.js +16 -1
  19. package/dist/common/src/esbuildConfigs/node.js +2 -16
  20. package/dist/common/src/esbuildConfigs/pure.js +2 -16
  21. package/dist/common/src/esbuildConfigs/rebuildPlugin.js +22 -0
  22. package/dist/common/src/esbuildConfigs/web.js +2 -16
  23. package/dist/common/src/lib/abstractBase.js +8 -1
  24. package/dist/common/src/lib/basebuilder.js +4 -0
  25. package/dist/common/src/lib/classBuilder.js +2 -3
  26. package/dist/common/src/lib/core.js +2 -0
  27. package/dist/common/src/run.js +1 -1
  28. package/dist/common/src/utils/buildTemplates.js +88 -0
  29. package/dist/common/tsconfig.common.tsbuildinfo +1 -1
  30. package/dist/module/src/Init.js +4 -1
  31. package/dist/module/src/Node.js +1 -1
  32. package/dist/module/src/PM/PM_WithEslintAndTsc.js +10 -8
  33. package/dist/module/src/PM/__tests__/nodeSidecar.testeranto.js +2 -2
  34. package/dist/module/src/PM/main.js +12 -7
  35. package/dist/module/src/PM/node.js +10 -3
  36. package/dist/module/src/Project.js +41 -47
  37. package/dist/module/src/TestReport.js +34 -31
  38. package/dist/module/src/Web.js +2 -2
  39. package/dist/module/src/build.js +7 -72
  40. package/dist/module/src/defaultConfig.js +0 -1
  41. package/dist/module/src/esbuildConfigs/eslint-formatter-testeranto.js +16 -1
  42. package/dist/module/src/esbuildConfigs/node.js +2 -16
  43. package/dist/module/src/esbuildConfigs/pure.js +2 -16
  44. package/dist/module/src/esbuildConfigs/rebuildPlugin.js +17 -0
  45. package/dist/module/src/esbuildConfigs/web.js +2 -16
  46. package/dist/module/src/lib/abstractBase.js +8 -1
  47. package/dist/module/src/lib/basebuilder.js +4 -0
  48. package/dist/module/src/lib/classBuilder.js +2 -3
  49. package/dist/module/src/lib/core.js +2 -0
  50. package/dist/module/src/run.js +1 -1
  51. package/dist/module/src/utils/buildTemplates.js +82 -0
  52. package/dist/module/tsconfig.module.tsbuildinfo +1 -1
  53. package/dist/prebuild/Project.js +77 -29
  54. package/dist/prebuild/TestReport.js +51 -32
  55. package/dist/prebuild/build.mjs +132 -131
  56. package/dist/prebuild/esbuildConfigs/eslint-formatter-testeranto.mjs +14 -1
  57. package/dist/prebuild/init-docs.mjs +0 -4
  58. package/dist/prebuild/run.mjs +50 -31
  59. package/dist/tsconfig.tsbuildinfo +1 -0
  60. package/dist/types/src/CoreTypes.d.ts +53 -0
  61. package/dist/types/src/Node.d.ts +3 -3
  62. package/dist/types/src/PM/__tests__/nodeSidecar.testeranto.d.ts +2 -4
  63. package/dist/types/src/PM/__tests__/pureSidecar.testeranto.d.ts +2 -4
  64. package/dist/types/src/PM/__tests__/webSidecar.testeranto.d.ts +2 -4
  65. package/dist/types/src/PM/index.d.ts +1 -1
  66. package/dist/types/src/PM/nodeSidecar.d.ts +2 -2
  67. package/dist/types/src/Pure.d.ts +3 -3
  68. package/dist/types/src/Types.d.ts +21 -61
  69. package/dist/types/src/Web.d.ts +3 -3
  70. package/dist/types/src/esbuildConfigs/rebuildPlugin.d.ts +6 -0
  71. package/dist/types/src/lib/abstractBase.d.ts +10 -16
  72. package/dist/types/src/lib/basebuilder.d.ts +3 -3
  73. package/dist/types/src/lib/classBuilder.d.ts +2 -2
  74. package/dist/types/src/lib/core.d.ts +2 -2
  75. package/dist/types/src/lib/index.d.ts +7 -6
  76. package/dist/types/src/lib/types.d.ts +8 -8
  77. package/dist/types/src/mothership/test.d.ts +2 -2
  78. package/dist/types/src/utils/buildTemplates.d.ts +3 -0
  79. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  80. package/docs/index.md +567 -0
  81. package/docs/style.md +116 -0
  82. package/docs.html +537 -0
  83. package/example.css +351 -0
  84. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Black.ttf +0 -0
  85. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Bold.ttf +0 -0
  86. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-ExtraBold.ttf +0 -0
  87. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Light.ttf +0 -0
  88. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Medium.ttf +0 -0
  89. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Regular.ttf +0 -0
  90. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Thin.ttf +0 -0
  91. package/fonts/M_PLUS_Rounded_1c/OFL.txt +91 -0
  92. package/index.html +245 -24
  93. package/logo.svg +72 -0
  94. package/package.json +11 -2
  95. package/scripts/compile-docs.js +89 -0
  96. package/src/CoreTypes.ts +152 -0
  97. package/src/Init.ts +4 -4
  98. package/src/Node.ts +13 -13
  99. package/src/PM/PM_WithEslintAndTsc.ts +46 -15
  100. package/src/PM/__tests__/nodeSidecar.testeranto.ts +13 -20
  101. package/src/PM/__tests__/pureSidecar.testeranto.ts +8 -15
  102. package/src/PM/__tests__/webSidecar.testeranto.ts +8 -15
  103. package/src/PM/index.ts +1 -1
  104. package/src/PM/main.ts +17 -16
  105. package/src/PM/node.ts +10 -10
  106. package/src/PM/nodeSidecar.ts +2 -2
  107. package/src/PM/pure.ts +0 -4
  108. package/src/Project.tsx +289 -292
  109. package/src/Pure.ts +13 -14
  110. package/src/PureSidecar.ts +1 -0
  111. package/src/TestReport.tsx +179 -165
  112. package/src/Types.ts +52 -151
  113. package/src/Web.ts +15 -14
  114. package/src/build.ts +22 -72
  115. package/src/defaultConfig.ts +2 -1
  116. package/src/esbuildConfigs/eslint-formatter-testeranto.ts +17 -1
  117. package/src/esbuildConfigs/node.ts +2 -18
  118. package/src/esbuildConfigs/pure.ts +2 -18
  119. package/src/esbuildConfigs/rebuildPlugin.ts +23 -0
  120. package/src/esbuildConfigs/web.ts +2 -18
  121. package/src/lib/BaseSuite.test.ts +457 -0
  122. package/src/lib/BaseSuite.ts +155 -0
  123. package/src/lib/abstractBase.ts +13 -163
  124. package/src/lib/basebuilder.ts +11 -11
  125. package/src/lib/classBuilder.ts +13 -7
  126. package/src/lib/core.ts +13 -17
  127. package/src/lib/index.ts +21 -24
  128. package/src/lib/types.ts +23 -9
  129. package/src/mothership/test.ts +13 -10
  130. package/src/run.ts +1 -1
  131. package/src/style.css +1 -1
  132. package/src/utils/buildTemplates.ts +88 -0
  133. package/style.css +496 -0
  134. package/testeranto/bundles/node/{mothership/chunk-V2EQEXU2.mjs → allTests/chunk-4PJCC2XT.mjs} +66 -59
  135. package/testeranto/bundles/node/allTests/metafile.json +4151 -0
  136. package/testeranto/bundles/node/allTests/src/PM/__tests__/nodeSidecar.testeranto.mjs +187 -0
  137. package/testeranto/bundles/node/{mothership → allTests}/src/PM/__tests__/pureSidecar.testeranto.mjs +1 -1
  138. package/testeranto/bundles/node/{mothership → allTests}/src/PM/__tests__/webSidecar.testeranto.mjs +1 -1
  139. package/testeranto/bundles/node/allTests/src/lib/BaseSuite.test.mjs +305 -0
  140. package/testeranto/bundles/node/{mothership → allTests}/src/mothership/test.mjs +1 -1
  141. package/testeranto/dev.html +29 -0
  142. package/testeranto/index.html +28 -27
  143. package/testeranto/reports/allTests/config.json +57 -0
  144. package/testeranto/reports/{mothership/index.html → allTests/dev.html} +2 -0
  145. package/testeranto/reports/allTests/index.html +26 -0
  146. package/testeranto/reports/{mothership/src/PM/__tests__/sidecar.testeranto/node/index.html → allTests/src/PM/__tests__/nodeSidecar.testeranto/node/dev.html} +4 -3
  147. package/testeranto/reports/allTests/src/PM/__tests__/nodeSidecar.testeranto/node/index.html +21 -0
  148. package/testeranto/reports/allTests/src/PM/__tests__/nodeSidecar.testeranto/node/lint_errors.json +80 -0
  149. package/testeranto/reports/allTests/src/PM/__tests__/nodeSidecar.testeranto/node/message +1 -0
  150. package/testeranto/reports/allTests/src/PM/__tests__/nodeSidecar.testeranto/node/prompt.txt +8 -0
  151. package/testeranto/reports/allTests/src/PM/__tests__/nodeSidecar.testeranto/node/type_errors.txt +28 -0
  152. package/testeranto/reports/{mothership/src/PM/__tests__/webSidecar.testeranto/node/index.html → allTests/src/PM/__tests__/pureSidecar.testeranto/node/dev.html} +4 -3
  153. package/testeranto/reports/allTests/src/PM/__tests__/pureSidecar.testeranto/node/index.html +21 -0
  154. package/testeranto/reports/{mothership → allTests}/src/PM/__tests__/pureSidecar.testeranto/node/lint_errors.json +12 -12
  155. package/testeranto/reports/allTests/src/PM/__tests__/pureSidecar.testeranto/node/message +1 -0
  156. package/testeranto/reports/allTests/src/PM/__tests__/pureSidecar.testeranto/node/prompt.txt +8 -0
  157. package/testeranto/reports/allTests/src/PM/__tests__/pureSidecar.testeranto/node/type_errors.txt +32 -0
  158. package/testeranto/reports/{mothership/src/PM/__tests__/nodeSidecar.testeranto/node/index.html → allTests/src/PM/__tests__/webSidecar.testeranto/node/dev.html} +4 -3
  159. package/testeranto/reports/allTests/src/PM/__tests__/webSidecar.testeranto/node/index.html +21 -0
  160. package/testeranto/reports/{mothership → allTests}/src/PM/__tests__/webSidecar.testeranto/node/lint_errors.json +12 -12
  161. package/testeranto/reports/allTests/src/PM/__tests__/webSidecar.testeranto/node/message +1 -0
  162. package/testeranto/reports/allTests/src/PM/__tests__/webSidecar.testeranto/node/prompt.txt +8 -0
  163. package/testeranto/reports/allTests/src/PM/__tests__/webSidecar.testeranto/node/type_errors.txt +32 -0
  164. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/console_log.txt +35 -0
  165. package/testeranto/reports/{mothership/src/PM/__tests__/pureSidecar.testeranto/node/index.html → allTests/src/lib/BaseSuite.test/node/dev.html} +4 -3
  166. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/index.html +21 -0
  167. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/lint_errors.json +608 -0
  168. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/message +1 -0
  169. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/prompt.txt +7 -0
  170. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/type_errors.txt +68 -0
  171. package/testeranto/reports/allTests/src/mothership/test/node/dev.html +21 -0
  172. package/testeranto/reports/allTests/src/mothership/test/node/index.html +21 -0
  173. package/testeranto/reports/allTests/src/mothership/test/node/message +1 -0
  174. package/testeranto/reports/allTests/src/mothership/test/node/prompt.txt +8 -0
  175. package/testeranto/reports/allTests/src/mothership/test/node/type_errors.txt +24 -0
  176. package/testeranto/reports/allTests/summary.json +37 -0
  177. package/testeranto.config.ts +16 -26
  178. package/tsc.log +66 -69
  179. package/.aider.tags.cache.v3/cache.db-shm +0 -0
  180. package/.aider.tags.cache.v3/cache.db-wal +0 -0
  181. package/dist/common/src/SP__Polygon.test.js +0 -10
  182. package/dist/module/src/ReportClient.js +0 -132
  183. package/dist/module/src/SP__Polygon.test.js +0 -8
  184. package/dist/prebuild/ReportClient.js +0 -3
  185. package/src/ReportClient.tsx +0 -164
  186. package/src/SP__Polygon.test.ts +0 -13
  187. package/testeranto/ReportClient.css +0 -11367
  188. package/testeranto/ReportClient.js +0 -24641
  189. package/testeranto/bundles/node/mothership/metafile.json +0 -389
  190. package/testeranto/bundles/node/mothership/src/PM/__tests__/nodeSidecar.testeranto.mjs +0 -1219
  191. package/testeranto/bundles/node/mothership/src/PM/__tests__/sidecar.testeranto.mjs +0 -1199
  192. package/testeranto/reports/mothership/config.json +0 -25
  193. package/testeranto/reports/mothership/src/PM/__tests__/nodeSidecar.testeranto/node/console_log.txt +0 -0
  194. package/testeranto/reports/mothership/src/PM/__tests__/nodeSidecar.testeranto/node/lint_errors.json +0 -1564
  195. package/testeranto/reports/mothership/src/PM/__tests__/nodeSidecar.testeranto/node/prompt.txt +0 -22
  196. package/testeranto/reports/mothership/src/PM/__tests__/nodeSidecar.testeranto/node/type_errors.txt +0 -35
  197. package/testeranto/reports/mothership/src/PM/__tests__/pureSidecar.testeranto/node/prompt.txt +0 -12
  198. package/testeranto/reports/mothership/src/PM/__tests__/pureSidecar.testeranto/node/type_errors.txt +0 -26
  199. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/bdd_errors.txt +0 -1
  200. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/console_log.txt +0 -0
  201. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/lint_errors.json +0 -1564
  202. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/log.txt +0 -0
  203. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/prompt.txt +0 -22
  204. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/tests.json +0 -56
  205. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/type_errors.txt +0 -29
  206. package/testeranto/reports/mothership/src/PM/__tests__/webSidecar.testeranto/node/prompt.txt +0 -12
  207. package/testeranto/reports/mothership/src/PM/__tests__/webSidecar.testeranto/node/type_errors.txt +0 -26
  208. package/testeranto/reports/mothership/src/mothership/test/node/bdd_errors.txt +0 -1
  209. package/testeranto/reports/mothership/src/mothership/test/node/console_log.txt +0 -4
  210. package/testeranto/reports/mothership/src/mothership/test/node/index.html +0 -20
  211. package/testeranto/reports/mothership/src/mothership/test/node/log.txt +0 -0
  212. package/testeranto/reports/mothership/src/mothership/test/node/prompt.txt +0 -12
  213. package/testeranto/reports/mothership/src/mothership/test/node/tests.json +0 -24
  214. package/testeranto/reports/mothership/src/mothership/test/node/type_errors.txt +0 -18
  215. package/testeranto/reports/mothership/summary.json +0 -9
  216. /package/dist/{types/src/SP__Polygon.test.d.ts → module/src/CoreTypes.js} +0 -0
  217. /package/testeranto/bundles/node/{mothership → allTests}/chunk-PG6KUKNP.mjs +0 -0
  218. /package/testeranto/bundles/pure/{mothership → allTests}/metafile.json +0 -0
  219. /package/testeranto/bundles/web/{mothership → allTests}/metafile.json +0 -0
  220. /package/testeranto/reports/{mothership/src/PM/__tests__/nodeSidecar.testeranto → allTests/src/lib/BaseSuite.test}/node/log.txt +0 -0
  221. /package/testeranto/reports/{mothership → allTests}/src/mothership/test/node/lint_errors.json +0 -0
@@ -20,7 +20,10 @@ export default async () => {
20
20
  }
21
21
  });
22
22
  fs.copyFileSync(`node_modules/testeranto/dist/prebuild/Project.js`, `testeranto/Project.js`);
23
- fs.copyFileSync(`node_modules/testeranto/dist/prebuild/ReportClient.js`, `testeranto/ReportClient.js`);
23
+ // fs.copyFileSync(
24
+ // `node_modules/testeranto/dist/prebuild/ReportClient.js`,
25
+ // `testeranto/ReportClient.js`
26
+ // );
24
27
  fs.copyFileSync(`node_modules/testeranto/dist/prebuild/Project.css`, `testeranto/Project.css`);
25
28
  // fs.copyFileSync(
26
29
  // `node_modules/testeranto/dist/prebuild/ReportClient.css`,
@@ -44,6 +44,6 @@ const testeranto = async (input, testSpecification, testImplementation, testInte
44
44
  // });
45
45
  // });
46
46
  }
47
- return t;
47
+ // return t;
48
48
  };
49
49
  export default testeranto;
@@ -66,8 +66,12 @@ export class PM_WithEslintAndTsc extends PM_Base {
66
66
  this.makePrompt = async (entryPoint, addableFiles, platform) => {
67
67
  this.summary[entryPoint].prompt = "?";
68
68
  const promptPath = promptPather(entryPoint, platform, this.name);
69
- const testPaths = path.join("testeranto", "reports", this.name, platform, entryPoint.split(".").slice(0, -1).join("."), `tests.json`);
69
+ const testPaths = path.join("testeranto", "reports", this.name, entryPoint.split(".").slice(0, -1).join("."), platform, `tests.json`);
70
70
  const featuresPath = path.join("testeranto", "reports", this.name, platform, entryPoint.split(".").slice(0, -1).join("."), `featurePrompt.txt`);
71
+ const logPath = path.join("testeranto", "reports", this.name, entryPoint.split(".").slice(0, -1).join("."), platform, `console_log.txt`);
72
+ const lintPath = path.join("testeranto", "reports", this.name, entryPoint.split(".").slice(0, -1).join("."), platform, `lint_errors.json`);
73
+ const typePath = path.join("testeranto", "reports", this.name, entryPoint.split(".").slice(0, -1).join("."), platform, `type_errors.txt`);
74
+ const messagePath = path.join("testeranto", "reports", this.name, entryPoint.split(".").slice(0, -1).join("."), platform, `message`);
71
75
  fs.writeFileSync(promptPath, `
72
76
  ${addableFiles
73
77
  .map((x) => {
@@ -75,14 +79,12 @@ ${addableFiles
75
79
  })
76
80
  .join("\n")}
77
81
 
78
- /read ${lintPather(entryPoint, platform, this.name)}
79
- /read ${tscPather(entryPoint, platform, this.name)}
80
82
  /read ${testPaths}
81
-
82
- /load ${featuresPath}
83
-
84
- /code Fix the failing tests described in ${testPaths}. Correct any type signature errors described in the files ${tscPather(entryPoint, platform, this.name)}. Implement any method which throws "Function not implemented. Resolve the lint errors described in ${lintPather(entryPoint, platform, this.name)}"
85
- `);
83
+ /read ${logPath}
84
+ /read ${typePath}
85
+ /read ${lintPath}
86
+ `);
87
+ fs.writeFileSync(messagePath, `Fix the failing tests described in ${testPaths} and ${logPath}. DO NOT refactor beyond what is necessary. Always prefer minimal changes, focusing mostly on keeping the BDD tests passing`);
86
88
  this.summary[entryPoint].prompt = `aider --model deepseek/deepseek-chat --load testeranto/${this.name}/reports/${platform}/${entryPoint
87
89
  .split(".")
88
90
  .slice(0, -1)
@@ -36,7 +36,7 @@ const implementation = {
36
36
  return mockProcess;
37
37
  },
38
38
  addListener: () => mockProcess,
39
- removeListener: () => mockProcess
39
+ removeListener: () => mockProcess,
40
40
  };
41
41
  process = mockProcess;
42
42
  let writeCalled = false;
@@ -58,7 +58,7 @@ const implementation = {
58
58
  removeListener: () => {
59
59
  removeListenerCalled = true;
60
60
  return mockProcess;
61
- }
61
+ },
62
62
  };
63
63
  process = mockProcess;
64
64
  await sidecar.send("test-command", "test");
@@ -273,7 +273,9 @@ export class PM_Main extends PM_WithEslintAndTsc {
273
273
  const builtfile = dest;
274
274
  let haltReturns = false;
275
275
  const ipcfile = "/tmp/tpipe_" + Math.random();
276
- const child = spawn("node", [builtfile, testResources, ipcfile], {
276
+ const child = spawn("node",
277
+ // "node --inspect-brk ",
278
+ [builtfile, testResources, ipcfile], {
277
279
  stdio: ["pipe", "pipe", "pipe", "ipc"],
278
280
  });
279
281
  let buffer = new Buffer("");
@@ -328,7 +330,6 @@ export class PM_Main extends PM_WithEslintAndTsc {
328
330
  oStream.write(`stdout > ${data}`);
329
331
  });
330
332
  child.on("close", (code) => {
331
- console.log("close");
332
333
  oStream.close();
333
334
  server.close();
334
335
  // this.receiveFeaturesV2(reportDest, src, "node");
@@ -347,14 +348,12 @@ export class PM_Main extends PM_WithEslintAndTsc {
347
348
  haltReturns = true;
348
349
  });
349
350
  child.on("exit", (code) => {
350
- console.log("exit");
351
351
  haltReturns = true;
352
352
  for (let i = 0; i <= portsToUse.length; i++) {
353
353
  if (portsToUse[i]) {
354
354
  this.ports[portsToUse[i]] = true; //port is open again
355
355
  }
356
356
  }
357
- console.log("exitthis.ports", this.ports);
358
357
  });
359
358
  child.on("error", (e) => {
360
359
  console.log("error");
@@ -390,7 +389,10 @@ export class PM_Main extends PM_WithEslintAndTsc {
390
389
  files[src] = new Set();
391
390
  }
392
391
  // files[t].add(filepath);
393
- fs.writeFileSync(destFolder + "/manifest.json", JSON.stringify(Array.from(files[src])));
392
+ // fs.writeFileSync(
393
+ // destFolder + "/manifest.json",
394
+ // JSON.stringify(Array.from(files[src]))
395
+ // );
394
396
  delete files[src];
395
397
  Promise.all(screenshots[src] || []).then(() => {
396
398
  delete screenshots[src];
@@ -710,7 +712,10 @@ export class PM_Main extends PM_WithEslintAndTsc {
710
712
  files[src] = new Set();
711
713
  }
712
714
  // files[t].add(filepath);
713
- fs.writeFileSync(destFolder + "/manifest.json", JSON.stringify(Array.from(files[src])));
715
+ // fs.writeFileSync(
716
+ // destFolder + "/manifest.json",
717
+ // JSON.stringify(Array.from(files[src]))
718
+ // );
714
719
  delete files[src];
715
720
  Promise.all(screenshots[src] || []).then(() => {
716
721
  delete screenshots[src];
@@ -931,7 +936,7 @@ export class PM_Main extends PM_WithEslintAndTsc {
931
936
  slowMo: 1,
932
937
  waitForInitialPage: false,
933
938
  executablePath,
934
- headless: false,
939
+ headless: true,
935
940
  dumpio: false,
936
941
  devtools: false,
937
942
  args: [
@@ -144,9 +144,16 @@ export class PM_Node extends PM {
144
144
  if (error) {
145
145
  console.error(`❗️testArtiFactory failed`, targetDir, error);
146
146
  }
147
- fs.writeFileSync(path.resolve(targetDir.split("/").slice(0, -1).join("/"), "manifest"), fPaths.join(`\n`), {
148
- encoding: "utf-8",
149
- });
147
+ // fs.writeFileSync(
148
+ // path.resolve(
149
+ // targetDir.split("/").slice(0, -1).join("/"),
150
+ // "manifest"
151
+ // ),
152
+ // fPaths.join(`\n`),
153
+ // {
154
+ // encoding: "utf-8",
155
+ // }
156
+ // );
150
157
  if (Buffer.isBuffer(value)) {
151
158
  fs.writeFileSync(fPath, value, "binary");
152
159
  res();
@@ -3,23 +3,10 @@ import ReactDom from "react-dom/client";
3
3
  import React, { useEffect, useState } from "react";
4
4
  import { Col, Nav, Row, Tab, Table } from "react-bootstrap";
5
5
  import { Footer } from "./Footer";
6
- import 'bootstrap/dist/css/bootstrap.min.css';
6
+ import "bootstrap/dist/css/bootstrap.min.css";
7
7
  import "./style.css";
8
- // type ICollation = {
9
- // name: string;
10
- // runTime: IRunTime;
11
- // tr: {
12
- // ports: number;
13
- // };
14
- // sidecars: ITestTypes[];
15
- // staticAnalysis: number | "?";
16
- // typeErrors: number | "?";
17
- // bddErrors: number | "?";
18
- // prompt: string | "?";
19
- // };
20
- // type ICollations = ICollation[];
21
8
  const ExternalFeatures = ({ summary }) => {
22
- return React.createElement("div", null,
9
+ return (React.createElement("div", null,
23
10
  React.createElement(Row, null,
24
11
  React.createElement(Tab.Container, { id: "external-features-tab-container" },
25
12
  React.createElement(Row, null,
@@ -37,10 +24,10 @@ const ExternalFeatures = ({ summary }) => {
37
24
  React.createElement(Col, { sm: 3 },
38
25
  React.createElement(Nav, { variant: "pills", className: "flex-column" })),
39
26
  React.createElement(Col, { sm: 9 },
40
- React.createElement(Tab.Content, null)))))))))));
27
+ React.createElement(Tab.Content, null))))))))))));
41
28
  };
42
29
  const Features = ({ summary }) => {
43
- return React.createElement("div", null,
30
+ return (React.createElement("div", null,
44
31
  React.createElement(Table, { striped: true, bordered: true, hover: true },
45
32
  React.createElement("thead", null,
46
33
  React.createElement("tr", null,
@@ -51,28 +38,31 @@ const Features = ({ summary }) => {
51
38
  React.createElement("th", null, "Type errors"),
52
39
  React.createElement("th", null, "prompt"))),
53
40
  React.createElement("tbody", null, ...summary.map((s) => {
54
- return React.createElement(React.Fragment, null,
41
+ return (React.createElement(React.Fragment, null,
55
42
  React.createElement("tr", null,
56
43
  React.createElement("th", null, s[0])),
57
44
  ...s[1].tests.map((t) => {
58
- const x = `${s[0]}/${t[0].split(".").slice(0, -1).join(".")}/${t[1]}`;
45
+ const x = `${s[0]}/${t[0]
46
+ .split(".")
47
+ .slice(0, -1)
48
+ .join(".")}/${t[1]}`;
59
49
  const y = s[2][t[0]];
60
- return React.createElement("tr", null,
50
+ return (React.createElement("tr", null,
61
51
  React.createElement("td", null, t[0]),
62
52
  React.createElement("td", null, t[1]),
63
53
  React.createElement("td", null,
64
- React.createElement("a", { href: `./reports/${x}/index.html` }, y.runTimeError)),
54
+ React.createElement("a", { href: `./asdasasdasdd/reports/${x}/index.html` }, y.runTimeError)),
65
55
  React.createElement("td", null,
66
- React.createElement("a", { href: `./reports/${x}/lint_errors.json` }, y.staticErrors)),
56
+ React.createElement("a", { href: `./testeasdqqweqweranto/reports/${x}/lint_errors.json` }, y.staticErrors)),
67
57
  React.createElement("td", null,
68
- React.createElement("a", { href: `./reports/${x}/type_errors.txt` }, y.typeErrors)),
58
+ React.createElement("a", { href: `./testezxcdcdfranto/reports/${x}/type_errors.txt` }, y.typeErrors)),
69
59
  React.createElement("td", null,
70
- React.createElement("pre", null, s[2][t[0]].prompt)));
71
- }));
72
- }))));
60
+ React.createElement("pre", null, s[2][t[0]].prompt))));
61
+ })));
62
+ })))));
73
63
  };
74
64
  const Docs = ({ summary }) => {
75
- return React.createElement("div", null,
65
+ return (React.createElement("div", null,
76
66
  React.createElement(Tab.Container, { id: "DocsPane-tabs", defaultActiveKey: "external" },
77
67
  React.createElement(Row, null,
78
68
  React.createElement(Col, { sm: 12 },
@@ -88,12 +78,12 @@ const Docs = ({ summary }) => {
88
78
  React.createElement(Tab.Pane, { eventKey: `markdown` },
89
79
  React.createElement(ExternalFeatures, { summary: summary })),
90
80
  React.createElement(Tab.Pane, { eventKey: `string` },
91
- React.createElement(ExternalFeatures, { summary: summary })))))));
81
+ React.createElement(ExternalFeatures, { summary: summary }))))))));
92
82
  };
93
83
  const BigBoard = () => {
94
- const bigConfigElement = document.getElementById('bigConfig');
84
+ const bigConfigElement = document.getElementById("bigConfig");
95
85
  if (!bigConfigElement)
96
- throw new Error('bigConfig element not found');
86
+ throw new Error("bigConfig element not found");
97
87
  const projects = JSON.parse(bigConfigElement.innerHTML);
98
88
  const [summary, setSummary] = useState();
99
89
  useEffect(() => {
@@ -101,8 +91,8 @@ const BigBoard = () => {
101
91
  const x = projects.map(async (p) => {
102
92
  return [
103
93
  p,
104
- (await (await fetch(`./reports/${p}/config.json`)).json()),
105
- (await (await fetch(`./reports/${p}/summary.json`)).json())
94
+ (await (await fetch(`./testeranto/reports/${p}/config.json`)).json()),
95
+ (await (await fetch(`./testeranto/reports/${p}/summary.json`)).json()),
106
96
  ];
107
97
  });
108
98
  Promise.all(x).then((v) => {
@@ -128,16 +118,17 @@ const BigBoard = () => {
128
118
  // // } as ICollation
129
119
  // // });
130
120
  function copyToClipboard(text) {
131
- navigator.clipboard.writeText(text)
121
+ navigator.clipboard
122
+ .writeText(text)
132
123
  .then(() => {
133
- console.log('Text copied to clipboard');
124
+ console.log("Text copied to clipboard");
134
125
  })
135
- .catch(err => {
136
- console.error('Error copying text: ', err);
126
+ .catch((err) => {
127
+ console.error("Error copying text: ", err);
137
128
  });
138
129
  }
139
- return React.createElement("div", null,
140
- " ",
130
+ return (React.createElement("div", null,
131
+ " ",
141
132
  React.createElement(Tab.Container, { id: "TestPane-tabs", defaultActiveKey: "tests" },
142
133
  React.createElement(Row, null,
143
134
  React.createElement(Col, { sm: 12 },
@@ -160,21 +151,24 @@ const BigBoard = () => {
160
151
  React.createElement("th", null, "prompt"),
161
152
  React.createElement("th", null, "failing features"))),
162
153
  React.createElement("tbody", null, ...summary.map((s) => {
163
- return React.createElement(React.Fragment, null,
154
+ return (React.createElement(React.Fragment, null,
164
155
  React.createElement("tr", null,
165
156
  React.createElement("th", null, s[0])),
166
157
  ...s[1].tests.map((t) => {
167
- const x = `${s[0]}/${t[0].split(".").slice(0, -1).join(".")}/${t[1]}`;
158
+ const x = `${s[0]}/${t[0]
159
+ .split(".")
160
+ .slice(0, -1)
161
+ .join(".")}/${t[1]}`;
168
162
  const y = s[2][t[0]];
169
- return React.createElement("tr", null,
163
+ return (React.createElement("tr", null,
170
164
  React.createElement("td", null, t[0]),
171
165
  React.createElement("td", null, t[1]),
172
166
  React.createElement("td", null,
173
- React.createElement("a", { href: `./reports/${x}/index.html` }, y.runTimeError)),
167
+ React.createElement("a", { href: `./testeranto/reports/${x}/index.html` }, y.runTimeError)),
174
168
  React.createElement("td", null,
175
- React.createElement("a", { href: `./reports/${x}/lint_errors.json` }, y.staticErrors)),
169
+ React.createElement("a", { href: `./testeranto/reports/${x}/lint_errors.json` }, y.staticErrors)),
176
170
  React.createElement("td", null,
177
- React.createElement("a", { href: `./reports/${x}/type_errors.txt` }, y.typeErrors)),
171
+ React.createElement("a", { href: `./testeranto/reports/${x}/type_errors.txt` }, y.typeErrors)),
178
172
  React.createElement("td", null,
179
173
  React.createElement("pre", null,
180
174
  React.createElement("button", { onClick: () => {
@@ -182,14 +176,14 @@ const BigBoard = () => {
182
176
  } }, "copy"))),
183
177
  React.createElement("td", null,
184
178
  React.createElement("pre", null,
185
- React.createElement("code", null, JSON.stringify(y.failingFeatures, null, 2)))));
186
- }));
179
+ React.createElement("code", null, JSON.stringify(y.failingFeatures, null, 2))))));
180
+ })));
187
181
  })))),
188
182
  React.createElement(Tab.Pane, { eventKey: `features` },
189
183
  React.createElement(Features, { summary: summary })),
190
184
  React.createElement(Tab.Pane, { eventKey: `docs` },
191
185
  React.createElement(Docs, { summary: summary })))))),
192
- React.createElement(Footer, null));
186
+ React.createElement(Footer, null)));
193
187
  };
194
188
  document.addEventListener("DOMContentLoaded", function () {
195
189
  const elem = document.getElementById("root");
@@ -1,46 +1,46 @@
1
1
  import ReactDom from "react-dom/client";
2
2
  import React, { useEffect, useState } from "react";
3
3
  import { Col, Nav, Row, Tab } from "react-bootstrap";
4
- import 'bootstrap/dist/css/bootstrap.min.css';
4
+ import "bootstrap/dist/css/bootstrap.min.css";
5
5
  import "./style.css";
6
6
  import { Footer } from "./Footer";
7
- const StepPane = ({ step }) => {
8
- return React.createElement("div", null,
7
+ const StepPane = ({ step, }) => {
8
+ return (React.createElement("div", null,
9
9
  React.createElement("pre", null,
10
- React.createElement("code", null, JSON.stringify(step, null, 2))));
10
+ React.createElement("code", null, JSON.stringify(step, null, 2)))));
11
11
  };
12
- const TestPane = ({ given }) => {
13
- return React.createElement("div", null,
14
- " ",
12
+ const TestPane = ({ given, }) => {
13
+ return (React.createElement("div", null,
14
+ " ",
15
15
  React.createElement(Tab.Container, { id: "TestPane-tabs", defaultActiveKey: "first" },
16
16
  React.createElement(Row, null,
17
17
  React.createElement(Col, { sm: 3 },
18
18
  React.createElement(Nav, { variant: "pills", className: "flex-column" },
19
19
  React.createElement(Nav.Item, null,
20
20
  React.createElement(Nav.Link, { eventKey: `bdd-features` }, "features"),
21
- ...given.whens.map((w, ndx) => React.createElement(Nav.Link, { eventKey: `bdd-when-${ndx}` },
21
+ ...given.whens.map((w, ndx) => (React.createElement(Nav.Link, { eventKey: `bdd-when-${ndx}` },
22
22
  "When ",
23
23
  w.name,
24
24
  " ",
25
- w.error && "!")),
26
- ...given.thens.map((t, ndx) => React.createElement(Nav.Link, { eventKey: `bdd-then-${ndx}` },
25
+ w.error && "!"))),
26
+ ...given.thens.map((t, ndx) => (React.createElement(Nav.Link, { eventKey: `bdd-then-${ndx}` },
27
27
  "Then ",
28
28
  t.name,
29
29
  " ",
30
- t.error && "!")),
30
+ t.error && "!"))),
31
31
  React.createElement(Nav.Link, { eventKey: `bdd-errors` }, "errors")))),
32
32
  React.createElement(Col, { sm: 6 },
33
33
  React.createElement(Tab.Content, null,
34
34
  React.createElement(Tab.Pane, { eventKey: `bdd-features` },
35
35
  React.createElement("pre", null,
36
36
  React.createElement("code", null, JSON.stringify(given.features, null, 2)))),
37
- ...given.whens.map((w, ndx) => React.createElement(Tab.Pane, { eventKey: `bdd-when-${ndx}` },
38
- React.createElement(StepPane, { step: w }))),
39
- ...given.thens.map((t, ndx) => React.createElement(Tab.Pane, { eventKey: `bdd-then-${ndx}` },
40
- React.createElement(StepPane, { step: t }))),
37
+ ...given.whens.map((w, ndx) => (React.createElement(Tab.Pane, { eventKey: `bdd-when-${ndx}` },
38
+ React.createElement(StepPane, { step: w })))),
39
+ ...given.thens.map((t, ndx) => (React.createElement(Tab.Pane, { eventKey: `bdd-then-${ndx}` },
40
+ React.createElement(StepPane, { step: t })))),
41
41
  React.createElement(Tab.Pane, { eventKey: `bdd-errors` },
42
42
  React.createElement("pre", null,
43
- React.createElement("code", null, JSON.stringify(given.error, null, 2)))))))));
43
+ React.createElement("code", null, JSON.stringify(given.error, null, 2))))))))));
44
44
  };
45
45
  const BddPage = () => {
46
46
  // const [configs, setConfigs] = useState<IBuiltConfig>();
@@ -57,20 +57,23 @@ const BddPage = () => {
57
57
  const [bddErrors, setBddErrors] = useState();
58
58
  useEffect(() => {
59
59
  (async () => {
60
- setBddErrors(await (await fetch(`tests.json`)).json());
60
+ setBddErrors(await (await fetch(`${window.location.href
61
+ .split("/")
62
+ .slice(0, -1)
63
+ .join("/")}/tests.json`)).json());
61
64
  })();
62
65
  }, []);
63
66
  const [log, setLog] = useState();
64
67
  useEffect(() => {
65
68
  (async () => {
66
- setLog(await (await fetch(`log.txt`)).text());
69
+ setLog(await (await fetch(`${window.location.href.split("/").slice(0, -1).join("/")}/log.txt`)).text());
67
70
  })();
68
71
  }, []);
69
- if (!bddErrors || !log) {
72
+ if (bddErrors === undefined || log === undefined) {
70
73
  return React.createElement("div", null, "loading...");
71
74
  }
72
- return React.createElement("div", null,
73
- " ",
75
+ return (React.createElement("div", null,
76
+ " ",
74
77
  React.createElement(Row, null,
75
78
  React.createElement(Col, { sm: 12 },
76
79
  React.createElement("h2", null, bddErrors.name))),
@@ -91,24 +94,24 @@ const BddPage = () => {
91
94
  React.createElement(Tab.Container, { id: "secondary-tab-container", defaultActiveKey: "first" },
92
95
  React.createElement(Row, null,
93
96
  React.createElement(Col, { sm: 3 },
94
- React.createElement(Nav, { variant: "pills", className: "flex-column" }, ...bddErrors.givens.map((g) => React.createElement(Nav.Item, null,
97
+ React.createElement(Nav, { variant: "pills", className: "flex-column" }, ...bddErrors.givens.map((g) => (React.createElement(Nav.Item, null,
95
98
  React.createElement(Nav.Link, { eventKey: g.key },
96
99
  g.key,
97
100
  ": Given ",
98
- g.name))))),
101
+ g.name)))))),
99
102
  React.createElement(Col, { sm: 9 },
100
- React.createElement(Tab.Content, null, ...bddErrors.givens.map((g) => React.createElement(Tab.Pane, { eventKey: g.key },
101
- React.createElement(TestPane, { given: g }))))))))))))),
103
+ React.createElement(Tab.Content, null, ...bddErrors.givens.map((g) => (React.createElement(Tab.Pane, { eventKey: g.key },
104
+ React.createElement(TestPane, { given: g })))))))))))))),
102
105
  React.createElement("div", { style: {
103
- backgroundColor: 'lightgray',
104
- margin: '0.5rem',
105
- padding: '0.5rem',
106
- position: 'fixed',
106
+ backgroundColor: "lightgray",
107
+ margin: "0.5rem",
108
+ padding: "0.5rem",
109
+ position: "fixed",
107
110
  left: 0,
108
- bottom: 0
111
+ bottom: 0,
109
112
  } },
110
113
  React.createElement("a", { href: "/" }, "\uD83C\uDFE0")),
111
- React.createElement(Footer, null));
114
+ React.createElement(Footer, null)));
112
115
  };
113
116
  document.addEventListener("DOMContentLoaded", function () {
114
117
  const elem = document.getElementById("root");
@@ -1,11 +1,11 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
3
  import { PM_Web } from "./PM/web";
2
4
  import Testeranto from "./lib/core.js";
3
5
  import { defaultTestResourceRequirement, } from "./lib/index.js";
4
6
  let errorCallback = (e) => { };
5
7
  let unhandledrejectionCallback = (event) => {
6
8
  console.log("window.addEventListener unhandledrejection", event);
7
- // cb({ error: event.reason.message });
8
- // throw event;
9
9
  };
10
10
  export class WebTesteranto extends Testeranto {
11
11
  constructor(input, testSpecification, testImplementation, testResourceRequirement, testInterface) {
@@ -10,6 +10,7 @@ import esbuildWebConfiger from "./esbuildConfigs/web.js";
10
10
  import esbuildImportConfiger from "./esbuildConfigs/pure.js";
11
11
  import webHtmlFrame from "./web.html.js";
12
12
  import { getRunnables } from "./utils.js";
13
+ import { idkPage, testReportPage, testsReportPage, } from "./utils/buildTemplates.js";
13
14
  readline.emitKeypressEvents(process.stdin);
14
15
  if (process.stdin.isTTY)
15
16
  process.stdin.setRawMode(true);
@@ -106,59 +107,11 @@ import(process.cwd() + "/" + "testeranto.config.ts").then(async (module) => {
106
107
  if (!fs.existsSync(`testeranto/reports/${testName}`)) {
107
108
  fs.mkdirSync(`testeranto/reports/${testName}`);
108
109
  }
109
- fs.writeFileSync(`${process.cwd()}/testeranto/reports/${testName}/index.html`, `
110
- <!DOCTYPE html>
111
- <html lang="en">
112
-
113
- <head>
114
- <meta name="description" content="Webpage description goes here" />
115
- <meta charset="utf-8" />
116
- <title>${pckge.name} - testeranto</title>
117
- <meta name="viewport" content="width=device-width, initial-scale=1" />
118
- <meta name="author" content="" />
119
-
120
- <link rel="stylesheet" href="../ReportClient.css" />
121
- <script type="module" src="../ReportClient.js"></script>
122
-
123
- </head>
124
-
125
- <body>
126
- <div id="root">
127
- react is loading
128
- </div>
129
- </body>
130
-
131
- </html>
132
- `);
110
+ fs.writeFileSync(`${process.cwd()}/testeranto/reports/${testName}/index.html`, testReportPage(pckge.name, bigConfig.reportDomain));
111
+ fs.writeFileSync(`${process.cwd()}/testeranto/reports/${testName}/dev.html`, testReportPage(pckge.name, "/"));
133
112
  fs.writeFileSync(`testeranto/reports/${testName}/config.json`, JSON.stringify(config, null, 2));
134
- fs.writeFileSync(`${process.cwd()}/testeranto/index.html`, `
135
- <!DOCTYPE html>
136
- <html lang="en">
137
-
138
- <head>
139
- <meta name="description" content="Webpage description goes here" />
140
- <meta charset="utf-8" />
141
- <title>${pckge.name} - testeranto</title>
142
- <meta name="viewport" content="width=device-width, initial-scale=1" />
143
- <meta name="author" content="" />
144
-
145
- <script type="application/json" id="bigConfig">
146
- ${JSON.stringify(Object.keys(bigConfig.projects))}
147
- </script>
148
-
149
- <link rel="stylesheet" href="Project.css" />
150
- <script type="module" src="Project.js"></script>
151
-
152
- </head>
153
-
154
- <body>
155
- <div id="root">
156
- react is loading
157
- </div>
158
- </body>
159
-
160
- </html>
161
- `);
113
+ fs.writeFileSync(`${process.cwd()}/testeranto/index.html`, testsReportPage(pckge.name, bigConfig.reportDomain, bigConfig.projects));
114
+ fs.writeFileSync(`${process.cwd()}/testeranto/dev.html`, testsReportPage(pckge.name, "/", bigConfig.projects));
162
115
  Promise.resolve(Promise.all([...getSecondaryEndpointsPoints("web")].map(async (sourceFilePath) => {
163
116
  const sourceFileSplit = sourceFilePath.split("/");
164
117
  const sourceDir = sourceFileSplit.slice(0, -1);
@@ -205,26 +158,8 @@ import(process.cwd() + "/" + "testeranto.config.ts").then(async (module) => {
205
158
  .slice(0, -1)
206
159
  .join(".")}/${runtime}`;
207
160
  await fs.mkdirSync(folder, { recursive: true });
208
- fs.writeFileSync(`${folder}/index.html`, `
209
- <!DOCTYPE html>
210
- <html lang="en">
211
-
212
- <head>
213
- <meta name="description" content="Webpage description goes here" />
214
- <meta charset="utf-8" />
215
- <title>${testName} - testeranto</title>
216
- <meta name="viewport" content="width=device-width, initial-scale=1" />
217
- <meta name="author" content="" />
218
-
219
- <link rel="stylesheet" href="../../../../../../TestReport.css" />
220
- <script src="../../../../../../TestReport.js"></script>
221
-
222
- </head>
223
-
224
- <body>
225
- <div id="root"/>
226
- </body>
227
- `);
161
+ fs.writeFileSync(`${folder}/index.html`, idkPage(testName, bigConfig.reportDomain));
162
+ fs.writeFileSync(`${folder}/dev.html`, idkPage(testName, ""));
228
163
  });
229
164
  });
230
165
  [
@@ -9,7 +9,6 @@ const config = {
9
9
  nodePlugins: [],
10
10
  webPlugins: [],
11
11
  importPlugins: [],
12
- externalTests: {},
13
12
  featureIngestor: function (s) {
14
13
  throw new Error("Function not implemented.");
15
14
  },
@@ -1,3 +1,18 @@
1
1
  export default function (results) {
2
- return JSON.stringify(results, null, 2);
2
+ return results
3
+ .filter((r) => r.messages.length)
4
+ .map((r) => {
5
+ const path = r.filePath.replace(process.cwd() + "/", "");
6
+ return [
7
+ path,
8
+ ...r.messages.map((m) => {
9
+ var _a;
10
+ return [
11
+ `${m.line}:${m.column} ${m.message} (${m.ruleId || ""})`,
12
+ ...(((_a = m.suggestions) === null || _a === void 0 ? void 0 : _a.map((s) => `- ${s.message}${s.fix ? " (fix)" : ""}`)) || []),
13
+ ].join("\n");
14
+ }),
15
+ ].join("\n");
16
+ })
17
+ .join("\n\n");
3
18
  }