diff --git a/README.md b/README.md index d53cc5c..77036be 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ # acorn [![ci](https://github.com/oakserver/acorn/workflows/ci/badge.svg)](https://github.com/oakserver/acorn) -[![acorn docs](https://deno.land/badge/acorn/version)](https://deno.land/x/acorn/) Rapidly develop and iterate on RESTful APIs using a strongly typed router designed for Deno CLI and Deno Deploy. ```ts -import { Router } from "https://deno.land/x/acorn/mod.ts"; +import { Router } from "jsr:@oak/acorn/router"; const BOOKS: Record = { "1": { id: 1, title: "The Hound of the Baskervilles" }, @@ -71,20 +70,18 @@ The `.url()` method returns an instance of URL associated with the request. The `.body()` method is a convenience method to deal with decoding a JSON string body. It can be used with an optional -[deserializer](https://doc.deno.land/https://deno.land/x/acorn/mod.ts/~/Deserializer) -which can do advanced decoding of the body, or it will attempted to be decoded -from the JSON string. +[deserializer](https://deno.land/x/acorn@0.4.0/mod.ts?s=Deserializer) which can +do advanced decoding of the body, or it will attempted to be decoded from the +JSON string. More advanced request body handling can be handled via the `.request` property. The handler is then expected to have a return value which can be a `Request` -instance, a value that is a -[`BodyInit`](https://doc.deno.land/deno/dom/~/BodyInit), or any other value. If -an optional -[serializer](https://doc.deno.land/https://deno.land/x/acorn/mod.ts/~/Serializer) -is provided and the response is not a `Request` instance or of the type -`BodyInit`, the value will be passed to the serializer. If no serializer is -present then +instance, a value that is a [`BodyInit`](https://deno.land/api?s=BodyInit), or +any other value. If an optional +[serializer](https://deno.land/x/acorn@0.4.0/mod.ts?s=Serializer) is provided +and the response is not a `Request` instance or of the type `BodyInit`, the +value will be passed to the serializer. If no serializer is present then [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) will be used to attempt to convert the value to a JSON string. If `undefined` is returned, then a `404 NotFound` response will be generated. @@ -101,4 +98,4 @@ and matches the pathname part of the URL. --- -Copyright 2018-2023 the oak authors. All rights reserved. MIT License. +Copyright 2018-2024 the oak authors. All rights reserved. MIT License. diff --git a/_examples/server.ts b/_examples/server.ts index 6d1c9f3..6ff96a6 100644 --- a/_examples/server.ts +++ b/_examples/server.ts @@ -1,9 +1,9 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. import { ServerSentEvent, ServerSentEventStreamTarget, -} from "https://deno.land/x/oak_commons@0.5.0/server_sent_event.ts"; +} from "jsr:@oak/commons@0.7/server_sent_event"; import { auth, immutable, Router } from "../mod.ts"; import { createHttpError, Status } from "../deps.ts"; diff --git a/context.ts b/context.ts index f114545..85d3e21 100644 --- a/context.ts +++ b/context.ts @@ -1,4 +1,4 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. /** * Contains the class {@linkcode Context} which provides context for the request diff --git a/deno.json b/deno.json index a046acd..a0ddba7 100644 --- a/deno.json +++ b/deno.json @@ -1,4 +1,14 @@ { + "name": "@oak/acorn", + "version": "0.4.0", + "exports": { + ".": "./mod.ts", + "./context": "./context.ts", + "./handlers": "./handlers.ts", + "./http_server_native": "./http_server_native.ts", + "./router": "./router.ts", + "./types": "./types.ts" + }, "tasks": { "bench": "deno bench", "example": "deno run --allow-net --allow-hrtime _examples/server.ts", diff --git a/deps.ts b/deps.ts index 8133412..0adc9ee 100644 --- a/deps.ts +++ b/deps.ts @@ -1,20 +1,20 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. export { type Data as SigningData, type Key as SigningKey, -} from "https://deno.land/std@0.212.0/crypto/unstable_keystack.ts"; -export { accepts } from "https://deno.land/std@0.212.0/http/negotiation.ts"; -export { UserAgent } from "https://deno.land/std@0.212.0/http/user_agent.ts"; -export { contentType } from "https://deno.land/std@0.212.0/media_types/content_type.ts"; +} from "jsr:@std/crypto@0.218/unstable_keystack"; +export { accepts } from "jsr:@std/http@0.218/negotiation"; +export { UserAgent } from "jsr:@std/http@0.218/user_agent"; +export { contentType } from "jsr:@std/media-types@0.218/content_type"; -export { SecureCookieMap } from "https://deno.land/x/oak_commons@0.5.0/cookie_map.ts"; +export { SecureCookieMap } from "jsr:@oak/commons@0.7/cookie_map"; export { createHttpError, errors, type HttpError, isHttpError, -} from "https://deno.land/x/oak_commons@0.5.0/http_errors.ts"; +} from "jsr:@oak/commons@0.7/http_errors"; export { isClientErrorStatus, isErrorStatus, @@ -24,4 +24,4 @@ export { isSuccessfulStatus, Status, STATUS_TEXT, -} from "https://deno.land/x/oak_commons@0.5.0/status.ts"; +} from "jsr:@oak/commons@0.7/status"; diff --git a/deps_test.ts b/deps_test.ts index 92eefc6..9e7bea9 100644 --- a/deps_test.ts +++ b/deps_test.ts @@ -1,5 +1,5 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. -export { assert } from "https://deno.land/std@0.212.0/assert/assert.ts"; -export { assertEquals } from "https://deno.land/std@0.212.0/assert/assert_equals.ts"; -export { assertRejects } from "https://deno.land/std@0.212.0/assert/assert_rejects.ts"; +export { assert } from "jsr:@std/assert@0.218/assert"; +export { assertEquals } from "jsr:@std/assert@0.218/assert_equals"; +export { assertRejects } from "jsr:@std/assert@0.218/assert_rejects"; diff --git a/handlers.test.ts b/handlers.test.ts index 44095d2..20b14f0 100644 --- a/handlers.test.ts +++ b/handlers.test.ts @@ -1,4 +1,4 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. import { assert, assertEquals, assertRejects } from "./deps_test.ts"; import { errors, SecureCookieMap, Status } from "./deps.ts"; diff --git a/handlers.ts b/handlers.ts index a3f79eb..3dd17a9 100644 --- a/handlers.ts +++ b/handlers.ts @@ -1,4 +1,4 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. /** Contains handler factory functions which simplify some common use cases. * @@ -42,10 +42,9 @@ export interface AuthOptions< * The {@linkcode auth} handler takes the content handler plus options which * includes an authorization handler. * - * ### Example - * + * @example * ```ts - * import { Router, immutable } from "https://deno.land/x/acorn/mod.ts"; + * import { Router, immutable } from "jsr:@oak/acorn/"; * * const router = new Router(); * @@ -105,7 +104,7 @@ export function auth< * ## Example * * ```ts - * import { Router, immutable } from "https://deno.land/x/acorn/mod.ts"; + * import { Router, immutable } from "jsr:@oak/acorn/"; * * const router = new Router(); * diff --git a/http_server_native.ts b/http_server_native.ts index abd32d1..b89b496 100644 --- a/http_server_native.ts +++ b/http_server_native.ts @@ -1,4 +1,4 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. import { type Addr, diff --git a/mod.ts b/mod.ts index 845588e..c127141 100644 --- a/mod.ts +++ b/mod.ts @@ -1,13 +1,12 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. /** * Provides a router which specifically tailored for providing RESTful * endpoints. * - * ## Example - * + * @example * ```ts - * import { Router } from "https://deno.land/x/acorn/mod.ts"; + * import { Router } from "jsr:@oak/acorn/router"; * * const router = new Router(); * diff --git a/router.test.ts b/router.test.ts index fc0296f..36f0a0a 100644 --- a/router.test.ts +++ b/router.test.ts @@ -1,4 +1,4 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. import { Status } from "./deps.ts"; import { assertEquals } from "./deps_test.ts"; diff --git a/router.ts b/router.ts index b0468b1..521f628 100644 --- a/router.ts +++ b/router.ts @@ -1,4 +1,28 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. + +/** + * The router for acorn, which is the foundational part of the framework. + * + * @example + * ```ts + * import { Router } from "jsr:@oak/acorn/router"; + * + * const router = new Router(); + * + * router.get("/", () => ({ hello: "world" })); + * + * const BOOKS = { + * "1": { title: "The Hound of the Baskervilles" }, + * "2": { title: "It" }, + * }; + * + * router.get("/books/:id", (ctx) => BOOKS[ctx.params.id]); + * + * router.listen({ port: 3000 }); + * ``` + * + * @module + */ import { Context } from "./context.ts"; import { @@ -82,6 +106,11 @@ export interface RouteHandler< | undefined; } +/** + * The interface too status handlers, which are registered on the + * {@linkcode Router} via the `.on()` method and intended for being notified of + * certain state changes related to routing requests. + */ export interface StatusHandler { ( context: Context>, @@ -718,6 +747,8 @@ class StatusRoute { } } +/** Context to be provided when invoking the `.handle()` method on the + * router. */ export interface RouterHandleInit { addr: Addr; /** @default {false} */ @@ -730,24 +761,20 @@ export interface RouterHandleInit { * A {@linkcode RouteHandler} is registered with the router, and when a request * matches a route the handler will be invoked. The handler will be provided * with {@linkcode Context} of the current request. The handler can return a - * web platform - * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) - * instance, {@linkcode BodyInit} value, or any other object which will be to be - * serialized to a JSON string as set as the value of the response body. + * web platform {@linkcode Response} instance, {@linkcode BodyInit} value, or + * any other object which will be to be serialized to a JSON string as set as + * the value of the response body. * * The handler context includes a property named `cookies` which is an instance * of {@linkcode Cookies}, which provides an interface for reading request * cookies and setting cookies in the response. `Cookies` supports cryptographic * signing of keys using a key ring which adheres to the {@linkcode KeyRing} * interface, which can be passed as an option when creating the router. - * [KeyStack](https://doc.deno.land/https://deno.land/x/oak_commons/key_stack.ts/~/KeyStack) - * is a key ring that implements this interface. * - * The route is specified using the pathname part of the - * [`URLPattern` API](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API), - * which supports routes with wildcards (e.g. `/posts/*`) and named groups (e.g. - * `/books/:id`) which are then provided as `.params` on the context argument to - * the handler. + * The route is specified using the pathname part of the {@linkcode URLPattern} + * API which supports routes with wildcards (e.g. `/posts/*`) and named groups + * (e.g. `/books/:id`) which are then provided as `.params` on the context + * argument to the handler. * * When registering a route handler, a {@linkcode Deserializer}, * {@linkcode Serializer}, and {@linkcode ErrorHandler} can all be specified. @@ -777,7 +804,7 @@ export interface RouterHandleInit { * ## Example * * ```ts - * import { Router } from "https://deno.land/x/acorn/mod.ts"; + * import { Router } from "jsr:@oak/acorn/router"; * * const router = new Router(); * @@ -1584,7 +1611,9 @@ export class Router extends EventTarget { super.addEventListener(type, listener, options); } - [Symbol.for("Deno.customInspect")](inspect: (value: unknown) => string) { + [Symbol.for("Deno.customInspect")]( + inspect: (value: unknown) => string, + ): string { return `${this.constructor.name} ${inspect({})}`; } @@ -1593,7 +1622,8 @@ export class Router extends EventTarget { // deno-lint-ignore no-explicit-any options: any, inspect: (value: unknown, options?: unknown) => string, - ) { + // deno-lint-ignore no-explicit-any + ): any { if (depth < 0) { return options.stylize(`[${this.constructor.name}]`, "special"); } diff --git a/routing.bench.ts b/routing.bench.ts index d9353aa..16d3c2e 100644 --- a/routing.bench.ts +++ b/routing.bench.ts @@ -1,4 +1,4 @@ -import { pathToRegexp } from "https://deno.land/x/path_to_regexp@v6.2.1/index.ts"; +import { pathToRegexp } from "npm:path-to-regexp@6.2.1"; const urlPattern = new URLPattern("/", "http://localhost/"); diff --git a/types.ts b/types.ts index 521dced..371b6a4 100644 --- a/types.ts +++ b/types.ts @@ -1,4 +1,4 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. import type { SigningData } from "./deps.ts"; diff --git a/util.ts b/util.ts index f148bed..e62ca2d 100644 --- a/util.ts +++ b/util.ts @@ -1,4 +1,10 @@ -// Copyright 2022-2023 the oak authors. All rights reserved. +// Copyright 2022-2024 the oak authors. All rights reserved. + +/** + * Contains some internal utilities. + * + * @module + */ import { accepts, contentType, type HttpError, STATUS_TEXT } from "./deps.ts"; @@ -36,7 +42,7 @@ export function isJsonLike(value: string): boolean { /** Generate a `Response` based on the original `Request` and an `HttpError`. * It will ensure negotiation of the content type and will provide the stack - * trace in errors that are marked as exposeable. */ + * trace in errors that are marked as expose-able. */ export function responseFromHttpError( request: Request, error: HttpError,