which-url 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -321
- package/dist/types.d.ts +4 -1
- package/package.json +7 -3
- package/dist/env-var.d.ts +0 -11
- package/dist/env-var.d.ts.map +0 -1
- package/dist/env.d.ts +0 -7
- package/dist/env.d.ts.map +0 -1
- package/dist/index.cjs +0 -224
- package/dist/index.d.ts.map +0 -1
- package/dist/normalize.d.ts +0 -2
- package/dist/normalize.d.ts.map +0 -1
- package/dist/providers.d.ts +0 -3
- package/dist/providers.d.ts.map +0 -1
- package/dist/resolve.d.ts +0 -8
- package/dist/resolve.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -22,12 +22,15 @@ Production https://myapp.com "production"
|
|
|
22
22
|
|
|
23
23
|
Works across environments (local, preview, production), browser bundles, Node/Bun servers, and edge runtimes that expose compatible env vars through `process.env` or build-time public env replacement.
|
|
24
24
|
|
|
25
|
+
For browser bundles, framework-prefixed env vars must be referenced statically so the bundler can inline them at build time. `which-url` includes literal references such as `process.env.NEXT_PUBLIC_APP_URL` and `process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL`; dynamic lookup like `process.env["NEXT_PUBLIC_" + name]` cannot be inlined by Next.js.
|
|
26
|
+
|
|
25
27
|
The default export gives you everything as an object:
|
|
26
28
|
|
|
27
29
|
```typescript
|
|
28
30
|
import appUrl from 'which-url'
|
|
29
31
|
|
|
30
32
|
appUrl.origin // "https://myapp.com"
|
|
33
|
+
appUrl.productionOrigin // "https://myapp.com"
|
|
31
34
|
appUrl.hostname // "myapp.com"
|
|
32
35
|
appUrl.protocol // "https:"
|
|
33
36
|
appUrl.env // "production"
|
|
@@ -89,6 +92,10 @@ When you call `createUrl({ env })`, the passed object replaces `process.env` as
|
|
|
89
92
|
|
|
90
93
|
If nothing is detected in production, the default singleton returns empty URL strings so imports stay safe in tests, client bundles, and build tools. Call `createUrl()` directly when a missing URL should throw.
|
|
91
94
|
|
|
95
|
+
`origin` is the current environment origin. In a preview deployment, it should point at the preview. In production, it should point at production. Locally, it should point at local dev.
|
|
96
|
+
|
|
97
|
+
`productionOrigin` is the canonical production origin when configured or detectable. Use it for things that should still point at the public production site from previews, such as canonical metadata, social cards, and "view live site" links.
|
|
98
|
+
|
|
92
99
|
## Strict mode with `createUrl()`
|
|
93
100
|
|
|
94
101
|
Use the default export or named constants for convenience:
|
|
@@ -122,7 +129,28 @@ APP_URL=https://myapp.com
|
|
|
122
129
|
|
|
123
130
|
Works with or without protocol (`APP_URL=myapp.com` → `https://myapp.com`).
|
|
124
131
|
|
|
125
|
-
**Client-side frameworks:** All framework prefixes are supported automatically — `NEXT_PUBLIC_APP_URL`, `VITE_APP_URL`, `PUBLIC_APP_URL`, `NUXT_ENV_APP_URL`, etc.
|
|
132
|
+
**Client-side frameworks:** All framework prefixes are supported automatically — `NEXT_PUBLIC_APP_URL`, `VITE_APP_URL`, `PUBLIC_APP_URL`, `NUXT_ENV_APP_URL`, etc. These are build-time values in browser bundles.
|
|
133
|
+
|
|
134
|
+
## Production URL
|
|
135
|
+
|
|
136
|
+
Use `APP_PRODUCTION_URL` when the canonical production URL is different from the current environment URL:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
APP_PRODUCTION_URL=https://myapp.com
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { origin, productionOrigin } from 'which-url'
|
|
144
|
+
|
|
145
|
+
origin // current environment origin
|
|
146
|
+
productionOrigin // canonical production origin, when available
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
On Vercel, `productionOrigin` is detected from `VERCEL_PROJECT_PRODUCTION_URL`, even in preview deployments.
|
|
150
|
+
|
|
151
|
+
In Next.js browser bundles on Vercel deployments, it is detected from `NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL`. Vercel adds these framework-prefixed vars for production and preview deployments based on the framework preset, but `vercel env pull` does not create the prefixed local versions automatically.
|
|
152
|
+
|
|
153
|
+
**Client-side frameworks:** Framework prefixes are supported here too — `NEXT_PUBLIC_APP_PRODUCTION_URL`, `VITE_APP_PRODUCTION_URL`, `PUBLIC_APP_PRODUCTION_URL`, etc. These are build-time values in browser bundles.
|
|
126
154
|
|
|
127
155
|
## Platform support
|
|
128
156
|
|
|
@@ -255,13 +283,14 @@ Strict resolver function. It resolves when called and throws if no URL can be de
|
|
|
255
283
|
| `href` | `string` | Same as `origin` |
|
|
256
284
|
| `protocol` | `string` | `"https:"` |
|
|
257
285
|
| `port` | `string` | `""` or `"3000"` |
|
|
286
|
+
| `productionOrigin` | `string` | `"https://myapp.com"` |
|
|
258
287
|
| `env` | `AppEnv` | `"production"` \| `"preview"` \| `"local"` |
|
|
259
288
|
| `platform` | `Platform` | `"vercel"` \| `"netlify"` \| ... \| `null` |
|
|
260
289
|
| `debug`* | `string` | `"[provider:vercel] url=myapp.com \| env=production (vercel:production)"` |
|
|
261
290
|
| `isProduction` | `boolean` | |
|
|
262
291
|
| `isPreview` | `boolean` | |
|
|
263
292
|
| `isLocal` | `boolean` | |
|
|
264
|
-
| `createUrl` | `(options?: { env?:
|
|
293
|
+
| `createUrl` | `(options?: { env?: object }) => WhichUrlWithDebug` | strict resolver |
|
|
265
294
|
|
|
266
295
|
\* `debug` is non-enumerable on the default export and objects returned by `createUrl()` — excluded from `JSON.stringify` to avoid React hydration mismatches. It is also available as a named export.
|
|
267
296
|
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export declare const host: string;
|
|
|
13
13
|
export declare const protocol: string;
|
|
14
14
|
/** Port string — `""` for default ports, `"3000"` for custom */
|
|
15
15
|
export declare const port: string;
|
|
16
|
+
/** Canonical production origin when configured or detectable — `"https://myapp.com"` */
|
|
17
|
+
export declare const productionOrigin: string;
|
|
16
18
|
/** Current environment — `"production"`, `"preview"`, or `"local"` */
|
|
17
19
|
export declare const env: AppEnv;
|
|
18
20
|
/** Detected hosting platform — `"vercel"`, `"netlify"`, etc. or `null` */
|
|
@@ -33,6 +35,7 @@ export declare const isLocal: boolean;
|
|
|
33
35
|
* import appUrl from 'which-url'
|
|
34
36
|
*
|
|
35
37
|
* appUrl.origin // "https://myapp.com"
|
|
38
|
+
* appUrl.productionOrigin // "https://myapp.com"
|
|
36
39
|
* appUrl.env // "production"
|
|
37
40
|
* appUrl.platform // "vercel"
|
|
38
41
|
* appUrl.debug // "[provider:vercel] url=myapp.com | env=production (vercel:production)"
|
package/dist/index.js
CHANGED
|
@@ -1,321 +1 @@
|
|
|
1
|
-
|
|
2
|
-
var ENV_VARS = [
|
|
3
|
-
"VERCEL_ENV",
|
|
4
|
-
"VERCEL_URL",
|
|
5
|
-
"VERCEL_BRANCH_URL",
|
|
6
|
-
"VERCEL_PROJECT_PRODUCTION_URL",
|
|
7
|
-
"APP_URL",
|
|
8
|
-
"APP_ENV"
|
|
9
|
-
];
|
|
10
|
-
function readStatic(name) {
|
|
11
|
-
switch (name) {
|
|
12
|
-
case "VERCEL_ENV":
|
|
13
|
-
return process.env.VERCEL_ENV || process.env.NEXT_PUBLIC_VERCEL_ENV || process.env.NUXT_ENV_VERCEL_ENV || process.env.VITE_VERCEL_ENV || process.env.PUBLIC_VERCEL_ENV || process.env.REACT_APP_VERCEL_ENV || process.env.GATSBY_VERCEL_ENV || process.env.VUE_APP_VERCEL_ENV || process.env.REDWOOD_ENV_VERCEL_ENV || process.env.SANITY_STUDIO_VERCEL_ENV || undefined;
|
|
14
|
-
case "VERCEL_URL":
|
|
15
|
-
return process.env.VERCEL_URL || process.env.NEXT_PUBLIC_VERCEL_URL || process.env.NUXT_ENV_VERCEL_URL || process.env.VITE_VERCEL_URL || process.env.PUBLIC_VERCEL_URL || process.env.REACT_APP_VERCEL_URL || process.env.GATSBY_VERCEL_URL || process.env.VUE_APP_VERCEL_URL || process.env.REDWOOD_ENV_VERCEL_URL || process.env.SANITY_STUDIO_VERCEL_URL || undefined;
|
|
16
|
-
case "VERCEL_BRANCH_URL":
|
|
17
|
-
return process.env.VERCEL_BRANCH_URL || process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL || process.env.NUXT_ENV_VERCEL_BRANCH_URL || process.env.VITE_VERCEL_BRANCH_URL || process.env.PUBLIC_VERCEL_BRANCH_URL || process.env.REACT_APP_VERCEL_BRANCH_URL || process.env.GATSBY_VERCEL_BRANCH_URL || process.env.VUE_APP_VERCEL_BRANCH_URL || process.env.REDWOOD_ENV_VERCEL_BRANCH_URL || process.env.SANITY_STUDIO_VERCEL_BRANCH_URL || undefined;
|
|
18
|
-
case "VERCEL_PROJECT_PRODUCTION_URL":
|
|
19
|
-
return process.env.VERCEL_PROJECT_PRODUCTION_URL || process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL || process.env.NUXT_ENV_VERCEL_PROJECT_PRODUCTION_URL || process.env.VITE_VERCEL_PROJECT_PRODUCTION_URL || process.env.PUBLIC_VERCEL_PROJECT_PRODUCTION_URL || process.env.REACT_APP_VERCEL_PROJECT_PRODUCTION_URL || process.env.GATSBY_VERCEL_PROJECT_PRODUCTION_URL || process.env.VUE_APP_VERCEL_PROJECT_PRODUCTION_URL || process.env.REDWOOD_ENV_VERCEL_PROJECT_PRODUCTION_URL || process.env.SANITY_STUDIO_VERCEL_PROJECT_PRODUCTION_URL || undefined;
|
|
20
|
-
case "APP_URL":
|
|
21
|
-
return process.env.APP_URL || process.env.NEXT_PUBLIC_APP_URL || process.env.NUXT_ENV_APP_URL || process.env.VITE_APP_URL || process.env.PUBLIC_APP_URL || process.env.REACT_APP_APP_URL || process.env.GATSBY_APP_URL || process.env.VUE_APP_APP_URL || process.env.REDWOOD_ENV_APP_URL || process.env.SANITY_STUDIO_APP_URL || undefined;
|
|
22
|
-
case "APP_ENV":
|
|
23
|
-
return process.env.APP_ENV || process.env.NEXT_PUBLIC_APP_ENV || process.env.NUXT_ENV_APP_ENV || process.env.VITE_APP_ENV || process.env.PUBLIC_APP_ENV || process.env.REACT_APP_APP_ENV || process.env.GATSBY_APP_ENV || process.env.VUE_APP_APP_ENV || process.env.REDWOOD_ENV_APP_ENV || process.env.SANITY_STUDIO_APP_ENV || undefined;
|
|
24
|
-
default:
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function getVar(env, name) {
|
|
29
|
-
if (typeof process !== "undefined" && process?.env && env === process.env) {
|
|
30
|
-
if (ENV_VARS.includes(name)) {
|
|
31
|
-
const val = readStatic(name);
|
|
32
|
-
if (val)
|
|
33
|
-
return val;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
const PREFIXES = [
|
|
37
|
-
"",
|
|
38
|
-
"NEXT_PUBLIC_",
|
|
39
|
-
"NUXT_ENV_",
|
|
40
|
-
"VITE_",
|
|
41
|
-
"PUBLIC_",
|
|
42
|
-
"REACT_APP_",
|
|
43
|
-
"GATSBY_",
|
|
44
|
-
"VUE_APP_",
|
|
45
|
-
"REDWOOD_ENV_",
|
|
46
|
-
"SANITY_STUDIO_"
|
|
47
|
-
];
|
|
48
|
-
for (const prefix of PREFIXES) {
|
|
49
|
-
const val = env[prefix + name];
|
|
50
|
-
if (val)
|
|
51
|
-
return val;
|
|
52
|
-
}
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
function getEnv(override) {
|
|
56
|
-
if (override !== undefined) {
|
|
57
|
-
return filterStrings(override);
|
|
58
|
-
}
|
|
59
|
-
if (typeof process !== "undefined" && process?.env) {
|
|
60
|
-
return process.env;
|
|
61
|
-
}
|
|
62
|
-
return {};
|
|
63
|
-
}
|
|
64
|
-
function filterStrings(source) {
|
|
65
|
-
const out = {};
|
|
66
|
-
for (const key in source) {
|
|
67
|
-
const value = source[key];
|
|
68
|
-
if (typeof value === "string")
|
|
69
|
-
out[key] = value;
|
|
70
|
-
}
|
|
71
|
-
return out;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// src/providers.ts
|
|
75
|
-
var providers = [
|
|
76
|
-
{
|
|
77
|
-
name: "vercel",
|
|
78
|
-
detect: (env) => !!env.VERCEL || !!getVar(env, "VERCEL_ENV"),
|
|
79
|
-
resolveUrl: (env) => {
|
|
80
|
-
const vercelEnv = getVar(env, "VERCEL_ENV");
|
|
81
|
-
if (vercelEnv === "production") {
|
|
82
|
-
return getVar(env, "VERCEL_PROJECT_PRODUCTION_URL") || getVar(env, "VERCEL_URL") || null;
|
|
83
|
-
}
|
|
84
|
-
return getVar(env, "VERCEL_BRANCH_URL") || getVar(env, "VERCEL_URL") || null;
|
|
85
|
-
},
|
|
86
|
-
resolveEnv: (env) => {
|
|
87
|
-
const vercelEnv = getVar(env, "VERCEL_ENV");
|
|
88
|
-
if (vercelEnv === "production")
|
|
89
|
-
return "production";
|
|
90
|
-
if (vercelEnv === "preview")
|
|
91
|
-
return "preview";
|
|
92
|
-
return "local";
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
name: "netlify",
|
|
97
|
-
detect: (env) => !!env.NETLIFY,
|
|
98
|
-
resolveUrl: (env) => {
|
|
99
|
-
if (env.CONTEXT === "production")
|
|
100
|
-
return env.URL || null;
|
|
101
|
-
return env.DEPLOY_PRIME_URL || env.DEPLOY_URL || null;
|
|
102
|
-
},
|
|
103
|
-
resolveEnv: (env) => {
|
|
104
|
-
if (env.CONTEXT === "production")
|
|
105
|
-
return "production";
|
|
106
|
-
if (env.CONTEXT === "deploy-preview" || env.CONTEXT === "branch-deploy")
|
|
107
|
-
return "preview";
|
|
108
|
-
return "local";
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
name: "cloudflare",
|
|
113
|
-
detect: (env) => !!env.CF_PAGES,
|
|
114
|
-
resolveUrl: (env) => env.CF_PAGES_URL || null,
|
|
115
|
-
resolveEnv: (env) => {
|
|
116
|
-
if (env.CF_PAGES_BRANCH === "main" || env.CF_PAGES_BRANCH === "master")
|
|
117
|
-
return "production";
|
|
118
|
-
return "preview";
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
name: "railway",
|
|
123
|
-
detect: (env) => !!env.RAILWAY_PUBLIC_DOMAIN,
|
|
124
|
-
resolveUrl: (env) => env.RAILWAY_PUBLIC_DOMAIN || null,
|
|
125
|
-
resolveEnv: (env) => {
|
|
126
|
-
if (env.RAILWAY_ENVIRONMENT === "production")
|
|
127
|
-
return "production";
|
|
128
|
-
return "production";
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
name: "fly",
|
|
133
|
-
detect: (env) => !!env.FLY_APP_NAME,
|
|
134
|
-
resolveUrl: (env) => env.FLY_APP_NAME ? `${env.FLY_APP_NAME}.fly.dev` : null,
|
|
135
|
-
resolveEnv: () => "production"
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
name: "render",
|
|
139
|
-
detect: (env) => !!env.RENDER,
|
|
140
|
-
resolveUrl: (env) => env.RENDER_EXTERNAL_URL || null,
|
|
141
|
-
resolveEnv: (env) => {
|
|
142
|
-
if (env.IS_PULL_REQUEST === "true")
|
|
143
|
-
return "preview";
|
|
144
|
-
return "production";
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
name: "digitalocean",
|
|
149
|
-
detect: (env) => !!env.DIGITALOCEAN_APP_PLATFORM,
|
|
150
|
-
resolveUrl: (env) => env.APP_URL || null,
|
|
151
|
-
resolveEnv: () => "production"
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
name: "heroku",
|
|
155
|
-
detect: (env) => !!env.HEROKU_APP_NAME,
|
|
156
|
-
resolveUrl: (env) => env.HEROKU_APP_NAME ? `${env.HEROKU_APP_NAME}.herokuapp.com` : null,
|
|
157
|
-
resolveEnv: () => "production"
|
|
158
|
-
}
|
|
159
|
-
];
|
|
160
|
-
|
|
161
|
-
// src/normalize.ts
|
|
162
|
-
function normalizeUrl(raw) {
|
|
163
|
-
let url = raw.trim().replace(/\/+$/, "");
|
|
164
|
-
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
165
|
-
return url;
|
|
166
|
-
}
|
|
167
|
-
return `https://${url}`;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// src/resolve.ts
|
|
171
|
-
function resolveUrl(envOverride) {
|
|
172
|
-
const env = getEnv(envOverride);
|
|
173
|
-
const override = getVar(env, "APP_URL");
|
|
174
|
-
if (override)
|
|
175
|
-
return { url: normalizeUrl(override), debugLabel: `[override] APP_URL=${override}` };
|
|
176
|
-
if (env.PORTLESS_TAILSCALE_URL) {
|
|
177
|
-
return { url: env.PORTLESS_TAILSCALE_URL, debugLabel: `[portless:tailscale] PORTLESS_TAILSCALE_URL=${env.PORTLESS_TAILSCALE_URL}` };
|
|
178
|
-
}
|
|
179
|
-
if (env.PORTLESS_URL) {
|
|
180
|
-
return { url: env.PORTLESS_URL, debugLabel: `[portless] PORTLESS_URL=${env.PORTLESS_URL}` };
|
|
181
|
-
}
|
|
182
|
-
for (const p of providers) {
|
|
183
|
-
if (p.detect(env)) {
|
|
184
|
-
const url = p.resolveUrl(env);
|
|
185
|
-
if (url)
|
|
186
|
-
return { url: normalizeUrl(url), debugLabel: `[provider:${p.name}] url=${url}` };
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
if (typeof window !== "undefined" && window.location) {
|
|
190
|
-
return { url: window.location.origin, debugLabel: `[browser] window.location.origin` };
|
|
191
|
-
}
|
|
192
|
-
const isProduction = env.NODE_ENV === "production";
|
|
193
|
-
if (!isProduction) {
|
|
194
|
-
const port = env.PORT || "3000";
|
|
195
|
-
return { url: `http://localhost:${port}`, debugLabel: `[fallback] PORT=${port}` };
|
|
196
|
-
}
|
|
197
|
-
throw new Error("which-url: Cannot detect app URL. Set APP_URL environment variable.");
|
|
198
|
-
}
|
|
199
|
-
function resolvePlatform(envOverride) {
|
|
200
|
-
const env = getEnv(envOverride);
|
|
201
|
-
for (const p of providers) {
|
|
202
|
-
if (p.detect(env)) {
|
|
203
|
-
return p.name;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return null;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// src/env.ts
|
|
210
|
-
var validEnvs = ["production", "preview", "local"];
|
|
211
|
-
function resolveEnv(envOverride) {
|
|
212
|
-
const env = getEnv(envOverride);
|
|
213
|
-
const appEnv = getVar(env, "APP_ENV");
|
|
214
|
-
if (appEnv && validEnvs.includes(appEnv)) {
|
|
215
|
-
return { env: appEnv, debugLabel: `APP_ENV=${appEnv}` };
|
|
216
|
-
}
|
|
217
|
-
if (env.NODE_ENV === "development")
|
|
218
|
-
return { env: "local", debugLabel: "NODE_ENV=development" };
|
|
219
|
-
for (const p of providers) {
|
|
220
|
-
if (p.detect(env)) {
|
|
221
|
-
const resolved = p.resolveEnv(env);
|
|
222
|
-
return { env: resolved, debugLabel: `${p.name}:${resolved}` };
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
if (env.NODE_ENV === "production")
|
|
226
|
-
return { env: "production", debugLabel: "NODE_ENV=production" };
|
|
227
|
-
return { env: "local", debugLabel: "default" };
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// src/index.ts
|
|
231
|
-
function makeDebugNonEnumerable(result) {
|
|
232
|
-
Object.defineProperty(result, "debug", {
|
|
233
|
-
value: result.debug,
|
|
234
|
-
enumerable: false,
|
|
235
|
-
configurable: false
|
|
236
|
-
});
|
|
237
|
-
return result;
|
|
238
|
-
}
|
|
239
|
-
function createUrl(options) {
|
|
240
|
-
const envOverride = options?.env;
|
|
241
|
-
const { url, debugLabel: urlDebug } = resolveUrl(envOverride);
|
|
242
|
-
const parsed = new URL(url);
|
|
243
|
-
const { env, debugLabel: envDebug } = resolveEnv(envOverride);
|
|
244
|
-
const platform = resolvePlatform(envOverride);
|
|
245
|
-
const debug = `${urlDebug} | env=${env} (${envDebug})`;
|
|
246
|
-
const result = {
|
|
247
|
-
href: parsed.origin,
|
|
248
|
-
origin: parsed.origin,
|
|
249
|
-
hostname: parsed.hostname,
|
|
250
|
-
host: parsed.host,
|
|
251
|
-
protocol: parsed.protocol,
|
|
252
|
-
port: parsed.port,
|
|
253
|
-
env,
|
|
254
|
-
platform,
|
|
255
|
-
debug,
|
|
256
|
-
isProduction: env === "production",
|
|
257
|
-
isPreview: env === "preview",
|
|
258
|
-
isLocal: env === "local"
|
|
259
|
-
};
|
|
260
|
-
return makeDebugNonEnumerable(result);
|
|
261
|
-
}
|
|
262
|
-
function createFallback(error) {
|
|
263
|
-
const message = error instanceof Error ? error.message : "resolution failed";
|
|
264
|
-
let resolvedEnv = "local";
|
|
265
|
-
let envDebug = "default";
|
|
266
|
-
try {
|
|
267
|
-
const result = resolveEnv();
|
|
268
|
-
resolvedEnv = result.env;
|
|
269
|
-
envDebug = result.debugLabel;
|
|
270
|
-
} catch {}
|
|
271
|
-
const fallback = {
|
|
272
|
-
href: "",
|
|
273
|
-
origin: "",
|
|
274
|
-
hostname: "",
|
|
275
|
-
host: "",
|
|
276
|
-
protocol: "",
|
|
277
|
-
port: "",
|
|
278
|
-
env: resolvedEnv,
|
|
279
|
-
platform: resolvePlatform(),
|
|
280
|
-
debug: `[error] ${message} | env=${resolvedEnv} (${envDebug})`,
|
|
281
|
-
isProduction: resolvedEnv === "production",
|
|
282
|
-
isPreview: resolvedEnv === "preview",
|
|
283
|
-
isLocal: resolvedEnv === "local"
|
|
284
|
-
};
|
|
285
|
-
return makeDebugNonEnumerable(fallback);
|
|
286
|
-
}
|
|
287
|
-
var _resolved;
|
|
288
|
-
try {
|
|
289
|
-
_resolved = createUrl();
|
|
290
|
-
} catch (e) {
|
|
291
|
-
_resolved = createFallback(e);
|
|
292
|
-
}
|
|
293
|
-
var href = _resolved.href;
|
|
294
|
-
var origin = _resolved.origin;
|
|
295
|
-
var hostname = _resolved.hostname;
|
|
296
|
-
var host = _resolved.host;
|
|
297
|
-
var protocol = _resolved.protocol;
|
|
298
|
-
var port = _resolved.port;
|
|
299
|
-
var env = _resolved.env;
|
|
300
|
-
var platform = _resolved.platform;
|
|
301
|
-
var debug = _resolved.debug;
|
|
302
|
-
var isProduction = _resolved.isProduction;
|
|
303
|
-
var isPreview = _resolved.isPreview;
|
|
304
|
-
var isLocal = _resolved.isLocal;
|
|
305
|
-
var src_default = _resolved;
|
|
306
|
-
export {
|
|
307
|
-
protocol,
|
|
308
|
-
port,
|
|
309
|
-
platform,
|
|
310
|
-
origin,
|
|
311
|
-
isProduction,
|
|
312
|
-
isPreview,
|
|
313
|
-
isLocal,
|
|
314
|
-
href,
|
|
315
|
-
hostname,
|
|
316
|
-
host,
|
|
317
|
-
env,
|
|
318
|
-
src_default as default,
|
|
319
|
-
debug,
|
|
320
|
-
createUrl
|
|
321
|
-
};
|
|
1
|
+
var u=["VERCEL_ENV","VERCEL_URL","VERCEL_BRANCH_URL","VERCEL_PROJECT_PRODUCTION_URL","APP_URL","APP_PRODUCTION_URL","APP_ENV"];function D(E){switch(E){case"VERCEL_ENV":return process.env.VERCEL_ENV||process.env.NEXT_PUBLIC_VERCEL_ENV||process.env.NUXT_ENV_VERCEL_ENV||process.env.VITE_VERCEL_ENV||process.env.PUBLIC_VERCEL_ENV||process.env.REACT_APP_VERCEL_ENV||process.env.GATSBY_VERCEL_ENV||process.env.VUE_APP_VERCEL_ENV||process.env.REDWOOD_ENV_VERCEL_ENV||process.env.SANITY_STUDIO_VERCEL_ENV||void 0;case"VERCEL_URL":return process.env.VERCEL_URL||process.env.NEXT_PUBLIC_VERCEL_URL||process.env.NUXT_ENV_VERCEL_URL||process.env.VITE_VERCEL_URL||process.env.PUBLIC_VERCEL_URL||process.env.REACT_APP_VERCEL_URL||process.env.GATSBY_VERCEL_URL||process.env.VUE_APP_VERCEL_URL||process.env.REDWOOD_ENV_VERCEL_URL||process.env.SANITY_STUDIO_VERCEL_URL||void 0;case"VERCEL_BRANCH_URL":return process.env.VERCEL_BRANCH_URL||process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL||process.env.NUXT_ENV_VERCEL_BRANCH_URL||process.env.VITE_VERCEL_BRANCH_URL||process.env.PUBLIC_VERCEL_BRANCH_URL||process.env.REACT_APP_VERCEL_BRANCH_URL||process.env.GATSBY_VERCEL_BRANCH_URL||process.env.VUE_APP_VERCEL_BRANCH_URL||process.env.REDWOOD_ENV_VERCEL_BRANCH_URL||process.env.SANITY_STUDIO_VERCEL_BRANCH_URL||void 0;case"VERCEL_PROJECT_PRODUCTION_URL":return process.env.VERCEL_PROJECT_PRODUCTION_URL||process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL||process.env.NUXT_ENV_VERCEL_PROJECT_PRODUCTION_URL||process.env.VITE_VERCEL_PROJECT_PRODUCTION_URL||process.env.PUBLIC_VERCEL_PROJECT_PRODUCTION_URL||process.env.REACT_APP_VERCEL_PROJECT_PRODUCTION_URL||process.env.GATSBY_VERCEL_PROJECT_PRODUCTION_URL||process.env.VUE_APP_VERCEL_PROJECT_PRODUCTION_URL||process.env.REDWOOD_ENV_VERCEL_PROJECT_PRODUCTION_URL||process.env.SANITY_STUDIO_VERCEL_PROJECT_PRODUCTION_URL||void 0;case"APP_URL":return process.env.APP_URL||process.env.NEXT_PUBLIC_APP_URL||process.env.NUXT_ENV_APP_URL||process.env.VITE_APP_URL||process.env.PUBLIC_APP_URL||process.env.REACT_APP_APP_URL||process.env.GATSBY_APP_URL||process.env.VUE_APP_APP_URL||process.env.REDWOOD_ENV_APP_URL||process.env.SANITY_STUDIO_APP_URL||void 0;case"APP_PRODUCTION_URL":return process.env.APP_PRODUCTION_URL||process.env.NEXT_PUBLIC_APP_PRODUCTION_URL||process.env.NUXT_ENV_APP_PRODUCTION_URL||process.env.VITE_APP_PRODUCTION_URL||process.env.PUBLIC_APP_PRODUCTION_URL||process.env.REACT_APP_APP_PRODUCTION_URL||process.env.GATSBY_APP_PRODUCTION_URL||process.env.VUE_APP_APP_PRODUCTION_URL||process.env.REDWOOD_ENV_APP_PRODUCTION_URL||process.env.SANITY_STUDIO_APP_PRODUCTION_URL||void 0;case"APP_ENV":return process.env.APP_ENV||process.env.NEXT_PUBLIC_APP_ENV||process.env.NUXT_ENV_APP_ENV||process.env.VITE_APP_ENV||process.env.PUBLIC_APP_ENV||process.env.REACT_APP_APP_ENV||process.env.GATSBY_APP_ENV||process.env.VUE_APP_APP_ENV||process.env.REDWOOD_ENV_APP_ENV||process.env.SANITY_STUDIO_APP_ENV||void 0;default:return}}function C(E,P){if(typeof process<"u"&&process?.env&&E===process.env){if(u.includes(P)){let L=D(P);if(L)return L}}let A=["","NEXT_PUBLIC_","NUXT_ENV_","VITE_","PUBLIC_","REACT_APP_","GATSBY_","VUE_APP_","REDWOOD_ENV_","SANITY_STUDIO_"];for(let L of A){let _=E[L+P];if(_)return _}return}function t(E){if(E!==void 0)return G(E);if(typeof process<"u"&&process?.env)return process.env;return{}}function G(E){let P={};for(let[A,L]of Object.entries(E))if(typeof L==="string")P[A]=L;return P}var U=[{name:"vercel",detect:(E)=>!!E.VERCEL||!!C(E,"VERCEL_ENV"),resolveUrl:(E)=>{if(C(E,"VERCEL_ENV")==="production")return C(E,"VERCEL_PROJECT_PRODUCTION_URL")||C(E,"VERCEL_URL")||null;return C(E,"VERCEL_BRANCH_URL")||C(E,"VERCEL_URL")||null},resolveProductionUrl:(E)=>C(E,"VERCEL_PROJECT_PRODUCTION_URL")||null,resolveEnv:(E)=>{let P=C(E,"VERCEL_ENV");if(P==="production")return"production";if(P==="preview")return"preview";return"local"}},{name:"netlify",detect:(E)=>!!E.NETLIFY,resolveUrl:(E)=>{if(E.CONTEXT==="production")return E.URL||null;return E.DEPLOY_PRIME_URL||E.DEPLOY_URL||null},resolveProductionUrl:(E)=>E.URL||null,resolveEnv:(E)=>{if(E.CONTEXT==="production")return"production";if(E.CONTEXT==="deploy-preview"||E.CONTEXT==="branch-deploy")return"preview";return"local"}},{name:"cloudflare",detect:(E)=>!!E.CF_PAGES,resolveUrl:(E)=>E.CF_PAGES_URL||null,resolveEnv:(E)=>{if(E.CF_PAGES_BRANCH==="main"||E.CF_PAGES_BRANCH==="master")return"production";return"preview"}},{name:"railway",detect:(E)=>!!E.RAILWAY_PUBLIC_DOMAIN,resolveUrl:(E)=>E.RAILWAY_PUBLIC_DOMAIN||null,resolveProductionUrl:(E)=>E.RAILWAY_PUBLIC_DOMAIN||null,resolveEnv:(E)=>{if(E.RAILWAY_ENVIRONMENT==="production")return"production";return"production"}},{name:"fly",detect:(E)=>!!E.FLY_APP_NAME,resolveUrl:(E)=>E.FLY_APP_NAME?`${E.FLY_APP_NAME}.fly.dev`:null,resolveProductionUrl:(E)=>E.FLY_APP_NAME?`${E.FLY_APP_NAME}.fly.dev`:null,resolveEnv:()=>"production"},{name:"render",detect:(E)=>!!E.RENDER,resolveUrl:(E)=>E.RENDER_EXTERNAL_URL||null,resolveProductionUrl:(E)=>E.IS_PULL_REQUEST==="true"?null:E.RENDER_EXTERNAL_URL||null,resolveEnv:(E)=>{if(E.IS_PULL_REQUEST==="true")return"preview";return"production"}},{name:"digitalocean",detect:(E)=>!!E.DIGITALOCEAN_APP_PLATFORM,resolveUrl:(E)=>E.APP_URL||null,resolveProductionUrl:(E)=>E.APP_URL||null,resolveEnv:()=>"production"},{name:"heroku",detect:(E)=>!!E.HEROKU_APP_NAME,resolveUrl:(E)=>E.HEROKU_APP_NAME?`${E.HEROKU_APP_NAME}.herokuapp.com`:null,resolveProductionUrl:(E)=>E.HEROKU_APP_NAME?`${E.HEROKU_APP_NAME}.herokuapp.com`:null,resolveEnv:()=>"production"}];function T(E){let P=E.trim().replace(/\/+$/,"");if(P.startsWith("http://")||P.startsWith("https://"))return P;return`https://${P}`}function f(E){let P=t(E),A=C(P,"APP_URL");if(A)return{url:T(A),debugLabel:`[override] APP_URL=${A}`};if(P.PORTLESS_TAILSCALE_URL)return{url:P.PORTLESS_TAILSCALE_URL,debugLabel:`[portless:tailscale] PORTLESS_TAILSCALE_URL=${P.PORTLESS_TAILSCALE_URL}`};if(P.PORTLESS_URL)return{url:P.PORTLESS_URL,debugLabel:`[portless] PORTLESS_URL=${P.PORTLESS_URL}`};for(let _ of U)if(_.detect(P)){let R=_.resolveUrl(P);if(R)return{url:T(R),debugLabel:`[provider:${_.name}] url=${R}`}}if(typeof window<"u"&&window.location)return{url:window.location.origin,debugLabel:"[browser] window.location.origin"};if(P.NODE_ENV!=="production"){let _=P.PORT||"3000";return{url:`http://localhost:${_}`,debugLabel:`[fallback] PORT=${_}`}}throw Error("which-url: Cannot detect app URL. Set APP_URL environment variable.")}function F(E){let P=t(E),A=C(P,"APP_PRODUCTION_URL");if(A)return{url:T(A),debugLabel:`[production:override] APP_PRODUCTION_URL=${A}`};for(let _ of U)if(_.detect(P)){let R=_.resolveProductionUrl?.(P);if(R)return{url:T(R),debugLabel:`[production:provider:${_.name}] url=${R}`}}for(let _ of U)if(_.detect(P)&&_.resolveEnv(P)==="production"){let R=_.resolveUrl(P);if(R)return{url:T(R),debugLabel:`[production:current:${_.name}] url=${R}`}}let L=C(P,"APP_URL");if(L&&P.NODE_ENV==="production")return{url:T(L),debugLabel:`[production:current] APP_URL=${L}`};return null}function M(E){let P=t(E);for(let A of U)if(A.detect(P))return A.name;return null}var K=["production","preview","local"];function c(E){let P=t(E),A=C(P,"APP_ENV");if(A&&K.includes(A))return{env:A,debugLabel:`APP_ENV=${A}`};if(P.NODE_ENV==="development")return{env:"local",debugLabel:"NODE_ENV=development"};for(let L of U)if(L.detect(P)){let _=L.resolveEnv(P);return{env:_,debugLabel:`${L.name}:${_}`}}if(P.NODE_ENV==="production")return{env:"production",debugLabel:"NODE_ENV=production"};return{env:"local",debugLabel:"default"}}function H(E){return Object.defineProperty(E,"debug",{value:E.debug,enumerable:!1,configurable:!1}),E}function X(E){let P=E?.env,{url:A,debugLabel:L}=f(P),_=new URL(A),{env:R,debugLabel:O}=c(P),V=M(P),I=F(P),Y=I?new URL(I.url).origin:"",B=I?` | production=${Y} (${I.debugLabel})`:" | production=unresolved",W=`${L} | env=${R} (${O})${B}`,$={href:_.origin,origin:_.origin,hostname:_.hostname,host:_.host,protocol:_.protocol,port:_.port,productionOrigin:Y,env:R,platform:V,debug:W,isProduction:R==="production",isPreview:R==="preview",isLocal:R==="local"};return H($)}function S(E){let P=E instanceof Error?E.message:"resolution failed",A="local",L="default";try{let R=c();A=R.env,L=R.debugLabel}catch{}let _={href:"",origin:"",hostname:"",host:"",protocol:"",port:"",productionOrigin:"",env:A,platform:M(),debug:`[error] ${P} | env=${A} (${L})`,isProduction:A==="production",isPreview:A==="preview",isLocal:A==="local"};return H(_)}var N;try{N=X()}catch(E){N=S(E)}var{href:m,origin:g,hostname:i,host:o,protocol:s,port:d,productionOrigin:n,env:p,platform:a,debug:r,isProduction:v,isPreview:e,isLocal:EE}=N,_E=N;export{s as protocol,n as productionOrigin,d as port,a as platform,g as origin,v as isProduction,e as isPreview,EE as isLocal,m as href,i as hostname,o as host,p as env,_E as default,r as debug,X as createUrl};
|
package/dist/types.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface WhichUrl {
|
|
|
14
14
|
readonly protocol: string;
|
|
15
15
|
/** Port string — `""` for default ports, `"3000"` for custom */
|
|
16
16
|
readonly port: string;
|
|
17
|
+
/** Canonical production origin when configured or detectable — `"https://myapp.com"` */
|
|
18
|
+
readonly productionOrigin: string;
|
|
17
19
|
/** Current environment — `"production"`, `"preview"`, or `"local"` */
|
|
18
20
|
readonly env: AppEnv;
|
|
19
21
|
/** Detected hosting platform — `"vercel"`, `"netlify"`, etc. or `null` */
|
|
@@ -39,12 +41,13 @@ export interface CreateUrlOptions {
|
|
|
39
41
|
* entries participate in URL detection — non-string Workers bindings
|
|
40
42
|
* (KV namespaces, Durable Objects, R2 buckets, service bindings) are dropped.
|
|
41
43
|
*/
|
|
42
|
-
env?:
|
|
44
|
+
env?: object;
|
|
43
45
|
}
|
|
44
46
|
export interface ProviderDetector {
|
|
45
47
|
name: PlatformName;
|
|
46
48
|
detect: (env: Record<string, string | undefined>) => boolean;
|
|
47
49
|
resolveUrl: (env: Record<string, string | undefined>) => string | null;
|
|
50
|
+
resolveProductionUrl?: (env: Record<string, string | undefined>) => string | null;
|
|
48
51
|
resolveEnv: (env: Record<string, string | undefined>) => AppEnv;
|
|
49
52
|
}
|
|
50
53
|
//# sourceMappingURL=types.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "which-url",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "Auto-detect your app's URL across hosting providers. Zero config.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -12,7 +12,11 @@
|
|
|
12
12
|
"main": "./dist/index.js",
|
|
13
13
|
"module": "./dist/index.js",
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
|
-
"files": [
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/index.js",
|
|
17
|
+
"dist/index.d.ts",
|
|
18
|
+
"dist/types.d.ts"
|
|
19
|
+
],
|
|
16
20
|
"sideEffects": false,
|
|
17
21
|
"keywords": ["url", "base-url", "vercel", "netlify", "cloudflare", "railway", "hosting", "auto-detect", "which-url"],
|
|
18
22
|
"author": {
|
|
@@ -25,7 +29,7 @@
|
|
|
25
29
|
},
|
|
26
30
|
"license": "MIT",
|
|
27
31
|
"scripts": {
|
|
28
|
-
"build": "bun build src/index.ts --outdir dist --format esm && tsc --emitDeclarationOnly --outDir dist",
|
|
32
|
+
"build": "bun build src/index.ts --outdir dist --format esm --minify && tsc --emitDeclarationOnly --outDir dist",
|
|
29
33
|
"test": "bun test",
|
|
30
34
|
"prepublishOnly": "bun run build"
|
|
31
35
|
},
|
package/dist/env-var.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Read an env var, checking all framework-prefixed versions.
|
|
3
|
-
* On the server, unprefixed wins (it's always set).
|
|
4
|
-
* On the client, the bundler inlines the prefixed version.
|
|
5
|
-
*
|
|
6
|
-
* When called with an `env` object (e.g. from provider detection),
|
|
7
|
-
* falls back to dynamic lookup for test/server compatibility.
|
|
8
|
-
*/
|
|
9
|
-
export declare function getVar(env: Record<string, string | undefined>, name: string): string | undefined;
|
|
10
|
-
export declare function getEnv(override?: Record<string, unknown>): Record<string, string | undefined>;
|
|
11
|
-
//# sourceMappingURL=env-var.d.ts.map
|
package/dist/env-var.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"env-var.d.ts","sourceRoot":"","sources":["../src/env-var.ts"],"names":[],"mappings":"AAkGA;;;;;;;GAOG;AACH,wBAAgB,MAAM,CACpB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CA4BpB;AAED,wBAAgB,MAAM,CACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAQpC"}
|
package/dist/env.d.ts
DELETED
package/dist/env.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAIrC,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAyB3E"}
|
package/dist/index.cjs
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
6
|
-
var __toCommonJS = (from) => {
|
|
7
|
-
var entry = __moduleCache.get(from), desc;
|
|
8
|
-
if (entry)
|
|
9
|
-
return entry;
|
|
10
|
-
entry = __defProp({}, "__esModule", { value: true });
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
12
|
-
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
13
|
-
get: () => from[key],
|
|
14
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
-
}));
|
|
16
|
-
__moduleCache.set(from, entry);
|
|
17
|
-
return entry;
|
|
18
|
-
};
|
|
19
|
-
var __export = (target, all) => {
|
|
20
|
-
for (var name in all)
|
|
21
|
-
__defProp(target, name, {
|
|
22
|
-
get: all[name],
|
|
23
|
-
enumerable: true,
|
|
24
|
-
configurable: true,
|
|
25
|
-
set: (newValue) => all[name] = () => newValue
|
|
26
|
-
});
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// src/index.ts
|
|
30
|
-
var exports_src = {};
|
|
31
|
-
__export(exports_src, {
|
|
32
|
-
protocol: () => protocol,
|
|
33
|
-
port: () => port,
|
|
34
|
-
origin: () => origin,
|
|
35
|
-
isProduction: () => isProduction,
|
|
36
|
-
isPreview: () => isPreview,
|
|
37
|
-
isLocal: () => isLocal,
|
|
38
|
-
href: () => href,
|
|
39
|
-
hostname: () => hostname,
|
|
40
|
-
host: () => host,
|
|
41
|
-
env: () => env,
|
|
42
|
-
default: () => src_default,
|
|
43
|
-
createUrl: () => createUrl
|
|
44
|
-
});
|
|
45
|
-
module.exports = __toCommonJS(exports_src);
|
|
46
|
-
|
|
47
|
-
// src/providers.ts
|
|
48
|
-
var providers = [
|
|
49
|
-
{
|
|
50
|
-
name: "vercel",
|
|
51
|
-
detect: (env) => env.VERCEL === "1",
|
|
52
|
-
resolveUrl: (env) => {
|
|
53
|
-
if (env.VERCEL_ENV === "production") {
|
|
54
|
-
return env.VERCEL_PROJECT_PRODUCTION_URL ?? env.VERCEL_URL ?? null;
|
|
55
|
-
}
|
|
56
|
-
return env.VERCEL_BRANCH_URL ?? env.VERCEL_URL ?? null;
|
|
57
|
-
},
|
|
58
|
-
resolveEnv: (env) => {
|
|
59
|
-
if (env.VERCEL_ENV === "production")
|
|
60
|
-
return "production";
|
|
61
|
-
if (env.VERCEL_ENV === "preview")
|
|
62
|
-
return "preview";
|
|
63
|
-
return "local";
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
name: "netlify",
|
|
68
|
-
detect: (env) => env.NETLIFY === "true",
|
|
69
|
-
resolveUrl: (env) => {
|
|
70
|
-
if (env.CONTEXT === "production")
|
|
71
|
-
return env.URL ?? null;
|
|
72
|
-
return env.DEPLOY_PRIME_URL ?? env.DEPLOY_URL ?? null;
|
|
73
|
-
},
|
|
74
|
-
resolveEnv: (env) => {
|
|
75
|
-
if (env.CONTEXT === "production")
|
|
76
|
-
return "production";
|
|
77
|
-
if (env.CONTEXT === "deploy-preview" || env.CONTEXT === "branch-deploy")
|
|
78
|
-
return "preview";
|
|
79
|
-
return "local";
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
name: "cloudflare",
|
|
84
|
-
detect: (env) => env.CF_PAGES === "1",
|
|
85
|
-
resolveUrl: (env) => env.CF_PAGES_URL ?? null,
|
|
86
|
-
resolveEnv: (env) => {
|
|
87
|
-
if (env.CF_PAGES_BRANCH === "main" || env.CF_PAGES_BRANCH === "master")
|
|
88
|
-
return "production";
|
|
89
|
-
return "preview";
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
name: "railway",
|
|
94
|
-
detect: (env) => !!env.RAILWAY_PUBLIC_DOMAIN,
|
|
95
|
-
resolveUrl: (env) => env.RAILWAY_PUBLIC_DOMAIN ?? null,
|
|
96
|
-
resolveEnv: (env) => {
|
|
97
|
-
if (env.RAILWAY_ENVIRONMENT === "production")
|
|
98
|
-
return "production";
|
|
99
|
-
return "preview";
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
name: "render",
|
|
104
|
-
detect: (env) => env.RENDER === "true",
|
|
105
|
-
resolveUrl: (env) => env.RENDER_EXTERNAL_URL ?? null,
|
|
106
|
-
resolveEnv: (env) => {
|
|
107
|
-
if (env.IS_PULL_REQUEST === "true")
|
|
108
|
-
return "preview";
|
|
109
|
-
return "production";
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
name: "fly",
|
|
114
|
-
detect: (env) => !!env.FLY_APP_NAME,
|
|
115
|
-
resolveUrl: (env) => {
|
|
116
|
-
const name = env.FLY_APP_NAME;
|
|
117
|
-
return name ? `${name}.fly.dev` : null;
|
|
118
|
-
},
|
|
119
|
-
resolveEnv: () => "production"
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
name: "digitalocean",
|
|
123
|
-
detect: (env) => !!env.DIGITALOCEAN_APP_PLATFORM,
|
|
124
|
-
resolveUrl: (env) => env.APP_URL ?? null,
|
|
125
|
-
resolveEnv: () => "production"
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
name: "heroku",
|
|
129
|
-
detect: (env) => !!env.HEROKU_APP_NAME,
|
|
130
|
-
resolveUrl: (env) => {
|
|
131
|
-
const name = env.HEROKU_APP_NAME;
|
|
132
|
-
return name ? `${name}.herokuapp.com` : null;
|
|
133
|
-
},
|
|
134
|
-
resolveEnv: () => "production"
|
|
135
|
-
}
|
|
136
|
-
];
|
|
137
|
-
|
|
138
|
-
// src/normalize.ts
|
|
139
|
-
function normalizeUrl(raw, protocol = "https") {
|
|
140
|
-
let url = raw.trim();
|
|
141
|
-
url = url.replace(/\/+$/, "");
|
|
142
|
-
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
143
|
-
return url;
|
|
144
|
-
}
|
|
145
|
-
url = url.replace(/^\/+/, "");
|
|
146
|
-
return `${protocol}://${url}`;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// src/resolve.ts
|
|
150
|
-
function resolveUrl(options) {
|
|
151
|
-
const env = typeof process !== "undefined" ? process.env : {};
|
|
152
|
-
const override = env.APP_URL ?? env.NEXT_PUBLIC_APP_URL;
|
|
153
|
-
if (override)
|
|
154
|
-
return normalizeUrl(override);
|
|
155
|
-
for (const p of providers) {
|
|
156
|
-
if (p.detect(env)) {
|
|
157
|
-
const url = p.resolveUrl(env);
|
|
158
|
-
if (url)
|
|
159
|
-
return normalizeUrl(url);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
if (typeof window !== "undefined" && window.location?.origin) {
|
|
163
|
-
return window.location.origin;
|
|
164
|
-
}
|
|
165
|
-
if (options?.fallback)
|
|
166
|
-
return normalizeUrl(options.fallback);
|
|
167
|
-
const isProduction = env.NODE_ENV === "production";
|
|
168
|
-
if (isProduction) {
|
|
169
|
-
throw new Error(`thisapp: Cannot detect app URL. Set APP_URL environment variable.
|
|
170
|
-
` + "See: https://github.com/manishrc/thisapp#configuration");
|
|
171
|
-
}
|
|
172
|
-
const port = env.PORT ?? "3000";
|
|
173
|
-
return `http://localhost:${port}`;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// src/env.ts
|
|
177
|
-
function resolveEnv() {
|
|
178
|
-
const env = typeof process !== "undefined" ? process.env : {};
|
|
179
|
-
const override = env.APP_ENV;
|
|
180
|
-
if (override === "production" || override === "preview" || override === "local") {
|
|
181
|
-
return override;
|
|
182
|
-
}
|
|
183
|
-
if (env.NODE_ENV === "development")
|
|
184
|
-
return "local";
|
|
185
|
-
for (const p of providers) {
|
|
186
|
-
if (p.detect(env)) {
|
|
187
|
-
return p.resolveEnv(env);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (env.NODE_ENV === "production")
|
|
191
|
-
return "production";
|
|
192
|
-
return "local";
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// src/index.ts
|
|
196
|
-
function createUrl(options) {
|
|
197
|
-
const resolved = resolveUrl(options);
|
|
198
|
-
const parsed = new URL(resolved);
|
|
199
|
-
const env = resolveEnv();
|
|
200
|
-
return {
|
|
201
|
-
href: parsed.origin,
|
|
202
|
-
origin: parsed.origin,
|
|
203
|
-
hostname: parsed.hostname,
|
|
204
|
-
host: parsed.host,
|
|
205
|
-
protocol: parsed.protocol,
|
|
206
|
-
port: parsed.port,
|
|
207
|
-
env,
|
|
208
|
-
isProduction: env === "production",
|
|
209
|
-
isPreview: env === "preview",
|
|
210
|
-
isLocal: env === "local"
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
var _resolved = createUrl();
|
|
214
|
-
var href = _resolved.href;
|
|
215
|
-
var origin = _resolved.origin;
|
|
216
|
-
var hostname = _resolved.hostname;
|
|
217
|
-
var host = _resolved.host;
|
|
218
|
-
var protocol = _resolved.protocol;
|
|
219
|
-
var port = _resolved.port;
|
|
220
|
-
var env = _resolved.env;
|
|
221
|
-
var isProduction = _resolved.isProduction;
|
|
222
|
-
var isPreview = _resolved.isPreview;
|
|
223
|
-
var isLocal = _resolved.isLocal;
|
|
224
|
-
var src_default = _resolved;
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAYpF,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,iBAAiB,CAwBvE;AAkCD,QAAA,IAAI,SAAS,EAAE,iBAAiB,CAAA;AAOhC,0DAA0D;AAC1D,eAAO,MAAM,IAAI,EAAE,MAAuB,CAAA;AAC1C,yDAAyD;AACzD,eAAO,MAAM,MAAM,EAAE,MAAyB,CAAA;AAC9C,4CAA4C;AAC5C,eAAO,MAAM,QAAQ,EAAE,MAA2B,CAAA;AAClD,+DAA+D;AAC/D,eAAO,MAAM,IAAI,EAAE,MAAuB,CAAA;AAC1C,oDAAoD;AACpD,eAAO,MAAM,QAAQ,EAAE,MAA2B,CAAA;AAClD,gEAAgE;AAChE,eAAO,MAAM,IAAI,EAAE,MAAuB,CAAA;AAC1C,sEAAsE;AACtE,eAAO,MAAM,GAAG,EAAE,MAAsB,CAAA;AACxC,0EAA0E;AAC1E,eAAO,MAAM,QAAQ,EAAE,QAA6B,CAAA;AACpD,+BAA+B;AAC/B,eAAO,MAAM,KAAK,EAAE,MAAwB,CAAA;AAC5C,wCAAwC;AACxC,eAAO,MAAM,YAAY,EAAE,OAAgC,CAAA;AAC3D,0DAA0D;AAC1D,eAAO,MAAM,SAAS,EAAE,OAA6B,CAAA;AACrD,gDAAgD;AAChD,eAAO,MAAM,OAAO,EAAE,OAA2B,CAAA;AAEjD;;;;;;;;;;;;GAYG;AACH,eAAe,SAAS,CAAA;AAExB,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA"}
|
package/dist/normalize.d.ts
DELETED
package/dist/normalize.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMhD"}
|
package/dist/providers.d.ts
DELETED
package/dist/providers.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAG/C,eAAO,MAAM,SAAS,EAAE,gBAAgB,EAgFvC,CAAA"}
|
package/dist/resolve.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Platform } from "./types";
|
|
2
|
-
export interface ResolveResult {
|
|
3
|
-
url: string;
|
|
4
|
-
debugLabel: string;
|
|
5
|
-
}
|
|
6
|
-
export declare function resolveUrl(envOverride?: Record<string, unknown>): ResolveResult;
|
|
7
|
-
export declare function resolvePlatform(envOverride?: Record<string, unknown>): Platform;
|
|
8
|
-
//# sourceMappingURL=resolve.d.ts.map
|
package/dist/resolve.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,CAuC/E;AAED,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ,CAQ/E"}
|
package/dist/types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,CAAA;AAEvD,MAAM,MAAM,YAAY,GACpB,QAAQ,GACR,SAAS,GACT,YAAY,GACZ,SAAS,GACT,KAAK,GACL,QAAQ,GACR,cAAc,GACd,QAAQ,CAAA;AAEZ,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,IAAI,CAAA;AAE1C,MAAM,WAAW,QAAQ;IACvB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,sEAAsE;IACtE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,gDAAgD;IAChD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,iBAAkB,SAAQ,QAAQ;IACjD,iGAAiG;IACjG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;OAQG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAA;IAClB,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,KAAK,OAAO,CAAA;IAC5D,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,KAAK,MAAM,GAAG,IAAI,CAAA;IACtE,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,KAAK,MAAM,CAAA;CAChE"}
|