{"repo": "964896765/shenghuobang", "files": {"server/_core/env.ts": {"8973608d7580dccaa06f752bbdfa067ed9cd6c1a": {"t": 1785746044.1198559, "n": 4270, "h": "933ba77aed78152c", "c": "import path from \"node:path\";\n\nexport type RuntimeEnvironment = ReturnType;\n\nexport function readEnvironment(source: Readonly> = process.env) {\n const storageProvider = source.STORAGE_PROVIDER === \"s3\" ? \"s3\" : \"local\";\n return {\n nodeEnv: source.NODE_ENV ?? \"development\",\n port: Number(source.PORT ?? 3000),\n cookieSecret: source.JWT_SECRET ?? \"\",\n fileSigningSecret: source.FILE_SIGNING_SECRET ?? \"\",\n databaseUrl: source.DATABASE_URL ?? \"\",\n isProduction: source.NODE_ENV === \"production\",\n aiApiUrl: source.AI_API_URL ?? \"https://api.deepseek.com\",\n aiApiKey: source.AI_API_KEY ?? \"\",\n aiModel: source.AI_MODEL ?? \"deepseek-chat\",\n uploadDir: source.LOCAL_UPLOAD_DIR ?? source.UPLOAD_DIR ?? \"./uploads\",\n storageProvider: storageProvider as \"local\" | \"s3\",\n s3Endpoint: source.S3_ENDPOINT ?? \"\",\n s3Region: source.S3_REGION ?? \"\",\n s3Bucket: source.S3_BUCKET ?? \"\",\n s3AccessKeyId: source.S3_ACCESS_KEY_ID ?? \"\",\n s3SecretAccessKey: source.S3_SECRET_ACCESS_KEY ?? \"\",\n s3ForcePathStyle: source.S3_FORCE_PATH_STYLE === \"true\",\n maxUploadBytes: Number(source.MAX_UPLOAD_BYTES ?? 8388608),\n maxFilesPerEntity: Number(source.MAX_FILES_PER_ENTITY ?? 20),\n publicBaseUrl: source.PUBLIC_BASE_URL ?? \"\",\n pushProvider: source.PUSH_PROVIDER ?? \"log\",\n expoPushAccessToken: source.EXPO_PUSH_ACCESS_TOKEN ?? \"\",\n allowNativeWsWithoutOrigin: source.WS_ALLOW_NATIVE_WITHOUT_ORIGIN === \"true\",\n wsMaxConnectionsPerUser: Number(source.WS_MAX_CONNECTIONS_PER_USER ?? 3),\n wsMaxSubscriptions: Number(source.WS_MAX_SUBSCRIPTIONS ?? 20),\n wsMaxMessageBytes: Number(source.WS_MAX_MESSAGE_BYTES ?? 16384),\n corsOrigins: (source.CORS_ORIGINS ?? \"\")\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean),\n };\n}\n\nexport type ConfigurationCheck = { ok: boolean; missing: string[]; invalid: string[] };\n\nexport function validateConfiguration(env: RuntimeEnvironment, options: { production?: boolean } = {}): ConfigurationCheck {\n const production = options.production ?? env.isProduction;\n const missing: string[] = [];\n const invalid: string[] = [];\n const requireValue = (name: string, value: string) => { if (!value.trim()) missing.push(name); };\n\n requireValue(\"DATABASE_URL\", env.databaseUrl);\n requireValue(\"JWT_SECRET\", env.cookieSecret);\n requireValue(\"FILE_SIGNING_SECRET\", env.fileSigningSecret);\n if (production) requireValue(\"CORS_ORIGINS\", env.corsOrigins.join(\",\"));\n if (production && env.cookieSecret.length < 32) invalid.push(\"JWT_SECRET\");\n if (production && env.fileSigningSecret.length < 32) invalid.push(\"FILE_SIGNING_SECRET\");\n if (!Number.isSafeInteger(env.maxUploadBytes) || env.maxUploadBytes <= 0) invalid.push(\"MAX_UPLOAD_BYTES\");\n if (!new Set([\"log\", \"expo\"]).has(env.pushProvider)) invalid.push(\"PUSH_PROVIDER\");\n if (env.corsOrigins.some((origin) => {\n try { const url = new URL(origin); return ![\"http:\", \"https:\"].includes(url.protocol) || url.origin !== origin; }\n catch { return true; }\n })) invalid.push(\"CORS_ORIGINS\");\n\n if (env.storageProvider === \"s3\") {\n requireValue(\"S3_ENDPOINT\", env.s3Endpoint);\n requireValue(\"S3_REGION\", env.s3Region);\n requireValue(\"S3_BUCKET\", env.s3Bucket);\n requireValue(\"S3_ACCESS_KEY_ID\", env.s3AccessKeyId);\n requireValue(\"S3_SECRET_ACCESS_KEY\", env.s3SecretAccessKey);\n } else {\n requireValue(\"LOCAL_UPLOAD_DIR\", env.uploadDir);\n const resolved = path.resolve(env.uploadDir);\n const publicRoots = [\"assets\", \"public\", \"web-dist\"].map((dir) => path.resolve(process.cwd(), dir));\n if (publicRoots.some((root) => resolved === root || resolved.startsWith(`${root}${path.sep}`))) invalid.push(\"LOCAL_UPLOAD_DIR\");\n }\n return { ok: missing.length === 0 && invalid.length === 0, missing, invalid };\n}\n\nexport function assertProductionConfiguration(env: RuntimeEnvironment = ENV) {\n if (!env.isProduction) return;\n const result = validateConfiguration(env, { production: true });\n if (!result.ok) {\n const fields = [...new Set([...result.missing, ...result.invalid])].join(\", \");\n throw new Error(`Production configuration is incomplete or invalid: ${fields}`);\n }\n}\n\nexport const ENV = readEnvironment();\n"}, "b50e198c19bda33a8c88ab903375c4e1958af71a": {"t": 1785759151.9686804, "n": 4270, "h": "933ba77aed78152c", "c": "import path from \"node:path\";\n\nexport type RuntimeEnvironment = ReturnType;\n\nexport function readEnvironment(source: Readonly> = process.env) {\n const storageProvider = source.STORAGE_PROVIDER === \"s3\" ? \"s3\" : \"local\";\n return {\n nodeEnv: source.NODE_ENV ?? \"development\",\n port: Number(source.PORT ?? 3000),\n cookieSecret: source.JWT_SECRET ?? \"\",\n fileSigningSecret: source.FILE_SIGNING_SECRET ?? \"\",\n databaseUrl: source.DATABASE_URL ?? \"\",\n isProduction: source.NODE_ENV === \"production\",\n aiApiUrl: source.AI_API_URL ?? \"https://api.deepseek.com\",\n aiApiKey: source.AI_API_KEY ?? \"\",\n aiModel: source.AI_MODEL ?? \"deepseek-chat\",\n uploadDir: source.LOCAL_UPLOAD_DIR ?? source.UPLOAD_DIR ?? \"./uploads\",\n storageProvider: storageProvider as \"local\" | \"s3\",\n s3Endpoint: source.S3_ENDPOINT ?? \"\",\n s3Region: source.S3_REGION ?? \"\",\n s3Bucket: source.S3_BUCKET ?? \"\",\n s3AccessKeyId: source.S3_ACCESS_KEY_ID ?? \"\",\n s3SecretAccessKey: source.S3_SECRET_ACCESS_KEY ?? \"\",\n s3ForcePathStyle: source.S3_FORCE_PATH_STYLE === \"true\",\n maxUploadBytes: Number(source.MAX_UPLOAD_BYTES ?? 8388608),\n maxFilesPerEntity: Number(source.MAX_FILES_PER_ENTITY ?? 20),\n publicBaseUrl: source.PUBLIC_BASE_URL ?? \"\",\n pushProvider: source.PUSH_PROVIDER ?? \"log\",\n expoPushAccessToken: source.EXPO_PUSH_ACCESS_TOKEN ?? \"\",\n allowNativeWsWithoutOrigin: source.WS_ALLOW_NATIVE_WITHOUT_ORIGIN === \"true\",\n wsMaxConnectionsPerUser: Number(source.WS_MAX_CONNECTIONS_PER_USER ?? 3),\n wsMaxSubscriptions: Number(source.WS_MAX_SUBSCRIPTIONS ?? 20),\n wsMaxMessageBytes: Number(source.WS_MAX_MESSAGE_BYTES ?? 16384),\n corsOrigins: (source.CORS_ORIGINS ?? \"\")\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean),\n };\n}\n\nexport type ConfigurationCheck = { ok: boolean; missing: string[]; invalid: string[] };\n\nexport function validateConfiguration(env: RuntimeEnvironment, options: { production?: boolean } = {}): ConfigurationCheck {\n const production = options.production ?? env.isProduction;\n const missing: string[] = [];\n const invalid: string[] = [];\n const requireValue = (name: string, value: string) => { if (!value.trim()) missing.push(name); };\n\n requireValue(\"DATABASE_URL\", env.databaseUrl);\n requireValue(\"JWT_SECRET\", env.cookieSecret);\n requireValue(\"FILE_SIGNING_SECRET\", env.fileSigningSecret);\n if (production) requireValue(\"CORS_ORIGINS\", env.corsOrigins.join(\",\"));\n if (production && env.cookieSecret.length < 32) invalid.push(\"JWT_SECRET\");\n if (production && env.fileSigningSecret.length < 32) invalid.push(\"FILE_SIGNING_SECRET\");\n if (!Number.isSafeInteger(env.maxUploadBytes) || env.maxUploadBytes <= 0) invalid.push(\"MAX_UPLOAD_BYTES\");\n if (!new Set([\"log\", \"expo\"]).has(env.pushProvider)) invalid.push(\"PUSH_PROVIDER\");\n if (env.corsOrigins.some((origin) => {\n try { const url = new URL(origin); return ![\"http:\", \"https:\"].includes(url.protocol) || url.origin !== origin; }\n catch { return true; }\n })) invalid.push(\"CORS_ORIGINS\");\n\n if (env.storageProvider === \"s3\") {\n requireValue(\"S3_ENDPOINT\", env.s3Endpoint);\n requireValue(\"S3_REGION\", env.s3Region);\n requireValue(\"S3_BUCKET\", env.s3Bucket);\n requireValue(\"S3_ACCESS_KEY_ID\", env.s3AccessKeyId);\n requireValue(\"S3_SECRET_ACCESS_KEY\", env.s3SecretAccessKey);\n } else {\n requireValue(\"LOCAL_UPLOAD_DIR\", env.uploadDir);\n const resolved = path.resolve(env.uploadDir);\n const publicRoots = [\"assets\", \"public\", \"web-dist\"].map((dir) => path.resolve(process.cwd(), dir));\n if (publicRoots.some((root) => resolved === root || resolved.startsWith(`${root}${path.sep}`))) invalid.push(\"LOCAL_UPLOAD_DIR\");\n }\n return { ok: missing.length === 0 && invalid.length === 0, missing, invalid };\n}\n\nexport function assertProductionConfiguration(env: RuntimeEnvironment = ENV) {\n if (!env.isProduction) return;\n const result = validateConfiguration(env, { production: true });\n if (!result.ok) {\n const fields = [...new Set([...result.missing, ...result.invalid])].join(\", \");\n throw new Error(`Production configuration is incomplete or invalid: ${fields}`);\n }\n}\n\nexport const ENV = readEnvironment();\n"}}}}