vite-plugin-caddy-multiple-tls 1.7.1 → 1.8.0

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
@@ -1,19 +1,18 @@
1
1
  # vite-plugin-caddy-multiple-tls
2
2
 
3
3
  ## What it does
4
+
4
5
  Runs Caddy alongside Vite to give you HTTPS locally with automatic, per-branch domains like `<repo>.<branch>.localhost`, so you can use real hostnames, cookies, and secure APIs without manual proxy setup.
5
6
 
6
7
  ## Usage
7
8
 
8
9
  ```js
9
10
  // vite.config.js
10
- import { defineConfig } from 'vite';
11
- import caddyTls from 'vite-plugin-caddy-multiple-tls';
11
+ import { defineConfig } from "vite";
12
+ import caddyTls from "vite-plugin-caddy-multiple-tls";
12
13
 
13
14
  const config = defineConfig({
14
- plugins: [
15
- caddyTls(),
16
- ]
15
+ plugins: [caddyTls()],
17
16
  });
18
17
 
19
18
  export default config;
@@ -22,6 +21,7 @@ export default config;
22
21
  Will give this in the terminal, allow you to connect to your app on HTTPS with a self-signed and trusted cert.
23
22
 
24
23
  The plugin defaults `server.host = true` and `server.allowedHosts = true` (plus preview equivalents) so custom hostnames work without extra config. When a domain is resolved, it also defaults `server.hmr` to use `wss` on port `443` and the resolved host, isolating multiple Vite instances without extra config. Override these in your Vite config if you need different values.
24
+
25
25
  ```
26
26
  > vite
27
27
 
@@ -36,19 +36,37 @@ The plugin defaults `server.host = true` and `server.allowedHosts = true` (plus
36
36
  By default, the plugin derives `<repo>.<branch>.localhost` from git.
37
37
  If repo or branch can't be detected, pass `repo`/`branch` or use `domain`.
38
38
 
39
+ If you need the resolved hostname in tooling, the package also exports pure helpers:
40
+
41
+ ```js
42
+ import { resolveCaddyTlsDomains, resolveCaddyTlsUrl } from "vite-plugin-caddy-multiple-tls";
43
+
44
+ const url = resolveCaddyTlsUrl({
45
+ baseDomain: "localhost",
46
+ });
47
+ // https://my-repo.my-branch.localhost
48
+
49
+ const domains = resolveCaddyTlsDomains({
50
+ domain: ["app.localhost", "api.localhost"],
51
+ });
52
+ // ['app.localhost', 'api.localhost']
53
+ ```
54
+
55
+ `resolveCaddyTlsUrl()` returns `null` when the config resolves to zero or multiple domains.
56
+
39
57
  If you want a fixed host without repo/branch in the URL, pass a single domain:
40
58
 
41
59
  ```js
42
60
  // vite.config.js
43
- import { defineConfig } from 'vite';
44
- import caddyTls from 'vite-plugin-caddy-multiple-tls';
61
+ import { defineConfig } from "vite";
62
+ import caddyTls from "vite-plugin-caddy-multiple-tls";
45
63
 
46
64
  const config = defineConfig({
47
65
  plugins: [
48
66
  caddyTls({
49
- domain: 'app.localhost',
50
- })
51
- ]
67
+ domain: "app.localhost",
68
+ }),
69
+ ],
52
70
  });
53
71
 
54
72
  export default config;
@@ -58,15 +76,15 @@ You can also pass multiple explicit domains:
58
76
 
59
77
  ```js
60
78
  // vite.config.js
61
- import { defineConfig } from 'vite';
62
- import caddyTls from 'vite-plugin-caddy-multiple-tls';
79
+ import { defineConfig } from "vite";
80
+ import caddyTls from "vite-plugin-caddy-multiple-tls";
63
81
 
64
82
  const config = defineConfig({
65
83
  plugins: [
66
84
  caddyTls({
67
- domain: ['app.localhost', 'api.localhost'],
68
- })
69
- ]
85
+ domain: ["app.localhost", "api.localhost"],
86
+ }),
87
+ ],
70
88
  });
71
89
 
72
90
  export default config;
