v1.10

v1.10.1

Improvements

  • Generate step after build is faster
    • Generated assemblies are compiled in parallel and share metadata references
    • Roslyn is warmed up in background while domain model is being built
      • Minor breaking change: AddDomainTypes phase is removed, domain layer now provides its configuration targets in Prepare phase of buildtime layer
    • Domain model conventions reuse model contexts instead of recreating them for every convention
      • Minor breaking change: Trace of a model context is only available while a convention is being applied, assign it to a variable to use it in a delegate that runs later
    • Xml documentation of domain members is looked up from an index instead of searching the whole xml file, so it no longer slows down as domain grows
  • Compile errors of generated code are now reported as compile-error diagnostics instead of an unhandled exception
    • Errors of all failing assemblies are reported at once, each with the name of its generated assembly
  • Minor UI improvements
    • Page title icons in method form page was configured incorrectly, fixed
    • Every page uses their route icon as large avatar by default
    • PageTitle
      • Its shadow was leaking to side menu, removed completely, it now has a backdrop blur
    • Avatar size wasn't consistent between type and method pages, fixed
    • Wrap was causing button to behave different under certain conditions, it is now contents and completely transparent, now button with a wrapper behaves identical to a button without wrapper
      • Button.w-full under SimpleForm is now removed

Bugfixes

  • Page title actions were being drilled without using page-title in the path, fixed

v1.10.0

Features

Domain

  • Business namespace now provides Validate object to perform business validations
  • FlagsEnumCodingStyle is now available that supports enums with [Flags]
  • StatusEnumViaSuffixCodingStyle is now available that provides a status enum system using codes that are similar to HTTP status codes
    • Enums with Status suffix get Severities attribute mapping their values to a severity, e.g., 2xx is success, 4xx is warn
    • Properties of a status enum type get Status attribute
    • Severities are exported to severities.json and are available through useSeverities composable
    • It is included in MonolithRecipe by default
  • IExportOptions in Baked.Binding lets an attribute set the name it is exported with, e.g., IdProperty is exported as @id

Schemas and Conventions

  • All component, data, action, trigger and constraint schemas now have a parameterless constructor, so a convention can add any of them by its type, e.g., conventions.AddMethodComponent<DataPanel>()
  • Values are no longer set while adding, they are set by edit conventions, so adding and configuring a schema are separate concerns
  • Default theme provides default conventions for the schemas it adds at Order.At.Min, so an added schema comes configured without any extra convention
    • To change a default, add an edit convention at default order, e.g., conventions.EditMethodSchema<RemoteData>(schema: rd => ...)
  • A schema is turned into a component descriptor with ToDescriptor(), which also accepts data and action

Components

  • New display components are added; Tag and Avatar
    • Enum properties are rendered as Tag with localized text by default, and status enums are colored with their severity
    • Page titles of routes with an icon render an Avatar by default
  • Button now has DialogOptions to render a dialog before executing its action, with Dialog and Confirm modes
    • ActionsAsButtons renders delete methods and methods with up to maxParameterCountForConfirm parameters (default 3) as a confirm popup
  • SimpleForm now accepts a Message component to render before its inputs
  • Wrap is introduced to help wrap multi children depending on a condition
    • It strips out any comment node when condition is false to make sure a single child node renders on its own allowing directives to work properly

Breaking Changes

Feature Definitions

  • Features are now defined with Define() of their abstraction configurator, feature classes and XConfigurator classes are removed
    // was
    public class WelcomeGreetingFeature : IFeature<GreetingConfigurator>
    {
        public void Configure(LayerConfigurator configurator) { ... }
    }
    
    // now
    public static IFeature<GreetingFeature.Configurator> Welcome(this GreetingFeature.Configurator x) =>
        x.Define(configurator => { ... });
    
    • Every abstraction now provides Disabled(), Feature.Empty<T>() is removed
    • Custom themes no longer inherit DefaultThemeFeature, they give their configuration to c.Default(configure: ...) instead

