Newer
Older
client_dwatch / scripts / check-env.ts
/**
 * 環境変数の検証(指示書I 段階5-B)。★実行方法: `npm run check:env`★
 *
 * ★このファイルは薄い実行部だけ★ — 検査の中身は `lib/config/env-check.ts`
 * (純粋関数。テストは `lib/config/__tests__/env-check.test.ts`)。
 * ★`scripts/` 配下に置いたテストは vitest が拾わない★ため
 * (`vitest.config.ts` の include は `lib/**` と `app/**`)、ロジックをここに書かないこと。
 *
 * ★`tsx` で単体実行すると env ファイルは自動で読まれない★
 *   (Next.js が読むのはアプリ実行時だけ)。そこで★Next.js と同じ `@next/env` の
 *   `loadEnvConfig()` で読む★。読む順(先に見つかった値が勝つ):
 *   ★実際の環境変数(Docker の env_file / environment など)★ > `.env.$(NODE_ENV).local`
 *   > `.env.local` > `.env.$(NODE_ENV)` > `.env`(`NODE_ENV=test` のときは `.env.local` を読まない)。
 *   ★既にある process.env は上書きしない★ので、Docker で渡した値がそのまま検査される。
 *   `NODE_ENV=production` なら production の、それ以外は development のファイルを読む
 *   (`next start` / `next dev` と同じ)。
 *
 * ★終了コード★: エラーが1件でもあれば 1、警告だけなら 0。
 *   `npm run build` の前に挟めるようにするため(`docs/deploy.md` の手順3)。
 */
import { loadEnvConfig } from "@next/env";
loadEnvConfig(process.cwd(), process.env.NODE_ENV !== "production", {
  // 読んだファイルのパスだけを出す(値は出さない)
  info: (...args: unknown[]) => console.log("[check:env]", ...args),
  error: (...args: unknown[]) => console.error("[check:env]", ...args),
});

import { checkEnv, formatFinding, hasError } from "../lib/config/env-check";

// ★「本番判定」に NODE_ENV を使うことについては lib/config/env-check.ts の
//   冒頭コメントを読むこと(本指示書の「NODE_ENV ではなく設定値で切れ」とは
//   矛盾しない。ここは警告文言の寄せ方を変えるだけで、アプリの挙動を変えない)★
const isProduction = process.env.NODE_ENV === "production";

const findings = checkEnv(process.env, isProduction);

console.log(
  `[check:env] ${isProduction ? "本番" : "開発機"}として検査しました(NODE_ENV=${
    process.env.NODE_ENV ?? "未設定"
  })`
);

if (findings.length === 0) {
  console.log("[check:env] OK — 問題は見つかりませんでした。");
  process.exitCode = 0;
} else {
  for (const finding of findings) {
    console.log(`[check:env] ${formatFinding(finding)}`);
  }
  const errorCount = findings.filter((f) => f.severity === "error").length;
  const warnCount = findings.length - errorCount;
  console.log(`[check:env] エラー ${errorCount} 件 / 警告 ${warnCount} 件`);

  if (hasError(findings)) {
    console.log(
      "[check:env] ★エラーがあります。先に進まないでください(docs/deploy.md 手順3)★"
    );
    process.exitCode = 1;
  } else {
    process.exitCode = 0;
  }
}