brut 0.4.0 → 0.8.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.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/CHANGELOG.md +36 -1
- data/Dockerfile.dx +19 -0
- data/Gemfile.lock +1 -1
- data/README.md +19 -0
- data/assets/MetroIcon.graffle +0 -0
- data/assets/YouTubeThumb.pxd +0 -0
- data/bin/build +86 -0
- data/bin/ci +36 -0
- data/bin/docs +39 -9
- data/bin/publish +61 -0
- data/bin/setup +6 -0
- data/brut-css/bin/build +19 -0
- data/brut-css/bin/ci +19 -0
- data/brut-css/bin/docs +19 -0
- data/brut-css/bin/publish +21 -0
- data/brut-css/bin/setup +1 -0
- data/brut-css/package-lock.json +2 -2
- data/brut-css/package.json +1 -1
- data/brut-css/src/css/flex.css +1 -1
- data/brut-css/src/docs/includes/body-and-header.html.ejs +1 -1
- data/brut-js/bin/build +15 -6
- data/brut-js/bin/docs +25 -0
- data/brut-js/bin/publish +21 -0
- data/brut-js/bin/setup +1 -0
- data/brut-js/dx +1 -0
- data/brut-js/package-lock.json +2 -2
- data/brut-js/package.json +1 -1
- data/brut-js/specs/AjaxSubmit.spec.js +100 -7
- data/brut-js/src/AjaxSubmit.js +76 -40
- data/brut.gemspec +2 -2
- data/brutrb.com/adrs.md +1 -0
- data/brutrb.com/bin/setup +1 -0
- data/brutrb.com/getting-started.md +3 -0
- data/brutrb.com/overview.md +6 -0
- data/brutrb.com/tutorial.md +7 -3
- data/docs/404.html +2 -2
- data/docs/adrs.html +5 -5
- 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 +2 -2
- 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 +86 -2
- data/docs/api/Brut/FrontEnd/Component.html +78 -9
- data/docs/api/Brut/FrontEnd/Components/ConstraintViolations.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/FormTag.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/I18nTranslations.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/Input.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/Inputs/CsrfToken.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/Inputs/InputTag.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/Inputs/RadioButton.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/Inputs/SelectTagWithOptions.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/Inputs/TextareaTag.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/Inputs.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/LocaleDetection.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/PageIdentifier.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/TimeTag.html +3 -3
- data/docs/api/Brut/FrontEnd/Components/Traceparent.html +3 -3
- data/docs/api/Brut/FrontEnd/Components.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/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 +3 -3
- 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 +31 -23
- data/docs/api/Brut/FrontEnd/Pages/MissingPage.html +3 -3
- 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/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/SinatraHelpers/ClassMethods.html +13 -11
- 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/method_list.html +92 -76
- data/docs/api/top-level-namespace.html +1 -1
- data/docs/assets/{adrs.md.JRxZ5uYE.js → adrs.md.BxjHi9-8.js} +1 -1
- data/docs/assets/adrs.md.BxjHi9-8.lean.js +1 -0
- data/docs/assets/{app.AkS4fHzI.js → app.DyQLb4Ot.js} +1 -1
- data/docs/assets/chunks/@localSearchIndexroot.CmtZyrFA.js +1 -0
- data/docs/assets/chunks/{VPLocalSearchBox.By6un1FD.js → VPLocalSearchBox.T1iA-eJx.js} +1 -1
- data/docs/assets/chunks/{theme.DwiUPdci.js → theme.ChwsbWjK.js} +2 -2
- data/docs/assets/{components.md.BfeWD9sX.js → components.md.DHh-NwKs.js} +3 -3
- data/docs/assets/{configuration.md.DoSBNc0H.js → configuration.md.D8Wz3oJU.js} +1 -1
- data/docs/assets/{forms.md.DFveP5g_.js → forms.md.BRE85eju.js} +1 -1
- data/docs/assets/{getting-started.md.DZWjCVC0.js → getting-started.md.2ioiTe-B.js} +6 -3
- data/docs/assets/{getting-started.md.DZWjCVC0.lean.js → getting-started.md.2ioiTe-B.lean.js} +1 -1
- data/docs/assets/overview.md.DlKiRRG_.js +1 -0
- data/docs/assets/overview.md.DlKiRRG_.lean.js +1 -0
- data/docs/assets/tutorial.md.BIb7XT6j.js +1 -0
- data/docs/assets/tutorial.md.BIb7XT6j.lean.js +1 -0
- data/docs/assets.html +3 -3
- data/docs/brut-css/brut.max.css +1 -1
- data/docs/brut-css/classes/appearances.html +1 -1
- data/docs/brut-css/classes/background-colors.html +1 -1
- data/docs/brut-css/classes/border-colors.html +1 -1
- data/docs/brut-css/classes/borders.html +1 -1
- data/docs/brut-css/classes/dimensions.html +1 -1
- data/docs/brut-css/classes/flex.html +3 -3
- data/docs/brut-css/classes/foreground-colors.html +1 -1
- data/docs/brut-css/classes/junk-drawer.html +1 -1
- data/docs/brut-css/classes/layout.html +1 -1
- data/docs/brut-css/classes/lists.html +1 -1
- data/docs/brut-css/classes/positioning.html +1 -1
- data/docs/brut-css/classes/spacings.html +1 -1
- data/docs/brut-css/classes/typography.html +1 -1
- data/docs/brut-css/customization/advanced-configuration.html +1 -1
- data/docs/brut-css/customization/breakpoints.html +1 -1
- data/docs/brut-css/customization/design-system.html +1 -1
- data/docs/brut-css/customization/pseudo-classes.html +1 -1
- data/docs/brut-css/getting-started/core-concepts.html +1 -1
- data/docs/brut-css/getting-started/installation.html +1 -1
- data/docs/brut-css/getting-started/overview.html +1 -1
- data/docs/brut-css/getting-started/simple-example.html +1 -1
- data/docs/brut-css/index.html +1 -1
- data/docs/brut-css/properties/colors.html +1 -1
- data/docs/brut-css/properties/spacings.html +1 -1
- data/docs/brut-css/properties/typography.html +1 -1
- data/docs/brut-js/api/AjaxSubmit.html +56 -7
- data/docs/brut-js/api/AjaxSubmit.js.html +77 -41
- data/docs/brut-js/api/Autosubmit.html +1 -1
- data/docs/brut-js/api/Autosubmit.js.html +1 -1
- data/docs/brut-js/api/BaseCustomElement.html +1 -1
- data/docs/brut-js/api/BaseCustomElement.js.html +1 -1
- data/docs/brut-js/api/BrutCustomElements.html +1 -1
- data/docs/brut-js/api/BufferedLogger.html +1 -1
- data/docs/brut-js/api/ConfirmSubmit.html +1 -1
- data/docs/brut-js/api/ConfirmSubmit.js.html +1 -1
- data/docs/brut-js/api/ConfirmationDialog.html +1 -1
- data/docs/brut-js/api/ConfirmationDialog.js.html +1 -1
- data/docs/brut-js/api/ConstraintViolationMessage.html +1 -1
- data/docs/brut-js/api/ConstraintViolationMessage.js.html +1 -1
- data/docs/brut-js/api/ConstraintViolationMessages.html +1 -1
- data/docs/brut-js/api/ConstraintViolationMessages.js.html +1 -1
- data/docs/brut-js/api/CopyToClipboard.html +1 -1
- data/docs/brut-js/api/CopyToClipboard.js.html +1 -1
- data/docs/brut-js/api/Form.html +1 -1
- data/docs/brut-js/api/Form.js.html +1 -1
- data/docs/brut-js/api/I18nTranslation.html +1 -1
- data/docs/brut-js/api/I18nTranslation.js.html +1 -1
- data/docs/brut-js/api/LocaleDetection.html +1 -1
- data/docs/brut-js/api/LocaleDetection.js.html +1 -1
- data/docs/brut-js/api/Logger.html +1 -1
- data/docs/brut-js/api/Logger.js.html +1 -1
- data/docs/brut-js/api/Message.html +1 -1
- data/docs/brut-js/api/Message.js.html +1 -1
- data/docs/brut-js/api/PrefixedLogger.html +1 -1
- data/docs/brut-js/api/RichString.html +1 -1
- data/docs/brut-js/api/RichString.js.html +1 -1
- data/docs/brut-js/api/Tabs.html +1 -1
- data/docs/brut-js/api/Tabs.js.html +1 -1
- data/docs/brut-js/api/Tracing.html +1 -1
- data/docs/brut-js/api/Tracing.js.html +1 -1
- data/docs/brut-js/api/external-CustomElementRegistry.html +1 -1
- data/docs/brut-js/api/external-Performance.html +1 -1
- data/docs/brut-js/api/external-Promise.html +1 -1
- data/docs/brut-js/api/external-ValidityState.html +1 -1
- data/docs/brut-js/api/external-Window.html +1 -1
- data/docs/brut-js/api/external-fetch.html +1 -1
- data/docs/brut-js/api/global.html +1 -1
- data/docs/brut-js/api/index.html +1 -1
- data/docs/brut-js/api/index.js.html +1 -1
- data/docs/brut-js/api/module-testing.html +1 -1
- data/docs/brut-js/api/testing.AssetMetadata.html +1 -1
- data/docs/brut-js/api/testing.AssetMetadataLoader.html +1 -1
- data/docs/brut-js/api/testing.CustomElementTest.html +1 -1
- data/docs/brut-js/api/testing.DOMCreator.html +1 -1
- data/docs/brut-js/api/testing_AssetMetadata.js.html +1 -1
- data/docs/brut-js/api/testing_AssetMetadataLoader.js.html +1 -1
- data/docs/brut-js/api/testing_CustomElementTest.js.html +1 -1
- data/docs/brut-js/api/testing_DOMCreator.js.html +1 -1
- data/docs/brut-js/api/testing_index.js.html +1 -1
- data/docs/brut-js.html +3 -3
- 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 +9 -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 +5 -5
- data/docs/pages.html +3 -3
- data/docs/recipes/alternate-layouts.html +3 -3
- data/docs/recipes/authentication.html +3 -3
- data/docs/recipes/blank-layouts.html +3 -3
- data/docs/recipes/custom-flash.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 +5 -5
- data/docs/unit-tests.html +3 -3
- data/docs/why.html +3 -3
- data/lib/brut/cli/apps/scaffold.rb +1 -1
- data/lib/brut/framework/mcp.rb +1 -1
- data/lib/brut/front_end/component.rb +19 -0
- data/lib/brut/front_end/components/form_tag.rb +2 -2
- data/lib/brut/front_end/page.rb +11 -7
- data/lib/brut/sinatra_helpers.rb +1 -0
- data/lib/brut/version.rb +1 -1
- data/mkbrut/.gitignore +16 -0
- data/mkbrut/CODE_OF_CONDUCT.txt +100 -0
- data/mkbrut/Gemfile +3 -0
- data/mkbrut/Gemfile.lock +19 -0
- data/mkbrut/LICENSE.txt +370 -0
- data/mkbrut/README.md +145 -0
- data/mkbrut/Rakefile +2 -0
- data/mkbrut/bin/build +36 -0
- data/mkbrut/bin/ci +19 -0
- data/mkbrut/bin/docs +19 -0
- data/mkbrut/bin/publish +129 -0
- data/mkbrut/bin/rake +16 -0
- data/mkbrut/bin/setup +30 -0
- data/mkbrut/brut-welcome.png +0 -0
- data/mkbrut/deploy/.dockerignore +2 -0
- data/mkbrut/deploy/Dockerfile +25 -0
- data/mkbrut/exe/mkbrut +5 -0
- data/mkbrut/lib/mkbrut/app.rb +79 -0
- data/mkbrut/lib/mkbrut/app_id.rb +8 -0
- data/mkbrut/lib/mkbrut/app_name.rb +29 -0
- data/mkbrut/lib/mkbrut/app_options.rb +36 -0
- data/mkbrut/lib/mkbrut/base.rb +57 -0
- data/mkbrut/lib/mkbrut/cli.rb +107 -0
- data/mkbrut/lib/mkbrut/erb_binding_delegate.rb +20 -0
- data/mkbrut/lib/mkbrut/internet_identifier.rb +32 -0
- data/mkbrut/lib/mkbrut/invalid_identifier.rb +4 -0
- data/mkbrut/lib/mkbrut/ops/add_css_import.rb +42 -0
- data/mkbrut/lib/mkbrut/ops/add_i18n_message.rb +74 -0
- data/mkbrut/lib/mkbrut/ops/add_method.rb +48 -0
- data/mkbrut/lib/mkbrut/ops/append_to_file.rb +20 -0
- data/mkbrut/lib/mkbrut/ops/base_op.rb +21 -0
- data/mkbrut/lib/mkbrut/ops/copy_file.rb +12 -0
- data/mkbrut/lib/mkbrut/ops/insert_code_in_method.rb +58 -0
- data/mkbrut/lib/mkbrut/ops/insert_route.rb +52 -0
- data/mkbrut/lib/mkbrut/ops/mkdir.rb +13 -0
- data/mkbrut/lib/mkbrut/ops/prism_parsing_op.rb +70 -0
- data/mkbrut/lib/mkbrut/ops/render_template.rb +26 -0
- data/mkbrut/lib/mkbrut/ops/skip_file.rb +10 -0
- data/mkbrut/lib/mkbrut/ops.rb +16 -0
- data/mkbrut/lib/mkbrut/organization.rb +5 -0
- data/mkbrut/lib/mkbrut/prefix.rb +26 -0
- data/mkbrut/lib/mkbrut/prefixed_io.rb +16 -0
- data/mkbrut/lib/mkbrut/segments/bare_bones.rb +185 -0
- data/mkbrut/lib/mkbrut/segments/demo.rb +121 -0
- data/mkbrut/lib/mkbrut/segments/heroku.rb +30 -0
- data/mkbrut/lib/mkbrut/segments/sidekiq.rb +3 -0
- data/mkbrut/lib/mkbrut/segments.rb +8 -0
- data/mkbrut/lib/mkbrut/version.rb +3 -0
- data/mkbrut/lib/mkbrut/versions.rb +13 -0
- data/mkbrut/lib/mkbrut.rb +18 -0
- data/mkbrut/mkbrut.gemspec +32 -0
- data/mkbrut/templates/Base/.dockerignore +25 -0
- data/mkbrut/templates/Base/.env.development.erb +60 -0
- data/mkbrut/templates/Base/.env.test.erb +8 -0
- data/mkbrut/templates/Base/.gitignore +31 -0
- data/mkbrut/templates/Base/.projections.json +59 -0
- data/mkbrut/templates/Base/Dockerfile.dx +205 -0
- data/mkbrut/templates/Base/Gemfile.erb +53 -0
- data/mkbrut/templates/Base/Procfile.development +5 -0
- data/mkbrut/templates/Base/Procfile.test +1 -0
- data/mkbrut/templates/Base/README.md +4 -0
- data/mkbrut/templates/Base/README.md.erb +40 -0
- data/mkbrut/templates/Base/app/bootstrap.rb +61 -0
- data/mkbrut/templates/Base/app/config/i18n/en/1_defaults.rb +128 -0
- data/mkbrut/templates/Base/app/config/i18n/en/2_app.rb +24 -0
- data/mkbrut/templates/Base/app/public/static/manifest.json.erb +33 -0
- data/mkbrut/templates/Base/app/src/app.rb.erb +37 -0
- data/mkbrut/templates/Base/app/src/back_end/data_models/app_data_model.rb +5 -0
- data/mkbrut/templates/Base/app/src/back_end/data_models/db.rb +19 -0
- data/mkbrut/templates/Base/app/src/back_end/data_models/migrations/20240101130000_citext.rb +6 -0
- data/mkbrut/templates/Base/app/src/back_end/data_models/seed/seed_data.rb +9 -0
- data/mkbrut/templates/Base/app/src/front_end/components/app_component.rb +8 -0
- data/mkbrut/templates/Base/app/src/front_end/components/custom_element_registration.rb.erb +7 -0
- data/mkbrut/templates/Base/app/src/front_end/css/index.css +2 -0
- data/mkbrut/templates/Base/app/src/front_end/css/svgs.css +12 -0
- data/mkbrut/templates/Base/app/src/front_end/forms/app_form.rb +4 -0
- data/mkbrut/templates/Base/app/src/front_end/handlers/app_handler.rb +4 -0
- data/mkbrut/templates/Base/app/src/front_end/images/LogoPylon.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/LogoTransit.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-120x120.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-152x152.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-167x167.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-180x180.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/favicon.ico +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/icon.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/mkicons.sh +6 -0
- data/mkbrut/templates/Base/app/src/front_end/js/index.js +6 -0
- data/mkbrut/templates/Base/app/src/front_end/layouts/default_layout.rb.erb +73 -0
- data/mkbrut/templates/Base/app/src/front_end/pages/app_page.rb +11 -0
- data/mkbrut/templates/Base/app/src/front_end/pages/home_page.rb +62 -0
- data/mkbrut/templates/Base/app/src/front_end/support/app_session.rb +6 -0
- data/mkbrut/templates/Base/app/src/front_end/svgs/README.md +5 -0
- data/mkbrut/templates/Base/app/src/front_end/svgs/comment-button.svg +59 -0
- data/mkbrut/templates/Base/bin/README.md.erb +5 -0
- data/mkbrut/templates/Base/bin/build-assets +7 -0
- data/mkbrut/templates/Base/bin/ci +39 -0
- data/mkbrut/templates/Base/bin/console +31 -0
- data/mkbrut/templates/Base/bin/db +9 -0
- data/mkbrut/templates/Base/bin/dbconsole +51 -0
- data/mkbrut/templates/Base/bin/dev +25 -0
- data/mkbrut/templates/Base/bin/release +26 -0
- data/mkbrut/templates/Base/bin/run +86 -0
- data/mkbrut/templates/Base/bin/scaffold +9 -0
- data/mkbrut/templates/Base/bin/setup +256 -0
- data/mkbrut/templates/Base/bin/startup-message +65 -0
- data/mkbrut/templates/Base/bin/test +9 -0
- data/mkbrut/templates/Base/bin/test-server +29 -0
- data/mkbrut/templates/Base/bin/watch-and-build-assets +37 -0
- data/mkbrut/templates/Base/config.ru +16 -0
- data/mkbrut/templates/Base/docker-compose.dx.yml +92 -0
- data/mkbrut/templates/Base/dx/README.md +28 -0
- data/mkbrut/templates/Base/dx/bash_customizations +12 -0
- data/mkbrut/templates/Base/dx/bash_customizations.local +8 -0
- data/mkbrut/templates/Base/dx/build +107 -0
- data/mkbrut/templates/Base/dx/docker-compose.env.erb +25 -0
- data/mkbrut/templates/Base/dx/dx.sh.lib +137 -0
- data/mkbrut/templates/Base/dx/exec +68 -0
- data/mkbrut/templates/Base/dx/prune +19 -0
- data/mkbrut/templates/Base/dx/show-help-in-app-container-then-wait.sh +38 -0
- data/mkbrut/templates/Base/dx/start +30 -0
- data/mkbrut/templates/Base/dx/stop +23 -0
- data/mkbrut/templates/Base/package.json.erb +37 -0
- data/mkbrut/templates/Base/puma.config.rb +53 -0
- data/mkbrut/templates/Base/specs/e2e/home_page.spec.rb.erb +23 -0
- data/mkbrut/templates/Base/specs/front_end/js/SpecHelper.js +24 -0
- data/mkbrut/templates/Base/specs/front_end/pages/home_page.spec.rb +22 -0
- data/mkbrut/templates/Base/specs/lint_factories.spec.rb +7 -0
- data/mkbrut/templates/Base/specs/spec_helper.rb +78 -0
- data/mkbrut/templates/Base/specs/support.rb +2 -0
- data/mkbrut/templates/segments/BareBones/app/src/front_end/handlers/trigger_exception_handler.rb +24 -0
- data/mkbrut/templates/segments/BareBones/app/src/front_end/js/Example.js.erb +49 -0
- data/mkbrut/templates/segments/BareBones/specs/front_end/handlers/trigger_exception_handler.spec.rb +41 -0
- data/mkbrut/templates/segments/BareBones/specs/front_end/js/Example.spec.js.erb +38 -0
- data/mkbrut/templates/segments/Demo/app/src/back_end/data_models/db/guestbook_message.rb +3 -0
- data/mkbrut/templates/segments/Demo/app/src/back_end/data_models/migrations/20250628194124_guestbook.rb +14 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/components/flash_component.rb +36 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/css/constraint-violations.css +18 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/css/fonts.css +19 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/fonts/monaspace-xenon.ttf +0 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/forms/guestbook_message_form.rb +4 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/handlers/guestbook_message_handler.rb +64 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/pages/guestbook_page/message_component.rb +41 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/pages/guestbook_page.rb +43 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/pages/new_guestbook_message_page.rb +64 -0
- data/mkbrut/templates/segments/Demo/specs/back_end/data_models/db/guestbook_message.spec.rb +5 -0
- data/mkbrut/templates/segments/Demo/specs/e2e/guest_message.spec.rb +54 -0
- data/mkbrut/templates/segments/Demo/specs/factories/db/guestbook_message.factory.rb +7 -0
- data/mkbrut/templates/segments/Demo/specs/front_end/components/flash_component.spec.rb +5 -0
- data/mkbrut/templates/segments/Demo/specs/front_end/handlers/guestbook_message_handler.spec.rb +122 -0
- data/mkbrut/templates/segments/Demo/specs/front_end/pages/guestbook_page/message_component.spec.rb +5 -0
- data/mkbrut/templates/segments/Demo/specs/front_end/pages/guestbook_page.spec.rb +52 -0
- data/mkbrut/templates/segments/Demo/specs/front_end/pages/new_guestbook_message_page.spec.rb +5 -0
- data/mkbrut/templates/segments/Heroku/bin/deploy +11 -0
- data/mkbrut/templates/segments/Heroku/deploy/Dockerfile +125 -0
- data/mkbrut/templates/segments/Heroku/deploy/docker-entrypoint +15 -0
- data/mkbrut/templates/segments/Heroku/deploy/heroku_config.rb +26 -0
- metadata +188 -24
- data/brut-js/CHANGELOG.md +0 -5
- data/docs/assets/adrs.md.JRxZ5uYE.lean.js +0 -1
- data/docs/assets/chunks/@localSearchIndexroot.C9FqcQxD.js +0 -1
- data/docs/assets/overview.md.iMnwLO4x.js +0 -1
- data/docs/assets/overview.md.iMnwLO4x.lean.js +0 -1
- data/docs/assets/tutorial.md.BYXj4cOu.js +0 -1
- data/docs/assets/tutorial.md.BYXj4cOu.lean.js +0 -1
- /data/docs/assets/{components.md.BfeWD9sX.lean.js → components.md.DHh-NwKs.lean.js} +0 -0
- /data/docs/assets/{configuration.md.DoSBNc0H.lean.js → configuration.md.D8Wz3oJU.lean.js} +0 -0
- /data/docs/assets/{forms.md.DFveP5g_.lean.js → forms.md.BRE85eju.lean.js} +0 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
# This file is an input to Docker Compose, and serves
|
2
|
+
# as an additional set of environment variables.
|
3
|
+
|
4
|
+
# IMAGE is the name of the image to be built for running
|
5
|
+
# your app. The recommended format is ORG/REPO:TAG
|
6
|
+
#
|
7
|
+
# The ORG and REPO are based on the values used
|
8
|
+
# with mkbrut. TAG is set to mimic the value
|
9
|
+
# in the FROM directive of the Dockerfile.
|
10
|
+
# This will allow you to upgrade Ruby and run both
|
11
|
+
# versions more easily.
|
12
|
+
IMAGE=<%= organization %>/<%= app_name %>:ruby-3.4
|
13
|
+
|
14
|
+
# PROJECT_NAME is used when running Docker compose
|
15
|
+
# to help ensure the output includes your project's name.
|
16
|
+
PROJECT_NAME=<%= app_name %>
|
17
|
+
|
18
|
+
# DEFAULT_SERVICE is the name of the service (keys under
|
19
|
+
# service: in docker-compose.dx.yml) to use when
|
20
|
+
# running dx/exec and no service is specified.
|
21
|
+
# The value "app" should match that in docker-compose.dx.yml
|
22
|
+
# having the effect of dx/exec running commands inside your app's
|
23
|
+
# container.
|
24
|
+
DEFAULT_SERVICE=app
|
25
|
+
# vim: ft=bash
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# shellcheck shell=bash
|
2
|
+
|
3
|
+
# These are various functions needed by all the other scripts in dx/
|
4
|
+
|
5
|
+
# Log a fatal error and exit nonzero
|
6
|
+
fatal() {
|
7
|
+
remainder=${*:2}
|
8
|
+
if [ -z "$remainder" ]; then
|
9
|
+
log "🛑" "${@}"
|
10
|
+
else
|
11
|
+
log "${@}"
|
12
|
+
fi
|
13
|
+
exit 1
|
14
|
+
}
|
15
|
+
|
16
|
+
# Log an informational message. This is preferable to simply
|
17
|
+
# using `echo` because it prepends the message with the name
|
18
|
+
# of the script so you can tell where the message came from.
|
19
|
+
log() {
|
20
|
+
emoji=$1
|
21
|
+
remainder=${*:2}
|
22
|
+
if [ -z "${NO_EMOJI}" ]; then
|
23
|
+
echo "[ ${0} ] ${*}"
|
24
|
+
else
|
25
|
+
# if remainder is empty that means no emoji was passed
|
26
|
+
if [ -z "$remainder" ]; then
|
27
|
+
echo "[ ${0} ] ${*}"
|
28
|
+
else # emoji was passed, but we ignore it
|
29
|
+
echo "[ ${0} ] ${remainder}"
|
30
|
+
fi
|
31
|
+
fi
|
32
|
+
}
|
33
|
+
|
34
|
+
# Output a debug message if BRUT_WORKSPACE_DEBUG is set
|
35
|
+
debug() {
|
36
|
+
message=$1
|
37
|
+
if [ -z "${BRUT_WORKSPACE_DEBUG}" ]; then
|
38
|
+
return
|
39
|
+
fi
|
40
|
+
log "🐛" "${message}"
|
41
|
+
}
|
42
|
+
|
43
|
+
# Output general usage information for the command and exit zero.
|
44
|
+
#
|
45
|
+
# Args:
|
46
|
+
#
|
47
|
+
# [1] the description of the command
|
48
|
+
# [2] The names of the arguments
|
49
|
+
# [3] If given, the name of the pre hook that the command responds to
|
50
|
+
# [4] If given, the name of the post hook that the command responds to
|
51
|
+
usage() {
|
52
|
+
description=$1
|
53
|
+
arg_names=$2
|
54
|
+
pre_hook=$3
|
55
|
+
post_hook=$4
|
56
|
+
echo "usage: ${0} [-h] ${arg_names}"
|
57
|
+
if [ -n "${description}" ]; then
|
58
|
+
echo
|
59
|
+
echo "DESCRIPTION"
|
60
|
+
echo " ${description}"
|
61
|
+
fi
|
62
|
+
if [ -n "${pre_hook}" ] || [ -n "${post_hook}" ]; then
|
63
|
+
echo
|
64
|
+
echo "HOOKS"
|
65
|
+
if [ -n "${pre_hook}" ]; then
|
66
|
+
echo " ${pre_hook} - if present, called before the main action"
|
67
|
+
fi
|
68
|
+
if [ -n "${post_hook}" ]; then
|
69
|
+
echo " ${post_hook} - if present, called after the main action"
|
70
|
+
fi
|
71
|
+
fi
|
72
|
+
exit 0
|
73
|
+
}
|
74
|
+
|
75
|
+
# Show usage if the command line invocation indicated that help was requested.
|
76
|
+
# This calls usage, so this will exit 0
|
77
|
+
#
|
78
|
+
# Args:
|
79
|
+
#
|
80
|
+
# [1] the description of the command
|
81
|
+
# [2] The names of the arguments
|
82
|
+
# [3] If given, the name of the pre hook that the command responds to
|
83
|
+
# [4] If given, the name of the post hook that the command responds to
|
84
|
+
usage_on_help() {
|
85
|
+
description=$1
|
86
|
+
arg_names=$2
|
87
|
+
pre_hook=$3
|
88
|
+
post_hook=$4
|
89
|
+
# These are the args passed to the invocation so this
|
90
|
+
# function can determine if the user requested help
|
91
|
+
cli_args=( "${@:5}" )
|
92
|
+
|
93
|
+
for arg in "${cli_args[@]}"; do
|
94
|
+
if [ "${arg}" = "-h" ] || [ "${arg}" = "--help" ]; then
|
95
|
+
usage "${description}" "${arg_names}" "${pre_hook}" "${post_hook}"
|
96
|
+
fi
|
97
|
+
done
|
98
|
+
}
|
99
|
+
|
100
|
+
# Ensure that a command line utility exists, exiting nonzero if not.
|
101
|
+
# This is needed to avoid assumptions about what commands a user may have
|
102
|
+
# on their computer. It attempts to provide a more useful error message
|
103
|
+
# than "command not found".
|
104
|
+
require_command() {
|
105
|
+
command_name=$1
|
106
|
+
if ! command -v "${command_name}" >/dev/null 2>&1; then
|
107
|
+
fatal "Command '${command_name}' not found - it is required for this script to run"
|
108
|
+
fi
|
109
|
+
}
|
110
|
+
|
111
|
+
# This loads dx/docker-compose.env as variables to the bash script, thus
|
112
|
+
# allowing Docker Compose and these scripts to share configuration.
|
113
|
+
load_docker_compose_env() {
|
114
|
+
. "${ENV_FILE}"
|
115
|
+
}
|
116
|
+
|
117
|
+
# Execute a hook if the file exists. Note that if the hook exits
|
118
|
+
# nonzero, the caller will need to check the return value of this function and decide
|
119
|
+
# what to do.
|
120
|
+
exec_hook_if_exists() {
|
121
|
+
script_name=$1
|
122
|
+
shift
|
123
|
+
if [ -x "${SCRIPT_DIR}"/"${script_name}" ]; then
|
124
|
+
log "🪝" "${script_name} exists - executing"
|
125
|
+
"${SCRIPT_DIR}"/"${script_name}" "${@}"
|
126
|
+
else
|
127
|
+
debug "${script_name} does not exist"
|
128
|
+
fi
|
129
|
+
}
|
130
|
+
|
131
|
+
require_command "realpath"
|
132
|
+
require_command "cat"
|
133
|
+
|
134
|
+
# Set up the location to the docker-compose.env file.
|
135
|
+
ENV_FILE=$(realpath "${SCRIPT_DIR}")/docker-compose.env
|
136
|
+
|
137
|
+
# vim: ft=bash
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
SCRIPT_DIR=$( cd -- "$( dirname -- "${0}" )" > /dev/null 2>&1 && pwd )
|
6
|
+
|
7
|
+
. "${SCRIPT_DIR}/dx.sh.lib"
|
8
|
+
|
9
|
+
require_command "docker"
|
10
|
+
load_docker_compose_env
|
11
|
+
|
12
|
+
usage_description="Execute a command inside the app's container. Any command other than 'bash' will be run with bash -lc. Use -B to just run the command directly."
|
13
|
+
usage_args="[-s service] [-B] command"
|
14
|
+
usage_pre="exec.pre"
|
15
|
+
usage_on_help "${usage_description}" "${usage_args}" "${usage_pre}" "" "${@}"
|
16
|
+
|
17
|
+
SERVICE="${SERVICE_NAME:-${DEFAULT_SERVICE}}"
|
18
|
+
INCLUDE_PREFIX_FOR_NON_BASH=true
|
19
|
+
while getopts "s:B" opt "${@}"; do
|
20
|
+
case ${opt} in
|
21
|
+
s )
|
22
|
+
SERVICE="${OPTARG}"
|
23
|
+
;;
|
24
|
+
B )
|
25
|
+
INCLUDE_PREFIX_FOR_NON_BASH=false
|
26
|
+
;;
|
27
|
+
\? )
|
28
|
+
log "🛑" "Unknown option: ${opt}"
|
29
|
+
usage "${description}" "${usage_args}" "${usage_pre}"
|
30
|
+
;;
|
31
|
+
: )
|
32
|
+
log "🛑" "Invalid option: ${opt} requires an argument"
|
33
|
+
usage "${description}" "${usage_args}" "${usage_pre}"
|
34
|
+
;;
|
35
|
+
esac
|
36
|
+
done
|
37
|
+
shift $((OPTIND -1))
|
38
|
+
|
39
|
+
if [ $# -eq 0 ]; then
|
40
|
+
log "🛑" "You must provide a command e.g. bash or ls -l"
|
41
|
+
usage "${description}" "${usage_args}" "${usage_pre}"
|
42
|
+
fi
|
43
|
+
|
44
|
+
if ! exec_hook_if_exists "exec.pre"; then
|
45
|
+
log "build.pre failed"
|
46
|
+
exit 1
|
47
|
+
fi
|
48
|
+
|
49
|
+
if [ "$#" -eq 1 ] && [ "$1" = "bash" ]; then
|
50
|
+
COMMAND=(bash)
|
51
|
+
elif [ "$INCLUDE_PREFIX_FOR_NON_BASH" = "true" ]; then
|
52
|
+
COMMAND=(bash -lc "$*")
|
53
|
+
else
|
54
|
+
COMMAND=("$@")
|
55
|
+
fi
|
56
|
+
|
57
|
+
log "🚂" "Running '${COMMAND[@]}' inside container with service name '${SERVICE}'"
|
58
|
+
|
59
|
+
docker \
|
60
|
+
compose \
|
61
|
+
--file docker-compose.dx.yaml \
|
62
|
+
--project-name "${PROJECT_NAME}" \
|
63
|
+
--env-file "${ENV_FILE}" \
|
64
|
+
exec \
|
65
|
+
"${SERVICE}" \
|
66
|
+
"${COMMAND[@]}"
|
67
|
+
|
68
|
+
# vim: ft=bash
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
SCRIPT_DIR=$( cd -- "$( dirname -- "${0}" )" > /dev/null 2>&1 && pwd )
|
6
|
+
|
7
|
+
. "${SCRIPT_DIR}/dx.sh.lib"
|
8
|
+
require_command "docker"
|
9
|
+
load_docker_compose_env
|
10
|
+
|
11
|
+
usage_on_help "Prune containers for this repo" "" "" "" "${@}"
|
12
|
+
|
13
|
+
for container_id in $(docker container ls -a -f "name=^${PROJECT_NAME}-.*-1$" --format="{{.ID}}"); do
|
14
|
+
log "🗑" "Removing container with id '${container_id}'"
|
15
|
+
docker container rm "${container_id}"
|
16
|
+
done
|
17
|
+
echo "🧼" "Containers removed"
|
18
|
+
|
19
|
+
# vim: ft=bash
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
# Ideally, the message below is shown after everything starts up. We can't
|
6
|
+
# achieve this using healthchecks because the interval for a healtcheck is
|
7
|
+
# also an initial delay, and we don't really want to do healthchecks on
|
8
|
+
# our DB or Redis every 2 seconds. So, we sleep just a bit to let
|
9
|
+
# the other containers start up and vomit out their output first.
|
10
|
+
sleep 2
|
11
|
+
# Output some helpful messaging when invoking `dx/start` (which itself is
|
12
|
+
# a convenience script for `docker compose up`.
|
13
|
+
#
|
14
|
+
# Adding this to work around the mild inconvenience of the `app` container's
|
15
|
+
# entrypoint generating no output.
|
16
|
+
#
|
17
|
+
cat <<-'PROMPT'
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
🎉 Dev Environment Initialized! 🎉
|
22
|
+
|
23
|
+
ℹ️ To use this environment, open a new terminal and run
|
24
|
+
|
25
|
+
dx/exec bash
|
26
|
+
|
27
|
+
🕹 Use `ctrl-c` to exit.
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
PROMPT
|
32
|
+
|
33
|
+
# Using `sleep infinity` instead of `tail -f /dev/null`. This may be a
|
34
|
+
# performance improvement based on the conversation on a semi-related
|
35
|
+
# StackOverflow page.
|
36
|
+
#
|
37
|
+
# @see https://stackoverflow.com/a/41655546
|
38
|
+
sleep infinity
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
SCRIPT_DIR=$( cd -- "$( dirname -- "${0}" )" > /dev/null 2>&1 && pwd )
|
6
|
+
|
7
|
+
. "${SCRIPT_DIR}/dx.sh.lib"
|
8
|
+
require_command "docker"
|
9
|
+
load_docker_compose_env
|
10
|
+
|
11
|
+
usage_on_help "Starts all services, including a container in which to run your app" "" "" "" "${@}"
|
12
|
+
|
13
|
+
log "🚀" "Starting docker-compose.dx.yml"
|
14
|
+
|
15
|
+
BUILD=--build
|
16
|
+
if [ "${1}" == "--no-build" ]; then
|
17
|
+
BUILD=
|
18
|
+
fi
|
19
|
+
|
20
|
+
docker \
|
21
|
+
compose \
|
22
|
+
--file docker-compose.dx.yml \
|
23
|
+
--project-name "${PROJECT_NAME}" \
|
24
|
+
--env-file "${ENV_FILE}" \
|
25
|
+
up \
|
26
|
+
"${BUILD}" \
|
27
|
+
--timestamps \
|
28
|
+
--force-recreate
|
29
|
+
|
30
|
+
# vim: ft=bash
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
SCRIPT_DIR=$( cd -- "$( dirname -- "${0}" )" > /dev/null 2>&1 && pwd )
|
6
|
+
|
7
|
+
. "${SCRIPT_DIR}/dx.sh.lib"
|
8
|
+
require_command "docker"
|
9
|
+
load_docker_compose_env
|
10
|
+
|
11
|
+
usage_on_help "Stops all services, the container in which to run your app and removes any volumes" "" "" "" "${@}"
|
12
|
+
|
13
|
+
log "🚀" "Stopping docker-compose.dx.yml"
|
14
|
+
|
15
|
+
docker \
|
16
|
+
compose \
|
17
|
+
--file docker-compose.dx.yml \
|
18
|
+
--project-name "${PROJECT_NAME}" \
|
19
|
+
--env-file "${ENV_FILE}" \
|
20
|
+
down \
|
21
|
+
--volumes
|
22
|
+
|
23
|
+
# vim: ft=bash
|
@@ -0,0 +1,37 @@
|
|
1
|
+
{
|
2
|
+
"name": "<%= app_name %>",
|
3
|
+
"type": "module",
|
4
|
+
"license": "UNLICENSED",
|
5
|
+
"dependencies": {
|
6
|
+
"brut-css": "<%= versions.brut_css_version_specifier %>",
|
7
|
+
"brut-js": "<%= versions.brut_js_version_specifier %>"
|
8
|
+
},
|
9
|
+
"devDependencies": {
|
10
|
+
"chokidar-cli": "^3.0.0",
|
11
|
+
"esbuild": "^0.20.2",
|
12
|
+
"jsdom": "^25.0.1",
|
13
|
+
"mocha": "^10.7.3",
|
14
|
+
"playwright": "1.50.1",
|
15
|
+
"typescript": "^5.8.3",
|
16
|
+
"typescript-language-server": "^4.3.4",
|
17
|
+
"vscode-langservers-extracted": "^4.10.0"
|
18
|
+
},
|
19
|
+
"notes": {
|
20
|
+
"note": "This section provides documentation on what the various information in here is for",
|
21
|
+
"type": "Needs to be 'module' so that the web components unit tests work properly",
|
22
|
+
"dependencies": {
|
23
|
+
"brut-css": "Basic CSS library to get you started. See Brut's docs for how to use or remove",
|
24
|
+
"brut-js": "Autonomous custom elements and utilities. See Brut's docs for how to use and why you should not remove"
|
25
|
+
},
|
26
|
+
"devDependencies": {
|
27
|
+
"chokidar-cli": "Used to watch files and and rebuild stuff on changes",
|
28
|
+
"esbuild": "Bundles JS and CSS - you may need this in dependencies depending on how you deploy",
|
29
|
+
"jsdom": "Used for unit testing custom elements",
|
30
|
+
"mocha": "Used for unit testing custom elements",
|
31
|
+
"playwright": "Used for end-to-end testing. This version is locked and must be the same as the one in the Gemfile for playwright-ruby-client.",
|
32
|
+
"typescript": "Needed for the JS and CSS LSP servers",
|
33
|
+
"typescript-language-server": "Provides a JS LSP server",
|
34
|
+
"vscode-langservers-extracted": "Despite the name, provides a CSS LSP server"
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Mostly based on Heroku's guidance:
|
2
|
+
# https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server
|
3
|
+
|
4
|
+
# Ensures the logger is setup and availbale as early as possible
|
5
|
+
require "semantic_logger"
|
6
|
+
|
7
|
+
# workers should be set to the # of cores. Heroku
|
8
|
+
# recommends the following, with 2 as a default if you don't have a good
|
9
|
+
# reason to change it.
|
10
|
+
workers Integer(ENV["WEB_CONCURRENCY"] || 2)
|
11
|
+
|
12
|
+
# Heroku recommens 5 as a default, with the ability
|
13
|
+
# to change it as needed.
|
14
|
+
threads_count = Integer(ENV["PUMA_MAX_THREADS"] || 5)
|
15
|
+
|
16
|
+
# This actually sets the min and max # of threads.
|
17
|
+
# Heroku recommends setting them both to the thread_count
|
18
|
+
# above.
|
19
|
+
threads threads_count, threads_count
|
20
|
+
|
21
|
+
# Indicate that the app should be loaded before any
|
22
|
+
# forking or thread creation. Despite the bang,
|
23
|
+
# this doesn't actually do anything - it just sets configuration
|
24
|
+
preload_app!
|
25
|
+
|
26
|
+
# Support IPv6 by binding to host `::` instead of `0.0.0.0`
|
27
|
+
port(ENV["PORT"] || 3000, "::")
|
28
|
+
|
29
|
+
# Turn off keepalive support for better long tails response time with Router 2.0
|
30
|
+
# Remove this line when https://github.com/puma/puma/issues/3487 is closed, and the fix is released
|
31
|
+
if respond_to?(:enable_keep_alives)
|
32
|
+
enable_keep_alives(false)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Commenting this out as a) we don't default DefaultRackup
|
36
|
+
# and b) I don't exactly know what it means or does.
|
37
|
+
# rackup DefaultRackup if defined?(DefaultRackup)
|
38
|
+
|
39
|
+
# Set the environment based on RACK_ENV
|
40
|
+
environment ENV["RACK_ENV"]
|
41
|
+
|
42
|
+
before_fork do
|
43
|
+
# Per http://sequel.jeremyevans.net/rdoc/files/doc/fork_safety_rdoc.html
|
44
|
+
# we must disconnect before forking. Sequel will reconnect as needed.
|
45
|
+
Sequel::DATABASES.each(&:disconnect)
|
46
|
+
end
|
47
|
+
|
48
|
+
on_worker_boot do
|
49
|
+
# Per https://logger.rocketjob.io/forking.html we want to reopen
|
50
|
+
# this to avoid issues
|
51
|
+
SemanticLogger.reopen
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe "The home page works" do
|
4
|
+
it "shows a welcome message" do
|
5
|
+
# Instead of hard-coding URLs, you can use the
|
6
|
+
# page classes to navigate to their routing.
|
7
|
+
page.goto(HomePage.routing)
|
8
|
+
|
9
|
+
# The Brut::FrontEnd::Components::PageIdentifier component
|
10
|
+
# renders a <meta> tag that Brut's `be_page_for` will look for.
|
11
|
+
# This is a useful check that you ended up on the page you meant to.
|
12
|
+
expect(page).to be_page_for(HomePage)
|
13
|
+
|
14
|
+
# In Playwright, elements are "located" asynchronously. What is returned
|
15
|
+
# here is an object that will look for an <h1> only when an expectation
|
16
|
+
# is made on it.
|
17
|
+
h1 = page.locator("h1")
|
18
|
+
|
19
|
+
# This will actually locate the <h1> (waiting for some time for it to
|
20
|
+
# show up if it's not there), and then assert its text content.
|
21
|
+
expect(h1).to have_text("Welcome to Brut")
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { createTestBasedOnHTML } from "brut-js/testing"
|
2
|
+
|
3
|
+
import path from "node:path"
|
4
|
+
import fs from "node:fs"
|
5
|
+
|
6
|
+
const __dirname = import.meta.dirname
|
7
|
+
|
8
|
+
const appRoot = path.resolve(__dirname,"..","..","..","app")
|
9
|
+
const publicRoot = path.resolve(appRoot,"public")
|
10
|
+
const assetMetadataFilePath = path.resolve(appRoot,"config","asset_metadata.json")
|
11
|
+
const assetMetadata = JSON.parse(fs.readFileSync(assetMetadataFilePath))
|
12
|
+
|
13
|
+
const withHTML = (html) => {
|
14
|
+
return createTestBasedOnHTML({
|
15
|
+
html,
|
16
|
+
assetMetadata,
|
17
|
+
publicRoot
|
18
|
+
})
|
19
|
+
}
|
20
|
+
|
21
|
+
export {
|
22
|
+
withHTML,
|
23
|
+
}
|
24
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe HomePage do
|
4
|
+
it "should show the H1" do
|
5
|
+
# Page specs should evaluate the generated HTML, so
|
6
|
+
# the generate_and_parse help will accept an instaniated
|
7
|
+
# page (or components), generate its HTML, then use Nokogiri
|
8
|
+
# to parse it, return the result.
|
9
|
+
result = generate_and_parse(described_class.new)
|
10
|
+
|
11
|
+
# e! is provided by Brut::SpecSupport::EnhancedNode which
|
12
|
+
# delegates everything to the underlying Nokogiri::XML::Node
|
13
|
+
# while adding a few methods. e! requires that exactly
|
14
|
+
# one element match the given CSS selector, then returns it.
|
15
|
+
#
|
16
|
+
# Thus, this expectation will fail if:
|
17
|
+
# * there is no <h1> (and the error message would indcate this)
|
18
|
+
# * there is is more than one <h1> (and the error message would indcate this)
|
19
|
+
# * the only <h1>'s text is not exactly "Welcome to Brut"
|
20
|
+
expect(result.e!("h1").text).to eq("Welcome to Brut")
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
ENV["RACK_ENV"] = "test"
|
2
|
+
require_relative "../app/bootstrap"
|
3
|
+
Bootstrap.new.bootstrap!
|
4
|
+
|
5
|
+
require "brut/spec_support"
|
6
|
+
|
7
|
+
require "nokogiri"
|
8
|
+
require "playwright"
|
9
|
+
require "playwright/test"
|
10
|
+
require "confidence_check/for_rspec"
|
11
|
+
require "with_clues"
|
12
|
+
|
13
|
+
require_relative "support"
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
# This configuration has two main parts.
|
17
|
+
#
|
18
|
+
# The first part is here: a call to Brut::SpecSupport::RSpecSetup,
|
19
|
+
# which will set configuration values required for Brut's spec
|
20
|
+
# helpers and other APIs. In generally, you do not want to change
|
21
|
+
# this configuration.
|
22
|
+
rspec_setup = Brut::SpecSupport::RSpecSetup.new(rspec_config: config)
|
23
|
+
rspec_setup.setup!
|
24
|
+
|
25
|
+
# The second part is here and is RSpec configuration that you may want
|
26
|
+
# to change. Changing the configuration below here should not break
|
27
|
+
# any of Brut's internal behavior around tests. The values
|
28
|
+
# and configuration options set are a recommended default, but you
|
29
|
+
# can certainly change it to suit your needs.
|
30
|
+
|
31
|
+
|
32
|
+
# Confidence Check allows you to wrap test expectations
|
33
|
+
# with confidence_check as a way to indicate those expectations are
|
34
|
+
# checking that the test is setup properly and not testing
|
35
|
+
# the behavior of the code under test
|
36
|
+
config.include ConfidenceCheck::ForRSpec
|
37
|
+
|
38
|
+
# With Clues allows you to wrap expectations in
|
39
|
+
# a with_clues block that will provide more details
|
40
|
+
# about the failure and make it easier to diagnose
|
41
|
+
# why a test failed.
|
42
|
+
config.include WithClues::Method
|
43
|
+
config.include FactoryBot::Syntax::Methods
|
44
|
+
|
45
|
+
config.expect_with :rspec do |expectations|
|
46
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
47
|
+
end
|
48
|
+
|
49
|
+
config.mock_with :rspec do |mocks|
|
50
|
+
mocks.verify_partial_doubles = true
|
51
|
+
end
|
52
|
+
|
53
|
+
# Not that you should be using shared contexts, but if you are, please
|
54
|
+
# see https://rubydoc.info/gems/rspec-core/3.13.5/RSpec/Core/Configuration#shared_context_metadata_behavior-instance_method
|
55
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
56
|
+
|
57
|
+
config.filter_run_when_matching :focus
|
58
|
+
|
59
|
+
# Can't find docs on how this path is resolved, so disabling
|
60
|
+
# config.example_status_persistence_file_path = "spec/examples.txt"
|
61
|
+
|
62
|
+
config.disable_monkey_patching!
|
63
|
+
|
64
|
+
config.warnings = ENV.fetch("RSPEC_WARNINGS","false") == "true"
|
65
|
+
|
66
|
+
if config.files_to_run.one?
|
67
|
+
config.default_formatter = "doc"
|
68
|
+
end
|
69
|
+
|
70
|
+
if ENV["RSPEC_PROFILE_EXAMPLES"]
|
71
|
+
config.profile_examples = ENV["RSPEC_PROFILE_EXAMPLES"].to_i
|
72
|
+
end
|
73
|
+
|
74
|
+
config.order = :random
|
75
|
+
|
76
|
+
Kernel.srand config.seed
|
77
|
+
end
|
78
|
+
|
data/mkbrut/templates/segments/BareBones/app/src/front_end/handlers/trigger_exception_handler.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Allows manually triggering an exception so you can see
|
2
|
+
# the exception handling mechanism execute without waiting
|
3
|
+
# for a real exception to happen.
|
4
|
+
class TriggerExceptionHandler < AppHandler
|
5
|
+
# These arguments are query string parameters that
|
6
|
+
# can be given to the URL connected to this handler.
|
7
|
+
# See https://brutrb.com/keyword-injection.html for more details.
|
8
|
+
def initialize(message: "no message provided", status: nil, key: nil)
|
9
|
+
@message = message
|
10
|
+
@status = status
|
11
|
+
@key = key
|
12
|
+
end
|
13
|
+
|
14
|
+
def handle
|
15
|
+
if @key != Brut.container.trigger_exception_key
|
16
|
+
http_status(404)
|
17
|
+
elsif @status
|
18
|
+
http_status(@status)
|
19
|
+
else
|
20
|
+
raise @message
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import { BaseCustomElement } from "brut-js"
|
2
|
+
|
3
|
+
// This is very similar to a vanilla on-spec
|
4
|
+
// implementation of an autonomous custom element.
|
5
|
+
// The only difference is BaseCustomElement (which
|
6
|
+
// extends HTMLElement) provides a few convenience
|
7
|
+
// methods to make it easier to build your own custom
|
8
|
+
// elements.
|
9
|
+
class Example extends BaseCustomElement {
|
10
|
+
// tagName allows BaseCustomElement's define() method to
|
11
|
+
// define your custom element
|
12
|
+
static tagName = "<%= prefix %>-example"
|
13
|
+
|
14
|
+
static observedAttributes = [
|
15
|
+
"transform",
|
16
|
+
"show-warnings", // recognized by BaseCustomElement to allow
|
17
|
+
// for debugguing in the browser console,
|
18
|
+
// but clean consoles in production.
|
19
|
+
]
|
20
|
+
|
21
|
+
#transform = "upper"
|
22
|
+
|
23
|
+
// Called by BaseCustomElement's attributeChangedCallback.
|
24
|
+
transformChangedCallback({newValue}) {
|
25
|
+
this.#transform = newValue
|
26
|
+
}
|
27
|
+
|
28
|
+
// Called by connectCallback and attributeChangedCallback, this
|
29
|
+
// method should make whatever changes are necessary based on the current
|
30
|
+
// state of the element.
|
31
|
+
update() {
|
32
|
+
const content = this.textContent
|
33
|
+
if (this.#transform == "upper") {
|
34
|
+
this.textContent = content.toLocaleUpperCase()
|
35
|
+
}
|
36
|
+
else if (this.#transform == "lower") {
|
37
|
+
this.textContent = content.toLocaleLowerCase()
|
38
|
+
}
|
39
|
+
else {
|
40
|
+
// Example of debugging. if show-warnings is not set, this message
|
41
|
+
// is not shown in the console. If show-warnings IS set (including
|
42
|
+
// when you override it in production using the browser's devtools)
|
43
|
+
// this message WILL be shown
|
44
|
+
this.logger.info("We only support upper or lower, but got %s",this.#transform)
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
export default Example
|