@learnpack/learnpack 5.0.362 → 5.0.364

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 (55) hide show
  1. package/lib/commands/serve.js +444 -279
  2. package/lib/creatorDist/assets/{index-B7s5Nmq8.css → index-Cco3XhDR.css} +96 -0
  3. package/lib/creatorDist/assets/{index-CKg5uuoj.js → index-o3Cw0bsF.js} +69620 -66788
  4. package/lib/creatorDist/index.html +2 -2
  5. package/lib/models/creator.d.ts +1 -0
  6. package/lib/utils/api.d.ts +0 -9
  7. package/lib/utils/api.js +1 -65
  8. package/lib/utils/generationRetry.d.ts +48 -0
  9. package/lib/utils/generationRetry.js +81 -0
  10. package/lib/utils/interactivity/componentsGuide.d.ts +50 -0
  11. package/lib/utils/interactivity/componentsGuide.js +193 -0
  12. package/lib/utils/interactivity/interactivityPlan.d.ts +20 -0
  13. package/lib/utils/interactivity/interactivityPlan.js +33 -0
  14. package/lib/utils/interactivity/structuredComponents.d.ts +34 -0
  15. package/lib/utils/interactivity/structuredComponents.js +792 -0
  16. package/lib/utils/rigoActions.d.ts +1 -1
  17. package/lib/utils/rigoActions.js +2 -2
  18. package/package.json +1 -1
  19. package/src/commands/serve.ts +653 -397
  20. package/src/creator/package-lock.json +297 -3
  21. package/src/creator/package.json +1 -0
  22. package/src/creator/src/App.test.tsx +124 -1
  23. package/src/creator/src/App.tsx +52 -36
  24. package/src/creator/src/components/FileCard.tsx +63 -19
  25. package/src/creator/src/components/FileReadListener.test.tsx +128 -0
  26. package/src/creator/src/components/FileReadListener.tsx +75 -0
  27. package/src/creator/src/components/FileReviewModal.test.tsx +193 -0
  28. package/src/creator/src/components/FileReviewModal.tsx +128 -0
  29. package/src/creator/src/components/FileUploader.test.tsx +229 -0
  30. package/src/creator/src/components/FileUploader.tsx +212 -58
  31. package/src/creator/src/components/GenerationErrorCard.tsx +57 -0
  32. package/src/creator/src/components/MarkdownRenderer.tsx +4 -2
  33. package/src/creator/src/components/syllabus/SyllabusEditor.tsx +6 -9
  34. package/src/creator/src/index.css +45 -0
  35. package/src/creator/src/locales/en.json +27 -5
  36. package/src/creator/src/locales/es.json +27 -5
  37. package/src/creator/src/main.tsx +2 -0
  38. package/src/creator/src/utils/completionResult.test.ts +61 -0
  39. package/src/creator/src/utils/completionResult.ts +61 -2
  40. package/src/creator/src/utils/courseLanguage.test.ts +6 -0
  41. package/src/creator/src/utils/creationRequest.test.ts +53 -18
  42. package/src/creator/src/utils/creationRequest.ts +17 -12
  43. package/src/creator/src/utils/fileRead.ts +60 -0
  44. package/src/creator/src/utils/lib.ts +0 -5
  45. package/src/creator/src/utils/store.ts +0 -10
  46. package/src/creatorDist/assets/{index-B7s5Nmq8.css → index-Cco3XhDR.css} +96 -0
  47. package/src/creatorDist/assets/{index-CKg5uuoj.js → index-o3Cw0bsF.js} +69620 -66788
  48. package/src/creatorDist/index.html +2 -2
  49. package/src/models/creator.ts +87 -84
  50. package/src/utils/api.ts +0 -83
  51. package/src/utils/generationRetry.ts +100 -0
  52. package/src/utils/interactivity/componentsGuide.ts +294 -0
  53. package/src/utils/interactivity/interactivityPlan.ts +57 -0
  54. package/src/utils/interactivity/structuredComponents.ts +1004 -0
  55. package/src/utils/rigoActions.ts +3 -2
@@ -30,6 +30,7 @@
30
30
  "react-i18next": "^15.5.2",
31
31
  "react-markdown": "^10.1.0",
32
32
  "react-router": "^7.5.0",
33
+ "remark-gfm": "^4.0.1",
33
34
  "socket.io-client": "^4.8.1",
