brut 0.16.0 → 0.18.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 (1088) hide show
  1. checksums.yaml +4 -4
  2. data/exe/brut +34 -0
  3. data/lib/brut/cli/apps/build_assets.rb +78 -48
  4. data/lib/brut/cli/apps/db.rb +168 -202
  5. data/lib/brut/cli/apps/deploy.rb +291 -0
  6. data/lib/brut/cli/apps/heroku_container_based_deploy.rb +7 -1
  7. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/add_segment.rb +5 -5
  8. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/add_segment_options.rb +1 -1
  9. data/lib/brut/cli/apps/new/app.rb +240 -0
  10. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/app_id.rb +1 -1
  11. data/lib/brut/cli/apps/new/app_name.rb +29 -0
  12. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/base.rb +9 -6
  13. data/lib/brut/cli/apps/new/erb_binding_delegate.rb +23 -0
  14. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/internet_identifier.rb +5 -5
  15. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/invalid_identifier.rb +1 -1
  16. data/{mkbrut/lib/mkbrut/app.rb → lib/brut/cli/apps/new/old_app.rb} +8 -11
  17. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/add_css_import.rb +1 -1
  18. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/add_i18n_message.rb +1 -1
  19. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/add_method.rb +1 -1
  20. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/append_to_file.rb +1 -1
  21. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/base_op.rb +3 -3
  22. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/copy_file.rb +1 -1
  23. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/insert_code_in_method.rb +1 -1
  24. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/insert_into_file.rb +1 -1
  25. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/insert_route.rb +1 -1
  26. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/mkdir.rb +1 -1
  27. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/prism_parsing_op.rb +1 -1
  28. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/render_template.rb +1 -1
  29. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/skip_file.rb +1 -1
  30. data/lib/brut/cli/apps/new/ops.rb +17 -0
  31. data/lib/brut/cli/apps/new/organization.rb +5 -0
  32. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/prefix.rb +1 -1
  33. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/bare_bones.rb +12 -11
  34. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/demo.rb +16 -15
  35. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/heroku.rb +9 -5
  36. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/sidekiq.rb +44 -21
  37. data/lib/brut/cli/apps/new/segments.rb +8 -0
  38. data/lib/brut/cli/apps/new/version.rb +3 -0
  39. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/versions.rb +2 -2
  40. data/lib/brut/cli/apps/new.rb +26 -0
  41. data/lib/brut/cli/apps/scaffold.rb +150 -141
  42. data/lib/brut/cli/apps/test.rb +95 -69
  43. data/lib/brut/cli/commands/base_command.rb +174 -0
  44. data/lib/brut/cli/commands/compound_command.rb +29 -0
  45. data/lib/brut/cli/commands/execution_context.rb +32 -0
  46. data/lib/brut/cli/commands/help.rb +26 -0
  47. data/lib/brut/cli/commands/output_error.rb +13 -0
  48. data/lib/brut/cli/commands/raise_error.rb +11 -0
  49. data/lib/brut/cli/commands.rb +8 -0
  50. data/lib/brut/cli/execute_result.rb +39 -0
  51. data/lib/brut/cli/executor.rb +9 -4
  52. data/lib/brut/cli/output.rb +13 -0
  53. data/lib/brut/cli/parsed_command_line.rb +143 -0
  54. data/lib/brut/cli/runner.rb +124 -0
  55. data/lib/brut/cli.rb +7 -29
  56. data/lib/brut/framework/container.rb +1 -1
  57. data/lib/brut/framework/mcp.rb +59 -13
  58. data/lib/brut/framework/project_environment.rb +3 -1
  59. data/lib/brut/junk_drawer.rb +3 -1
  60. data/lib/brut/spec_support/cli_command_support.rb +45 -0
  61. data/lib/brut/spec_support/e2e_test_server.rb +3 -0
  62. data/lib/brut/spec_support/general_support.rb +1 -1
  63. data/lib/brut/spec_support/matchers/have_executed.rb +35 -0
  64. data/lib/brut/spec_support/rspec_setup.rb +4 -8
  65. data/lib/brut/spec_support.rb +1 -0
  66. data/lib/brut/tui/ansi_escape_code.rb +104 -0
  67. data/lib/brut/tui/event_loop.rb +168 -0
  68. data/lib/brut/tui/events/base_event.rb +29 -0
  69. data/lib/brut/tui/events/event_bus.rb +73 -0
  70. data/lib/brut/tui/events/event_loop_started.rb +5 -0
  71. data/lib/brut/tui/events/exception.rb +24 -0
  72. data/lib/brut/tui/events/tick.rb +12 -0
  73. data/lib/brut/tui/events.rb +7 -0
  74. data/lib/brut/tui/markup_string.rb +70 -0
  75. data/lib/brut/tui/script/block_step.rb +17 -0
  76. data/lib/brut/tui/script/events/command_execution_failed.rb +4 -0
  77. data/lib/brut/tui/script/events/command_execution_succeeded.rb +3 -0
  78. data/lib/brut/tui/script/events/command_std_err.rb +3 -0
  79. data/lib/brut/tui/script/events/command_std_out.rb +14 -0
  80. data/lib/brut/tui/script/events/executing_command.rb +12 -0
  81. data/lib/brut/tui/script/events/message.rb +15 -0
  82. data/lib/brut/tui/script/events/phase_completed.rb +4 -0
  83. data/lib/brut/tui/script/events/phase_started.rb +14 -0
  84. data/lib/brut/tui/script/events/script_completed.rb +5 -0
  85. data/lib/brut/tui/script/events/script_started.rb +12 -0
  86. data/lib/brut/tui/script/events/step_completed.rb +3 -0
  87. data/lib/brut/tui/script/events/step_started.rb +12 -0
  88. data/lib/brut/tui/script/events.rb +14 -0
  89. data/lib/brut/tui/script/exec_step.rb +67 -0
  90. data/lib/brut/tui/script/logging_subscriber.rb +98 -0
  91. data/lib/brut/tui/script/puts_subscriber.rb +109 -0
  92. data/lib/brut/tui/script/step.rb +13 -0
  93. data/lib/brut/tui/script.rb +215 -0
  94. data/lib/brut/tui/terminal.rb +74 -0
  95. data/lib/brut/tui/terminal_theme.rb +144 -0
  96. data/lib/brut/tui/themes/dark.rb +14 -0
  97. data/lib/brut/tui/themes/light.rb +17 -0
  98. data/lib/brut/tui/themes/none.rb +9 -0
  99. data/lib/brut/tui/themes.rb +5 -0
  100. data/lib/brut/tui.rb +15 -0
  101. data/lib/brut/version.rb +1 -1
  102. data/lib/brut.rb +1 -0
  103. data/templates/Base/.env.development.local +2 -0
  104. data/templates/Base/bin/ci +42 -0
  105. data/{mkbrut/templates → templates}/Base/bin/release +2 -2
  106. data/templates/Base/bin/setup +174 -0
  107. data/{mkbrut/templates → templates}/Base/bin/watch-and-build-assets +1 -1
  108. data/{mkbrut/templates → templates}/Base/dx/docker-compose.env.erb +1 -1
  109. data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/css/fonts.css +1 -1
  110. data/{mkbrut/templates → templates}/segments/Heroku/deploy/Dockerfile +2 -2
  111. data/templates/segments/Heroku/deploy/docker_config.rb +30 -0
  112. metadata +254 -1009
  113. data/.gitignore +0 -55
  114. data/.projections.json +0 -10
  115. data/CHANGELOG.md +0 -167
  116. data/CODE_OF_CONDUCT.txt +0 -99
  117. data/Dockerfile.dx +0 -82
  118. data/Gemfile +0 -6
  119. data/Gemfile.lock +0 -243
  120. data/LICENSE.txt +0 -370
  121. data/README.md +0 -90
  122. data/Rakefile +0 -25
  123. data/assets/Logo-Square.pxd +0 -0
  124. data/assets/LogoPylon.pxd +0 -0
  125. data/assets/LogoStop.pxd +0 -0
  126. data/assets/LogoTall.pxd +0 -0
  127. data/assets/MetroIcon.graffle +0 -0
  128. data/assets/MetroLogo.graffle +0 -0
  129. data/assets/SocialImage.png +0 -0
  130. data/assets/SocialImage.pxd +0 -0
  131. data/assets/YouTubeThumb.pxd +0 -0
  132. data/bin/bin_kit.rb +0 -51
  133. data/bin/build +0 -86
  134. data/bin/ci +0 -40
  135. data/bin/dev +0 -20
  136. data/bin/docs +0 -79
  137. data/bin/generate-and-run-rubocop +0 -52
  138. data/bin/new-version +0 -8
  139. data/bin/publish +0 -61
  140. data/bin/rake +0 -27
  141. data/bin/rspec +0 -27
  142. data/bin/rubocop +0 -27
  143. data/bin/setup +0 -252
  144. data/bin/test +0 -18
  145. data/brut-css/.nvim.lua +0 -1
  146. data/brut-css/README.md +0 -28
  147. data/brut-css/bin/build +0 -50
  148. data/brut-css/bin/ci +0 -19
  149. data/brut-css/bin/dev +0 -1
  150. data/brut-css/bin/docs +0 -34
  151. data/brut-css/bin/publish +0 -21
  152. data/brut-css/bin/setup +0 -6
  153. data/brut-css/config/media-queries-all.css +0 -15
  154. data/brut-css/config/media-queries-minimal.css +0 -5
  155. data/brut-css/config/postcss.config.cjs +0 -7
  156. data/brut-css/config/pseudo-classes-all.css +0 -9
  157. data/brut-css/dx +0 -1
  158. data/brut-css/package-lock.json +0 -3165
  159. data/brut-css/package.json +0 -36
  160. data/brut-css/src/css/appearance.css +0 -145
  161. data/brut-css/src/css/border.css +0 -522
  162. data/brut-css/src/css/colors.css +0 -3502
  163. data/brut-css/src/css/dimensions.css +0 -548
  164. data/brut-css/src/css/flex.css +0 -179
  165. data/brut-css/src/css/index.css +0 -13
  166. data/brut-css/src/css/layout.css +0 -120
  167. data/brut-css/src/css/list.css +0 -41
  168. data/brut-css/src/css/positioning.css +0 -354
  169. data/brut-css/src/css/properties/colors.css +0 -455
  170. data/brut-css/src/css/properties/index.css +0 -3
  171. data/brut-css/src/css/properties/spacing.css +0 -140
  172. data/brut-css/src/css/properties/typography.css +0 -224
  173. data/brut-css/src/css/reset.css +0 -107
  174. data/brut-css/src/css/spacing.css +0 -585
  175. data/brut-css/src/css/typography.css +0 -519
  176. data/brut-css/src/css/utils.css +0 -104
  177. data/brut-css/src/docs/1_getting-started/1_overview.md +0 -46
  178. data/brut-css/src/docs/1_getting-started/2_installation.md +0 -25
  179. data/brut-css/src/docs/1_getting-started/3_core-concepts.md +0 -75
  180. data/brut-css/src/docs/1_getting-started/4_simple-example.md +0 -132
  181. data/brut-css/src/docs/1_getting-started/page.html.ejs +0 -10
  182. data/brut-css/src/docs/2_properties/page.html.ejs +0 -71
  183. data/brut-css/src/docs/3_classes/color-demo.html.ejs +0 -31
  184. data/brut-css/src/docs/3_classes/page.html.ejs +0 -87
  185. data/brut-css/src/docs/4_customization/1_design-system.md +0 -36
  186. data/brut-css/src/docs/4_customization/2_breakpoints.md +0 -75
  187. data/brut-css/src/docs/4_customization/3_pseudo-classes.md +0 -74
  188. data/brut-css/src/docs/4_customization/4_advanced-configuration.md +0 -40
  189. data/brut-css/src/docs/4_customization/page.html.ejs +0 -10
  190. data/brut-css/src/docs/docs.css +0 -98
  191. data/brut-css/src/docs/includes/body-and-header.html.ejs +0 -30
  192. data/brut-css/src/docs/includes/footer-and-rest.html.ejs +0 -9
  193. data/brut-css/src/docs/includes/head.html.ejs +0 -5
  194. data/brut-css/src/docs/includes/nav.html.ejs +0 -10
  195. data/brut-css/src/docs/index.html.ejs +0 -32
  196. data/brut-css/src/docs/prism-twilight.min.css +0 -1
  197. data/brut-css/src/js/Logger.js +0 -71
  198. data/brut-css/src/js/build.js +0 -111
  199. data/brut-css/src/js/cli/CLIArgError.js +0 -7
  200. data/brut-css/src/js/cli/Debug.js +0 -27
  201. data/brut-css/src/js/cli/DocsDir.js +0 -16
  202. data/brut-css/src/js/cli/DocsTemplateSourceDir.js +0 -16
  203. data/brut-css/src/js/cli/InputFile.js +0 -31
  204. data/brut-css/src/js/cli/MediaQueryConfigFile.js +0 -10
  205. data/brut-css/src/js/cli/OutputFile.js +0 -22
  206. data/brut-css/src/js/cli/ParsedArg.js +0 -17
  207. data/brut-css/src/js/cli/PathToBrutCSSRoot.js +0 -19
  208. data/brut-css/src/js/cli/PseudoClassConfigFile.js +0 -11
  209. data/brut-css/src/js/cli.js +0 -108
  210. data/brut-css/src/js/docGenerator.js +0 -467
  211. data/brut-css/src/js/mediaQueryConfigParser.js +0 -98
  212. data/brut-css/src/js/post-css-plugins/addMediaQueriesPlugin.js +0 -49
  213. data/brut-css/src/js/post-css-plugins/addPseudoClassesPlugin.js +0 -42
  214. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Category.js +0 -9
  215. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/DocState.js +0 -185
  216. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Documentable.js +0 -8
  217. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Group.js +0 -7
  218. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/ParsedComment.js +0 -73
  219. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Property.js +0 -9
  220. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/PropertyCategory.js +0 -4
  221. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/PropertyGroup.js +0 -8
  222. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Rule.js +0 -12
  223. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/RuleCategory.js +0 -4
  224. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/RuleGroup.js +0 -8
  225. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/SeeRef.js +0 -5
  226. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/SeeURL.js +0 -9
  227. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin.js +0 -49
  228. data/brut-css/src/js/post-css-plugins/generateRootCustomPropertiesPlugin.js +0 -45
  229. data/brut-css/src/js/pseudoClassConfigParser.js +0 -145
  230. data/brut-js/.projections.json +0 -10
  231. data/brut-js/README.md +0 -118
  232. data/brut-js/bin/build +0 -19
  233. data/brut-js/bin/ci +0 -5
  234. data/brut-js/bin/docs +0 -25
  235. data/brut-js/bin/publish +0 -21
  236. data/brut-js/bin/setup +0 -6
  237. data/brut-js/docs/README.md +0 -8
  238. data/brut-js/docs/jsdoc-plugins/customElementTag.js +0 -8
  239. data/brut-js/docs/jsdoc-theme/publish.js +0 -692
  240. data/brut-js/docs/jsdoc-theme/static/scripts/linenumber.js +0 -25
  241. data/brut-js/docs/jsdoc-theme/static/scripts/prettify/Apache-License-2.0.txt +0 -202
  242. data/brut-js/docs/jsdoc-theme/static/scripts/prettify/lang-css.js +0 -2
  243. data/brut-js/docs/jsdoc-theme/static/scripts/prettify/prettify.js +0 -28
  244. data/brut-js/docs/jsdoc-theme/static/styles/jsdoc-default.css +0 -327
  245. data/brut-js/docs/jsdoc-theme/static/styles/prettify-jsdoc.css +0 -111
  246. data/brut-js/docs/jsdoc-theme/static/styles/prettify-tomorrow.css +0 -132
  247. data/brut-js/docs/jsdoc-theme/tmpl/augments.tmpl +0 -10
  248. data/brut-js/docs/jsdoc-theme/tmpl/container.tmpl +0 -199
  249. data/brut-js/docs/jsdoc-theme/tmpl/details.tmpl +0 -143
  250. data/brut-js/docs/jsdoc-theme/tmpl/example.tmpl +0 -2
  251. data/brut-js/docs/jsdoc-theme/tmpl/examples.tmpl +0 -13
  252. data/brut-js/docs/jsdoc-theme/tmpl/exceptions.tmpl +0 -32
  253. data/brut-js/docs/jsdoc-theme/tmpl/layout.tmpl +0 -38
  254. data/brut-js/docs/jsdoc-theme/tmpl/mainpage.tmpl +0 -14
  255. data/brut-js/docs/jsdoc-theme/tmpl/members.tmpl +0 -38
  256. data/brut-js/docs/jsdoc-theme/tmpl/method.tmpl +0 -131
  257. data/brut-js/docs/jsdoc-theme/tmpl/modifies.tmpl +0 -14
  258. data/brut-js/docs/jsdoc-theme/tmpl/params.tmpl +0 -131
  259. data/brut-js/docs/jsdoc-theme/tmpl/properties.tmpl +0 -108
  260. data/brut-js/docs/jsdoc-theme/tmpl/returns.tmpl +0 -19
  261. data/brut-js/docs/jsdoc-theme/tmpl/source.tmpl +0 -8
  262. data/brut-js/docs/jsdoc-theme/tmpl/tutorial.tmpl +0 -19
  263. data/brut-js/docs/jsdoc-theme/tmpl/type.tmpl +0 -7
  264. data/brut-js/docs/jsdoc.config.json +0 -23
  265. data/brut-js/docs/package-lock.json +0 -343
  266. data/brut-js/docs/package.json +0 -7
  267. data/brut-js/dx +0 -1
  268. data/brut-js/package-lock.json +0 -2210
  269. data/brut-js/package.json +0 -36
  270. data/brut-js/specs/AjaxSubmit.spec.js +0 -453
  271. data/brut-js/specs/Autosubmit.spec.js +0 -127
  272. data/brut-js/specs/ConfirmSubmit.spec.js +0 -224
  273. data/brut-js/specs/ConstraintViolationMessage.spec.js +0 -33
  274. data/brut-js/specs/ConstraintViolationMessages.spec.js +0 -32
  275. data/brut-js/specs/CopyToClipboard.spec.js +0 -35
  276. data/brut-js/specs/Form.spec.js +0 -137
  277. data/brut-js/specs/I18nTranslation.spec.js +0 -19
  278. data/brut-js/specs/LocaleDetection.spec.js +0 -22
  279. data/brut-js/specs/Message.spec.js +0 -15
  280. data/brut-js/specs/SpecHelper.js +0 -23
  281. data/brut-js/specs/Tabs.spec.js +0 -41
  282. data/brut-js/specs/Toast.spec.js +0 -34
  283. data/brut-js/specs/config/asset_metadata.json +0 -7
  284. data/brut-js/src/AjaxSubmit.js +0 -499
  285. data/brut-js/src/Autosubmit.js +0 -63
  286. data/brut-js/src/BaseCustomElement.js +0 -261
  287. data/brut-js/src/ConfirmSubmit.js +0 -137
  288. data/brut-js/src/ConfirmationDialog.js +0 -143
  289. data/brut-js/src/ConstraintViolationMessage.js +0 -140
  290. data/brut-js/src/ConstraintViolationMessages.js +0 -98
  291. data/brut-js/src/CopyToClipboard.js +0 -96
  292. data/brut-js/src/Form.js +0 -147
  293. data/brut-js/src/I18nTranslation.js +0 -64
  294. data/brut-js/src/LocaleDetection.js +0 -117
  295. data/brut-js/src/Logger.js +0 -90
  296. data/brut-js/src/Message.js +0 -62
  297. data/brut-js/src/RichString.js +0 -116
  298. data/brut-js/src/Tabs.js +0 -168
  299. data/brut-js/src/Toast.js +0 -102
  300. data/brut-js/src/Tracing.js +0 -247
  301. data/brut-js/src/appForTestingOnly.js +0 -15
  302. data/brut-js/src/index.js +0 -133
  303. data/brut-js/src/testing/AssetMetadata.js +0 -35
  304. data/brut-js/src/testing/AssetMetadataLoader.js +0 -25
  305. data/brut-js/src/testing/CustomElementTest.js +0 -235
  306. data/brut-js/src/testing/DOMCreator.js +0 -45
  307. data/brut-js/src/testing/index.js +0 -48
  308. data/brut.gemspec +0 -71
  309. data/brutrb.com/.vitepress/config.mjs +0 -164
  310. data/brutrb.com/.vitepress/plugins/jsdocLinker.js +0 -34
  311. data/brutrb.com/.vitepress/plugins/rdocLinker.js +0 -18
  312. data/brutrb.com/.vitepress/theme/custom.css +0 -14
  313. data/brutrb.com/.vitepress/theme/index.js +0 -18
  314. data/brutrb.com/.vitepress/theme/style.css +0 -139
  315. data/brutrb.com/adrs.md +0 -16
  316. data/brutrb.com/ai.md +0 -68
  317. data/brutrb.com/assets.md +0 -131
  318. data/brutrb.com/bin/build +0 -5
  319. data/brutrb.com/bin/deploy +0 -7
  320. data/brutrb.com/bin/dev +0 -5
  321. data/brutrb.com/bin/setup +0 -6
  322. data/brutrb.com/brut-js.md +0 -128
  323. data/brutrb.com/business-logic.md +0 -55
  324. data/brutrb.com/cli.md +0 -274
  325. data/brutrb.com/components.md +0 -265
  326. data/brutrb.com/configuration.md +0 -256
  327. data/brutrb.com/css.md +0 -103
  328. data/brutrb.com/custom-element-tests.md +0 -148
  329. data/brutrb.com/database-access.md +0 -201
  330. data/brutrb.com/database-schema.md +0 -320
  331. data/brutrb.com/deployment.md +0 -158
  332. data/brutrb.com/dev-environment.md +0 -186
  333. data/brutrb.com/dir-structure.md +0 -120
  334. data/brutrb.com/doc-conventions.md +0 -41
  335. data/brutrb.com/dx +0 -1
  336. data/brutrb.com/end-to-end-tests.md +0 -176
  337. data/brutrb.com/features.md +0 -373
  338. data/brutrb.com/flash-and-session.md +0 -208
  339. data/brutrb.com/form-constraints.md +0 -266
  340. data/brutrb.com/forms.md +0 -238
  341. data/brutrb.com/getting-started.md +0 -142
  342. data/brutrb.com/handlers.md +0 -177
  343. data/brutrb.com/hooks.md +0 -176
  344. data/brutrb.com/i18n.md +0 -190
  345. data/brutrb.com/images/DevEnvironment.graffle +0 -0
  346. data/brutrb.com/images/DevEnvironment.png +0 -0
  347. data/brutrb.com/images/LogoSquare.png +0 -0
  348. data/brutrb.com/images/LogoStop.png +0 -0
  349. data/brutrb.com/images/LogoTall.png +0 -0
  350. data/brutrb.com/images/Makefile +0 -10
  351. data/brutrb.com/images/OverviewMetro.graffle +0 -0
  352. data/brutrb.com/images/OverviewMetro.png +0 -0
  353. data/brutrb.com/images/dev-env-overview.dot +0 -54
  354. data/brutrb.com/images/dev-env-overview.png +0 -0
  355. data/brutrb.com/images/dev-env-protocol.dot +0 -37
  356. data/brutrb.com/images/dev-env-protocol.png +0 -0
  357. data/brutrb.com/images/overview.graffle +0 -0
  358. data/brutrb.com/images/overview.png +0 -0
  359. data/brutrb.com/images/spa.dot +0 -19
  360. data/brutrb.com/images/spa.png +0 -0
  361. data/brutrb.com/images/tutorial/02-confirmation-dialog-browser-element-styled.png +0 -0
  362. data/brutrb.com/images/tutorial/02-confirmation-dialog-browser-element.png +0 -0
  363. data/brutrb.com/images/tutorial/02-confirmation-dialog-browser.png +0 -0
  364. data/brutrb.com/images/tutorial/02-confirmation-flow.graffle +0 -0
  365. data/brutrb.com/images/tutorial/02-confirmation-flow.png +0 -0
  366. data/brutrb.com/images/tutorial/basic-form-with-violations.png +0 -0
  367. data/brutrb.com/images/tutorial/basic-form.png +0 -0
  368. data/brutrb.com/images/tutorial/initial-home-page.png +0 -0
  369. data/brutrb.com/images/tutorial/new-post-editor.png +0 -0
  370. data/brutrb.com/images/tutorial/new-post-home-page.png +0 -0
  371. data/brutrb.com/images/tutorial/styled-form-with-server-side-violations.png +0 -0
  372. data/brutrb.com/images/tutorial/styled-form-with-violations.png +0 -0
  373. data/brutrb.com/images/tutorial/styled-home-page-with-posts.png +0 -0
  374. data/brutrb.com/images/tutorial/styled-home-page.png +0 -0
  375. data/brutrb.com/images/tutorial/welcome-to-brut.png +0 -0
  376. data/brutrb.com/images/workspace-protocol.dot +0 -44
  377. data/brutrb.com/images/workspace-protocol.png +0 -0
  378. data/brutrb.com/index.md +0 -34
  379. data/brutrb.com/instrumentation.md +0 -331
  380. data/brutrb.com/javascript.md +0 -122
  381. data/brutrb.com/jobs.md +0 -114
  382. data/brutrb.com/keyword-injection.md +0 -195
  383. data/brutrb.com/layouts.md +0 -156
  384. data/brutrb.com/lsp.md +0 -23
  385. data/brutrb.com/markdown-examples.md +0 -85
  386. data/brutrb.com/middleware.md +0 -80
  387. data/brutrb.com/overview.md +0 -68
  388. data/brutrb.com/package-lock.json +0 -2451
  389. data/brutrb.com/package.json +0 -11
  390. data/brutrb.com/pages.md +0 -290
  391. data/brutrb.com/public/SocialImage.png +0 -0
  392. data/brutrb.com/public/favicon.ico +0 -0
  393. data/brutrb.com/recipes/alternate-layouts.md +0 -32
  394. data/brutrb.com/recipes/authentication.md +0 -336
  395. data/brutrb.com/recipes/custom-flash.md +0 -51
  396. data/brutrb.com/recipes/dev-env-secrets.md +0 -87
  397. data/brutrb.com/recipes/form-errors.md +0 -148
  398. data/brutrb.com/recipes/indexed-forms.md +0 -149
  399. data/brutrb.com/recipes/migrations.md +0 -210
  400. data/brutrb.com/recipes/text-field-component.md +0 -182
  401. data/brutrb.com/roadmap.md +0 -52
  402. data/brutrb.com/routes.md +0 -189
  403. data/brutrb.com/security.md +0 -102
  404. data/brutrb.com/seed-data.md +0 -63
  405. data/brutrb.com/space-time-continuum.md +0 -81
  406. data/brutrb.com/tutorial.md +0 -138
  407. data/brutrb.com/tutorials/01-intro.md +0 -1654
  408. data/brutrb.com/tutorials/02-dialog.md +0 -569
  409. data/brutrb.com/unit-tests.md +0 -148
  410. data/brutrb.com/why.md +0 -19
  411. data/docker-compose.dx.yml +0 -25
  412. data/docs/404.html +0 -26
  413. data/docs/CNAME +0 -1
  414. data/docs/SocialImage.png +0 -0
  415. data/docs/adrs.html +0 -29
  416. data/docs/ai.html +0 -29
  417. data/docs/api/Brut/BackEnd/SeedData.html +0 -493
  418. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server/FlushSpans.html +0 -214
  419. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server.html +0 -125
  420. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares.html +0 -125
  421. data/docs/api/Brut/BackEnd/Sidekiq.html +0 -125
  422. data/docs/api/Brut/BackEnd/Validators/FormValidator.html +0 -414
  423. data/docs/api/Brut/BackEnd/Validators.html +0 -128
  424. data/docs/api/Brut/BackEnd.html +0 -132
  425. data/docs/api/Brut/CLI/App.html +0 -1601
  426. data/docs/api/Brut/CLI/AppRunner.html +0 -491
  427. data/docs/api/Brut/CLI/Apps/BuildAssets/All.html +0 -264
  428. data/docs/api/Brut/CLI/Apps/BuildAssets/CSS.html +0 -306
  429. data/docs/api/Brut/CLI/Apps/BuildAssets/Images.html +0 -262
  430. data/docs/api/Brut/CLI/Apps/BuildAssets/JS.html +0 -314
  431. data/docs/api/Brut/CLI/Apps/BuildAssets.html +0 -183
  432. data/docs/api/Brut/CLI/Apps/DB/Create.html +0 -365
  433. data/docs/api/Brut/CLI/Apps/DB/Drop.html +0 -357
  434. data/docs/api/Brut/CLI/Apps/DB/Migrate.html +0 -389
  435. data/docs/api/Brut/CLI/Apps/DB/NewMigration.html +0 -339
  436. data/docs/api/Brut/CLI/Apps/DB/Rebuild.html +0 -329
  437. data/docs/api/Brut/CLI/Apps/DB/Seed.html +0 -347
  438. data/docs/api/Brut/CLI/Apps/DB/Status.html +0 -383
  439. data/docs/api/Brut/CLI/Apps/DB.html +0 -183
  440. data/docs/api/Brut/CLI/Apps/DeployBase/GitChecks.html +0 -270
  441. data/docs/api/Brut/CLI/Apps/DeployBase.html +0 -257
  442. data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy/Deploy.html +0 -587
  443. data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy.html +0 -196
  444. data/docs/api/Brut/CLI/Apps/Scaffold/Action/Route.html +0 -303
  445. data/docs/api/Brut/CLI/Apps/Scaffold/Action.html +0 -508
  446. data/docs/api/Brut/CLI/Apps/Scaffold/Component.html +0 -398
  447. data/docs/api/Brut/CLI/Apps/Scaffold/CustomElementTest.html +0 -374
  448. data/docs/api/Brut/CLI/Apps/Scaffold/DbModel.html +0 -384
  449. data/docs/api/Brut/CLI/Apps/Scaffold/E2ETest.html +0 -410
  450. data/docs/api/Brut/CLI/Apps/Scaffold/Form.html +0 -262
  451. data/docs/api/Brut/CLI/Apps/Scaffold/Page/Route.html +0 -303
  452. data/docs/api/Brut/CLI/Apps/Scaffold/Page.html +0 -480
  453. data/docs/api/Brut/CLI/Apps/Scaffold/RoutesEditor.html +0 -450
  454. data/docs/api/Brut/CLI/Apps/Scaffold/Test.html +0 -380
  455. data/docs/api/Brut/CLI/Apps/Scaffold.html +0 -253
  456. data/docs/api/Brut/CLI/Apps/Test/Audit.html +0 -470
  457. data/docs/api/Brut/CLI/Apps/Test/E2e.html +0 -407
  458. data/docs/api/Brut/CLI/Apps/Test/JS.html +0 -262
  459. data/docs/api/Brut/CLI/Apps/Test/Run.html +0 -578
  460. data/docs/api/Brut/CLI/Apps/Test.html +0 -253
  461. data/docs/api/Brut/CLI/Apps.html +0 -125
  462. data/docs/api/Brut/CLI/Command.html +0 -2425
  463. data/docs/api/Brut/CLI/Error.html +0 -139
  464. data/docs/api/Brut/CLI/ExecutionResults/Result.html +0 -664
  465. data/docs/api/Brut/CLI/ExecutionResults.html +0 -675
  466. data/docs/api/Brut/CLI/Executor.html +0 -561
  467. data/docs/api/Brut/CLI/InvalidOption.html +0 -245
  468. data/docs/api/Brut/CLI/Options.html +0 -880
  469. data/docs/api/Brut/CLI/Output.html +0 -699
  470. data/docs/api/Brut/CLI/SystemExecError.html +0 -451
  471. data/docs/api/Brut/CLI.html +0 -263
  472. data/docs/api/Brut/FactoryBot.html +0 -225
  473. data/docs/api/Brut/Framework/App.html +0 -1097
  474. data/docs/api/Brut/Framework/Config.html +0 -1071
  475. data/docs/api/Brut/Framework/Container.html +0 -1464
  476. data/docs/api/Brut/Framework/Error.html +0 -140
  477. data/docs/api/Brut/Framework/Errors/AbstractMethod.html +0 -232
  478. data/docs/api/Brut/Framework/Errors/Bug.html +0 -234
  479. data/docs/api/Brut/Framework/Errors/MissingConfiguration.html +0 -257
  480. data/docs/api/Brut/Framework/Errors/MissingParameter.html +0 -273
  481. data/docs/api/Brut/Framework/Errors/NoClassForPath.html +0 -471
  482. data/docs/api/Brut/Framework/Errors/NotFound.html +0 -308
  483. data/docs/api/Brut/Framework/Errors/NotImplemented.html +0 -234
  484. data/docs/api/Brut/Framework/Errors.html +0 -351
  485. data/docs/api/Brut/Framework/FussyTypeEnforcement.html +0 -392
  486. data/docs/api/Brut/Framework/MCP.html +0 -871
  487. data/docs/api/Brut/Framework/ProjectEnvironment.html +0 -648
  488. data/docs/api/Brut/Framework.html +0 -129
  489. data/docs/api/Brut/FrontEnd/AssetPathResolver.html +0 -317
  490. data/docs/api/Brut/FrontEnd/Component/Helpers.html +0 -420
  491. data/docs/api/Brut/FrontEnd/Component.html +0 -434
  492. data/docs/api/Brut/FrontEnd/Components/ConstraintViolations.html +0 -491
  493. data/docs/api/Brut/FrontEnd/Components/FormTag.html +0 -526
  494. data/docs/api/Brut/FrontEnd/Components/I18nTranslations.html +0 -313
  495. data/docs/api/Brut/FrontEnd/Components/Input.html +0 -195
  496. data/docs/api/Brut/FrontEnd/Components/Inputs/ButtonTag.html +0 -447
  497. data/docs/api/Brut/FrontEnd/Components/Inputs/CsrfToken.html +0 -339
  498. data/docs/api/Brut/FrontEnd/Components/Inputs/InputTag.html +0 -568
  499. data/docs/api/Brut/FrontEnd/Components/Inputs/RadioButton.html +0 -419
  500. data/docs/api/Brut/FrontEnd/Components/Inputs/SelectTagWithOptions.html +0 -610
  501. data/docs/api/Brut/FrontEnd/Components/Inputs/TextareaTag.html +0 -534
  502. data/docs/api/Brut/FrontEnd/Components/Inputs.html +0 -125
  503. data/docs/api/Brut/FrontEnd/Components/LocaleDetection.html +0 -367
  504. data/docs/api/Brut/FrontEnd/Components/PageIdentifier.html +0 -355
  505. data/docs/api/Brut/FrontEnd/Components/TimeTag.html +0 -655
  506. data/docs/api/Brut/FrontEnd/Components/Traceparent.html +0 -352
  507. data/docs/api/Brut/FrontEnd/Components.html +0 -156
  508. data/docs/api/Brut/FrontEnd/CsrfProtector.html +0 -250
  509. data/docs/api/Brut/FrontEnd/Download.html +0 -467
  510. data/docs/api/Brut/FrontEnd/Flash.html +0 -1150
  511. data/docs/api/Brut/FrontEnd/Form.html +0 -1227
  512. data/docs/api/Brut/FrontEnd/Forms/Button.html +0 -331
  513. data/docs/api/Brut/FrontEnd/Forms/ButtonInputDefinition.html +0 -537
  514. data/docs/api/Brut/FrontEnd/Forms/ConstraintViolation.html +0 -590
  515. data/docs/api/Brut/FrontEnd/Forms/Input/Color.html +0 -201
  516. data/docs/api/Brut/FrontEnd/Forms/Input/TimeOfDay.html +0 -535
  517. data/docs/api/Brut/FrontEnd/Forms/Input.html +0 -1567
  518. data/docs/api/Brut/FrontEnd/Forms/InputDeclarations.html +0 -635
  519. data/docs/api/Brut/FrontEnd/Forms/InputDefinition.html +0 -1336
  520. data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInput.html +0 -730
  521. data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInputDefinition.html +0 -587
  522. data/docs/api/Brut/FrontEnd/Forms/SelectInput.html +0 -734
  523. data/docs/api/Brut/FrontEnd/Forms/SelectInputDefinition.html +0 -582
  524. data/docs/api/Brut/FrontEnd/Forms/ValidityState.html +0 -659
  525. data/docs/api/Brut/FrontEnd/Forms.html +0 -127
  526. data/docs/api/Brut/FrontEnd/GenericResponse.html +0 -377
  527. data/docs/api/Brut/FrontEnd/Handler.html +0 -442
  528. data/docs/api/Brut/FrontEnd/Handlers/CspReportingHandler.html +0 -318
  529. data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler/TraceParent.html +0 -336
  530. data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler.html +0 -399
  531. data/docs/api/Brut/FrontEnd/Handlers/LocaleDetectionHandler.html +0 -354
  532. data/docs/api/Brut/FrontEnd/Handlers/MissingHandler/Form.html +0 -151
  533. data/docs/api/Brut/FrontEnd/Handlers/MissingHandler.html +0 -315
  534. data/docs/api/Brut/FrontEnd/Handlers.html +0 -125
  535. data/docs/api/Brut/FrontEnd/HandlingResults.html +0 -339
  536. data/docs/api/Brut/FrontEnd/HttpMethod.html +0 -661
  537. data/docs/api/Brut/FrontEnd/HttpStatus.html +0 -496
  538. data/docs/api/Brut/FrontEnd/InlineSvgLocator.html +0 -284
  539. data/docs/api/Brut/FrontEnd/Layout.html +0 -486
  540. data/docs/api/Brut/FrontEnd/Middleware.html +0 -135
  541. data/docs/api/Brut/FrontEnd/Middlewares/AnnotateBrutOwnedPaths.html +0 -288
  542. data/docs/api/Brut/FrontEnd/Middlewares/Favicon.html +0 -292
  543. data/docs/api/Brut/FrontEnd/Middlewares/OpenTelemetrySpan.html +0 -324
  544. data/docs/api/Brut/FrontEnd/Middlewares/ReloadApp.html +0 -376
  545. data/docs/api/Brut/FrontEnd/Middlewares.html +0 -125
  546. data/docs/api/Brut/FrontEnd/Page.html +0 -781
  547. data/docs/api/Brut/FrontEnd/Pages/MissingPage.html +0 -797
  548. data/docs/api/Brut/FrontEnd/Pages.html +0 -125
  549. data/docs/api/Brut/FrontEnd/RequestContext.html +0 -1312
  550. data/docs/api/Brut/FrontEnd/RouteHook.html +0 -424
  551. data/docs/api/Brut/FrontEnd/RouteHooks/AgeFlash.html +0 -242
  552. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineScripts.html +0 -249
  553. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts/ReportOnly.html +0 -264
  554. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts.html +0 -261
  555. data/docs/api/Brut/FrontEnd/RouteHooks/LocaleDetection.html +0 -284
  556. data/docs/api/Brut/FrontEnd/RouteHooks/SetupRequestContext.html +0 -252
  557. data/docs/api/Brut/FrontEnd/RouteHooks.html +0 -115
  558. data/docs/api/Brut/FrontEnd/Routing/FormHandlerRoute.html +0 -227
  559. data/docs/api/Brut/FrontEnd/Routing/FormRoute.html +0 -305
  560. data/docs/api/Brut/FrontEnd/Routing/MissingForm.html +0 -324
  561. data/docs/api/Brut/FrontEnd/Routing/MissingHandler.html +0 -319
  562. data/docs/api/Brut/FrontEnd/Routing/MissingPage.html +0 -315
  563. data/docs/api/Brut/FrontEnd/Routing/MissingPath.html +0 -315
  564. data/docs/api/Brut/FrontEnd/Routing/PageRoute.html +0 -327
  565. data/docs/api/Brut/FrontEnd/Routing/Route.html +0 -761
  566. data/docs/api/Brut/FrontEnd/Routing.html +0 -927
  567. data/docs/api/Brut/FrontEnd/Session.html +0 -1195
  568. data/docs/api/Brut/FrontEnd.html +0 -134
  569. data/docs/api/Brut/I18n/BaseMethods.html +0 -931
  570. data/docs/api/Brut/I18n/ForBackEnd.html +0 -302
  571. data/docs/api/Brut/I18n/ForCLI.html +0 -302
  572. data/docs/api/Brut/I18n/ForHTML.html +0 -296
  573. data/docs/api/Brut/I18n/HTTPAcceptLanguage/AlwaysEnglish.html +0 -316
  574. data/docs/api/Brut/I18n/HTTPAcceptLanguage.html +0 -930
  575. data/docs/api/Brut/I18n.html +0 -127
  576. data/docs/api/Brut/Instrumentation/LoggerSpanExporter.html +0 -435
  577. data/docs/api/Brut/Instrumentation/Methods/ClassMethods.html +0 -596
  578. data/docs/api/Brut/Instrumentation/Methods.html +0 -173
  579. data/docs/api/Brut/Instrumentation/OpenTelemetry/NormalizedAttributes.html +0 -286
  580. data/docs/api/Brut/Instrumentation/OpenTelemetry/Span.html +0 -302
  581. data/docs/api/Brut/Instrumentation/OpenTelemetry.html +0 -866
  582. data/docs/api/Brut/Instrumentation.html +0 -128
  583. data/docs/api/Brut/RubocopConfig.html +0 -237
  584. data/docs/api/Brut/SinatraHelpers/ClassMethods.html +0 -534
  585. data/docs/api/Brut/SinatraHelpers.html +0 -281
  586. data/docs/api/Brut/SpecSupport/ClockSupport.html +0 -383
  587. data/docs/api/Brut/SpecSupport/ComponentSupport.html +0 -496
  588. data/docs/api/Brut/SpecSupport/E2ETestServer.html +0 -503
  589. data/docs/api/Brut/SpecSupport/E2eSupport.html +0 -142
  590. data/docs/api/Brut/SpecSupport/EnhancedNode.html +0 -403
  591. data/docs/api/Brut/SpecSupport/FlashSupport.html +0 -278
  592. data/docs/api/Brut/SpecSupport/GeneralSupport/ClassMethods.html +0 -401
  593. data/docs/api/Brut/SpecSupport/GeneralSupport.html +0 -195
  594. data/docs/api/Brut/SpecSupport/HandlerSupport.html +0 -160
  595. data/docs/api/Brut/SpecSupport/Matchers/BeABug.html +0 -142
  596. data/docs/api/Brut/SpecSupport/Matchers/BePageFor.html +0 -142
  597. data/docs/api/Brut/SpecSupport/Matchers/BeRoutingFor.html +0 -155
  598. data/docs/api/Brut/SpecSupport/Matchers/HaveConstraintViolation.html +0 -583
  599. data/docs/api/Brut/SpecSupport/Matchers/HaveGenerated.html +0 -149
  600. data/docs/api/Brut/SpecSupport/Matchers/HaveHTMLAttribute.html +0 -466
  601. data/docs/api/Brut/SpecSupport/Matchers/HaveI18nString.html +0 -149
  602. data/docs/api/Brut/SpecSupport/Matchers/HaveLinkTo.html +0 -149
  603. data/docs/api/Brut/SpecSupport/Matchers/HaveRedirectedTo.html +0 -165
  604. data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedHttpStatus.html +0 -158
  605. data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedRackResponse.html +0 -156
  606. data/docs/api/Brut/SpecSupport/Matchers.html +0 -125
  607. data/docs/api/Brut/SpecSupport/RSpecSetup/OptionalSidekiqSupport.html +0 -335
  608. data/docs/api/Brut/SpecSupport/RSpecSetup.html +0 -637
  609. data/docs/api/Brut/SpecSupport/SessionSupport.html +0 -196
  610. data/docs/api/Brut/SpecSupport.html +0 -129
  611. data/docs/api/Brut.html +0 -341
  612. data/docs/api/Clock.html +0 -603
  613. data/docs/api/ModuleName.html +0 -595
  614. data/docs/api/RichString.html +0 -775
  615. data/docs/api/SemanticLogger/Appender/Async.html +0 -219
  616. data/docs/api/Sequel/Extensions/BrutInstrumentation.html +0 -119
  617. data/docs/api/Sequel/Extensions/BrutMigrations.html +0 -541
  618. data/docs/api/Sequel/Extensions.html +0 -117
  619. data/docs/api/Sequel/Plugins/CreatedAt/InstanceMethods.html +0 -105
  620. data/docs/api/Sequel/Plugins/CreatedAt.html +0 -125
  621. data/docs/api/Sequel/Plugins/ExternalId/ClassMethods.html +0 -207
  622. data/docs/api/Sequel/Plugins/ExternalId/InstanceMethods.html +0 -186
  623. data/docs/api/Sequel/Plugins/ExternalId.html +0 -218
  624. data/docs/api/Sequel/Plugins/FindBang/ClassMethods.html +0 -202
  625. data/docs/api/Sequel/Plugins/FindBang.html +0 -125
  626. data/docs/api/Sequel/Plugins.html +0 -117
  627. data/docs/api/Sequel.html +0 -117
  628. data/docs/api/_index.html +0 -1719
  629. data/docs/api/class_list.html +0 -54
  630. data/docs/api/css/common.css +0 -1
  631. data/docs/api/css/full_list.css +0 -59
  632. data/docs/api/css/style.css +0 -504
  633. data/docs/api/file.README.html +0 -172
  634. data/docs/api/file_list.html +0 -59
  635. data/docs/api/frames.html +0 -22
  636. data/docs/api/index.html +0 -172
  637. data/docs/api/js/app.js +0 -344
  638. data/docs/api/js/full_list.js +0 -242
  639. data/docs/api/js/jquery.js +0 -4
  640. data/docs/api/method_list.html +0 -4422
  641. data/docs/api/top-level-namespace.html +0 -112
  642. data/docs/assets/02-confirmation-dialog-browser-element-styled.3NEGM20-.png +0 -0
  643. data/docs/assets/02-confirmation-dialog-browser-element.DPsf0xUW.png +0 -0
  644. data/docs/assets/02-confirmation-dialog-browser.DH8ALFO4.png +0 -0
  645. data/docs/assets/02-confirmation-flow.D9gZ0S5U.png +0 -0
  646. data/docs/assets/DevEnvironment.DaFcVfwP.png +0 -0
  647. data/docs/assets/LogoStop.Gb3tDhL1.png +0 -0
  648. data/docs/assets/OverviewMetro.DUS-5fUZ.png +0 -0
  649. data/docs/assets/adrs.md.YglbWtQe.js +0 -1
  650. data/docs/assets/adrs.md.YglbWtQe.lean.js +0 -1
  651. data/docs/assets/ai.md.ChLnvDAX.js +0 -1
  652. data/docs/assets/ai.md.ChLnvDAX.lean.js +0 -1
  653. data/docs/assets/app.CovevI7X.js +0 -1
  654. data/docs/assets/assets.md.BEF6Oz6K.js +0 -19
  655. data/docs/assets/assets.md.BEF6Oz6K.lean.js +0 -1
  656. data/docs/assets/basic-form-with-violations.Cv6Y9-Q_.png +0 -0
  657. data/docs/assets/basic-form.DbHnu0oW.png +0 -0
  658. data/docs/assets/brut-js.md.BMz0X1Rz.js +0 -12
  659. data/docs/assets/brut-js.md.BMz0X1Rz.lean.js +0 -1
  660. data/docs/assets/business-logic.md.DbuaOYGU.js +0 -1
  661. data/docs/assets/business-logic.md.DbuaOYGU.lean.js +0 -1
  662. data/docs/assets/chunks/@localSearchIndexroot.BiNc3tFI.js +0 -1
  663. data/docs/assets/chunks/VPLocalSearchBox.CrvLAvKW.js +0 -8
  664. data/docs/assets/chunks/framework.C4nOkCZI.js +0 -18
  665. data/docs/assets/chunks/theme.BAi5_yQI.js +0 -2
  666. data/docs/assets/cli.md.DDMar_51.js +0 -122
  667. data/docs/assets/cli.md.DDMar_51.lean.js +0 -1
  668. data/docs/assets/components.md.9sqJ27Oc.js +0 -96
  669. data/docs/assets/components.md.9sqJ27Oc.lean.js +0 -1
  670. data/docs/assets/configuration.md.Cb_oAR8Z.js +0 -78
  671. data/docs/assets/configuration.md.Cb_oAR8Z.lean.js +0 -1
  672. data/docs/assets/css.md.K5rOCOQY.js +0 -21
  673. data/docs/assets/css.md.K5rOCOQY.lean.js +0 -1
  674. data/docs/assets/custom-element-tests.md.DiLe-eFw.js +0 -69
  675. data/docs/assets/custom-element-tests.md.DiLe-eFw.lean.js +0 -1
  676. data/docs/assets/database-access.md.Dc8l2Plf.js +0 -63
  677. data/docs/assets/database-access.md.Dc8l2Plf.lean.js +0 -1
  678. data/docs/assets/database-schema.md.BJ_JhXmO.js +0 -70
  679. data/docs/assets/database-schema.md.BJ_JhXmO.lean.js +0 -1
  680. data/docs/assets/deployment.md.CHTx2eTR.js +0 -55
  681. data/docs/assets/deployment.md.CHTx2eTR.lean.js +0 -1
  682. data/docs/assets/dev-env-protocol.DysDAtnz.png +0 -0
  683. data/docs/assets/dev-environment.md.B1S9p5ZK.js +0 -16
  684. data/docs/assets/dev-environment.md.B1S9p5ZK.lean.js +0 -1
  685. data/docs/assets/dir-structure.md.D1T2kGwj.js +0 -46
  686. data/docs/assets/dir-structure.md.D1T2kGwj.lean.js +0 -1
  687. data/docs/assets/doc-conventions.md.CDnWaEFg.js +0 -1
  688. data/docs/assets/doc-conventions.md.CDnWaEFg.lean.js +0 -1
  689. data/docs/assets/end-to-end-tests.md.BJJdNDYL.js +0 -28
  690. data/docs/assets/end-to-end-tests.md.BJJdNDYL.lean.js +0 -1
  691. data/docs/assets/features.md.BDWxnyNO.js +0 -154
  692. data/docs/assets/features.md.BDWxnyNO.lean.js +0 -1
  693. data/docs/assets/flash-and-session.md.CUsMxoNl.js +0 -79
  694. data/docs/assets/flash-and-session.md.CUsMxoNl.lean.js +0 -1
  695. data/docs/assets/form-constraints.md.KlfXSKm2.js +0 -90
  696. data/docs/assets/form-constraints.md.KlfXSKm2.lean.js +0 -1
  697. data/docs/assets/forms.md.BdpYpNIk.js +0 -64
  698. data/docs/assets/forms.md.BdpYpNIk.lean.js +0 -1
  699. data/docs/assets/getting-started.md.CKpNGvno.js +0 -31
  700. data/docs/assets/getting-started.md.CKpNGvno.lean.js +0 -1
  701. data/docs/assets/handlers.md.C5tUwmmo.js +0 -54
  702. data/docs/assets/handlers.md.C5tUwmmo.lean.js +0 -1
  703. data/docs/assets/hooks.md.CoiYCKRc.js +0 -80
  704. data/docs/assets/hooks.md.CoiYCKRc.lean.js +0 -1
  705. data/docs/assets/i18n.md.DxkCKhUw.js +0 -23
  706. data/docs/assets/i18n.md.DxkCKhUw.lean.js +0 -1
  707. data/docs/assets/index.md.DnphWyQd.js +0 -1
  708. data/docs/assets/index.md.DnphWyQd.lean.js +0 -1
  709. data/docs/assets/initial-home-page.DNIaYmgP.png +0 -0
  710. data/docs/assets/instrumentation.md.BcxjC4jd.js +0 -90
  711. data/docs/assets/instrumentation.md.BcxjC4jd.lean.js +0 -1
  712. data/docs/assets/javascript.md.D6fxhaQb.js +0 -31
  713. data/docs/assets/javascript.md.D6fxhaQb.lean.js +0 -1
  714. data/docs/assets/jobs.md.Bi3qb3v6.js +0 -25
  715. data/docs/assets/jobs.md.Bi3qb3v6.lean.js +0 -1
  716. data/docs/assets/keyword-injection.md.CqLnnzIz.js +0 -21
  717. data/docs/assets/keyword-injection.md.CqLnnzIz.lean.js +0 -1
  718. data/docs/assets/layouts.md.HEbeK7Jr.js +0 -68
  719. data/docs/assets/layouts.md.HEbeK7Jr.lean.js +0 -1
  720. data/docs/assets/lsp.md.bE9dW8n9.js +0 -1
  721. data/docs/assets/lsp.md.bE9dW8n9.lean.js +0 -1
  722. data/docs/assets/markdown-examples.md.BPmtHlc-.js +0 -33
  723. data/docs/assets/markdown-examples.md.BPmtHlc-.lean.js +0 -1
  724. data/docs/assets/middleware.md.BhOIsg59.js +0 -20
  725. data/docs/assets/middleware.md.BhOIsg59.lean.js +0 -1
  726. data/docs/assets/new-post-editor.DrHr-5oh.png +0 -0
  727. data/docs/assets/new-post-home-page.Bm34lyMg.png +0 -0
  728. data/docs/assets/overview.md.BpWAgPFH.js +0 -1
  729. data/docs/assets/overview.md.BpWAgPFH.lean.js +0 -1
  730. data/docs/assets/pages.md.B3sQXpEd.js +0 -45
  731. data/docs/assets/pages.md.B3sQXpEd.lean.js +0 -1
  732. data/docs/assets/recipes_alternate-layouts.md.C1QzVkA7.js +0 -22
  733. data/docs/assets/recipes_alternate-layouts.md.C1QzVkA7.lean.js +0 -1
  734. data/docs/assets/recipes_authentication.md.CyvoIW82.js +0 -157
  735. data/docs/assets/recipes_authentication.md.CyvoIW82.lean.js +0 -1
  736. data/docs/assets/recipes_custom-flash.md.6gFqf2uL.js +0 -26
  737. data/docs/assets/recipes_custom-flash.md.6gFqf2uL.lean.js +0 -1
  738. data/docs/assets/recipes_dev-env-secrets.md.DC_jVY9U.js +0 -12
  739. data/docs/assets/recipes_dev-env-secrets.md.DC_jVY9U.lean.js +0 -1
  740. data/docs/assets/recipes_form-errors.md.B5ptSzMO.js +0 -66
  741. data/docs/assets/recipes_form-errors.md.B5ptSzMO.lean.js +0 -1
  742. data/docs/assets/recipes_indexed-forms.md.BYYQGW2C.js +0 -74
  743. data/docs/assets/recipes_indexed-forms.md.BYYQGW2C.lean.js +0 -1
  744. data/docs/assets/recipes_migrations.md.Cid7-3cu.js +0 -97
  745. data/docs/assets/recipes_migrations.md.Cid7-3cu.lean.js +0 -1
  746. data/docs/assets/recipes_text-field-component.md.VhOsCtKI.js +0 -101
  747. data/docs/assets/recipes_text-field-component.md.VhOsCtKI.lean.js +0 -1
  748. data/docs/assets/roadmap.md.DqC1Y7Zt.js +0 -1
  749. data/docs/assets/roadmap.md.DqC1Y7Zt.lean.js +0 -1
  750. data/docs/assets/routes.md.C1dgIBtD.js +0 -21
  751. data/docs/assets/routes.md.C1dgIBtD.lean.js +0 -1
  752. data/docs/assets/security.md.Jn4SY1uK.js +0 -1
  753. data/docs/assets/security.md.Jn4SY1uK.lean.js +0 -1
  754. data/docs/assets/seed-data.md.UZW0WxYN.js +0 -14
  755. data/docs/assets/seed-data.md.UZW0WxYN.lean.js +0 -1
  756. data/docs/assets/spa.qejUdp-5.png +0 -0
  757. data/docs/assets/space-time-continuum.md.D9rYGDFH.js +0 -1
  758. data/docs/assets/space-time-continuum.md.D9rYGDFH.lean.js +0 -1
  759. data/docs/assets/style.B1z60PPQ.css +0 -1
  760. data/docs/assets/styled-form-with-server-side-violations.Bjxd8Dpv.png +0 -0
  761. data/docs/assets/styled-form-with-violations.Bv_sa9tg.png +0 -0
  762. data/docs/assets/styled-home-page-with-posts.Dd4kG89D.png +0 -0
  763. data/docs/assets/styled-home-page.BzdI7dWz.png +0 -0
  764. data/docs/assets/tutorial.md.BX6f6l00.js +0 -27
  765. data/docs/assets/tutorial.md.BX6f6l00.lean.js +0 -1
  766. data/docs/assets/tutorials_01-intro.md.CzZ3kpF_.js +0 -708
  767. data/docs/assets/tutorials_01-intro.md.CzZ3kpF_.lean.js +0 -1
  768. data/docs/assets/tutorials_02-dialog.md.Z_DOF2mU.js +0 -274
  769. data/docs/assets/tutorials_02-dialog.md.Z_DOF2mU.lean.js +0 -1
  770. data/docs/assets/unit-tests.md.vDsdBbO_.js +0 -13
  771. data/docs/assets/unit-tests.md.vDsdBbO_.lean.js +0 -1
  772. data/docs/assets/welcome-to-brut.VSWzl17-.png +0 -0
  773. data/docs/assets/why.md.4WpxdrQ2.js +0 -1
  774. data/docs/assets/why.md.4WpxdrQ2.lean.js +0 -1
  775. data/docs/assets/workspace-protocol.C0gXsoDb.png +0 -0
  776. data/docs/assets.html +0 -47
  777. data/docs/brut-css/brut.max.css +0 -22372
  778. data/docs/brut-css/classes/appearances.html +0 -783
  779. data/docs/brut-css/classes/background-colors.html +0 -3529
  780. data/docs/brut-css/classes/border-colors.html +0 -3529
  781. data/docs/brut-css/classes/borders.html +0 -2293
  782. data/docs/brut-css/classes/dimensions.html +0 -2581
  783. data/docs/brut-css/classes/flex.html +0 -917
  784. data/docs/brut-css/classes/foreground-colors.html +0 -3261
  785. data/docs/brut-css/classes/junk-drawer.html +0 -431
  786. data/docs/brut-css/classes/layout.html +0 -668
  787. data/docs/brut-css/classes/lists.html +0 -331
  788. data/docs/brut-css/classes/positioning.html +0 -1751
  789. data/docs/brut-css/classes/spacings.html +0 -2633
  790. data/docs/brut-css/classes/typography.html +0 -2206
  791. data/docs/brut-css/customization/advanced-configuration.html +0 -204
  792. data/docs/brut-css/customization/breakpoints.html +0 -227
  793. data/docs/brut-css/customization/design-system.html +0 -197
  794. data/docs/brut-css/customization/pseudo-classes.html +0 -228
  795. data/docs/brut-css/docs.css +0 -98
  796. data/docs/brut-css/getting-started/core-concepts.html +0 -234
  797. data/docs/brut-css/getting-started/installation.html +0 -190
  798. data/docs/brut-css/getting-started/overview.html +0 -210
  799. data/docs/brut-css/getting-started/simple-example.html +0 -285
  800. data/docs/brut-css/index.html +0 -193
  801. data/docs/brut-css/prism-twilight.min.css +0 -1
  802. data/docs/brut-css/properties/colors.html +0 -1548
  803. data/docs/brut-css/properties/spacings.html +0 -614
  804. data/docs/brut-css/properties/typography.html +0 -777
  805. data/docs/brut-js/api/AjaxSubmit.html +0 -452
  806. data/docs/brut-js/api/AjaxSubmit.js.html +0 -550
  807. data/docs/brut-js/api/Autosubmit.html +0 -192
  808. data/docs/brut-js/api/Autosubmit.js.html +0 -114
  809. data/docs/brut-js/api/BaseCustomElement.html +0 -1091
  810. data/docs/brut-js/api/BaseCustomElement.js.html +0 -312
  811. data/docs/brut-js/api/BrutCustomElements.html +0 -172
  812. data/docs/brut-js/api/BufferedLogger.html +0 -173
  813. data/docs/brut-js/api/ConfirmSubmit.html +0 -286
  814. data/docs/brut-js/api/ConfirmSubmit.js.html +0 -188
  815. data/docs/brut-js/api/ConfirmationDialog.html +0 -425
  816. data/docs/brut-js/api/ConfirmationDialog.js.html +0 -194
  817. data/docs/brut-js/api/ConstraintViolationMessage.html +0 -498
  818. data/docs/brut-js/api/ConstraintViolationMessage.js.html +0 -191
  819. data/docs/brut-js/api/ConstraintViolationMessages.html +0 -590
  820. data/docs/brut-js/api/ConstraintViolationMessages.js.html +0 -149
  821. data/docs/brut-js/api/CopyToClipboard.html +0 -345
  822. data/docs/brut-js/api/CopyToClipboard.js.html +0 -147
  823. data/docs/brut-js/api/Form.html +0 -291
  824. data/docs/brut-js/api/Form.js.html +0 -198
  825. data/docs/brut-js/api/I18nTranslation.html +0 -409
  826. data/docs/brut-js/api/I18nTranslation.js.html +0 -115
  827. data/docs/brut-js/api/LocaleDetection.html +0 -312
  828. data/docs/brut-js/api/LocaleDetection.js.html +0 -168
  829. data/docs/brut-js/api/Logger.html +0 -702
  830. data/docs/brut-js/api/Logger.js.html +0 -141
  831. data/docs/brut-js/api/Message.html +0 -238
  832. data/docs/brut-js/api/Message.js.html +0 -113
  833. data/docs/brut-js/api/PrefixedLogger.html +0 -369
  834. data/docs/brut-js/api/RichString.html +0 -1049
  835. data/docs/brut-js/api/RichString.js.html +0 -167
  836. data/docs/brut-js/api/Tabs.html +0 -295
  837. data/docs/brut-js/api/Tabs.js.html +0 -219
  838. data/docs/brut-js/api/Toast.html +0 -270
  839. data/docs/brut-js/api/Toast.js.html +0 -153
  840. data/docs/brut-js/api/Tracing.html +0 -277
  841. data/docs/brut-js/api/Tracing.js.html +0 -298
  842. data/docs/brut-js/api/external-CustomElementRegistry.html +0 -140
  843. data/docs/brut-js/api/external-Performance.html +0 -138
  844. data/docs/brut-js/api/external-Promise.html +0 -138
  845. data/docs/brut-js/api/external-ValidityState.html +0 -138
  846. data/docs/brut-js/api/external-Window.html +0 -233
  847. data/docs/brut-js/api/external-fetch.html +0 -138
  848. data/docs/brut-js/api/global.html +0 -400
  849. data/docs/brut-js/api/index.html +0 -168
  850. data/docs/brut-js/api/index.js.html +0 -184
  851. data/docs/brut-js/api/module-testing.html +0 -383
  852. data/docs/brut-js/api/scripts/linenumber.js +0 -25
  853. data/docs/brut-js/api/scripts/prettify/Apache-License-2.0.txt +0 -202
  854. data/docs/brut-js/api/scripts/prettify/lang-css.js +0 -2
  855. data/docs/brut-js/api/scripts/prettify/prettify.js +0 -28
  856. data/docs/brut-js/api/styles/jsdoc-default.css +0 -327
  857. data/docs/brut-js/api/styles/prettify-jsdoc.css +0 -111
  858. data/docs/brut-js/api/styles/prettify-tomorrow.css +0 -132
  859. data/docs/brut-js/api/testing.AssetMetadata.html +0 -172
  860. data/docs/brut-js/api/testing.AssetMetadataLoader.html +0 -171
  861. data/docs/brut-js/api/testing.CustomElementTest.html +0 -679
  862. data/docs/brut-js/api/testing.DOMCreator.html +0 -171
  863. data/docs/brut-js/api/testing_AssetMetadata.js.html +0 -86
  864. data/docs/brut-js/api/testing_AssetMetadataLoader.js.html +0 -76
  865. data/docs/brut-js/api/testing_CustomElementTest.js.html +0 -286
  866. data/docs/brut-js/api/testing_DOMCreator.js.html +0 -96
  867. data/docs/brut-js/api/testing_index.js.html +0 -99
  868. data/docs/brut-js.html +0 -40
  869. data/docs/business-logic.html +0 -29
  870. data/docs/cli.html +0 -150
  871. data/docs/components.html +0 -124
  872. data/docs/configuration.html +0 -106
  873. data/docs/css.html +0 -49
  874. data/docs/custom-element-tests.html +0 -97
  875. data/docs/database-access.html +0 -91
  876. data/docs/database-schema.html +0 -98
  877. data/docs/deployment.html +0 -83
  878. data/docs/dev-environment.html +0 -44
  879. data/docs/dir-structure.html +0 -74
  880. data/docs/doc-conventions.html +0 -29
  881. data/docs/end-to-end-tests.html +0 -56
  882. data/docs/favicon.ico +0 -0
  883. data/docs/features.html +0 -182
  884. data/docs/flash-and-session.html +0 -107
  885. data/docs/form-constraints.html +0 -118
  886. data/docs/forms.html +0 -92
  887. data/docs/getting-started.html +0 -59
  888. data/docs/handlers.html +0 -82
  889. data/docs/hashmap.json +0 -1
  890. data/docs/hooks.html +0 -108
  891. data/docs/i18n.html +0 -51
  892. data/docs/index.html +0 -29
  893. data/docs/instrumentation.html +0 -118
  894. data/docs/javascript.html +0 -59
  895. data/docs/jobs.html +0 -53
  896. data/docs/keyword-injection.html +0 -49
  897. data/docs/layouts.html +0 -96
  898. data/docs/lsp.html +0 -29
  899. data/docs/markdown-examples.html +0 -61
  900. data/docs/middleware.html +0 -48
  901. data/docs/overview.html +0 -29
  902. data/docs/pages.html +0 -73
  903. data/docs/recipes/alternate-layouts.html +0 -50
  904. data/docs/recipes/authentication.html +0 -185
  905. data/docs/recipes/custom-flash.html +0 -54
  906. data/docs/recipes/dev-env-secrets.html +0 -40
  907. data/docs/recipes/form-errors.html +0 -94
  908. data/docs/recipes/indexed-forms.html +0 -102
  909. data/docs/recipes/migrations.html +0 -125
  910. data/docs/recipes/text-field-component.html +0 -129
  911. data/docs/roadmap.html +0 -29
  912. data/docs/routes.html +0 -49
  913. data/docs/security.html +0 -29
  914. data/docs/seed-data.html +0 -42
  915. data/docs/space-time-continuum.html +0 -29
  916. data/docs/tutorial.html +0 -55
  917. data/docs/tutorials/01-intro.html +0 -736
  918. data/docs/tutorials/02-dialog.html +0 -302
  919. data/docs/unit-tests.html +0 -41
  920. data/docs/vp-icons.css +0 -1
  921. data/docs/why.html +0 -29
  922. data/docs-todo.md +0 -32
  923. data/dx/bash_customizations +0 -6
  924. data/dx/build +0 -73
  925. data/dx/build.pre +0 -15
  926. data/dx/docker-compose.env +0 -22
  927. data/dx/dx.sh.lib +0 -24
  928. data/dx/exec +0 -75
  929. data/dx/setupkit.sh.lib +0 -144
  930. data/dx/show-help-in-app-container-then-wait.sh +0 -38
  931. data/lib/brut/cli/app.rb +0 -238
  932. data/lib/brut/cli/app_runner.rb +0 -252
  933. data/lib/brut/cli/command.rb +0 -258
  934. data/lib/brut/cli/execution_results.rb +0 -119
  935. data/lib/brut/front_end/layouts/_internal.html.erb +0 -68
  936. data/lib/brut/front_end/pages/_missing_page.html.erb +0 -17
  937. data/mkbrut/.gitignore +0 -16
  938. data/mkbrut/CODE_OF_CONDUCT.txt +0 -100
  939. data/mkbrut/Gemfile +0 -3
  940. data/mkbrut/Gemfile.lock +0 -20
  941. data/mkbrut/LICENSE.txt +0 -370
  942. data/mkbrut/README.md +0 -145
  943. data/mkbrut/Rakefile +0 -2
  944. data/mkbrut/bin/build +0 -36
  945. data/mkbrut/bin/ci +0 -19
  946. data/mkbrut/bin/docs +0 -19
  947. data/mkbrut/bin/publish +0 -129
  948. data/mkbrut/bin/rake +0 -16
  949. data/mkbrut/bin/setup +0 -30
  950. data/mkbrut/brut-welcome.png +0 -0
  951. data/mkbrut/deploy/.dockerignore +0 -2
  952. data/mkbrut/deploy/Dockerfile +0 -25
  953. data/mkbrut/dx +0 -1
  954. data/mkbrut/exe/mkbrut +0 -5
  955. data/mkbrut/lib/mkbrut/app_name.rb +0 -29
  956. data/mkbrut/lib/mkbrut/app_options.rb +0 -36
  957. data/mkbrut/lib/mkbrut/cli.rb +0 -189
  958. data/mkbrut/lib/mkbrut/erb_binding_delegate.rb +0 -20
  959. data/mkbrut/lib/mkbrut/ops.rb +0 -17
  960. data/mkbrut/lib/mkbrut/organization.rb +0 -5
  961. data/mkbrut/lib/mkbrut/segments.rb +0 -8
  962. data/mkbrut/lib/mkbrut/version.rb +0 -3
  963. data/mkbrut/lib/mkbrut.rb +0 -20
  964. data/mkbrut/mkbrut.gemspec +0 -34
  965. data/mkbrut/templates/Base/app/src/front_end/images/LogoPylon.png +0 -0
  966. data/mkbrut/templates/Base/bin/build-assets +0 -7
  967. data/mkbrut/templates/Base/bin/ci +0 -39
  968. data/mkbrut/templates/Base/bin/db +0 -9
  969. data/mkbrut/templates/Base/bin/scaffold +0 -9
  970. data/mkbrut/templates/Base/bin/setup +0 -287
  971. data/mkbrut/templates/Base/bin/test +0 -9
  972. data/mkbrut/templates/Base/bin/test-server +0 -29
  973. data/mkbrut/templates/Base/dx/prune +0 -19
  974. data/mkbrut/templates/Base/dx/start +0 -30
  975. data/mkbrut/templates/Base/dx/stop +0 -23
  976. data/mkbrut/templates/segments/Heroku/deploy/heroku_config.rb +0 -27
  977. data/specs/brut/front_end/forms/input.spec.rb +0 -978
  978. data/specs/brut/front_end/forms/radio_button_group_input.spec.rb +0 -54
  979. data/specs/brut/front_end/forms/select_input.spec.rb +0 -54
  980. data/specs/brut/instrumentation/methods.spec.rb +0 -399
  981. data/specs/brut/junk_drawer.spec.rb +0 -79
  982. data/specs/spec_helper.rb +0 -27
  983. data/specs/support/matchers/have_constraint_violation.rb +0 -23
  984. data/specs/support/matchers.rb +0 -5
  985. data/specs/support.rb +0 -3
  986. /data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/prefixed_io.rb +0 -0
  987. /data/{mkbrut/templates → templates}/Base/.dockerignore +0 -0
  988. /data/{mkbrut/templates → templates}/Base/.env.development.erb +0 -0
  989. /data/{mkbrut/templates → templates}/Base/.env.test.erb +0 -0
  990. /data/{mkbrut/templates → templates}/Base/.gitignore +0 -0
  991. /data/{mkbrut/templates → templates}/Base/.projections.json +0 -0
  992. /data/{mkbrut/templates → templates}/Base/Dockerfile.dx +0 -0
  993. /data/{mkbrut/templates → templates}/Base/Gemfile.erb +0 -0
  994. /data/{mkbrut/templates → templates}/Base/Procfile.development +0 -0
  995. /data/{mkbrut/templates → templates}/Base/Procfile.test +0 -0
  996. /data/{mkbrut/templates → templates}/Base/README.md +0 -0
  997. /data/{mkbrut/templates → templates}/Base/README.md.erb +0 -0
  998. /data/{mkbrut/templates → templates}/Base/app/bootstrap.rb +0 -0
  999. /data/{mkbrut/templates → templates}/Base/app/config/i18n/en/1_defaults.rb +0 -0
  1000. /data/{mkbrut/templates → templates}/Base/app/config/i18n/en/2_app.rb +0 -0
  1001. /data/{mkbrut/templates → templates}/Base/app/public/static/manifest.json.erb +0 -0
  1002. /data/{mkbrut/templates → templates}/Base/app/src/app.rb.erb +0 -0
  1003. /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/app_data_model.rb +0 -0
  1004. /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/db.rb +0 -0
  1005. /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/migrations/20240101130000_citext.rb +0 -0
  1006. /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/seed/seed_data.rb +0 -0
  1007. /data/{mkbrut/templates → templates}/Base/app/src/front_end/components/app_component.rb +0 -0
  1008. /data/{mkbrut/templates → templates}/Base/app/src/front_end/components/custom_element_registration.rb.erb +0 -0
  1009. /data/{mkbrut/templates → templates}/Base/app/src/front_end/css/index.css +0 -0
  1010. /data/{mkbrut/templates → templates}/Base/app/src/front_end/css/svgs.css +0 -0
  1011. /data/{mkbrut/templates → templates}/Base/app/src/front_end/forms/app_form.rb +0 -0
  1012. /data/{mkbrut/templates → templates}/Base/app/src/front_end/handlers/app_handler.rb +0 -0
  1013. /data/{brutrb.com → templates/Base/app/src/front_end}/images/LogoPylon.png +0 -0
  1014. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/LogoTransit.png +0 -0
  1015. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-120x120.png +0 -0
  1016. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-152x152.png +0 -0
  1017. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-167x167.png +0 -0
  1018. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-180x180.png +0 -0
  1019. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/favicon.ico +0 -0
  1020. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/icon.png +0 -0
  1021. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/mkicons.sh +0 -0
  1022. /data/{mkbrut/templates → templates}/Base/app/src/front_end/js/index.js +0 -0
  1023. /data/{mkbrut/templates → templates}/Base/app/src/front_end/layouts/blank_layout.rb +0 -0
  1024. /data/{mkbrut/templates → templates}/Base/app/src/front_end/layouts/default_layout.rb.erb +0 -0
  1025. /data/{mkbrut/templates → templates}/Base/app/src/front_end/pages/app_page.rb +0 -0
  1026. /data/{mkbrut/templates → templates}/Base/app/src/front_end/pages/home_page.rb +0 -0
  1027. /data/{mkbrut/templates → templates}/Base/app/src/front_end/support/app_session.rb +0 -0
  1028. /data/{mkbrut/templates → templates}/Base/app/src/front_end/svgs/README.md +0 -0
  1029. /data/{mkbrut/templates → templates}/Base/app/src/front_end/svgs/comment-button.svg +0 -0
  1030. /data/{mkbrut/templates → templates}/Base/bin/README.md.erb +0 -0
  1031. /data/{mkbrut/templates → templates}/Base/bin/console +0 -0
  1032. /data/{mkbrut/templates → templates}/Base/bin/dbconsole +0 -0
  1033. /data/{mkbrut/templates → templates}/Base/bin/dev +0 -0
  1034. /data/{mkbrut/templates → templates}/Base/bin/run +0 -0
  1035. /data/{mkbrut/templates → templates}/Base/bin/run.run +0 -0
  1036. /data/{mkbrut/templates → templates}/Base/bin/startup-message +0 -0
  1037. /data/{mkbrut/templates → templates}/Base/config.ru +0 -0
  1038. /data/{mkbrut/templates → templates}/Base/docker-compose.dx.yml +0 -0
  1039. /data/{mkbrut/templates → templates}/Base/dx/README.md +0 -0
  1040. /data/{mkbrut/templates → templates}/Base/dx/bash_customizations +0 -0
  1041. /data/{mkbrut/templates → templates}/Base/dx/bash_customizations.local +0 -0
  1042. /data/{mkbrut/templates → templates}/Base/dx/build +0 -0
  1043. /data/{mkbrut/templates → templates}/Base/dx/dx.sh.lib +0 -0
  1044. /data/{mkbrut/templates → templates}/Base/dx/exec +0 -0
  1045. /data/{dx → templates/Base/dx}/prune +0 -0
  1046. /data/{mkbrut/templates → templates}/Base/dx/show-help-in-app-container-then-wait.sh +0 -0
  1047. /data/{dx → templates/Base/dx}/start +0 -0
  1048. /data/{dx → templates/Base/dx}/stop +0 -0
  1049. /data/{mkbrut/templates → templates}/Base/package.json.erb +0 -0
  1050. /data/{mkbrut/templates → templates}/Base/puma.config.rb +0 -0
  1051. /data/{mkbrut/templates → templates}/Base/specs/e2e/home_page.spec.rb.erb +0 -0
  1052. /data/{mkbrut/templates → templates}/Base/specs/front_end/js/SpecHelper.js +0 -0
  1053. /data/{mkbrut/templates → templates}/Base/specs/front_end/pages/home_page.spec.rb +0 -0
  1054. /data/{mkbrut/templates → templates}/Base/specs/lint_factories.spec.rb +0 -0
  1055. /data/{mkbrut/templates → templates}/Base/specs/spec_helper.rb +0 -0
  1056. /data/{mkbrut/templates → templates}/Base/specs/support.rb +0 -0
  1057. /data/{mkbrut/templates → templates}/segments/BareBones/app/src/front_end/handlers/trigger_exception_handler.rb +0 -0
  1058. /data/{mkbrut/templates → templates}/segments/BareBones/app/src/front_end/js/Example.js.erb +0 -0
  1059. /data/{mkbrut/templates → templates}/segments/BareBones/specs/front_end/handlers/trigger_exception_handler.spec.rb +0 -0
  1060. /data/{mkbrut/templates → templates}/segments/BareBones/specs/front_end/js/Example.spec.js.erb +0 -0
  1061. /data/{mkbrut/templates → templates}/segments/Demo/app/src/back_end/data_models/db/guestbook_message.rb +0 -0
  1062. /data/{mkbrut/templates → templates}/segments/Demo/app/src/back_end/data_models/migrations/20250628194124_guestbook.rb +0 -0
  1063. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/components/flash_component.rb +0 -0
  1064. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/css/constraint-violations.css +0 -0
  1065. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/fonts/monaspace-xenon.ttf +0 -0
  1066. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/forms/guestbook_message_form.rb +0 -0
  1067. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/handlers/guestbook_message_handler.rb +0 -0
  1068. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/pages/guestbook_page/message_component.rb +0 -0
  1069. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/pages/guestbook_page.rb +0 -0
  1070. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/pages/new_guestbook_message_page.rb +0 -0
  1071. /data/{mkbrut/templates → templates}/segments/Demo/specs/back_end/data_models/db/guestbook_message.spec.rb +0 -0
  1072. /data/{mkbrut/templates → templates}/segments/Demo/specs/e2e/guest_message.spec.rb +0 -0
  1073. /data/{mkbrut/templates → templates}/segments/Demo/specs/factories/db/guestbook_message.factory.rb +0 -0
  1074. /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/components/flash_component.spec.rb +0 -0
  1075. /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/handlers/guestbook_message_handler.spec.rb +0 -0
  1076. /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/pages/guestbook_page/message_component.spec.rb +0 -0
  1077. /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/pages/guestbook_page.spec.rb +0 -0
  1078. /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/pages/new_guestbook_message_page.spec.rb +0 -0
  1079. /data/{mkbrut/templates → templates}/segments/Heroku/bin/deploy +0 -0
  1080. /data/{mkbrut/templates → templates}/segments/Heroku/deploy/docker-entrypoint +0 -0
  1081. /data/{mkbrut/templates → templates}/segments/Sidekiq/app/boot_sidekiq.rb +0 -0
  1082. /data/{mkbrut/templates → templates}/segments/Sidekiq/app/config/sidekiq.yml +0 -0
  1083. /data/{mkbrut/templates → templates}/segments/Sidekiq/app/src/back_end/jobs/app_job.rb +0 -0
  1084. /data/{mkbrut/templates → templates}/segments/Sidekiq/app/src/back_end/jobs/example_job.rb +0 -0
  1085. /data/{mkbrut/templates → templates}/segments/Sidekiq/app/src/back_end/segments/sidekiq_segment.rb +0 -0
  1086. /data/{mkbrut/templates → templates}/segments/Sidekiq/bin/run.sidekiq +0 -0
  1087. /data/{mkbrut/templates → templates}/segments/Sidekiq/specs/back_end/jobs/example_job.spec.rb +0 -0
  1088. /data/{mkbrut/templates → templates}/segments/Sidekiq/specs/integration/sidekiq_works.spec.rb +0 -0
