Skip to content

Commit

Permalink
Merge branch 'canary' into swc-up-123
Browse files Browse the repository at this point in the history
  • Loading branch information
ijjk committed Jul 8, 2022
2 parents e5a49c1 + 6d8b2cd commit 076c0ae
Show file tree
Hide file tree
Showing 103 changed files with 142 additions and 932 deletions.
3 changes: 3 additions & 0 deletions examples/api-routes-rate-limit/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ yarn-error.log*

# vercel
.vercel

# typescript
*.tsbuildinfo
15 changes: 11 additions & 4 deletions examples/api-routes-rate-limit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@
"start": "next start"
},
"dependencies": {
"lru-cache": "^6.0.0",
"lru-cache": "^7.12.0",
"next": "latest",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"uuid": "^8.3.1"
"react": "^18.2.0",
"react-dom": "^18.2.0",
"uuid": "^8.3.2"
},
"devDependencies": {
"@types/node": "^18.0.3",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"@types/uuid": "^8.3.4",
"typescript": "^4.7.4"
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import * as uuid from 'uuid'
import type { NextApiRequest, NextApiResponse } from 'next'
import { v4 as uuidv4 } from 'uuid'
import rateLimit from '../../utils/rate-limit'

const limiter = rateLimit({
interval: 60 * 1000, // 60 seconds
uniqueTokenPerInterval: 500, // Max 500 users per second
})

export default async function handler(req, res) {
export default async function handler(
_req: NextApiRequest,
res: NextApiResponse
) {
try {
await limiter.check(res, 10, 'CACHE_TOKEN') // 10 requests per minute
res.status(200).json({ id: uuid.v4() })
res.status(200).json({ id: uuidv4() })
} catch {
res.status(429).json({ error: 'Rate limit exceeded' })
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useState } from 'react'
import styles from '../styles.module.css'

export default function Index() {
const [response, setResponse] = useState()
const [response, setResponse] = useState<Record<string, unknown> | null>(null)

const makeRequest = async () => {
const res = await fetch('/api/user')
Expand All @@ -24,29 +24,11 @@ export default function Index() {
Functions).
</p>
<button onClick={() => makeRequest()}>Make Request</button>
<code className={styles.code}>
<div>
<b>Status Code: </b>
{response?.status || 'None'}
</div>
<div>
<b>Request Limit: </b>
{response?.limit || 'None'}
</div>
<div>
<b>Remaining Requests: </b>
{response?.remaining || 'None'}
</div>
<div>
<b>Body: </b>
{JSON.stringify(response?.body) || 'None'}
</div>
</code>
<div className={styles.links}>
<a href="#">View Source</a>
{' | '}
<a href="#">Deploy You Own ▲</a>
</div>
{response && (
<code className={styles.code}>
<pre>{JSON.stringify(response, null, 2)}</pre>
</code>
)}
</main>
)
}
20 changes: 20 additions & 0 deletions examples/api-routes-rate-limit/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
31 changes: 0 additions & 31 deletions examples/api-routes-rate-limit/utils/rate-limit.js

This file was deleted.

35 changes: 35 additions & 0 deletions examples/api-routes-rate-limit/utils/rate-limit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { NextApiResponse } from 'next'
import LRU from 'lru-cache'

type Options = {
uniqueTokenPerInterval?: number
interval?: number
}

export default function rateLimit(options?: Options) {
const tokenCache = new LRU({
max: options?.uniqueTokenPerInterval || 500,
ttl: options?.interval || 60000,
})

return {
check: (res: NextApiResponse, limit: number, token: string) =>
new Promise<void>((resolve, reject) => {
const tokenCount = (tokenCache.get(token) as number[]) || [0]
if (tokenCount[0] === 0) {
tokenCache.set(token, tokenCount)
}
tokenCount[0] += 1

const currentUsage = tokenCount[0]
const isRateLimited = currentUsage >= limit
res.setHeader('X-RateLimit-Limit', limit)
res.setHeader(
'X-RateLimit-Remaining',
isRateLimited ? 0 : limit - currentUsage
)

return isRateLimited ? reject() : resolve()
}),
}
}
37 changes: 0 additions & 37 deletions examples/blog-starter-typescript/.gitignore

This file was deleted.

36 changes: 2 additions & 34 deletions examples/blog-starter-typescript/README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,3 @@
# A statically generated blog example using Next.js, Markdown, and TypeScript
## Deprecated

This is the existing [blog-starter](https://github.com/vercel/next.js/tree/canary/examples/blog-starter) plus TypeScript.

This example showcases Next.js's [Static Generation](https://nextjs.org/docs/basic-features/pages) feature using Markdown files as the data source.

The blog posts are stored in `/_posts` as Markdown files with front matter support. Adding a new Markdown file in there will create a new blog post.

To create the blog posts we use [`remark`](https://github.com/remarkjs/remark) and [`remark-html`](https://github.com/remarkjs/remark-html) to convert the Markdown files into an HTML string, and then send it down as a prop to the page. The metadata of every post is handled by [`gray-matter`](https://github.com/jonschlinkert/gray-matter) and also sent in props to the page.

## Deploy your own

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/blog-starter-typescript)

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/blog-starter-typescript&project-name=blog-starter-typescript&repository-name=blog-starter-typescript)

## How to use

Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example:

```bash
npx create-next-app --example blog-starter-typescript blog-starter-typescript-app
# or
yarn create next-app --example blog-starter-typescript blog-starter-typescript-app
# or
pnpm create next-app --example blog-starter-typescript blog-starter-typescript-app
```

Your blog should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions).

Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).

# Notes

`blog-starter-typescript` uses [Tailwind CSS](https://tailwindcss.com) [(v3.0)](https://tailwindcss.com/blog/tailwindcss-v3).
The main [blog-starter](/examples/blog-starter) example has been refactored to use TypeScript, so this example is deprecated.
19 changes: 0 additions & 19 deletions examples/blog-starter-typescript/_posts/dynamic-routing.md

This file was deleted.

19 changes: 0 additions & 19 deletions examples/blog-starter-typescript/_posts/hello-world.md

This file was deleted.

19 changes: 0 additions & 19 deletions examples/blog-starter-typescript/_posts/preview.md

This file was deleted.

11 changes: 0 additions & 11 deletions examples/blog-starter-typescript/components/container.tsx

This file was deleted.

This file was deleted.

4 changes: 0 additions & 4 deletions examples/blog-starter-typescript/lib/constants.ts

This file was deleted.

29 changes: 0 additions & 29 deletions examples/blog-starter-typescript/package.json

This file was deleted.

6 changes: 0 additions & 6 deletions examples/blog-starter-typescript/postcss.config.js

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
3 changes: 0 additions & 3 deletions examples/blog-starter-typescript/styles/index.css

This file was deleted.

0 comments on commit 076c0ae

Please sign in to comment.