@cyberismo/backend 0.0.14 → 0.0.16

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 (113) hide show
  1. package/dist/app.d.ts +21 -0
  2. package/dist/app.js +9 -3
  3. package/dist/app.js.map +1 -1
  4. package/dist/common/validationSchemas.d.ts +48 -0
  5. package/dist/domain/calculations/index.d.ts +15 -0
  6. package/dist/domain/calculations/index.js +1 -53
  7. package/dist/domain/calculations/index.js.map +1 -1
  8. package/dist/domain/calculations/schema.d.ts +16 -0
  9. package/dist/domain/calculations/schema.js +0 -7
  10. package/dist/domain/calculations/schema.js.map +1 -1
  11. package/dist/domain/calculations/service.d.ts +14 -0
  12. package/dist/domain/calculations/service.js +0 -5
  13. package/dist/domain/calculations/service.js.map +1 -1
  14. package/dist/domain/cardTypes/index.d.ts +15 -0
  15. package/dist/domain/cardTypes/schema.d.ts +17 -0
  16. package/dist/domain/cardTypes/service.d.ts +15 -0
  17. package/dist/domain/cards/index.d.ts +15 -0
  18. package/dist/domain/cards/index.js +24 -8
  19. package/dist/domain/cards/index.js.map +1 -1
  20. package/dist/domain/cards/lib.d.ts +29 -0
  21. package/dist/domain/cards/lib.js +74 -13
  22. package/dist/domain/cards/lib.js.map +1 -1
  23. package/dist/domain/cards/service.d.ts +61 -0
  24. package/dist/domain/cards/service.js +22 -18
  25. package/dist/domain/cards/service.js.map +1 -1
  26. package/dist/domain/fieldTypes/index.d.ts +15 -0
  27. package/dist/domain/fieldTypes/schema.d.ts +28 -0
  28. package/dist/domain/fieldTypes/service.d.ts +16 -0
  29. package/dist/domain/graphModels/index.d.ts +15 -0
  30. package/dist/domain/graphModels/schema.d.ts +16 -0
  31. package/dist/domain/graphModels/service.d.ts +14 -0
  32. package/dist/domain/graphViews/index.d.ts +15 -0
  33. package/dist/domain/graphViews/schema.d.ts +4 -0
  34. package/dist/domain/graphViews/service.d.ts +14 -0
  35. package/dist/domain/labels/index.d.ts +15 -0
  36. package/dist/domain/labels/index.js +33 -0
  37. package/dist/domain/labels/index.js.map +1 -0
  38. package/dist/domain/labels/service.d.ts +19 -0
  39. package/dist/domain/labels/service.js +21 -0
  40. package/dist/domain/labels/service.js.map +1 -0
  41. package/dist/domain/linkTypes/index.d.ts +15 -0
  42. package/dist/domain/linkTypes/schema.d.ts +16 -0
  43. package/dist/domain/linkTypes/service.d.ts +15 -0
  44. package/dist/domain/logicPrograms/index.d.ts +15 -0
  45. package/dist/domain/logicPrograms/service.d.ts +15 -0
  46. package/dist/domain/reports/index.d.ts +15 -0
  47. package/dist/domain/reports/schema.d.ts +16 -0
  48. package/dist/domain/reports/service.d.ts +14 -0
  49. package/dist/domain/resources/index.d.ts +15 -0
  50. package/dist/domain/resources/index.js +2 -20
  51. package/dist/domain/resources/index.js.map +1 -1
  52. package/dist/domain/resources/schema.d.ts +60 -0
  53. package/dist/domain/resources/schema.js +12 -1
  54. package/dist/domain/resources/schema.js.map +1 -1
  55. package/dist/domain/resources/service.d.ts +36 -0
  56. package/dist/domain/resources/service.js +14 -34
  57. package/dist/domain/resources/service.js.map +1 -1
  58. package/dist/domain/templates/index.d.ts +15 -0
  59. package/dist/domain/templates/index.js +1 -1
  60. package/dist/domain/templates/index.js.map +1 -1
  61. package/dist/domain/templates/schema.d.ts +22 -0
  62. package/dist/domain/templates/service.d.ts +16 -0
  63. package/dist/domain/tree/index.d.ts +15 -0
  64. package/dist/domain/tree/index.js +3 -2
  65. package/dist/domain/tree/index.js.map +1 -1
  66. package/dist/domain/tree/service.d.ts +22 -0
  67. package/dist/domain/tree/service.js +10 -2
  68. package/dist/domain/tree/service.js.map +1 -1
  69. package/dist/domain/workflows/index.d.ts +15 -0
  70. package/dist/domain/workflows/schema.d.ts +16 -0
  71. package/dist/domain/workflows/service.d.ts +14 -0
  72. package/dist/export.d.ts +42 -0
  73. package/dist/export.js +48 -152
  74. package/dist/export.js.map +1 -1
  75. package/dist/index.d.ts +13 -0
  76. package/dist/index.js +3 -4
  77. package/dist/index.js.map +1 -1
  78. package/dist/main.d.ts +1 -0
  79. package/dist/middleware/commandManager.d.ts +20 -0
  80. package/dist/middleware/tree.d.ts +9 -0
  81. package/dist/middleware/tree.js +13 -0
  82. package/dist/middleware/tree.js.map +1 -0
  83. package/dist/middleware/zvalidator.d.ts +9 -0
  84. package/dist/public/THIRD-PARTY.txt +164 -164
  85. package/dist/public/assets/{index-OjHhVGiV.js → index-D410yunq.js} +89249 -81256
  86. package/dist/public/assets/index-DnK7MBer.css +1 -0
  87. package/dist/public/index.html +2 -2
  88. package/dist/types.d.ts +29 -0
  89. package/dist/utils.d.ts +11 -0
  90. package/dist/utils.js +0 -32
  91. package/dist/utils.js.map +1 -1
  92. package/package.json +8 -8
  93. package/src/app.ts +11 -4
  94. package/src/domain/calculations/index.ts +1 -68
  95. package/src/domain/calculations/schema.ts +0 -9
  96. package/src/domain/calculations/service.ts +0 -11
  97. package/src/domain/cards/index.ts +33 -8
  98. package/src/domain/cards/lib.ts +95 -22
  99. package/src/domain/cards/service.ts +38 -37
  100. package/src/domain/labels/index.ts +36 -0
  101. package/src/domain/labels/service.ts +23 -0
  102. package/src/domain/resources/index.ts +3 -41
  103. package/src/domain/resources/schema.ts +13 -1
  104. package/src/domain/resources/service.ts +28 -67
  105. package/src/domain/templates/index.ts +1 -1
  106. package/src/domain/tree/index.ts +10 -3
  107. package/src/domain/tree/service.ts +15 -1
  108. package/src/export.ts +59 -192
  109. package/src/index.ts +7 -4
  110. package/src/middleware/tree.ts +17 -0
  111. package/src/types.ts +13 -0
  112. package/src/utils.ts +0 -39
  113. package/dist/public/assets/index-DA46eVkH.css +0 -1