34
35
  "syllable": "^5.0.1",
35
36
  "tailwind-merge": "^3.3.1",
@@ -5622,6 +5623,16 @@
5622
5623
  "sprintf-js": "~1.0.2"
5623
5624
  }
5624
5625
  },
5626
+ "node_modules/markdown-table": {
5627
+ "version": "3.0.4",
5628
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz",
5629
+ "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==",
5630
+ "license": "MIT",
5631
+ "funding": {
5632
+ "type": "github",
5633
+ "url": "https://github.com/sponsors/wooorm"
5634
+ }
5635
+ },
5625
5636
  "node_modules/math-intrinsics": {
5626
5637
  "version": "1.1.0",
5627
5638
  "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -5631,6 +5642,34 @@
5631
5642
  "node": ">= 0.4"
5632
5643
  }
5633
5644
  },
5645
+ "node_modules/mdast-util-find-and-replace": {
5646
+ "version": "3.0.4",
5647
+ "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.4.tgz",
5648
+ "integrity": "sha512-z4B5c6jrnJ1ltOQemhWYPBSAo6y42Z8Gt2yEgfgNTMcLSU59B8bfj8Z8AnAlJrBGLnqkdAUZ7jdDEqQw3KuipQ==",
5649
+ "license": "MIT",
5650
+ "dependencies": {
5651
+ "@types/mdast": "^4.0.0",
5652
+ "escape-string-regexp": "^5.0.0",
5653
+ "unist-util-is": "^6.0.0",
5654
+ "unist-util-visit-parents": "^6.1.0"
5655
+ },
5656
+ "funding": {
5657
+ "type": "opencollective",
5658
+ "url": "https://opencollective.com/unified"
5659
+ }
5660
+ },
5661
+ "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": {
5662
+ "version": "5.0.0",
5663
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
5664
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
5665
+ "license": "MIT",
5666
+ "engines": {
5667
+ "node": ">=12"
5668
+ },
5669
+ "funding": {
5670
+ "url": "https://github.com/sponsors/sindresorhus"
5671
+ }
5672
+ },
5634
5673
  "node_modules/mdast-util-from-markdown": {
5635
5674
  "version": "2.0.2",
5636
5675
  "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz",
@@ -5655,6 +5694,107 @@
5655
5694
  "url": "https://opencollective.com/unified"
5656
5695
  }
5657
5696
  },