Renamings

  • Attributes used in conventions no longer have the Attribute suffix, e.g., LabelAttribute -> Label. These also changed beyond the suffix;
    oldnew
    ControllerModelAttributeApiController
    ActionModelAttributeApiAction
    ParameterModelAttributeApiParameter
    ActionAttributeUiAction
    DataAttributeUiData
    DescriptionAttributeUiDescription
    RouteAttributeUiRoute
    ApiInputAttributeBindable
    IdAttributeIdProperty
    RichTransientAttributeResource
    ValueTypeAttributePrimitive
    • Bindable moved from Baked.RestApi.Model to Baked.Binding
  • Members named after a renamed attribute follow it;
    oldnew
    GetControllerModel()GetApiController()
    TryGetControllerModel()TryGetApiController()
    GetActionModel()GetAction()
    IsApiInputIsBindable
    AllParametersAreApiInput()AllParametersAreBindable()
    TryGetLocatableAttribute()TryGetLocatable()
    ValueTypeUserType<T>PrimitiveUserType<T>
  • Coding styles are renamed to express how they detect types, via is used when the mechanism needs naming and based when it reads as a qualifier;
    oldnew
    AddRemoveChildAddRemoveChildAsSubResource
    ClientSuffixBasedClient
    CommandPatternCommandViaMethodName
    IdTypeBasedId
    InitializableInitializableViaMethodName
    LabelNameBasedLabel
    LocatableLocateViaId
    LocatableExtensionExtensionViaLocatableInitializer
    QueryQueryViaPluralName
    RichTransientResourceViaIdInitializer
    ScopedBySuffixScopedViaSuffix
    UniqueUniqueViaSingleBy
    ValueTypePrimitiveViaParsable
  • Lifetime features are renamed after the lifetime they provide;
    oldnew
    SingletonApplication
    ScopedScope
    TransientInstance
  • Additional renamings are as below
    oldnew
    Generator<T>.GeneratorGenerator<T>.GeneratorDelegate
    Generator<T>.FilterGenerator<T>.FilterDelegate
    ContextBasedComponent.FilterContextBasedComponent.FilterDelegate
    EntityInitializerIsPostResourceConventionEntityInitializerIsPostConvention
    PageContext.NewLocaleKeyPageContext.Localize

Schemas and Conventions

  • Conventions that configure an existing attribute, component or schema are renamed as edits
    // was
    conventions.AddTypeAttributeConfiguration<Entity>(...);
    conventions.AddMethodComponentConfiguration<Button>(...);
    conventions.AddParameterSchemaConfiguration<Select>(...);
    
    // now
    conventions.EditTypeAttribute<Entity>(...);
    conventions.EditMethodComponent<Button>(...);
    conventions.EditParameterSchema<Select>(...);
    
  • All schemas now have a parameterless constructor, their constructor parameters became settable properties, except that constraint and trigger properties became required

    Page Path is set from the route when it is left empty

  • DomainComponents, DomainDatas, DomainActions and Components builder classes are removed, their defaults are now handled by the default theme. A schema is built with its own constructor and turned into a descriptor with ToDescriptor()
    // was
    using B = Baked.Ui.Components;
    
    B.Filter(
        options: f => f.Placeholder = l("Filter"),
        action: Publish.Event("filter-changed")
    );
    B.PageTitle(options: pt => pt.LocalizeTitle = true);
    
    // now
    new Filter { Placeholder = l("Filter") }
        .ToDescriptor(action: Execute.Publish.Event("filter-changed"));
    new PageTitle { LocalizeTitle = true }.ToDescriptor();
    
    • options parameters are gone, using static and using B = are no longer needed
    • Label component is renamed as Labeler
    • Component exports are now collected from the theme assembly instead of builder classes
      // was
      exports.AddFromExtensions(typeof(C));
      
      // now
      exports.AddFromAssembly(typeof(CustomThemeFeature));
      
  • Datas, Actions and Constraints builder classes are renamed as Fetch, Execute and Evaluate
    // was
    using static Baked.Ui.Datas;
    using static Baked.Ui.Actions;
    using static Baked.Ui.Constraints;
    
    conventions.AddMethodComponentConfiguration<Button>(component: c =>
    {
        c.Data = Remote("some/endpoint");
        c.Action = Publish.Event("saved");
        c.ShowWhen("state", constraint: Is("editing"));
    });
    
    // now
    conventions.EditMethodComponent<Button>(component: c =>
    {
        c.Data = Fetch.Remote("some/endpoint");
        c.Action = Execute.Publish.Event("saved");
        c.ShowWhen("state", constraint: Evaluate.Is("editing"));
    });
    

Components

  • SimpleForm no more provides a dialog mode, switch to Button to render methods as button with a dialog
  • Dialog.Submit became redundant and removed, use Button to render a dialog action
  • SimpleForm.AlwaysShowTitle is removed, title is rendered whenever it is set and SimpleForm.Title is now optional

Authentication

  • FixedBearerToken form post hash is now an HMAC-SHA256 signature of form parameters, so that a value can no longer be shifted to another field
    // was
    base64(sha256("12" + "3" + token))
    
    // now
    base64(hmacsha256(key: token, message: "amount=12&fee=3"))
    
    • Parameters are sorted by key, URL encoded as key=value pairs and joined with &, see Authentication for details

