which-url 0.0.7 → 0.0.9
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 +55 -8
- package/dist/index.d.ts +5 -2
- package/dist/index.js +1 -297
- package/dist/types.d.ts +12 -0
- 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
|
@@ -20,7 +20,7 @@ Preview https://myapp-git-feat.vercel.app "preview"
|
|
|
20
20
|
Production https://myapp.com "production"
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
Works across environments (local, preview, production),
|
|
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
25
|
The default export gives you everything as an object:
|
|
26
26
|
|
|
@@ -85,7 +85,31 @@ Reads environment variables that hosting providers set automatically:
|
|
|
85
85
|
3. `window.location.origin` (browser fallback)
|
|
86
86
|
4. `http://localhost:${PORT || 3000}` (development fallback)
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
When you call `createUrl({ env })`, the passed object replaces `process.env` as the source for steps 1–2.
|
|
89
|
+
|
|
90
|
+
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
|
+
|
|
92
|
+
## Strict mode with `createUrl()`
|
|
93
|
+
|
|
94
|
+
Use the default export or named constants for convenience:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { origin } from 'which-url'
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Use `createUrl()` for production-critical configuration like auth, CORS, emails, and webhooks:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { createUrl } from 'which-url'
|
|
104
|
+
|
|
105
|
+
const appUrl = createUrl()
|
|
106
|
+
|
|
107
|
+
auth({ baseURL: appUrl.origin })
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`createUrl()` resolves fresh environment values when called. If no URL can be detected in production, it throws with instructions to set `APP_URL`.
|
|
111
|
+
|
|
112
|
+
For runtimes that pass env as an argument (e.g. Cloudflare Workers), call `createUrl({ env })` and the passed object replaces `process.env` for that resolution. See [Cloudflare Workers](#cloudflare-workers) below.
|
|
89
113
|
|
|
90
114
|
## Override with `APP_URL`
|
|
91
115
|
|
|
@@ -172,14 +196,32 @@ APP_URL=https://abc123.ngrok-free.app npm run dev
|
|
|
172
196
|
|
|
173
197
|
### Cloudflare Workers
|
|
174
198
|
|
|
175
|
-
Cloudflare Workers
|
|
199
|
+
Cloudflare Workers pass config through the `env` argument to `fetch`, not `process.env`. Pass it to `createUrl({ env })`:
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { createUrl } from "which-url"
|
|
203
|
+
|
|
204
|
+
export default {
|
|
205
|
+
async fetch(request: Request, env: Env) {
|
|
206
|
+
const appUrl = createUrl({ env })
|
|
207
|
+
|
|
208
|
+
return Response.json({ origin: appUrl.origin, env: appUrl.env })
|
|
209
|
+
},
|
|
210
|
+
}
|
|
211
|
+
```
|
|
176
212
|
|
|
177
213
|
```toml
|
|
214
|
+
# wrangler.toml
|
|
178
215
|
[vars]
|
|
179
|
-
APP_URL = "https://
|
|
216
|
+
APP_URL = "https://api.example.com"
|
|
217
|
+
APP_ENV = "production"
|
|
180
218
|
```
|
|
181
219
|
|
|
182
|
-
|
|
220
|
+
Non-string bindings (KV, Durable Objects, R2, service bindings) are ignored automatically — only string `[vars]` participate in URL detection.
|
|
221
|
+
|
|
222
|
+
> ⚠️ The default singleton (`import appUrl from "which-url"`) and named exports (`origin`, `env`, etc.) resolve at **module load**, before your `fetch` handler runs. On Workers they will not see your `[vars]`. Use `createUrl({ env })` from inside your handler.
|
|
223
|
+
|
|
224
|
+
If you're on `nodejs_compat` and prefer `process.env`, the default singleton works too — but `createUrl({ env })` is the runtime-native path and doesn't require the compat flag.
|
|
183
225
|
|
|
184
226
|
### Debugging
|
|
185
227
|
|
|
@@ -197,7 +239,11 @@ console.log(appUrl.debug)
|
|
|
197
239
|
|
|
198
240
|
### Default export
|
|
199
241
|
|
|
200
|
-
An object with URL properties and environment helpers.
|
|
242
|
+
An import-safe singleton object with URL properties and environment helpers. It resolves once when the package is imported.
|
|
243
|
+
|
|
244
|
+
### `createUrl()`
|
|
245
|
+
|
|
246
|
+
Strict resolver function. It resolves when called and throws if no URL can be detected.
|
|
201
247
|
|
|
202
248
|
### Named exports
|
|
203
249
|
|
|
@@ -212,11 +258,12 @@ An object with URL properties and environment helpers.
|
|
|
212
258
|
| `env` | `AppEnv` | `"production"` \| `"preview"` \| `"local"` |
|
|
213
259
|
| `platform` | `Platform` | `"vercel"` \| `"netlify"` \| ... \| `null` |
|
|
214
260
|
| `debug`* | `string` | `"[provider:vercel] url=myapp.com \| env=production (vercel:production)"` |
|
|
215
|
-
|
|
216
|
-
\* `debug` is non-enumerable — excluded from `JSON.stringify` to avoid React hydration mismatches. Access via `appUrl.debug`.
|
|
217
261
|
| `isProduction` | `boolean` | |
|
|
218
262
|
| `isPreview` | `boolean` | |
|
|
219
263
|
| `isLocal` | `boolean` | |
|
|
264
|
+
| `createUrl` | `(options?: { env?: object }) => WhichUrlWithDebug` | strict resolver |
|
|
265
|
+
|
|
266
|
+
\* `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.
|
|
220
267
|
|
|
221
268
|
## License
|
|
222
269
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { WhichUrlWithDebug, AppEnv, Platform } from "./types";
|
|
1
|
+
import type { WhichUrlWithDebug, AppEnv, Platform, CreateUrlOptions } from "./types";
|
|
2
|
+
export declare function createUrl(options?: CreateUrlOptions): WhichUrlWithDebug;
|
|
2
3
|
declare let _resolved: WhichUrlWithDebug;
|
|
3
4
|
/** Full URL including protocol — `"https://myapp.com"` */
|
|
4
5
|
export declare const href: string;
|
|
@@ -16,6 +17,8 @@ export declare const port: string;
|
|
|
16
17
|
export declare const env: AppEnv;
|
|
17
18
|
/** Detected hosting platform — `"vercel"`, `"netlify"`, etc. or `null` */
|
|
18
19
|
export declare const platform: Platform;
|
|
20
|
+
/** Resolution debug string. */
|
|
21
|
+
export declare const debug: string;
|
|
19
22
|
/** `true` when running in production */
|
|
20
23
|
export declare const isProduction: boolean;
|
|
21
24
|
/** `true` when running in a preview/staging deployment */
|
|
@@ -36,5 +39,5 @@ export declare const isLocal: boolean;
|
|
|
36
39
|
* ```
|
|
37
40
|
*/
|
|
38
41
|
export default _resolved;
|
|
39
|
-
export type { WhichUrl, WhichUrlWithDebug, AppEnv, Platform, PlatformName } from "./types";
|
|
42
|
+
export type { WhichUrl, WhichUrlWithDebug, AppEnv, Platform, PlatformName, CreateUrlOptions } from "./types";
|
|
40
43
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,297 +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() {
|
|
56
|
-
if (typeof process !== "undefined" && process?.env) {
|
|
57
|
-
return process.env;
|
|
58
|
-
}
|
|
59
|
-
return {};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// src/providers.ts
|
|
63
|
-
var providers = [
|
|
64
|
-
{
|
|
65
|
-
name: "vercel",
|
|
66
|
-
detect: (env) => !!env.VERCEL || !!getVar(env, "VERCEL_ENV"),
|
|
67
|
-
resolveUrl: (env) => {
|
|
68
|
-
const vercelEnv = getVar(env, "VERCEL_ENV");
|
|
69
|
-
if (vercelEnv === "production") {
|
|
70
|
-
return getVar(env, "VERCEL_PROJECT_PRODUCTION_URL") || getVar(env, "VERCEL_URL") || null;
|
|
71
|
-
}
|
|
72
|
-
return getVar(env, "VERCEL_BRANCH_URL") || getVar(env, "VERCEL_URL") || null;
|
|
73
|
-
},
|
|
74
|
-
resolveEnv: (env) => {
|
|
75
|
-
const vercelEnv = getVar(env, "VERCEL_ENV");
|
|
76
|
-
if (vercelEnv === "production")
|
|
77
|
-
return "production";
|
|
78
|
-
if (vercelEnv === "preview")
|
|
79
|
-
return "preview";
|
|
80
|
-
return "local";
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
name: "netlify",
|
|
85
|
-
detect: (env) => !!env.NETLIFY,
|
|
86
|
-
resolveUrl: (env) => {
|
|
87
|
-
if (env.CONTEXT === "production")
|
|
88
|
-
return env.URL || null;
|
|
89
|
-
return env.DEPLOY_PRIME_URL || env.DEPLOY_URL || null;
|
|
90
|
-
},
|
|
91
|
-
resolveEnv: (env) => {
|
|
92
|
-
if (env.CONTEXT === "production")
|
|
93
|
-
return "production";
|
|
94
|
-
if (env.CONTEXT === "deploy-preview" || env.CONTEXT === "branch-deploy")
|
|
95
|
-
return "preview";
|
|
96
|
-
return "local";
|
|
97
|
-
}
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
name: "cloudflare",
|
|
101
|
-
detect: (env) => !!env.CF_PAGES,
|
|
102
|
-
resolveUrl: (env) => env.CF_PAGES_URL || null,
|
|
103
|
-
resolveEnv: (env) => {
|
|
104
|
-
if (env.CF_PAGES_BRANCH === "main" || env.CF_PAGES_BRANCH === "master")
|
|
105
|
-
return "production";
|
|
106
|
-
return "preview";
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
name: "railway",
|
|
111
|
-
detect: (env) => !!env.RAILWAY_PUBLIC_DOMAIN,
|
|
112
|
-
resolveUrl: (env) => env.RAILWAY_PUBLIC_DOMAIN || null,
|
|
113
|
-
resolveEnv: (env) => {
|
|
114
|
-
if (env.RAILWAY_ENVIRONMENT === "production")
|
|
115
|
-
return "production";
|
|
116
|
-
return "production";
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
name: "fly",
|
|
121
|
-
detect: (env) => !!env.FLY_APP_NAME,
|
|
122
|
-
resolveUrl: (env) => env.FLY_APP_NAME ? `${env.FLY_APP_NAME}.fly.dev` : null,
|
|
123
|
-
resolveEnv: () => "production"
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: "render",
|
|
127
|
-
detect: (env) => !!env.RENDER,
|
|
128
|
-
resolveUrl: (env) => env.RENDER_EXTERNAL_URL || null,
|
|
129
|
-
resolveEnv: (env) => {
|
|
130
|
-
if (env.IS_PULL_REQUEST === "true")
|
|
131
|
-
return "preview";
|
|
132
|
-
return "production";
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
name: "digitalocean",
|
|
137
|
-
detect: (env) => !!env.DIGITALOCEAN_APP_PLATFORM,
|
|
138
|
-
resolveUrl: (env) => env.APP_URL || null,
|
|
139
|
-
resolveEnv: () => "production"
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
name: "heroku",
|
|
143
|
-
detect: (env) => !!env.HEROKU_APP_NAME,
|
|
144
|
-
resolveUrl: (env) => env.HEROKU_APP_NAME ? `${env.HEROKU_APP_NAME}.herokuapp.com` : null,
|
|
145
|
-
resolveEnv: () => "production"
|
|
146
|
-
}
|
|
147
|
-
];
|
|
148
|
-
|
|
149
|
-
// src/normalize.ts
|
|
150
|
-
function normalizeUrl(raw) {
|
|
151
|
-
let url = raw.trim().replace(/\/+$/, "");
|
|
152
|
-
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
153
|
-
return url;
|
|
154
|
-
}
|
|
155
|
-
return `https://${url}`;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// src/resolve.ts
|
|
159
|
-
function resolveUrl() {
|
|
160
|
-
const env = getEnv();
|
|
161
|
-
const override = getVar(env, "APP_URL");
|
|
162
|
-
if (override)
|
|
163
|
-
return { url: normalizeUrl(override), debugLabel: `[override] APP_URL=${override}` };
|
|
164
|
-
if (env.PORTLESS_TAILSCALE_URL) {
|
|
165
|
-
return { url: env.PORTLESS_TAILSCALE_URL, debugLabel: `[portless:tailscale] PORTLESS_TAILSCALE_URL=${env.PORTLESS_TAILSCALE_URL}` };
|
|
166
|
-
}
|
|
167
|
-
if (env.PORTLESS_URL) {
|
|
168
|
-
return { url: env.PORTLESS_URL, debugLabel: `[portless] PORTLESS_URL=${env.PORTLESS_URL}` };
|
|
169
|
-
}
|
|
170
|
-
for (const p of providers) {
|
|
171
|
-
if (p.detect(env)) {
|
|
172
|
-
const url = p.resolveUrl(env);
|
|
173
|
-
if (url)
|
|
174
|
-
return { url: normalizeUrl(url), debugLabel: `[provider:${p.name}] url=${url}` };
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if (typeof window !== "undefined" && window.location) {
|
|
178
|
-
return { url: window.location.origin, debugLabel: `[browser] window.location.origin` };
|
|
179
|
-
}
|
|
180
|
-
const isProduction = env.NODE_ENV === "production";
|
|
181
|
-
if (!isProduction) {
|
|
182
|
-
const port = env.PORT || "3000";
|
|
183
|
-
return { url: `http://localhost:${port}`, debugLabel: `[fallback] PORT=${port}` };
|
|
184
|
-
}
|
|
185
|
-
throw new Error("which-url: Cannot detect app URL. Set APP_URL environment variable.");
|
|
186
|
-
}
|
|
187
|
-
function resolvePlatform() {
|
|
188
|
-
const env = getEnv();
|
|
189
|
-
for (const p of providers) {
|
|
190
|
-
if (p.detect(env)) {
|
|
191
|
-
return p.name;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return null;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// src/env.ts
|
|
198
|
-
var validEnvs = ["production", "preview", "local"];
|
|
199
|
-
function resolveEnv() {
|
|
200
|
-
const env = getEnv();
|
|
201
|
-
const appEnv = getVar(env, "APP_ENV");
|
|
202
|
-
if (appEnv && validEnvs.includes(appEnv)) {
|
|
203
|
-
return { env: appEnv, debugLabel: `APP_ENV=${appEnv}` };
|
|
204
|
-
}
|
|
205
|
-
if (env.NODE_ENV === "development")
|
|
206
|
-
return { env: "local", debugLabel: "NODE_ENV=development" };
|
|
207
|
-
for (const p of providers) {
|
|
208
|
-
if (p.detect(env)) {
|
|
209
|
-
const resolved = p.resolveEnv(env);
|
|
210
|
-
return { env: resolved, debugLabel: `${p.name}:${resolved}` };
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
if (env.NODE_ENV === "production")
|
|
214
|
-
return { env: "production", debugLabel: "NODE_ENV=production" };
|
|
215
|
-
return { env: "local", debugLabel: "default" };
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// src/index.ts
|
|
219
|
-
function resolve() {
|
|
220
|
-
const { url, debugLabel: urlDebug } = resolveUrl();
|
|
221
|
-
const parsed = new URL(url);
|
|
222
|
-
const { env, debugLabel: envDebug } = resolveEnv();
|
|
223
|
-
const platform = resolvePlatform();
|
|
224
|
-
const debug = `${urlDebug} | env=${env} (${envDebug})`;
|
|
225
|
-
const result = {
|
|
226
|
-
href: parsed.origin,
|
|
227
|
-
origin: parsed.origin,
|
|
228
|
-
hostname: parsed.hostname,
|
|
229
|
-
host: parsed.host,
|
|
230
|
-
protocol: parsed.protocol,
|
|
231
|
-
port: parsed.port,
|
|
232
|
-
env,
|
|
233
|
-
platform,
|
|
234
|
-
debug,
|
|
235
|
-
isProduction: env === "production",
|
|
236
|
-
isPreview: env === "preview",
|
|
237
|
-
isLocal: env === "local"
|
|
238
|
-
};
|
|
239
|
-
Object.defineProperty(result, "debug", {
|
|
240
|
-
value: debug,
|
|
241
|
-
enumerable: false,
|
|
242
|
-
configurable: false
|
|
243
|
-
});
|
|
244
|
-
return result;
|
|
245
|
-
}
|
|
246
|
-
var _resolved;
|
|
247
|
-
try {
|
|
248
|
-
_resolved = resolve();
|
|
249
|
-
} catch (e) {
|
|
250
|
-
console.warn(`[which-url] Could not detect app URL. Set APP_URL (e.g. APP_URL=https://myapp.com or APP_URL=myapp.com)`);
|
|
251
|
-
const fallback = {
|
|
252
|
-
href: "",
|
|
253
|
-
origin: "",
|
|
254
|
-
hostname: "",
|
|
255
|
-
host: "",
|
|
256
|
-
protocol: "",
|
|
257
|
-
port: "",
|
|
258
|
-
env: "local",
|
|
259
|
-
platform: null,
|
|
260
|
-
debug: "[error] resolution failed",
|
|
261
|
-
isProduction: false,
|
|
262
|
-
isPreview: false,
|
|
263
|
-
isLocal: true
|
|
264
|
-
};
|
|
265
|
-
Object.defineProperty(fallback, "debug", {
|
|
266
|
-
value: "[error] resolution failed",
|
|
267
|
-
enumerable: false,
|
|
268
|
-
configurable: false
|
|
269
|
-
});
|
|
270
|
-
_resolved = fallback;
|
|
271
|
-
}
|
|
272
|
-
var href = _resolved.href;
|
|
273
|
-
var origin = _resolved.origin;
|
|
274
|
-
var hostname = _resolved.hostname;
|
|
275
|
-
var host = _resolved.host;
|
|
276
|
-
var protocol = _resolved.protocol;
|
|
277
|
-
var port = _resolved.port;
|
|
278
|
-
var env = _resolved.env;
|
|
279
|
-
var platform = _resolved.platform;
|
|
280
|
-
var isProduction = _resolved.isProduction;
|
|
281
|
-
var isPreview = _resolved.isPreview;
|
|
282
|
-
var isLocal = _resolved.isLocal;
|
|
283
|
-
var src_default = _resolved;
|
|
284
|
-
export {
|
|
285
|
-
protocol,
|
|
286
|
-
port,
|
|
287
|
-
platform,
|
|
288
|
-
origin,
|
|
289
|
-
isProduction,
|
|
290
|
-
isPreview,
|
|
291
|
-
isLocal,
|
|
292
|
-
href,
|
|
293
|
-
hostname,
|
|
294
|
-
host,
|
|
295
|
-
env,
|
|
296
|
-
src_default as default
|
|
297
|
-
};
|
|
1
|
+
var F=["VERCEL_ENV","VERCEL_URL","VERCEL_BRANCH_URL","VERCEL_PROJECT_PRODUCTION_URL","APP_URL","APP_ENV"];function H(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_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,R){if(typeof process<"u"&&process?.env&&E===process.env){if(F.includes(R)){let _=H(R);if(_)return _}}let A=["","NEXT_PUBLIC_","NUXT_ENV_","VITE_","PUBLIC_","REACT_APP_","GATSBY_","VUE_APP_","REDWOOD_ENV_","SANITY_STUDIO_"];for(let _ of A){let L=E[_+R];if(L)return L}return}function N(E){if(E!==void 0)return G(E);if(typeof process<"u"&&process?.env)return process.env;return{}}function G(E){let R={};for(let[A,_]of Object.entries(E))if(typeof _==="string")R[A]=_;return R}var T=[{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},resolveEnv:(E)=>{let R=C(E,"VERCEL_ENV");if(R==="production")return"production";if(R==="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},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,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,resolveEnv:()=>"production"},{name:"render",detect:(E)=>!!E.RENDER,resolveUrl:(E)=>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,resolveEnv:()=>"production"},{name:"heroku",detect:(E)=>!!E.HEROKU_APP_NAME,resolveUrl:(E)=>E.HEROKU_APP_NAME?`${E.HEROKU_APP_NAME}.herokuapp.com`:null,resolveEnv:()=>"production"}];function U(E){let R=E.trim().replace(/\/+$/,"");if(R.startsWith("http://")||R.startsWith("https://"))return R;return`https://${R}`}function Y(E){let R=N(E),A=C(R,"APP_URL");if(A)return{url:U(A),debugLabel:`[override] APP_URL=${A}`};if(R.PORTLESS_TAILSCALE_URL)return{url:R.PORTLESS_TAILSCALE_URL,debugLabel:`[portless:tailscale] PORTLESS_TAILSCALE_URL=${R.PORTLESS_TAILSCALE_URL}`};if(R.PORTLESS_URL)return{url:R.PORTLESS_URL,debugLabel:`[portless] PORTLESS_URL=${R.PORTLESS_URL}`};for(let L of T)if(L.detect(R)){let t=L.resolveUrl(R);if(t)return{url:U(t),debugLabel:`[provider:${L.name}] url=${t}`}}if(typeof window<"u"&&window.location)return{url:window.location.origin,debugLabel:"[browser] window.location.origin"};if(R.NODE_ENV!=="production"){let L=R.PORT||"3000";return{url:`http://localhost:${L}`,debugLabel:`[fallback] PORT=${L}`}}throw Error("which-url: Cannot detect app URL. Set APP_URL environment variable.")}function I(E){let R=N(E);for(let A of T)if(A.detect(R))return A.name;return null}var W=["production","preview","local"];function M(E){let R=N(E),A=C(R,"APP_ENV");if(A&&W.includes(A))return{env:A,debugLabel:`APP_ENV=${A}`};if(R.NODE_ENV==="development")return{env:"local",debugLabel:"NODE_ENV=development"};for(let _ of T)if(_.detect(R)){let L=_.resolveEnv(R);return{env:L,debugLabel:`${_.name}:${L}`}}if(R.NODE_ENV==="production")return{env:"production",debugLabel:"NODE_ENV=production"};return{env:"local",debugLabel:"default"}}function c(E){return Object.defineProperty(E,"debug",{value:E.debug,enumerable:!1,configurable:!1}),E}function B(E){let R=E?.env,{url:A,debugLabel:_}=Y(R),L=new URL(A),{env:t,debugLabel:V}=M(R),u=I(R),O=`${_} | env=${t} (${V})`,f={href:L.origin,origin:L.origin,hostname:L.hostname,host:L.host,protocol:L.protocol,port:L.port,env:t,platform:u,debug:O,isProduction:t==="production",isPreview:t==="preview",isLocal:t==="local"};return c(f)}function X(E){let R=E instanceof Error?E.message:"resolution failed",A="local",_="default";try{let t=M();A=t.env,_=t.debugLabel}catch{}let L={href:"",origin:"",hostname:"",host:"",protocol:"",port:"",env:A,platform:I(),debug:`[error] ${R} | env=${A} (${_})`,isProduction:A==="production",isPreview:A==="preview",isLocal:A==="local"};return c(L)}var P;try{P=B()}catch(E){P=X(E)}var{href:z,origin:i,hostname:k,host:m,protocol:g,port:b,env:p,platform:l,debug:o,isProduction:n,isPreview:d,isLocal:s}=P,a=P;export{g as protocol,b as port,l as platform,i as origin,n as isProduction,d as isPreview,s as isLocal,z as href,k as hostname,m as host,p as env,a as default,o as debug,B as createUrl};
|
package/dist/types.d.ts
CHANGED
|
@@ -29,6 +29,18 @@ export interface WhichUrlWithDebug extends WhichUrl {
|
|
|
29
29
|
/** Resolution debug string (non-enumerable — excluded from JSON.stringify and object spread). */
|
|
30
30
|
readonly debug: string;
|
|
31
31
|
}
|
|
32
|
+
export interface CreateUrlOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Runtime environment source. Pass this when `process.env` isn't available
|
|
35
|
+
* or doesn't contain your config — e.g. on Cloudflare Workers, where the
|
|
36
|
+
* Worker `env` argument carries `[vars]` from `wrangler.toml`.
|
|
37
|
+
*
|
|
38
|
+
* When provided, `process.env` is ignored entirely. Only string-valued
|
|
39
|
+
* entries participate in URL detection — non-string Workers bindings
|
|
40
|
+
* (KV namespaces, Durable Objects, R2 buckets, service bindings) are dropped.
|
|
41
|
+
*/
|
|
42
|
+
env?: object;
|
|
43
|
+
}
|
|
32
44
|
export interface ProviderDetector {
|
|
33
45
|
name: PlatformName;
|
|
34
46
|
detect: (env: Record<string, string | undefined>) => boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "which-url",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
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(): 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,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAK3D"}
|
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,IAAI,SAAS,CAyBtC"}
|
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,MAAM,SAAS,CAAA;AAqClE,QAAA,IAAI,SAAS,EAAE,iBAAiB,CAAA;AA6BhC,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,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,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(): ResolveResult;
|
|
7
|
-
export declare function resolvePlatform(): 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,IAAI,aAAa,CAuC1C;AAED,wBAAgB,eAAe,IAAI,QAAQ,CAQ1C"}
|
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,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"}
|