From d07c89c8c33fd96fa6b9c83291b46cef3828fb80 Mon Sep 17 00:00:00 2001 From: Jay V Date: Wed, 18 Sep 2024 13:33:59 -0400 Subject: [PATCH] docs: bucket router change --- examples/aws-angular/sst.config.ts | 2 +- examples/aws-api/sst.config.ts | 2 +- examples/aws-astro/sst.config.ts | 2 +- examples/aws-cluster/sst.config.ts | 2 +- examples/aws-hono/sst.config.ts | 2 +- examples/aws-nextjs/sst.config.ts | 2 +- examples/aws-nuxt/sst.config.ts | 2 +- examples/aws-remix/sst.config.ts | 2 +- examples/aws-router/sst.config.ts | 2 +- examples/aws-svelte-kit/sst.config.ts | 2 +- examples/internal/playground/sst.config.ts | 2 +- platform/src/components/aws/bucket.ts | 21 ++- platform/src/components/aws/router.ts | 141 +++++++++++------- www/src/content/docs/docs/examples.mdx | 6 +- .../content/docs/docs/start/aws/angular.mdx | 4 +- www/src/content/docs/docs/start/aws/api.mdx | 4 +- www/src/content/docs/docs/start/aws/astro.mdx | 4 +- .../content/docs/docs/start/aws/container.mdx | 4 +- www/src/content/docs/docs/start/aws/hono.mdx | 4 +- .../content/docs/docs/start/aws/nextjs.mdx | 4 +- www/src/content/docs/docs/start/aws/nuxt.mdx | 4 +- www/src/content/docs/docs/start/aws/remix.mdx | 4 +- www/src/content/docs/docs/start/aws/solid.mdx | 4 +- .../content/docs/docs/start/aws/svelte.mdx | 4 +- 24 files changed, 135 insertions(+), 95 deletions(-) diff --git a/examples/aws-angular/sst.config.ts b/examples/aws-angular/sst.config.ts index cf5c3940d..2a2628ce9 100644 --- a/examples/aws-angular/sst.config.ts +++ b/examples/aws-angular/sst.config.ts @@ -10,7 +10,7 @@ export default $config({ }, async run() { const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public", }); const pre = new sst.aws.Function("MyFunction", { diff --git a/examples/aws-api/sst.config.ts b/examples/aws-api/sst.config.ts index 68e8e0b7c..5caa57124 100644 --- a/examples/aws-api/sst.config.ts +++ b/examples/aws-api/sst.config.ts @@ -10,7 +10,7 @@ export default $config({ }, async run() { const bucket = new sst.aws.Bucket("MyBucket", { - public: true, + access: "public", }); const api = new sst.aws.ApiGatewayV2("MyApi"); api.route("GET /", { diff --git a/examples/aws-astro/sst.config.ts b/examples/aws-astro/sst.config.ts index 5ff9e2ca6..f115965f2 100644 --- a/examples/aws-astro/sst.config.ts +++ b/examples/aws-astro/sst.config.ts @@ -10,7 +10,7 @@ export default $config({ }, async run() { const bucket = new sst.aws.Bucket("MyBucket", { - public: true, + access: "public", }); new sst.aws.Astro("MyWeb", { link: [bucket], diff --git a/examples/aws-cluster/sst.config.ts b/examples/aws-cluster/sst.config.ts index aa3faf970..2f93773c2 100644 --- a/examples/aws-cluster/sst.config.ts +++ b/examples/aws-cluster/sst.config.ts @@ -10,7 +10,7 @@ export default $config({ }, async run() { const bucket = new sst.aws.Bucket("MyBucket", { - public: true, + access: "public", }); const vpc = new sst.aws.Vpc("MyVpc"); diff --git a/examples/aws-hono/sst.config.ts b/examples/aws-hono/sst.config.ts index 8439d9fb9..c83f2bb13 100644 --- a/examples/aws-hono/sst.config.ts +++ b/examples/aws-hono/sst.config.ts @@ -15,7 +15,7 @@ export default $config({ }, async run() { const bucket = new sst.aws.Bucket("MyBucket", { - public: true, + access: "public", }); const hono = new sst.aws.Function("Hono", { url: true, diff --git a/examples/aws-nextjs/sst.config.ts b/examples/aws-nextjs/sst.config.ts index add71c305..9acb84a8f 100644 --- a/examples/aws-nextjs/sst.config.ts +++ b/examples/aws-nextjs/sst.config.ts @@ -10,7 +10,7 @@ export default $config({ }, async run() { const bucket = new sst.aws.Bucket("MyBucket", { - public: true, + access: "public", }); new sst.aws.Nextjs("MyWeb", { link: [bucket], diff --git a/examples/aws-nuxt/sst.config.ts b/examples/aws-nuxt/sst.config.ts index 1cf92a5e5..462d33051 100644 --- a/examples/aws-nuxt/sst.config.ts +++ b/examples/aws-nuxt/sst.config.ts @@ -10,7 +10,7 @@ export default $config({ }, async run() { const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public", }); new sst.aws.Nuxt("MyWeb", { link: [bucket], diff --git a/examples/aws-remix/sst.config.ts b/examples/aws-remix/sst.config.ts index 02983faf9..197bfb526 100644 --- a/examples/aws-remix/sst.config.ts +++ b/examples/aws-remix/sst.config.ts @@ -10,7 +10,7 @@ export default $config({ }, async run() { const bucket = new sst.aws.Bucket("MyBucket", { - public: true, + access: "public", }); new sst.aws.Remix("MyWeb", { link: [bucket], diff --git a/examples/aws-router/sst.config.ts b/examples/aws-router/sst.config.ts index 3a90c7f02..a314b27ea 100644 --- a/examples/aws-router/sst.config.ts +++ b/examples/aws-router/sst.config.ts @@ -19,7 +19,7 @@ export default $config({ url: true, }); const bucket = new sst.aws.Bucket("MyBucket", { - public: true, + access: "public", }); const router = new sst.aws.Router("MyRouter", { domain: "router.ion.dev.sst.dev", diff --git a/examples/aws-svelte-kit/sst.config.ts b/examples/aws-svelte-kit/sst.config.ts index 8ca8f4c67..2b00b759e 100644 --- a/examples/aws-svelte-kit/sst.config.ts +++ b/examples/aws-svelte-kit/sst.config.ts @@ -10,7 +10,7 @@ export default $config({ }, async run() { const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public", }); new sst.aws.SvelteKit("MyWeb", { link: [bucket], diff --git a/examples/internal/playground/sst.config.ts b/examples/internal/playground/sst.config.ts index 0a1f18559..372be351b 100644 --- a/examples/internal/playground/sst.config.ts +++ b/examples/internal/playground/sst.config.ts @@ -28,7 +28,7 @@ export default $config({ }, async run() { const bucket = new sst.aws.Bucket("MyBucket", { - public: true, + access: "public", transform: { bucket: (args) => { args.tags = { foo: "bar" }; diff --git a/platform/src/components/aws/bucket.ts b/platform/src/components/aws/bucket.ts index b2c9792c0..f65545b38 100644 --- a/platform/src/components/aws/bucket.ts +++ b/platform/src/components/aws/bucket.ts @@ -122,11 +122,16 @@ export interface BucketArgs { */ public?: Input; /** - * Enable public read access for all the files in the bucket. + * Enable public read access for all the files in the bucket. By default, no access is + * granted. * - * Following are the possible values: - * - `public`: Host files directly from the bucket. - * - `cloudfront`: Use CloudFront to serve files from the bucket. + * :::tip + * If you are using the `Router` to serve files from this bucket, you need to allow + * `cloudfront` access the bucket. + * ::: + * + * This adds a statement to the bucket policy that either allows `public` access or just + * `cloudfront` access. * * @example * ```js @@ -279,7 +284,7 @@ interface BucketRef { * * ```ts title="sst.config.ts" * new sst.aws.Bucket("MyBucket", { - * public: true + * access: "public" * }); * ``` * @@ -410,9 +415,9 @@ export class Bucket extends Component implements Link.Linkable { access === "public" ? { type: "*", identifiers: ["*"] } : { - type: "Service", - identifiers: ["cloudfront.amazonaws.com"], - }, + type: "Service", + identifiers: ["cloudfront.amazonaws.com"], + }, ], actions: ["s3:GetObject"], resources: [interpolate`${bucket.arn}/*`], diff --git a/platform/src/components/aws/router.ts b/platform/src/components/aws/router.ts index 11c0074c3..fcf4dd89a 100644 --- a/platform/src/components/aws/router.ts +++ b/platform/src/components/aws/router.ts @@ -25,15 +25,54 @@ export interface RouterUrlRouteArgs extends BaseRouteArgs { * ``` */ url: Input; + /** + * Rewrite the request path. + * + * @example + * + * By default, if the route path is `/api/*` and a request comes in for `/api/users/profile`, + * the request path the destination sees is `/api/users/profile`. + * + * If you want to serve the route from the root, you can rewrite the request path to + * `/users/profile`. + * + * ```js + * { + * routes: { + * "/api/*": { + * url: "https://api.example.com", + * rewrite: { + * regex: "^/api/(.*)$", + * to: "/$1" + * } + * } + * } + * } + * ``` + */ + rewrite?: Input<{ + /** + * The regex to match the request path. + */ + regex: Input; + /** + * The replacement for the matched path. + */ + to: Input; + }>; } export interface RouterBucketRouteArgs extends BaseRouteArgs { /** * A bucket to route to. * + * :::note + * You need to let CloudFront `access` the bucket. + * ::: + * * @example * - * For example, let's say you have a bucket. + * For example, let's say you have a bucket that gives CloudFront `access`. * * ```ts title="sst.config.ts" {2} * const myBucket = new sst.aws.Bucket("MyBucket", { @@ -41,11 +80,7 @@ export interface RouterBucketRouteArgs extends BaseRouteArgs { * }); * ``` * - * :::note - * The `access` props lets CloudFront access this bucket. - * ::: - * - * You can set this directly as the destination for the route. + * You can then this directly as the destination for the route. * * ```js * { @@ -70,9 +105,6 @@ export interface RouterBucketRouteArgs extends BaseRouteArgs { * ``` */ bucket?: Input; -} - -interface BaseRouteArgs { /** * Rewrite the request path. * @@ -109,6 +141,9 @@ interface BaseRouteArgs { */ to: Input; }>; +} + +interface BaseRouteArgs { /** * Configure CloudFront Functions to customize the behavior of HTTP requests and responses at the edge. */ @@ -307,8 +342,10 @@ export interface RouterArgs { * A map of routes to their destinations. The _key_ is the route path and the * _value_ can be: * - * - A string, the destination URL. - * - Or an object with the above properties. + * - The destination URL as a string + * - Or, an object with + * - Args for a URL route + * - Args for a bucket route * * :::note * All routes need to start with `/`. @@ -478,19 +515,21 @@ export interface RouterArgs { * * #### Route to a bucket * - * ```ts title="sst.config.ts" + * ```ts title="sst.config.ts" {2} * const myBucket = new sst.aws.Bucket("MyBucket", { - * access: "cloudfront", + * access: "cloudfront" * }); * * new sst.aws.Router("MyRouter", { * routes: { - * "/files/*": myBucket + * "/files/*": { + * bucket: myBucket + * } * } * }); * ``` * - * Make sure to allow AWS CloudFront to access the bucket by setting the `access` prop on the bucket. + * Make sure to allow CloudFront access to the bucket by setting the `access` prop on the bucket. * * #### Route all API requests separately * @@ -587,15 +626,15 @@ export class Router extends Component implements Link.Linkable { path: string, config: | { - injection: string; - kvStores?: string[]; - } + injection: string; + kvStores?: string[]; + } | undefined, rewrite: | { - regex: string; - to: string; - } + regex: string; + to: string; + } | undefined, injectHostHeader: boolean, ) { @@ -606,18 +645,16 @@ export class Router extends Component implements Link.Linkable { keyValueStoreAssociations: config?.kvStores ?? [], code: ` function handler(event) { - ${ - injectHostHeader - ? `event.request.headers["x-forwarded-host"] = event.request.headers.host;` - : "" - } - ${ - rewrite - ? ` + ${injectHostHeader + ? `event.request.headers["x-forwarded-host"] = event.request.headers.host;` + : "" + } + ${rewrite + ? ` const re = new RegExp("${rewrite.regex}"); event.request.uri = event.request.uri.replace(re, "${rewrite.to}");` - : "" - } + : "" + } ${config?.injection ?? ""} return event.request; }`, @@ -796,30 +833,30 @@ function handler(event) { functionAssociations: [ ...("url" in route || route.edge?.viewerRequest || route.rewrite ? [ - { - eventType: "viewer-request", - functionArn: - route.edge?.viewerRequest || route.rewrite - ? createCfRequestFunction( - path, - route.edge?.viewerRequest, - route.rewrite, - "url" in route, - ).arn - : createCfRequestDefaultFunction().arn, - }, - ] + { + eventType: "viewer-request", + functionArn: + route.edge?.viewerRequest || route.rewrite + ? createCfRequestFunction( + path, + route.edge?.viewerRequest, + route.rewrite, + "url" in route, + ).arn + : createCfRequestDefaultFunction().arn, + }, + ] : []), ...(route.edge?.viewerResponse ? [ - { - eventType: "viewer-response", - functionArn: createCfResponseFunction( - path, - route.edge.viewerResponse, - ).arn, - }, - ] + { + eventType: "viewer-response", + functionArn: createCfResponseFunction( + path, + route.edge.viewerResponse, + ).arn, + }, + ] : []), ], ...("url" in route ? urlDefaultConfig : bucketDefaultConfig), diff --git a/www/src/content/docs/docs/examples.mdx b/www/src/content/docs/docs/examples.mdx index 8a5173703..bcbcb2cb1 100644 --- a/www/src/content/docs/docs/examples.mdx +++ b/www/src/content/docs/docs/examples.mdx @@ -781,9 +781,7 @@ new aws.s3.BucketObjectv2("MyImage", { bucket: bucket.name, key: "public/spongebob.svg", contentType: "image/svg+xml", - source: new $util.asset.FileAsset( - path.join($cli.paths.root, "spongebob.svg") - ), + source: $asset("spongebob.svg"), }); const router = new sst.aws.Router("MyRouter", { @@ -813,7 +811,7 @@ const api = new sst.aws.Function("MyApi", { url: true, }); const bucket = new sst.aws.Bucket("MyBucket", { - public: true, + access: "public", }); const router = new sst.aws.Router("MyRouter", { domain: "router.ion.dev.sst.dev", diff --git a/www/src/content/docs/docs/start/aws/angular.mdx b/www/src/content/docs/docs/start/aws/angular.mdx index 59d08e943..96a749f08 100644 --- a/www/src/content/docs/docs/start/aws/angular.mdx +++ b/www/src/content/docs/docs/start/aws/angular.mdx @@ -41,11 +41,11 @@ This'll create a `sst.config.ts` file in your project root. ## 2. Add an S3 Bucket -Let's add a `public` S3 Bucket for file uploads. Update your `sst.config.ts`. +Let's allow public `access` to our S3 Bucket for file uploads. Update your `sst.config.ts`. ```ts title="sst.config.ts" const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public" }); ``` diff --git a/www/src/content/docs/docs/start/aws/api.mdx b/www/src/content/docs/docs/start/aws/api.mdx index 81efe18b1..edb667992 100644 --- a/www/src/content/docs/docs/start/aws/api.mdx +++ b/www/src/content/docs/docs/start/aws/api.mdx @@ -74,11 +74,11 @@ This will give you the URL of your API. ## 3. Add an S3 Bucket -Let's add a `public` S3 Bucket for file uploads. Update your `sst.config.ts`. +Let's allow public `access` to our S3 Bucket for file uploads. Update your `sst.config.ts`. ```js title="sst.config.ts" const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public" }); ``` diff --git a/www/src/content/docs/docs/start/aws/astro.mdx b/www/src/content/docs/docs/start/aws/astro.mdx index f2bcc5f0e..169f6a6b1 100644 --- a/www/src/content/docs/docs/start/aws/astro.mdx +++ b/www/src/content/docs/docs/start/aws/astro.mdx @@ -64,11 +64,11 @@ Once complete, click on **MyWeb** in the sidebar and open your Astro site in you ## 2. Add an S3 Bucket -Let's add a `public` S3 Bucket for file uploads. Update your `sst.config.ts`. +Let's allow public `access` to our S3 Bucket for file uploads. Update your `sst.config.ts`. ```js title="sst.config.ts" const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public" }); ``` diff --git a/www/src/content/docs/docs/start/aws/container.mdx b/www/src/content/docs/docs/start/aws/container.mdx index a258c47ab..966fc963c 100644 --- a/www/src/content/docs/docs/start/aws/container.mdx +++ b/www/src/content/docs/docs/start/aws/container.mdx @@ -108,11 +108,11 @@ ENTRYPOINT ["node", "index.mjs"] ## 3. Add an S3 Bucket -Let's add a `public` S3 Bucket for file uploads. Update your `sst.config.ts`. +Let's allow public `access` to our S3 Bucket for file uploads. Update your `sst.config.ts`. ```js title="sst.config.ts" const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public" }); ``` diff --git a/www/src/content/docs/docs/start/aws/hono.mdx b/www/src/content/docs/docs/start/aws/hono.mdx index 56d283b54..ab8eb0c6b 100644 --- a/www/src/content/docs/docs/start/aws/hono.mdx +++ b/www/src/content/docs/docs/start/aws/hono.mdx @@ -75,11 +75,11 @@ This will give you the URL of your API. ## 3. Add an S3 Bucket -Let's add a `public` S3 Bucket for file uploads. Update your `sst.config.ts`. +Let's allow public `access` to our S3 Bucket for file uploads. Update your `sst.config.ts`. ```js title="sst.config.ts" const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public" }); ``` diff --git a/www/src/content/docs/docs/start/aws/nextjs.mdx b/www/src/content/docs/docs/start/aws/nextjs.mdx index a95beeffc..25ed91330 100644 --- a/www/src/content/docs/docs/start/aws/nextjs.mdx +++ b/www/src/content/docs/docs/start/aws/nextjs.mdx @@ -52,11 +52,11 @@ Once complete, click on **MyWeb** in the sidebar and open your Next.js app in yo ## 2. Add an S3 Bucket -Let's add a `public` S3 Bucket for file uploads. Update your `sst.config.ts`. +Let's allow public `access` to our S3 Bucket for file uploads. Update your `sst.config.ts`. ```js title="sst.config.ts" const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public" }); ``` diff --git a/www/src/content/docs/docs/start/aws/nuxt.mdx b/www/src/content/docs/docs/start/aws/nuxt.mdx index 42ec22d40..963a8b51f 100644 --- a/www/src/content/docs/docs/start/aws/nuxt.mdx +++ b/www/src/content/docs/docs/start/aws/nuxt.mdx @@ -65,11 +65,11 @@ Once complete, click on **MyWeb** in the sidebar and open your Nuxt app in your ## 2. Add an S3 Bucket -Let's add a `public` S3 Bucket for file uploads. Update your `sst.config.ts`. +Let's allow public `access` to our S3 Bucket for file uploads. Update your `sst.config.ts`. ```ts title="sst.config.ts" const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public" }); ``` diff --git a/www/src/content/docs/docs/start/aws/remix.mdx b/www/src/content/docs/docs/start/aws/remix.mdx index 3283b0e3b..125122663 100644 --- a/www/src/content/docs/docs/start/aws/remix.mdx +++ b/www/src/content/docs/docs/start/aws/remix.mdx @@ -53,11 +53,11 @@ Once complete, click on **MyWeb** in the sidebar and open your Remix app in your ## 2. Add an S3 Bucket -Let's add a `public` S3 Bucket for file uploads. Update your `sst.config.ts`. +Let's allow public `access` to our S3 Bucket for file uploads. Update your `sst.config.ts`. ```js title="sst.config.ts" const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public" }); ``` diff --git a/www/src/content/docs/docs/start/aws/solid.mdx b/www/src/content/docs/docs/start/aws/solid.mdx index ccb8de30a..f3ea02d1f 100644 --- a/www/src/content/docs/docs/start/aws/solid.mdx +++ b/www/src/content/docs/docs/start/aws/solid.mdx @@ -63,11 +63,11 @@ Once complete, click on **MyWeb** in the sidebar and open your SolidStart app in ## 2. Add an S3 Bucket -Let's add a `public` S3 Bucket for file uploads. Update your `sst.config.ts`. +Let's allow public `access` to our S3 Bucket for file uploads. Update your `sst.config.ts`. ```js title="sst.config.ts" const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public" }); ``` diff --git a/www/src/content/docs/docs/start/aws/svelte.mdx b/www/src/content/docs/docs/start/aws/svelte.mdx index 02be2cf9b..1d633132a 100644 --- a/www/src/content/docs/docs/start/aws/svelte.mdx +++ b/www/src/content/docs/docs/start/aws/svelte.mdx @@ -60,11 +60,11 @@ Once complete, click on **MyWeb** in the sidebar and open your SvelteKit app in ## 2. Add an S3 Bucket -Let's add a `public` S3 Bucket for file uploads. Update your `sst.config.ts`. +Let's allow public `access` to our S3 Bucket for file uploads. Update your `sst.config.ts`. ```js title="sst.config.ts" const bucket = new sst.aws.Bucket("MyBucket", { - public: true + access: "public" }); ```