which-url 0.0.1 → 0.0.2

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 CHANGED
@@ -7,16 +7,35 @@ npm install which-url
7
7
  ```
8
8
 
9
9
  ```typescript
10
- import whichUrl from 'which-url'
10
+ import appUrl from 'which-url'
11
11
 
12
- whichUrl.href // "https://myapp.vercel.app"
13
- whichUrl.hostname // "myapp.vercel.app"
12
+ auth({ baseURL: appUrl.href }) // just works — local, preview, production
14
13
  ```
15
14
 
16
15
  Works on Vercel, Netlify, Cloudflare Pages, Railway, Fly.io, Render, DigitalOcean, and Heroku — automatically.
17
16
 
18
17
  ## Usage
19
18
 
19
+ ### Default export (object with dot access)
20
+
21
+ ```typescript
22
+ import appUrl from 'which-url'
23
+
24
+ appUrl.href // "https://myapp.vercel.app"
25
+ appUrl.origin // "https://myapp.vercel.app"
26
+ appUrl.hostname // "myapp.vercel.app"
27
+ appUrl.host // "myapp.vercel.app"
28
+ appUrl.protocol // "https:"
29
+ appUrl.port // ""
30
+
31
+ appUrl.env // "production" | "preview" | "local"
32
+ appUrl.isProduction // boolean
33
+ appUrl.isPreview // boolean
34
+ appUrl.isLocal // boolean
35
+ ```
36
+
37
+ Property names follow the [WHATWG URL spec](https://url.spec.whatwg.org/) — nothing new to learn.
38
+
20
39
  ### Named exports (plain strings — zero type friction)
21
40
 
22
41
  ```typescript
@@ -32,26 +51,6 @@ if (isProduction) {
32
51
  }
33
52
  ```
34
53
 
35
- ### Default export (object with dot access)
36
-
37
- ```typescript
38
- import whichUrl from 'which-url'
39
-
40
- whichUrl.href // "https://myapp.vercel.app"
41
- whichUrl.origin // "https://myapp.vercel.app"
42
- whichUrl.hostname // "myapp.vercel.app"
43
- whichUrl.host // "myapp.vercel.app"
44
- whichUrl.protocol // "https:"
45
- whichUrl.port // ""
46
-
47
- whichUrl.env // "production" | "preview" | "local"
48
- whichUrl.isProduction // boolean
49
- whichUrl.isPreview // boolean
50
- whichUrl.isLocal // boolean
51
- ```
52
-
53
- Property names follow the [WHATWG URL spec](https://url.spec.whatwg.org/) — nothing new to learn.
54
-
55
54
  ## How it works
56
55
 
57
56
  `which-url` reads environment variables that hosting providers set automatically. No configuration needed.
@@ -143,11 +142,11 @@ Modern wrangler polyfills `process.env` from `[vars]`, so `which-url` picks it u
143
142
  ### Better Auth
144
143
 
145
144
  ```typescript
146
- import { href } from 'which-url'
145
+ import appUrl from 'which-url'
147
146
  import { betterAuth } from 'better-auth'
148
147
 
149
148
  export const auth = betterAuth({
150
- baseURL: href,
149
+ baseURL: appUrl.href,
151
150
  // ...
152
151
  })
153
152
  ```
@@ -155,14 +154,18 @@ export const auth = betterAuth({
155
154
  ### NextAuth / Auth.js
156
155
 
157
156
  ```typescript
158
- import { href } from 'which-url'
157
+ import appUrl from 'which-url'
159
158
 
160
159
  // No need to set NEXTAUTH_URL manually