@@ -76,15 +94,15 @@ To derive a domain like `<repo>.<branch>.<baseDomain>` automatically from git (r
76
94
 
77
95
  ```js
78
96
  // vite.config.js
79
- import { defineConfig } from 'vite';
80
- import caddyTls from 'vite-plugin-caddy-multiple-tls';
97
+ import { defineConfig } from "vite";
98
+ import caddyTls from "vite-plugin-caddy-multiple-tls";
81
99
 
82
100
  const config = defineConfig({
83
101
  plugins: [
84
102
  caddyTls({
85
- baseDomain: 'local.conekto.eu',
86
- })
87
- ]
103
+ baseDomain: "local.conekto.eu",
104
+ }),
105
+ ],
88
106
  });
89
107
 
90
108
  export default config;
@@ -96,15 +114,15 @@ If you run different projects that derive the same `<repo>.<branch>` host, add `
96
114
 
97
115
  ```js
98
116
  // vite.config.js
99
- import { defineConfig } from 'vite';
100
- import caddyTls from 'vite-plugin-caddy-multiple-tls';
117
+ import { defineConfig } from "vite";
118
+ import caddyTls from "vite-plugin-caddy-multiple-tls";
101
119
 
102
120
  const config = defineConfig({
103
121
  plugins: [
104
122
  caddyTls({
105
- instanceLabel: 'web-1',
106
- })
107
- ]
123
+ instanceLabel: "web-1",
124
+ }),
125
+ ],
108
126
  });
109
127
 
110
128
  export default config;
@@ -126,15 +144,15 @@ If your Caddy Admin API is not on the default `http://localhost:2019`, set `cadd
126
144
 
127
145
  ```js
128
146
  // vite.config.js
129
- import { defineConfig } from 'vite';
130
- import caddyTls from 'vite-plugin-caddy-multiple-tls';
147
+ import { defineConfig } from "vite";
148
+ import caddyTls from "vite-plugin-caddy-multiple-tls";
131
149
 
132
150
  const config = defineConfig({
133
151
  plugins: [
134
152
  caddyTls({
135
- caddyApiUrl: 'http://localhost:2020',
136
- })
137
- ]
153
+ caddyApiUrl: "http://localhost:2020",
154
+ }),
155
+ ],
138
156
  });
139
157
 
140
158
  export default config;
@@ -144,16 +162,16 @@ If your Caddy Admin API enforces a specific allowed origin that differs from `ca
144
162
 
145
163
  ```js
146
164
  // vite.config.js
147
- import { defineConfig } from 'vite';
148
- import caddyTls from 'vite-plugin-caddy-multiple-tls';
165
+ import { defineConfig } from "vite";
166
+ import caddyTls from "vite-plugin-caddy-multiple-tls";
149
167
 
150
168
  const config = defineConfig({
151
169
  plugins: [
152
170
  caddyTls({
153
- caddyApiUrl: 'http://127.0.0.1:2019',
154
- caddyAdminOrigin: 'http://localhost:2019',
155
- })
156
- ]
171
+ caddyApiUrl: "http://127.0.0.1:2019",
172
+ caddyAdminOrigin: "http://localhost:2019",
173
+ }),
174
+ ],
157
175
  });
158
176
 
159
177
  export default config;
@@ -182,11 +200,13 @@ curl -i http://127.0.0.1:2019/config/
182
200
  curl -i -H 'Origin: http://127.0.0.1:2019' http://127.0.0.1:2019/config/
183
201
  ```
184
202
 
185
- > [!IMPORTANT]
203
+ > [!IMPORTANT]
186
204
  > **Hosts file limitation:** If you use a custom domain, you must **manually** add each generated subdomain to your `/etc/hosts` file (e.g., `127.0.0.1 repo.branch.local.example.test`). System hosts files **do not support wildcards** (e.g., `*.local.example.test`), so you lose the benefit of automatic domain resolution that `localhost` provides.
187
205
 
188
206
  ## Recommended base domain: `.localhost`
207
+
189
208
  Why `localhost` is the best option for local development:
209
+
190
210
  - Reserved by RFC 6761 (never on the public internet).
191
211
  - Automatic resolution on macOS: `*.localhost` maps to `127.0.0.1` and `::1` without DNS or `/etc/hosts`.
192
212
  - Subdomain support: `api.localhost`, `foo.bar.localhost`, etc.
@@ -194,6 +214,7 @@ Why `localhost` is the best option for local development:
194
214
  - Works well with Caddy and other local reverse proxies.
195
215
 
196
216
  Example usage:
217
+
197
218
  ```
198
219
  app.localhost
199
220
  api.app.localhost
@@ -201,27 +222,32 @@ api.app.localhost
201
222
 
202
223
  > [!NOTE]
203
224
  > **Linux users:** Unlike macOS, most Linux distributions don't automatically resolve `*.localhost` subdomains. The plugin will detect Linux and show you the exact command to run:
225
+ >
204
226
  > ```
205
227
  > 🐧 Linux users: if the domain doesn't resolve, run:
206
228
  > echo "127.0.0.1 my-repo.my-branch.localhost" | sudo tee -a /etc/hosts
207
229
  > ```
208
230
  >
209
231
  > If you want to avoid `/etc/hosts` edits on Linux, set `loopbackDomain` to a public loopback domain:
232
+ >
210
233
  > ```ts
211
234
  > caddyTls({
212
- > loopbackDomain: 'localtest.me',
213
- > })
235
+ > loopbackDomain: "localtest.me",
236
+ > });
214
237
  > ```
238
+ >
215
239
  > Supported values: `localtest.me`, `lvh.me`, `nip.io` (maps to `127.0.0.1.nip.io`). These rely on public DNS, so they can fail offline or on restricted networks.
216
240
  >
217
241
  > Why these work: they use wildcard DNS so any subdomain resolves to `127.0.0.1`, meaning the request loops back to your machine after DNS.
242
+ >
218
243
  > - `localtest.me` and `lvh.me`: static wildcard -> always `127.0.0.1` (great for subdomain testing).
219
244
  > - `nip.io`: dynamic parsing of the IP in the hostname (e.g. `app.192.168.1.50.nip.io`) so you can target LAN devices.
220
- > Why use them: subdomains behave like real domains, no `/etc/hosts` edits, and closer parity for cookies/CORS rules.
245
+ > Why use them: subdomains behave like real domains, no `/etc/hosts` edits, and closer parity for cookies/CORS rules.
221
246
  >
222
247
  > When using loopback domains, ensure your Vite config allows the Host header and binds to all interfaces, e.g. `server: { allowedHosts: true, host: true }`.
223
248
  >
224
249
  > For a permanent fix that handles all `*.localhost` domains automatically, install dnsmasq:
250
+ >
225
251
  > ```bash
