Skip to content

Commit

Permalink
feat: support runtime proxy using route rules (#926)
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 authored Feb 8, 2023
1 parent aa5a2f4 commit 4d8cda3
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
17 changes: 9 additions & 8 deletions docs/content/3.config/index.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
---
title: Configuration
aside: false
description: 'Customize your Nitro app with a configuration file!'
description: "Customize your Nitro app with a configuration file!"
---

In order to customize nitro's behavior, we create a file named `nitro.config.ts`.

```js
// nitro.config.ts
import { defineNitroConfig } from 'nitropack'
import { defineNitroConfig } from "nitropack";

export default defineNitroConfig({
})
export default defineNitroConfig({});
```

## Config Reference
Expand Down Expand Up @@ -219,11 +218,11 @@ Path to a custom runtime error handler. Replacing nitro's built-in error page.
**Example:**

```js [nitro.config]
import { defineNitroConfig } from 'nitropack'
import { defineNitroConfig } from "nitropack";

export default defineNitroConfig({
errorHandler: '~/error'
})
errorHandler: "~/error",
});
```

```js [error.ts]
Expand Down Expand Up @@ -253,7 +252,9 @@ When `cache` option is set, handlers matching pattern will be automatically wrap
'/blog/**': { cache: { /* cache options*/ } },
'/assets/**': { headers: { 'cache-control': 's-maxage=0' } },
'/api/v1/**': { cors: true, headers: { 'access-control-allowed-methods': 'GET' } },
'/old-page': { redirect: '/new-page' }
'/old-page': { redirect: '/new-page' },
'/proxy/example': { proxy: 'https://example.com' },
"/proxy/**": { proxy: '/api/**' },
}
}
```
Expand Down
12 changes: 12 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ export async function loadOptions(
const routeRules: NitroRouteRules = {
...routeConfig,
redirect: undefined,
proxy: undefined,
};
// Redirect
if (routeConfig.redirect) {
Expand All @@ -258,6 +259,17 @@ export async function loadOptions(
: routeConfig.redirect),
};
}
// Proxy
if (routeConfig.proxy) {
routeRules.proxy =
typeof routeConfig.proxy === "string"
? { to: routeConfig.proxy }
: routeConfig.proxy;
if (path.endsWith("/**")) {
// Internal flag
(routeRules.proxy as any)._proxyStripBase = path.slice(0, -3);
}
}
// CORS
if (routeConfig.cors) {
routeRules.headers = {
Expand Down
26 changes: 24 additions & 2 deletions src/runtime/route-rules.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { eventHandler, H3Event, sendRedirect, setHeaders } from "h3";
import {
eventHandler,
H3Event,
sendRedirect,
setHeaders,
proxyRequest,
} from "h3";
import defu from "defu";
import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";
import { withoutBase } from "ufo";
import { joinURL, withoutBase } from "ufo";
import { useRuntimeConfig } from "./config";
import type { NitroRouteRules } from "nitropack";

Expand All @@ -26,6 +32,22 @@ export function createRouteRulesHandler() {
routeRules.redirect.statusCode
);
}
// Apply proxy options
if (routeRules.proxy) {
let target = routeRules.proxy.to;
if (target.endsWith("/**")) {
let targetPath = event.path;
const strpBase = (routeRules.proxy as any)._proxyStripBase;
if (strpBase) {
targetPath = withoutBase(targetPath, strpBase);
}
target = joinURL(target.slice(0, -3), targetPath);
}
return proxyRequest(event, target, {
fetch: $fetch.raw as any,
...routeRules.proxy,
});
}
});
}

Expand Down
3 changes: 3 additions & 0 deletions src/types/nitro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { RollupCommonJSOptions } from "@rollup/plugin-commonjs";
import type { RollupWasmOptions } from "@rollup/plugin-wasm";
import type { Storage, BuiltinDriverName } from "unstorage";
import type { ServerOptions as HTTPProxyOptions } from "http-proxy";
import type { ProxyOptions } from "h3";
import type { NodeExternalsOptions } from "../rollup/plugins/externals";
import type { RollupConfig } from "../rollup/config";
import type { Options as EsbuildOptions } from "../rollup/plugins/esbuild";
Expand Down Expand Up @@ -124,6 +125,7 @@ export interface NitroRouteConfig {
headers?: Record<string, string>;
redirect?: string | { to: string; statusCode?: HTTPStatusCode };
prerender?: boolean;
proxy?: string | ({ to: string } & ProxyOptions);

// Shortcuts
cors?: boolean;
Expand All @@ -134,6 +136,7 @@ export interface NitroRouteConfig {
export interface NitroRouteRules
extends Omit<NitroRouteConfig, "redirect" | "cors" | "swr" | "static"> {
redirect?: { to: string; statusCode: HTTPStatusCode };
proxy?: { to: string } & ProxyOptions;
}

export interface NitroOptions extends PresetOptions {
Expand Down

0 comments on commit 4d8cda3

Please sign in to comment.