Coding Styles

  • ExtensionViaLocatableInitializerCodingStyle no longer requires extension classes to have an implicit operator, any transient with an initializer that has one locatable parameter becomes an extension for it

    This might make unintended classes an extension and change their API endpoint routes, removing LocatableExtension attribute from them, or adding another parameter to the initializer, resolves it

  • QueryMethodCodingStyle is merged into QueryViaPluralNameCodingStyle
  • EntitySubclassCodingStyle is removed completely

Others

  • ICasts interface and Caster.Cast() extension are removed
  • AllowAnonymous, ClientCache and NoTransaction now declare [AttributeUsage], so they are no longer included in every export target
  • messages returned from useValidation().validate() is now an array of validation results instead of a joined string

Improvements

Build and Domain

  • Locale files were not found when build output path was customized, e.g., --artifacts-path, causing keys to be generated as values, fixed
  • C# friendly name calculation is now fully compliant with C# language standards
  • It was not possible to validate records have locatables in their constructor due to late initialization, fixed
    • Records implementing IValidatableObject are validated once more after they are initialized, only for actions that have such parameters
    • Their validation results are returned as ValidationProblemDetails, same as any other model validation error
  • DefaultThemeFeature.JsonSettings is now public to be used in custom themes

Authentication

  • FixedBearerToken is hardened
    • Tokens and form post hashes are compared in constant time
    • Only the leading Bearer scheme is trimmed from authorization header, and the scheme is now case insensitive
    • Tokens configured with an empty value are ignored

Loading

  • Bake.vue improvements
    • It now waits until data is loaded to show a component when there is a show reaction in the descriptor
      • It was showing the components that reacts to showWhen: is null causing to render unintended components while page is loading
    • Reactions to a page context value now wait until the component writing that value is loaded, e.g., DataTable with DataLengthContextKey, see usePageContext below
  • AwaitLoading no more shows skeleton during a reload, instead a page-wide loading indicator is displayed
  • Reloading a component without data was failing with undefined is not a valid data type, now it tells which component cannot reload because it has no data

Forms and Dialogs

  • Dialog mode is migrated from SimpleForm to Button
    • You can now simplify conventions by configuring methods as buttons with dialogs instead of simple form in dialog mode
    • Modal form was closing before action is completed, now it executes and closes only if action is success
    • Execute.Publish.CloseDialog() helper is introduced to achieve the dialog close after a form action
    • Execute.Publish.Event() now accepts empty to publish an event without data
  • Validation tooltip is replaced with a check list popover
  • Enum defaults weren't getting camelized in Input, fixed

Look and Feel

  • SideMenu UI is improved to distract the user less
  • DefaultLayout now places header in a fixed area above a rounded page body
  • PageTitle and Button are made more compact, and page title is more responsive
  • Header now renders on home page as well, Route.HeaderTitle is set for index route too
  • Buttons in DataContainer actions are rendered small by default
  • Minor improvements in components.css

Composables

  • useFormat now provides asCamelCase helper function
  • useLocalization can now be used as a computed data through Fetch.Computed.UseLocalization(l("..."))
  • usePageContext is introduced to read and write page context values
    • set marks a value as pending while the writing component is loading, so that reactions to it wait until it is written
    • Use usePageContext({ trackLoading: false }) when the value is not loaded, e.g., in actions
  • useContext now provides providePageScope to provide events, page context and pending values of a page at once, e.g., in a custom page or layout component

Library Upgrades

NuGet PackageOld VersionNew Version
Microsoft.AspNetCore.Authentication.JwtBearer10.0.1210.0.13
Microsoft.AspNetCore.Mvc.NewtonsoftJson10.0.1210.0.13
Microsoft.AspNetCore.Mvc.Testing10.0.1210.0.13
Microsoft.Data.Sqlite.Core10.0.1210.0.13
Microsoft.Extensions.Caching.Abstractions10.0.1210.0.13
Microsoft.Extensions.Configuration.Abstractions10.0.1210.0.13
Microsoft.Extensions.Configuration.Binder10.0.1210.0.13
Microsoft.Extensions.FileProviders.Abstractions10.0.1210.0.13
Microsoft.Extensions.Localization.Abstractions10.0.1210.0.13
Microsoft.Extensions.Logging.Abstractions10.0.1210.0.13
Microsoft.Extensions.TimeProvider.Testing10.10.010.11.0
Microsoft.NET.Test.Sdk18.10.118.11.0
Microsoft.Testing.Extensions.CodeCoverage18.11.218.12.0
Microsoft.Testing.Extensions.TrxReport2.4.12.5.1
NUnit3TestAdapter6.3.06.3.1
Swashbuckle.AspNetCore10.2.310.3.0
Swashbuckle.AspNetCore.Annotations10.2.310.3.0
System.Security.Cryptography.Pkcs (transitive)8.0.110.0.13
npm PackageOld VersionNew Version
playwright1.63.01.64.1