226
252
  > sudo apt install dnsmasq
227
253
  > echo "address=/.localhost/127.0.0.1" | sudo tee /etc/dnsmasq.d/localhost.conf
@@ -229,13 +255,15 @@ api.app.localhost
229
255
  > ```
230
256
 
231
257
  ## Development
258
+
232
259
  This repo uses npm workspaces. Install from the root with `npm install`, then run workspace scripts like `npm run build --workspace packages/plugin` or `npm run dev --workspace playground`.
233
260
 
234
261
  The published package README is synced from the root `README.md` via `packages/plugin/scripts/sync-readme.sh`.
235
262
 
236
263
  ## Contributing
264
+
237
265
  See [CONTRIBUTING.md](./CONTRIBUTING.md) to see how to get started.
238
-
266
+
239
267
  ## License
240
268
 
241
269
  MIT
package/dist/index.d.ts CHANGED
@@ -1,6 +1,17 @@
1
1
  import { PluginOption } from 'vite';
2
2
 
3
- interface ViteCaddyTlsPluginOptions {
3
+ type LoopbackDomain = "localtest.me" | "lvh.me" | "nip.io";
4
+
5
+ interface CaddyTlsDomainOptions {
6
+ domain?: string | string[];
7
+ baseDomain?: string;
8
+ loopbackDomain?: LoopbackDomain;
9
+ repo?: string;
10
+ branch?: string;
11
+ instanceLabel?: string;
12
+ }
13
+
14
+ interface ViteCaddyTlsPluginOptions extends CaddyTlsDomainOptions {
4
15
  /** Explicit domain to proxy without repo/branch derivation */
5
16
  domain?: string | string[];
6
17
  /** Base domain to build <repo>.<branch>.<baseDomain> (defaults to localhost) */
@@ -28,7 +39,8 @@ interface ViteCaddyTlsPluginOptions {
28
39
  */
29
40
  upstreamHostHeader?: string;
30
41
  }
31
- type LoopbackDomain = 'localtest.me' | 'lvh.me' | 'nip.io';
42
+ declare function resolveCaddyTlsDomains(options?: ViteCaddyTlsPluginOptions): string[] | null;
43
+ declare function resolveCaddyTlsUrl(options?: ViteCaddyTlsPluginOptions): string | null;
32
44
  /**
33
45
  * Vite plugin to run Caddy server to proxy traffic on https for local development
34
46
  *
@@ -43,4 +55,4 @@ type LoopbackDomain = 'localtest.me' | 'lvh.me' | 'nip.io';
43
55
  */
44
56
  declare function viteCaddyTlsPlugin({ domain, baseDomain, loopbackDomain, repo, branch, instanceLabel, cors, serverName, caddyApiUrl, caddyAdminOrigin, internalTls, upstreamHostHeader, }?: ViteCaddyTlsPluginOptions): PluginOption;
45
57
 
46
- export { type ViteCaddyTlsPluginOptions, viteCaddyTlsPlugin as default };
58
+ export { type ViteCaddyTlsPluginOptions, viteCaddyTlsPlugin as default, resolveCaddyTlsDomains, resolveCaddyTlsUrl };
package/dist/index.js CHANGED
@@ -1,7 +1,5 @@
1
1
  // src/index.ts
2
- import { execSync as execSync2 } from "child_process";
3
2
  import { randomUUID } from "crypto";
4
- import path2 from "path";
5
3
 
6
4
  // src/utils.ts
7
5
  import { execSync } from "child_process";
@@ -87,7 +85,7 @@ function parseConfig(text) {
87
85
  if (!text.trim()) return {};
88
86
  try {
89
87
  return JSON.parse(text);
90
- } catch (e) {
88
+ } catch {
91
89
  return void 0;
92
90
  }
93
91
  }
@@ -142,7 +140,7 @@ function getAdminOrigin(apiUrl, adminOrigin) {
142
140
  const originSource = adminOrigin ?? getApiUrl(apiUrl);
143
141
  try {
144
142
  return new URL(originSource).origin;
145
- } catch (e) {
143
+ } catch {
146
144
  return new URL(getApiUrl(apiUrl)).origin;
147
145
  }
148
146
  }
@@ -363,7 +361,7 @@ function validateCaddyIsInstalled() {
363
361
  try {
364
362
  execSync("caddy version");
365
363
  return true;
366
- } catch (e) {
364
+ } catch {
367
365
  console.error("caddy cli is not installed");
368
366
  return false;
369
367
  }
@@ -371,7 +369,7 @@ function validateCaddyIsInstalled() {
371
369
  async function startCaddy(apiUrl, adminOrigin) {
372
370
  try {
373
371
  execSync("caddy start", { stdio: "ignore" });
374
- } catch (e) {
372
+ } catch {
375
373
  }
376
374
  for (let i = 0; i < 10; i++) {
377
375
  const status = await checkCaddyAdminStatus(apiUrl, adminOrigin);
@@ -407,12 +405,7 @@ async function ensureBaseConfig(serverName = DEFAULT_SERVER_NAME, apiUrl, adminO
407
405
  [serverName]: baseConfig
408
406
  }
409
407
  };
410
- const configRes = await caddyFetch(
411
- `${resolvedApiUrl}/config/`,
412
- void 0,
413
- apiUrl,
414
- adminOrigin
415
- );
408
+ const configRes = await caddyFetch(`${resolvedApiUrl}/config/`, void 0, apiUrl, adminOrigin);
416
409
  await assertCaddyResponse(configRes, "Failed to read Caddy config");
417
410
  const configText = await configRes.text();
418
411
  const config = parseConfig(configText);
@@ -577,11 +570,7 @@ async function ensureTlsAutomation(apiUrl, adminOrigin) {
577
570
  );
578
571
  if (!tlsRes.ok && tlsRes.status !== 409) {
579
572
  const text = await tlsRes.text();
580
- throw buildCaddyRequestError(
581
- "Failed to initialize Caddy TLS automation",
582
- tlsRes.status,
583
- text
584
- );
573
+ throw buildCaddyRequestError("Failed to initialize Caddy TLS automation", tlsRes.status, text);
585
574
  }
586
575
  }
587
576
  function formatDialAddress(host, port) {
@@ -676,14 +665,7 @@ async function addRoute(id, domains, port, cors, serverName = DEFAULT_SERVER_NAM
676
665
  response: {
677
666
  set: {
678
667
  "Access-Control-Allow-Origin": [cors],
679
- "Access-Control-Allow-Methods": [
680
- "GET",
681
- "POST",
682
- "PUT",
683
- "PATCH",
684
- "DELETE",
685
- "OPTIONS"
686
- ],
668
+ "Access-Control-Allow-Methods": ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
687
669
  "Access-Control-Allow-Headers": ["*"]
688
670
  }
689
671
  }
@@ -791,11 +773,7 @@ async function removeTlsPolicy(id, apiUrl, adminOrigin) {
791
773
  );
792
774
  if (!res.ok && res.status !== 404) {
793
775
  const text = await res.text();
794
- const error = buildCaddyRequestError(
795
- `Failed to remove TLS policy ${id}`,
796
- res.status,
797
- text
798
- );
776
+ const error = buildCaddyRequestError(`Failed to remove TLS policy ${id}`, res.status, text);
799
777
  console.error(error.message);
800
778
  return false;
801
779
  }
@@ -818,7 +796,12 @@ async function ensureCaddyReady(serverName = DEFAULT_SERVER_NAME, apiUrl, adminO
818
796
  });
819
797
  }
820
798
 
821
- // src/index.ts
799
+ // src/domain-resolution.js
800
+ import { execSync as execSync2 } from "child_process";
801
+ import { createHash as createHash2 } from "crypto";
802
+ import path2 from "path";
803
+ var MAX_DOMAIN_LABEL_LENGTH = 63;
804
+ var DOMAIN_LABEL_HASH_LENGTH = 10;
822
805
  var LOOPBACK_DOMAINS = {
823
806
  "localtest.me": "localtest.me",
824
807
  "lvh.me": "lvh.me",
@@ -834,7 +817,7 @@ function getGitRepoInfo() {
834
817
  if (repoRoot) {
835
818
  info.repo = path2.basename(repoRoot);
836
819
  }
837
- } catch (e) {
820
+ } catch {
838
821
  }
839
822
  try {
840
823
  let branch = execGit("git rev-parse --abbrev-ref HEAD");
@@ -844,7 +827,7 @@ function getGitRepoInfo() {
844
827
  if (branch) {
845
828
  info.branch = branch;
846
829
  }
847
- } catch (e) {
830
+ } catch {
848
831
  }
849
832
  return info;
850
833
  }
@@ -860,18 +843,34 @@ function resolveBaseDomain(options) {
860
843
  }
861
844
  return "localhost";
862
845
  }
863
- function resolveUpstreamHost(host) {
864
- if (typeof host === "string") {
865
- const trimmed = host.trim();
866
- if (trimmed && trimmed !== "0.0.0.0" && trimmed !== "::") {
867
- return trimmed;
868
- }
869
- }
870
- return "127.0.0.1";
846
+ function normalizeDomain(domain) {
847
+ const trimmed = domain.trim().toLowerCase();
848
+ if (!trimmed) return null;
849
+ return trimmed;
850
+ }
851
+ function normalizeDomains(domains) {
852
+ const domainList = Array.isArray(domains) ? domains : [domains];
853
+ const normalized = domainList.map((domain) => normalizeDomain(domain)).filter(Boolean);
854
+ if (normalized.length === 0) return null;
855
+ return Array.from(new Set(normalized));
871
856
  }
872
857
  function sanitizeDomainLabel(value) {
873
858
  return value.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
874
859
  }
860
+ function compactDomainLabel(value) {
861
+ const sanitized = sanitizeDomainLabel(value);
862
+ if (!sanitized) return "";
863
+ if (sanitized.length <= MAX_DOMAIN_LABEL_LENGTH) {
864
+ return sanitized;
865
+ }
866
+ const hash = createHash2("sha1").update(sanitized).digest("hex").slice(0, DOMAIN_LABEL_HASH_LENGTH);
867
+ const prefixLength = MAX_DOMAIN_LABEL_LENGTH - hash.length - 1;
868
+ const prefix = sanitized.slice(0, prefixLength).replace(/-+$/g, "");
869
+ if (!prefix) {
870
+ return hash;
871
+ }
872
+ return `${prefix}-${hash}`;
873
+ }
875
874
  function buildDerivedDomain(options) {
876
875
  const baseDomain = resolveBaseDomain(options);
877
876
  if (!baseDomain) return null;
@@ -883,27 +882,40 @@ function buildDerivedDomain(options) {
883
882
  if (!branch) branch = info.branch;
884
883
  }
885
884
  if (!repo || !branch) return null;
886
- const repoLabel = sanitizeDomainLabel(repo);
887
- const branchLabel = sanitizeDomainLabel(branch);
885
+ const repoLabel = compactDomainLabel(repo);
886
+ const branchLabel = compactDomainLabel(branch);
888
887
  if (!repoLabel || !branchLabel) return null;
889
888
  const labels = [repoLabel, branchLabel];
890
889
  if (options.instanceLabel !== void 0) {
891
- const instanceLabel = sanitizeDomainLabel(options.instanceLabel);
890
+ const instanceLabel = compactDomainLabel(options.instanceLabel);
892
891
  if (!instanceLabel) return null;
893
892
  labels.push(instanceLabel);
894
893
  }
895
894
  return `${labels.join(".")}.${baseDomain}`;
896
895
  }
897
- function normalizeDomain(domain) {
898
- const trimmed = domain.trim().toLowerCase();
899
- if (!trimmed) return null;
900
- return trimmed;
896
+ function resolveCaddyTlsDomains(options = {}) {
897
+ if (options.domain) {
898
+ return normalizeDomains(options.domain);
899
+ }
900
+ const derivedDomain = buildDerivedDomain(options);
901
+ if (!derivedDomain) return null;
902
+ return [derivedDomain];
901
903
  }
902
- function normalizeDomains(domains) {
903
- const domainList = Array.isArray(domains) ? domains : [domains];
904
- const normalized = domainList.map((domain) => normalizeDomain(domain)).filter((domain) => Boolean(domain));
905
- if (normalized.length === 0) return null;
906
- return Array.from(new Set(normalized));
904
+ function resolveCaddyTlsUrl(options = {}) {
905
+ const domains = resolveCaddyTlsDomains(options);
906
+ if (!domains || domains.length !== 1) return null;
907
+ return `https://${domains[0]}`;
908
+ }
909
+
910
+ // src/index.ts
911
+ function resolveUpstreamHost(host) {
912
+ if (typeof host === "string") {
913
+ const trimmed = host.trim();
914
+ if (trimmed && trimmed !== "0.0.0.0" && trimmed !== "::") {
915
+ return trimmed;
916
+ }
917
+ }
918
+ return "127.0.0.1";
907
919
  }
