Updates
-
Changelog - V23.28.1
Bugfix:
local_only
webhooks for Home Assistant entitiesQuick change to resolve warnings being emitted from the Lovelace UI:
Updated the webhook yaml generation to include the
local_only
flag. This appears to be a feature added in the last month or two for Home Assistant, which the library is now properly compatible with> Note: this flag is hard coded on, and requires an yaml package rebuild to properly add the flag in to all webhooks
-
Changelog - v23.27.1
New Feature:
dynamic_config
The
ApplicationModuleMetadata
interface has been updated with a new configuration parameter:dynamic_config
.This parameter takes the format of a
ValueProvider
|FactoryProvider
, which can pull in other providers in order to generate configuration data.The value merge priorities have been updated to the following:
- values provided via module definitions
- values provided via bootstrap
- values loaded via dynamic config
- values loaded from configuration files
- values loaded from environment variables
- values loaded from command line switches
Use Case: Centralized configuration provider
At the beginning of the bootstrapping sequence, the application perform a http request to a central configuration provider in order to retrieve additional auth keys. These keys could then be injected / refined via the normal
@InjectConfig
mechanismsGotchas
This value is resolved at the extreme start of bootstrapping. Care needs to be taken to not create chicken-and-egg situations. It is best for loaders to be extremely lean in their dependences
Example
loader.ts
``` import { AbstractConfig, AutoLogService, FetchService } from "@digital-alchemy/boilerplate"; import { is, SECOND, sleep, START } from "@digital-alchemy/utilities"; import { hostname, userInfo } from "os"; import { exit } from "process";
type SystemInitResponse = { config: AbstractConfig }; const { username } = userInfo(); const name = hostname();
const ATTEMPTS = 10;
export const CONFIG_LOADER = (app: string) => ({ inject: [FetchService, AutoLogService], async useFactory(fetch: FetchService, logger: AutoLogService) { for (let i = START; i <= ATTEMPTS; i++) { const configuration = await fetch.fetch<SystemInitResponse>({ rawUrl: true, url:
http://central.control/init/identify/${username}/${name}/${app}
, }); if (is.object(configuration)) { return configuration.config; } logger.warn(Failed to load configuration. Attempt [%s]/[%s]
, i, ATTEMPTS); await sleep(SECOND); } logger.fatal(FAILED TO LOAD CONFIGURATION
); exit(); }, }); ```app.ts
``` import { ApplicationModule } from "@digital-alchemy/boilerplate";
import { CONFIG_LOADER } from "./loader"
@ApplicationModule({ dynamic_config: CONFIG_LOADER("special-app"), }) export class MyApplication {} ```