Skip to content

Commit 882e7eb

Browse files
authored
Merge pull request #2 from softnetics/yu/feat/rewrite-server-function
[DRIZZ-39] Server Function RPC
2 parents 5be46b1 + 82a92ad commit 882e7eb

18 files changed

Lines changed: 165 additions & 355 deletions

File tree

.changeset/itchy-peaches-peel.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@example/erp": patch
3+
"@kivotos/core": minor
4+
"@kivotos/next": minor
5+
---
6+
7+
[[DRIZZ-39] Server Function RPC](https://app.plane.so/softnetics/browse/DRIZZ-39/)

examples/erp/drizzlify/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const serverConfig = baseConfig.toServerConfig({
2323
},
2424
({ query }) => {
2525
return {
26-
status: 200,
26+
status: 200 as const,
2727
body: {
2828
message: `Hello ${query.name ?? 'World'}`,
2929
},
@@ -45,7 +45,7 @@ export const serverConfig = baseConfig.toServerConfig({
4545
},
4646
({ query }) => {
4747
return {
48-
status: 200,
48+
status: 200 as const,
4949
body: {
5050
message: `Hello2 ${query.name ?? 'World'}`,
5151
},

packages/core/src/auth/context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export type AuthContext<TConfig extends AuthConfig = AuthConfig> = {
2626
authConfig: TConfig
2727
internalHandlers: InternalHandlers
2828

29-
requiredAuthenticated: (headers: Headers) => Promise<InferTableType<AnyUserTable>>
29+
requiredAuthenticated: (headers: Record<string, string>) => Promise<InferTableType<AnyUserTable>>
3030
}
3131

3232
export function createAuthContext<TAuthConfig extends AuthConfig, TContext extends MinimalContext>(
@@ -39,7 +39,7 @@ export function createAuthContext<TAuthConfig extends AuthConfig, TContext exten
3939
authConfig: authConfig,
4040
internalHandlers: internalHandlers,
4141

42-
requiredAuthenticated: async (headers: Headers) => {
42+
requiredAuthenticated: async (headers: Record<string, string>) => {
4343
const sessionId = getSessionCookie(headers)
4444
if (!sessionId) throw new Error('Unauthorized')
4545
const session = await internalHandlers.session.findUserBySessionId(sessionId)

packages/core/src/auth/handlers/forgot-password.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import z from 'zod'
22

3-
import { ApiRoute, ApiRouteHandler, ApiRouteSchema } from '~/core/endpoint'
4-
3+
import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
54
import { AuthContext } from '../context'
65
import { WithPrefix } from '../types'
76

@@ -14,18 +13,17 @@ export function forgotPasswordEmail<const TOptions extends InternalRouteOptions>
1413
) {
1514
const schema = {
1615
method: 'POST',
17-
path: (options.prefix ? `${options.prefix}/forgot-password` : '/forgot-password') as WithPrefix<
18-
TOptions['prefix'],
19-
'/forgot-password'
20-
>,
21-
body: z.interface({
16+
path: (options.prefix
17+
? `${options.prefix}/auth/forgot-password`
18+
: '/auth/forgot-password') as WithPrefix<TOptions['prefix'], '/auth/forgot-password'>,
19+
body: z.object({
2220
email: z.string(),
2321
}),
2422
responses: {
25-
200: z.interface({
23+
200: z.object({
2624
status: z.string(),
2725
}),
28-
400: z.interface({
26+
400: z.object({
2927
status: z.string(),
3028
}),
3129
},
@@ -63,8 +61,5 @@ export function forgotPasswordEmail<const TOptions extends InternalRouteOptions>
6361
}
6462
}
6563

66-
return {
67-
...schema,
68-
handler,
69-
} satisfies ApiRoute
64+
return createEndpoint(schema, handler)
7065
}
Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import z from 'zod'
22

3-
import { ApiRoute, ApiRouteHandler, ApiRouteSchema } from '~/core/endpoint'
4-
3+
import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
54
import { AuthContext } from '../context'
5+
import { WithPrefix } from '../types'
66

77
interface InternalRouteOptions {
88
prefix?: string
@@ -11,17 +11,18 @@ interface InternalRouteOptions {
1111
export function me<const TOptions extends InternalRouteOptions>(options: TOptions) {
1212
const schema = {
1313
method: 'GET',
14-
path: (options.prefix ? `${options.prefix}/me` : '/me') as TOptions['prefix'] extends string
15-
? `${TOptions['prefix']}/me`
16-
: '/me',
14+
path: (options.prefix ? `${options.prefix}/auth/me` : '/auth/me') as WithPrefix<
15+
TOptions['prefix'],
16+
'/auth/me'
17+
>,
1718
responses: {
18-
200: z.interface({
19+
200: z.object({
1920
id: z.string(),
2021
name: z.string(),
2122
email: z.string(),
22-
'image?': z.string().nullable(),
23+
image: z.string().nullable().optional(),
2324
}),
24-
401: z.interface({
25+
401: z.object({
2526
status: z.string(),
2627
}),
2728
},
@@ -36,8 +37,5 @@ export function me<const TOptions extends InternalRouteOptions>(options: TOption
3637
}
3738
}
3839

39-
return {
40-
...schema,
41-
handler,
42-
} satisfies ApiRoute
40+
return createEndpoint(schema, handler)
4341
}

packages/core/src/auth/handlers/reset-password.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import z from 'zod'
22

3-
import { ApiRoute, ApiRouteHandler, ApiRouteSchema } from '~/core/endpoint'
4-
3+
import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
54
import { AuthContext } from '../context'
5+
import { WithPrefix } from '../types'
66

77
interface InternalRouteOptions {
88
prefix?: string
@@ -12,21 +12,19 @@ export function resetPasswordEmail<const TOptions extends InternalRouteOptions>(
1212
const schema = {
1313
method: 'POST',
1414
path: (options.prefix
15-
? `${options.prefix}/reset-password`
16-
: '/reset-password') as TOptions['prefix'] extends string
17-
? `${TOptions['prefix']}/reset-password`
18-
: '/reset-password',
19-
query: z.interface({
15+
? `${options.prefix}/auth/reset-password`
16+
: '/auth/reset-password') as WithPrefix<TOptions['prefix'], '/auth/reset-password'>,
17+
query: z.object({
2018
token: z.string(),
2119
}),
22-
body: z.interface({
20+
body: z.object({
2321
password: z.string(),
2422
}),
2523
responses: {
26-
200: z.interface({
24+
200: z.object({
2725
status: z.string(),
2826
}),
29-
400: z.interface({
27+
400: z.object({
3028
status: z.string(),
3129
}),
3230
},
@@ -59,8 +57,9 @@ export function resetPasswordEmail<const TOptions extends InternalRouteOptions>(
5957

6058
const redirectTo = `${args.context.authConfig.resetPassword?.redirectTo ?? '/auth/login'}`
6159

62-
const responseHeaders = new Headers()
63-
responseHeaders.set('Location', redirectTo)
60+
const responseHeaders = {
61+
Location: redirectTo,
62+
}
6463

6564
return {
6665
status: 200,
@@ -69,8 +68,5 @@ export function resetPasswordEmail<const TOptions extends InternalRouteOptions>(
6968
}
7069
}
7170

72-
return {
73-
...schema,
74-
handler,
75-
} satisfies ApiRoute
71+
return createEndpoint(schema, handler)
7672
}

packages/core/src/auth/handlers/sign-in-email.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import z from 'zod'
22

3-
import { ApiRoute, ApiRouteHandler, ApiRouteSchema } from '~/core/endpoint'
4-
3+
import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
54
import { AccountProvider } from '../constant'
65
import { AuthContext } from '../context'
76
import { WithPrefix } from '../types'
@@ -14,23 +13,22 @@ interface InternalRouteOptions {
1413
export function signInEmail<const TOptions extends InternalRouteOptions>(options: TOptions) {
1514
const schema = {
1615
method: 'POST',
17-
path: (options.prefix ? `${options.prefix}/sign-in/email` : '/sign-in/email') as WithPrefix<
18-
TOptions['prefix'],
19-
'/sign-in/email'
20-
>,
16+
path: (options.prefix
17+
? `${options.prefix}/auth/sign-in/email`
18+
: '/auth/sign-in/email') as WithPrefix<TOptions['prefix'], '/auth/sign-in/email'>,
2119

22-
body: z.interface({
20+
body: z.object({
2321
email: z.string(),
2422
password: z.string(),
2523
}),
2624
responses: {
27-
200: z.interface({
25+
200: z.object({
2826
token: z.string().nullable(),
29-
user: z.interface({
27+
user: z.object({
3028
id: z.string(),
3129
name: z.string(),
3230
email: z.string(),
33-
'image?': z.string().nullable(),
31+
image: z.string().nullable().optional(),
3432
}),
3533
}),
3634
},
@@ -54,7 +52,7 @@ export function signInEmail<const TOptions extends InternalRouteOptions>(options
5452
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24),
5553
})
5654

57-
const responseHeaders = new Headers()
55+
const responseHeaders = {}
5856
setSessionCookie(responseHeaders, session.token)
5957

6058
return {
@@ -67,8 +65,5 @@ export function signInEmail<const TOptions extends InternalRouteOptions>(options
6765
}
6866
}
6967

70-
return {
71-
...schema,
72-
handler,
73-
} satisfies ApiRoute
68+
return createEndpoint(schema, handler)
7469
}

packages/core/src/auth/handlers/sign-out.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import z from 'zod'
22

3-
import { ApiRoute, ApiRouteHandler, ApiRouteSchema } from '~/core/endpoint'
4-
3+
import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
54
import { AuthContext } from '../context'
65
import { WithPrefix } from '../types'
76
import { deleteSessionCookie, getSessionCookie } from '../utils'
@@ -13,13 +12,13 @@ interface InternalRouteOptions {
1312
export function signOut<const TOptions extends InternalRouteOptions>(options: TOptions) {
1413
const schema = {
1514
method: 'POST',
16-
path: (options.prefix ? `${options.prefix}/sign-out` : '/sign-out') as WithPrefix<
15+
path: (options.prefix ? `${options.prefix}/auth/sign-out` : '/auth/sign-out') as WithPrefix<
1716
TOptions['prefix'],
1817
'/sign-out'
1918
>,
2019
body: undefined,
2120
responses: {
22-
200: z.interface({
21+
200: z.object({
2322
status: z.string(),
2423
}),
2524
},
@@ -45,8 +44,5 @@ export function signOut<const TOptions extends InternalRouteOptions>(options: TO
4544
}
4645
}
4746

48-
return {
49-
...schema,
50-
handler,
51-
} satisfies ApiRoute
47+
return createEndpoint(schema, handler)
5248
}

packages/core/src/auth/handlers/sign-up.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import z from 'zod'
22

3-
import { ApiRoute, ApiRouteHandler, ApiRouteSchema } from '~/core/endpoint'
4-
3+
import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
54
import { AccountProvider } from '../constant'
65
import { AuthContext } from '../context'
76
import { WithPrefix } from '../types'
@@ -13,22 +12,22 @@ interface InternalRouteOptions {
1312
export function signUp<const TOptions extends InternalRouteOptions>(options: TOptions) {
1413
const schema = {
1514
method: 'POST',
16-
path: (options.prefix ? `${options.prefix}/sign-up` : '/sign-up') as WithPrefix<
15+
path: (options.prefix ? `${options.prefix}/auth/sign-up` : '/auth/sign-up') as WithPrefix<
1716
TOptions['prefix'],
18-
'/sign-up'
17+
'/auth/sign-up'
1918
>,
2019
body: z
21-
.interface({
20+
.object({
2221
name: z.string(),
2322
email: z.string(),
2423
password: z.string(),
2524
callbackURL: z.string().optional(),
2625
})
2726
.and(z.record(z.string(), z.any())),
2827
responses: {
29-
200: z.interface({
28+
200: z.object({
3029
token: z.string().nullable(),
31-
user: z.interface({
30+
user: z.object({
3231
id: z.string(),
3332
name: z.string(),
3433
email: z.string(),
@@ -73,8 +72,5 @@ export function signUp<const TOptions extends InternalRouteOptions>(options: TOp
7372
}
7473
}
7574

76-
return {
77-
...schema,
78-
handler,
79-
} satisfies ApiRoute
75+
return createEndpoint(schema, handler)
8076
}

packages/core/src/auth/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ type ChangeAuthHandlerContextToMinimalContext<
103103
any,
104104
infer TApiRouteSchema
105105
>
106-
? TApiRouteSchema & { handler: ApiRouteHandler<TContext, TApiRouteSchema> }
106+
? { schema: TApiRouteSchema; handler: ApiRouteHandler<TContext, TApiRouteSchema> }
107107
: never
108108
}
109109

@@ -140,7 +140,7 @@ export function createAuth<TContext extends MinimalContext = MinimalContext>(
140140
const handler: ApiRouteHandler<TContext, any> = (args) => {
141141
return h.handler({ ...args, context: authContext } as any) as any
142142
}
143-
return { ...h, handler }
143+
return { schema: h.schema, handler }
144144
}) as ChangeAuthHandlerContextToMinimalContext<
145145
TContext,
146146
ReturnType<typeof createAuthHandlers>['handlers']

0 commit comments

Comments
 (0)