Configuration
Zeltは、@Configデコレータとinject()ヘルパーを使った型安全な設定システムを提供します。
Defining Configuration
設定クラスを定義するには@Configデコレータを使います。各configクラスは静的なTokenプロパティを持つ必要があります:
import { Config, Env, inject } from '@zeltjs/core';
@Config
export class DatabaseConfig {
static readonly Token = DatabaseConfig;
constructor(private env = inject(Env)) {}
get host() {
return this.env.getString('DATABASE_HOST', 'localhost');
}
get port() {
return this.env.getNumber('DATABASE_PORT', 5432);
}
get connectionString() {
return `postgres://${this.host}:${this.port}/mydb`;
}
}
Using Configuration
inject()を使って、serviceやcontrollerへ設定を注入します:
@Injectable()
export class DatabaseService {
constructor(private config = inject(DatabaseConfig)) {}
connect() {
return this.config.connectionString;
}
}
Registering Configuration
アプリ作成時にconfigクラスを登録します:
const app = createApp([http({
controllers: [AppController],
})], { configs: [DatabaseConfig] });
Overriding Configuration
configクラスを継承することで、テスト用に設定値をオーバーライドできます:
@Config
export class TestDatabaseConfig extends DatabaseConfig {
override get host() {
return 'test-db';
}
override get port() {
return 5433;
}
}
// テストのセットアップ内
const app = createApp([http({
controllers: [AppController],
})], { configs: [TestDatabaseConfig] });
Tokenプロパティは親クラスから継承されるため、inject(DatabaseConfig)はオーバーライドされたTestDatabaseConfigのインスタンスを受け取ります。
Abstract Configuration
デフォルト実装を持たないconfigベースクラスを宣言するには@Config({ abstract: true })を使います。これは、意味のあるフォールバック値が存在せず、全ての環境で具体的な値を供給しなければならないconfig契約に便利です:
const app = createApp([], { configs: [StripeConfig] });
abstract configが、それを解決する具象サブクラスなしに登録された場合 — 未登録のまま、configsへ直接渡された、あるいはabstractなサブクラスのみで解決された場合のいずれでも — createRuntime()(またはそのtokenの最初のinject())は理由abstract_leaf_without_concreteとともにZeltAppConfigurationErrorを投げます。
Fallback Configuration
createRuntime({ fallbackConfigs })は、他に何もベースconfigを解決しない場合にのみ適用されるconfigサブクラスを登録します。解決の優先順位は、高い方から順に:
createRuntime({ configs })— runtimeオーバーライドcreateApp([...], { configs })— ユーザー指定createRuntime({ fallbackConfigs })— フォールバック- ベースconfigクラス自身のデフォルトgetter値
fallbackConfigsは、開発専用のデフォルトでabstract configを満たしつつ、本番コードには具体的なconfigsエントリを明示的に渡すことを要求する用途でよく使われます:
const app = createApp([]);
const readyApp = await app.createRuntime({
fallbackConfigs: [DevPaymentGatewayConfig],
});
Environment-Based Configuration
inject(Env)は、adapterによって登録されたプラットフォーム固有のソースから環境変数を読み取ります。一般的なケースでは追加の設定は不要です。
Node.js Environment
onNode()を使う場合、ProcessEnvAdaptorが自動的に登録されるため、inject(Env)は追加の設定なしにprocess.envから読み取ります:
@Config
export class DatabaseConfig {
static readonly Token = DatabaseConfig;
constructor(private env = inject(Env)) {}
get host() {
return this.env.getString('DATABASE_HOST', 'localhost');
}
get port() {
return this.env.getNumber('DATABASE_PORT', 5432);
}
get connectionString() {
return `postgres://${this.host}:${this.port}/mydb`;
}
}
const app = createApp([http({
controllers: [AppController],
})], { configs: [DatabaseConfig] });
Loading .env Files
.envファイルを読み込むには、アプリケーションのエントリポイントの最初にdotenv/configをimportします:
import 'dotenv/config';import { onNode } from '@zeltjs/adapter-node';
// ...アプリのセットアップの続き
その後、inject(Env)はdotenvがprocess.envへ設定した変数を読み取ります。
Cloudflare Workers Environment
Cloudflare Workersの場合、環境設定はonCloudflareWorkers()によって自動的に処理されます。詳細はCloudflare Workers Getting Startedガイドを参照してください。
TypeScript Decorator Configuration
ZeltはTC39標準デコレータと、レガシーなTypeScriptデコレータの両方をサポートしています。フレームワークは実行時にどちらのモードが使われているかを自動で検出します。
TC39 Standard Decorators (Recommended)
新規プロジェクトではTC39標準デコレータを使ってください。特別なTypeScript設定は不要です:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext"
}
}
Legacy Decorators
既存のコードベースとの互換性のためには、レガシーデコレータを有効にします:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"experimentalDecorators": true
}
}
Detection Behavior
Zeltは実行時のコンテキストに基づいてデコレータのモードを自動検出します:
- TC39 mode: デコレータは
kind、name、metadataプロパティを持つcontextオブジェクトを受け取る - Legacy mode: デコレータは
target、propertyKey、descriptor引数を受け取る
どちらのモードもAPIの観点からは同一に動作します — モードを切り替える際にコードを変更する必要はありません。