メインコンテンツまでスキップ

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サブクラスを登録します。解決の優先順位は、高い方から順に:

  1. createRuntime({ configs }) — runtimeオーバーライド
  2. createApp([...], { configs }) — ユーザー指定
  3. createRuntime({ fallbackConfigs }) — フォールバック
  4. ベース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標準デコレータを使ってください。特別なTypeScript設定は不要です:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext"
  }
}

Legacy Decorators

既存のコードベースとの互換性のためには、レガシーデコレータを有効にします:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "experimentalDecorators": true
  }
}

Detection Behavior

Zeltは実行時のコンテキストに基づいてデコレータのモードを自動検出します:

  • TC39 mode: デコレータはkindnamemetadataプロパティを持つcontextオブジェクトを受け取る
  • Legacy mode: デコレータはtargetpropertyKeydescriptor引数を受け取る

どちらのモードもAPIの観点からは同一に動作します — モードを切り替える際にコードを変更する必要はありません。