5697
+ "node_modules/mdast-util-gfm": {
5698
+ "version": "3.1.0",
5699
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz",
5700
+ "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==",
5701
+ "license": "MIT",
5702
+ "dependencies": {
5703
+ "mdast-util-from-markdown": "^2.0.0",
5704
+ "mdast-util-gfm-autolink-literal": "^2.0.0",
5705
+ "mdast-util-gfm-footnote": "^2.0.0",
5706
+ "mdast-util-gfm-strikethrough": "^2.0.0",
5707
+ "mdast-util-gfm-table": "^2.0.0",
5708
+ "mdast-util-gfm-task-list-item": "^2.0.0",
5709
+ "mdast-util-to-markdown": "^2.0.0"
5710
+ },
5711
+ "funding": {
5712
+ "type": "opencollective",
5713
+ "url": "https://opencollective.com/unified"
5714
+ }
5715
+ },
5716
+ "node_modules/mdast-util-gfm-autolink-literal": {
5717
+ "version": "2.0.1",
5718
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz",
5719
+ "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==",
5720
+ "license": "MIT",
5721
+ "dependencies": {
5722
+ "@types/mdast": "^4.0.0",
5723
+ "ccount": "^2.0.0",
5724
+ "devlop": "^1.0.0",
5725
+ "mdast-util-find-and-replace": "^3.0.0",
5726
+ "micromark-util-character": "^2.0.0"
5727
+ },
5728
+ "funding": {
5729
+ "type": "opencollective",
5730
+ "url": "https://opencollective.com/unified"
5731
+ }
5732
+ },
5733
+ "node_modules/mdast-util-gfm-footnote": {
5734
+ "version": "2.1.0",
5735
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz",
5736
+ "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==",
5737
+ "license": "MIT",
5738
+ "dependencies": {
5739
+ "@types/mdast": "^4.0.0",
5740
+ "devlop": "^1.1.0",
5741
+ "mdast-util-from-markdown": "^2.0.0",
5742
+ "mdast-util-to-markdown": "^2.0.0",
5743
+ "micromark-util-normalize-identifier": "^2.0.0"
5744
+ },
5745
+ "funding": {
5746
+ "type": "opencollective",
5747
+ "url": "https://opencollective.com/unified"
5748
+ }
5749
+ },
5750
+ "node_modules/mdast-util-gfm-strikethrough": {
5751
+ "version": "2.0.1",
5752
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.1.tgz",
5753
+ "integrity": "sha512-OuJHqvr455pwu2OaOrir7dbzqs4jlWKOtlu9L6GjcIjjQwNyw02VntQsr/Ek6/A13vgnXfUhBekWRUP1OkNivw==",
5754
+ "license": "MIT",
5755
+ "dependencies": {
5756
+ "@types/mdast": "^4.0.0",
5757
+ "mdast-util-from-markdown": "^2.0.0",
5758
+ "mdast-util-to-markdown": "^2.0.0"
5759
+ },
5760
+ "funding": {
5761
+ "type": "opencollective",
5762
+ "url": "https://opencollective.com/unified"
5763
+ }
5764
+ },
5765
+ "node_modules/mdast-util-gfm-table": {
5766
+ "version": "2.0.0",
5767
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz",
5768
+ "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==",
5769
+ "license": "MIT",
5770
+ "dependencies": {
5771
+ "@types/mdast": "^4.0.0",
5772
+ "devlop": "^1.0.0",
5773
+ "markdown-table": "^3.0.0",
5774
+ "mdast-util-from-markdown": "^2.0.0",
5775
+ "mdast-util-to-markdown": "^2.0.0"
5776
+ },
5777
+ "funding": {
5778
+ "type": "opencollective",
5779
+ "url": "https://opencollective.com/unified"
5780
+ }
5781
+ },
5782
+ "node_modules/mdast-util-gfm-task-list-item": {
5783
+ "version": "2.0.0",
5784
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz",
5785
+ "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==",
5786
+ "license": "MIT",
5787
+ "dependencies": {
5788
+ "@types/mdast": "^4.0.0",
5789
+ "devlop": "^1.0.0",
5790
+ "mdast-util-from-markdown": "^2.0.0",
5791
+ "mdast-util-to-markdown": "^2.0.0"
5792
+ },
5793
+ "funding": {
5794
+ "type": "opencollective",
5795
+ "url": "https://opencollective.com/unified"
5796
+ }
5797
+ },
5658
5798
  "node_modules/mdast-util-mdx-expression": {
5659
5799
  "version": "2.0.1",
5660
5800
  "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz",
@@ -5870,6 +6010,127 @@
5870
6010
  "micromark-util-types": "^2.0.0"
5871
6011
  }
5872
6012
  },
