Skip to content

Commit

Permalink
docs: Add JSDoc (#1916)
Browse files Browse the repository at this point in the history
* docs: Add JSDoc for App

* docs: Add JSDoc for Routing

* docs: Add JSDoc for Context

* docs: Add JSDoc for HonoRequest

* docs: Add JSDoc for Exception

* add .header JSDoc & getPath JSDoc (`nabeken5:feat/add-jsdoc#1`)

* add .header JSDoc & getPath JSDoc

* fix: Apply the format to JSDoc

---------

Thanks @EdamAme-x 
Co-authored-by: Kengo Watanabe <121782456+nabeken5@users.noreply.github.com>

* refactor: format

* feat: run denoify

---------

Co-authored-by: Ame_x <121654029+EdamAme-x@users.noreply.github.com>
  • Loading branch information
goisaki and EdamAme-x authored Jan 21, 2024
1 parent 64b98b8 commit 6801166
Show file tree
Hide file tree
Showing 8 changed files with 870 additions and 0 deletions.
177 changes: 177 additions & 0 deletions deno_dist/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,37 @@ export class Context<
P extends string = any,
I extends Input = {}
> {
/**
* `.req` is the instance of {@link HonoRequest}.
*/
req: HonoRequest<P, I['out']>
/**
* `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
* @example
* ```ts
* // Environment object for Cloudflare Workers
* app.get('*', async c => {
* const counter = c.env.COUNTER
* })
* ```
* @see https://hono.dev/api/context#env
*/
env: E['Bindings'] = {}
private _var: E['Variables'] = {}
finalized: boolean = false
/**
* `.error` can get the error object from the middleware if the Handler throws an error.
* @example
* ```ts
* app.use('*', async (c, next) => {
* await next()
* if (c.error) {
* // do something...
* }
* })
* ```
* @see https://hono.dev/api/context#error
*/
error: Error | undefined = undefined

#status: StatusCode = 200
Expand All @@ -122,6 +149,9 @@ export class Context<
}
}

/**
* @see https://hono.dev/api/context#event
*/
get event(): FetchEventLike {
if (this.#executionCtx && 'respondWith' in this.#executionCtx) {
return this.#executionCtx
Expand All @@ -130,6 +160,9 @@ export class Context<
}
}

/**
* @see https://hono.dev/api/context#executionctx
*/
get executionCtx(): ExecutionContext {
if (this.#executionCtx) {
return this.#executionCtx as ExecutionContext
Expand All @@ -138,6 +171,9 @@ export class Context<
}
}

/**
* @see https://hono.dev/api/context#res
*/
get res(): Response {
this.#isFresh = false
return (this.#res ||= new Response('404 Not Found', { status: 404 }))
Expand All @@ -163,6 +199,40 @@ export class Context<
this.finalized = true
}

/**
* `.render()` can create a response within a layout.
* @example
* ```ts
* app.get('/', (c) => {
* return c.render('Hello!')
* })
* ```
* @see https://hono.dev/api/context#render-setrenderer
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-explicit-any
render: Renderer = (...args: any[]) => this.renderer(...args)

/**
* `.setRenderer()` can set the layout in the custom middleware.
* @example
* ```tsx
* app.use('*', async (c, next) => {
* c.setRenderer((content) => {
* return c.html(
* <html>
* <body>
* <p>{content}</p>
* </body>
* </html>
* )
* })
* await next()
* })
* ```
* @see https://hono.dev/api/context#render-setrenderer
*/
// @ts-expect-error It is unknown how many arguments the renderer will receive.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
render: Renderer = (...args: any[]) => this.renderer(...args)
Expand All @@ -174,6 +244,20 @@ export class Context<
this.renderer = renderer
}

/**
* `.header()` can set headers.
* @example
* ```ts
* app.get('/welcome', (c) => {
* // Set headers
* c.header('X-Message', 'Hello!')
* c.header('Content-Type', 'text/plain')
*
* return c.body('Thank you for coming')
* })
* ```
* @see https://hono.dev/api/context#body
*/
header = (name: string, value: string | undefined, options?: { append?: boolean }): void => {
// Clear the header
if (value === undefined) {
Expand Down Expand Up @@ -218,15 +302,46 @@ export class Context<
this.#status = status
}

/**
* `.set()` can set the value specified by the key.
* @example
* ```ts
* app.use('*', async (c, next) => {
* c.set('message', 'Hono is cool!!')
* await next()
* })
* ```
* @see https://hono.dev/api/context#set-get
```
*/
set: Set<E> = (key: string, value: unknown) => {
this._var ??= {}
this._var[key as string] = value
}

/**
* `.get()` can use the value specified by the key.
* @example
* ```ts
* app.get('/', (c) => {
* const message = c.get('message')
* return c.text(`The message is "${message}"`)
* })
* ```
* @see https://hono.dev/api/context#set-get
*/
get: Get<E> = (key: string) => {
return this._var ? this._var[key] : undefined
}

/**
* `.var` can access the value of a variable.
* @example
* ```ts
* const result = c.var.client.oneMethod()
* ```
* @see https://hono.dev/api/context#var
*/
// c.var.propName is a read-only
get var(): Readonly<E['Variables'] & ContextVariableMap> {
return { ...this._var } as never
Expand Down Expand Up @@ -283,6 +398,25 @@ export class Context<
})
}

/**
* `.body()` can return the HTTP response.
* You can set headers with `.header()` and set HTTP status code with `.status`.
* This can also be set in `.text()`, `.json()` and so on.
* @example
* ```ts
* app.get('/welcome', (c) => {
* // Set headers
* c.header('X-Message', 'Hello!')
* c.header('Content-Type', 'text/plain')
* // Set HTTP status code
* c.status(201)
*
* // Return the response body
* return c.body('Thank you for coming')
* })
* ```
* @see https://hono.dev/api/context#body
*/
body: BodyRespond = (
data: Data | null,
arg?: StatusCode | ResponseInit,
Expand All @@ -293,6 +427,16 @@ export class Context<
: this.newResponse(data, arg)
}

