-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbasic-usage.ts
More file actions
116 lines (104 loc) · 2.88 KB
/
basic-usage.ts
File metadata and controls
116 lines (104 loc) · 2.88 KB
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
106
107
108
109
110
111
112
113
114
115
116
import type { HattipHandler } from '@hattip/core'
import * as z from 'zod'
import { $type, chain, createClient, createRouter } from 'rouzer'
import * as http from 'rouzer/http'
type Profile = {
id: string
name: string
includePosts: boolean
requestId: string
}
export const profiles = http.resource('profiles/:id', {
get: http.get({
query: z.object({
includePosts: z.optional(z.boolean()),
}),
response: $type<Profile>(),
}),
update: http.patch({
body: z.object({
name: z.string().check(z.minLength(1)),
}),
headers: z.object({
'content-type': z.literal('application/json'),
}),
response: $type<Profile>(),
}),
})
export const routes = { profiles }
/**
* Tiny Hattip adapter used only to keep this example self-contained. Real apps
* mount the handler with a Hattip adapter for their runtime.
*/
function createLocalFetch(handler: HattipHandler): typeof fetch {
return async (input, init) => {
const request = new Request(input, init)
const response = await handler({
request,
ip: '127.0.0.1',
platform: undefined,
env() {
return undefined
},
passThrough() {},
waitUntil(promise) {
void promise
},
})
return response ?? new Response(null, { status: 404 })
}
}
export async function runBasicUsageExample() {
const profileMap = new Map([['42', { id: '42', name: 'Ada' }]])
const requestMiddleware = chain().use(ctx => ({
requestId: ctx.request.headers.get('x-request-id') ?? 'local',
}))
const handler = createRouter({ basePath: 'api/' })
.use(requestMiddleware)
.use(routes, {
profiles: {
get(ctx) {
const profile = profileMap.get(ctx.path.id)
if (!profile) {
return new Response('Profile not found', { status: 404 })
}
return {
...profile,
includePosts: ctx.query.includePosts ?? false,
requestId: ctx.requestId,
}
},
update(ctx) {
const current = profileMap.get(ctx.path.id)
if (!current) {
return new Response('Profile not found', { status: 404 })
}
const profile = { ...current, name: ctx.body.name }
profileMap.set(ctx.path.id, profile)
return {
...profile,
includePosts: false,
requestId: ctx.requestId,
}
},
},
})
const client = createClient({
baseURL: 'https://example.test/api/',
routes,
headers: {
'content-type': 'application/json',
},
fetch: createLocalFetch(handler),
})
const fetched = await client.profiles.get({
path: { id: '42' },
query: { includePosts: false },
headers: { 'x-request-id': 'docs' },
})
const updated = await client.profiles.update({
path: { id: '42' },
body: { name: 'Grace' },
})
return { fetched, updated }
}