6013
+ "node_modules/micromark-extension-gfm": {
6014
+ "version": "3.0.0",
6015
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz",
6016
+ "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==",
6017
+ "license": "MIT",
6018
+ "dependencies": {
6019
+ "micromark-extension-gfm-autolink-literal": "^2.0.0",
6020
+ "micromark-extension-gfm-footnote": "^2.0.0",
6021
+ "micromark-extension-gfm-strikethrough": "^2.0.0",
6022
+ "micromark-extension-gfm-table": "^2.0.0",
6023
+ "micromark-extension-gfm-tagfilter": "^2.0.0",
6024
+ "micromark-extension-gfm-task-list-item": "^2.0.0",
6025
+ "micromark-util-combine-extensions": "^2.0.0",
6026
+ "micromark-util-types": "^2.0.0"
6027
+ },
6028
+ "funding": {
6029
+ "type": "opencollective",
6030
+ "url": "https://opencollective.com/unified"
6031
+ }
6032
+ },
6033
+ "node_modules/micromark-extension-gfm-autolink-literal": {
6034
+ "version": "2.1.0",
6035
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz",
6036
+ "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==",
6037
+ "license": "MIT",
6038
+ "dependencies": {
6039
+ "micromark-util-character": "^2.0.0",
6040
+ "micromark-util-sanitize-uri": "^2.0.0",
6041
+ "micromark-util-symbol": "^2.0.0",
6042
+ "micromark-util-types": "^2.0.0"
6043
+ },
6044
+ "funding": {
6045
+ "type": "opencollective",
6046
+ "url": "https://opencollective.com/unified"
6047
+ }
6048
+ },
6049
+ "node_modules/micromark-extension-gfm-footnote": {
6050
+ "version": "2.1.0",
6051
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz",
6052
+ "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==",
6053
+ "license": "MIT",
6054
+ "dependencies": {
6055
+ "devlop": "^1.0.0",
6056
+ "micromark-core-commonmark": "^2.0.0",
6057
+ "micromark-factory-space": "^2.0.0",
6058
+ "micromark-util-character": "^2.0.0",
6059
+ "micromark-util-normalize-identifier": "^2.0.0",
6060
+ "micromark-util-sanitize-uri": "^2.0.0",
6061
+ "micromark-util-symbol": "^2.0.0",
6062
+ "micromark-util-types": "^2.0.0"
6063
+ },
6064
+ "funding": {
6065
+ "type": "opencollective",
6066
+ "url": "https://opencollective.com/unified"
6067
+ }
6068
+ },
6069
+ "node_modules/micromark-extension-gfm-strikethrough": {
6070
+ "version": "2.1.0",
6071
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz",
6072
+ "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==",
6073
+ "license": "MIT",
6074
+ "dependencies": {
6075
+ "devlop": "^1.0.0",
6076
+ "micromark-util-chunked": "^2.0.0",
6077
+ "micromark-util-classify-character": "^2.0.0",
6078
+ "micromark-util-resolve-all": "^2.0.0",
6079
+ "micromark-util-symbol": "^2.0.0",
6080
+ "micromark-util-types": "^2.0.0"
6081
+ },
6082
+ "funding": {
6083
+ "type": "opencollective",
6084
+ "url": "https://opencollective.com/unified"
6085
+ }
6086
+ },
6087
+ "node_modules/micromark-extension-gfm-table": {
6088
+ "version": "2.1.2",
6089
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.2.tgz",
6090
+ "integrity": "sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==",
6091
+ "license": "MIT",
6092
+ "dependencies": {
6093
+ "devlop": "^1.0.0",
6094
+ "micromark-factory-space": "^2.0.0",
6095
+ "micromark-util-character": "^2.0.0",
6096
+ "micromark-util-symbol": "^2.0.0",
6097
+ "micromark-util-types": "^2.0.0"
6098
+ },
6099
+ "funding": {
6100
+ "type": "opencollective",
6101
+ "url": "https://opencollective.com/unified"
6102
+ }
6103
+ },
6104
+ "node_modules/micromark-extension-gfm-tagfilter": {
6105
+ "version": "2.0.0",
6106
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz",
6107
+ "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==",
6108
+ "license": "MIT",
6109
+ "dependencies": {
6110
+ "micromark-util-types": "^2.0.0"
6111
+ },
6112
+ "funding": {
6113
+ "type": "opencollective",
6114
+ "url": "https://opencollective.com/unified"
6115
+ }
6116
+ },
6117
+ "node_modules/micromark-extension-gfm-task-list-item": {
6118
+ "version": "2.1.0",
6119
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz",
6120
+ "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==",
6121
+ "license": "MIT",
6122
+ "dependencies": {
6123
+ "devlop": "^1.0.0",
6124
+ "micromark-factory-space": "^2.0.0",
6125
+ "micromark-util-character": "^2.0.0",
6126
+ "micromark-util-symbol": "^2.0.0",
6127
+ "micromark-util-types": "^2.0.0"
6128
+ },
6129
+ "funding": {
6130
+ "type": "opencollective",
6131
+ "url": "https://opencollective.com/unified"
6132
+ }
6133
+ },
5873
6134
  "node_modules/micromark-factory-destination": {
5874
6135
  "version": "2.0.1",
5875
6136
  "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
@@ -6884,6 +7145,24 @@
6884
7145
  "node": ">= 6"
6885
7146
  }
6886
7147
  },
7148
+ "node_modules/remark-gfm": {
7149
+ "version": "4.0.1",
7150
+ "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz",
7151
+ "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==",
7152
+ "license": "MIT",
7153
+ "dependencies": {
7154
+ "@types/mdast": "^4.0.0",
7155
+ "mdast-util-gfm": "^3.0.0",
7156
+ "micromark-extension-gfm": "^3.0.0",
7157
+ "remark-parse": "^11.0.0",
7158
+ "remark-stringify": "^11.0.0",
7159
+ "unified": "^11.0.0"
7160
+ },
7161
+ "funding": {
7162
+ "type": "opencollective",
7163
+ "url": "https://opencollective.com/unified"
7164
+ }
7165
+ },
6887
7166
  "node_modules/remark-parse": {
6888
7167
  "version": "11.0.0",
6889
7168
  "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
@@ -6917,6 +7196,21 @@
6917
7196
  "url": "https://opencollective.com/unified"
6918
7197
  }
