Skip to content

Commit e4485a8

Browse files
committed
chore: add vercel edge end2end test
1 parent 13c5054 commit e4485a8

File tree

2 files changed

+174
-0
lines changed

2 files changed

+174
-0
lines changed

e2e/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import { dockerDeployment } from './tests/docker'
77
import { DeploymentConfiguration } from './types'
88
import { env, getCommitId } from './utils'
99
import { vercelDeployment } from './tests/vercel'
10+
import { vercelEdgeDeployment } from './tests/vercel-edge'
1011

1112
const AVAILABLE_TEST_PLANS = {
1213
'cf-worker': cloudFlareDeployment,
1314
'cf-modules': cfModulesDeployment,
1415
'azure-function': azureFunctionDeployment,
1516
'aws-lambda': awsLambdaDeployment,
1617
'vercel-function': vercelDeployment,
18+
'vercel-edge': vercelEdgeDeployment,
1719
'docker-node-17': dockerDeployment('node:17.8.0-alpine3.14'),
1820
}
1921

e2e/tests/vercel-edge.ts

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import * as pulumi from '@pulumi/pulumi'
2+
import {
3+
assertGraphiQL,
4+
assertQuery,
5+
env,
6+
execPromise,
7+
fsPromises,
8+
waitForEndpoint,
9+
} from '../utils'
10+
import { DeploymentConfiguration } from '../types'
11+
12+
type VercelProviderInputs = {
13+
name: string
14+
files: {
15+
file: string
16+
data: string
17+
}[]
18+
projectSettings: {
19+
framework: string
20+
}
21+
functions: Record<
22+
string,
23+
{
24+
memory: number
25+
maxDuration: number
26+
}
27+
>
28+
}
29+
30+
type VercelDeploymentInputs = {
31+
[K in keyof VercelProviderInputs]: pulumi.Input<VercelProviderInputs[K]>
32+
}
33+
34+
class VercelProvider implements pulumi.dynamic.ResourceProvider {
35+
private baseUrl = 'https://api.vercel.com'
36+
private authToken = env('VERCEL_AUTH_TOKEN')
37+
38+
private getTeamId(): string | null {
39+
try {
40+
return env('VERCEL_TEAM_ID')
41+
} catch {
42+
return null
43+
}
44+
}
45+
46+
async delete(id: string) {
47+
const teamId = this.getTeamId()
48+
const response = await fetch(
49+
`${this.baseUrl}/v13/deployments/${id}${
50+
teamId ? `?teamId=${teamId}` : ''
51+
}`,
52+
{
53+
method: 'DELETE',
54+
headers: {
55+
Authorization: `Bearer ${this.authToken}`,
56+
},
57+
},
58+
)
59+
60+
if (response.status !== 200) {
61+
throw new Error(
62+
`Failed to delete Vercel deployment: invalid status code (${
63+
response.status
64+
}), body: ${await response.text()}`,
65+
)
66+
}
67+
}
68+
69+
async create(
70+
inputs: VercelProviderInputs,
71+
): Promise<pulumi.dynamic.CreateResult> {
72+
const teamId = this.getTeamId()
73+
const response = await fetch(
74+
`${this.baseUrl}/v13/deployments${teamId ? `?teamId=${teamId}` : ''}`,
75+
{
76+
method: 'POST',
77+
headers: {
78+
'content-type': 'application/json',
79+
Authorization: `Bearer ${this.authToken}`,
80+
},
81+
body: JSON.stringify({
82+
name: inputs.name,
83+
files: inputs.files,
84+
functions: inputs.functions,
85+
projectSettings: inputs.projectSettings,
86+
}),
87+
},
88+
)
89+
90+
if (response.status !== 200) {
91+
throw new Error(
92+
`Failed to create Vercel deployment: invalid status code (${
93+
response.status
94+
}), body: ${await response.text()}`,
95+
)
96+
}
97+
98+
const responseJson = await response.json()
99+
100+
return {
101+
id: responseJson.id,
102+
outs: {
103+
url: responseJson.url,
104+
},
105+
}
106+
}
107+
}
108+
109+
export class VercelDeployment extends pulumi.dynamic.Resource {
110+
public readonly url: pulumi.Output<string>
111+
112+
constructor(
113+
name: string,
114+
props: VercelDeploymentInputs,
115+
opts?: pulumi.CustomResourceOptions,
116+
) {
117+
super(
118+
new VercelProvider(),
119+
name,
120+
{
121+
url: undefined,
122+
...props,
123+
},
124+
opts,
125+
)
126+
}
127+
}
128+
129+
export const vercelEdgeDeployment: DeploymentConfiguration<{
130+
functionUrl: string
131+
}> = {
132+
prerequisites: async () => {
133+
// Build and bundle the function
134+
console.info('\t\tℹ️ Bundling the Vercel Function....')
135+
await execPromise('pnpm bundle', {
136+
cwd: '../examples/nextjs-edge',
137+
})
138+
},
139+
program: async () => {
140+
const deployment = new VercelDeployment('vercel-function', {
141+
files: [
142+
{
143+
file: '/api/graphql.js',
144+
data: await fsPromises.readFile(
145+
'../examples/nextjs-edge/dist/index.js',
146+
'utf-8',
147+
),
148+
},
149+
],
150+
name: `yoga-e2e-testing`,
151+
functions: {
152+
'api/graphql.js': {
153+
memory: 256,
154+
maxDuration: 5,
155+
},
156+
},
157+
projectSettings: {
158+
framework: null,
159+
},
160+
})
161+
162+
return {
163+
functionUrl: pulumi.interpolate`https://${deployment.url}/api/graphql`,
164+
}
165+
},
166+
test: async ({ functionUrl }) => {
167+
console.log(`ℹ️ Vercel Edge Function deployed to URL: ${functionUrl.value}`)
168+
await waitForEndpoint(functionUrl.value, 5, 10000)
169+
await assertGraphiQL(functionUrl.value)
170+
await assertQuery(functionUrl.value)
171+
},
172+
}

0 commit comments

Comments
 (0)