908
920
  function normalizeCaddyApiUrl(url) {
909
921
  const trimmed = url.trim();
@@ -915,17 +927,15 @@ function normalizeCaddyAdminOrigin(origin) {
915
927
  if (!trimmed) return null;
916
928
  try {
917
929
  return new URL(trimmed).origin;
918
- } catch (e) {
930
+ } catch {
919
931
  return null;
920
932
  }
921
933
  }
922
- function resolveDomains(options) {
923
- if (options.domain) {
924
- return normalizeDomains(options.domain);
925
- }
926
- const derivedDomain = buildDerivedDomain(options);
927
- if (!derivedDomain) return null;
928
- return [derivedDomain];
934
+ function resolveCaddyTlsDomains2(options = {}) {
935
+ return resolveCaddyTlsDomains(options);
936
+ }
937
+ function resolveCaddyTlsUrl2(options = {}) {
938
+ return resolveCaddyTlsUrl(options);
929
939
  }
930
940
  function viteCaddyTlsPlugin({
931
941
  domain,
@@ -946,14 +956,10 @@ function viteCaddyTlsPlugin({
946
956
  const normalizedAdminOrigin = caddyAdminOrigin ? normalizeCaddyAdminOrigin(caddyAdminOrigin) : null;
947
957
  const pluginCaddyAdminOrigin = normalizedAdminOrigin ?? pluginCaddyApiUrl;
948
958
  if (caddyApiUrl !== void 0 && !normalizedApiUrl) {
949
- console.warn(
950
- `caddyApiUrl is empty after trimming. Falling back to ${DEFAULT_CADDY_API_URL}.`
951
- );
959
+ console.warn(`caddyApiUrl is empty after trimming. Falling back to ${DEFAULT_CADDY_API_URL}.`);
952
960
  }
953
961
  if (caddyAdminOrigin !== void 0 && !normalizedAdminOrigin) {
954
- console.warn(
955
- `caddyAdminOrigin is invalid. Falling back to ${pluginCaddyApiUrl}.`
956
- );
962
+ console.warn(`caddyAdminOrigin is invalid. Falling back to ${pluginCaddyApiUrl}.`);
957
963
  }
958
964
  function createOwnerId() {
959
965
  return `${process.pid}-${Date.now().toString(36)}-${randomUUID().slice(0, 8)}`;
@@ -998,11 +1004,7 @@ function viteCaddyTlsPlugin({
998
1004
  if (record.tlsPolicyId) {
999
1005
  const tlsPolicyId = record.tlsPolicyId;
1000
1006
  cleaned = await removeWithRetry(
1001
- () => removeTlsPolicy(
1002
- tlsPolicyId,
1003
- pluginCaddyApiUrl,
1004
- pluginCaddyAdminOrigin
1005
- ),
1007
+ () => removeTlsPolicy(tlsPolicyId, pluginCaddyApiUrl, pluginCaddyAdminOrigin),
1006
1008
  "TLS policy"
1007
1009
  ) && cleaned;
1008
1010
  }
@@ -1016,11 +1018,7 @@ function viteCaddyTlsPlugin({
1016
1018
  let cleaned = true;
1017
1019
  for (const managedTlsPolicyId of tlsPolicyIds) {
1018
1020
  cleaned = await removeWithRetry(
1019
- () => removeTlsPolicy(
1020
- managedTlsPolicyId,
1021
- pluginCaddyApiUrl,
1022
- pluginCaddyAdminOrigin
1023
- ),
1021
+ () => removeTlsPolicy(managedTlsPolicyId, pluginCaddyApiUrl, pluginCaddyAdminOrigin),
1024
1022
  `managed TLS policy ${managedTlsPolicyId}`
1025
1023
  ) && cleaned;
1026
1024
  }
@@ -1054,7 +1052,7 @@ function viteCaddyTlsPlugin({
1054
1052
  const { httpServer, config } = server;
1055
1053
  const previewMode = isPreviewServer(server);
1056
1054
  const fallbackPort = previewMode ? getPreviewPort(config) ?? 4173 : config.server.port || 5173;
1057
- const resolvedDomains = resolveDomains({
1055
+ const resolvedDomains = resolveCaddyTlsDomains2({
1058
1056
  domain,
1059
1057
  baseDomain,
1060
1058
  loopbackDomain,
@@ -1125,7 +1123,7 @@ function viteCaddyTlsPlugin({
1125
1123
  if (resolvedPort === null && !Number.isNaN(port)) {
1126
1124
  resolvedPort = port;
1127
1125
  }
1128
- } catch (e) {
1126
+ } catch {
1129
1127
  }
1130
1128
  }
1131
1129
  if (httpServer) {
@@ -1274,9 +1272,7 @@ function viteCaddyTlsPlugin({
1274
1272
  return;
1275
1273
  }
1276
1274
  if (claimResult.status === "active-conflict") {
1277
- console.error(
1278
- buildOwnershipConflictMessage(domainArray, claimResult.existingRecord)
1279
- );
1275
+ console.error(buildOwnershipConflictMessage(domainArray, claimResult.existingRecord));
1280
1276
  return;
1281
1277
  }
1282
1278
  activeOwnershipRecord = claimResult.currentRecord;
@@ -1317,9 +1313,7 @@ function viteCaddyTlsPlugin({
1317
1313
  removeWithRetry
1318
1314
  );
1319
1315
  if (reclaimedOrphans) {
1320
- console.warn(
1321
- `Reclaimed orphaned managed Caddy resources for ${domainArray.join(", ")}.`
1322
- );
1316
+ console.warn(`Reclaimed orphaned managed Caddy resources for ${domainArray.join(", ")}.`);
1323
1317
  } else {
1324
1318
  console.error(
1325
1319
  `Cannot claim ${domainArray.join(", ")} because Caddy still has orphaned managed resources. Remove the stale Caddy state or use \`instanceLabel\` or \`domain\` to make the hostname unique.`
@@ -1331,12 +1325,7 @@ function viteCaddyTlsPlugin({
1331
1325
  }
1332
1326
  if (tlsPolicyId) {
1333
1327
  try {
1334
- await addTlsPolicy(
1335
- tlsPolicyId,
1336
- domainArray,
1337
- pluginCaddyApiUrl,
1338
- pluginCaddyAdminOrigin
1339
- );
1328
+ await addTlsPolicy(tlsPolicyId, domainArray, pluginCaddyApiUrl, pluginCaddyAdminOrigin);
1340
1329
  tlsPolicyAdded = true;
1341
1330
  } catch (e) {
1342
1331
  console.error(
@@ -1378,10 +1367,8 @@ function viteCaddyTlsPlugin({
1378
1367
  console.log("\n\u{1F512} Caddy is proxying your traffic on https");
1379
1368
  console.log(`
1380
1369
  \u27A1\uFE0F Upstream target: http://${formatUpstreamTarget(upstreamHost, port)}`);
1381
- console.log(
1382
- `
1383
- \u{1F517} Access your local ${domainArray.length > 1 ? "servers" : "server"}!`
1384
- );
1370
+ console.log(`
1371
+ \u{1F517} Access your local ${domainArray.length > 1 ? "servers" : "server"}!`);
1385
1372
  domainArray.forEach((domain2) => {
1386
1373
  console.log(`\u{1F30D} https://${domain2}`);
1387
1374
  });
@@ -1428,7 +1415,7 @@ function viteCaddyTlsPlugin({
1428
1415
  return {
1429
1416
  name: "vite:caddy-tls",
1430
1417
  config(userConfig) {
1431
- const resolvedDomains = resolveDomains({
1418
+ const resolvedDomains = resolveCaddyTlsDomains2({
1432
1419
  domain,
1433
1420
  baseDomain,
1434
1421
  loopbackDomain,
@@ -1463,5 +1450,7 @@ function viteCaddyTlsPlugin({
1463
1450
  };
1464
1451
  }
1465
1452
  export {
1466
- viteCaddyTlsPlugin as default
1453
+ viteCaddyTlsPlugin as default,
1454
+ resolveCaddyTlsDomains2 as resolveCaddyTlsDomains,
1455
+ resolveCaddyTlsUrl2 as resolveCaddyTlsUrl
1467
1456
  };
package/package.json CHANGED
@@ -1,19 +1,24 @@
1
1
  {
2
2
  "name": "vite-plugin-caddy-multiple-tls",
3
- "version": "1.7.1",
3
+ "version": "1.8.0",
4
4
  "description": "Vite plugin that uses Caddy to provide local HTTPS with derived domains.",
5
5
  "keywords": [
6
- "vite",
7
- "plugin",
8
6
  "caddy",
9
7
  "https",
8
+ "local-development",
9
+ "plugin",
10
10
  "tls",
11
- "local-development"
11
+ "vite"
12
12
  ],
13
+ "homepage": "https://github.com/vampaz/vite-plugin-caddy-multiple-tls/#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/vampaz/vite-plugin-caddy-multiple-tls/issues"
16
+ },
13
17
  "license": "MIT",
14
18
  "author": "vampaz",
15
- "publishConfig": {
16
- "access": "public"
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/vampaz/vite-plugin-caddy-multiple-tls.git"
17
22
  },
18
23
  "files": [
19
24
  "dist"
@@ -27,6 +32,9 @@
27
32
  "import": "./dist/index.js"
28
33
  }
29
34
  },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
30
38
  "scripts": {
31
39
  "dev": "tsup --watch src/**/* src/index.ts --format esm --dts-resolve",
32
40
  "sync-readme": "bash scripts/sync-readme.sh",
@@ -35,20 +43,6 @@
35
43
  "test": "vitest run",
36
44
  "test:watch": "vitest"
37
45
  },
38
- "engines": {
39
- "node": ">=22.0.0"
40
- },
41
- "repository": {
42
- "type": "git",
43
- "url": "git+https://github.com/vampaz/vite-plugin-caddy-multiple-tls.git"
44
- },
45
- "bugs": {
46
- "url": "https://github.com/vampaz/vite-plugin-caddy-multiple-tls/issues"
47
- },
48
- "homepage": "https://github.com/vampaz/vite-plugin-caddy-multiple-tls/#readme",
49
- "peerDependencies": {
50
- "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
51
- },
52
46
  "devDependencies": {
53
47
  "@types/fs-extra": "^11.0.4",
54
48
  "@types/node": "^25.0.3",
@@ -56,5 +50,11 @@
56
50
  "tsup": "^8.5.1",
57
51
  "vite": "^8.0.0",
58
52
  "vitest": "^4.0.16"
53
+ },
54
+ "peerDependencies": {
55
+ "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
56
+ },
57
+ "engines": {
58
+ "node": ">=22.0.0"
59
59
  }
60
60
  }