6919
7198
  },
7199
+ "node_modules/remark-stringify": {
7200
+ "version": "11.0.0",
7201
+ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz",
7202
+ "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==",
7203
+ "license": "MIT",
7204
+ "dependencies": {
7205
+ "@types/mdast": "^4.0.0",
7206
+ "mdast-util-to-markdown": "^2.0.0",
7207
+ "unified": "^11.0.0"
7208
+ },
7209
+ "funding": {
7210
+ "type": "opencollective",
7211
+ "url": "https://opencollective.com/unified"
7212
+ }
7213
+ },
6920
7214
  "node_modules/require-from-string": {
6921
7215
  "version": "2.0.2",
6922
7216
  "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
@@ -7774,9 +8068,9 @@
7774
8068
  }
7775
8069
  },
7776
8070
  "node_modules/unist-util-visit-parents": {
7777
- "version": "6.0.1",
7778
- "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
7779
- "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
8071
+ "version": "6.1.0",
8072
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.1.0.tgz",
8073
+ "integrity": "sha512-vKXxz6O38sKDj1mtx/k2cWvkkFBuYGx6uGrlzBkVeWCRF/F8sdI0j3Wbkz/5rVNRRuVc8UrgRdbCxNhmYXgP3w==",
7780
8074
  "license": "MIT",
7781
8075
  "dependencies": {
7782
8076
  "@types/unist": "^3.0.0",
@@ -34,6 +34,7 @@
34
34
  "react-i18next": "^15.5.2",
35
35
  "react-markdown": "^10.1.0",
36
36
  "react-router": "^7.5.0",
37
+ "remark-gfm": "^4.0.1",
37
38
  "socket.io-client": "^4.8.1",
38
39
  "syllable": "^5.0.1",
39
40
  "tailwind-merge": "^3.3.1",
@@ -24,7 +24,6 @@ vi.mock("./utils/lib", async (importOriginal) => ({
24
24
  ...(await importOriginal<typeof import("./utils/lib")>()),
25
25
  isValidPublicToken: vi.fn(async () => true),
26
26
  isValidRigoToken: vi.fn(async () => false),
27
- getTechnologies: vi.fn(async () => []),
28
27
  loginWithToken: vi.fn(),
29
28
  }));
30
29
  let deliverNotification: ((payload: unknown) => void) | null = null;
@@ -34,6 +33,12 @@ vi.mock("./components/NotificationListener", () => ({
34
33
  return null;
35
34
  },
36
35
  }));
36
+ let expireWatchdog: (() => void) | null = null;
37
+ vi.mock("./utils/useCompletionWatchdog", () => ({
38
+ useCompletionWatchdog: (_id: string, onTimeout: () => void) => {
39
+ expireWatchdog = onTimeout;
40
+ },
41
+ }));
37
42
  vi.mock("./components/TurnstileChallenge", () => ({ default: () => null }));
38
43
  vi.mock("./components/TurnstileModal", () => ({ default: () => null }));
39
44
 
@@ -296,6 +301,124 @@ describe("language URL param", () => {
296
301
  });
297
302
  });
298
303
 