@@ -0,0 +1 @@
1
+ @media(max-width:800px){.breadcrumbs{display:none}}[role=treeitem][aria-selected=false]:hover{.treenode{background-color:#dedede}}[role=treeitem][aria-selected=true]{outline:none}.resizeHandle{width:2px}.resizeHandle:hover,.resizeHandle:active{background-color:#0b6bcb}.cyberismo-svg-wrapper svg{max-height:100vh}.doc .MuiButton-root{margin-top:12px}.doc table.tableblock{border-collapse:collapse}.doc{color:#333;font-size:inherit;-ms-hyphens:auto;hyphens:auto;line-height:1.6;margin:0;padding:0}@media screen and (min-width:1024px){.doc{-webkit-box-flex:1;-ms-flex:auto;flex:auto;font-size:.94444rem;margin:0;min-width:0}}.doc h1,.doc h2,.doc h3,.doc h4,.doc h5,.doc h6{color:#191919;font-weight:400;-ms-hyphens:none;hyphens:none;line-height:1.3;margin:1rem 0 0}.doc>h1.page:first-child{font-size:2rem;margin:1.5rem 0}@media screen and (min-width:769px){.doc>h1.page:first-child{margin-top:2.5rem}}.doc>h1.page:first-child+aside.toc.embedded{margin-top:-.5rem}.doc>h2#name+.sectionbody{margin-top:1rem}#preamble+.sect1,.doc .sect1+.sect1{margin-top:2rem}.doc h1.sect0{background:#f0f0f0;font-size:1.8em;margin:1.5rem -1rem 0;padding:.5rem 1rem}.doc h2:not(.discrete){border-bottom:1px solid #e1e1e1;margin-left:-1rem;margin-right:-1rem;padding:.4rem 1rem .1rem}.doc h3:not(.discrete),.doc h4:not(.discrete){font-weight:600}.doc h1 .anchor,.doc h2 .anchor,.doc h3 .anchor,.doc h4 .anchor,.doc h5 .anchor,.doc h6 .anchor{position:absolute;text-decoration:none;width:1.75ex;margin-left:-1.5ex;visibility:hidden;font-size:.8em;font-weight:400;padding-top:.05em}.doc h1 .anchor:before,.doc h2 .anchor:before,.doc h3 .anchor:before,.doc h4 .anchor:before,.doc h5 .anchor:before,.doc h6 .anchor:before{content:"§"}.doc h1:hover .anchor,.doc h2:hover .anchor,.doc h3:hover .anchor,.doc h4:hover .anchor,.doc h5:hover .anchor,.doc h6:hover .anchor{visibility:visible}.doc dl,.doc p{margin:0}.doc a{color:#1565c0}.doc a:hover{color:#104d92}.doc a.bare{-ms-hyphens:none;hyphens:none}.doc a.unresolved{color:#d32f2f}.doc i.fa{-ms-hyphens:none;hyphens:none;font-style:normal}.doc .colist>table code,.doc p code,.doc thead code{color:#222;background:#fafafa;border-radius:.25em;font-size:.95em;padding:.125em .25em}.doc code,.doc pre{-ms-hyphens:none;hyphens:none}.doc pre{font-size:.88889rem;line-height:1.5;margin:0}.doc blockquote{margin:0}.doc .paragraph.lead>p{font-size:1rem}.doc .right{float:right}.doc .left{float:left}.doc .float-gap.right{margin:0 1rem 1rem 0}.doc .float-gap.left{margin:0 0 1rem 1rem}.doc .float-group:after{content:"";display:table;clear:both}.doc .text-left{text-align:left}.doc .text-center{text-align:center}.doc .text-right{text-align:right}.doc .text-justify{text-align:justify}.doc .stretch{width:100%}.doc .big{font-size:larger}.doc .small{font-size:smaller}.doc .underline{text-decoration:underline}.doc .line-through{text-decoration:line-through}.doc .dlist,.doc .exampleblock,.doc .hdlist,.doc .imageblock,.doc .listingblock,.doc .literalblock,.doc .olist,.doc .paragraph,.doc .partintro,.doc .quoteblock,.doc .sidebarblock,.doc .tabs,.doc .ulist,.doc .verseblock,.doc .videoblock,.doc details,.doc hr{margin:1rem 0 0}.doc .tablecontainer,.doc .tablecontainer+*,.doc :not(.tablecontainer)>table.tableblock,.doc :not(.tablecontainer)>table.tableblock+*,.doc>table.tableblock,.doc>table.tableblock+*{margin-top:1.5rem}.doc table.tableblock{font-size:.83333rem}.doc p.tableblock+p.tableblock{margin-top:.5rem}.doc table.tableblock pre{font-size:inherit}.doc td.tableblock>.content{word-wrap:anywhere}.doc td.tableblock>.content>:first-child{margin-top:0}.doc table.tableblock td{padding:.5rem}.doc table.tableblock th{padding:.5rem;background:#fbfcfe}.doc table.tableblock,.doc table.tableblock>*>tr>*{border:0 solid #e1e1e1}.doc table.grid-all>*>tr>*{border-width:1px}.doc table.grid-cols>*>tr>*{border-width:0 1px}.doc table.grid-rows>*>tr>*{border-width:1px 0}.doc table.grid-all>thead th,.doc table.grid-rows>thead th{border-bottom-width:2.5px}.doc table.frame-all{border-width:1px}.doc table.frame-ends{border-width:1px 0}.doc table.frame-sides{border-width:0 1px}.doc table.frame-none>colgroup+*>:first-child>*,.doc table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}.doc table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}.doc table.frame-ends>*>tr>:first-child,.doc table.frame-none>*>tr>:first-child{border-left-width:0}.doc table.frame-ends>*>tr>:last-child,.doc table.frame-none>*>tr>:last-child{border-right-width:0}.doc table.stripes-all>tbody>tr,.doc table.stripes-even>tbody>tr:nth-of-type(2n),.doc table.stripes-hover>tbody>tr:hover,.doc table.stripes-odd>tbody>tr:nth-of-type(odd){background:#fafafa}.doc table.tableblock>tfoot{background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#fff));background:linear-gradient(180deg,#f0f0f0 0,#fff)}.doc .halign-left{text-align:left}.doc .halign-right{text-align:right}.doc .halign-center{text-align:center}.doc .valign-top{vertical-align:top}.doc .valign-bottom{vertical-align:bottom}.doc .valign-middle{vertical-align:middle}.doc .admonitionblock{margin:1.4rem 0 0}.doc .admonitionblock p,.doc .admonitionblock td.content{font-size:.88889rem}.doc .admonitionblock td.content>.title+*,.doc .admonitionblock td.content>:not(.title):first-child{margin-top:0}.doc .admonitionblock td.content pre{font-size:.83333rem}.doc .admonitionblock>table{table-layout:fixed;position:relative;width:100%}.doc .admonitionblock td.content{padding:1rem 1rem .75rem;background:#fafafa;width:100%;word-wrap:anywhere}.doc .admonitionblock td.icon{font-size:.83333rem;left:0;line-height:1;padding:0;position:absolute;top:0;-webkit-transform:translate(-.5rem,-50%);transform:translate(-.5rem,-50%)}.doc .admonitionblock td.icon i{-webkit-box-align:center;-ms-flex-align:center;align-items:center;border-radius:.45rem;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-filter:initial;filter:none;height:1.25rem;padding:0 .5rem;vertical-align:initial;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.doc .admonitionblock td.icon i:after{content:attr(title);font-weight:600;font-style:normal;text-transform:uppercase}.doc .admonitionblock td.icon i.icon-caution{background-color:#a0439c;color:#fff}.doc .admonitionblock td.icon i.icon-important{background-color:#d32f2f;color:#fff}.doc .admonitionblock td.icon i.icon-note{background-color:#217ee7;color:#fff}.doc .admonitionblock td.icon i.icon-tip{background-color:#41af46;color:#fff}.doc .admonitionblock td.icon i.icon-warning{background-color:#e18114;color:#fff}.doc .imageblock,.doc .videoblock{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.doc .imageblock .content{-ms-flex-item-align:stretch;align-self:stretch;text-align:center}.doc .imageblock.text-left,.doc .videoblock.text-left{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.doc .imageblock.text-left .content{text-align:left}.doc .imageblock.text-right,.doc .videoblock.text-right{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.doc .imageblock.text-right .content{text-align:right}.doc .image>img,.doc .image>object,.doc .image>svg,.doc .imageblock img,.doc .imageblock object,.doc .imageblock svg{display:inline-block;max-height:75vh;max-width:100%;vertical-align:middle}.doc .image:not(.left):not(.right)>img{margin-top:-.2em}.doc .videoblock iframe,.doc .videoblock video{max-width:100%;vertical-align:middle}#preamble .abstract blockquote{background:#f0f0f0;border-left:5px solid #e1e1e1;color:#4a4a4a;font-size:.88889rem;padding:.75em 1em}.doc .quoteblock,.doc .verseblock{background:#fafafa;border-left:5px solid #5d5d5d;color:#5d5d5d}.doc .quoteblock{padding:.25rem 2rem 1.25rem}.doc .quoteblock .attribution{color:#8e8e8e;font-size:.83333rem;margin-top:.75rem}.doc .quoteblock blockquote{margin-top:1rem}.doc .quoteblock .paragraph{font-style:italic}.doc .quoteblock cite{padding-left:1em}.doc .verseblock{font-size:1.15em;padding:1rem 2rem}.doc .verseblock pre{font-family:inherit;font-size:inherit}.doc ol,.doc ul{margin:0;padding:0 0 0 2rem}.doc ol.none,.doc ol.unnumbered,.doc ol.unstyled,.doc ul.checklist,.doc ul.no-bullet,.doc ul.none,.doc ul.unstyled{list-style-type:none}.doc ol.unnumbered,.doc ul.no-bullet{padding-left:1.25rem}.doc ol.unstyled,.doc ul.unstyled{padding-left:0}.doc ul.circle{list-style-type:circle}.doc ul.disc{list-style-type:disc}.doc ul.square{list-style-type:square}.doc ul.circle ul:not([class]),.doc ul.disc ul:not([class]),.doc ul.square ul:not([class]){list-style:inherit}.doc ol.arabic{list-style-type:decimal}.doc ol.decimal{list-style-type:decimal-leading-zero}.doc ol.loweralpha{list-style-type:lower-alpha}.doc ol.upperalpha{list-style-type:upper-alpha}.doc ol.lowerroman{list-style-type:lower-roman}.doc ol.upperroman{list-style-type:upper-roman}.doc ol.lowergreek{list-style-type:lower-greek}.doc ul.checklist{padding-left:1.75rem}.doc ul.checklist p>i.fa-check-square-o:first-child,.doc ul.checklist p>i.fa-square-o:first-child{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:1.25rem;margin-left:-1.25rem}.doc ul.checklist i.fa-check-square-o:before{content:"✓"}.doc ul.checklist i.fa-square-o:before{content:"❏"}.doc .dlist .dlist,.doc .dlist .olist,.doc .dlist .ulist,.doc .olist .dlist,.doc .olist .olist,.doc .olist .ulist,.doc .olist li+li,.doc .ulist .dlist,.doc .ulist .olist,.doc .ulist .ulist,.doc .ulist li+li{margin-top:.5rem}.doc .admonitionblock .listingblock,.doc .olist .listingblock,.doc .ulist .listingblock{padding:0}.doc .admonitionblock .title,.doc .exampleblock .title,.doc .imageblock .title,.doc .listingblock .title,.doc .literalblock .title,.doc .openblock .title,.doc .videoblock .title,.doc table.tableblock caption{color:#5d5d5d;font-size:.88889rem;font-style:italic;font-weight:600;-ms-hyphens:none;hyphens:none;letter-spacing:.01em;padding-bottom:.075rem}.doc table.tableblock caption{text-align:left}.doc .olist .title,.doc .ulist .title{font-style:italic;font-weight:600;margin-bottom:.25rem}.doc .imageblock .title,.doc .videoblock .title{margin-top:.5rem;padding-bottom:0}.doc details{margin-left:1rem}.doc details>summary{display:block;position:relative;line-height:1.6;margin-bottom:.5rem}.doc details>summary::-webkit-details-marker{display:none}.doc details>summary:before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1rem;-webkit-transform:translateX(15%);transform:translate(15%)}.doc details[open]>summary:before{border-color:currentColor transparent transparent;border-width:.5rem .3rem 0;-webkit-transform:translateY(15%);transform:translateY(15%)}.doc details>summary:after{content:"";width:1rem;height:1em;position:absolute;top:.3em;left:-1rem}.doc details.result{margin-top:.25rem}.doc details.result>summary{color:#5d5d5d;font-style:italic;margin-bottom:0}.doc details.result>.content{margin-left:-1rem}.doc .exampleblock>.content,.doc details.result>.content{background:#fff;border:.25rem solid #5d5d5d;border-radius:.5rem;padding:.75rem}.doc .exampleblock>.content:after,.doc details.result>.content:after{content:"";display:table;clear:both}.doc .exampleblock>.content>:first-child,.doc details>.content>:first-child{margin-top:0}.doc .sidebarblock{background:#e1e1e1;border-radius:.75rem;padding:.75rem 1.5rem}.doc .sidebarblock>.content>.title{font-size:1.25rem;font-weight:600;line-height:1.3;margin-bottom:.5rem;text-align:center}.doc .sidebarblock>.content>.title+*,.doc .sidebarblock>.content>:not(.title):first-child{margin-top:0}.doc .listingblock.wrap pre,.doc table.tableblock pre{white-space:pre-wrap}.doc .listingblock pre:not(.highlight),.doc .literalblock pre,.doc pre.highlight>code{background:#fafafa;-webkit-box-shadow:inset 0 0 1.75px #e1e1e1;box-shadow:inset 0 0 1.75px #e1e1e1;display:block;overflow-x:auto;padding:.875em}.doc .listingblock>.content{position:relative}.doc .source-toolbox{display:-webkit-box;display:-ms-flexbox;display:flex;visibility:hidden;position:absolute;top:.25rem;right:.5rem;color:gray;font-family:Roboto,sans-serif;font-size:.72222rem;line-height:1;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap;z-index:1}.doc .listingblock:hover .source-toolbox{visibility:visible}.doc .source-toolbox .source-lang{text-transform:uppercase;letter-spacing:.075em}.doc .source-toolbox>:not(:last-child):after{content:"|";letter-spacing:0;padding:0 1ch}.doc .source-toolbox .copy-button{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:none;border:none;color:inherit;outline:none;padding:0;font-size:inherit;line-height:inherit;width:1em;height:1em}.doc .source-toolbox .copy-icon{-webkit-box-flex:0;-ms-flex:none;flex:none;width:inherit;height:inherit}.doc .source-toolbox img.copy-icon{-webkit-filter:invert(50.2%);filter:invert(50.2%)}.doc .source-toolbox svg.copy-icon{fill:currentColor}.doc .source-toolbox .copy-toast{-webkit-box-flex:0;-ms-flex:none;flex:none;position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-top:1em;background-color:#333;border-radius:.25em;padding:.5em;color:#fff;cursor:auto;opacity:0;-webkit-transition:opacity .5s ease .5s;transition:opacity .5s ease .5s}.doc .source-toolbox .copy-toast:after{content:"";position:absolute;top:0;width:1em;height:1em;border:.55em solid transparent;border-left-color:#333;-webkit-transform:rotate(-90deg) translateX(50%) translateY(50%);transform:rotate(-90deg) translate(50%) translateY(50%);-webkit-transform-origin:left;transform-origin:left}.doc .source-toolbox .copy-button.clicked .copy-toast{opacity:1;-webkit-transition:none;transition:none}.doc .language-console .hljs-meta{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.doc .dlist dt{font-style:italic}.doc .dlist dd{margin:0 0 0 1.5rem}.doc .dlist dd+dt,.doc .dlist dd>p:first-child{margin-top:.5rem}.doc td.hdlist1,.doc td.hdlist2{padding:.5rem 0 0;vertical-align:top}.doc tr:first-child>.hdlist1,.doc tr:first-child>.hdlist2{padding-top:0}.doc td.hdlist1{font-weight:600;padding-right:.25rem}.doc td.hdlist2{padding-left:.25rem}.doc .colist{font-size:.88889rem;margin:.25rem 0 -.25rem}.doc .colist>table>tbody>tr>:first-child,.doc .colist>table>tr>:first-child{padding:.25em .5rem 0;vertical-align:top}.doc .colist>table>tbody>tr>:last-child,.doc .colist>table>tr>:last-child{padding:.25rem 0}.doc .conum[data-value]{border:1px solid;border-radius:100%;display:inline-block;font-family:Roboto,sans-serif;font-size:.75rem;font-style:normal;line-height:1.2;text-align:center;width:1.25em;height:1.25em;letter-spacing:-.25ex;text-indent:-.25ex}.doc .conum[data-value]:after{content:attr(data-value)}.doc .conum[data-value]+b{display:none}.doc hr{border:solid #e1e1e1;border-width:2px 0 0;height:0}.doc b.button{white-space:nowrap}.doc b.button:before{content:"[";padding-right:.25em}.doc b.button:after{content:"]";padding-left:.25em}.doc kbd{display:inline-block;font-size:.66667rem;background:#fafafa;border:1px solid #c1c1c1;border-radius:.25em;-webkit-box-shadow:0 1px 0 #c1c1c1,0 0 0 .1em #fff inset;box-shadow:0 1px #c1c1c1,inset 0 0 0 .1em #fff;padding:.25em .5em;vertical-align:text-bottom;white-space:nowrap}.doc .keyseq,.doc kbd{line-height:1}.doc .keyseq{font-size:.88889rem}.doc .keyseq kbd{margin:0 .125em}.doc .keyseq kbd:first-child{margin-left:0}.doc .keyseq kbd:last-child{margin-right:0}.doc .menuseq,.doc .path{-ms-hyphens:none;hyphens:none}.doc .menuseq i.caret:before{content:"›";font-size:1.1em;font-weight:600;line-height:.90909}.doc :not(pre).nowrap{white-space:nowrap}.doc .nobreak{-ms-hyphens:none;hyphens:none;word-wrap:normal}.doc :not(pre).pre-wrap{white-space:pre-wrap}#footnotes{font-size:.85em;line-height:1.5;margin:2rem -.5rem 0}.doc td.tableblock>.content #footnotes{margin:2rem 0 0}#footnotes hr{border-top-width:1px;margin-top:0;width:20%}#footnotes .footnote{margin:.5em 0 0 1em}#footnotes .footnote+.footnote{margin-top:.25em}#footnotes .footnote>a:first-of-type{display:inline-block;margin-left:-2em;text-align:right;width:1.5em}.toc-menu{color:#5d5d5d}.toc.sidebar .toc-menu{margin-right:.75rem;position:sticky;top:6rem}.toc .toc-menu h3{color:#333;font-size:.88889rem;font-weight:600;line-height:1.3;margin:0 -.5px;padding-bottom:.25rem}.toc.sidebar .toc-menu h3{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;height:2.5rem;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.toc .toc-menu ul{font-size:.83333rem;line-height:1.2;list-style:none;margin:0;padding:0}.toc.sidebar .toc-menu ul{max-height:calc(100vh - 8.5rem);overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:none}@supports (scrollbar-width: none){.toc.sidebar .toc-menu ul{scrollbar-width:none}}.toc .toc-menu ul::-webkit-scrollbar{width:0;height:0}@media screen and (min-width:1024px){.toc .toc-menu h3{font-size:.83333rem}.toc .toc-menu ul{font-size:.75rem}}.toc .toc-menu li{margin:0}.toc .toc-menu li[data-level="2"] a{padding-left:1.25rem}.toc .toc-menu li[data-level="3"] a{padding-left:2rem}.toc .toc-menu a{color:inherit;border-left:2px solid #e1e1e1;display:inline-block;padding:.25rem 0 .25rem .5rem;text-decoration:none}.sidebar.toc .toc-menu a{display:block;outline:none}.toc .toc-menu a:hover{color:#1565c0}.toc .toc-menu a.is-active{border-left-color:#2a7ee4;color:#2a7ee4}.sidebar.toc .toc-menu a:focus{background:#fafafa}.toc .toc-menu .is-hidden-toc{display:none!important}.contentSidebar{min-width:160px}.doc .videoblock .content{position:relative;width:100%;max-width:100%}.doc .videoblock .content:before{content:"";display:block;padding-top:56.25%}.doc .videoblock .content>iframe,.doc .videoblock .content>video{position:absolute;inset:0;width:100%!important;height:100%!important;border:0;background:#000;display:block}
@@ -11,8 +11,8 @@
11
11
  name="msapplication-TileImage"
12
12
  content="/cropped-favicon-270x270.png"
13
13
  />
14
- <script type="module" crossorigin src="/assets/index-OjHhVGiV.js"></script>
15
- <link rel="stylesheet" crossorigin href="/assets/index-DA46eVkH.css">
14
+ <script type="module" crossorigin src="/assets/index-D410yunq.js"></script>
15
+ <link rel="stylesheet" crossorigin href="/assets/index-DnK7MBer.css">
16
16
  </head>
17
17
  <body>
18
18
  <div id="root"></div>
@@ -0,0 +1,29 @@
1
+ /**
2
+ Cyberismo
3
+ Copyright © Cyberismo Ltd and contributors 2025
4
+ This program is free software: you can redistribute it and/or modify it under
5
+ the terms of the GNU Affero General Public License version 3 as published by
6
+ the Free Software Foundation.
7
+ This program is distributed in the hope that it will be useful, but WITHOUT
8
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
10
+ details. You should have received a copy of the GNU Affero General Public
11
+ License along with this program. If not, see <https://www.gnu.org/licenses/>.
12
+ */
13
+ import type { Context } from 'hono';
14
+ export interface ResourceFileContentResponse {
15
+ content: string;
16
+ }
17
+ export interface ResourceValidationResponse {
18
+ errors: string[];
19
+ }
20
+ export interface TreeOptions {
21
+ recursive?: boolean;
22
+ cardKey?: string;
23
+ }
24
+ export interface AppVars {
25
+ tree?: TreeOptions;
26
+ }
27
+ export type AppContext = Context<{
28
+ Variables: AppVars;
29
+ }>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The relative path to the static frontend directory.
3
+ */
4
+ export declare const staticFrontendDirRelative: string;
5
+ /**
6
+ * Finds a free port.
7
+ * @param port - The port to start looking for.
8
+ * @param maxAttempts - The maximum number of attempts to find a free port.
9
+ * @returns The free port.
10
+ */
11
+ export declare function findFreePort(minPort: number, maxPort: number): Promise<number>;
package/dist/utils.js CHANGED
@@ -12,38 +12,6 @@
12
12
  */
13
13
  import path from 'node:path';
14
14
  import { createServer } from 'node:net';
15
- /**
16
- * Runs promises in parallel, but only maxConcurrent at a time.
17
- * @param promises - Array of promises to run in parallel
18
- * @param maxConcurrent - Maximum number of promises to run at a time
19
- * @returns - Promise that resolves when all promises have resolved
20
- */
21
- export async function runInParallel(promises, maxConcurrent = 2) {
22
- const waitingPromises = [];
23
- const wrappedPromises = promises.map((fn) => async () => {
24
- await fn();
25
- const next = waitingPromises.shift();
26
- if (next) {
27
- await next();
28
- }
29
- });
30
- const runningPromises = wrappedPromises.slice(0, maxConcurrent);
31
- waitingPromises.push(...wrappedPromises.slice(maxConcurrent));
32
- return Promise.all(runningPromises.map((p) => p()));
33
- }
34
- /**
35
- * Runs a callback and returns the result or undefined if it throws.
36
- * @param cb - The callback to run.
37
- * @returns The result of the callback or undefined if it throws.
38
- */
39
- export async function runCbSafely(cb) {
40
- try {
41
- return await cb();
42
- }
43
- catch {
44
- // All exceptions are ignored.
45
- }
46
- }
47
15
  /**
48
16
  * The relative path to the static frontend directory.
49
17
  */
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;EAWE;AACF,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAoC,EACpC,gBAAwB,CAAC;IAEzB,MAAM,eAAe,GAA+B,EAAE,CAAC;IACvD,MAAM,eAAe,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE;QACtD,MAAM,EAAE,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,EAAE,CAAC;QACrC,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAChE,eAAe,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;IAE9D,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACtD,CAAC;AACD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,EAAwB;IAExB,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC,QAAQ,CACpD,OAAO,CAAC,GAAG,EAAE,EACb,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAC5C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,OAAe;IAEf,KAAK,IAAI,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC;YAClB,OAAO,CAAC,CAAC;QACX,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC/D,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,yCAAyC,CAAC,CAAC;YAClE,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YACvB,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;QAC7D,CAAC,EAAE,IAAI,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;EAWE;AACF,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC,QAAQ,CACpD,OAAO,CAAC,GAAG,EAAE,EACb,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAC5C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,OAAe;IAEf,KAAK,IAAI,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC;YAClB,OAAO,CAAC,CAAC;QACX,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC/D,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,yCAAyC,CAAC,CAAC;YAClE,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YACvB,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;QAC7D,CAAC,EAAE,IAAI,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyberismo/backend",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "Express backend for Cyberismo",
5
5
  "main": "dist/index.js",
6
6
  "keywords": [],
@@ -9,13 +9,13 @@
9
9
  "dependencies": {
10
10
  "@asciidoctor/core": "^3.0.4",
11
11
  "@hono/node-server": "^1.19.2",
12
- "@hono/zod-validator": "^0.7.2",
12
+ "@hono/zod-validator": "^0.7.5",
13
13
  "@types/mime-types": "^3.0.1",
14
- "dotenv": "^17.2.2",
15
- "hono": "^4.9.7",
16
- "mime-types": "^3.0.1",
17
- "zod": "^4.1.8",
18
- "@cyberismo/data-handler": "0.0.14"
14
+ "dotenv": "^17.2.3",
15
+ "hono": "^4.10.6",
16
+ "mime-types": "^3.0.2",
17
+ "zod": "^4.1.12",
18
+ "@cyberismo/data-handler": "0.0.16"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@cyberismo/app": "0.0.2"
@@ -36,7 +36,7 @@
36
36
  "debug": "tsx --inspect-brk src/main.ts",
37
37
  "export": "pnpm build && node dist/main.js --export",
38
38
  "build": "tsc -p tsconfig.build.json && shx rm -rf ./dist/public && shx cp -r ../app/dist ./dist/public",
39
- "test": "vitest run",
39
+ "test": "vitest run --silent",
40
40
  "lint": "eslint ."
41
41
  }
42
42
  }
package/src/app.ts CHANGED
@@ -26,18 +26,21 @@ import reportsRouter from './domain/reports/index.js';
26
26
  import templatesRouter from './domain/templates/index.js';
27
27
  import treeRouter from './domain/tree/index.js';
28
28
  import workflowsRouter from './domain/workflows/index.js';
29
+ import labelsRouter from './domain/labels/index.js';
29
30
  import { readFile } from 'node:fs/promises';
30
31
  import path from 'node:path';
31
- import { isSSGContext } from './export.js';
32
32
  import resourcesRouter from './domain/resources/index.js';
33
33
  import logicProgramsRouter from './domain/logicPrograms/index.js';
34
+ import { isSSGContext } from 'hono/ssg';
35
+ import type { AppVars, TreeOptions } from './types.js';
36
+ import treeMiddleware from './middleware/tree.js';
34
37
 
35
38
  /**
36
39
  * Create the Hono app for the backend
37
40
  * @param projectPath - Path to the project
38
41
  */
39
- export function createApp(projectPath?: string) {
40
- const app = new Hono();
42
+ export function createApp(projectPath?: string, opts?: TreeOptions) {
43
+ const app = new Hono<{ Variables: AppVars }>();
41
44
 
42
45
  app.use('/api', cors());
43
46
 
@@ -48,6 +51,7 @@ export function createApp(projectPath?: string) {
48
51
  }),
49
52
  );
50
53
 
54
+ app.use(treeMiddleware(opts));
51
55
  // Attach CommandManager to all requests
52
56
  app.use(attachCommandManager(projectPath));
53
57
 
@@ -65,6 +69,7 @@ export function createApp(projectPath?: string) {
65
69
  app.route('/api/workflows', workflowsRouter);
66
70
  app.route('/api/resources', resourcesRouter);
67
71
  app.route('/api/logicPrograms', logicProgramsRouter);
72
+ app.route('/api/labels', labelsRouter);
68
73
 
69
74
  // serve index.html for all other routes
70
75
  app.notFound(async (c) => {
@@ -79,7 +84,9 @@ export function createApp(projectPath?: string) {
79
84
  // Error handling
80
85
  app.onError((err, c) => {
81
86
  if (!isSSGContext(c)) {
82
- console.error(err.stack);
87
+ if (process.env.NODE_ENV !== 'test') {
88
+ console.error(err.stack);
89
+ }
83
90
  }
84
91
  return c.json(
85
92
  {
@@ -13,11 +13,7 @@
13
13
 
14
14
  import { Hono } from 'hono';
15
15
  import * as calculationService from './service.js';
16
- import {
17
- createCalculationSchema,
18
- updateCalculationParamsSchema,
19
- updateCalculationBodySchema,
20
- } from './schema.js';
16
+ import { createCalculationSchema } from './schema.js';
21
17
  import { zValidator } from '../../middleware/zvalidator.js';
22
18
 
23
19
  const router = new Hono();
@@ -56,66 +52,3 @@ router.post('/', zValidator('json', createCalculationSchema), async (c) => {
56
52
  });
57
53
 
58
54
  export default router;
59
- /**
60
- * @swagger
61
- * /api/calculations/{prefix}/{identifier}:
62
- * put:
63
- * summary: Update a calculation content
64
- * description: Updates the content of a calculation file
65
- * parameters:
66
- * - in: path
67
- * name: prefix
68
- * required: true
69
- * schema:
70
- * type: string
71
- * description: Prefix of the calculation
72
- * - in: path
73
- * name: type
74
- * required: true
75
- * schema:
76
- * type: string
77
- * description: Resource type (must be 'calculations')
78
- * - in: path
79
- * name: identifier
80
- * required: true
81
- * schema:
82
- * type: string
83
- * description: Identifier of the calculation
84
- * requestBody:
85
- * required: true
86
- * content:
87
- * application/json:
88
- * schema:
89
- * type: object
90
- * properties:
91
- * content:
92
- * type: string
93
- * description: New content for the calculation
94
- * responses:
95
- * 200:
96
- * description: Calculation updated successfully
97
- * 400:
98
- * description: Invalid request
99
- * 404:
100
- * description: Calculation not found
101
- * 500:
102
- * description: Server error
103
- */
104
- router.put(
105
- '/:prefix/:type/:identifier',
106
- zValidator('param', updateCalculationParamsSchema),
107
- zValidator('json', updateCalculationBodySchema),
108
- async (c) => {
109
- const commands = c.get('commands');
110
- const { prefix, identifier } = c.req.valid('param');
111
- const { content } = c.req.valid('json');
112
-
113
- await calculationService.updateCalculation(
114
- commands,
115
- prefix,
116
- identifier,
117
- content,
118
- );
119
- return c.json({ message: 'Calculation updated successfully' });
120
- },
121
- );
@@ -12,16 +12,7 @@
12
12
  */
13
13
 
14
14
  import { z } from 'zod';
15
- import { resourceParamsSchema } from '../../common/validationSchemas.js';
16
15
 
17
16
  export const createCalculationSchema = z.object({
18
17
  fileName: z.string().min(1),
19
18
  });
20
-
21
- export const updateCalculationBodySchema = z.object({
22
- content: z.string(),
23
- });
24
-
25
- export const updateCalculationParamsSchema = resourceParamsSchema.extend({
26
- type: z.literal('calculations'),
27
- });
@@ -12,7 +12,6 @@
12
12
  */
13
13
 
14
14
  import type { CommandManager } from '@cyberismo/data-handler';
15
- import { resourceName } from '@cyberismo/data-handler';
16
15
 
17
16
  export async function createCalculation(
18
17
  commands: CommandManager,
@@ -20,13 +19,3 @@ export async function createCalculation(
20
19
  ) {
21
20
  await commands.createCmd.createCalculation(fileName);
22
21
  }
23
-
24
- export async function updateCalculation(
25
- commands: CommandManager,
26
- prefix: string,
27
- identifier: string,
28
- content: string,
29
- ) {
30
- const name = resourceName(`${prefix}/calculations/${identifier}`, true);
31
- await commands.editCmd.editCalculation(name, content);
32
- }
@@ -13,9 +13,10 @@
13
13
 
14
14
  import { type Context, Hono } from 'hono';
15
15
  import type { ContentfulStatusCode } from 'hono/utils/http-status';
16
- import { ssgParams, isSSGContext } from '../../export.js';
17
16
  import { getCardDetails } from './lib.js';
18
17
  import * as cardService from './service.js';
18
+ import { isSSGContext, ssgParams } from 'hono/ssg';
19
+ import type { AppContext } from '../../types.js';
19
20
 
20
21
  const router = new Hono();
21
22
 
@@ -58,6 +59,12 @@ router.get('/', async (c) => {
58
59
  * in: path
59
60
  * required: true
60
61
  * description: Card key (string)
62
+ * - name: raw
63
+ * in: query
64
+ * required: false
65
+ * schema:
66
+ * type: boolean
67
+ * description: When true, returns the raw card data without triggering calculations
61
68
  * responses:
62
69
  * 200:
63
70
  * description: Object containing card details. See lib/api/types.ts/CardResponse for the structure.
@@ -68,10 +75,11 @@ router.get('/', async (c) => {
68
75
  */
69
76
  router.get(
70
77
  '/:key',
71
- ssgParams(async (c: Context) => {
78
+ ssgParams(async (c: AppContext) => {
72
79
  const commands = c.get('commands');
73
- const cards = await cardService.getAllCards(commands);
74
- return cards.map((key) => ({ key }));
80
+ const opts = c.get('tree');
81
+ const cards = await cardService.findAllCards(commands, opts);
82
+ return cards.map((card) => ({ key: card.key }));
75
83
  }),
76
84
  async (c) => {
77
85
  const key = c.req.param('key');
@@ -79,10 +87,13 @@ router.get(
79
87
  return c.text('No search key', 400);
80
88
  }
81
89
 
90
+ const raw = c.req.query('raw');
91
+
82
92
  const result = await getCardDetails(
83
93
  c.get('commands'),
84
94
  key,
85
95
  isSSGContext(c),
96
+ raw?.toLowerCase() === 'true' ? true : false,
86
97
  );
87
98
  if (result.status === 200) {
88
99
  return c.json(result.data);
@@ -117,6 +128,12 @@ router.get(
117
128
  * type: object
118
129
  * required: false
119
130
  * description: New metadata for the card. Must be an object with key-value pairs.
131
+ * - name: raw
132
+ * in: query
133
+ * required: false
134
+ * schema:
135
+ * type: boolean
136
+ * description: When true, returns the raw card data without triggering calculations
120
137
  * responses:
121
138
  * 200:
122
139
  * description: Object containing card details, same as GET. See definitions.ts/CardDetails for the structure.
@@ -134,10 +151,18 @@ router.patch('/:key', async (c) => {
134
151
  return c.text('No search key', 400);
135
152
  }
136
153
 
154
+ const raw = c.req.query('raw');
155
+
137
156
  const body = await c.req.json();
138
157
 
139
158
  try {
140
- const result = await cardService.updateCard(commands, key, body);
159
+ await cardService.updateCard(commands, key, body);
160
+ const result = await getCardDetails(
161
+ c.get('commands'),
162
+ key,
163
+ isSSGContext(c),
164
+ raw?.toLowerCase() === 'true' ? true : false,
165
+ );
141
166
  if (result.status === 200) {
142
167
  return c.json(result.data);
143
168
  } else {
@@ -587,9 +612,9 @@ router.get(
587
612
  '/:key/a/:attachment',
588
613
  ssgParams(async (c: Context) => {
589
614
  const commands = c.get('commands');
590
- return await cardService.getAllAttachments(commands);
615
+ return await cardService.findRelevantAttachments(commands, c.get('tree'));
591
616
  }),
592
- async (c) => {
617
+ (c) => {
593
618
  const commands = c.get('commands');
594
619
  const { key, attachment } = c.req.param();
595
620
  const filename = decodeURI(attachment);
@@ -599,7 +624,7 @@ router.get(
599
624
  }
600
625
 
601
626
  try {
602
- const attachmentResponse = await cardService.getAttachment(
627
+ const attachmentResponse = cardService.getAttachment(
603
628
  commands,
604
629
  key,
605
630
  filename,
@@ -12,13 +12,11 @@
12
12
  */
13
13
 
14
14
  import Processor from '@asciidoctor/core';
15
- import {
16
- type Card,
17
- CardLocation,
18
- type ProjectFetchCardDetails,
19
- } from '@cyberismo/data-handler/interfaces/project-interfaces';
15
+ import type { Card } from '@cyberismo/data-handler/interfaces/project-interfaces';
20
16
  import { type CommandManager, evaluateMacros } from '@cyberismo/data-handler';
21
17
  import { getCardQueryResult } from '../../export.js';
18
+ import type { TreeOptions } from '../../types.js';
19
+ import type { QueryResult } from '@cyberismo/data-handler/types/queries';
22
20
 
23
21
  interface result {
24
22
  status: number;
@@ -29,24 +27,12 @@ interface result {
29
27
  export async function getCardDetails(
30
28
  commands: CommandManager,
31
29
  key: string,
32
- staticMode?: boolean,
30
+ staticMode: boolean,
31
+ raw: boolean,
33
32
  ): Promise<result> {
34
- const fetchCardDetails: ProjectFetchCardDetails = {
35
- attachments: true,
36
- children: false,
37
- content: true,
38
- contentType: 'adoc',
39
- metadata: false,
40
- parent: false,
41
- location: CardLocation.all,
42
- };
43
-
44
- let cardDetailsResponse: Card | undefined;
33
+ let cardDetailsResponse: Card;
45
34
  try {
46
- cardDetailsResponse = await commands.showCmd.showCardDetails(
47
- fetchCardDetails,
48
- key,
49
- );
35
+ cardDetailsResponse = commands.showCmd.showCardDetails(key);
50
36
  } catch {
51
37
  return { status: 400, message: `Card ${key} not found from project` };
52
38
  }
@@ -56,7 +42,7 @@ export async function getCardDetails(
56
42
  }
57
43
 
58
44
  // always parse for now if not in export mode
59
- if (!staticMode) {
45
+ if (!staticMode && !raw) {
60
46
  await commands.calculateCmd.generate();
61
47
  }
62
48
 
@@ -82,6 +68,66 @@ export async function getCardDetails(
82
68
  })
83
69
  .toString();
84
70
 
71
+ if (raw) {
72
+ if (!cardDetailsResponse.metadata) {
73
+ throw new Error('Card has no metadata');
74
+ }
75
+ const cardType = await commands.showCmd.showResource(
76
+ cardDetailsResponse.metadata.cardType,
77
+ 'cardTypes',
78
+ );
79
+
80
+ const fields = [];
81
+ let i = 0;
82
+ for (const customField of cardType.customFields) {
83
+ const fieldType = await commands.showCmd.showResource(
84
+ customField.name,
85
+ 'fieldTypes',
86
+ );
87
+ fields.push({
88
+ key: customField.name,
89
+ visibility: 'always',
90
+ index: i++,
91
+ fieldDisplayName: fieldType.displayName,
92
+ fieldDescription: fieldType.description,
93
+ dataType: fieldType.dataType,
94
+ isCalculated: customField.isCalculated,
95
+ value: cardDetailsResponse.metadata[customField.name],
96
+ enumValues: fieldType.enumValues ?? [],
97
+ });
98
+ }
99
+ return {
100
+ status: 200,
101
+ data: {
102
+ key: cardDetailsResponse.key,
103
+ rank: cardDetailsResponse.metadata?.rank,
104
+ title: cardDetailsResponse.metadata?.title || '',
105
+ cardType: cardDetailsResponse.metadata?.cardType || '',
106
+ cardTypeDisplayName: cardDetailsResponse.metadata.cardType,
107
+ workflowState: '',
108
+ lastUpdated: cardDetailsResponse.metadata.lastUpdated,
109
+ fields,
110
+ labels: cardDetailsResponse.metadata?.labels || [],
111
+ links: [],
112
+ notifications: [],
113
+ policyChecks: {
114
+ successes: [],
115
+ failures: [],
116
+ },
117
+ deniedOperations: {
118
+ transition: [],
119
+ move: [],
120
+ delete: [],
121
+ editField: [],
122
+ editContent: [],
123
+ },
124
+ rawContent: cardDetailsResponse.content || '',
125
+ parsedContent: htmlContent,
126
+ attachments: cardDetailsResponse.attachments,
127
+ },
128
+ };
129
+ }
130
+
85
131
  const card = staticMode
86
132
  ? await getCardQueryResult(commands.project.basePath, key)
87
133
  : await commands.calculateCmd.runQuery('card', 'localApp', {
@@ -101,3 +147,30 @@ export async function getCardDetails(
101
147
  },
102
148
  };
103
149
  }
150
+ /**
151
+ * Returns all cards from a tree query, flattened.
152
+ * @param commands the command manager used for the query
153
+ * @param options optional tree query options
154
+ * @returns a promise that resolves to an array of all cards
155
+ */
156
+ export async function allCards(
157
+ commands: CommandManager,
158
+ options?: TreeOptions,
159
+ ): Promise<QueryResult<'tree'>[]> {
160
+ const fetchedCards = await commands.calculateCmd.runQuery(
161
+ 'tree',
162
+ 'exportedSite',
163
+ options || {},
164
+ );
165
+
166
+ function flattenCards(cards: QueryResult<'tree'>[]): QueryResult<'tree'>[] {
167
+ return cards.reduce<QueryResult<'tree'>[]>((acc, curr) => {
168
+ acc.push(curr);
169
+ if (curr.children && curr.children.length > 0) {
170
+ acc.push(...flattenCards(curr.children));
171
+ }
172
+ return acc;
173
+ }, []);
174
+ }
175
+ return flattenCards(fetchedCards);
176
+ }