brut 0.15.0 → 0.16.0.pre
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/CHANGELOG.md +5 -0
- data/Dockerfile.dx +3 -6
- data/Gemfile.lock +1 -1
- data/brut-css/package-lock.json +2 -2
- data/brut-css/package.json +1 -1
- data/brut-js/package-lock.json +2 -2
- data/brut-js/package.json +1 -1
- data/brutrb.com/.vitepress/config.mjs +4 -3
- data/brutrb.com/deployment.md +23 -9
- data/brutrb.com/jobs.md +107 -7
- data/brutrb.com/recipes/dev-env-secrets.md +87 -0
- data/brutrb.com/roadmap.md +2 -7
- data/docs/404.html +2 -2
- data/docs/adrs.html +3 -3
- data/docs/ai.html +3 -3
- data/docs/api/Brut/BackEnd/SeedData.html +1 -1
- data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server/FlushSpans.html +1 -1
- data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server.html +1 -1
- data/docs/api/Brut/BackEnd/Sidekiq/Middlewares.html +1 -1
- data/docs/api/Brut/BackEnd/Sidekiq.html +1 -1
- data/docs/api/Brut/BackEnd/Validators/FormValidator.html +1 -1
- data/docs/api/Brut/BackEnd/Validators.html +1 -1
- data/docs/api/Brut/BackEnd.html +1 -1
- data/docs/api/Brut/CLI/App.html +1 -1
- data/docs/api/Brut/CLI/AppRunner.html +1 -1
- data/docs/api/Brut/CLI/Apps/BuildAssets/All.html +1 -1
- data/docs/api/Brut/CLI/Apps/BuildAssets/CSS.html +1 -1
- data/docs/api/Brut/CLI/Apps/BuildAssets/Images.html +1 -1
- data/docs/api/Brut/CLI/Apps/BuildAssets/JS.html +1 -1
- data/docs/api/Brut/CLI/Apps/BuildAssets.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Create.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Drop.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Migrate.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/NewMigration.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Rebuild.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Seed.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Status.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB.html +1 -1
- data/docs/api/Brut/CLI/Apps/DeployBase/GitChecks.html +1 -1
- data/docs/api/Brut/CLI/Apps/DeployBase.html +1 -1
- data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy/Deploy.html +1 -1
- data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Action/Route.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Action.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Component.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/CustomElementTest.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/DbModel.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/E2ETest.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Form.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Page/Route.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Page.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/RoutesEditor.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Test.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold.html +1 -1
- data/docs/api/Brut/CLI/Apps/Test/Audit.html +1 -1
- data/docs/api/Brut/CLI/Apps/Test/E2e.html +1 -1
- data/docs/api/Brut/CLI/Apps/Test/JS.html +1 -1
- data/docs/api/Brut/CLI/Apps/Test/Run.html +1 -1
- data/docs/api/Brut/CLI/Apps/Test.html +1 -1
- data/docs/api/Brut/CLI/Apps.html +1 -1
- data/docs/api/Brut/CLI/Command.html +1 -1
- data/docs/api/Brut/CLI/Error.html +1 -1
- data/docs/api/Brut/CLI/ExecutionResults/Result.html +1 -1
- data/docs/api/Brut/CLI/ExecutionResults.html +1 -1
- data/docs/api/Brut/CLI/Executor.html +1 -1
- data/docs/api/Brut/CLI/InvalidOption.html +1 -1
- data/docs/api/Brut/CLI/Options.html +1 -1
- data/docs/api/Brut/CLI/Output.html +1 -1
- data/docs/api/Brut/CLI/SystemExecError.html +1 -1
- data/docs/api/Brut/CLI.html +1 -1
- data/docs/api/Brut/FactoryBot.html +1 -1
- data/docs/api/Brut/Framework/App.html +1 -1
- data/docs/api/Brut/Framework/Config.html +1 -1
- data/docs/api/Brut/Framework/Container.html +1 -1
- data/docs/api/Brut/Framework/Error.html +1 -1
- data/docs/api/Brut/Framework/Errors/AbstractMethod.html +1 -1
- data/docs/api/Brut/Framework/Errors/Bug.html +1 -1
- data/docs/api/Brut/Framework/Errors/MissingConfiguration.html +1 -1
- data/docs/api/Brut/Framework/Errors/MissingParameter.html +1 -1
- data/docs/api/Brut/Framework/Errors/NoClassForPath.html +1 -1
- data/docs/api/Brut/Framework/Errors/NotFound.html +1 -1
- data/docs/api/Brut/Framework/Errors/NotImplemented.html +1 -1
- data/docs/api/Brut/Framework/Errors.html +1 -1
- data/docs/api/Brut/Framework/FussyTypeEnforcement.html +1 -1
- data/docs/api/Brut/Framework/MCP.html +1 -1
- data/docs/api/Brut/Framework/ProjectEnvironment.html +1 -1
- data/docs/api/Brut/Framework.html +1 -1
- data/docs/api/Brut/FrontEnd/AssetPathResolver.html +1 -1
- data/docs/api/Brut/FrontEnd/Component/Helpers.html +1 -1
- data/docs/api/Brut/FrontEnd/Component.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/ConstraintViolations.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/FormTag.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/I18nTranslations.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Input.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs/ButtonTag.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs/CsrfToken.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs/InputTag.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs/RadioButton.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs/SelectTagWithOptions.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs/TextareaTag.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/LocaleDetection.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/PageIdentifier.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/TimeTag.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Traceparent.html +1 -1
- data/docs/api/Brut/FrontEnd/Components.html +1 -1
- data/docs/api/Brut/FrontEnd/CsrfProtector.html +1 -1
- data/docs/api/Brut/FrontEnd/Download.html +1 -1
- data/docs/api/Brut/FrontEnd/Flash.html +1 -1
- data/docs/api/Brut/FrontEnd/Form.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/Button.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/ButtonInputDefinition.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/ConstraintViolation.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/Input/Color.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/Input/TimeOfDay.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/Input.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/InputDeclarations.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/InputDefinition.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInput.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInputDefinition.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/SelectInput.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/SelectInputDefinition.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/ValidityState.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms.html +1 -1
- data/docs/api/Brut/FrontEnd/GenericResponse.html +1 -1
- data/docs/api/Brut/FrontEnd/Handler.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/CspReportingHandler.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler/TraceParent.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/LocaleDetectionHandler.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/MissingHandler/Form.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/MissingHandler.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers.html +1 -1
- data/docs/api/Brut/FrontEnd/HandlingResults.html +1 -1
- data/docs/api/Brut/FrontEnd/HttpMethod.html +1 -1
- data/docs/api/Brut/FrontEnd/HttpStatus.html +1 -1
- data/docs/api/Brut/FrontEnd/InlineSvgLocator.html +1 -1
- data/docs/api/Brut/FrontEnd/Layout.html +1 -1
- data/docs/api/Brut/FrontEnd/Middleware.html +1 -1
- data/docs/api/Brut/FrontEnd/Middlewares/AnnotateBrutOwnedPaths.html +1 -1
- data/docs/api/Brut/FrontEnd/Middlewares/Favicon.html +1 -1
- data/docs/api/Brut/FrontEnd/Middlewares/OpenTelemetrySpan.html +1 -1
- data/docs/api/Brut/FrontEnd/Middlewares/ReloadApp.html +1 -1
- data/docs/api/Brut/FrontEnd/Middlewares.html +1 -1
- data/docs/api/Brut/FrontEnd/Page.html +1 -1
- data/docs/api/Brut/FrontEnd/Pages/MissingPage.html +1 -1
- data/docs/api/Brut/FrontEnd/Pages.html +1 -1
- data/docs/api/Brut/FrontEnd/RequestContext.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHook.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/AgeFlash.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineScripts.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts/ReportOnly.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/LocaleDetection.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/SetupRequestContext.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/FormHandlerRoute.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/FormRoute.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/MissingForm.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/MissingHandler.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/MissingPage.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/MissingPath.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/PageRoute.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/Route.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing.html +1 -1
- data/docs/api/Brut/FrontEnd/Session.html +1 -1
- data/docs/api/Brut/FrontEnd.html +1 -1
- data/docs/api/Brut/I18n/BaseMethods.html +1 -1
- data/docs/api/Brut/I18n/ForBackEnd.html +1 -1
- data/docs/api/Brut/I18n/ForCLI.html +1 -1
- data/docs/api/Brut/I18n/ForHTML.html +1 -1
- data/docs/api/Brut/I18n/HTTPAcceptLanguage/AlwaysEnglish.html +1 -1
- data/docs/api/Brut/I18n/HTTPAcceptLanguage.html +1 -1
- data/docs/api/Brut/I18n.html +1 -1
- data/docs/api/Brut/Instrumentation/LoggerSpanExporter.html +1 -1
- data/docs/api/Brut/Instrumentation/Methods/ClassMethods.html +1 -1
- data/docs/api/Brut/Instrumentation/Methods.html +1 -1
- data/docs/api/Brut/Instrumentation/OpenTelemetry/NormalizedAttributes.html +1 -1
- data/docs/api/Brut/Instrumentation/OpenTelemetry/Span.html +1 -1
- data/docs/api/Brut/Instrumentation/OpenTelemetry.html +1 -1
- data/docs/api/Brut/Instrumentation.html +1 -1
- data/docs/api/Brut/RubocopConfig.html +1 -1
- data/docs/api/Brut/SinatraHelpers/ClassMethods.html +1 -1
- data/docs/api/Brut/SinatraHelpers.html +1 -1
- data/docs/api/Brut/SpecSupport/ClockSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/ComponentSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/E2ETestServer.html +1 -1
- data/docs/api/Brut/SpecSupport/E2eSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/EnhancedNode.html +1 -1
- data/docs/api/Brut/SpecSupport/FlashSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/GeneralSupport/ClassMethods.html +1 -1
- data/docs/api/Brut/SpecSupport/GeneralSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/HandlerSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/BeABug.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/BePageFor.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/BeRoutingFor.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveConstraintViolation.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveGenerated.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveHTMLAttribute.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveI18nString.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveLinkTo.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveRedirectedTo.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedHttpStatus.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedRackResponse.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers.html +1 -1
- data/docs/api/Brut/SpecSupport/RSpecSetup/OptionalSidekiqSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/RSpecSetup.html +1 -1
- data/docs/api/Brut/SpecSupport/SessionSupport.html +1 -1
- data/docs/api/Brut/SpecSupport.html +1 -1
- data/docs/api/Brut.html +1 -1
- data/docs/api/Clock.html +1 -1
- data/docs/api/ModuleName.html +1 -1
- data/docs/api/RichString.html +1 -1
- data/docs/api/SemanticLogger/Appender/Async.html +1 -1
- data/docs/api/Sequel/Extensions/BrutInstrumentation.html +1 -1
- data/docs/api/Sequel/Extensions/BrutMigrations.html +1 -1
- data/docs/api/Sequel/Extensions.html +1 -1
- data/docs/api/Sequel/Plugins/CreatedAt/InstanceMethods.html +1 -1
- data/docs/api/Sequel/Plugins/CreatedAt.html +1 -1
- data/docs/api/Sequel/Plugins/ExternalId/ClassMethods.html +1 -1
- data/docs/api/Sequel/Plugins/ExternalId/InstanceMethods.html +1 -1
- data/docs/api/Sequel/Plugins/ExternalId.html +1 -1
- data/docs/api/Sequel/Plugins/FindBang/ClassMethods.html +1 -1
- data/docs/api/Sequel/Plugins/FindBang.html +1 -1
- data/docs/api/Sequel/Plugins.html +1 -1
- data/docs/api/Sequel.html +1 -1
- data/docs/api/_index.html +1 -1
- data/docs/api/file.README.html +1 -1
- data/docs/api/index.html +1 -1
- data/docs/api/top-level-namespace.html +1 -1
- data/docs/assets/{app.B0X8upRm.js → app.Dm7v_ouO.js} +1 -1
- data/docs/assets/{brut-js.md.CbJAe2Ky.js → brut-js.md.BMz0X1Rz.js} +1 -1
- data/docs/assets/chunks/@localSearchIndexroot.BiNFswvo.js +1 -0
- data/docs/assets/chunks/{VPLocalSearchBox.jLmhant1.js → VPLocalSearchBox.DQK6jQou.js} +1 -1
- data/docs/assets/chunks/{theme.CtVUdCdt.js → theme.BuExsdM9.js} +2 -2
- data/docs/assets/{components.md.C6nWgDP0.js → components.md.Dfd3w6UW.js} +3 -3
- data/docs/assets/{configuration.md.CpbYHWPb.js → configuration.md.DTYoV2Ea.js} +1 -1
- data/docs/assets/{forms.md.Bii91k3E.js → forms.md.DEkmJUvb.js} +1 -1
- data/docs/assets/{getting-started.md.ChAvueK7.js → getting-started.md.DO-4eoGW.js} +2 -2
- data/docs/assets/{tutorials_02-dialog.md.De6iTsWX.js → tutorials_02-dialog.md.D2vSjDVf.js} +1 -1
- data/docs/assets.html +3 -3
- data/docs/brut-js/api/AjaxSubmit.html +2 -2
- data/docs/brut-js/api/AjaxSubmit.js.html +2 -2
- data/docs/brut-js/api/Autosubmit.html +2 -2
- data/docs/brut-js/api/Autosubmit.js.html +2 -2
- data/docs/brut-js/api/BaseCustomElement.html +2 -2
- data/docs/brut-js/api/BaseCustomElement.js.html +2 -2
- data/docs/brut-js/api/BrutCustomElements.html +3 -3
- data/docs/brut-js/api/BufferedLogger.html +2 -2
- data/docs/brut-js/api/ConfirmSubmit.html +2 -2
- data/docs/brut-js/api/ConfirmSubmit.js.html +2 -2
- data/docs/brut-js/api/ConfirmationDialog.html +2 -2
- data/docs/brut-js/api/ConfirmationDialog.js.html +2 -2
- data/docs/brut-js/api/ConstraintViolationMessage.html +2 -2
- data/docs/brut-js/api/ConstraintViolationMessage.js.html +2 -2
- data/docs/brut-js/api/ConstraintViolationMessages.html +2 -2
- data/docs/brut-js/api/ConstraintViolationMessages.js.html +2 -2
- data/docs/brut-js/api/CopyToClipboard.html +2 -2
- data/docs/brut-js/api/CopyToClipboard.js.html +2 -2
- data/docs/brut-js/api/Form.html +2 -2
- data/docs/brut-js/api/Form.js.html +2 -2
- data/docs/brut-js/api/I18nTranslation.html +2 -2
- data/docs/brut-js/api/I18nTranslation.js.html +5 -2
- data/docs/brut-js/api/LocaleDetection.html +2 -2
- data/docs/brut-js/api/LocaleDetection.js.html +2 -2
- data/docs/brut-js/api/Logger.html +2 -2
- data/docs/brut-js/api/Logger.js.html +2 -2
- data/docs/brut-js/api/Message.html +2 -2
- data/docs/brut-js/api/Message.js.html +11 -5
- data/docs/brut-js/api/PrefixedLogger.html +2 -2
- data/docs/brut-js/api/RichString.html +9 -9
- data/docs/brut-js/api/RichString.js.html +6 -3
- data/docs/brut-js/api/Tabs.html +2 -2
- data/docs/brut-js/api/Tabs.js.html +2 -2
- data/docs/brut-js/api/Toast.html +270 -0
- data/docs/brut-js/api/Toast.js.html +153 -0
- data/docs/brut-js/api/Tracing.html +2 -2
- data/docs/brut-js/api/Tracing.js.html +2 -2
- data/docs/brut-js/api/external-CustomElementRegistry.html +3 -3
- data/docs/brut-js/api/external-Performance.html +3 -3
- data/docs/brut-js/api/external-Promise.html +3 -3
- data/docs/brut-js/api/external-ValidityState.html +3 -3
- data/docs/brut-js/api/external-Window.html +4 -4
- data/docs/brut-js/api/external-fetch.html +3 -3
- data/docs/brut-js/api/global.html +3 -3
- data/docs/brut-js/api/index.html +2 -2
- data/docs/brut-js/api/index.js.html +5 -2
- data/docs/brut-js/api/module-testing.html +2 -2
- data/docs/brut-js/api/testing.AssetMetadata.html +2 -2
- data/docs/brut-js/api/testing.AssetMetadataLoader.html +2 -2
- data/docs/brut-js/api/testing.CustomElementTest.html +2 -2
- data/docs/brut-js/api/testing.DOMCreator.html +2 -2
- data/docs/brut-js/api/testing_AssetMetadata.js.html +2 -2
- data/docs/brut-js/api/testing_AssetMetadataLoader.js.html +2 -2
- data/docs/brut-js/api/testing_CustomElementTest.js.html +2 -2
- data/docs/brut-js/api/testing_DOMCreator.js.html +2 -2
- data/docs/brut-js/api/testing_index.js.html +2 -2
- data/docs/brut-js.html +5 -5
- data/docs/business-logic.html +3 -3
- data/docs/cli.html +3 -3
- data/docs/components.html +7 -7
- data/docs/configuration.html +5 -5
- data/docs/css.html +3 -3
- data/docs/custom-element-tests.html +3 -3
- data/docs/database-access.html +3 -3
- data/docs/database-schema.html +3 -3
- data/docs/deployment.html +3 -3
- data/docs/dev-environment.html +3 -3
- data/docs/dir-structure.html +3 -3
- data/docs/doc-conventions.html +3 -3
- data/docs/end-to-end-tests.html +3 -3
- data/docs/features.html +3 -3
- data/docs/flash-and-session.html +3 -3
- data/docs/form-constraints.html +3 -3
- data/docs/forms.html +5 -5
- data/docs/getting-started.html +6 -6
- data/docs/handlers.html +3 -3
- data/docs/hashmap.json +1 -1
- data/docs/hooks.html +3 -3
- data/docs/i18n.html +3 -3
- data/docs/index.html +3 -3
- data/docs/instrumentation.html +3 -3
- data/docs/javascript.html +3 -3
- data/docs/jobs.html +3 -3
- data/docs/keyword-injection.html +3 -3
- data/docs/layouts.html +3 -3
- data/docs/lsp.html +3 -3
- data/docs/markdown-examples.html +3 -3
- data/docs/middleware.html +3 -3
- data/docs/overview.html +3 -3
- data/docs/pages.html +3 -3
- data/docs/recipes/alternate-layouts.html +3 -3
- data/docs/recipes/authentication.html +3 -3
- data/docs/recipes/custom-flash.html +3 -3
- data/docs/recipes/form-errors.html +3 -3
- data/docs/recipes/indexed-forms.html +3 -3
- data/docs/recipes/migrations.html +3 -3
- data/docs/recipes/text-field-component.html +3 -3
- data/docs/roadmap.html +3 -3
- data/docs/routes.html +3 -3
- data/docs/security.html +3 -3
- data/docs/seed-data.html +3 -3
- data/docs/space-time-continuum.html +3 -3
- data/docs/tutorial.html +3 -3
- data/docs/tutorials/01-intro.html +3 -3
- data/docs/tutorials/02-dialog.html +5 -5
- data/docs/unit-tests.html +3 -3
- data/docs/why.html +3 -3
- data/dx/bash_customizations +3 -4
- data/dx/build.pre +15 -0
- data/lib/brut/cli/apps/heroku_container_based_deploy.rb +41 -15
- data/lib/brut/cli/apps/test.rb +2 -0
- data/lib/brut/framework/container.rb +6 -4
- data/lib/brut/framework/mcp.rb +1 -1
- data/lib/brut/version.rb +1 -1
- data/mkbrut/Gemfile.lock +2 -2
- data/mkbrut/lib/mkbrut/add_segment.rb +38 -0
- data/mkbrut/lib/mkbrut/add_segment_options.rb +22 -0
- data/mkbrut/lib/mkbrut/app.rb +7 -2
- data/mkbrut/lib/mkbrut/base.rb +1 -0
- data/mkbrut/lib/mkbrut/cli.rb +90 -8
- data/mkbrut/lib/mkbrut/ops/insert_code_in_method.rb +19 -7
- data/mkbrut/lib/mkbrut/ops/insert_into_file.rb +36 -0
- data/mkbrut/lib/mkbrut/ops/prism_parsing_op.rb +14 -2
- data/mkbrut/lib/mkbrut/ops.rb +1 -0
- data/mkbrut/lib/mkbrut/segments/bare_bones.rb +8 -0
- data/mkbrut/lib/mkbrut/segments/demo.rb +8 -0
- data/mkbrut/lib/mkbrut/segments/heroku.rb +23 -3
- data/mkbrut/lib/mkbrut/segments/sidekiq.rb +136 -1
- data/mkbrut/lib/mkbrut/segments.rb +1 -1
- data/mkbrut/lib/mkbrut/version.rb +1 -1
- data/mkbrut/lib/mkbrut.rb +2 -0
- data/mkbrut/templates/Base/.gitignore +3 -0
- data/mkbrut/templates/Base/Dockerfile.dx +18 -21
- data/mkbrut/templates/Base/Gemfile.erb +1 -1
- data/mkbrut/templates/Base/bin/run +107 -67
- data/mkbrut/templates/Base/bin/run.run +4 -0
- data/mkbrut/templates/Base/bin/setup +32 -1
- data/mkbrut/templates/Base/dx/bash_customizations +0 -4
- data/mkbrut/templates/Base/package.json.erb +1 -1
- data/mkbrut/templates/segments/Heroku/deploy/Dockerfile +15 -15
- data/mkbrut/templates/segments/Heroku/deploy/heroku_config.rb +5 -4
- data/mkbrut/templates/segments/Sidekiq/app/boot_sidekiq.rb +2 -0
- data/mkbrut/templates/segments/Sidekiq/app/config/sidekiq.yml +4 -0
- data/mkbrut/templates/segments/Sidekiq/app/src/back_end/jobs/app_job.rb +3 -0
- data/mkbrut/templates/segments/Sidekiq/app/src/back_end/jobs/example_job.rb +12 -0
- data/mkbrut/templates/segments/Sidekiq/app/src/back_end/segments/sidekiq_segment.rb +56 -0
- data/mkbrut/templates/segments/Sidekiq/bin/run.sidekiq +4 -0
- data/mkbrut/templates/segments/Sidekiq/specs/back_end/jobs/example_job.spec.rb +5 -0
- data/mkbrut/templates/segments/Sidekiq/specs/integration/sidekiq_works.spec.rb +38 -0
- metadata +34 -18
- data/docs/assets/chunks/@localSearchIndexroot.C0s1k0UQ.js +0 -1
- /data/docs/assets/{brut-js.md.CbJAe2Ky.lean.js → brut-js.md.BMz0X1Rz.lean.js} +0 -0
- /data/docs/assets/{components.md.C6nWgDP0.lean.js → components.md.Dfd3w6UW.lean.js} +0 -0
- /data/docs/assets/{configuration.md.CpbYHWPb.lean.js → configuration.md.DTYoV2Ea.lean.js} +0 -0
- /data/docs/assets/{forms.md.Bii91k3E.lean.js → forms.md.DEkmJUvb.lean.js} +0 -0
- /data/docs/assets/{getting-started.md.ChAvueK7.lean.js → getting-started.md.DO-4eoGW.lean.js} +0 -0
- /data/docs/assets/{tutorials_02-dialog.md.De6iTsWX.lean.js → tutorials_02-dialog.md.D2vSjDVf.lean.js} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98447eff97921a8aeb30a9ffa801452a97c8f46a6169e300f6792582c6af191c
|
4
|
+
data.tar.gz: 3040a27ce2283e967f0f0bac694cb0a4fcaa7c7c0bd1bb2c52246dea9dcc2ba5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 834e282f6c08942742733de34e04b9b4ada8cf03bbff02b6604fe54a49af28d1fdebe9da173b852e49f29ab87562335495fc9b6846a0b3a6184aa833677908d1
|
7
|
+
data.tar.gz: 9d41d53d28c12e4d5a99ab81490f10c5e0ccb4f6158c1c1dee51ba5321e3d1e92c04e5e1d566815319dea20bc0071662da174c4d930e84d7a30510da1a382cca
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Brut CHANGELOG
|
2
2
|
|
3
|
+
## v0.16.0.pre - Sep 29, 2025
|
4
|
+
|
5
|
+
* Sidekiq support - this may have some churn in various config files that only reveal themselves on deploy so this
|
6
|
+
is a pre-release. Do not use this version.
|
7
|
+
|
3
8
|
## v0.15.0 - Sep 16, 2025
|
4
9
|
|
5
10
|
* Added `<brut-toast>` to help with toast notifications. They rely on CSS for showing, hiding, and animations, all your
|
data/Dockerfile.dx
CHANGED
@@ -37,6 +37,9 @@ ENV EDITOR=vim
|
|
37
37
|
RUN apt-get install -y vim && \
|
38
38
|
echo "set -o vi" >> /root/.bashrc
|
39
39
|
|
40
|
+
# Install NodeJS
|
41
|
+
COPY --from=node:22-slim /usr/local /usr/local
|
42
|
+
|
40
43
|
|
41
44
|
# Setup a non-root user
|
42
45
|
|
@@ -70,12 +73,6 @@ COPY --chown=appuser:${user_gid} dx/bash_customizations.local /home/appuser/.bas
|
|
70
73
|
# ONLY in that group and not in all the groups in which they are a part.
|
71
74
|
USER appuser
|
72
75
|
|
73
|
-
# Install NodeJS, per https://nodejs.org/en/download
|
74
|
-
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash && \
|
75
|
-
\. "$HOME/.nvm/nvm.sh" && \
|
76
|
-
nvm install 22 && \
|
77
|
-
node -v && nvm current && npm -v
|
78
|
-
|
79
76
|
# Node's colors are hand-crafted to always look bad and render at least some text unreadable
|
80
77
|
# no matter what your setup. Cool.
|
81
78
|
ENV NODE_DISABLE_COLORS=1
|
data/Gemfile.lock
CHANGED
data/brut-css/package-lock.json
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "brut-css",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.16.0.pre",
|
4
4
|
"lockfileVersion": 3,
|
5
5
|
"requires": true,
|
6
6
|
"packages": {
|
7
7
|
"": {
|
8
8
|
"name": "brut-css",
|
9
|
-
"version": "0.
|
9
|
+
"version": "0.16.0.pre",
|
10
10
|
"license": "Hippocratic-2.1",
|
11
11
|
"devDependencies": {
|
12
12
|
"comment-parser": "^1.4.1",
|
data/brut-css/package.json
CHANGED
data/brut-js/package-lock.json
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "brut-js",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.16.0.pre",
|
4
4
|
"lockfileVersion": 3,
|
5
5
|
"requires": true,
|
6
6
|
"packages": {
|
7
7
|
"": {
|
8
8
|
"name": "brut-js",
|
9
|
-
"version": "0.
|
9
|
+
"version": "0.16.0.pre",
|
10
10
|
"license": "Hippocratic-2.1",
|
11
11
|
"devDependencies": {
|
12
12
|
"esbuild": "^0.24.2",
|
data/brut-js/package.json
CHANGED
@@ -129,12 +129,13 @@ export default defineConfig({
|
|
129
129
|
text: "Recipes",
|
130
130
|
collapsed: true,
|
131
131
|
items: [
|
132
|
-
{ text: "Migration Basics", link: "/recipes/migrations" },
|
133
|
-
{ text: "Styling Form Errors", link: "/recipes/form-errors" },
|
134
|
-
{ text: "Authentication", link: "/recipes/authentication" },
|
135
132
|
{ text: "Alternate Layouts", link: "/recipes/alternate-layouts" },
|
133
|
+
{ text: "Authentication", link: "/recipes/authentication" },
|
136
134
|
{ text: "Custom Flash Class", link: "/recipes/custom-flash" },
|
137
135
|
{ text: "Indexed Form Elements", link: "/recipes/indexed-forms" },
|
136
|
+
{ text: "Managing Secrets in the Dev Environment", link: "/recipes/dev-env-secrets" },
|
137
|
+
{ text: "Migration Basics", link: "/recipes/migrations" },
|
138
|
+
{ text: "Styling Form Errors", link: "/recipes/form-errors" },
|
138
139
|
{ text: "Text Field Component", link: "/recipes/text-field-component" },
|
139
140
|
],
|
140
141
|
},
|
data/brutrb.com/deployment.md
CHANGED
@@ -22,30 +22,45 @@ When creating your Brut app with `mkbrut`, the Heroku segment can be used to cre
|
|
22
22
|
|
23
23
|
How to deploy:
|
24
24
|
|
25
|
-
1.
|
25
|
+
1. Get an auth token from Heroku, which you can do from inside the container, and save it to
|
26
|
+
`bash_customizations.local`:
|
26
27
|
|
27
28
|
```
|
28
29
|
your-computer> dx/exec bash
|
29
30
|
devcontainer> heroku auth:login
|
30
31
|
# You will need to copy/paste the URL to log in
|
31
|
-
devcontainer> heroku container
|
32
|
+
devcontainer> heroku authorizations:create -d "container pushes" --expires-in 31536000
|
33
|
+
# Copy the token output by this command
|
34
|
+
devcontainer> echo "HEROKU_API_KEY=«TOKEN YOU COPIED»" >> dx/bash_customizations.local
|
32
35
|
```
|
36
|
+
2. Exit the devcontainer and stop `dx/start` (e.g. hit `Ctrl-C` wherever you ran it)
|
37
|
+
3. Rebuild and restart the devcontainer (this will set `HEROKU_API_KEY` for you)
|
33
38
|
|
34
|
-
|
39
|
+
```
|
40
|
+
your-computer> dx/build
|
41
|
+
your-computer> dx/start
|
42
|
+
# In another terminal window
|
43
|
+
your-computer> dx/exec bash
|
44
|
+
devcontainer> echo $HEROKU_API_KEY
|
45
|
+
# You should see the token
|
46
|
+
```
|
47
|
+
|
48
|
+
Setting this environment variable avoids having to constantly re-authenticate to Heroku.
|
49
|
+
|
50
|
+
4. Create your app using the container stack:
|
35
51
|
|
36
52
|
```
|
37
53
|
> heroku create --stack container -a «your heroku app name»
|
38
54
|
```
|
39
|
-
|
40
|
-
|
55
|
+
5. Ensure your app's source code is all checked in, there are no uncommitted or unadded files, and you have pushed to the `main` branch of your remote Git repository.
|
56
|
+
6. `bin/deploy`
|
41
57
|
|
42
58
|
This will generate a `Dockerfile` for each process (by default, `Dockerfile.web` and `Dockerfile.release`), build images, push those images to Heroku, and ask Heroku to release them.
|
43
59
|
|
44
60
|
Debugging Tips:
|
45
61
|
|
46
|
-
* Keep in mind it's hard to make general deployment tools. You are expected to understand your deployment and be capable of deploying an arbitrary Rack app manually. Brut's tooling automates what you need to know.
|
47
|
-
* `bin/deploy` runs the `deploy` subcommand, so `bin/deploy help deploy` can provide
|
48
|
-
some options for debugging issues:
|
62
|
+
* Keep in mind it's hard to make general deployment tools. You are expected to understand your deployment and be capable of deploying an arbitrary Rack app manually. Brut's tooling automates what you need to do based on what you already need to know.
|
63
|
+
* `bin/deploy` runs the `deploy` subcommand, so `bin/deploy help deploy` can provide some options for debugging issues:
|
49
64
|
|
50
65
|
```
|
51
66
|
devcontainer> bin/deploy help deploy
|
@@ -106,7 +121,6 @@ some options for debugging issues:
|
|
106
121
|
You'll need to have a better understanding of Docker to do this, however if you
|
107
122
|
are deploying with Docker, this is an understanding you hopefully already have.
|
108
123
|
|
109
|
-
|
110
124
|
### Other Mechanisms for Deployment
|
111
125
|
|
112
126
|
As a Rack app, other deployments should be possible. To make the app work, you'll need to make sure a few things are dealt with:
|
data/brutrb.com/jobs.md
CHANGED
@@ -1,14 +1,114 @@
|
|
1
1
|
# Background Jobs
|
2
2
|
|
3
|
-
Brut
|
4
|
-
|
3
|
+
Brut ships without any background job system, however it should work with any system you'd like to use. Brut
|
4
|
+
can install/configure Sidekiq for you, however you are expected to understand Sidekiq in order to use it.
|
5
5
|
|
6
|
-
|
6
|
+
## Setting up Sidekiq
|
7
7
|
|
8
|
-
|
8
|
+
Brut's code-generation system used for installing capabilities are called *segments*, and Brut provides a
|
9
|
+
Sidekiq segment you can use to get an initial working setup of Sidekiq in your Brut app.
|
9
10
|
|
10
|
-
|
11
|
-
> The way Sidekiq is configured with Brut is effective and reliable, but it is complex. It currently
|
12
|
-
> involves several moving parts to make it work properly. This will be an area for improvement.
|
11
|
+
### Adding the Segment
|
13
12
|
|
13
|
+
1. Ensure your project files are all committed. This is so you can easily see (and, if needed, undo) the
|
14
|
+
changes `mkbrut` will make.
|
15
|
+
2. Use `mkbrut` to add the segment:
|
14
16
|
|
17
|
+
```
|
18
|
+
docker run \
|
19
|
+
--pull always \
|
20
|
+
-v "$PWD":"$PWD" \
|
21
|
+
-w "$PWD" \
|
22
|
+
-u $(id -u):$(id -g) \
|
23
|
+
-it \
|
24
|
+
thirdtank/mkbrut \
|
25
|
+
mkbrut add-segment -r /path/to/your/project sidekiq
|
26
|
+
```
|
27
|
+
3. This will modify and create various files in your project. Check them out if you like:
|
28
|
+
|
29
|
+
```
|
30
|
+
> git status
|
31
|
+
```
|
32
|
+
4. Exit your dev environment (i.e. hit `Ctrl-C` wherever you ran `dx/start`).
|
33
|
+
5. Rebuild and restart your dev environment. This may take a moment, since Valkey will be downloaded.
|
34
|
+
|
35
|
+
```
|
36
|
+
your-computer> dx/build
|
37
|
+
your-computer> dx/start
|
38
|
+
```
|
39
|
+
6. In another Terminal, connect to your dev container and run `bin/setup`
|
40
|
+
|
41
|
+
```
|
42
|
+
your-computer> dx/exec bash
|
43
|
+
devcontainer> bin/setup
|
44
|
+
```
|
45
|
+
7. The segment provides an integration test that will use the actual Sidekiq server and client, running
|
46
|
+
against the actual Valkey database that was installed:
|
47
|
+
|
48
|
+
```
|
49
|
+
devcontainer> bin/test e2e specs/integration/sidekiq_works.spec.rb
|
50
|
+
```
|
51
|
+
|
52
|
+
If this test passes, you are ready to go.
|
53
|
+
|
54
|
+
### Using Sidekiq in Brut
|
55
|
+
|
56
|
+
Jobs live in `app/src/back_end/jobs`, however this is just a convention and is not enforced - you can place a
|
57
|
+
job anywhere that Zeitwerk will find the class. Brut also provides basic configuration and a base job.
|
58
|
+
|
59
|
+
| File | Purpose|
|
60
|
+
|------|--------|
|
61
|
+
| `app/config/sidekiq.yml` | Standard configuration for Sidekiq |
|
62
|
+
| `app/src/back-end/jobs/app_job.r` | Base class for your jobs that includes `Sidekiq::Job` |
|
63
|
+
| `app/src/back-end/segments/sidekiq_segment.rb` | Initial client and server configuration for Sidekiq (that you can't do with `sidekiq.yml`. This sets up basic observability for your jobs |
|
64
|
+
|
65
|
+
### Accessing the Web UI
|
66
|
+
|
67
|
+
The Sidekiq segment mounts the Sidekiq Web UI to your app inside `config.ru`:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
# ...
|
71
|
+
map "/sidekiq" do
|
72
|
+
use Rack::Auth::Basic, "Sidekiq" do |username, password|
|
73
|
+
[username, password] == [ENV.fetch("SIDEKIQ_BASIC_AUTH_USER"), ENV.fetch("SIDEKIQ_BASIC_AUTH_PASSWORD")]
|
74
|
+
end
|
75
|
+
run Sidekiq::Web.new
|
76
|
+
end
|
77
|
+
# ...
|
78
|
+
```
|
79
|
+
|
80
|
+
Values for `SIDEKIQ_BASIC_AUTH_USER` and `SIDEKIQ_BASIC_AUTH_PASSWORD` for dev and test are placed into
|
81
|
+
`.env.development` and `.env.test`, respectively. You must provide these values for production, based on
|
82
|
+
however you are managing environment variables.
|
83
|
+
|
84
|
+
Once you start the app, navigat to `http://localhost:6502/sidekiq` and enter the username/password from
|
85
|
+
`.env.development`. You should see the web UI.
|
86
|
+
|
87
|
+
### Deploying with The Heroku Segment
|
88
|
+
|
89
|
+
If you have set up [Heroku Container-based Deployment](/deployment.md#heroku-container-based-deployment), you
|
90
|
+
may need to modify `deploy/heroku_config.rb`. The Sidekiq segement should have edited this, however if you
|
91
|
+
installed the Heroku segment after setting up Sidekiq, you'll need to add to the file:
|
92
|
+
|
93
|
+
```ruby [2-6]
|
94
|
+
class HerokuConfig
|
95
|
+
def self.additional_images
|
96
|
+
{
|
97
|
+
"sidekiq" => {
|
98
|
+
cmd: "bin/run-sidekiq",
|
99
|
+
}
|
100
|
+
}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
## Setting Up Other Job Systems
|
106
|
+
|
107
|
+
To use another job system, you'll likely want to start with `app/src/app.rb`. You can place all your
|
108
|
+
initialize code in `#boot!` to get things working, then factor it out from there. `App`, the class in that
|
109
|
+
file, is a normal class, so you can extract your setup to other normal classes and bring them in as you would
|
110
|
+
in any other Ruby app.
|
111
|
+
|
112
|
+
Just note that `App`'s `initialize` method should avoid making network connections, so while you are safe to
|
113
|
+
create objects and configuration here, do not connect to databases or anything like that. You *can* do that
|
114
|
+
inside `boot!`.
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Managing Secrets in the Dev Environment
|
2
|
+
|
3
|
+
Often, you need API keys like GitHub or Heroku tokens in order to perform development tasks. These should not be checked into version
|
4
|
+
control, however you can still manage them.
|
5
|
+
|
6
|
+
## Feature - API Keys
|
7
|
+
|
8
|
+
* Developers need do use the Heroku command-line app inside the dev container.
|
9
|
+
* Develoeprs do not want to have to perform a daily, browser-based authentication via `heroku auth:login`
|
10
|
+
|
11
|
+
### Recipe
|
12
|
+
|
13
|
+
The file `dx/bash_customizations.local` is set up for exactly this. It is not checked into version control (see your `.gitignore`), and it
|
14
|
+
is included when the development environment is built.
|
15
|
+
|
16
|
+
```bash
|
17
|
+
# dx/bash_customizations.local
|
18
|
+
HEROKU_API_KEY=xxxxxx
|
19
|
+
```
|
20
|
+
|
21
|
+
When you change this file, you must rebuild your dev environment:
|
22
|
+
|
23
|
+
1. `Ctrl-C` wherever you ran `dx/start`
|
24
|
+
2. `dx/build`
|
25
|
+
3. `dx/start`
|
26
|
+
4. `dx/exec bash`, then `bin/setup`, then continue where you left off
|
27
|
+
|
28
|
+
#### How This Works
|
29
|
+
|
30
|
+
Here is a snippet of how this works. In the first `RUN` directlive, the non-root user is created. When that is completed, `~/.profile` and
|
31
|
+
`~/.bashrc` are modified to source both `bash_customizations` (per-project customizations that should **not** contain secrets) and
|
32
|
+
`bash_customizations.local`, which is the file we are discussing.
|
33
|
+
|
34
|
+
After that, the files are copied into the image via the `COPY` directives.
|
35
|
+
|
36
|
+
```dockerfile
|
37
|
+
# Snippet from Dockerfile.dx
|
38
|
+
RUN useradd --uid ${user_uid} --gid ${user_gid} --groups ${sadly_user_must_be_added_to_root}${docker_gid} --create-home --home-dir /home/appuser appuser && \
|
39
|
+
echo ". ~/.bash_customizations" >> /home/appuser/.profile && \
|
40
|
+
echo ". ~/.bash_customizations.local" >> /home/appuser/.profile && \
|
41
|
+
echo ". ~/.bash_customizations" >> /home/appuser/.bashrc && \
|
42
|
+
echo ". ~/.bash_customizations.local" >> /home/appuser/.bashrc
|
43
|
+
|
44
|
+
COPY --chown=appuser:${user_gid} dx/show-help-in-app-container-then-wait.sh /home/appuser
|
45
|
+
COPY --chown=appuser:${user_gid} dx/bash_customizations /home/appuser/.bash_customizations
|
46
|
+
COPY --chown=appuser:${user_gid} dx/bash_customizations.local /home/appuser/.bash_customizations.local
|
47
|
+
```
|
48
|
+
|
49
|
+
> [!WARNING]
|
50
|
+
> The resulting image **will** contain the secrets from `bash_customizations.local`, so it's
|
51
|
+
> **very important** you never push that image to a regsitry.
|
52
|
+
|
53
|
+
## Feature - SSH Keys
|
54
|
+
|
55
|
+
* You need an SSH key in order to push to GitHub from the dev container
|
56
|
+
* You do not want to creata new key every time
|
57
|
+
|
58
|
+
### Recipe
|
59
|
+
|
60
|
+
Ultimately, you want the SSH key to be copied into the container and set up as if you'd created the key there. The recipe below is an
|
61
|
+
example of how you could do this, and should demonstrate the various seams in Brut's dev environment to allow you to craft it how you like.
|
62
|
+
|
63
|
+
1. Choose a directory in the project where each developer will store their keys. **This directory should be excluded from version control**
|
64
|
+
|
65
|
+
```
|
66
|
+
mkdir dx/credentials
|
67
|
+
echo "/dx/credetials" >> .gitignore
|
68
|
+
```
|
69
|
+
|
70
|
+
2. Assuming you create an SSH key already, place `id_ed25519` (private key) and `id_ed25519.pub` (public key) into `dx/credentials`.
|
71
|
+
3. Create `dx/credentials/known_hosts` using `id_ed25519.pub`:
|
72
|
+
|
73
|
+
```
|
74
|
+
github.com ssh-ed25519 «key from id_ed25519.pub here»
|
75
|
+
```
|
76
|
+
4. Your dev container will have access to `dx/credentials` already, so you can use `bin/setup` to copy them to the right place. How
|
77
|
+
you do this depends on how complicated you want to get. You can examine Brut's `bin/setup` to see how it manages it. You will
|
78
|
+
see that ti uses `ssh-agent` to avoid requiring the passcode every time, and that it uses `chmod` to make sure the SSH
|
79
|
+
directories are the right permissions.
|
80
|
+
|
81
|
+
> [!WARNING]
|
82
|
+
> The resulting image **will** contain your SSH key, so it's
|
83
|
+
> **very important** you never push that image to a regsitry.
|
84
|
+
|
85
|
+
|
86
|
+
This recipe is scant on details, since each credential is highly specific. The key points to know are that you can store information in the
|
87
|
+
project, but not checked in, then rely on that information being available to `bin/setup` inside the container.
|
data/brutrb.com/roadmap.md
CHANGED
@@ -5,10 +5,10 @@ call a 1.0 release. Here are some ideas of what I think is needed:
|
|
5
5
|
|
6
6
|
## Better Dev Experience
|
7
7
|
|
8
|
+
* The CLI apps are all shimmed in a wierd way, expecially `mkbrut`. They should be part of the gem.
|
8
9
|
* The output of `bin/dev` isn't great.
|
9
10
|
* otel-desktop-viewer is cool, but not the easiest to figure out issues as compred to good 'ole logging.
|
10
11
|
* Error pages in the app are *really* bad.
|
11
|
-
* CLI apps are OK, but could be fancier.
|
12
12
|
|
13
13
|
## More Tests
|
14
14
|
|
@@ -21,7 +21,7 @@ call a 1.0 release. Here are some ideas of what I think is needed:
|
|
21
21
|
|
22
22
|
## More Complete Web Features
|
23
23
|
|
24
|
-
* Content security policy
|
24
|
+
* Content security policy is all or nothing. You can bring stuff in via CDN without disabling the feature entirely. I want everyone using CSP, but it needs to be more configurable.
|
25
25
|
* Websockets, server-push, etc. should be possible or at least have a recipe.
|
26
26
|
* Learn more about importmaps.
|
27
27
|
|
@@ -50,8 +50,3 @@ Out of the box support for more deployment mechanism, at least:
|
|
50
50
|
* A unified look and feel across the board
|
51
51
|
* Get rid of VitePress for something less client-heavy, but still great
|
52
52
|
* Dash-accessible API docs
|
53
|
-
|
54
|
-
## Misc
|
55
|
-
|
56
|
-
* More direct Sidekiq support
|
57
|
-
|
data/docs/404.html
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
<link rel="preload stylesheet" href="/assets/style.B1z60PPQ.css" as="style">
|
10
10
|
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
|
11
11
|
|
12
|
-
<script type="module" src="/assets/app.
|
12
|
+
<script type="module" src="/assets/app.Dm7v_ouO.js"></script>
|
13
13
|
<link rel="icon" href="/favicon.ico">
|
14
14
|
<meta property="og:title" content="BrutRB Documentation">
|
15
15
|
<meta property="og:type" content="website">
|
@@ -20,7 +20,7 @@
|
|
20
20
|
</head>
|
21
21
|
<body>
|
22
22
|
<div id="app"></div>
|
23
|
-
<script>window.__VP_HASH_MAP__=JSON.parse("{\"adrs.md\":\"YglbWtQe\",\"ai.md\":\"ChLnvDAX\",\"assets.md\":\"BEF6Oz6K\",\"brut-js.md\":\"
|
23
|
+
<script>window.__VP_HASH_MAP__=JSON.parse("{\"adrs.md\":\"YglbWtQe\",\"ai.md\":\"ChLnvDAX\",\"assets.md\":\"BEF6Oz6K\",\"brut-js.md\":\"BMz0X1Rz\",\"business-logic.md\":\"DbuaOYGU\",\"cli.md\":\"DDMar_51\",\"components.md\":\"Dfd3w6UW\",\"configuration.md\":\"DTYoV2Ea\",\"css.md\":\"K5rOCOQY\",\"custom-element-tests.md\":\"DiLe-eFw\",\"database-access.md\":\"Dc8l2Plf\",\"database-schema.md\":\"BJ_JhXmO\",\"deployment.md\":\"C1u5ep0g\",\"dev-environment.md\":\"B1S9p5ZK\",\"dir-structure.md\":\"D1T2kGwj\",\"doc-conventions.md\":\"CDnWaEFg\",\"end-to-end-tests.md\":\"BJJdNDYL\",\"features.md\":\"BDWxnyNO\",\"flash-and-session.md\":\"CUsMxoNl\",\"form-constraints.md\":\"KlfXSKm2\",\"forms.md\":\"DEkmJUvb\",\"getting-started.md\":\"DO-4eoGW\",\"handlers.md\":\"C5tUwmmo\",\"hooks.md\":\"CoiYCKRc\",\"i18n.md\":\"DxkCKhUw\",\"index.md\":\"DnphWyQd\",\"instrumentation.md\":\"BcxjC4jd\",\"javascript.md\":\"D6fxhaQb\",\"jobs.md\":\"Bc7Y1YpK\",\"keyword-injection.md\":\"CqLnnzIz\",\"layouts.md\":\"HEbeK7Jr\",\"lsp.md\":\"bE9dW8n9\",\"markdown-examples.md\":\"BPmtHlc-\",\"middleware.md\":\"BhOIsg59\",\"overview.md\":\"BpWAgPFH\",\"pages.md\":\"B3sQXpEd\",\"recipes_alternate-layouts.md\":\"C1QzVkA7\",\"recipes_authentication.md\":\"CyvoIW82\",\"recipes_custom-flash.md\":\"6gFqf2uL\",\"recipes_form-errors.md\":\"B5ptSzMO\",\"recipes_indexed-forms.md\":\"BYYQGW2C\",\"recipes_migrations.md\":\"Cid7-3cu\",\"recipes_text-field-component.md\":\"VhOsCtKI\",\"roadmap.md\":\"CJsbUmK_\",\"routes.md\":\"C1dgIBtD\",\"security.md\":\"Jn4SY1uK\",\"seed-data.md\":\"UZW0WxYN\",\"space-time-continuum.md\":\"D9rYGDFH\",\"tutorial.md\":\"BX6f6l00\",\"tutorials_01-intro.md\":\"CzZ3kpF_\",\"tutorials_02-dialog.md\":\"D2vSjDVf\",\"unit-tests.md\":\"vDsdBbO_\",\"why.md\":\"4WpxdrQ2\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Brut RB\",\"description\":\"Documentation for the Brut.RB web framework.\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"search\":{\"provider\":\"local\"},\"nav\":[{\"text\":\"Home\",\"link\":\"/\"},{\"text\":\"Getting Started\",\"link\":\"/getting-started\"},{\"text\":\"Overview\",\"link\":\"/overview\"},{\"text\":\"Brut API\",\"link\":\"/api/index.html\",\"target\":\"_self\"},{\"text\":\"BrutJS\",\"link\":\"/brut-js/api/index.html\",\"target\":\"_self\"},{\"text\":\"BrutCSS\",\"link\":\"/brut-css/index.html\",\"target\":\"_self\"}],\"outline\":[2,3],\"sidebar\":[{\"text\":\"Overview\",\"collapsed\":false,\"items\":[{\"text\":\"Getting Started\",\"link\":\"/getting-started\"},{\"text\":\"Concepts\",\"link\":\"/overview\"},{\"text\":\"Features\",\"link\":\"/features\"},{\"text\":\"Directory Structure\",\"link\":\"/dir-structure\"},{\"text\":\"Dev Environment\",\"link\":\"/dev-environment\"},{\"text\":\"Tutorial\",\"link\":\"/tutorial\"},{\"text\":\"Documentation Conventions\",\"link\":\"/doc-conventions\"}]},{\"text\":\"Front-End\",\"collapsed\":false,\"items\":[{\"text\":\"Routes\",\"link\":\"/routes\"},{\"text\":\"Pages\",\"link\":\"/pages\"},{\"text\":\"Layouts\",\"link\":\"/layouts\"},{\"text\":\"Forms\",\"link\":\"/forms\"},{\"text\":\"Form Constraints\",\"link\":\"/form-constraints\"},{\"text\":\"Handlers and Actions\",\"link\":\"/handlers\"},{\"text\":\"Components\",\"link\":\"/components\"},{\"text\":\"Flash and Session\",\"link\":\"/flash-and-session\"},{\"text\":\"Space/Time Continuum\",\"link\":\"/space-time-continuum\"},{\"text\":\"JavaScript\",\"link\":\"/javascript\"},{\"text\":\"CSS\",\"link\":\"/css\"},{\"text\":\"Assets\",\"link\":\"/assets\"},{\"text\":\"BrutJS\",\"link\":\"/brut-js\"}]},{\"text\":\"Back-End\",\"collapsed\":false,\"items\":[{\"text\":\"Database Schema\",\"link\":\"/database-schema\"},{\"text\":\"Database Access\",\"link\":\"/database-access\"},{\"text\":\"Seed Data\",\"link\":\"/seed-data\"},{\"text\":\"Jobs\",\"link\":\"/jobs\"},{\"text\":\"Business Logic\",\"link\":\"/business-logic\"}]},{\"text\":\"Framework\",\"collapsed\":false,\"items\":[{\"text\":\"Configuration\",\"link\":\"/configuration\"},{\"text\":\"Keyword Injection\",\"link\":\"/keyword-injection\"},{\"text\":\"I18n\",\"link\":\"/i18n\"},{\"text\":\"CLI / Tasks\",\"link\":\"/cli\"},{\"text\":\"Deployment\",\"link\":\"/deployment\"}]},{\"text\":\"Testing\",\"collapsed\":false,\"items\":[{\"text\":\"Unit Tests\",\"link\":\"/unit-tests\"},{\"text\":\"End-to-End Tests\",\"link\":\"/end-to-end-tests\"},{\"text\":\"Testing Custom Elements\",\"link\":\"/custom-element-tests\"}]},{\"text\":\"Advanced Topics\",\"collapsed\":true,\"items\":[{\"text\":\"Route Hooks\",\"link\":\"/hooks\"},{\"text\":\"Middleware\",\"link\":\"/middleware\"},{\"text\":\"Instrumentation\",\"link\":\"/instrumentation\"},{\"text\":\"Security\",\"link\":\"/security\"},{\"text\":\"LSP Support\",\"link\":\"/lsp\"}]},{\"text\":\"Recipes\",\"collapsed\":true,\"items\":[{\"text\":\"Migration Basics\",\"link\":\"/recipes/migrations\"},{\"text\":\"Styling Form Errors\",\"link\":\"/recipes/form-errors\"},{\"text\":\"Authentication\",\"link\":\"/recipes/authentication\"},{\"text\":\"Alternate Layouts\",\"link\":\"/recipes/alternate-layouts\"},{\"text\":\"Custom Flash Class\",\"link\":\"/recipes/custom-flash\"},{\"text\":\"Indexed Form Elements\",\"link\":\"/recipes/indexed-forms\"},{\"text\":\"Text Field Component\",\"link\":\"/recipes/text-field-component\"}]},{\"text\":\"Meta\",\"collapsed\":false,\"items\":[{\"text\":\"Why?!\",\"link\":\"/why\"},{\"text\":\"ADRs\",\"link\":\"/adrs\"},{\"text\":\"Roadmap to 1.0\",\"link\":\"/roadmap\"},{\"text\":\"AI Declaration\",\"link\":\"/ai\"}]}],\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/thirdtank/brut\"}]},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
|
24
24
|
|
25
25
|
</body>
|
26
26
|
</html>
|