@stacksjs/rpx 0.5.1 → 0.6.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/dist/cli.js CHANGED
@@ -20461,7 +20461,7 @@ var quotes = collect([
20461
20461
  ]);
20462
20462
  var export_prompts = import_prompts.default;
20463
20463
  // package.json
20464
- var version = "0.5.1";
20464
+ var version = "0.6.0";
20465
20465
 
20466
20466
  // src/config.ts
20467
20467
  import { homedir } from "os";
@@ -20520,6 +20520,7 @@ async function loadConfig({ name, cwd, defaultConfig }) {
20520
20520
  var defaultConfig = {
20521
20521
  from: "localhost:5173",
20522
20522
  to: "stacks.localhost",
20523
+ cleanUrls: false,
20523
20524
  https: {
20524
20525
  basePath: "",
20525
20526
  caCertPath: join2(homedir(), ".stacks", "ssl", `stacks.localhost.ca.crt`),
@@ -57671,14 +57672,24 @@ async function startServer(options3) {
57671
57672
  ssl: sslConfig
57672
57673
  });
57673
57674
  }
57674
- async function createProxyServer(from, to, fromPort, listenPort, hostname, sourceUrl, ssl, verbose) {
57675
- debugLog2("proxy", `Creating proxy server ${from} -> ${to}`, verbose);
57675
+ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourceUrl, ssl, verbose, cleanUrls) {
57676
+ debugLog2("proxy", `Creating proxy server ${from} -> ${to} with cleanUrls: ${cleanUrls}`, verbose);
57676
57677
  const requestHandler = (req, res) => {
57677
57678
  debugLog2("request", `Incoming request: ${req.method} ${req.url}`, verbose);
57679
+ let path5 = req.url || "/";
57680
+ if (cleanUrls) {
57681
+ if (!path5.match(/\.[a-z0-9]+$/i)) {
57682
+ if (path5.endsWith("/")) {
57683
+ path5 = `${path5}index.html`;
57684
+ } else {
57685
+ path5 = `${path5}.html`;
57686
+ }
57687
+ }
57688
+ }
57678
57689
  const proxyOptions = {
57679
57690
  hostname: sourceUrl.hostname,
57680
57691
  port: fromPort,
57681
- path: req.url,
57692
+ path: path5,
57682
57693
  method: req.method,
57683
57694
  headers: {
57684
57695
  ...req.headers,
@@ -57688,6 +57699,42 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
57688
57699
  debugLog2("request", `Proxy request options: ${JSON.stringify(proxyOptions)}`, verbose);
57689
57700
  const proxyReq = http.request(proxyOptions, (proxyRes) => {
57690
57701
  debugLog2("response", `Proxy response received with status ${proxyRes.statusCode}`, verbose);
57702
+ if (cleanUrls && proxyRes.statusCode === 404) {
57703
+ const alternativePaths = [];
57704
+ if (path5.endsWith(".html")) {
57705
+ alternativePaths.push(path5.slice(0, -5));
57706
+ } else if (!path5.match(/\.[a-z0-9]+$/i)) {
57707
+ alternativePaths.push(`${path5}.html`);
57708
+ }
57709
+ if (!path5.endsWith("/")) {
57710
+ alternativePaths.push(`${path5}/index.html`);
57711
+ }
57712
+ if (alternativePaths.length > 0) {
57713
+ debugLog2("cleanUrls", `Trying alternative paths: ${alternativePaths.join(", ")}`, verbose);
57714
+ const tryNextPath = (paths) => {
57715
+ if (paths.length === 0) {
57716
+ res.writeHead(proxyRes.statusCode || 404, proxyRes.headers);
57717
+ proxyRes.pipe(res);
57718
+ return;
57719
+ }
57720
+ const altPath = paths[0];
57721
+ const altOptions = { ...proxyOptions, path: altPath };
57722
+ const altReq = http.request(altOptions, (altRes) => {
57723
+ if (altRes.statusCode === 200) {
57724
+ debugLog2("cleanUrls", `Found matching path: ${altPath}`, verbose);
57725
+ res.writeHead(altRes.statusCode, altRes.headers);
57726
+ altRes.pipe(res);
57727
+ } else {
57728
+ tryNextPath(paths.slice(1));
57729
+ }
57730
+ });
57731
+ altReq.on("error", () => tryNextPath(paths.slice(1)));
57732
+ altReq.end();
57733
+ };
57734
+ tryNextPath(alternativePaths);
57735
+ return;
57736
+ }
57737
+ }
57691
57738
  const headers = {
57692
57739
  ...proxyRes.headers,
57693
57740
  "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
@@ -57753,6 +57800,9 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
57753
57800
  console.log(` - HTTP/2 enabled`);
57754
57801
  console.log(` - HSTS enabled`);
57755
57802
  }
57803
+ if (cleanUrls) {
57804
+ console.log(` ${green("\u279C")} Clean URLs enabled`);
57805
+ }
57756
57806
  resolve4();
57757
57807
  });
57758
57808
  server.on("error", (err3) => {
@@ -57824,6 +57874,7 @@ function startProxy(options3) {
57824
57874
  const serverOptions = {
57825
57875
  from: mergedOptions.from,
57826
57876
  to: mergedOptions.to,
57877
+ cleanUrls: mergedOptions.cleanUrls,
57827
57878
  https: httpsConfig(mergedOptions),
57828
57879
  etcHostsCleanup: mergedOptions.etcHostsCleanup,
57829
57880
  verbose: mergedOptions.verbose
@@ -57865,11 +57916,13 @@ async function startProxies(options3) {
57865
57916
  ...proxy,
57866
57917
  https: mergedOptions.https,
57867
57918
  etcHostsCleanup: mergedOptions.etcHostsCleanup,
57919
+ cleanUrls: mergedOptions.cleanUrls,
57868
57920
  verbose: mergedOptions.verbose,
57869
57921
  _cachedSSLConfig: mergedOptions._cachedSSLConfig
57870
57922
  })) : [{
57871
57923
  from: mergedOptions.from || "localhost:5173",
57872
57924
  to: mergedOptions.to || "stacks.localhost",
57925
+ cleanUrls: mergedOptions.cleanUrls || false,
57873
57926
  https: mergedOptions.https,
57874
57927
  etcHostsCleanup: mergedOptions.etcHostsCleanup,
57875
57928
  verbose: mergedOptions.verbose,
@@ -57896,7 +57949,8 @@ async function startProxies(options3) {
57896
57949
  await startServer({
57897
57950
  from: option.from || "localhost:5173",
57898
57951
  to: domain,
57899
- https: option.https ?? false,
57952
+ cleanUrls: option.cleanUrls || false,
57953
+ https: option.https || false,
57900
57954
  etcHostsCleanup: option.etcHostsCleanup || false,
57901
57955
  verbose: option.verbose || false,
57902
57956
  _cachedSSLConfig: sslConfig
package/dist/index.js CHANGED
@@ -20467,7 +20467,7 @@ var quotes = collect([
20467
20467
  ]);
20468
20468
  var export_prompts = import_prompts.default;
20469
20469
  // package.json
20470
- var version = "0.5.1";
20470
+ var version = "0.6.0";
20471
20471
 
20472
20472
  // src/config.ts
20473
20473
  import { homedir } from "os";
@@ -20526,6 +20526,7 @@ async function loadConfig({ name, cwd, defaultConfig }) {
20526
20526
  var defaultConfig = {
20527
20527
  from: "localhost:5173",
20528
20528
  to: "stacks.localhost",
20529
+ cleanUrls: false,
20529
20530
  https: {
20530
20531
  basePath: "",
20531
20532
  caCertPath: join2(homedir(), ".stacks", "ssl", `stacks.localhost.ca.crt`),
@@ -57673,14 +57674,24 @@ async function startServer(options3) {
57673
57674
  ssl: sslConfig
57674
57675
  });
57675
57676
  }
57676
- async function createProxyServer(from, to, fromPort, listenPort, hostname, sourceUrl, ssl, verbose) {
57677
- debugLog("proxy", `Creating proxy server ${from} -> ${to}`, verbose);
57677
+ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourceUrl, ssl, verbose, cleanUrls) {
57678
+ debugLog("proxy", `Creating proxy server ${from} -> ${to} with cleanUrls: ${cleanUrls}`, verbose);
57678
57679
  const requestHandler = (req, res) => {
57679
57680
  debugLog("request", `Incoming request: ${req.method} ${req.url}`, verbose);
57681
+ let path4 = req.url || "/";
57682
+ if (cleanUrls) {
57683
+ if (!path4.match(/\.[a-z0-9]+$/i)) {
57684
+ if (path4.endsWith("/")) {
57685
+ path4 = `${path4}index.html`;
57686
+ } else {
57687
+ path4 = `${path4}.html`;
57688
+ }
57689
+ }
57690
+ }
57680
57691
  const proxyOptions = {
57681
57692
  hostname: sourceUrl.hostname,
57682
57693
  port: fromPort,
57683
- path: req.url,
57694
+ path: path4,
57684
57695
  method: req.method,
57685
57696
  headers: {
57686
57697
  ...req.headers,
@@ -57690,6 +57701,42 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
57690
57701
  debugLog("request", `Proxy request options: ${JSON.stringify(proxyOptions)}`, verbose);
57691
57702
  const proxyReq = http.request(proxyOptions, (proxyRes) => {
57692
57703
  debugLog("response", `Proxy response received with status ${proxyRes.statusCode}`, verbose);
57704
+ if (cleanUrls && proxyRes.statusCode === 404) {
57705
+ const alternativePaths = [];
57706
+ if (path4.endsWith(".html")) {
57707
+ alternativePaths.push(path4.slice(0, -5));
57708
+ } else if (!path4.match(/\.[a-z0-9]+$/i)) {
57709
+ alternativePaths.push(`${path4}.html`);
57710
+ }
57711
+ if (!path4.endsWith("/")) {
57712
+ alternativePaths.push(`${path4}/index.html`);
57713
+ }
57714
+ if (alternativePaths.length > 0) {
57715
+ debugLog("cleanUrls", `Trying alternative paths: ${alternativePaths.join(", ")}`, verbose);
57716
+ const tryNextPath = (paths) => {
57717
+ if (paths.length === 0) {
57718
+ res.writeHead(proxyRes.statusCode || 404, proxyRes.headers);
57719
+ proxyRes.pipe(res);
57720
+ return;
57721
+ }
57722
+ const altPath = paths[0];
57723
+ const altOptions = { ...proxyOptions, path: altPath };
57724
+ const altReq = http.request(altOptions, (altRes) => {
57725
+ if (altRes.statusCode === 200) {
57726
+ debugLog("cleanUrls", `Found matching path: ${altPath}`, verbose);
57727
+ res.writeHead(altRes.statusCode, altRes.headers);
57728
+ altRes.pipe(res);
57729
+ } else {
57730
+ tryNextPath(paths.slice(1));
57731
+ }
57732
+ });
57733
+ altReq.on("error", () => tryNextPath(paths.slice(1)));
57734
+ altReq.end();
57735
+ };
57736
+ tryNextPath(alternativePaths);
57737
+ return;
57738
+ }
57739
+ }
57693
57740
  const headers = {
57694
57741
  ...proxyRes.headers,
57695
57742
  "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
@@ -57755,6 +57802,9 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
57755
57802
  console.log(` - HTTP/2 enabled`);
57756
57803
  console.log(` - HSTS enabled`);
57757
57804
  }
57805
+ if (cleanUrls) {
57806
+ console.log(` ${green("\u279C")} Clean URLs enabled`);
57807
+ }
57758
57808
  resolve4();
57759
57809
  });
57760
57810
  server.on("error", (err3) => {
@@ -57826,6 +57876,7 @@ function startProxy(options3) {
57826
57876
  const serverOptions = {
57827
57877
  from: mergedOptions.from,
57828
57878
  to: mergedOptions.to,
57879
+ cleanUrls: mergedOptions.cleanUrls,
57829
57880
  https: httpsConfig(mergedOptions),
57830
57881
  etcHostsCleanup: mergedOptions.etcHostsCleanup,
57831
57882
  verbose: mergedOptions.verbose
@@ -57867,11 +57918,13 @@ async function startProxies(options3) {
57867
57918
  ...proxy,
57868
57919
  https: mergedOptions.https,
57869
57920
  etcHostsCleanup: mergedOptions.etcHostsCleanup,
57921
+ cleanUrls: mergedOptions.cleanUrls,
57870
57922
  verbose: mergedOptions.verbose,
57871
57923
  _cachedSSLConfig: mergedOptions._cachedSSLConfig
57872
57924
  })) : [{
57873
57925
  from: mergedOptions.from || "localhost:5173",
57874
57926
  to: mergedOptions.to || "stacks.localhost",
57927
+ cleanUrls: mergedOptions.cleanUrls || false,
57875
57928
  https: mergedOptions.https,
57876
57929
  etcHostsCleanup: mergedOptions.etcHostsCleanup,
57877
57930
  verbose: mergedOptions.verbose,
@@ -57898,7 +57951,8 @@ async function startProxies(options3) {
57898
57951
  await startServer({
57899
57952
  from: option.from || "localhost:5173",
57900
57953
  to: domain,
57901
- https: option.https ?? false,
57954
+ cleanUrls: option.cleanUrls || false,
57955
+ https: option.https || false,
57902
57956
  etcHostsCleanup: option.etcHostsCleanup || false,
57903
57957
  verbose: option.verbose || false,
57904
57958
  _cachedSSLConfig: sslConfig
package/dist/start.d.ts CHANGED
@@ -6,7 +6,7 @@ declare function isPortInUse(port: number, hostname: string, verbose?: boolean):
6
6
  declare function findAvailablePort(startPort: number, hostname: string, verbose?: boolean): Promise<number>;
7
7
  declare function testConnection(hostname: string, port: number, verbose?: boolean): Promise<void>;
8
8
  export declare function startServer(options: SingleReverseProxyConfig): Promise<void>;
9
- declare function createProxyServer(from: string, to: string, fromPort: number, listenPort: number, hostname: string, sourceUrl: Pick<URL, 'hostname' | 'host'>, ssl: SSLConfig | null, verbose?: boolean): Promise<void>;
9
+ declare function createProxyServer(from: string, to: string, fromPort: number, listenPort: number, hostname: string, sourceUrl: Pick<URL, 'hostname' | 'host'>, ssl: SSLConfig | null, verbose?: boolean, cleanUrls?: boolean): Promise<void>;
10
10
  export declare function setupReverseProxy(options: ProxySetupOptions): Promise<void>;
11
11
  export declare function startHttpRedirectServer(verbose?: boolean): void;
12
12
  export declare function startProxy(options: ReverseProxyOption): void;
package/dist/types.d.ts CHANGED
@@ -4,6 +4,7 @@ export type { TlsConfig, TlsOption }
4
4
  export declare interface BaseReverseProxyConfig {
5
5
  from: string
6
6
  to: string
7
+ cleanUrls: boolean
7
8
  }
8
9
  export declare type BaseReverseProxyOptions = Partial<BaseReverseProxyConfig>
9
10
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/rpx",
3
3
  "type": "module",
4
- "version": "0.5.1",
4
+ "version": "0.6.0",
5
5
  "description": "A modern reverse proxy.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",