161
- process.env.NEXTAUTH_URL = href
160
+ process.env.NEXTAUTH_URL = appUrl.href
162
161
  ```
163
162
 
164
163
  ## API
165
164
 
165
+ ### Default export
166
+
167
+ An object with URL properties and environment helpers.
168
+
166
169
  ### Named exports
167
170
 
168
171
  | Export | Type | Description |
@@ -0,0 +1,3 @@
1
+ export declare function getVar(env: Record<string, string | undefined>, name: string): string | undefined;
2
+ export declare function getEnv(): Record<string, string | undefined>;
3
+ //# sourceMappingURL=env-var.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-var.d.ts","sourceRoot":"","sources":["../src/env-var.ts"],"names":[],"mappings":"AAaA,wBAAgB,MAAM,CACpB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAMpB;AAED,wBAAgB,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAK3D"}
package/dist/env.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAIrC,wBAAgB,UAAU,IAAI,MAAM,CAuBnC"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAIrC,wBAAgB,UAAU,IAAI,MAAM,CAwBnC"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { WhichUrl, AppEnv, CreateUrlOptions } from "./types";
2
2
  export declare function createUrl(options?: CreateUrlOptions): WhichUrl;
3
- declare const _resolved: WhichUrl;
3
+ declare let _resolved: WhichUrl;
4
4
  export declare const href: string;
5
5
  export declare const origin: string;
6
6
  export declare const hostname: string;
@@ -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;AAEjE,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,QAAQ,CAgB9D;AAGD,QAAA,MAAM,SAAS,UAAc,CAAA;AAG7B,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,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,gBAAgB,EAAE,CAAA"}
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;AAEjE,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,QAAQ,CAgB9D;AAGD,QAAA,IAAI,SAAS,EAAE,QAAQ,CAAA;AAsBvB,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,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,gBAAgB,EAAE,CAAA"}
package/dist/index.js CHANGED
@@ -1,18 +1,48 @@
1
+ // src/env-var.ts
2
+ var FRAMEWORK_PREFIXES = [
3
+ "",
4
+ "NEXT_PUBLIC_",
5
+ "NUXT_ENV_",
6
+ "VITE_",
7
+ "PUBLIC_",
8
+ "REACT_APP_",
9
+ "GATSBY_",
10
+ "VUE_APP_",
11
+ "REDWOOD_ENV_",
12
+ "SANITY_STUDIO_"
13
+ ];
14
+ function getVar(env, name) {
15
+ for (const prefix of FRAMEWORK_PREFIXES) {
16
+ const val = env[prefix + name];
17
+ if (val)
18
+ return val;
19
+ }
20
+ return;
21
+ }
22
+ function getEnv() {
23
+ if (typeof process !== "undefined" && process?.env) {
24
+ return process.env;
25
+ }
26
+ return {};
27
+ }
28
+
1
29
  // src/providers.ts
2
30
  var providers = [
3
31
  {
4
32
  name: "vercel",
5
- detect: (env) => !!env.VERCEL,
33
+ detect: (env) => !!env.VERCEL || !!getVar(env, "VERCEL_ENV"),
6
34
  resolveUrl: (env) => {
7
- if (env.VERCEL_ENV === "production") {
8
- return env.VERCEL_PROJECT_PRODUCTION_URL || env.VERCEL_URL || null;
35
+ const vercelEnv = getVar(env, "VERCEL_ENV");
36
+ if (vercelEnv === "production") {
37
+ return getVar(env, "VERCEL_PROJECT_PRODUCTION_URL") || getVar(env, "VERCEL_URL") || null;
9
38
  }
10
- return env.VERCEL_BRANCH_URL || env.VERCEL_URL || null;
39
+ return getVar(env, "VERCEL_BRANCH_URL") || getVar(env, "VERCEL_URL") || null;
11
40
  },
12
41
  resolveEnv: (env) => {
13
- if (env.VERCEL_ENV === "production")
42
+ const vercelEnv = getVar(env, "VERCEL_ENV");
43
+ if (vercelEnv === "production")
14
44
  return "production";
15
- if (env.VERCEL_ENV === "preview")
45
+ if (vercelEnv === "preview")
16
46
  return "preview";
17
47
  return "local";
18
48
  }
@@ -94,8 +124,8 @@ function normalizeUrl(raw) {
94
124
 
95
125
  // src/resolve.ts
96
126
  function resolveUrl(options) {
97
- const env = typeof process !== "undefined" ? process.env : {};
98
- const override = env.APP_URL || env.NEXT_PUBLIC_APP_URL;
127
+ const env = getEnv();
128
+ const override = getVar(env, "APP_URL");
99
129
  if (override)
100
130
  return normalizeUrl(override);
101
131
  for (const p of providers) {
@@ -122,9 +152,10 @@ function resolveUrl(options) {
122
152
  // src/env.ts
123
153
  var validEnvs = ["production", "preview", "local"];
124
154
  function resolveEnv() {
125
- const env = typeof process !== "undefined" ? process.env : {};
126
- if (env.APP_ENV && validEnvs.includes(env.APP_ENV)) {
127
- return env.APP_ENV;
155
+ const env = getEnv();
156
+ const appEnv = getVar(env, "APP_ENV");
157
+ if (appEnv && validEnvs.includes(appEnv)) {
158
+ return appEnv;
128
159
  }
129
160
  if (env.NODE_ENV === "development")
130
161
  return "local";
@@ -156,7 +187,24 @@ function createUrl(options) {
156
187
  isLocal: env === "local"
157
188
  };
158
189
  }
159
- var _resolved = createUrl();
190
+ var _resolved;
191
+ try {
192
+ _resolved = createUrl();
193
+ } catch (e) {
194
+ console.warn(`[which-url] Could not detect app URL. Set APP_URL (e.g. APP_URL=https://myapp.com or APP_URL=myapp.com)`);
195
+ _resolved = {
196
+ href: "",
197
+ origin: "",
198
+ hostname: "",
199
+ host: "",
200
+ protocol: "",
201
+ port: "",
202
+ env: "local",
203
+ isProduction: false,
204
+ isPreview: false,
205
+ isLocal: true
206
+ };
207
+ }
160
208
  var href = _resolved.href;
161
209
  var origin = _resolved.origin;
162
210
  var hostname = _resolved.hostname;
@@ -1 +1 @@
1
- {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,eAAO,MAAM,SAAS,EAAE,gBAAgB,EA8EvC,CAAA"}
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"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAoC7D"}
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAoC7D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "which-url",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Auto-detect your app's URL across hosting providers. Zero config.",
5
5
  "type": "module",
6
6
  "exports": {