which-url 0.0.2 → 0.0.4
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 +120 -113
- package/dist/env-var.d.ts +8 -0
- package/dist/env-var.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -13
- package/dist/resolve.d.ts +2 -1
- package/dist/resolve.d.ts.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,126 +7,156 @@ npm install which-url
|
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
```typescript
|
|
10
|
-
import
|
|
10
|
+
import { origin } from 'which-url'
|
|
11
11
|
|
|
12
|
-
auth({ baseURL:
|
|
12
|
+
auth({ baseURL: origin })
|
|
13
|
+
fetch(`${origin}/api/data`)
|
|
13
14
|
```
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
```
|
|
17
|
+
origin env
|
|
18
|
+
Local http://localhost:3000 "local"
|
|
19
|
+
Preview https://myapp-git-feat.vercel.app "preview"
|
|
20
|
+
Production https://myapp.com "production"
|
|
21
|
+
```
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
Works across environments (local, preview, production), runtimes (server, client, edge), and [platforms](#platform-support).
|
|
18
24
|
|
|
19
|
-
|
|
25
|
+
The default export gives you everything as an object:
|
|
20
26
|
|
|
21
27
|
```typescript
|
|
22
28
|
import appUrl from 'which-url'
|
|
23
29
|
|
|
24
|
-
appUrl.
|
|
25
|
-
appUrl.
|
|
26
|
-
appUrl.
|
|
27
|
-
appUrl.
|
|
28
|
-
appUrl.
|
|
29
|
-
appUrl.
|
|
30
|
-
|
|
31
|
-
appUrl.env // "production" | "preview" | "local"
|
|
32
|
-
appUrl.isProduction // boolean
|
|
33
|
-
appUrl.isPreview // boolean
|
|
34
|
-
appUrl.isLocal // boolean
|
|
30
|
+
appUrl.origin // "https://myapp.com"
|
|
31
|
+
appUrl.hostname // "myapp.com"
|
|
32
|
+
appUrl.protocol // "https:"
|
|
33
|
+
appUrl.env // "production"
|
|
34
|
+
appUrl.platform // "vercel"
|
|
35
|
+
appUrl.isProduction // true
|
|
35
36
|
```
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
## The problem
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
Your app's base URL shows up everywhere — OAuth callbacks, API calls, CORS, emails. Every one of these breaks if the URL is wrong:
|
|
40
41
|
|
|
41
42
|
```typescript
|
|
42
|
-
|
|
43
|
+
// Auth — needs the exact URL for OAuth redirects
|
|
44
|
+
auth({ baseURL: ??? })
|
|
43
45
|
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
fetch(`${href}/api/data`)
|
|
47
|
-
cookie.domain = hostname
|
|
46
|
+
// API calls from the client
|
|
47
|
+
fetch(`${???}/api/data`)
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
// Emails — links need to point somewhere real
|
|
50
|
+
`Click here to verify: ${???}/verify?token=${token}`
|
|
51
|
+
|
|
52
|
+
// CORS — needs to know its own origin
|
|
53
|
+
cors({ origin: ??? })
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Most teams end up with a helper that grows over time:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// lib/url.ts — every team has one of these
|
|
60
|
+
function getBaseUrl() {
|
|
61
|
+
if (typeof window !== 'undefined') return ''
|
|
62
|
+
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`
|
|
63
|
+
return `http://localhost:${process.env.PORT ?? 3000}`
|
|
51
64
|
}
|
|
65
|
+
|
|
66
|
+
// But wait — VERCEL_URL is the deployment URL, not your domain.
|
|
67
|
+
// And it doesn't work on the client. So you add more:
|
|
68
|
+
const baseUrl =
|
|
69
|
+
process.env.NEXT_PUBLIC_VERCEL_ENV === 'production'
|
|
70
|
+
? `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`
|
|
71
|
+
: process.env.NEXT_PUBLIC_VERCEL_URL
|
|
72
|
+
? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}`
|
|
73
|
+
: `http://localhost:${process.env.PORT ?? 3000}`
|
|
74
|
+
|
|
75
|
+
// And then Netlify uses different env vars. And Cloudflare uses different ones.
|
|
76
|
+
// And someone forgets the https://. And preview URLs break in production...
|
|
52
77
|
```
|
|
53
78
|
|
|
54
79
|
## How it works
|
|
55
80
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
**Resolution priority:**
|
|
81
|
+
Reads environment variables that hosting providers set automatically:
|
|
59
82
|
|
|
60
83
|
1. `APP_URL` env var (your override — always wins)
|
|
61
|
-
2. Provider auto-detection
|
|
62
|
-
3. `window.location.origin` (browser)
|
|
63
|
-
4. `http://localhost:${PORT || 3000}` (development)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
## Provider support
|
|
67
|
-
|
|
68
|
-
| Provider | Detection | URL source |
|
|
69
|
-
|----------|-----------|------------|
|
|
70
|
-
| **Vercel** | `VERCEL` | `VERCEL_PROJECT_PRODUCTION_URL` / `VERCEL_BRANCH_URL` / `VERCEL_URL` |
|
|
71
|
-
| **Netlify** | `NETLIFY` | `URL` / `DEPLOY_PRIME_URL` / `DEPLOY_URL` |
|
|
72
|
-
| **Cloudflare Pages** | `CF_PAGES` | `CF_PAGES_URL` |
|
|
73
|
-
| **Railway** | `RAILWAY_PUBLIC_DOMAIN` | `RAILWAY_PUBLIC_DOMAIN` |
|
|
74
|
-
| **Fly.io** | `FLY_APP_NAME` | `{app}.fly.dev` |
|
|
75
|
-
| **Render** | `RENDER` | `RENDER_EXTERNAL_URL` |
|
|
76
|
-
| **DigitalOcean** | `DIGITALOCEAN_APP_PLATFORM` | `APP_URL` |
|
|
77
|
-
| **Heroku** | `HEROKU_APP_NAME` | `{app}.herokuapp.com` |
|
|
84
|
+
2. Provider auto-detection (Vercel, Netlify, etc.)
|
|
85
|
+
3. `window.location.origin` (browser fallback)
|
|
86
|
+
4. `http://localhost:${PORT || 3000}` (development fallback)
|
|
87
|
+
|
|
88
|
+
If nothing is detected in production, the singleton logs a warning and returns empty strings. Call `createUrl()` directly if you want it to throw instead.
|
|
78
89
|
|
|
79
90
|
## Override with `APP_URL`
|
|
80
91
|
|
|
81
|
-
Set `APP_URL`
|
|
92
|
+
Set `APP_URL` when auto-detection isn't enough — custom domains, tunnels, or unsupported providers:
|
|
82
93
|
|
|
83
94
|
```bash
|
|
84
95
|
# .env.local
|
|
85
96
|
APP_URL=https://myapp.com
|
|
86
97
|
```
|
|
87
98
|
|
|
88
|
-
|
|
99
|
+
Works with or without protocol (`APP_URL=myapp.com` → `https://myapp.com`).
|
|
89
100
|
|
|
90
|
-
|
|
101
|
+
**Client-side frameworks:** All framework prefixes are supported automatically — `NEXT_PUBLIC_APP_URL`, `VITE_APP_URL`, `PUBLIC_APP_URL`, `NUXT_ENV_APP_URL`, etc.
|
|
91
102
|
|
|
92
|
-
|
|
103
|
+
## Platform support
|
|
93
104
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
105
|
+
| Platform | Detection | URL source | Verified |
|
|
106
|
+
|----------|-----------|------------|:--------:|
|
|
107
|
+
| **Vercel** | `VERCEL` | `VERCEL_PROJECT_PRODUCTION_URL` / `VERCEL_BRANCH_URL` / `VERCEL_URL` | [x] |
|
|
108
|
+
| **Netlify** | `NETLIFY` | `URL` / `DEPLOY_PRIME_URL` / `DEPLOY_URL` | [ ] |
|
|
109
|
+
| **Cloudflare Pages** | `CF_PAGES` | `CF_PAGES_URL` | [ ] |
|
|
110
|
+
| **Railway** | `RAILWAY_PUBLIC_DOMAIN` | `RAILWAY_PUBLIC_DOMAIN` | [ ] |
|
|
111
|
+
| **Fly.io** | `FLY_APP_NAME` | `{app}.fly.dev` | [ ] |
|
|
112
|
+
| **Render** | `RENDER` | `RENDER_EXTERNAL_URL` | [ ] |
|
|
113
|
+
| **DigitalOcean** | `DIGITALOCEAN_APP_PLATFORM` | `APP_URL` | [ ] |
|
|
114
|
+
| **Heroku** | `HEROKU_APP_NAME` | `{app}.herokuapp.com` | [ ] |
|
|
97
115
|
|
|
98
|
-
|
|
99
|
-
APP_URL=http://myapp.local:3000
|
|
116
|
+
On the client, Vercel's framework-prefixed env vars (`NEXT_PUBLIC_VERCEL_URL`, `VITE_VERCEL_URL`, etc.) are detected automatically.
|
|
100
117
|
|
|
101
|
-
|
|
102
|
-
APP_URL=https://localhost:3000
|
|
118
|
+
**Help us verify:** If you're using one of these providers, [open an issue](https://github.com/manishrc/which-url/issues) with the output of `import appUrl from 'which-url'; console.log(appUrl)` from your deployment. We'll mark it as verified.
|
|
103
119
|
|
|
104
|
-
|
|
105
|
-
APP_URL=https://abc123.ngrok-free.app
|
|
106
|
-
```
|
|
120
|
+
## Examples
|
|
107
121
|
|
|
108
|
-
|
|
122
|
+
```typescript
|
|
123
|
+
import { origin, hostname, isProduction } from 'which-url'
|
|
109
124
|
|
|
110
|
-
|
|
111
|
-
|
|
125
|
+
// Better Auth
|
|
126
|
+
betterAuth({ baseURL: origin })
|
|
127
|
+
|
|
128
|
+
// API calls
|
|
129
|
+
fetch(`${origin}/api/data`)
|
|
130
|
+
|
|
131
|
+
// CORS
|
|
132
|
+
cors({ origin })
|
|
133
|
+
|
|
134
|
+
// Cookies
|
|
135
|
+
cookie.domain = hostname
|
|
136
|
+
|
|
137
|
+
// Environment checks
|
|
138
|
+
if (isProduction) {
|
|
139
|
+
enableAnalytics()
|
|
140
|
+
}
|
|
112
141
|
```
|
|
113
142
|
|
|
114
|
-
##
|
|
143
|
+
## Gotchas
|
|
115
144
|
|
|
116
|
-
|
|
145
|
+
### Vercel: Redeploy after assigning a custom domain
|
|
117
146
|
|
|
118
|
-
|
|
147
|
+
Framework-prefixed env vars like `NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL` are inlined into the bundle at **build time** — the bundler replaces references with their literal values. If you assign a custom domain after deploying, the old deployment still has the previous URL baked in. Trigger a new deployment for the updated domain to take effect.
|
|
119
148
|
|
|
120
|
-
|
|
121
|
-
import { createUrl } from 'which-url'
|
|
149
|
+
## Advanced
|
|
122
150
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
151
|
+
### Tunnels (ngrok, Cloudflare Tunnel)
|
|
152
|
+
|
|
153
|
+
Tunnel URLs can't be auto-detected — they're external to the app process. Set `APP_URL`:
|
|
126
154
|
|
|
127
|
-
|
|
155
|
+
```bash
|
|
156
|
+
APP_URL=https://abc123.ngrok-free.app npm run dev
|
|
157
|
+
```
|
|
128
158
|
|
|
129
|
-
|
|
159
|
+
### Cloudflare Workers
|
|
130
160
|
|
|
131
161
|
Cloudflare Workers use runtime `env` bindings instead of `process.env`. Set `APP_URL` in `wrangler.toml`:
|
|
132
162
|
|
|
@@ -135,29 +165,17 @@ Cloudflare Workers use runtime `env` bindings instead of `process.env`. Set `APP
|
|
|
135
165
|
APP_URL = "https://myapp.workers.dev"
|
|
136
166
|
```
|
|
137
167
|
|
|
138
|
-
Modern wrangler polyfills `process.env` from `[vars]`, so `which-url` picks it up automatically.
|
|
139
|
-
|
|
140
|
-
## Integrations
|
|
141
|
-
|
|
142
|
-
### Better Auth
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
import appUrl from 'which-url'
|
|
146
|
-
import { betterAuth } from 'better-auth'
|
|
168
|
+
Modern wrangler polyfills `process.env` from `[vars]`, so `which-url` picks it up automatically.
|
|
147
169
|
|
|
148
|
-
|
|
149
|
-
baseURL: appUrl.href,
|
|
150
|
-
// ...
|
|
151
|
-
})
|
|
152
|
-
```
|
|
170
|
+
### `createUrl(options?)`
|
|
153
171
|
|
|
154
|
-
|
|
172
|
+
Re-resolves the URL from the current environment. Unlike the singleton (which catches errors), `createUrl()` throws in production if no URL is detected.
|
|
155
173
|
|
|
156
174
|
```typescript
|
|
157
|
-
import
|
|
175
|
+
import { createUrl } from 'which-url'
|
|
158
176
|
|
|
159
|
-
|
|
160
|
-
|
|
177
|
+
const url = createUrl({ fallback: 'https://fallback.example.com' })
|
|
178
|
+
url.origin // never throws
|
|
161
179
|
```
|
|
162
180
|
|
|
163
181
|
## API
|
|
@@ -168,30 +186,19 @@ An object with URL properties and environment helpers.
|
|
|
168
186
|
|
|
169
187
|
### Named exports
|
|
170
188
|
|
|
171
|
-
| Export | Type |
|
|
172
|
-
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
176
|
-
| `
|
|
177
|
-
| `protocol` | `string` |
|
|
178
|
-
| `port` | `string` |
|
|
189
|
+
| Export | Type | Example |
|
|
190
|
+
|--------|------|---------|
|
|
191
|
+
| `origin` | `string` | `"https://myapp.vercel.app"` |
|
|
192
|
+
| `hostname` | `string` | `"myapp.vercel.app"` |
|
|
193
|
+
| `host` | `string` | `"myapp.vercel.app"` or `"localhost:3000"` |
|
|
194
|
+
| `href` | `string` | Same as `origin` |
|
|
195
|
+
| `protocol` | `string` | `"https:"` |
|
|
196
|
+
| `port` | `string` | `""` or `"3000"` |
|
|
179
197
|
| `env` | `AppEnv` | `"production"` \| `"preview"` \| `"local"` |
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
| `
|
|
184
|
-
|
|
185
|
-
### `createUrl(options?)`
|
|
186
|
-
|
|
187
|
-
```typescript
|
|
188
|
-
createUrl({ fallback?: string }): WhichUrl
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Re-resolves the URL from current environment. Use for:
|
|
192
|
-
- Custom fallbacks (never throws)
|
|
193
|
-
- Re-resolution in tests
|
|
194
|
-
- Dynamic configuration
|
|
198
|
+
| `platform` | `Platform` | `"vercel"` \| `"netlify"` \| ... \| `null` |
|
|
199
|
+
| `isProduction` | `boolean` | |
|
|
200
|
+
| `isPreview` | `boolean` | |
|
|
201
|
+
| `isLocal` | `boolean` | |
|
|
195
202
|
|
|
196
203
|
## License
|
|
197
204
|
|
package/dist/env-var.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
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
|
+
*/
|
|
1
9
|
export declare function getVar(env: Record<string, string | undefined>, name: string): string | undefined;
|
|
2
10
|
export declare function getEnv(): Record<string, string | undefined>;
|
|
3
11
|
//# sourceMappingURL=env-var.d.ts.map
|
package/dist/env-var.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env-var.d.ts","sourceRoot":"","sources":["../src/env-var.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"env-var.d.ts","sourceRoot":"","sources":["../src/env-var.ts"],"names":[],"mappings":"AAgGA;;;;;;;GAOG;AACH,wBAAgB,MAAM,CACpB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CA0BpB;AAED,wBAAgB,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAK3D"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WhichUrl, AppEnv, CreateUrlOptions } from "./types";
|
|
1
|
+
import type { WhichUrl, AppEnv, Platform, CreateUrlOptions } from "./types";
|
|
2
2
|
export declare function createUrl(options?: CreateUrlOptions): WhichUrl;
|
|
3
3
|
declare let _resolved: WhichUrl;
|
|
4
4
|
export declare const href: string;
|
|
@@ -8,9 +8,10 @@ export declare const host: string;
|
|
|
8
8
|
export declare const protocol: string;
|
|
9
9
|
export declare const port: string;
|
|
10
10
|
export declare const env: AppEnv;
|
|
11
|
+
export declare const platform: Platform;
|
|
11
12
|
export declare const isProduction: boolean;
|
|
12
13
|
export declare const isPreview: boolean;
|
|
13
14
|
export declare const isLocal: boolean;
|
|
14
15
|
export default _resolved;
|
|
15
|
-
export type { WhichUrl, AppEnv, CreateUrlOptions };
|
|
16
|
+
export type { WhichUrl, AppEnv, Platform, CreateUrlOptions };
|
|
16
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE3E,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,QAAQ,CAkB9D;AAGD,QAAA,IAAI,SAAS,EAAE,QAAQ,CAAA;AAuBvB,eAAO,MAAM,IAAI,EAAE,MAAuB,CAAA;AAC1C,eAAO,MAAM,MAAM,EAAE,MAAyB,CAAA;AAC9C,eAAO,MAAM,QAAQ,EAAE,MAA2B,CAAA;AAClD,eAAO,MAAM,IAAI,EAAE,MAAuB,CAAA;AAC1C,eAAO,MAAM,QAAQ,EAAE,MAA2B,CAAA;AAClD,eAAO,MAAM,IAAI,EAAE,MAAuB,CAAA;AAC1C,eAAO,MAAM,GAAG,EAAE,MAAsB,CAAA;AACxC,eAAO,MAAM,QAAQ,EAAE,QAA6B,CAAA;AACpD,eAAO,MAAM,YAAY,EAAE,OAAgC,CAAA;AAC3D,eAAO,MAAM,SAAS,EAAE,OAA6B,CAAA;AACrD,eAAO,MAAM,OAAO,EAAE,OAA2B,CAAA;AAGjD,eAAe,SAAS,CAAA;AAExB,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,39 @@
|
|
|
1
1
|
// src/env-var.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
function readStatic(name) {
|
|
3
|
+
switch (name) {
|
|
4
|
+
case "VERCEL_ENV":
|
|
5
|
+
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;
|
|
6
|
+
case "VERCEL_URL":
|
|
7
|
+
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;
|
|
8
|
+
case "VERCEL_BRANCH_URL":
|
|
9
|
+
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;
|
|
10
|
+
case "VERCEL_PROJECT_PRODUCTION_URL":
|
|
11
|
+
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;
|
|
12
|
+
case "APP_URL":
|
|
13
|
+
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;
|
|
14
|
+
case "APP_ENV":
|
|
15
|
+
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;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
14
18
|
function getVar(env, name) {
|
|
15
|
-
|
|
19
|
+
if (typeof process !== "undefined" && process?.env && env === process.env) {
|
|
20
|
+
const val = readStatic(name);
|
|
21
|
+
if (val)
|
|
22
|
+
return val;
|
|
23
|
+
}
|
|
24
|
+
const PREFIXES = [
|
|
25
|
+
"",
|
|
26
|
+
"NEXT_PUBLIC_",
|
|
27
|
+
"NUXT_ENV_",
|
|
28
|
+
"VITE_",
|
|
29
|
+
"PUBLIC_",
|
|
30
|
+
"REACT_APP_",
|
|
31
|
+
"GATSBY_",
|
|
32
|
+
"VUE_APP_",
|
|
33
|
+
"REDWOOD_ENV_",
|
|
34
|
+
"SANITY_STUDIO_"
|
|
35
|
+
];
|
|
36
|
+
for (const prefix of PREFIXES) {
|
|
16
37
|
const val = env[prefix + name];
|
|
17
38
|
if (val)
|
|
18
39
|
return val;
|
|
@@ -148,6 +169,15 @@ function resolveUrl(options) {
|
|
|
148
169
|
}
|
|
149
170
|
throw new Error("which-url: Cannot detect app URL. Set APP_URL environment variable.");
|
|
150
171
|
}
|
|
172
|
+
function resolvePlatform() {
|
|
173
|
+
const env = getEnv();
|
|
174
|
+
for (const p of providers) {
|
|
175
|
+
if (p.detect(env)) {
|
|
176
|
+
return p.name;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
151
181
|
|
|
152
182
|
// src/env.ts
|
|
153
183
|
var validEnvs = ["production", "preview", "local"];
|
|
@@ -174,6 +204,7 @@ function createUrl(options) {
|
|
|
174
204
|
const resolved = resolveUrl(options);
|
|
175
205
|
const parsed = new URL(resolved);
|
|
176
206
|
const env = resolveEnv();
|
|
207
|
+
const platform = resolvePlatform();
|
|
177
208
|
return {
|
|
178
209
|
href: parsed.origin,
|
|
179
210
|
origin: parsed.origin,
|
|
@@ -182,6 +213,7 @@ function createUrl(options) {
|
|
|
182
213
|
protocol: parsed.protocol,
|
|
183
214
|
port: parsed.port,
|
|
184
215
|
env,
|
|
216
|
+
platform,
|
|
185
217
|
isProduction: env === "production",
|
|
186
218
|
isPreview: env === "preview",
|
|
187
219
|
isLocal: env === "local"
|
|
@@ -200,6 +232,7 @@ try {
|
|
|
200
232
|
protocol: "",
|
|
201
233
|
port: "",
|
|
202
234
|
env: "local",
|
|
235
|
+
platform: null,
|
|
203
236
|
isProduction: false,
|
|
204
237
|
isPreview: false,
|
|
205
238
|
isLocal: true
|
|
@@ -212,6 +245,7 @@ var host = _resolved.host;
|
|
|
212
245
|
var protocol = _resolved.protocol;
|
|
213
246
|
var port = _resolved.port;
|
|
214
247
|
var env = _resolved.env;
|
|
248
|
+
var platform = _resolved.platform;
|
|
215
249
|
var isProduction = _resolved.isProduction;
|
|
216
250
|
var isPreview = _resolved.isPreview;
|
|
217
251
|
var isLocal = _resolved.isLocal;
|
|
@@ -219,6 +253,7 @@ var src_default = _resolved;
|
|
|
219
253
|
export {
|
|
220
254
|
protocol,
|
|
221
255
|
port,
|
|
256
|
+
platform,
|
|
222
257
|
origin,
|
|
223
258
|
isProduction,
|
|
224
259
|
isPreview,
|
package/dist/resolve.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import type { CreateUrlOptions } from "./types";
|
|
1
|
+
import type { CreateUrlOptions, Platform } from "./types";
|
|
2
2
|
export declare function resolveUrl(options?: CreateUrlOptions): string;
|
|
3
|
+
export declare function resolvePlatform(): Platform;
|
|
3
4
|
//# sourceMappingURL=resolve.d.ts.map
|
package/dist/resolve.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEzD,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAoC7D;AAED,wBAAgB,eAAe,IAAI,QAAQ,CAQ1C"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type AppEnv = "production" | "preview" | "local";
|
|
2
|
+
export type Platform = "vercel" | "netlify" | "cloudflare" | "railway" | "fly" | "render" | "digitalocean" | "heroku" | null;
|
|
2
3
|
export interface WhichUrl {
|
|
3
4
|
href: string;
|
|
4
5
|
origin: string;
|
|
@@ -7,6 +8,7 @@ export interface WhichUrl {
|
|
|
7
8
|
protocol: string;
|
|
8
9
|
port: string;
|
|
9
10
|
env: AppEnv;
|
|
11
|
+
platform: Platform;
|
|
10
12
|
isProduction: boolean;
|
|
11
13
|
isPreview: boolean;
|
|
12
14
|
isLocal: boolean;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,OAAO,CAAA;IACrB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,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"}
|
|
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,QAAQ,GAChB,QAAQ,GACR,SAAS,GACT,YAAY,GACZ,SAAS,GACT,KAAK,GACL,QAAQ,GACR,cAAc,GACd,QAAQ,GACR,IAAI,CAAA;AAER,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,QAAQ,CAAA;IAClB,YAAY,EAAE,OAAO,CAAA;IACrB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,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"}
|