Files
0090faa253 feat(next): codemod for removed geo and ip of NextRequest (#70064)
> [!NOTE]
> This codemod requires to install the `@vercel/functions` package.

### Why?

Codemod support for breaking change at
https://github.com/vercel/next.js/pull/68379. It removed the `ip`, and
`geo` properties from the `NextRequest` type. The `NextRequest` type was
mostly used in the `middleware` and `route`.



### How?

The codemod replaces the `ip`, and `geo` properties from the
`NextRequest` with corresponding `@vercel/functions` features.

#### Accessing NextRequest Value

When a file uses `NextRequest`, we look if there's an access to the type
with `geo` or `ip`. This targets destructuring and direct access.

```ts
export function GET (req: NextRequest) {
  const { geo, ip: ipAlias, pathname } = req // destructuring
  // direct access
  req.geo
  req.ip
}
```

Declares a variable based on the identifier within the object. If it was
aliased, we use the aliased name.

```ts
import { geolocation, ipAddress } from '@vercel/functions'

export function GET (req: NextRequest) {
  const { pathname } = req // destructuring
  const geo = geolocation(req)
  const ipAlias = ipAddress(req)
  // direct access
  geolocation(req)
  ipAddress(req)
}
```

#### Accessing NextRequest Types

When the file has accessed the `geo | ip` type from `NextRequest`, we
replace with the corresponding types.

```ts
import type { NextRequest } from 'next/server'

export function GET (req: NextRequest) {
  const ip = '...' as NextRequest['ip']
  const geo = { ... } as NextRequest['geo']
}
```

Since the type for `ip` is `string | undefined`, we explicitly replace
it. For `geo`, we replace with the `Geo` type.

```ts
import type { NextRequest } from 'next/server'
import type { Geo } from '@vercel/functions'

export function GET (req: NextRequest) {
  const ip = '...' as string | undefined
  const geo = { ... } as Geo
}
```

### Ref

Behavior FYI:
https://github.com/vercel/next.js/pull/70064#discussion_r1768718840,
https://github.com/vercel/next.js/pull/70064#discussion_r1768722282
Closes NDX-291

---------

Co-authored-by: Sebastian Silbermann <[email protected]>
Co-authored-by: Donny/강동윤 <[email protected]>
Co-authored-by: Jiachi Liu <[email protected]>
2024-09-24 01:42:16 +09:00

17 lines
583 B
JavaScript

/* global jest */
jest.autoMockOff()
const defineTest = require('jscodeshift/dist/testUtils').defineTest
const { readdirSync } = require('fs')
const { join } = require('path')
const fixtureDir = 'next-request-geo-ip'
const fixtureDirPath = join(__dirname, '..', '__testfixtures__', fixtureDir)
const fixtures = readdirSync(fixtureDirPath)
.filter(file => file.endsWith('.input.ts'))
.map(file => file.replace('.input.ts', ''))
for (const fixture of fixtures) {
const prefix = `${fixtureDir}/${fixture}`;
defineTest(__dirname, fixtureDir, null, prefix, { parser: 'ts' });
}