-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenv.ts
More file actions
85 lines (78 loc) · 2.92 KB
/
Copy pathenv.ts
File metadata and controls
85 lines (78 loc) · 2.92 KB
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
/**
* Environment + origin resolution.
*
* This is the single source of truth for two SEO-critical environment facts:
*
* 1. Which deployment environment we are in (production | preview | development).
* 2. The canonical origin to use when building absolute URLs.
*
* Why it lives in one place: a preview/staging deploy must *never* emit
* production canonicals or get indexed. Centralizing the lookup means the
* canonical builder, sitemap, robots route, and `proxy.ts` all agree.
*
* Everything reads `process.env` at call time (not module load) so the values
* can be overridden per-process at runtime (e.g. `DEPLOY_ENV=preview next start`)
* and so unit tests can set `process.env.SITE_ORIGIN` before exercising the code.
*/
export type DeployEnv = 'production' | 'preview' | 'development';
/**
* Default origins per environment. These are illustrative placeholders — a
* real deployment sets `SITE_ORIGIN` explicitly (see {@link getSiteOrigin}).
*/
export const DEFAULT_ORIGINS: Record<DeployEnv, string> = {
production: 'https://www.example.com',
preview: 'https://preview.example.com',
development: 'http://localhost:3000',
};
/**
* Resolve the current deployment environment.
*
* Honors an explicit `DEPLOY_ENV`, then Vercel's `VERCEL_ENV`, then falls back
* to `NODE_ENV` (production build => production, otherwise development).
*/
export function getDeployEnv(): DeployEnv {
const raw = (process.env.DEPLOY_ENV ?? process.env.VERCEL_ENV)?.trim();
if (raw === 'production' || raw === 'preview' || raw === 'development') {
return raw;
}
return process.env.NODE_ENV === 'production' ? 'production' : 'development';
}
/** True only in the production environment. Drives noindex + robots behavior. */
export function isProduction(): boolean {
return getDeployEnv() === 'production';
}
/** The default origin for the current environment, ignoring `SITE_ORIGIN`. */
export function resolveDefaultOrigin(): string {
return DEFAULT_ORIGINS[getDeployEnv()];
}
/**
* Normalize an origin string to a bare `scheme://host[:port]` with no trailing
* slash. Returns null if the value is not a valid http/https URL.
*/
function normalizeOrigin(value: string): string | null {
let parsed: URL;
try {
parsed = new URL(value);
} catch {
return null;
}
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
return null;
}
return parsed.origin;
}
/**
* The canonical origin for absolute URLs.
*
* Prefers an explicit, valid `SITE_ORIGIN`; otherwise falls back to the
* environment default. The result never has a trailing slash.
*/
export function getSiteOrigin(): string {
const explicit = process.env.SITE_ORIGIN?.trim();
if (explicit) {
const normalized = normalizeOrigin(explicit);
if (normalized) return normalized;
}
// Fall back to the environment default (also normalized for safety).
return normalizeOrigin(resolveDefaultOrigin()) ?? DEFAULT_ORIGINS.development;
}