Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/runtime/composables/hooks/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { Hooks } from './types'

export function defineHooks<SessionDataType = unknown>(hooks: Hooks<SessionDataType>): Hooks<SessionDataType> {
return hooks
}

interface Session {
// Data of users returned by `getSession` endpoint
}

export default defineHooks<Session>({
signIn: {
createRequest(credentials, authState, nuxt) {
// todo

return {
path: '',
request: {
body: credentials,
}
}
},

onResponse(response, authState, nuxt) {
// Possible return values:
// - false - skip any further logic (useful when onResponse handles everything);
// - {} - skip assigning tokens and session, but still possibly call getSession and redirect
// - { token: string } - assign token and continue as normal;
// - { token: string, session: object } - assign token, skip calling getSession, but do possibly call redirect;

// todo
return {

}
},
},

getSession: {
createRequest(data, authState, nuxt) {
// todo

return {
path: '',
request: {}
}
},

onResponse(response, authState, nuxt) {
return response._data as Session
}
},

// signOut: {
//
// }
})

95 changes: 95 additions & 0 deletions src/runtime/composables/hooks/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import type { NitroFetchOptions, NitroFetchRequest } from 'nitropack'
import type { CommonUseAuthStateReturn, GetSessionOptions, SecondarySignInOptions, SignUpOptions } from '../../types'
import type { useNuxtApp } from '#imports'
import type { FetchResponse } from 'ofetch'

export type RequestOptions = NitroFetchOptions<NitroFetchRequest>
type NuxtApp = ReturnType<typeof useNuxtApp>
type Awaitable<T> = T | Promise<T>

/**
* The main interface defining hooks for an endpoint
*/
export interface EndpointHooks<SessionDataType, CreateRequestData, ResponseAccept> {
createRequest(
data: CreateRequestData,
authState: CommonUseAuthStateReturn<SessionDataType>,
nuxt: NuxtApp,
): Awaitable<CreateRequestResult | false>

onResponse(
response: FetchResponse<unknown>,
authState: CommonUseAuthStateReturn<SessionDataType>,
nuxt: NuxtApp,
): Awaitable<ResponseAccept | false>
}

/** Object that needs to be returned from `createRequest` in order to continue with data fetching */
export interface CreateRequestResult {
/**
* Path to be provided to `$fetch`.
* It can start with `/` so that Nuxt would use function calls on server.
*/
path: string
/**
* Request to be provided to `$fetch`, can include method, body, params, etc.
* @see https://nuxt.com/docs/4.x/api/utils/dollarfetch
*/
request: RequestOptions
}

/** Credentials accepted by `signIn` function */
export interface Credentials extends Record<string, any> {
username?: string
email?: string
password?: string
}

/** Data provided to `signIn.createRequest` */
export interface SignInCreateRequestData {
credentials: Credentials
options?: SecondarySignInOptions
}

/**
* Object that can be returned from some `onResponse` endpoints in order to update the auth state
* and impact the next steps.
*/
export interface ResponseAccept<SessionDataType> {
/**
* The value of the access token to be set.
* Omit or set to `undefined` to not modify the value.
*/
token?: string | null

/** Omit or set to `undefined` if you don't use it */
refreshToken?: string

/**
* When the session is provided, method will not call `getSession` and the session will be returned.
* Otherwise `getSession` may be called:
* - for `signIn` and `signUp` - depending on `callGetSession`;
* - for `refresh` - `getSession` will always be called in this case.
*/
session?: SessionDataType
}

/** Data provided to `signIn.createRequest` */
export interface SignUpCreateRequestData {
credentials: Credentials
options?: SignUpOptions
}

// TODO Use full UseAuthStateReturn, not the CommonUseAuthStateReturn

export interface Hooks<SessionDataType> {
// Required endpoints
signIn: EndpointHooks<SessionDataType, SignInCreateRequestData, ResponseAccept<SessionDataType>>
getSession: EndpointHooks<SessionDataType, GetSessionOptions | undefined, SessionDataType | null>

// Optional endpoints
signOut?: EndpointHooks<SessionDataType, never, never>
signUp?: EndpointHooks<SessionDataType, SignUpCreateRequestData, ResponseAccept<SessionDataType> | undefined>
refresh?: EndpointHooks<SessionDataType, GetSessionOptions | undefined, ResponseAccept<SessionDataType>>
}

Loading
Loading