304
+ describe("when generation fails", () => {
305
+ const TITLE = "We could not generate your course";
306
+ const REJECTED = {
307
+ id: 231,
308
+ status: "ERROR",
309
+ status_text: "The selected model openai/gpt-5.6-luna doesn't support structured outputs",
310
+ parsed: null,
311
+ };
312
+ const UNEXPLAINED = { id: 232, status: "ERROR", status_text: "boom", parsed: null };
313
+
314
+ const generate = async () => {
315
+ deliverNotification = null;
316
+ finishWizard();
317
+ await waitFor(() => expect(deliverNotification).not.toBeNull());
318
+ };
319
+
320
+ const fail = async (payload: unknown) => {
321
+ await generate();
322
+ act(() => deliverNotification!(payload));
323
+ };
324
+
325
+ it("stays on screen with its reference instead of returning to the wizard", async () => {
326
+ await setUp({});
327
+ await fail(UNEXPLAINED);
328
+
329
+ expect(screen.getByRole("alert").textContent).toContain(TITLE);
330
+ expect(screen.getByText("Reference code: 232")).toBeTruthy();
331
+ expect(screen.getByText("Your answers and files are still saved.")).toBeTruthy();
332
+ expect(screen.queryByText("Any materials to get this course started?")).toBeNull();
333
+ });
334
+
335
+ it("retries with one click and no more questions", async () => {
336
+ await setUp({});
337
+ await fail(UNEXPLAINED);
338
+
339
+ deliverNotification = null;
340
+ fireEvent.click(screen.getByText("Try again"));
341
+
342
+ await waitFor(() => expect(publicInteractiveCreation).toHaveBeenCalledTimes(2));
343
+ await waitFor(() => expect(deliverNotification).not.toBeNull());
344
+ expect(screen.queryByRole("alert")).toBeNull();
345
+ });
346
+
347
+ it("sends to support a failure a retry cannot fix", async () => {
348
+ await setUp({});
349
+ await fail(REJECTED);
350
+
351
+ expect(
352
+ screen.getByText("Please contact support and share the reference code.")
353
+ ).toBeTruthy();
354
+ expect(screen.getByText("Reference code: 231")).toBeTruthy();
355
+ expect(screen.queryByText("Try again")).toBeNull();
356
+ expect(screen.getByText("Review my answers")).toBeTruthy();
357
+ });
358
+
359
+ it("sends to support an unknown failure that repeats", async () => {
360
+ await setUp({});
361
+ await fail(UNEXPLAINED);
362
+ expect(screen.getByText("Try again")).toBeTruthy();
363
+
364
+ deliverNotification = null;
365
+ fireEvent.click(screen.getByText("Try again"));
366
+ await waitFor(() => expect(deliverNotification).not.toBeNull());
367
+ act(() => deliverNotification!(UNEXPLAINED));
368
+
369
+ expect(screen.queryByText("Try again")).toBeNull();
370
+ expect(
371
+ screen.getByText("Please contact support and share the reference code.")
372
+ ).toBeTruthy();
373
+ });
374
+
375
+ it("names the job even when its notification never arrives", async () => {
376
+ vi.mocked(publicInteractiveCreation).mockResolvedValueOnce({
377
+ res: { id: 77 },
378
+ notificationId: "job-1",
379
+ });
380
+ await setUp({});
381
+ await generate();
382
+
383
+ act(() => expireWatchdog!());
384
+
385
+ expect(
386
+ screen.getByText("This is taking longer than expected, so we stopped waiting. Please try again.")
387
+ ).toBeTruthy();
388
+ expect(screen.getByText("Reference code: 77")).toBeTruthy();
389
+ });
390
+
391
+ it("shows no reference when the request never created a job", async () => {
392
+ vi.mocked(publicInteractiveCreation).mockResolvedValueOnce(null);
393
+ await setUp({});
394
+ finishWizard();
395
+
396
+ await waitFor(() => expect(screen.getByRole("alert")).toBeTruthy());
397
+ expect(screen.queryByText(/Reference code/)).toBeNull();
398
+ });
399
+
400
+ it("reviews the materials when there are files, keeping them", async () => {
401
+ await setUp({ form: { hasContentIndex: true }, files: [file(ENGLISH_SEED)] });
402
+ await fail(REJECTED);
403
+
404
+ fireEvent.click(screen.getByText("Review my answers"));
405
+
406
+ expect(screen.queryByRole("alert")).toBeNull();
407
+ expect(useStore.getState().formState.currentStep).toBe("contentIndex");
408
+ expect(useStore.getState().uploadedFiles).toHaveLength(1);
409
+ });
410
+
411
+ it("asks about materials again when there were none", async () => {
412
+ await setUp({});
413
+ await fail(REJECTED);
414
+
415
+ fireEvent.click(screen.getByText("Review my answers"));
416
+
417
+ expect(useStore.getState().formState.currentStep).toBe("hasContentIndex");
418
+ expect(screen.getByText("Any materials to get this course started?")).toBeTruthy();
419
+ });
420
+ });
421
+
299
422
  describe("description language modal", () => {
300
423
  const typeDescriptionAndGoNext = (description: string) => {
301
424
  fireEvent.change(screen.getByPlaceholderText(i18n.t("stepWizard.descriptionPlaceholder")), {