data/brutrb.com/forms.md DELETED
@@ -1,238 +0,0 @@
1
- # Forms
2
-
3
- In HTML, forms are the way data is submit to the server. Forms attract complexity
4
- since they interact with user experience, data validation, and interaction with a
5
- back-end database.
6
-
7
- ## Overview
8
-
9
- Forms in Brut accomplish three things:
10
-
11
- * Forms model the data elements of a `<form>`, including client-side constraints (which Brut can check server-side as well).
12
- * Forms assist in HTML generation, to ensure the HTML elements are consistent and
13
- correct.
14
- * Forms hold data submitted to the server. No need for strong parameters or digging
15
- into a Hash of Whatever.
16
-
17
- Since forms can lead to a lot of complexity, this module will stick to the very
18
- basics. There are several recipes we'll link to that explain more complex
19
- interactions with forms.
20
-
21
- ### Declaring Form Data/Elements
22
-
23
- When you [create a form route](/routes), this imlplies a form class exists to
24
- specify the data:
25
-
26
- ```ruby
27
- # app/src/app.rb
28
- routes do
29
- form "new_widget"
30
- end
31
-
32
- # app/src/front_end/forms/new_widget_form.rb
33
- class NewWidgetForm < AppForm
34
- end
35
- ```
36
-
37
- `AppForm` extends `Brut::FrontEnd::Form`, which provides class methods you can use
38
- to declare your form's elements. Let's say our form has a name (that must be at least 3 characters), a quantity (integer greater than 0), and an optional description.
39
-
40
- ```ruby
41
- class NewWidgetForm < AppForm
42
- input :name, minlength: 3
43
- input :quantity, type: :number, min: 0, step: 1
44
- input :description, required: true
45
- end
46
- ```
47
-
48
- `input` declares a form element that will ultimately be handled by an `<input>` or
49
- `<textarea>` tag. `select` and `radio_button_group` are also avaiable, and are
50
- discussed in recipes.
51
-
52
- `input` accepts an input name used for `<input>`'s `name` attribute. It also
53
- accepts keyword arguments that match the initializer of
54
- `Brut::FrontEnd::Forms::InputDefinition`. You'll notice those values mirror the
55
- various attributes related to client-side constraint validations, for example
56
- `minlength:` and `pattern:`.
57
-
58
- Form elements have some defaults, as described below:
59
-
60
- | Declaration | Default Behavior |
61
- |---|---|
62
- | `input :email` | `type: :email` |
63
- | `input :password` | `type: :password` |
64
- | `input :password_confirmation` | `type: :password` |
65
- | `input «any other name»` | `type: :text` |
66
- | `input «name», type: :checkbox` | `required: false` |
67
- | `input «name» type: «not checkbox»` | `required: true` |
68
-
69
- ### Using Forms to Generate HTML
70
-
71
- One reason Brut models forms as classes with declared inputs is that you can then
72
- use an instance of that class to generate HTML. Brut will generate appropriate
73
- HTML, optionally configured to show a pre-existing value from the form.
74
-
75
- The classes that do this are in `Brut::FrontEnd::Components`
76
-
77
- | Class | Purpose |
78
- |---|---|
79
- |`Brut::FrontEnd::Components::FormTag` | Creates a `<form>` tag that submits to the form's configured route and includes [CSRF protection](/security). |
80
- |`Brut::FrontEnd::Components::InputTag` | Creates an `<input>` tag |
81
- |`Brut::FrontEnd::Components::RadioButton` | Creates an `<input type="radio">` tag
82
- for use in a radio button group. |
83
- |`Brut::FrontEnd::Components::SelectTagWithOptions` | Creates a `<select>` tag with
84
- `<option>` tags inside. |
85
- |`Brut::FrontEnd::Components::TextareaTag` | Creates a `<textarea>` tag. |
86
- |`Brut::FrontEnd::Components::ButtonTag` | Creates a `<button>` tag to submit the form. |
87
-
88
- All of these classes have an initializer that accepts:
89
-
90
- * `form:` the form object, used to figure out the HTML attributes and current value of the element.
91
- * `input_name:` to know which input is being generated.
92
- * `index:` for [indexed form elements](/recipes/indexed-forms.md).
93
- * `**html_attributes` any other HTML attributesyou'd like to include.
94
-
95
- These class names are quite long, but since these are Phlex components, you can
96
- `include` `Brut::FrontEnd::Components` and access their initializers as a [Phlex
97
- kit](https://phlex.fun):
98
-
99
- ```ruby
100
- class NewWidgetPage < AppPage
101
- include Brut::FrontEnd::Components
102
-
103
- def initialize(form: nil)
104
- @form = form || NewWidgetForm.new
105
- end
106
-
107
- private attr_reader :form
108
-
109
- def page_template
110
- FormTag(for: form) do
111
- Components::InputTag(form:, input_name: :name)
112
- Components::InputTag(form:, input_name: :quantity)
113
- Components::TextareaTag(form:, input_name: :description)
114
- end
115
- end
116
- end
117
- ```
118
-
119
- Phlex kits provides a methods named for the class that call that class' constructor.
120
-
121
- The code above will generate this HTML
122
-
123
- ```html
124
- <form action="/new_widgets" method="post">
125
- <input type="hidden" name="authenticity_token" value=«value»>
126
- <input type="text" name="name" required minlength="3">
127
- <input type="number" name="quantity" required min="0" step="1">
128
- <textarea name="description">
129
- </textarea>
130
- </form>
131
- ```
132
-
133
- Forms accept a single initializer parameter, `params` that is a `Hash`.
134
- `Brut::FrontEnd::Form` implements this initializer, and will pluck values from the
135
- hash to initialize the inputs:
136
-
137
- ::: code-group
138
-
139
- ```ruby [Form Class] {5-8}
140
- class NewWidgetPage < AppPage
141
- include Brut::FrontEnd::Components
142
-
143
- def initialize(form: nil)
144
- @form = form || NewWidgetForm.new( params: {
145
- name: "My New Widget",
146
- quantity: 10,
147
- })
148
- end
149
-
150
- # ...
151
-
152
- end
153
- ```
154
-
155
- ```html [HTML Generated] {3,5}
156
- <form action="/new_widgets" method="post">
157
- <input type="hidden" name="authenticity_token" value=«value»>
158
- <input type="text" value="My New Widget"
159
- name="name" required minlength="3">
160
- <input type="number" value="10"
161
- name="quantity" required min="0" step="1">
162
- <textarea name="description">
163
- </textarea>
164
- </form>
165
- ```
166
-
167
- :::
168
-
169
- ### Accessing Data in a Submitted Form
170
-
171
- As mentioned in [routes](/routes), a `form` route implies not just a form class, but
172
- a [handler](/handlers) class to receive the submitted data.
173
-
174
- We'll discuss handlers in the next section, but they demonstrate how you can access
175
- a form's data:
176
-
177
- ```ruby
178
- class NewWidgetHandler < AppHandler
179
- def initialize(form:)
180
- @form = form
181
- end
182
-
183
- def handle
184
- form.name # => whatever name was submitted
185
- form.quantity # => whatever quantity was submitted
186
- form.description # => description provided
187
- end
188
- end
189
- ```
190
-
191
- A few things to note about how this works:
192
-
193
- * Only those inputs declared in the form class can be accessed. All other values are
194
- discarded. No need for "strong parameters".
195
- * All values are strings, because this is what HTML provides.
196
- * Blank values are coerced to `nil`.
197
-
198
- The next module will deal with form constraints and validations, in particular how
199
- to manage the user experience around client-side constraint violations, how to
200
- re-check them server side, and how to perform server-side checks.
201
-
202
- ## Testing
203
-
204
- Form classes don't need any logic on them, but they can be given helper methods or other logic if it makes sense. To test them, test them like any other class - instantiate an object and examine the behavior of its methods.
205
-
206
- ## Recommended Practices
207
-
208
- ### Create Components to Generate Form Controls
209
-
210
- `Brut::FrontEnd::Components::Inputs` will generate the basic tags like `<input>` or
211
- `<select>`. Everything else like `<label>` is up to you. We recommend that you
212
- create [components](/components) to generate the markup required for *your* inputs
213
- and controls.
214
-
215
- The recipe ["Creating a Text Field"](/recipes/text-field-component) will walk you
216
- through the steps and considerations.
217
-
218
- ### Take Advantage of Client Side Constraints
219
-
220
- Even though client-side constraints can sometimes be awkward in certain browsers,
221
- they are going to be eminently usable and accessible, and you can easily
222
- re-validate them on the server side.
223
-
224
- ## Technical Notes
225
-
226
- > [!IMPORTANT]
227
- > Technical Notes are for deeper understanding and debugging. While we will try to keep them up-to-date with changes to Brut's
228
- > internals, the source code is always more correct.
229
-
230
- _Last Updated May 13, 2025_
231
-
232
- For HTML generation, there are few classes that work together:
233
-
234
- * *input definitions* define an input and tend to provide an API similar to HTML's. See `Brut::FrontEnd::Forms::InputDefinition`.
235
- * *inputs* represent the runtime state of an input from the browser. Whereas an input definition has no state, the input does. It delegates much of its behavior to the underlying input definition. It's `value=` method performs client-side constraint validations by creating a `Brut::FrontEnd::Forms::ValidityState` internally. See `Brut::FrontEnd::Forms::Input`.
236
- * `Brut::FrontEnd::Forms::InputDeclarations` is a module that allows creating input definitions inside your form
237
- class. It implements the class methods like `input`.
238
- * `Brut::FrontEnd::Components::Inputs` contains components used to generate `<input>` fields. These classes will coerce the value of the `input` they are given to generate the correct HTML.
@@ -1,142 +0,0 @@
1
- # Getting Started
2
-
3
- Brut is developed alongside a separate gem called `mkbrut`, which allows you to
4
- create a new Brut app. It will set up your dev environment as well.
5
-
6
- ## Get `mkbrut`
7
-
8
- The simplest way to use `mkbrut` is to use an existing [Docker image](https://hub.docker.com/repository/docker/thirdtank/mkbrut/general). You don't have to install or configure Ruby:
9
-
10
- ```
11
- docker run \
12
- --pull always \
13
- -v "$PWD":"$PWD" \
14
- -w "$PWD" \
15
- -u $(id -u):$(id -g) \
16
- -it \
17
- thirdtank/mkbrut \
18
- mkbrut my-new-app
19
- ```
20
-
21
- If you already have Ruby 3.4 installed, you can install `mkbrut` directly:
22
-
23
- ```
24
- > gem install mkbrut
25
- > mkbrut my-new-app
26
- ```
27
-
28
- ## Init Your App
29
-
30
- A Brut app just needs a name, which will be used to derive a few more useful values.
31
- For now:
32
-
33
- ::: code-group
34
-
35
- ``` [Docker-based]
36
- docker run \
37
- --pull always \
38
- -v "$PWD":"$PWD" \
39
- -w "$PWD" \
40
- -u $(id -u):$(id -g) \
41
- -it \
42
- thirdtank/mkbrut \
43
- mkbrut my-new-app
44
- ```
45
-
46
- ``` [RubyGems-based]
47
- mkbrut my-new-app
48
- ```
49
-
50
- :::
51
-
52
- This will create your new app, along with some demo routes, components, handlers, and tests. If this is your first time using Brut, we recommend you examine these demo components.
53
-
54
- To create your app without the demo components:
55
-
56
- ::: code-group
57
-
58
- ``` [Docker-based]
59
- docker run \
60
- --pull always \
61
- -v "$PWD":"$PWD" \
62
- -w "$PWD" \
63
- -u $(id -u):$(id -g) \
64
- -it \
65
- thirdtank/mkbrut \
66
- mkbrut my-new-app --no-demo
67
- ```
68
-
69
- ``` [RubyGems-based]
70
- mkbrut my-new-app --no-demo
71
- ```
72
-
73
- :::
74
-
75
- ## Start Your Dev Environment
76
-
77
- Brut includes a dev environment based on Docker. It uses Docker compose to run a
78
- Docker container where your app will run, a Docker container for Postgres, and a
79
- Docker container for local observability via OpenTelemetry.
80
-
81
- 1. [Install Docker](https://docs.docker.com/get-started/get-docker/)
82
- 2. Build the image used to create you app's container:
83
-
84
- ```
85
- > dx/build
86
- ```
87
- 3. Start up all the containers:
88
-
89
- ```
90
- > dx/start
91
- ```
92
- 4. Now, install your aps gems and set it all up:
93
-
94
- ```
95
- > dx/exec bin/setup
96
- ```
97
-
98
- Now, you're ready to go. See [Dev Environemnt](/dev-environment) for details on how
99
- this all works.
100
-
101
- > [!NOTE]
102
- > Instead of running `dx/exec` in front of your commands, you
103
- > can instead do `dx/exec bash` to "log in" to the running container.
104
- > You'll have a normal prompt and can issue commands directly from there.
105
-
106
- ## Run the App
107
-
108
- ```
109
- dx/exec bin/dev
110
- ```
111
-
112
- You can now visit your app at `localhost:6502`
113
-
114
- You can make changes and see them when you reload. Open up `app/src/front_end/pages/home_page.rb` *in your editor running on your computer* and change the `h1` to look like so:
115
-
116
- ```ruby {6}
117
- class HomePage < AppPage
118
- def page_template
119
- div(class: "flex flex-column items-center justify-center h-80vh") do
120
- img(src: "/static/images/icon.png", class: "h-50")
121
- h1(class: "ff-sans ma-0 lh-title f-5") do
122
- "Welcome to My New App!"
123
- end
124
-
125
- # ...
126
- ```
127
-
128
- When you reload your browser, you'll see your change
129
-
130
- ## Run the Tests
131
-
132
- There are a few tests you can run, as well as some checks that you aren't using
133
- RubyGems with security vulnerabilities. Run it all now with `bin/ci`:
134
-
135
- ```
136
- dx/exec bin/ci
137
- ```
138
-
139
- ## Now Build The Rest of Your App 🦉
140
-
141
- You can [follow the tutorial](/tutorial), check out the [conceptual overview](/overview), or dive straight into the [API docs](/api/index.html). You might also want to check out the docs for [LSP Support](/lsp).
142
-
@@ -1,177 +0,0 @@
1
- # Handlers & Actions
2
-
3
- Handlers process form submissions, and *actions* work similarly to process any arbitrary HTTP request.
4
-
5
- ## Overview
6
-
7
- Where a [page](/pages) renders a web page in HTML, a *handler* responds to all other HTTP requests. To respond to such HTTP requests, you'd first create a [route](/routes), using `form`, `action`, or `path`.
8
-
9
- ### Handler Structure
10
-
11
- A handler's initializer is subject to [keyword injection](/keyword-injection), with
12
- the addition of the `form:` keyword, which, if present, will be an instance of the
13
- associated form class, populated with the data in the form submission (not available for `path` or `action` routes).
14
-
15
- You must implement `handle` to process the form. **A handler's public API, as
16
- called by Brut and your tests, is `handle!`**, however you implement `handle`, which
17
- `handle!` calls.
18
-
19
- `handle`'s return value dictates what will happen next:
20
-
21
- | Return Value | Behavior |
22
- |---|---|
23
- |Instance of a page or component | That page or component's HTML is generated and returned. This is not a redirect, but more like `render :new` in a Rails controller |
24
- |`Brut::FrontEnd::HttpStatus` | This HTTP status is returned with no body. Use `http_status` from `Brut::FrontEnd::HandlingResults` (included in all handlers) to create an instance from a number |
25
- | `URI` | Redirect to the URI. Use `redirect_to` from `Brut::FrontEnd::HandlingResults` (included in all handlers) to generate a URI from a page class and parameters |
26
- | Two element array with *element 0* being a `Brut::FrontEnd::HttpStatus`, and *element 1* being a page or component instance | Generates the page or component's HTML, but sets the given status instead of 200. Useful for Ajax responses where the HTTP status affects client-side behavior |
27
- | `Brut::FrontEnd::Download` | Download a file |
28
- | `Brut::FrontEnd::GenericResponse` | wrap any Rack response |
29
-
30
- > [!IMPORTANT]
31
- > The only way to render something other than HTML is to do so as a
32
- > `GenericResponse`, which is basically the low-level Rack API. Brut
33
- > encourages Ajax responses to be HTML and for you to use the browser's
34
- > APIs to interact with that HTML. Brut may make it easier to work
35
- > with other types of content in the future.
36
-
37
- ### Handling a Form Submission
38
-
39
- A common pattern when handling a form submisssion is to check for any constraint
40
- violations. If there are some, re-generate the HTML for the page containing the
41
- form, highlighting the violations. Otherwise, save the data and redirect to another
42
- page.
43
-
44
- Here's how that looks:
45
-
46
- ```ruby
47
- class NewWidgetHandler < AppHandler
48
- def initialize(form:)
49
- @form = form
50
- end
51
-
52
- def handle
53
- # if no client-side violations were submitted
54
- if @form.valid?
55
- widget = DB::Widget.find(name: form.name)
56
- if widget
57
- @form.server_side_constraint_violation(
58
- input_name: :name,
59
- key: :name_is_taken
60
- )
61
- end
62
- end
63
-
64
- if @form.constraint_violations?
65
- NewWidgetPage.new(form: @form)
66
- else
67
- DB::Widget.create(name: form.name,
68
- quantity: form.quantity,
69
- description: form.description)
70
- redirect_to(WidgetsPage)
71
- end
72
- end
73
- end
74
- ```
75
-
76
- Unlike a Rails controller, the return value of `handle` controls the behavior. As
77
- we saw in [Form Constraints](/form-constraints), the HTML generated by
78
- `NewWidgetPage` will show constraint violations, so by returning
79
- `NewWidgetPage.new(form: @form)`, the page has the same form instance, including all
80
- the constraint violations, and the visitor will see the problems.
81
-
82
- ### Handling Other Requests
83
-
84
- Non-form submissions work similarly, however there is no form available. If the
85
- request could potentially involve a visitor-initiated error, you can use the
86
- [flash](/flash-and-session) to communicate back. The flash is available for injection into the
87
- initializer and, assuming your page uses it to show messages, can allow for
88
- communication when something is wrong:
89
-
90
- ```ruby
91
- class App
92
- # ...
93
-
94
- routes do
95
- action "/delete_widget/:widget_id"
96
-
97
- # ...
98
- end
99
- end
100
-
101
- class DeleteWidgetByIdHandler < AppHandler
102
- def initialize(widget_id:, flash:)
103
- @widget_id = widget_id
104
- @flash = flash
105
- end
106
-
107
- def handle
108
- widget = DB::Widget.find!(id: @widget_id)
109
- if widget.can_delete?
110
- widget.delete
111
- @flash.notice = :widget_deleted
112
- redirect_to(WidgetsPage)
113
- else
114
- @flash.alert = :widget_cannot_be_deleted
115
- WidgetsPage.new
116
- end
117
- end
118
- end
119
- ```
120
-
121
- ### Hooks
122
-
123
- A handler's public API is `handle!`, because it first calls `before_handle`. This
124
- operates as a before hook, and has the same return values as `handle`, with the
125
- exception of also recognizing `nil`, which indicates processing should proceed to
126
- `handle`.
127
-
128
- Generally, you don't need to implement hooksd on a per-handler basis, but may find
129
- it useful in a shared super class to implement cross-cutting behavior.
130
-
131
- ## Testing
132
-
133
- See [Unit Testing](/unit-tests) for some basic assumptions and configuration available for all Brut unit tests.
134
-
135
- Handler tests should be straightforward: you create your handler, call `handle!`
136
- (remember, `handle!` is the public API, and will call your hooks, which you want in
137
- a test), then examine the result returned and any ancillary behavior, such as
138
- updated database records.
139
-
140
- Some matchers are available to make assertions about `handle!`'s return value:
141
-
142
- * `have_redirected_to` will check that the handler redirected to a give URI. See `Brut::SpecSupport::Matchers::HaveRedirectedTo`.
143
- * `have_generated` will check that the handler generated a specific page or component's HTML. See `<D-f>Brut::SpecSupport::Matchers::HaveGenerated`.
144
- * `have_returned_http_status` will check that the handler returned an HTTP status. See `Brut::SpecSupport::Matchers::HaveReturnedHttpStatus`.
145
- * `have_constraint_violation` will check if a form had a particular constraint violation set on it. See `Brut::SpecSupport::Matchers::HaveConstraintViolation`.
146
-
147
- ## Recommended Practices
148
-
149
- ### You Don't Always Need Resourceful or RESTful Routes
150
-
151
- For any code where the browser is performing a submission, use either `form` or
152
- `action` to declare your route. These will both use an HTTP `POST` to your server and handler. In the example above, we had a `POST` to `/delete_widget/:widget_id`, and not, say, a `DELETE` to it.
153
-
154
- The main reason is that a browser can only submit to a server using `GET` or `POST`, so there's little value in "tunneling" another verb of POST. It doesn't really matter. And, even though you may use Ajax to submit such data, having it degrade to normal browser-based HTTP is a good practice.
155
-
156
- For API-like calls where a browser will never directly interact with the route, and
157
- it would only be via a server-to-server call, RESTful routes makes sense. But they
158
- don't need to be the default.
159
-
160
- ### Avoid Business Logic in Handlers
161
-
162
-
163
- Since handlers bridge the gap between HTTP and your app, their API is naturally simplistic and String-based. The handler should defer to business logic (which can be done by either passing the form object directly, or extracting its data and passing that). Based on the response, the handler will then decide what HTTP response is approriate.
164
-
165
- This means that your handlers will be relatively simple and their tests will as well. It does mean that their tests may require the use of mocks or stubs, but that's fine. Mocks and stubs exist for a reason.
166
-
167
-
168
- ## Technical Notes
169
-
170
- > [!IMPORTANT]
171
- > Technical Notes are for deeper understanding and debugging. While we will try to keep them up-to-date with changes to Brut's
172
- > internals, the source code is always more correct.
173
-
174
- _Last Updated May 5, 2025_
175
-
176
- None at this time.
177
-