/**
* `.text()` can render text as `Content-Type:text/plain`.
* @example
* ```ts
* app.get('/say', (c) => {
* return c.text('Hello!')
* })
* ```
* @see https://hono.dev/api/context#text
*/
text: TextRespond = (
text: string,
arg?: StatusCode | ResponseInit,
Expand All @@ -312,6 +456,16 @@ export class Context<
: this.newResponse(text, arg)
}

/**
* `.json()` can render JSON as `Content-Type:application/json`.
* @example
* ```ts
* app.get('/api', (c) => {
* return c.json({ message: 'Hello!' })
* })
* ```
* @see https://hono.dev/api/context#json
*/
json: JSONRespond = <T>(
object: InterfaceToType<T> extends JSONValue ? T : JSONValue,
arg?: StatusCode | ResponseInit,
Expand Down Expand Up @@ -361,12 +515,35 @@ export class Context<
: this.newResponse(html as string, arg)
}

/**
* `.redirect()` can Redirect, default status code is 302.
* @example
* ```ts
* app.get('/redirect', (c) => {
* return c.redirect('/')
* })
* app.get('/redirect-permanently', (c) => {
* return c.redirect('/', 301)
* })
* ```
* @see https://hono.dev/api/context#redirect
*/
redirect = (location: string, status: StatusCode = 302): Response => {
this.#headers ??= new Headers()
this.#headers.set('Location', location)
return this.newResponse(null, status)
}

/**
* `.notFound()` can return the Not Found Response.
* @example
* ```ts
* app.get('/notfound', (c) => {
* return c.notFound()
* })
* ```
* @see https://hono.dev/api/context#notfound
*/
notFound = (): Response | Promise<Response> => {
return this.notFoundHandler(this)
}
Expand Down
79 changes: 79 additions & 0 deletions deno_dist/hono-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,38 @@ const errorHandler = (err: Error, c: Context) => {
type GetPath<E extends Env> = (request: Request, options?: { env?: E['Bindings'] }) => string

export type HonoOptions<E extends Env> = {
/**
* `strict` option specifies whether to distinguish whether the last path is a directory or not.
* @default true
* @see https://hono.dev/api/hono#strict-mode
*/
strict?: boolean
/**
* `router` option specifices which router to use.
* ```ts
* const app = new Hono({ router: new RegExpRouter() })
* ```
* @see https://hono.dev/api/hono#router-option
*/
router?: Router<[H, RouterRoute]>
/**
* `getPath` can handle the host header value.
* @example
* ```ts
* const app = new Hono({
* getPath: (req) =>
* '/' + req.headers.get('host') + req.url.replace(/^https?:\/\/[^/]+(\/[^?]*)/, '$1'),
* })
*
* app.get('/www1.example.com/hello', () => c.text('hello www1'))
*
* // A following request will match the route:
* // new Request('http://www1.example.com/hello', {
* // headers: { host: 'www1.example.com' },
* // })
* ```
* @see https://hono.dev/api/routing#routing-with-host-header-value
*/
getPath?: GetPath<E>
}

Expand Down Expand Up @@ -179,17 +209,43 @@ class Hono<
return this
}

/**
* `.basePath()` allows base paths to be specified.
* @example
* ```ts
* const api = new Hono().basePath('/api')
* ```
* @see https://hono.dev/api/routing#base-path
*/
basePath<SubPath extends string>(path: SubPath): Hono<E, S, MergePath<BasePath, SubPath>> {
const subApp = this.clone()
subApp._basePath = mergePath(this._basePath, path)
return subApp
}

/**
* `.onError()` handles an error and returns a customized Response.
* ```ts
* app.onError((err, c) => {
* console.error(`${err}`)
* return c.text('Custom Error Message', 500)
* })
* ```
*/
onError = (handler: ErrorHandler<E>) => {
this.errorHandler = handler
return this
}

/**
* `.notFound()` allows you to customize a Not Found Response.
* ```ts
* app.notFound((c) => {
* return c.text('Custom 404 Message', 404)
* })
* ```
* @see https://hono.dev/api/hono#not-found
*/
notFound = (handler: NotFoundHandler<E>) => {
this.notFoundHandler = handler
return this
Expand Down Expand Up @@ -314,10 +370,26 @@ class Hono<
})()
}

/**
* `.fetch()` will be entry point of your app.
* @see https://hono.dev/api/hono#fetch
*/
fetch = (request: Request, Env?: E['Bindings'] | {}, executionCtx?: ExecutionContext) => {
return this.dispatch(request, executionCtx, Env, request.method)
}

/**
* `.request()` is a useful method for testing.
* You can pass a URL or pathname to send a GET request.
* app will return a Response object.
* ```ts
* test('GET /hello is ok', async () => {
* const res = await app.request('/hello')
* expect(res.status).toBe(200)
* })
* ```
* @see https://hono.dev/api/hono#request
*/
request = (
input: RequestInfo | URL,
requestInit?: RequestInit,
Expand All @@ -336,6 +408,13 @@ class Hono<
return this.fetch(req, Env, executionCtx)
}

/**
* `.fire()` automatically adds a global fetch event listener.
* This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
* @see https://hono.dev/api/hono#fire
* @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
* @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
*/
fire = () => {
// @ts-expect-error `event` is not the type expected by addEventListener
addEventListener('fetch', (event: FetchEventLike): void => {
Expand Down
Loading

0 comments on commit 6801166

Please sign in to comment.