All files / utils / env.ts

100.00% Branches 0/0
4.72% Lines 5/106
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
 
 
 
 
 
x1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x1
x15
x15
x15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

















































































































































































/**
 * 环境变量加载和验证工具
 * 支持可选的环境变量,避免 dotenv 的严格检查
 */

import { load } from "$std/dotenv/mod.ts";

/**
 * 安全加载环境变量,允许空值
 */
export async function loadEnvSafely(): Promise<void> {
  try {
    // 使用 allowEmptyValues 选项允许空值
    await load({
      allowEmptyValues: true,
      defaultsPath: null, // 不使用默认文件
      examplePath: null, // 不强制检查示例文件
    });

    console.log("✅ 环境变量加载成功");
  } catch (error) {
    console.warn(
      "⚠️ 环境变量加载警告:",
      error instanceof Error ? error.message : String(error),
    );
    // 不抛出错误,允许应用继续运行
  }
}

/**
 * 获取环境变量,支持默认值
 */
export function getEnv(key: string, defaultValue: string = ""): string {
  const value = Deno.env.get(key);
  return value || defaultValue;
}

/**
 * 获取必需的环境变量,如果不存在则抛出错误
 */
export function getRequiredEnv(key: string): string {
  const value = Deno.env.get(key);
  if (!value) {
    throw new Error(`❌ 必需的环境变量 ${key} 未设置`);
  }
  return value;
}

/**
 * 获取布尔类型的环境变量
 */
export function getBoolEnv(
  key: string,
  defaultValue: boolean = false,
): boolean {
  const value = Deno.env.get(key);
  if (!value) return defaultValue;

  return value.toLowerCase() === "true" || value === "1";
}

/**
 * 获取数字类型的环境变量
 */
export function getNumberEnv(
  key: string,
  defaultValue?: number,
): number | undefined {
  const value = Deno.env.get(key);
  if (!value) return defaultValue;

  const parsed = parseInt(value, 10);
  if (isNaN(parsed)) {
    console.warn(`⚠️ 环境变量 ${key} 不是有效数字: ${value}`);
    return defaultValue;
  }

  return parsed;
}

/**
 * 检查 OAuth 提供商是否已配置
 */
export function isOAuthProviderConfigured(provider: string): boolean {
  const clientId = Deno.env.get(`${provider.toUpperCase()}_CLIENT_ID`);
  const clientSecret = Deno.env.get(`${provider.toUpperCase()}_CLIENT_SECRET`);

  return !!(clientId && clientSecret &&
    clientId !== `your_${provider}_client_id`);
}

/**
 * 获取已配置的 OAuth 提供商列表
 */
export function getConfiguredOAuthProviders(): string[] {
  const providers = ["github", "google", "microsoft", "gitee"];
  return providers.filter((provider) => isOAuthProviderConfigured(provider));
}

/**
 * 验证基础环境配置
 */
export function validateBaseEnvironment(): void {
  const errors: string[] = [];

  // 检查基础配置
  if (!getEnv("APP_BASE_URL")) {
    console.warn("⚠️ APP_BASE_URL 未设置,使用默认值: http://localhost:8000");
  }

  if (!getEnv("JWT_SECRET")) {
    console.warn("⚠️ JWT_SECRET 未设置,使用默认值(生产环境不安全)");
  }

  // 检查至少有一个 OAuth 提供商配置
  const configuredProviders = getConfiguredOAuthProviders();
  if (configuredProviders.length === 0) {
    console.warn("⚠️ 没有配置任何 OAuth 提供商,用户将无法登录");
    console.warn(
      "请配置至少一个 OAuth 提供商:GITHUB, GOOGLE, MICROSOFT, GITEE",
    );
  } else {
    console.log(`✅ 已配置的 OAuth 提供商: ${configuredProviders.join(", ")}`);
  }

  if (errors.length > 0) {
    console.error("❌ 环境配置错误:");
    errors.forEach((error) => console.error(`  - ${error}`));
    throw new Error("环境配置验证失败");
  }
}

/**
 * 获取环境信息摘要
 */
export function getEnvironmentSummary(): Record<string, unknown> {
  return {
    nodeEnv: getEnv("NODE_ENV", "development"),
    appBaseUrl: getEnv("APP_BASE_URL", "http://localhost:8000"),
    hasJwtSecret: !!getEnv("JWT_SECRET"),
    sessionExpireTime: getNumberEnv("SESSION_EXPIRE_TIME", 86400),
    configuredOAuthProviders: getConfiguredOAuthProviders(),
    isDevelopment: getEnv("NODE_ENV") !== "production",
    isProduction: getEnv("NODE_ENV") === "production",
  };
}

/**
 * 打印环境配置状态
 */
export function printEnvironmentStatus(): void {
  const summary = getEnvironmentSummary();

  console.log("🔍 环境配置状态:");
  console.log(`  - 环境: ${summary.nodeEnv}`);
  console.log(`  - 基础URL: ${summary.appBaseUrl}`);
  console.log(
    `  - JWT密钥: ${summary.hasJwtSecret ? "✅ 已配置" : "❌ 未配置"}`,
  );
  console.log(`  - 会话过期时间: ${summary.sessionExpireTime}秒`);
  console.log(
    `  - OAuth提供商: ${
      (summary.configuredOAuthProviders as string[]).join(", ") || "无"
    }`,
  );
}

/**
 * 开发环境初始化
 */
export async function initDevelopmentEnvironment(): Promise<void> {
  await loadEnvSafely();

  if (getEnv("NODE_ENV") !== "production") {
    printEnvironmentStatus();
  }

  validateBaseEnvironment();
}