Skip to content

Commit a59fc2c

Browse files
committed
chore: nuxt 4 compat
1 parent 7aa61f5 commit a59fc2c

15 files changed

+910
-283
lines changed

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,10 @@
114114
"unrs-resolver",
115115
"vue-demi"
116116
]
117+
},
118+
"resolutions": {
119+
"@nuxt/kit": "npm:@nuxt/[email protected]",
120+
"@nuxt/schema": "npm:@nuxt/[email protected]",
121+
"nuxt": "npm:[email protected]"
117122
}
118123
}

pnpm-lock.yaml

Lines changed: 860 additions & 239 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/module.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -528,10 +528,11 @@ export {}
528528

529529
// only prerender for `nuxi generate`
530530
const isFirebase = nitroPreset === 'firebase'
531-
if ((isNuxtGenerate() || (isFirebase && nuxt.options._build)) && config.robotsTxt) {
532-
nuxt.options.generate = nuxt.options.generate || {}
533-
nuxt.options.generate.routes = asArray(nuxt.options.generate.routes || [])
534-
nuxt.options.generate.routes.push('/robots.txt')
531+
// @ts-expected-error nuxt 3
532+
if ((isNuxtGenerate() || isFirebase) && config.robotsTxt) {
533+
nuxt.options.nitro.prerender = nuxt.options.nitro.prerender || {}
534+
nuxt.options.nitro.prerender.routes = nuxt.options.nitro.prerender.routes || []
535+
nuxt.options.nitro.prerender.routes.push('/robots.txt')
535536
if (isFirebase)
536537
logger.info('Firebase does not support dynamic robots.txt files. Prerendering /robots.txt.')
537538
}

src/runtime/server/plugins/initContext.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ export default defineNitroPlugin(async (nitroApp: NitroApp) => {
4444
const isIsland = (process.env.NUXT_COMPONENT_ISLANDS && event.path.startsWith('/__nuxt_island'))
4545
const noSSR = !!(process.env.NUXT_NO_SSR)
4646
|| event.context.nuxt?.noSSR
47-
// @ts-expect-error upstream type issue
4847
|| (routeOptions.ssr === false && !isIsland)
4948
|| (import.meta.prerender ? PRERENDER_NO_SSR_ROUTES.has(event.path) : false)
5049
if (noSSR) {

src/util.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ export function parseRobotsTxt(s: string): ParsedRobotsTxt {
5050
// read the contents
5151
for (const _line of s.split('\n')) {
5252
ln++
53-
const [line] = _line.split('#').map(s => s.trim())
53+
const [preComment] = _line.split('#').map(s => s.trim())
54+
const line = String(preComment)
5455
const sepIndex = line.indexOf(':')
5556
// may not exist for comments
5657
if (sepIndex === -1)
@@ -151,15 +152,17 @@ function matches(pattern: string, path: string): boolean {
151152
}
152153

153154
if (pattern[p] === '*') {
155+
// @ts-expect-error untyped
154156
numMatchingLengths = pathLength - matchingLengths[0] + 1
155157
for (let i = 1; i < numMatchingLengths; i++) {
158+
// @ts-expect-error untyped
156159
matchingLengths[i] = matchingLengths[i - 1] + 1
157160
}
158161
}
159162
else {
160163
let numMatches = 0
161164
for (let i = 0; i < numMatchingLengths; i++) {
162-
const matchLength = matchingLengths[i]
165+
const matchLength = matchingLengths[i] as number
163166
if (matchLength < pathLength && path[matchLength] === pattern[p]) {
164167
matchingLengths[numMatches++] = matchLength + 1
165168
}
@@ -182,7 +185,7 @@ export function matchPathToRule(path: string, _rules: Required<RobotsGroupResolv
182185
let i = 0
183186
while (i < rulesLength) {
184187
const rule = rules[i]
185-
if (!matches(rule.pattern, path)) {
188+
if (!rule || !matches(rule.pattern, path)) {
186189
i++
187190
continue
188191
}

test/e2e/bot-detection.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('bot detection', () => {
1717
headers: {
1818
'user-agent': 'Googlebot/2.1 (+http://www.google.com/bot.html)',
1919
},
20-
})
20+
}) as any
2121

2222
expect(botResult.isBot).toBe(true)
2323
expect(botResult.botName).toBe('googlebot')
@@ -29,7 +29,7 @@ describe('bot detection', () => {
2929
headers: {
3030
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
3131
},
32-
})
32+
}) as any
3333

3434
expect(humanResult.isBot).toBe(false)
3535
expect(humanResult.botName).toBeUndefined()
@@ -53,7 +53,7 @@ describe('bot detection', () => {
5353

5454
it('compares browser fingerprinting vs server-side detection', async () => {
5555
// Server-side detection (should not detect browser as bot)
56-
const serverResult = await $fetch('/api/bot-detection')
56+
const serverResult = await $fetch('/api/bot-detection') as any
5757
expect(serverResult.isBot).toBe(false)
5858

5959
// Client-side fingerprinting (should detect automation)

test/e2e/default.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ await setup({
1414

1515
describe('default', () => {
1616
it('basic', async () => {
17-
expect(await $fetch('/robots.txt')).toMatchInlineSnapshot(`
17+
const robots = await $fetch('/robots.txt')
18+
expect(robots).toMatchInlineSnapshot(`
1819
"# START nuxt-robots (indexable)
1920
User-agent: *
2021
Allow: /secret/exception

test/e2e/groups.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ await setup({
3838

3939
describe('stack', () => {
4040
it('basic', async () => {
41+
// @ts-expect-error untyped
4142
expect(await $fetch('/robots.txt')).toMatchInlineSnapshot(`
4243
"# START nuxt-robots (indexable)
4344
User-agent: Googlebot

test/e2e/i18n.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ describe('i18n', () => {
3838
`)
3939
})
4040
it('respects route rules', async () => {
41+
// @ts-expect-error untyped
4142
expect((await $fetch('/en/route-rules/?mockProductionEnv=true')).match(/<meta name="robots" content="([^"]+)">/)[1]).toMatchInlineSnapshot(`"noindex, nofollow"`)
4243
})
4344
})

test/e2e/queryOverride.test.ts

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,30 @@ import { describe, expect, it } from 'vitest'
44

55
const { resolve } = createResolver(import.meta.url)
66

7-
process.env.NODE_ENV = 'production'
8-
await setup({
9-
rootDir: resolve('../fixtures/basic'),
10-
build: true,
11-
nuxtConfig: {
12-
site: {
13-
env: 'staging', // staging blocks
14-
url: 'https://example.com',
15-
},
7+
describe('query override', async () => {
8+
process.env.NODE_ENV = 'production'
9+
await setup({
10+
rootDir: resolve('../fixtures/basic'),
11+
build: true,
12+
nuxtConfig: {
13+
site: {
14+
env: 'staging', // staging blocks
15+
url: 'https://example.com',
16+
},
1617

17-
robots: {
18-
debug: true,
18+
robots: {
19+
debug: true,
20+
},
1921
},
20-
},
21-
})
22-
23-
describe('query override', () => {
22+
})
2423
it('robots.txt', async () => {
2524
// blocked by default
2625
expect(await $fetch('/robots.txt')).toContain('(indexing disabled)')
2726
// but can be overridden
28-
expect(await $fetch('/robots.txt', {
29-
params: {
30-
mockProductionEnv: true,
31-
},
32-
})).toContain('(indexable)')
27+
expect(await $fetch('/robots.txt?mockProductionEnv=true')).toContain('(indexable)')
3328
})
3429
it('page', async () => {
3530
const homeResponse = await $fetch('/')
36-
expect(homeResponse.match(/<meta name="robots" content="(.*)">/)?.[1]).toMatchInlineSnapshot(`"noindex, nofollow"`)
31+
expect(homeResponse.match(/<meta name="robots" content="([^"]*)">/)?.[1]).toBe('noindex, nofollow')
3732
})
3833
})

0 commit comments

Comments
 (0)