|
1 | | -import { Constants } from "youtubei.js"; |
2 | 1 | import { getVersion } from "@imput/version-info"; |
3 | | -import { services } from "./processing/service-config.js"; |
4 | | -import { supportsReusePort } from "./misc/cluster.js"; |
| 2 | +import { loadEnvs, validateEnvs } from "./core/env.js"; |
5 | 3 |
|
6 | 4 | const version = await getVersion(); |
7 | 5 |
|
8 | | -const disabledServices = process.env.DISABLED_SERVICES?.split(',') || []; |
9 | | -const enabledServices = new Set(Object.keys(services).filter(e => { |
10 | | - if (!disabledServices.includes(e)) { |
11 | | - return e; |
12 | | - } |
13 | | -})); |
14 | | - |
15 | | -const forceLocalProcessingOptions = ["never", "session", "always"]; |
16 | | - |
17 | | -const env = { |
18 | | - apiURL: process.env.API_URL || '', |
19 | | - apiPort: process.env.API_PORT || 9000, |
20 | | - tunnelPort: process.env.API_PORT || 9000, |
21 | | - |
22 | | - listenAddress: process.env.API_LISTEN_ADDRESS, |
23 | | - freebindCIDR: process.platform === 'linux' && process.env.FREEBIND_CIDR, |
24 | | - |
25 | | - corsWildcard: process.env.CORS_WILDCARD !== '0', |
26 | | - corsURL: process.env.CORS_URL, |
27 | | - |
28 | | - cookiePath: process.env.COOKIE_PATH, |
29 | | - |
30 | | - rateLimitWindow: (process.env.RATELIMIT_WINDOW && parseInt(process.env.RATELIMIT_WINDOW)) || 60, |
31 | | - rateLimitMax: (process.env.RATELIMIT_MAX && parseInt(process.env.RATELIMIT_MAX)) || 20, |
32 | | - |
33 | | - tunnelRateLimitWindow: (process.env.TUNNEL_RATELIMIT_WINDOW && parseInt(process.env.TUNNEL_RATELIMIT_WINDOW)) || 60, |
34 | | - tunnelRateLimitMax: (process.env.TUNNEL_RATELIMIT_MAX && parseInt(process.env.TUNNEL_RATELIMIT_MAX)) || 40, |
35 | | - |
36 | | - sessionRateLimitWindow: (process.env.SESSION_RATELIMIT_WINDOW && parseInt(process.env.SESSION_RATELIMIT_WINDOW)) || 60, |
37 | | - sessionRateLimit: (process.env.SESSION_RATELIMIT && parseInt(process.env.SESSION_RATELIMIT)) || 10, |
38 | | - |
39 | | - durationLimit: (process.env.DURATION_LIMIT && parseInt(process.env.DURATION_LIMIT)) || 10800, |
40 | | - streamLifespan: (process.env.TUNNEL_LIFESPAN && parseInt(process.env.TUNNEL_LIFESPAN)) || 90, |
41 | | - |
42 | | - processingPriority: process.platform !== 'win32' |
43 | | - && process.env.PROCESSING_PRIORITY |
44 | | - && parseInt(process.env.PROCESSING_PRIORITY), |
45 | | - |
46 | | - externalProxy: process.env.API_EXTERNAL_PROXY, |
47 | | - |
48 | | - turnstileSitekey: process.env.TURNSTILE_SITEKEY, |
49 | | - turnstileSecret: process.env.TURNSTILE_SECRET, |
50 | | - jwtSecret: process.env.JWT_SECRET, |
51 | | - jwtLifetime: process.env.JWT_EXPIRY || 120, |
52 | | - |
53 | | - sessionEnabled: process.env.TURNSTILE_SITEKEY |
54 | | - && process.env.TURNSTILE_SECRET |
55 | | - && process.env.JWT_SECRET, |
56 | | - |
57 | | - apiKeyURL: process.env.API_KEY_URL && new URL(process.env.API_KEY_URL), |
58 | | - authRequired: process.env.API_AUTH_REQUIRED === '1', |
59 | | - redisURL: process.env.API_REDIS_URL, |
60 | | - instanceCount: (process.env.API_INSTANCE_COUNT && parseInt(process.env.API_INSTANCE_COUNT)) || 1, |
61 | | - keyReloadInterval: 900, |
62 | | - |
63 | | - enabledServices, |
64 | | - |
65 | | - customInnertubeClient: process.env.CUSTOM_INNERTUBE_CLIENT, |
66 | | - ytSessionServer: process.env.YOUTUBE_SESSION_SERVER, |
67 | | - ytSessionReloadInterval: 300, |
68 | | - ytSessionInnertubeClient: process.env.YOUTUBE_SESSION_INNERTUBE_CLIENT, |
69 | | - ytAllowBetterAudio: process.env.YOUTUBE_ALLOW_BETTER_AUDIO !== "0", |
70 | | - |
71 | | - // "never" | "session" | "always" |
72 | | - forceLocalProcessing: process.env.FORCE_LOCAL_PROCESSING ?? "never", |
73 | | -} |
| 6 | +let env = loadEnvs(); |
74 | 7 |
|
75 | 8 | const genericUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"; |
76 | 9 | const cobaltUserAgent = `cobalt/${version} (+https://github.com/imputnet/cobalt)`; |
77 | 10 |
|
78 | 11 | export const setTunnelPort = (port) => env.tunnelPort = port; |
79 | 12 | export const isCluster = env.instanceCount > 1; |
80 | 13 |
|
81 | | -if (env.sessionEnabled && env.jwtSecret.length < 16) { |
82 | | - throw new Error("JWT_SECRET env is too short (must be at least 16 characters long)"); |
83 | | -} |
84 | | - |
85 | | -if (env.instanceCount > 1 && !env.redisURL) { |
86 | | - throw new Error("API_REDIS_URL is required when API_INSTANCE_COUNT is >= 2"); |
87 | | -} else if (env.instanceCount > 1 && !await supportsReusePort()) { |
88 | | - console.error('API_INSTANCE_COUNT is not supported in your environment. to use this env, your node.js'); |
89 | | - console.error('version must be >= 23.1.0, and you must be running a recent enough version of linux'); |
90 | | - console.error('(or other OS that supports it). for more info, see `reusePort` option on'); |
91 | | - console.error('https://nodejs.org/api/net.html#serverlistenoptions-callback'); |
92 | | - throw new Error('SO_REUSEPORT is not supported'); |
93 | | -} |
94 | | - |
95 | | -if (env.customInnertubeClient && !Constants.SUPPORTED_CLIENTS.includes(env.customInnertubeClient)) { |
96 | | - console.error("CUSTOM_INNERTUBE_CLIENT is invalid. Provided client is not supported."); |
97 | | - console.error(`Supported clients are: ${Constants.SUPPORTED_CLIENTS.join(', ')}\n`); |
98 | | - throw new Error("Invalid CUSTOM_INNERTUBE_CLIENT"); |
99 | | -} |
100 | | - |
101 | | -if (env.forceLocalProcessing && !forceLocalProcessingOptions.includes(env.forceLocalProcessing)) { |
102 | | - console.error("FORCE_LOCAL_PROCESSING is invalid."); |
103 | | - console.error(`Supported options are are: ${forceLocalProcessingOptions.join(', ')}\n`); |
104 | | - throw new Error("Invalid FORCE_LOCAL_PROCESSING"); |
105 | | -} |
| 14 | +await validateEnvs(env); |
106 | 15 |
|
107 | 16 | export { |
108 | 17 | env, |
|
0 commit comments