-
Notifications
You must be signed in to change notification settings - Fork 83
/
server.ts
105 lines (98 loc) · 2.83 KB
/
server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { exec } from 'tinyexec'
import { getRandomPort, waitForPort } from 'get-port-please'
import type { FetchOptions } from 'ofetch'
import { $fetch as _$fetch, fetch as _fetch } from 'ofetch'
import * as _kit from '@nuxt/kit'
import { resolve } from 'pathe'
import { joinURL } from 'ufo'
import { useTestContext } from './context'
// @ts-expect-error type cast kit default export
const kit: typeof _kit = _kit.default || _kit
export interface StartServerOptions {
env?: Record<string, unknown>
}
export async function startServer(options: StartServerOptions = {}) {
const ctx = useTestContext()
await stopServer()
const host = '127.0.0.1'
const port = ctx.options.port || (await getRandomPort(host))
ctx.url = `http://${host}:${port}/`
if (ctx.options.dev) {
const nuxiCLI = await kit.resolvePath('nuxi/cli')
ctx.serverProcess = exec(nuxiCLI, ['_dev'], {
nodeOptions: {
cwd: ctx.nuxt!.options.rootDir,
stdio: 'inherit',
env: {
...process.env,
_PORT: String(port), // Used by internal _dev command
PORT: String(port),
HOST: host,
NODE_ENV: 'development',
...options.env,
...ctx.options.env,
},
},
})
await waitForPort(port, { retries: 32, host }).catch(() => {})
let lastError
for (let i = 0; i < 150; i++) {
await new Promise(resolve => setTimeout(resolve, 100))
try {
const res = await $fetch<string>(ctx.nuxt!.options.app.baseURL, {
responseType: 'text',
})
if (!res.includes('__NUXT_LOADING__')) {
return
}
}
catch (e) {
lastError = e
}
}
ctx.serverProcess.kill()
throw lastError || new Error('Timeout waiting for dev server!')
}
else {
ctx.serverProcess = exec(
'node',
[resolve(ctx.nuxt!.options.nitro.output!.dir!, 'server/index.mjs')],
{
nodeOptions: {
stdio: 'inherit',
env: {
...process.env,
PORT: String(port),
HOST: host,
NODE_ENV: 'test',
...options.env,
...ctx.options.env,
},
},
},
)
await waitForPort(port, { retries: 20, host })
}
}
export async function stopServer() {
const ctx = useTestContext()
if (ctx.serverProcess) {
ctx.serverProcess.kill()
}
}
export function fetch(path: string, options?: RequestInit) {
return _fetch(url(path), options)
}
export const $fetch = function (path: string, options?: FetchOptions) {
return _$fetch(url(path), options)
} as (typeof globalThis)['$fetch']
export function url(path: string) {
const ctx = useTestContext()
if (!ctx.url) {
throw new Error('url is not available (is server option enabled?)')
}
if (path.startsWith(ctx.url)) {
return path
}
return joinURL(ctx.url, path)
}